* [PATCH v4 1/2] ufs: rpmb: retry power-on UNIT ATTENTION on the RPMB WLUN
2026-08-27 7:03 [PATCH v4 0/2] ufs: rpmb: make RPMB usable with OP-TEE key derivation Jorge Ramirez-Ortiz
@ 2026-08-27 7:03 ` Jorge Ramirez-Ortiz
2026-08-27 7:03 ` [PATCH v4 2/2] ufs: rpmb: use a fixed-length RPMB dev_id Jorge Ramirez-Ortiz
1 sibling, 0 replies; 3+ messages in thread
From: Jorge Ramirez-Ortiz @ 2026-08-27 7:03 UTC (permalink / raw)
To: jorge.ramirez, beanhuo, James.Bottomley, martin.petersen,
alim.akhtar, avri.altman, bvanassche, beanhuo, can.guo,
sumit.garg, jenswi
Cc: linux-scsi, linux-kernel, op-tee
After a power cycle, the first command sent to any UFS logical unit
completes with CHECK CONDITION reporting a power-on UNIT ATTENTION.
The SCSI core surfaces this condition to the caller rather than
retrying it.
For the RPMB well-known LU the first command after boot is the first
RPMB frame, and RPMB has no earlier, guaranteed access that could clear
the condition beforehand. The power-on UNIT ATTENTION therefore reaches
RPMB and fails that first frame, breaking RPMB on every cold boot.
The RPMB WLUN needs the power-on UNIT ATTENTION to be retried so that
RPMB works from the very first access after a power cycle.
Signed-off-by: Jorge Ramirez-Ortiz <jorge.ramirez@oss.qualcomm.com>
---
drivers/ufs/core/ufs-rpmb.c | 20 +++++++++++++++++++-
1 file changed, 19 insertions(+), 1 deletion(-)
diff --git a/drivers/ufs/core/ufs-rpmb.c b/drivers/ufs/core/ufs-rpmb.c
index ffad049872b9..79e6cd2b20a0 100644
--- a/drivers/ufs/core/ufs-rpmb.c
+++ b/drivers/ufs/core/ufs-rpmb.c
@@ -21,6 +21,7 @@
#include <linux/unaligned.h>
#include "ufshcd-priv.h"
+#define UFS_RPMB_UA_RETRIES 3 /* Retries for the power-on UNIT ATTENTION */
#define UFS_RPMB_SEC_PROTOCOL 0xEC /* JEDEC UFS application */
#define UFS_RPMB_SEC_PROTOCOL_ID 0x01 /* JEDEC UFS RPMB protocol ID, CDB byte3 */
@@ -40,6 +41,22 @@ struct ufs_rpmb_dev {
static int ufs_sec_submit(struct ufs_hba *hba, u16 spsp, void *buffer, size_t len, bool send)
{
struct scsi_device *sdev = hba->ufs_rpmb_wlun;
+ struct scsi_failure failure_defs[] = {
+ {
+ .sense = UNIT_ATTENTION,
+ .asc = 0x29, /* power on, reset, or bus device reset occurred */
+ .ascq = SCMD_FAILURE_ASCQ_ANY,
+ .allowed = UFS_RPMB_UA_RETRIES,
+ .result = SAM_STAT_CHECK_CONDITION,
+ },
+ {}
+ };
+ struct scsi_failures failures = {
+ .failure_definitions = failure_defs,
+ };
+ const struct scsi_exec_args exec_args = {
+ .failures = &failures,
+ };
u8 cdb[12] = { };
cdb[0] = send ? SECURITY_PROTOCOL_OUT : SECURITY_PROTOCOL_IN;
@@ -48,7 +65,8 @@ static int ufs_sec_submit(struct ufs_hba *hba, u16 spsp, void *buffer, size_t le
put_unaligned_be32(len, &cdb[6]);
return scsi_execute_cmd(sdev, cdb, send ? REQ_OP_DRV_OUT : REQ_OP_DRV_IN,
- buffer, len, /*timeout=*/30 * HZ, 0, NULL);
+ buffer, len, /*timeout=*/30 * HZ, /*retries=*/0,
+ &exec_args);
}
/* UFS RPMB route frames implementation */
--
2.54.0
^ permalink raw reply [flat|nested] 3+ messages in thread* [PATCH v4 2/2] ufs: rpmb: use a fixed-length RPMB dev_id
2026-08-27 7:03 [PATCH v4 0/2] ufs: rpmb: make RPMB usable with OP-TEE key derivation Jorge Ramirez-Ortiz
2026-08-27 7:03 ` [PATCH v4 1/2] ufs: rpmb: retry power-on UNIT ATTENTION on the RPMB WLUN Jorge Ramirez-Ortiz
@ 2026-08-27 7:03 ` Jorge Ramirez-Ortiz
1 sibling, 0 replies; 3+ messages in thread
From: Jorge Ramirez-Ortiz @ 2026-08-27 7:03 UTC (permalink / raw)
To: jorge.ramirez, beanhuo, James.Bottomley, martin.petersen,
alim.akhtar, avri.altman, bvanassche, beanhuo, can.guo,
sumit.garg, jenswi
Cc: linux-scsi, linux-kernel, op-tee
The RPMB authentication key is derived from the dev_id handed to the
RPMB subsystem. OP-TEE implements the eMMC RPMB flow, where the dev_id
is the eMMC CID: a fixed 16-byte value the key derivation depends on.
The UFS RPMB id is "<device_id>-R<region>", which is variable length
and longer than 16 bytes. Handing it to the RPMB subsystem as-is would
tie the derived key to a length OP-TEE does not expect and diverge from
the fixed-CID eMMC ABI, forcing OP-TEE to be taught about
variable-length UFS ids.
A fixed 16-byte dev_id is needed so the derived key stays stable and
unique per region while matching the eMMC CID layout OP-TEE relies on,
keeping the key-derivation ABI identical with no OP-TEE change. The
reduction to a fixed 16 bytes must also be reproducible by the
bootloaders (such as U-Boot) that derive the same dev_id.
Signed-off-by: Jorge Ramirez-Ortiz <jorge.ramirez@oss.qualcomm.com>
---
drivers/ufs/Kconfig | 1 +
drivers/ufs/core/ufs-rpmb.c | 9 +++++++--
2 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/drivers/ufs/Kconfig b/drivers/ufs/Kconfig
index f662e7ce71f1..b62c00e7ff06 100644
--- a/drivers/ufs/Kconfig
+++ b/drivers/ufs/Kconfig
@@ -7,6 +7,7 @@ menuconfig SCSI_UFSHCD
tristate "Universal Flash Storage Controller"
depends on SCSI && SCSI_DMA
depends on RPMB || !RPMB
+ select CRYPTO_LIB_BLAKE2B if RPMB
select PM_DEVFREQ
select DEVFREQ_GOV_SIMPLE_ONDEMAND
select NLS
diff --git a/drivers/ufs/core/ufs-rpmb.c b/drivers/ufs/core/ufs-rpmb.c
index 79e6cd2b20a0..cb3ac23fa01a 100644
--- a/drivers/ufs/core/ufs-rpmb.c
+++ b/drivers/ufs/core/ufs-rpmb.c
@@ -10,6 +10,7 @@
* Can Guo <can.guo@oss.qualcomm.com>
*/
+#include <crypto/blake2b.h>
#include <linux/module.h>
#include <linux/device.h>
#include <linux/kernel.h>
@@ -21,6 +22,7 @@
#include <linux/unaligned.h>
#include "ufshcd-priv.h"
+#define UFS_RPMB_ID_LEN 16 /* Match eMMC CID Length */
#define UFS_RPMB_UA_RETRIES 3 /* Retries for the power-on UNIT ATTENTION */
#define UFS_RPMB_SEC_PROTOCOL 0xEC /* JEDEC UFS application */
#define UFS_RPMB_SEC_PROTOCOL_ID 0x01 /* JEDEC UFS RPMB protocol ID, CDB byte3 */
@@ -153,6 +155,7 @@ static void ufs_rpmb_device_release(struct device *dev)
int ufs_rpmb_probe(struct ufs_hba *hba)
{
struct ufs_rpmb_dev *ufs_rpmb, *it, *tmp;
+ u8 dev_id[UFS_RPMB_ID_LEN];
struct rpmb_dev *rdev;
char *cid = NULL;
int region;
@@ -213,8 +216,10 @@ int ufs_rpmb_probe(struct ufs_hba *hba)
goto err_out;
}
- descr.dev_id = cid;
- descr.dev_id_len = strlen(cid);
+ blake2b(NULL, 0, cid, strlen(cid), dev_id, UFS_RPMB_ID_LEN);
+
+ descr.dev_id = dev_id;
+ descr.dev_id_len = UFS_RPMB_ID_LEN;
descr.capacity = cap;
/* Register RPMB device */
--
2.54.0
^ permalink raw reply [flat|nested] 3+ messages in thread