Re: [PATCH] mmc: core: block: fix sloppy typing in mmc_blk_ioctl_multi_cmd()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, 30 Mar 2022 at 23:09, Sergey Shtylyov <s.shtylyov@xxxxxx> wrote:
>
> Despite mmc_ioc_multi_cmd::num_of_cmds is a 64-bit field, its maximum
> value is limited to MMC_IOC_MAX_CMDS (only 255); using a 64-bit local
> variable to hold a copy of that field leads to gcc generating ineffective
> loop code: despite the source code using an *int* variable for the loop
> counters,  the 32-bit object code uses 64-bit unsigned counters.  Also,
> gcc has to drop the most significant word of that 64-bit variable when
> calling kcalloc() and assigning to mmc_queue_req::ioc_count anyway.
> Using the *unsigned int* variable instead results in a better code.
>
> Found by Linux Verification Center (linuxtesting.org) with the SVACE static
> analysis tool.
>
> Signed-off-by: Sergey Shtylyov <s.shtylyov@xxxxxx>

Applied for next, thanks!

Kind regards
Uffe


>
> ---
> This patch is against the 'next' branch of Ulf Hansson's 'mmc.git' repo.
>
>  drivers/mmc/core/block.c |   16 +++++++++-------
>  1 file changed, 9 insertions(+), 7 deletions(-)
>
> Index: mmc/drivers/mmc/core/block.c
> ===================================================================
> --- mmc.orig/drivers/mmc/core/block.c
> +++ mmc/drivers/mmc/core/block.c
> @@ -676,8 +676,9 @@ static int mmc_blk_ioctl_multi_cmd(struc
>         struct mmc_ioc_cmd __user *cmds = user->cmds;
>         struct mmc_card *card;
>         struct mmc_queue *mq;
> -       int i, err = 0, ioc_err = 0;
> +       int err = 0, ioc_err = 0;
>         __u64 num_of_cmds;
> +       unsigned int i, n;
>         struct request *req;
>
>         if (copy_from_user(&num_of_cmds, &user->num_of_cmds,
> @@ -690,15 +691,16 @@ static int mmc_blk_ioctl_multi_cmd(struc
>         if (num_of_cmds > MMC_IOC_MAX_CMDS)
>                 return -EINVAL;
>
> -       idata = kcalloc(num_of_cmds, sizeof(*idata), GFP_KERNEL);
> +       n = num_of_cmds;
> +       idata = kcalloc(n, sizeof(*idata), GFP_KERNEL);
>         if (!idata)
>                 return -ENOMEM;
>
> -       for (i = 0; i < num_of_cmds; i++) {
> +       for (i = 0; i < n; i++) {
>                 idata[i] = mmc_blk_ioctl_copy_from_user(&cmds[i]);
>                 if (IS_ERR(idata[i])) {
>                         err = PTR_ERR(idata[i]);
> -                       num_of_cmds = i;
> +                       n = i;
>                         goto cmd_err;
>                 }
>                 /* This will be NULL on non-RPMB ioctl():s */
> @@ -725,18 +727,18 @@ static int mmc_blk_ioctl_multi_cmd(struc
>         req_to_mmc_queue_req(req)->drv_op =
>                 rpmb ? MMC_DRV_OP_IOCTL_RPMB : MMC_DRV_OP_IOCTL;
>         req_to_mmc_queue_req(req)->drv_op_data = idata;
> -       req_to_mmc_queue_req(req)->ioc_count = num_of_cmds;
> +       req_to_mmc_queue_req(req)->ioc_count = n;
>         blk_execute_rq(req, false);
>         ioc_err = req_to_mmc_queue_req(req)->drv_op_result;
>
>         /* copy to user if data and response */
> -       for (i = 0; i < num_of_cmds && !err; i++)
> +       for (i = 0; i < n && !err; i++)
>                 err = mmc_blk_ioctl_copy_to_user(&cmds[i], idata[i]);
>
>         blk_mq_free_request(req);
>
>  cmd_err:
> -       for (i = 0; i < num_of_cmds; i++) {
> +       for (i = 0; i < n; i++) {
>                 kfree(idata[i]->buf);
>                 kfree(idata[i]);
>         }



[Index of Archives]     [Linux Memonry Technology]     [Linux USB Devel]     [Linux Media]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux