HI Ilias, On Mon, Oct 19, 2026 at 10:35 AM Ilias Apalodimas <[email protected]> wrote: > > Hi Igor, > > On Mon, 12 Oct 2026 at 22:56, Igor Opaniuk > <[email protected]> wrote: > > > > The supplicant switched the eMMC to the RPMB hardware partition when the > > device was first used and only switched back when the OP-TEE session was > > released. Between two RPMB requests other users of the same device switch > > it back to the user area: libavb does so for every partition read while > > verifying a chain, and the Android bootmeth reads boot/vendor_boot right > > after verification. > > > > With RPMB left selected those reads hit the RPMB partition, and the next > > RPMB frames were routed to whatever partition the other user left > > selected, which ends in status timeouts and I/O errors (seen with > > the AVB TA on QEMU's emulated eMMC). > > > > Select the RPMB partition around every data request and restore the > > previously selected partition afterwards. > > Overall this seems correct, a few comments below. > > [...] > > > +/* > > + * The RPMB hardware partition is selected for the duration of a single > > + * request only. Between two requests other users of the same eMMC, for > > + * instance libavb reading the user area while verifying a chain of > > + * partitions, switch the device back to the user area. Keeping RPMB > > + * selected across requests would make those reads, and the following RPMB > > + * frames, hit the wrong partition. > > + */ > > +static int select_rpmb_part(struct optee_private *priv) > > +{ > > + int rc; > > + > > + priv->rpmb_original_part = mmc_get_blk_desc(priv->rpmb_mmc)->hwpart; > > + rc = blk_select_hwpart_devnum(UCLASS_MMC, priv->rpmb_dev_id, > > + MMC_PART_RPMB); > > + if (rc) > > + debug("Device id %d: cannot select RPMB partition: %d\n", > > + priv->rpmb_dev_id, rc); > > + > > + return rc; > > +} > > + > > +static void restore_part(struct optee_private *priv) > > +{ > > + int rc; > > + > > + rc = blk_select_hwpart_devnum(UCLASS_MMC, priv->rpmb_dev_id, > > + priv->rpmb_original_part); > > + if (rc) > > + debug("%s: blk_select_hwpart_devnum() failed: %d\n", > > + __func__, rc); > > +} > > + > > static u32 rpmb_get_dev_info(u16 dev_id, struct rpmb_dev_info *info) > > { > > struct mmc *mmc = find_mmc_device(dev_id); > > @@ -130,6 +146,7 @@ static u32 rpmb_process_request(struct optee_private > > *priv, void *req, > > { > > struct rpmb_req *sreq = req; > > struct mmc *mmc; > > + int rc; > > > > if (req_size < sizeof(*sreq)) > > return TEE_ERROR_BAD_PARAMETERS; > > @@ -139,9 +156,13 @@ static u32 rpmb_process_request(struct optee_private > > *priv, void *req, > > mmc = get_mmc(priv, sreq->dev_id); > > get_mmc already selects rpmb_original_part, which we now always overwrite. > > Cant we fold in select_rpmb_part() into get_mmc?
Right, that assignment in get_mmc() is a leftover from when it also switched to RPMB; Folded the fix in for v3 > > > if (!mmc) > > return TEE_ERROR_ITEM_NOT_FOUND; > > - if (mmc_rpmb_route_frames(mmc, RPMB_REQ_DATA(req), > > - req_size - sizeof(struct > > rpmb_req), > > - rsp, rsp_size)) > > + if (select_rpmb_part(priv)) > > + return TEE_ERROR_ITEM_NOT_FOUND; > > + rc = mmc_rpmb_route_frames(mmc, RPMB_REQ_DATA(req), > > + req_size - sizeof(struct > > rpmb_req), > > + rsp, rsp_size); > > + restore_part(priv); > > + if (rc) > > return TEE_ERROR_BAD_PARAMETERS; > > return TEE_SUCCESS; > > > > > > -- > > 2.53.0 > > > > Thanks > /Ilias
