When U-Boot serves OP-TEE's RPMB requests itself
(CONFIG_SUPPORT_EMMC_RPMB, drivers/tee/optee/rpmb_emmc.c), two problems
show up as soon as a TA uses RPMB secure storage while other code is
using the same eMMC. Both were found running the OP-TEE AVB TA from the
Android bootmeth on QEMU virt with QEMU's eMMC/RPMB model, but neither
is specific to QEMU.

The first patch makes the supplicant select the RPMB hardware partition
around every data request and restore the previously selected partition
afterwards. It used to switch to RPMB on first use and switch back only
when the OP-TEE session was released, so between two RPMB requests other
users of the device (libavb reading partitions, the bootmeth loading
boot images) switched the eMMC back to the user area, and the next RPMB
frames were routed to whatever partition was selected at the time,
ending in status timeouts and I/O errors.

The second patch stops optee_rpmb_available() from announcing the RPMB
device while a supplicant RPC is being serviced. When the first eMMC
initialisation is triggered by an RPMB request, OP-TEE is blocked in that
RPC holding its RPMB mutex; the announcement opens a nested session and
OP-TEE's second thread spins on the mutex forever, since U-Boot has no
notification support to put it to sleep.

Tested on QEMU virt (qemu_arm64_defconfig + OP-TEE, eMMC on sdhci-pci
with an RPMB partition) with OP-TEE 4.11.0-rc1: the AVB TA reads and
writes rollback indexes and the lock state while libavb verifies a
vbmeta chain, and a TA call that is the first eMMC access after reset
no longer hangs.

Signed-off-by: Igor Opaniuk <[email protected]>
---
Changes in v4:
- rebased on main, which now has UFS RPMB support: rpmb.c is
  rpmb_emmc.c and struct optee_private has one variant per RPMB backend
- patch 2: add in_supplicant to both struct optee_private variants and
  document it in their kernel-doc; v3 did not build with
  CONFIG_SUPPORT_UFS_RPMB (Ilias Apalodimas)
- Link to v3: 
https://patch.msgid.link/20261019-upstream-optee_rpmb_b4-v3-0-c97cf24fc...@oss.qualcomm.com

Changes in v3:
- patch 1: select the RPMB partition inside get_mmc() on every call
  instead of in a separate helper, dropping the dead store of the
  original partition on the first lookup (Ilias Apalodimas)
- patch 2: keep the supplicant counter in handle_rpc() as in v1, not in
  optee_suppl_cmd(): the sandbox TEE driver calls optee_suppl_cmd() with
  its own private data, so the v2 placement wrote into
  sandbox_tee_state (Ilias Apalodimas); explained in the commit message
- Link to v2: 
https://patch.msgid.link/20261012-upstream-optee_rpmb_b4-v2-0-85d76a542...@oss.qualcomm.com

Changes in v2:
- track the supplicant request inside optee_suppl_cmd() instead of
  handle_rpc(), and use a local variable for the private data in
  optee_rpmb_available() (Jan Kiszka)
- explain in the commit message of patch 2 how the hang is triggered,
  which TAs reproduce it, and why Linux does not need the check
- Link to v1: 
https://patch.msgid.link/20261011-upstream-optee_rpmb_b4-v1-0-7c63edca4...@oss.qualcomm.com

---
Igor Opaniuk (2):
      optee: rpmb: select the RPMB partition per request
      optee: do not announce RPMB from within a supplicant RPC

 drivers/tee/optee/core.c          |  7 +++
 drivers/tee/optee/optee_private.h |  6 +++
 drivers/tee/optee/rpmb_emmc.c     | 99 +++++++++++++++++++++++++--------------
 3 files changed, 76 insertions(+), 36 deletions(-)
---
base-commit: 03e45557e1f38a39a0c80fe30483130ff376cf92
change-id: 20261011-upstream-optee_rpmb_b4-ff86a4ea9039

Best regards,
-- 
Igor Opaniuk <[email protected]>

Reply via email to