Re: [PATCH v3] mmc-utils: RPMB fails with status 0x0001 on system eMMC chips

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

 



Hi Avri,

On Fri, 19 Oct 2018 at 13:41, Avri Altman <Avri.Altman@xxxxxxx> wrote:
>
> Hi,
>
> > Use MMC_IOC_MULTI_CMD for RPMB access
> Actually, this is much more appropriate title for this patch
>
> >
> > 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>
> > ---
> >
> > 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 | 98 +++++++++++++++++++++++++++++-------------------------
> >  1 file changed, 53 insertions(+), 45 deletions(-)
> >
> > diff --git a/mmc_cmds.c b/mmc_cmds.c
> > index 44623fe..c8bfc09 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)
> > +{
> > +     ioc->opcode = opcode;
> > +     ioc->write_flag = write_flag;
> > +     ioc->arg = 0x0;
> > +     ioc->blksz = 512;
> > +     ioc->blocks = 1;
> blocks Should be an input
>
> > +     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,27 @@ 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;
> >
> >       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 +1905,24 @@ 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);
> > +             mmc_ioc_cmd_set_data((*ioc), frame_in);
> >
> >               /* Result request */
> > +             ioc = &mioc->cmds[1];
> >               memset(frame_out, 0, sizeof(*frame_out));
> You need to save frame_out to carry the response - use a fresh frame here, e.g.:
> u_int8_t get_status_command[512] ={0};

Thanks for the explanation, I prefer to declare a new rpmb_frame.
Will send a new patch.

Thanks for your review,
Clement

>
> >               frame_out->req_resp = htobe16(MMC_RPMB_READ_RESP);
> get_status_command[511] = 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;
> > -             }
> > +             set_single_cmd(ioc, MMC_WRITE_MULTIPLE_BLOCK, 1);
> > +             mmc_ioc_cmd_set_data((*ioc), frame_out);
> mmc_ioc_cmd_set_data((*ioc), get_status_command);
>
> >
> >               /* 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);
> > +             mmc_ioc_cmd_set_data((*ioc), frame_in);
> mmc_ioc_cmd_set_data((*ioc), frame_out);
>
> >
> >               break;
> >       case MMC_RPMB_READ_CNT:
> > @@ -1924,23 +1933,18 @@ 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);
> > +             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);
> > +             ioc->blocks = out_cnt;
> Not needed if out_cnt is an input to set_single_cmd
>
> > +             mmc_ioc_cmd_set_data((*ioc), frame_out);
> >
> >               break;
> >       default:
> > @@ -1948,8 +1952,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.17.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