Re: [PATCH v4] mmc-utils: use MMC_IOC_MULTI_CMD for RPMB access

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

 



+Chris

On 20 October 2018 at 19:52, Clément Péron <peron.clem@xxxxxxxxx> wrote:
> From: Nikita Maslov <wkernelteam@xxxxxxxxx>
>
> On some systems which use MMC as a main storage device
> it is possible that RPMB commands are mixed with
> generic MMC access commands which invalidates RPMB.
>
> This patch uses MMC_IOC_MULTI_CMD.
>
> Signed-off-by: Clément Péron <peron.clem@xxxxxxxxx>

Please re-post and add Chris Ball, as he is the maintainer of mmc-utils.

Kind regards
Uffe

> ---
>
> v4:
>         change title of the commit
>         pass blocks as param of set_single_cmd
>         use temp rpmb_frame to carry the response
>
> v3:
>         move set_single_cmd in mmc_cmds.c
>         add MMC_IOC_MULTI_CMD check
>         set blocks in set_single_cmd
>         fix frame_ptr used
>
>
>  mmc_cmds.c | 101 ++++++++++++++++++++++++++++-------------------------
>  1 file changed, 54 insertions(+), 47 deletions(-)
>
> diff --git a/mmc_cmds.c b/mmc_cmds.c
> index 44623fe..886eaf4 100644
> --- a/mmc_cmds.c
> +++ b/mmc_cmds.c
> @@ -1825,6 +1825,8 @@ int do_sanitize(int nargs, char **argv)
>                 ret;                                                                            \
>         })
>
> +#define RMPB_MULTI_CMD_MAX_CMDS 3
> +
>  enum rpmb_op_type {
>         MMC_RPMB_WRITE_KEY = 0x01,
>         MMC_RPMB_READ_CNT  = 0x02,
> @@ -1847,6 +1849,17 @@ struct rpmb_frame {
>         u_int16_t req_resp;
>  };
>
> +static inline void set_single_cmd(struct mmc_ioc_cmd *ioc, __u32 opcode,
> +                                 int write_flag, unsigned int blocks)
> +{
> +       ioc->opcode = opcode;
> +       ioc->write_flag = write_flag;
> +       ioc->arg = 0x0;
> +       ioc->blksz = 512;
> +       ioc->blocks = blocks;
> +       ioc->flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC;
> +}
> +
>  /* Performs RPMB operation.
>   *
>   * @fd: RPMB device on which we should perform ioctl command
> @@ -1861,22 +1874,28 @@ static int do_rpmb_op(int fd,
>                                           struct rpmb_frame *frame_out,
>                                           unsigned int out_cnt)
>  {
> +#ifndef MMC_IOC_MULTI_CMD
> +       fprintf(stderr, "mmc-utils has been compiled without MMC_IOC_MULTI_CMD"
> +               " support, needed by RPMB operation.\n");
> +       exit(1);
> +#else
>         int err;
>         u_int16_t rpmb_type;
> -
> -       struct mmc_ioc_cmd ioc = {
> -               .arg        = 0x0,
> -               .blksz      = 512,
> -               .blocks     = 1,
> -               .write_flag = 1,
> -               .opcode     = MMC_WRITE_MULTIPLE_BLOCK,
> -               .flags      = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC,
> -               .data_ptr   = (uintptr_t)frame_in
> -       };
> +       struct mmc_ioc_multi_cmd *mioc;
> +       struct mmc_ioc_cmd *ioc;
> +       struct rpmb_frame frame_status = {0};
>
>         if (!frame_in || !frame_out || !out_cnt)
>                 return -EINVAL;
>
> +       /* prepare arguments for MMC_IOC_MUTLI_CMD ioctl */
> +       mioc = (struct mmc_ioc_multi_cmd *)
> +               malloc(sizeof (struct mmc_ioc_multi_cmd) +
> +                      RMPB_MULTI_CMD_MAX_CMDS * sizeof (struct mmc_ioc_cmd));
> +       if (!mioc) {
> +               return -ENOMEM;
> +       }
> +
>         rpmb_type = be16toh(frame_in->req_resp);
>
>         switch(rpmb_type) {
> @@ -1887,33 +1906,23 @@ static int do_rpmb_op(int fd,
>                         goto out;
>                 }
>
> +               mioc->num_of_cmds = 3;
> +
>                 /* Write request */
> -               ioc.write_flag |= (1<<31);
> -               err = ioctl(fd, MMC_IOC_CMD, &ioc);
> -               if (err < 0) {
> -                       err = -errno;
> -                       goto out;
> -               }
> +               ioc = &mioc->cmds[0];
> +               set_single_cmd(ioc, MMC_WRITE_MULTIPLE_BLOCK, (1 << 31) | 1, 1);
> +               mmc_ioc_cmd_set_data((*ioc), frame_in);
>
>                 /* Result request */
> -               memset(frame_out, 0, sizeof(*frame_out));
> -               frame_out->req_resp = htobe16(MMC_RPMB_READ_RESP);
> -               ioc.write_flag = 1;
> -               ioc.data_ptr = (uintptr_t)frame_out;
> -               err = ioctl(fd, MMC_IOC_CMD, &ioc);
> -               if (err < 0) {
> -                       err = -errno;
> -                       goto out;
> -               }
> +               ioc = &mioc->cmds[1];
> +               frame_status.req_resp = htobe16(MMC_RPMB_READ_RESP);
> +               set_single_cmd(ioc, MMC_WRITE_MULTIPLE_BLOCK, 1, 1);
> +               mmc_ioc_cmd_set_data((*ioc), &frame_status);
>
>                 /* Get response */
> -               ioc.write_flag = 0;
> -               ioc.opcode = MMC_READ_MULTIPLE_BLOCK;
> -               err = ioctl(fd, MMC_IOC_CMD, &ioc);
> -               if (err < 0) {
> -                       err = -errno;
> -                       goto out;
> -               }
> +               ioc = &mioc->cmds[2];
> +               set_single_cmd(ioc, MMC_READ_MULTIPLE_BLOCK, 0, 1);
> +               mmc_ioc_cmd_set_data((*ioc), frame_out);
>
>                 break;
>         case MMC_RPMB_READ_CNT:
> @@ -1924,23 +1933,17 @@ static int do_rpmb_op(int fd,
>                 /* fall through */
>
>         case MMC_RPMB_READ:
> -               /* Request */
> -               err = ioctl(fd, MMC_IOC_CMD, &ioc);
> -               if (err < 0) {
> -                       err = -errno;
> -                       goto out;
> -               }
> +               mioc->num_of_cmds = 2;
> +
> +               /* Read request */
> +               ioc = &mioc->cmds[0];
> +               set_single_cmd(ioc, MMC_WRITE_MULTIPLE_BLOCK, 1, 1);
> +               mmc_ioc_cmd_set_data((*ioc), frame_in);
>
>                 /* Get response */
> -               ioc.write_flag = 0;
> -               ioc.opcode   = MMC_READ_MULTIPLE_BLOCK;
> -               ioc.blocks   = out_cnt;
> -               ioc.data_ptr = (uintptr_t)frame_out;
> -               err = ioctl(fd, MMC_IOC_CMD, &ioc);
> -               if (err < 0) {
> -                       err = -errno;
> -                       goto out;
> -               }
> +               ioc = &mioc->cmds[1];
> +               set_single_cmd(ioc, MMC_READ_MULTIPLE_BLOCK, 0, out_cnt);
> +               mmc_ioc_cmd_set_data((*ioc), frame_out);
>
>                 break;
>         default:
> @@ -1948,8 +1951,12 @@ static int do_rpmb_op(int fd,
>                 goto out;
>         }
>
> +       err = ioctl(fd, MMC_IOC_MULTI_CMD, mioc);
> +
>  out:
> +       free(mioc);
>         return err;
> +#endif /* !MMC_IOC_MULTI_CMD */
>  }
>
>  int do_rpmb_write_key(int nargs, char **argv)
> --
> 2.19.1
>




[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