Message ID | 20210615072850.16812-1-litchi.pi@protonmail.com |
---|---|
State | Superseded |
Delegated to: | Peng Fan |
Headers | show |
Series | drivers/mmc/rpmb.c: Fix driver routing memory alignment with tmp buffer | expand |
Hi Timorthee, On 6/15/21 4:29 PM, Timothée Cercueil wrote: > From: litchipi <litchi.pi@protonmail.com> > Could you change to subject as "mmc: rpmb: fix ...."? > Fix mmc_rpmb_route_frames() implementation to comply with most MMC > drivers that expect some alignment of MMC data frames in memory. > > When called from drivers/tee/optee/rpmb.c, the address passed is not > aligned properly. OP-TEE OS inserts a 6-byte header before a raw RPMB > frame which makes RPMB data buffer not 32bit aligned. To prevent breaking > ABI with OPTEE-OS RPC memrefs, allocate a temporary buffer to copy the > data into an aligned memory. > > Many RPMB drivers implicitly expect 32bit alignment of the eMMC frame > including arm_pl180_mmci.c, sandbox_mmc.c and stm32_sdmmc2.c > > Signed-off-by: Timothée Cercueil <timothee.cercueil@st.com> > Signed-off-by: litchipi <litchi.pi@protonmail.com> > Change-Id: Iec7554cf6be1219e2d80eb7b45d8d60531c9a7d6 Remove Change-Id. Best Regards, Jaehoon Chung > Signed-off-by: Timothée Cercueil <litchi.pi@protonmail.com> > --- > drivers/mmc/rpmb.c | 18 ++++++++++++++++-- > 1 file changed, 16 insertions(+), 2 deletions(-) > > diff --git a/drivers/mmc/rpmb.c b/drivers/mmc/rpmb.c > index ea7e506666..b68d98573c 100644 > --- a/drivers/mmc/rpmb.c > +++ b/drivers/mmc/rpmb.c > @@ -480,10 +480,24 @@ int mmc_rpmb_route_frames(struct mmc *mmc, void *req, unsigned long reqlen, > * and possibly just delay an eventual error which will be harder > * to track down. > */ > + void *rpmb_data = NULL; > + int ret; > > if (reqlen % sizeof(struct s_rpmb) || rsplen % sizeof(struct s_rpmb)) > return -EINVAL; > > - return rpmb_route_frames(mmc, req, reqlen / sizeof(struct s_rpmb), > - rsp, rsplen / sizeof(struct s_rpmb)); > + if (!IS_ALIGNED((uintptr_t)req, ARCH_DMA_MINALIGN)) { > + /* Memory alignment is required by MMC driver */ > + rpmb_data = malloc(reqlen); > + if (!rpmb_data) > + return -ENOMEM; > + > + memcpy(rpmb_data, req, reqlen); > + req = rpmb_data; > + } > + > + ret = rpmb_route_frames(mmc, req, reqlen / sizeof(struct s_rpmb), > + rsp, rsplen / sizeof(struct s_rpmb)); > + free(rpmb_data); > + return ret; > } > -- > 2.17.1 > > >
diff --git a/drivers/mmc/rpmb.c b/drivers/mmc/rpmb.c index ea7e506666..b68d98573c 100644 --- a/drivers/mmc/rpmb.c +++ b/drivers/mmc/rpmb.c @@ -480,10 +480,24 @@ int mmc_rpmb_route_frames(struct mmc *mmc, void *req, unsigned long reqlen, * and possibly just delay an eventual error which will be harder * to track down. */ + void *rpmb_data = NULL; + int ret; if (reqlen % sizeof(struct s_rpmb) || rsplen % sizeof(struct s_rpmb)) return -EINVAL; - return rpmb_route_frames(mmc, req, reqlen / sizeof(struct s_rpmb), - rsp, rsplen / sizeof(struct s_rpmb)); + if (!IS_ALIGNED((uintptr_t)req, ARCH_DMA_MINALIGN)) { + /* Memory alignment is required by MMC driver */ + rpmb_data = malloc(reqlen); + if (!rpmb_data) + return -ENOMEM; + + memcpy(rpmb_data, req, reqlen); + req = rpmb_data; + } + + ret = rpmb_route_frames(mmc, req, reqlen / sizeof(struct s_rpmb), + rsp, rsplen / sizeof(struct s_rpmb)); + free(rpmb_data); + return ret; }