* [PATCH v6 0/3] Add OP-TEE based RPMB driver for UFS devices
@ 2025-10-26 21:25 Bean Huo
2025-10-26 21:25 ` [PATCH v6 1/3] scsi: ufs: core: Convert string descriptor format macros to enum Bean Huo
` (3 more replies)
0 siblings, 4 replies; 9+ messages in thread
From: Bean Huo @ 2025-10-26 21:25 UTC (permalink / raw)
To: avri.altman, avri.altman, bvanassche, alim.akhtar, jejb,
martin.petersen, can.guo, ulf.hansson, beanhuo, jens.wiklander
Cc: linux-scsi, linux-kernel, Bean Huo
This patch series introduces OP-TEE based RPMB (Replay Protected Memory Block)
support for UFS devices, extending the kernel-level secure storage capabilities
that are currently available for eMMC devices.
Previously, OP-TEE required a userspace supplicant to access RPMB partitions,
which created complex dependencies and reliability issues, especially during
early boot scenarios. Recent work by Linaro has moved core supplicant
functionality directly into the Linux kernel for eMMC devices, eliminating
userspace dependencies and enabling immediate secure storage access. This series
extends the same approach to UFS devices, which are used in enterprise and mobile
applications that require secure storage capabilities.
Benefits:
- Eliminates dependency on userspace supplicant for UFS RPMB access
- Enables early boot secure storage access (e.g., fTPM, secure UEFI variables)
- Provides kernel-level RPMB access as soon as UFS driver is initialized
- Removes complex initramfs dependencies and boot ordering requirements
- Ensures reliable and deterministic secure storage operations
- Supports both built-in and modular fTPM configurations.
v5 -- v6:
1. Added a comment in ufshcd_create_device_id() to warn against modifying the
device ID format without understanding its impact.
v4 -- v5:
1. Added helper function ufshcd_create_device_id() to generate unique device
identifier by combining manufacturer ID, specification version, model name,
serial number (as hex), device version, and manufacture date.
2. Added device_id field to struct ufs_dev_info for storing allocated unique device
identifier string.
3. Modified UFS RPMB driver to use device_id instead of just serial_number for creating
unique RPMB device identifiers
v3 -- v4:
1. Replaced patch "scsi: ufs: core: Remove duplicate macro definitions" with
"scsi: ufs: core: Convert string descriptor format macros to enum" based on
feedback from Bart Van Assche
2. Converted SD_ASCII_STD and SD_RAW from boolean macros to enum type for
improved code readability
3. Moved ufshcd_read_string_desc() declaration from include/ufs/ufshcd.h to
drivers/ufs/core/ufshcd-priv.h since it's not exported
v2 -- v3:
1. Removed patch "rpmb: move rpmb_frame struct and constants to common header". since it
has been queued in mmc tree, and added a new patch:
"scsi: ufs: core: Remove duplicate macro definitions"
2. Incorporated suggestions from Jens
3. Added check if Advanced RPMB is enabled, if enabled we will not register UFS OP-TEE RPMB.
v1 -- v2:
1. Added fix tag for patch [2/3]
2. Incorporated feedback and suggestions from Bart
RFC v1 -- v1:
1. Added support for all UFS RPMB regions based on https://github.com/OP-TEE/optee_os/issues/7532
2. Incorporated feedback and suggestions from Bart
Bean Huo (3):
scsi: ufs: core: Convert string descriptor format macros to enum
scsi: ufs: core: fix incorrect buffer duplication in
ufshcd_read_string_desc()
scsi: ufs: core: Add OP-TEE based RPMB driver for UFS devices
drivers/misc/Kconfig | 2 +-
drivers/ufs/core/Makefile | 1 +
drivers/ufs/core/ufs-rpmb.c | 254 +++++++++++++++++++++++++++++++++
drivers/ufs/core/ufshcd-priv.h | 27 +++-
drivers/ufs/core/ufshcd.c | 96 +++++++++++--
include/ufs/ufs.h | 5 +
include/ufs/ufshcd.h | 12 +-
7 files changed, 376 insertions(+), 21 deletions(-)
create mode 100644 drivers/ufs/core/ufs-rpmb.c
--
2.34.1
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH v6 1/3] scsi: ufs: core: Convert string descriptor format macros to enum
2025-10-26 21:25 [PATCH v6 0/3] Add OP-TEE based RPMB driver for UFS devices Bean Huo
@ 2025-10-26 21:25 ` Bean Huo
2025-10-26 21:25 ` [PATCH v6 2/3] scsi: ufs: core: fix incorrect buffer duplication in ufshcd_read_string_desc() Bean Huo
` (2 subsequent siblings)
3 siblings, 0 replies; 9+ messages in thread
From: Bean Huo @ 2025-10-26 21:25 UTC (permalink / raw)
To: avri.altman, avri.altman, bvanassche, alim.akhtar, jejb,
martin.petersen, can.guo, ulf.hansson, beanhuo, jens.wiklander
Cc: linux-scsi, linux-kernel, Avri Altman
From: Bean Huo <beanhuo@micron.com>
Convert SD_ASCII_STD and SD_RAW from boolean macros to enum values for improved
code readability. This makes ufshcd_read_string_desc() calls self-documenting by
using explicit enum values instead of true/false.
Move the ufshcd_read_string_desc() declaration from include/ufs/ufshcd.h to
drivers/ufs/core/ufshcd-priv.h since this function is not exported.
Co-developed-by: Bart Van Assche <bvanassche@acm.org>
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
Suggested-by: Avri Altman <Avri.Altman@sandisk.com>
Signed-off-by: Bean Huo <beanhuo@micron.com>
---
drivers/ufs/core/ufshcd-priv.h | 14 ++++++++++----
drivers/ufs/core/ufshcd.c | 8 +++-----
include/ufs/ufshcd.h | 4 ----
3 files changed, 13 insertions(+), 13 deletions(-)
diff --git a/drivers/ufs/core/ufshcd-priv.h b/drivers/ufs/core/ufshcd-priv.h
index d0a2c963a27d..d74742a855b2 100644
--- a/drivers/ufs/core/ufshcd-priv.h
+++ b/drivers/ufs/core/ufshcd-priv.h
@@ -78,11 +78,17 @@ int ufshcd_try_to_abort_task(struct ufs_hba *hba, int tag);
void ufshcd_release_scsi_cmd(struct ufs_hba *hba,
struct ufshcd_lrb *lrbp);
-#define SD_ASCII_STD true
-#define SD_RAW false
-int ufshcd_read_string_desc(struct ufs_hba *hba, u8 desc_index,
- u8 **buf, bool ascii);
+/**
+ * enum ufs_descr_fmt - UFS string descriptor format
+ * @SD_RAW: Raw UTF-16 format
+ * @SD_ASCII_STD: Convert to null-terminated ASCII string
+ */
+enum ufs_descr_fmt {
+ SD_RAW = 0,
+ SD_ASCII_STD = 1,
+};
+int ufshcd_read_string_desc(struct ufs_hba *hba, u8 desc_index, u8 **buf, enum ufs_descr_fmt fmt);
int ufshcd_send_uic_cmd(struct ufs_hba *hba, struct uic_command *uic_cmd);
int ufshcd_send_bsg_uic_cmd(struct ufs_hba *hba, struct uic_command *uic_cmd);
diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c
index 8339fec975b9..2a653137a9ea 100644
--- a/drivers/ufs/core/ufshcd.c
+++ b/drivers/ufs/core/ufshcd.c
@@ -3773,16 +3773,14 @@ static inline char ufshcd_remove_non_printable(u8 ch)
* @desc_index: descriptor index
* @buf: pointer to buffer where descriptor would be read,
* the caller should free the memory.
- * @ascii: if true convert from unicode to ascii characters
- * null terminated string.
+ * @fmt: if %SD_ASCII_STD, convert from UTF-16 to ASCII
*
* Return:
* * string size on success.
* * -ENOMEM: on allocation failure
* * -EINVAL: on a wrong parameter
*/
-int ufshcd_read_string_desc(struct ufs_hba *hba, u8 desc_index,
- u8 **buf, bool ascii)
+int ufshcd_read_string_desc(struct ufs_hba *hba, u8 desc_index, u8 **buf, enum ufs_descr_fmt fmt)
{
struct uc_string_id *uc_str;
u8 *str;
@@ -3811,7 +3809,7 @@ int ufshcd_read_string_desc(struct ufs_hba *hba, u8 desc_index,
goto out;
}
- if (ascii) {
+ if (fmt == SD_ASCII_STD) {
ssize_t ascii_len;
int i;
/* remove header and divide by 2 to move from UTF16 to UTF8 */
diff --git a/include/ufs/ufshcd.h b/include/ufs/ufshcd.h
index 9425cfd9d00e..b4eb2fa58552 100644
--- a/include/ufs/ufshcd.h
+++ b/include/ufs/ufshcd.h
@@ -1431,10 +1431,6 @@ static inline int ufshcd_disable_host_tx_lcc(struct ufs_hba *hba)
void ufshcd_auto_hibern8_update(struct ufs_hba *hba, u32 ahit);
void ufshcd_fixup_dev_quirks(struct ufs_hba *hba,
const struct ufs_dev_quirk *fixups);
-#define SD_ASCII_STD true
-#define SD_RAW false
-int ufshcd_read_string_desc(struct ufs_hba *hba, u8 desc_index,
- u8 **buf, bool ascii);
void ufshcd_hold(struct ufs_hba *hba);
void ufshcd_release(struct ufs_hba *hba);
--
2.34.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v6 2/3] scsi: ufs: core: fix incorrect buffer duplication in ufshcd_read_string_desc()
2025-10-26 21:25 [PATCH v6 0/3] Add OP-TEE based RPMB driver for UFS devices Bean Huo
2025-10-26 21:25 ` [PATCH v6 1/3] scsi: ufs: core: Convert string descriptor format macros to enum Bean Huo
@ 2025-10-26 21:25 ` Bean Huo
2025-10-26 21:25 ` [PATCH v6 3/3] scsi: ufs: core: Add OP-TEE based RPMB driver for UFS devices Bean Huo
2025-11-06 17:29 ` [PATCH v6 0/3] " Bean Huo
3 siblings, 0 replies; 9+ messages in thread
From: Bean Huo @ 2025-10-26 21:25 UTC (permalink / raw)
To: avri.altman, avri.altman, bvanassche, alim.akhtar, jejb,
martin.petersen, can.guo, ulf.hansson, beanhuo, jens.wiklander
Cc: linux-scsi, linux-kernel
From: Bean Huo <beanhuo@micron.com>
The function ufshcd_read_string_desc() was duplicating memory starting
from the beginning of struct uc_string_id, which included the length
and type fields. As a result, the allocated buffer contained unwanted
metadata in addition to the string itself.
The correct behavior is to duplicate only the Unicode character array in
the structure. Update the code so that only the actual string content is
copied into the new buffer.
Fixes: 5f57704dbcfe ("scsi: ufs: Use kmemdup in ufshcd_read_string_desc()")
Reviewed-by: Avri Altman <avri.altman@sandisk.com>
Reviewed-by: Bart Van Assche <bvanassche@acm.org>
Signed-off-by: Bean Huo <beanhuo@micron.com>
---
drivers/ufs/core/ufshcd.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c
index 2a653137a9ea..af7f87f27630 100644
--- a/drivers/ufs/core/ufshcd.c
+++ b/drivers/ufs/core/ufshcd.c
@@ -3835,7 +3835,7 @@ int ufshcd_read_string_desc(struct ufs_hba *hba, u8 desc_index, u8 **buf, enum u
str[ret++] = '\0';
} else {
- str = kmemdup(uc_str, uc_str->len, GFP_KERNEL);
+ str = kmemdup(uc_str->uc, uc_str->len, GFP_KERNEL);
if (!str) {
ret = -ENOMEM;
goto out;
--
2.34.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v6 3/3] scsi: ufs: core: Add OP-TEE based RPMB driver for UFS devices
2025-10-26 21:25 [PATCH v6 0/3] Add OP-TEE based RPMB driver for UFS devices Bean Huo
2025-10-26 21:25 ` [PATCH v6 1/3] scsi: ufs: core: Convert string descriptor format macros to enum Bean Huo
2025-10-26 21:25 ` [PATCH v6 2/3] scsi: ufs: core: fix incorrect buffer duplication in ufshcd_read_string_desc() Bean Huo
@ 2025-10-26 21:25 ` Bean Huo
2025-10-27 3:27 ` kernel test robot
2025-10-27 14:06 ` Jens Wiklander
2025-11-06 17:29 ` [PATCH v6 0/3] " Bean Huo
3 siblings, 2 replies; 9+ messages in thread
From: Bean Huo @ 2025-10-26 21:25 UTC (permalink / raw)
To: avri.altman, avri.altman, bvanassche, alim.akhtar, jejb,
martin.petersen, can.guo, ulf.hansson, beanhuo, jens.wiklander
Cc: linux-scsi, linux-kernel
From: Bean Huo <beanhuo@micron.com>
This patch adds OP-TEE based RPMB support for UFS devices. This enables secure
RPMB operations on UFS devices through OP-TEE, providing the same functionality
available for eMMC devices and extending kernel-based secure storage support to
UFS-based systems.
Benefits of OP-TEE based RPMB implementation:
- Eliminates dependency on userspace supplicant for RPMB access
- Enables early boot secure storage access (e.g., fTPM, secure UEFI variables)
- Provides kernel-level RPMB access as soon as UFS driver is initialized
- Removes complex initramfs dependencies and boot ordering requirements
- Ensures reliable and deterministic secure storage operations
- Supports both built-in and modular fTPM configurations
Co-developed-by: Can Guo <can.guo@oss.qualcomm.com>
Signed-off-by: Can Guo <can.guo@oss.qualcomm.com>
Reviewed-by: Avri Altman <avri.altman@sandisk.com>
Reviewed-by: Bart Van Assche <bvanassche@acm.org>
Signed-off-by: Bean Huo <beanhuo@micron.com>
---
drivers/misc/Kconfig | 2 +-
drivers/ufs/core/Makefile | 1 +
drivers/ufs/core/ufs-rpmb.c | 254 +++++++++++++++++++++++++++++++++
drivers/ufs/core/ufshcd-priv.h | 13 ++
drivers/ufs/core/ufshcd.c | 86 ++++++++++-
include/ufs/ufs.h | 5 +
include/ufs/ufshcd.h | 8 +-
7 files changed, 362 insertions(+), 7 deletions(-)
create mode 100644 drivers/ufs/core/ufs-rpmb.c
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index b9c11f67315f..9d1de68dee27 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -106,7 +106,7 @@ config PHANTOM
config RPMB
tristate "RPMB partition interface"
- depends on MMC
+ depends on MMC || SCSI_UFSHCD
help
Unified RPMB unit interface for RPMB capable devices such as eMMC and
UFS. Provides interface for in-kernel security controllers to access
diff --git a/drivers/ufs/core/Makefile b/drivers/ufs/core/Makefile
index cf820fa09a04..51e1867e524e 100644
--- a/drivers/ufs/core/Makefile
+++ b/drivers/ufs/core/Makefile
@@ -2,6 +2,7 @@
obj-$(CONFIG_SCSI_UFSHCD) += ufshcd-core.o
ufshcd-core-y += ufshcd.o ufs-sysfs.o ufs-mcq.o
+ufshcd-core-$(CONFIG_RPMB) += ufs-rpmb.o
ufshcd-core-$(CONFIG_DEBUG_FS) += ufs-debugfs.o
ufshcd-core-$(CONFIG_SCSI_UFS_BSG) += ufs_bsg.o
ufshcd-core-$(CONFIG_SCSI_UFS_CRYPTO) += ufshcd-crypto.o
diff --git a/drivers/ufs/core/ufs-rpmb.c b/drivers/ufs/core/ufs-rpmb.c
new file mode 100644
index 000000000000..ffad049872b9
--- /dev/null
+++ b/drivers/ufs/core/ufs-rpmb.c
@@ -0,0 +1,254 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * UFS OP-TEE based RPMB Driver
+ *
+ * Copyright (C) 2025 Micron Technology, Inc.
+ * Copyright (C) 2025 Qualcomm Technologies, Inc.
+ *
+ * Authors:
+ * Bean Huo <beanhuo@micron.com>
+ * Can Guo <can.guo@oss.qualcomm.com>
+ */
+
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/rpmb.h>
+#include <linux/string.h>
+#include <linux/list.h>
+#include <ufs/ufshcd.h>
+#include <linux/unaligned.h>
+#include "ufshcd-priv.h"
+
+#define UFS_RPMB_SEC_PROTOCOL 0xEC /* JEDEC UFS application */
+#define UFS_RPMB_SEC_PROTOCOL_ID 0x01 /* JEDEC UFS RPMB protocol ID, CDB byte3 */
+
+static const struct bus_type ufs_rpmb_bus_type = {
+ .name = "ufs_rpmb",
+};
+
+/* UFS RPMB device structure */
+struct ufs_rpmb_dev {
+ u8 region_id;
+ struct device dev;
+ struct rpmb_dev *rdev;
+ struct ufs_hba *hba;
+ struct list_head node;
+};
+
+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;
+ u8 cdb[12] = { };
+
+ cdb[0] = send ? SECURITY_PROTOCOL_OUT : SECURITY_PROTOCOL_IN;
+ cdb[1] = UFS_RPMB_SEC_PROTOCOL;
+ put_unaligned_be16(spsp, &cdb[2]);
+ 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);
+}
+
+/* UFS RPMB route frames implementation */
+static int ufs_rpmb_route_frames(struct device *dev, u8 *req, unsigned int req_len, u8 *resp,
+ unsigned int resp_len)
+{
+ struct ufs_rpmb_dev *ufs_rpmb = dev_get_drvdata(dev);
+ struct rpmb_frame *frm_out = (struct rpmb_frame *)req;
+ bool need_result_read = true;
+ u16 req_type, protocol_id;
+ struct ufs_hba *hba;
+ int ret;
+
+ if (!ufs_rpmb) {
+ dev_err(dev, "Missing driver data\n");
+ return -ENODEV;
+ }
+
+ hba = ufs_rpmb->hba;
+
+ req_type = be16_to_cpu(frm_out->req_resp);
+
+ switch (req_type) {
+ case RPMB_PROGRAM_KEY:
+ if (req_len != sizeof(struct rpmb_frame) || resp_len != sizeof(struct rpmb_frame))
+ return -EINVAL;
+ break;
+ case RPMB_GET_WRITE_COUNTER:
+ if (req_len != sizeof(struct rpmb_frame) || resp_len != sizeof(struct rpmb_frame))
+ return -EINVAL;
+ need_result_read = false;
+ break;
+ case RPMB_WRITE_DATA:
+ if (req_len % sizeof(struct rpmb_frame) || resp_len != sizeof(struct rpmb_frame))
+ return -EINVAL;
+ break;
+ case RPMB_READ_DATA:
+ if (req_len != sizeof(struct rpmb_frame) || resp_len % sizeof(struct rpmb_frame))
+ return -EINVAL;
+ need_result_read = false;
+ break;
+ default:
+ dev_err(dev, "Unknown request type=0x%04x\n", req_type);
+ return -EINVAL;
+ }
+
+ protocol_id = ufs_rpmb->region_id << 8 | UFS_RPMB_SEC_PROTOCOL_ID;
+
+ ret = ufs_sec_submit(hba, protocol_id, req, req_len, true);
+ if (ret) {
+ dev_err(dev, "Command failed with ret=%d\n", ret);
+ return ret;
+ }
+
+ if (need_result_read) {
+ struct rpmb_frame *frm_resp = (struct rpmb_frame *)resp;
+
+ memset(frm_resp, 0, sizeof(*frm_resp));
+ frm_resp->req_resp = cpu_to_be16(RPMB_RESULT_READ);
+ ret = ufs_sec_submit(hba, protocol_id, resp, resp_len, true);
+ if (ret) {
+ dev_err(dev, "Result read request failed with ret=%d\n", ret);
+ return ret;
+ }
+ }
+
+ if (!ret) {
+ ret = ufs_sec_submit(hba, protocol_id, resp, resp_len, false);
+ if (ret)
+ dev_err(dev, "Response read failed with ret=%d\n", ret);
+ }
+
+ return ret;
+}
+
+static void ufs_rpmb_device_release(struct device *dev)
+{
+ struct ufs_rpmb_dev *ufs_rpmb = dev_get_drvdata(dev);
+
+ rpmb_dev_unregister(ufs_rpmb->rdev);
+}
+
+/* UFS RPMB device registration */
+int ufs_rpmb_probe(struct ufs_hba *hba)
+{
+ struct ufs_rpmb_dev *ufs_rpmb, *it, *tmp;
+ struct rpmb_dev *rdev;
+ char *cid = NULL;
+ int region;
+ u32 cap;
+ int ret;
+
+ if (!hba->ufs_rpmb_wlun || hba->dev_info.b_advanced_rpmb_en) {
+ dev_info(hba->dev, "Skip OP-TEE RPMB registration\n");
+ return -ENODEV;
+ }
+
+ /* Check if device_id is available */
+ if (!hba->dev_info.device_id) {
+ dev_err(hba->dev, "UFS Device ID not available\n");
+ return -EINVAL;
+ }
+
+ INIT_LIST_HEAD(&hba->rpmbs);
+
+ struct rpmb_descr descr = {
+ .type = RPMB_TYPE_UFS,
+ .route_frames = ufs_rpmb_route_frames,
+ .reliable_wr_count = hba->dev_info.rpmb_io_size,
+ };
+
+ for (region = 0; region < ARRAY_SIZE(hba->dev_info.rpmb_region_size); region++) {
+ cap = hba->dev_info.rpmb_region_size[region];
+ if (!cap)
+ continue;
+
+ ufs_rpmb = devm_kzalloc(hba->dev, sizeof(*ufs_rpmb), GFP_KERNEL);
+ if (!ufs_rpmb) {
+ ret = -ENOMEM;
+ goto err_out;
+ }
+
+ ufs_rpmb->hba = hba;
+ ufs_rpmb->dev.parent = &hba->ufs_rpmb_wlun->sdev_gendev;
+ ufs_rpmb->dev.bus = &ufs_rpmb_bus_type;
+ ufs_rpmb->dev.release = ufs_rpmb_device_release;
+ dev_set_name(&ufs_rpmb->dev, "ufs_rpmb%d", region);
+
+ /* Set driver data BEFORE device_register */
+ dev_set_drvdata(&ufs_rpmb->dev, ufs_rpmb);
+
+ ret = device_register(&ufs_rpmb->dev);
+ if (ret) {
+ dev_err(hba->dev, "Failed to register UFS RPMB device %d\n", region);
+ put_device(&ufs_rpmb->dev);
+ goto err_out;
+ }
+
+ /* Create unique ID by appending region number to device_id */
+ cid = kasprintf(GFP_KERNEL, "%s-R%d", hba->dev_info.device_id, region);
+ if (!cid) {
+ device_unregister(&ufs_rpmb->dev);
+ ret = -ENOMEM;
+ goto err_out;
+ }
+
+ descr.dev_id = cid;
+ descr.dev_id_len = strlen(cid);
+ descr.capacity = cap;
+
+ /* Register RPMB device */
+ rdev = rpmb_dev_register(&ufs_rpmb->dev, &descr);
+ if (IS_ERR(rdev)) {
+ dev_err(hba->dev, "Failed to register UFS RPMB device.\n");
+ device_unregister(&ufs_rpmb->dev);
+ ret = PTR_ERR(rdev);
+ goto err_out;
+ }
+
+ kfree(cid);
+ cid = NULL;
+
+ ufs_rpmb->rdev = rdev;
+ ufs_rpmb->region_id = region;
+
+ list_add_tail(&ufs_rpmb->node, &hba->rpmbs);
+
+ dev_info(hba->dev, "UFS RPMB region %d registered (capacity=%u)\n", region, cap);
+ }
+
+ return 0;
+err_out:
+ kfree(cid);
+ list_for_each_entry_safe(it, tmp, &hba->rpmbs, node) {
+ list_del(&it->node);
+ device_unregister(&it->dev);
+ }
+
+ return ret;
+}
+
+/* UFS RPMB remove handler */
+void ufs_rpmb_remove(struct ufs_hba *hba)
+{
+ struct ufs_rpmb_dev *ufs_rpmb, *tmp;
+
+ if (list_empty(&hba->rpmbs))
+ return;
+
+ /* Remove all registered RPMB devices */
+ list_for_each_entry_safe(ufs_rpmb, tmp, &hba->rpmbs, node) {
+ dev_info(hba->dev, "Removing UFS RPMB region %d\n", ufs_rpmb->region_id);
+ /* Remove from list first */
+ list_del(&ufs_rpmb->node);
+ /* Unregister device */
+ device_unregister(&ufs_rpmb->dev);
+ }
+
+ dev_info(hba->dev, "All UFS RPMB devices unregistered\n");
+}
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("OP-TEE UFS RPMB driver");
diff --git a/drivers/ufs/core/ufshcd-priv.h b/drivers/ufs/core/ufshcd-priv.h
index d74742a855b2..e63b0e9075e0 100644
--- a/drivers/ufs/core/ufshcd-priv.h
+++ b/drivers/ufs/core/ufshcd-priv.h
@@ -417,4 +417,17 @@ static inline u32 ufshcd_mcq_get_sq_head_slot(struct ufs_hw_queue *q)
return val / sizeof(struct utp_transfer_req_desc);
}
+#ifdef CONFIG_RPMB
+int ufs_rpmb_probe(struct ufs_hba *hba);
+void ufs_rpmb_remove(struct ufs_hba *hba);
+#else
+static inline int ufs_rpmb_probe(struct ufs_hba *hba)
+{
+ return 0;
+}
+static inline void ufs_rpmb_remove(struct ufs_hba *hba)
+{
+}
+#endif
+
#endif /* _UFSHCD_PRIV_H_ */
diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c
index af7f87f27630..1a402b1ae37f 100644
--- a/drivers/ufs/core/ufshcd.c
+++ b/drivers/ufs/core/ufshcd.c
@@ -5254,10 +5254,15 @@ static void ufshcd_lu_init(struct ufs_hba *hba, struct scsi_device *sdev)
desc_buf[UNIT_DESC_PARAM_LU_WR_PROTECT] == UFS_LU_POWER_ON_WP)
hba->dev_info.is_lu_power_on_wp = true;
- /* In case of RPMB LU, check if advanced RPMB mode is enabled */
- if (desc_buf[UNIT_DESC_PARAM_UNIT_INDEX] == UFS_UPIU_RPMB_WLUN &&
- desc_buf[RPMB_UNIT_DESC_PARAM_REGION_EN] & BIT(4))
- hba->dev_info.b_advanced_rpmb_en = true;
+ /* In case of RPMB LU, check if advanced RPMB mode is enabled, and get region size */
+ if (desc_buf[UNIT_DESC_PARAM_UNIT_INDEX] == UFS_UPIU_RPMB_WLUN) {
+ if (desc_buf[RPMB_UNIT_DESC_PARAM_REGION_EN] & BIT(4))
+ hba->dev_info.b_advanced_rpmb_en = true;
+ hba->dev_info.rpmb_region_size[0] = desc_buf[RPMB_UNIT_DESC_PARAM_REGION0_SIZE];
+ hba->dev_info.rpmb_region_size[1] = desc_buf[RPMB_UNIT_DESC_PARAM_REGION1_SIZE];
+ hba->dev_info.rpmb_region_size[2] = desc_buf[RPMB_UNIT_DESC_PARAM_REGION2_SIZE];
+ hba->dev_info.rpmb_region_size[3] = desc_buf[RPMB_UNIT_DESC_PARAM_REGION3_SIZE];
+ }
kfree(desc_buf);
@@ -8187,8 +8192,11 @@ static int ufshcd_scsi_add_wlus(struct ufs_hba *hba)
ufshcd_upiu_wlun_to_scsi_wlun(UFS_UPIU_RPMB_WLUN), NULL);
if (IS_ERR(sdev_rpmb)) {
ret = PTR_ERR(sdev_rpmb);
+ hba->ufs_rpmb_wlun = NULL;
+ dev_err(hba->dev, "%s: RPMB WLUN not found\n", __func__);
goto remove_ufs_device_wlun;
}
+ hba->ufs_rpmb_wlun = sdev_rpmb;
ufshcd_blk_pm_runtime_init(sdev_rpmb);
scsi_device_put(sdev_rpmb);
@@ -8456,6 +8464,67 @@ static void ufs_init_rtc(struct ufs_hba *hba, u8 *desc_buf)
dev_info->rtc_update_period = 0;
}
+/**
+ * ufshcd_create_device_id - Generate unique device identifier string
+ * @hba: per-adapter instance
+ * @desc_buf: device descriptor buffer
+ *
+ * Creates a unique device ID string combining manufacturer ID, spec version,
+ * model name, serial number (as hex), device version, and manufacture date.
+ *
+ * Returns: Allocated device ID string on success, NULL on failure
+ */
+static char *ufshcd_create_device_id(struct ufs_hba *hba, u8 *desc_buf)
+{
+ struct ufs_dev_info *dev_info = &hba->dev_info;
+ u16 manufacture_date;
+ u16 device_version;
+ u8 *serial_number;
+ char *serial_hex;
+ char *device_id;
+ u8 serial_index;
+ int serial_len;
+ int ret;
+
+ serial_index = desc_buf[DEVICE_DESC_PARAM_SN];
+
+ ret = ufshcd_read_string_desc(hba, serial_index, &serial_number, SD_RAW);
+ if (ret < 0) {
+ dev_err(hba->dev, "Failed reading Serial Number. err = %d\n", ret);
+ return NULL;
+ }
+
+ device_version = get_unaligned_be16(&desc_buf[DEVICE_DESC_PARAM_DEV_VER]);
+ manufacture_date = get_unaligned_be16(&desc_buf[DEVICE_DESC_PARAM_MANF_DATE]);
+
+ serial_len = ret;
+ /* Allocate buffer for hex string: 2 chars per byte + null terminator */
+ serial_hex = kzalloc(serial_len * 2 + 1, GFP_KERNEL);
+ if (!serial_hex) {
+ kfree(serial_number);
+ return NULL;
+ }
+
+ bin2hex(serial_hex, serial_number, serial_len);
+
+ /*
+ * Device ID format is ABI with secure world - do not change without firmware
+ * coordination.
+ */
+ device_id = kasprintf(GFP_KERNEL, "%04X-%04X-%s-%s-%04X-%04X",
+ dev_info->wmanufacturerid, dev_info->wspecversion,
+ dev_info->model, serial_hex, device_version,
+ manufacture_date);
+
+ kfree(serial_hex);
+ kfree(serial_number);
+
+ if (!device_id)
+ dev_warn(hba->dev, "Failed to allocate unique device ID\n");
+
+ return device_id;
+}
+
static int ufs_get_device_desc(struct ufs_hba *hba)
{
int err;
@@ -8507,6 +8576,9 @@ static int ufs_get_device_desc(struct ufs_hba *hba)
goto out;
}
+ /* Generate unique device ID */
+ dev_info->device_id = ufshcd_create_device_id(hba, desc_buf);
+
hba->luns_avail = desc_buf[DEVICE_DESC_PARAM_NUM_LU] +
desc_buf[DEVICE_DESC_PARAM_NUM_WLU];
@@ -8542,6 +8614,8 @@ static void ufs_put_device_desc(struct ufs_hba *hba)
kfree(dev_info->model);
dev_info->model = NULL;
+ kfree(dev_info->device_id);
+ dev_info->device_id = NULL;
}
/**
@@ -8685,6 +8759,8 @@ static int ufshcd_device_geo_params_init(struct ufs_hba *hba)
else if (desc_buf[GEOMETRY_DESC_PARAM_MAX_NUM_LUN] == 0)
hba->dev_info.max_lu_supported = 8;
+ hba->dev_info.rpmb_io_size = desc_buf[GEOMETRY_DESC_PARAM_RPMB_RW_SIZE];
+
out:
kfree(desc_buf);
return err;
@@ -8871,6 +8947,7 @@ static int ufshcd_add_lus(struct ufs_hba *hba)
ufs_bsg_probe(hba);
scsi_scan_host(hba->host);
+ ufs_rpmb_probe(hba);
out:
return ret;
@@ -10425,6 +10502,7 @@ void ufshcd_remove(struct ufs_hba *hba)
ufshcd_rpm_get_sync(hba);
ufs_hwmon_remove(hba);
ufs_bsg_remove(hba);
+ ufs_rpmb_remove(hba);
ufs_sysfs_remove_nodes(hba->dev);
cancel_delayed_work_sync(&hba->ufs_rtc_update_work);
blk_mq_destroy_queue(hba->tmf_queue);
diff --git a/include/ufs/ufs.h b/include/ufs/ufs.h
index 245a6a829ce9..ab8f6c07b5a2 100644
--- a/include/ufs/ufs.h
+++ b/include/ufs/ufs.h
@@ -651,6 +651,11 @@ struct ufs_dev_info {
u8 rtt_cap; /* bDeviceRTTCap */
bool hid_sup;
+
+ /* Unique device ID string (manufacturer+model+serial+version+date) */
+ char *device_id;
+ u8 rpmb_io_size;
+ u8 rpmb_region_size[4];
};
#endif /* End of Header */
diff --git a/include/ufs/ufshcd.h b/include/ufs/ufshcd.h
index b4eb2fa58552..959d42d9b1c8 100644
--- a/include/ufs/ufshcd.h
+++ b/include/ufs/ufshcd.h
@@ -826,6 +826,7 @@ enum ufshcd_mcq_opr {
* @host: Scsi_Host instance of the driver
* @dev: device handle
* @ufs_device_wlun: WLUN that controls the entire UFS device.
+ * @ufs_rpmb_wlun: RPMB WLUN SCSI device
* @hwmon_device: device instance registered with the hwmon core.
* @curr_dev_pwr_mode: active UFS device power mode.
* @uic_link_state: active state of the link to the UFS device.
@@ -941,8 +942,8 @@ enum ufshcd_mcq_opr {
* @pm_qos_mutex: synchronizes PM QoS request and status updates
* @critical_health_count: count of critical health exceptions
* @dev_lvl_exception_count: count of device level exceptions since last reset
- * @dev_lvl_exception_id: vendor specific information about the
- * device level exception event.
+ * @dev_lvl_exception_id: vendor specific information about the device level exception event.
+ * @rpmbs: list of OP-TEE RPMB devices (one per RPMB region)
*/
struct ufs_hba {
void __iomem *mmio_base;
@@ -960,6 +961,7 @@ struct ufs_hba {
struct Scsi_Host *host;
struct device *dev;
struct scsi_device *ufs_device_wlun;
+ struct scsi_device *ufs_rpmb_wlun;
#ifdef CONFIG_SCSI_UFS_HWMON
struct device *hwmon_device;
@@ -1117,6 +1119,8 @@ struct ufs_hba {
int critical_health_count;
atomic_t dev_lvl_exception_count;
u64 dev_lvl_exception_id;
+
+ struct list_head rpmbs;
};
/**
--
2.34.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH v6 3/3] scsi: ufs: core: Add OP-TEE based RPMB driver for UFS devices
2025-10-26 21:25 ` [PATCH v6 3/3] scsi: ufs: core: Add OP-TEE based RPMB driver for UFS devices Bean Huo
@ 2025-10-27 3:27 ` kernel test robot
2025-10-27 10:08 ` Bean Huo
2025-10-27 14:06 ` Jens Wiklander
1 sibling, 1 reply; 9+ messages in thread
From: kernel test robot @ 2025-10-27 3:27 UTC (permalink / raw)
To: Bean Huo, avri.altman, avri.altman, bvanassche, alim.akhtar, jejb,
martin.petersen, can.guo, ulf.hansson, beanhuo, jens.wiklander
Cc: oe-kbuild-all, linux-scsi, linux-kernel
Hi Bean,
kernel test robot noticed the following build errors:
[auto build test ERROR on jejb-scsi/for-next]
[also build test ERROR on char-misc/char-misc-testing char-misc/char-misc-next char-misc/char-misc-linus linus/master v6.18-rc3]
[cannot apply to mkp-scsi/for-next next-20251024]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Bean-Huo/scsi-ufs-core-Convert-string-descriptor-format-macros-to-enum/20251027-053339
base: https://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi.git for-next
patch link: https://lore.kernel.org/r/20251026212506.4136610-4-beanhuo%40iokpp.de
patch subject: [PATCH v6 3/3] scsi: ufs: core: Add OP-TEE based RPMB driver for UFS devices
config: x86_64-buildonly-randconfig-001-20251027 (https://download.01.org/0day-ci/archive/20251027/202510271043.ptLcyAfD-lkp@intel.com/config)
compiler: gcc-14 (Debian 14.2.0-19) 14.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20251027/202510271043.ptLcyAfD-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202510271043.ptLcyAfD-lkp@intel.com/
All errors (new ones prefixed by >>):
from include/asm-generic/qrwlock_types.h:6,
from arch/x86/include/asm/spinlock_types.h:7,
from include/linux/spinlock_types_raw.h:7,
from include/linux/ratelimit_types.h:7,
from include/linux/printk.h:9,
from include/asm-generic/bug.h:22,
from arch/x86/include/asm/bug.h:108,
from arch/x86/include/asm/alternative.h:9,
from arch/x86/include/asm/barrier.h:5,
from include/linux/list.h:11,
from include/linux/module.h:12,
from drivers/ufs/core/ufs-rpmb.c:13:
drivers/ufs/core/ufs-rpmb.c: In function 'ufs_rpmb_route_frames':
drivers/ufs/core/ufs-rpmb.c:72:39: error: invalid use of undefined type 'struct rpmb_frame'
72 | req_type = be16_to_cpu(frm_out->req_resp);
| ^~
include/uapi/linux/swab.h:102:54: note: in definition of macro '__swab16'
102 | #define __swab16(x) (__u16)__builtin_bswap16((__u16)(x))
| ^
include/linux/byteorder/generic.h:97:21: note: in expansion of macro '__be16_to_cpu'
97 | #define be16_to_cpu __be16_to_cpu
| ^~~~~~~~~~~~~
drivers/ufs/core/ufs-rpmb.c:72:20: note: in expansion of macro 'be16_to_cpu'
72 | req_type = be16_to_cpu(frm_out->req_resp);
| ^~~~~~~~~~~
drivers/ufs/core/ufs-rpmb.c:75:14: error: 'RPMB_PROGRAM_KEY' undeclared (first use in this function)
75 | case RPMB_PROGRAM_KEY:
| ^~~~~~~~~~~~~~~~
drivers/ufs/core/ufs-rpmb.c:75:14: note: each undeclared identifier is reported only once for each function it appears in
drivers/ufs/core/ufs-rpmb.c:76:39: error: invalid application of 'sizeof' to incomplete type 'struct rpmb_frame'
76 | if (req_len != sizeof(struct rpmb_frame) || resp_len != sizeof(struct rpmb_frame))
| ^~~~~~
drivers/ufs/core/ufs-rpmb.c:76:80: error: invalid application of 'sizeof' to incomplete type 'struct rpmb_frame'
76 | if (req_len != sizeof(struct rpmb_frame) || resp_len != sizeof(struct rpmb_frame))
| ^~~~~~
drivers/ufs/core/ufs-rpmb.c:79:14: error: 'RPMB_GET_WRITE_COUNTER' undeclared (first use in this function)
79 | case RPMB_GET_WRITE_COUNTER:
| ^~~~~~~~~~~~~~~~~~~~~~
drivers/ufs/core/ufs-rpmb.c:80:39: error: invalid application of 'sizeof' to incomplete type 'struct rpmb_frame'
80 | if (req_len != sizeof(struct rpmb_frame) || resp_len != sizeof(struct rpmb_frame))
| ^~~~~~
drivers/ufs/core/ufs-rpmb.c:80:80: error: invalid application of 'sizeof' to incomplete type 'struct rpmb_frame'
80 | if (req_len != sizeof(struct rpmb_frame) || resp_len != sizeof(struct rpmb_frame))
| ^~~~~~
drivers/ufs/core/ufs-rpmb.c:84:14: error: 'RPMB_WRITE_DATA' undeclared (first use in this function)
84 | case RPMB_WRITE_DATA:
| ^~~~~~~~~~~~~~~
drivers/ufs/core/ufs-rpmb.c:85:38: error: invalid application of 'sizeof' to incomplete type 'struct rpmb_frame'
85 | if (req_len % sizeof(struct rpmb_frame) || resp_len != sizeof(struct rpmb_frame))
| ^~~~~~
drivers/ufs/core/ufs-rpmb.c:85:79: error: invalid application of 'sizeof' to incomplete type 'struct rpmb_frame'
85 | if (req_len % sizeof(struct rpmb_frame) || resp_len != sizeof(struct rpmb_frame))
| ^~~~~~
drivers/ufs/core/ufs-rpmb.c:88:14: error: 'RPMB_READ_DATA' undeclared (first use in this function); did you mean 'D_REAL_DATA'?
88 | case RPMB_READ_DATA:
| ^~~~~~~~~~~~~~
| D_REAL_DATA
drivers/ufs/core/ufs-rpmb.c:89:39: error: invalid application of 'sizeof' to incomplete type 'struct rpmb_frame'
89 | if (req_len != sizeof(struct rpmb_frame) || resp_len % sizeof(struct rpmb_frame))
| ^~~~~~
drivers/ufs/core/ufs-rpmb.c:89:79: error: invalid application of 'sizeof' to incomplete type 'struct rpmb_frame'
89 | if (req_len != sizeof(struct rpmb_frame) || resp_len % sizeof(struct rpmb_frame))
| ^~~~~~
In file included from include/linux/string.h:382,
from include/linux/bitmap.h:13,
from include/linux/cpumask.h:12,
from arch/x86/include/asm/cpumask.h:5,
from arch/x86/include/asm/msr.h:11,
from arch/x86/include/asm/tsc.h:11,
from arch/x86/include/asm/timex.h:6,
from include/linux/timex.h:67,
from include/linux/time32.h:13,
from include/linux/time.h:60,
from include/linux/stat.h:19,
from include/linux/module.h:13:
drivers/ufs/core/ufs-rpmb.c:109:43: error: invalid application of 'sizeof' to incomplete type 'struct rpmb_frame'
109 | memset(frm_resp, 0, sizeof(*frm_resp));
| ^
include/linux/fortify-string.h:502:42: note: in definition of macro '__fortify_memset_chk'
502 | size_t __fortify_size = (size_t)(size); \
| ^~~~
drivers/ufs/core/ufs-rpmb.c:109:17: note: in expansion of macro 'memset'
109 | memset(frm_resp, 0, sizeof(*frm_resp));
| ^~~~~~
drivers/ufs/core/ufs-rpmb.c:110:25: error: invalid use of undefined type 'struct rpmb_frame'
110 | frm_resp->req_resp = cpu_to_be16(RPMB_RESULT_READ);
| ^~
drivers/ufs/core/ufs-rpmb.c:110:50: error: 'RPMB_RESULT_READ' undeclared (first use in this function)
110 | frm_resp->req_resp = cpu_to_be16(RPMB_RESULT_READ);
| ^~~~~~~~~~~~~~~~
include/uapi/linux/swab.h:102:54: note: in definition of macro '__swab16'
102 | #define __swab16(x) (__u16)__builtin_bswap16((__u16)(x))
| ^
include/linux/byteorder/generic.h:96:21: note: in expansion of macro '__cpu_to_be16'
96 | #define cpu_to_be16 __cpu_to_be16
| ^~~~~~~~~~~~~
drivers/ufs/core/ufs-rpmb.c:110:38: note: in expansion of macro 'cpu_to_be16'
110 | frm_resp->req_resp = cpu_to_be16(RPMB_RESULT_READ);
| ^~~~~~~~~~~
drivers/ufs/core/ufs-rpmb.c: At top level:
>> drivers/ufs/core/ufs-rpmb.c:135:5: error: redefinition of 'ufs_rpmb_probe'
135 | int ufs_rpmb_probe(struct ufs_hba *hba)
| ^~~~~~~~~~~~~~
In file included from drivers/ufs/core/ufs-rpmb.c:22:
drivers/ufs/core/ufshcd-priv.h:424:19: note: previous definition of 'ufs_rpmb_probe' with type 'int(struct ufs_hba *)'
424 | static inline int ufs_rpmb_probe(struct ufs_hba *hba)
| ^~~~~~~~~~~~~~
>> drivers/ufs/core/ufs-rpmb.c:234:6: error: redefinition of 'ufs_rpmb_remove'
234 | void ufs_rpmb_remove(struct ufs_hba *hba)
| ^~~~~~~~~~~~~~~
drivers/ufs/core/ufshcd-priv.h:428:20: note: previous definition of 'ufs_rpmb_remove' with type 'void(struct ufs_hba *)'
428 | static inline void ufs_rpmb_remove(struct ufs_hba *hba)
| ^~~~~~~~~~~~~~~
Kconfig warnings: (for reference only)
WARNING: unmet direct dependencies detected for OF_GPIO
Depends on [n]: GPIOLIB [=y] && OF [=n] && HAS_IOMEM [=y]
Selected by [y]:
- GPIO_TB10X [=y] && GPIOLIB [=y] && HAS_IOMEM [=y] && (ARC_PLAT_TB10X || COMPILE_TEST [=y])
WARNING: unmet direct dependencies detected for GPIO_SYSCON
Depends on [n]: GPIOLIB [=y] && HAS_IOMEM [=y] && MFD_SYSCON [=y] && OF [=n]
Selected by [y]:
- GPIO_SAMA5D2_PIOBU [=y] && GPIOLIB [=y] && HAS_IOMEM [=y] && MFD_SYSCON [=y] && OF_GPIO [=y] && (ARCH_AT91 || COMPILE_TEST [=y])
WARNING: unmet direct dependencies detected for I2C_K1
Depends on [n]: I2C [=y] && HAS_IOMEM [=y] && (ARCH_SPACEMIT || COMPILE_TEST [=y]) && OF [=n]
Selected by [m]:
- MFD_SPACEMIT_P1 [=m] && HAS_IOMEM [=y] && (ARCH_SPACEMIT || COMPILE_TEST [=y]) && I2C [=y]
vim +/ufs_rpmb_probe +135 drivers/ufs/core/ufs-rpmb.c
133
134 /* UFS RPMB device registration */
> 135 int ufs_rpmb_probe(struct ufs_hba *hba)
136 {
137 struct ufs_rpmb_dev *ufs_rpmb, *it, *tmp;
138 struct rpmb_dev *rdev;
139 char *cid = NULL;
140 int region;
141 u32 cap;
142 int ret;
143
144 if (!hba->ufs_rpmb_wlun || hba->dev_info.b_advanced_rpmb_en) {
145 dev_info(hba->dev, "Skip OP-TEE RPMB registration\n");
146 return -ENODEV;
147 }
148
149 /* Check if device_id is available */
150 if (!hba->dev_info.device_id) {
151 dev_err(hba->dev, "UFS Device ID not available\n");
152 return -EINVAL;
153 }
154
155 INIT_LIST_HEAD(&hba->rpmbs);
156
157 struct rpmb_descr descr = {
158 .type = RPMB_TYPE_UFS,
159 .route_frames = ufs_rpmb_route_frames,
160 .reliable_wr_count = hba->dev_info.rpmb_io_size,
161 };
162
163 for (region = 0; region < ARRAY_SIZE(hba->dev_info.rpmb_region_size); region++) {
164 cap = hba->dev_info.rpmb_region_size[region];
165 if (!cap)
166 continue;
167
168 ufs_rpmb = devm_kzalloc(hba->dev, sizeof(*ufs_rpmb), GFP_KERNEL);
169 if (!ufs_rpmb) {
170 ret = -ENOMEM;
171 goto err_out;
172 }
173
174 ufs_rpmb->hba = hba;
175 ufs_rpmb->dev.parent = &hba->ufs_rpmb_wlun->sdev_gendev;
176 ufs_rpmb->dev.bus = &ufs_rpmb_bus_type;
177 ufs_rpmb->dev.release = ufs_rpmb_device_release;
178 dev_set_name(&ufs_rpmb->dev, "ufs_rpmb%d", region);
179
180 /* Set driver data BEFORE device_register */
181 dev_set_drvdata(&ufs_rpmb->dev, ufs_rpmb);
182
183 ret = device_register(&ufs_rpmb->dev);
184 if (ret) {
185 dev_err(hba->dev, "Failed to register UFS RPMB device %d\n", region);
186 put_device(&ufs_rpmb->dev);
187 goto err_out;
188 }
189
190 /* Create unique ID by appending region number to device_id */
191 cid = kasprintf(GFP_KERNEL, "%s-R%d", hba->dev_info.device_id, region);
192 if (!cid) {
193 device_unregister(&ufs_rpmb->dev);
194 ret = -ENOMEM;
195 goto err_out;
196 }
197
198 descr.dev_id = cid;
199 descr.dev_id_len = strlen(cid);
200 descr.capacity = cap;
201
202 /* Register RPMB device */
203 rdev = rpmb_dev_register(&ufs_rpmb->dev, &descr);
204 if (IS_ERR(rdev)) {
205 dev_err(hba->dev, "Failed to register UFS RPMB device.\n");
206 device_unregister(&ufs_rpmb->dev);
207 ret = PTR_ERR(rdev);
208 goto err_out;
209 }
210
211 kfree(cid);
212 cid = NULL;
213
214 ufs_rpmb->rdev = rdev;
215 ufs_rpmb->region_id = region;
216
217 list_add_tail(&ufs_rpmb->node, &hba->rpmbs);
218
219 dev_info(hba->dev, "UFS RPMB region %d registered (capacity=%u)\n", region, cap);
220 }
221
222 return 0;
223 err_out:
224 kfree(cid);
225 list_for_each_entry_safe(it, tmp, &hba->rpmbs, node) {
226 list_del(&it->node);
227 device_unregister(&it->dev);
228 }
229
230 return ret;
231 }
232
233 /* UFS RPMB remove handler */
> 234 void ufs_rpmb_remove(struct ufs_hba *hba)
235 {
236 struct ufs_rpmb_dev *ufs_rpmb, *tmp;
237
238 if (list_empty(&hba->rpmbs))
239 return;
240
241 /* Remove all registered RPMB devices */
242 list_for_each_entry_safe(ufs_rpmb, tmp, &hba->rpmbs, node) {
243 dev_info(hba->dev, "Removing UFS RPMB region %d\n", ufs_rpmb->region_id);
244 /* Remove from list first */
245 list_del(&ufs_rpmb->node);
246 /* Unregister device */
247 device_unregister(&ufs_rpmb->dev);
248 }
249
250 dev_info(hba->dev, "All UFS RPMB devices unregistered\n");
251 }
252
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v6 3/3] scsi: ufs: core: Add OP-TEE based RPMB driver for UFS devices
2025-10-27 3:27 ` kernel test robot
@ 2025-10-27 10:08 ` Bean Huo
0 siblings, 0 replies; 9+ messages in thread
From: Bean Huo @ 2025-10-27 10:08 UTC (permalink / raw)
To: kernel test robot, avri.altman, avri.altman, bvanassche,
alim.akhtar, jejb, martin.petersen, can.guo, ulf.hansson, beanhuo,
jens.wiklander
Cc: oe-kbuild-all, linux-scsi, linux-kernel
hallo,
Dependency patch has been merged into:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=7e8242405b94ceac6db820de7d4fd9318cbc1219,
Kind regards,
Bean
On Mon, 2025-10-27 at 11:27 +0800, kernel test robot wrote:
> Hi Bean,
>
> kernel test robot noticed the following build errors:
>
> [auto build test ERROR on jejb-scsi/for-next]
> [also build test ERROR on char-misc/char-misc-testing char-misc/char-misc-next
> char-misc/char-misc-linus linus/master v6.18-rc3]
> [cannot apply to mkp-scsi/for-next next-20251024]
> [If your patch is applied to the wrong git tree, kindly drop us a note.
> And when submitting patch, we suggest to use '--base' as documented in
> https://git-scm.com/docs/git-format-patch#_base_tree_information]
>
> url:
> https://github.com/intel-lab-lkp/linux/commits/Bean-Huo/scsi-ufs-core-Convert-string-descriptor-format-macros-to-enum/20251027-053339
> base: https://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi.git for-next
> patch link:
> https://lore.kernel.org/r/20251026212506.4136610-4-beanhuo%40iokpp.de
> patch subject: [PATCH v6 3/3] scsi: ufs: core: Add OP-TEE based RPMB driver
> for UFS devices
> config: x86_64-buildonly-randconfig-001-20251027
> (https://download.01.org/0day-ci/archive/20251027/202510271043.ptLcyAfD-lkp@in
> tel.com/config)
> compiler: gcc-14 (Debian 14.2.0-19) 14.2.0
> reproduce (this is a W=1 build):
> (https://download.01.org/0day-ci/archive/20251027/202510271043.ptLcyAfD-lkp@in
> tel.com/reproduce)
>
> If you fix the issue in a separate patch/commit (i.e. not just a new version
> of
> the same patch/commit), kindly add following tags
> > Reported-by: kernel test robot <lkp@intel.com>
> > Closes:
> > https://lore.kernel.org/oe-kbuild-all/202510271043.ptLcyAfD-lkp@intel.com/
>
> All errors (new ones prefixed by >>):
>
> from include/asm-generic/qrwlock_types.h:6,
> from arch/x86/include/asm/spinlock_types.h:7,
> from include/linux/spinlock_types_raw.h:7,
> from include/linux/ratelimit_types.h:7,
> from include/linux/printk.h:9,
> from include/asm-generic/bug.h:22,
> from arch/x86/include/asm/bug.h:108,
> from arch/x86/include/asm/alternative.h:9,
> from arch/x86/include/asm/barrier.h:5,
> from include/linux/list.h:11,
> from include/linux/module.h:12,
> from drivers/ufs/core/ufs-rpmb.c:13:
> drivers/ufs/core/ufs-rpmb.c: In function 'ufs_rpmb_route_frames':
> drivers/ufs/core/ufs-rpmb.c:72:39: error: invalid use of undefined type
> 'struct rpmb_frame'
> 72 | req_type = be16_to_cpu(frm_out->req_resp);
> | ^~
> include/uapi/linux/swab.h:102:54: note: in definition of macro '__swab16'
> 102 | #define __swab16(x) (__u16)__builtin_bswap16((__u16)(x))
> | ^
> include/linux/byteorder/generic.h:97:21: note: in expansion of macro
> '__be16_to_cpu'
> 97 | #define be16_to_cpu __be16_to_cpu
> | ^~~~~~~~~~~~~
> drivers/ufs/core/ufs-rpmb.c:72:20: note: in expansion of macro
> 'be16_to_cpu'
> 72 | req_type = be16_to_cpu(frm_out->req_resp);
> | ^~~~~~~~~~~
> drivers/ufs/core/ufs-rpmb.c:75:14: error: 'RPMB_PROGRAM_KEY' undeclared
> (first use in this function)
> 75 | case RPMB_PROGRAM_KEY:
> | ^~~~~~~~~~~~~~~~
> drivers/ufs/core/ufs-rpmb.c:75:14: note: each undeclared identifier is
> reported only once for each function it appears in
> drivers/ufs/core/ufs-rpmb.c:76:39: error: invalid application of 'sizeof'
> to incomplete type 'struct rpmb_frame'
> 76 | if (req_len != sizeof(struct rpmb_frame) ||
> resp_len != sizeof(struct rpmb_frame))
> | ^~~~~~
> drivers/ufs/core/ufs-rpmb.c:76:80: error: invalid application of 'sizeof'
> to incomplete type 'struct rpmb_frame'
> 76 | if (req_len != sizeof(struct rpmb_frame) ||
> resp_len != sizeof(struct rpmb_frame))
>
> |
> ^~~~~~
> drivers/ufs/core/ufs-rpmb.c:79:14: error: 'RPMB_GET_WRITE_COUNTER'
> undeclared (first use in this function)
> 79 | case RPMB_GET_WRITE_COUNTER:
> | ^~~~~~~~~~~~~~~~~~~~~~
> drivers/ufs/core/ufs-rpmb.c:80:39: error: invalid application of 'sizeof'
> to incomplete type 'struct rpmb_frame'
> 80 | if (req_len != sizeof(struct rpmb_frame) ||
> resp_len != sizeof(struct rpmb_frame))
> | ^~~~~~
> drivers/ufs/core/ufs-rpmb.c:80:80: error: invalid application of 'sizeof'
> to incomplete type 'struct rpmb_frame'
> 80 | if (req_len != sizeof(struct rpmb_frame) ||
> resp_len != sizeof(struct rpmb_frame))
>
> |
> ^~~~~~
> drivers/ufs/core/ufs-rpmb.c:84:14: error: 'RPMB_WRITE_DATA' undeclared
> (first use in this function)
> 84 | case RPMB_WRITE_DATA:
> | ^~~~~~~~~~~~~~~
> drivers/ufs/core/ufs-rpmb.c:85:38: error: invalid application of 'sizeof'
> to incomplete type 'struct rpmb_frame'
> 85 | if (req_len % sizeof(struct rpmb_frame) || resp_len
> != sizeof(struct rpmb_frame))
> | ^~~~~~
> drivers/ufs/core/ufs-rpmb.c:85:79: error: invalid application of 'sizeof'
> to incomplete type 'struct rpmb_frame'
> 85 | if (req_len % sizeof(struct rpmb_frame) || resp_len
> != sizeof(struct rpmb_frame))
>
> |
> ^~~~~~
> drivers/ufs/core/ufs-rpmb.c:88:14: error: 'RPMB_READ_DATA' undeclared
> (first use in this function); did you mean 'D_REAL_DATA'?
> 88 | case RPMB_READ_DATA:
> | ^~~~~~~~~~~~~~
> | D_REAL_DATA
> drivers/ufs/core/ufs-rpmb.c:89:39: error: invalid application of 'sizeof'
> to incomplete type 'struct rpmb_frame'
> 89 | if (req_len != sizeof(struct rpmb_frame) ||
> resp_len % sizeof(struct rpmb_frame))
> | ^~~~~~
> drivers/ufs/core/ufs-rpmb.c:89:79: error: invalid application of 'sizeof'
> to incomplete type 'struct rpmb_frame'
> 89 | if (req_len != sizeof(struct rpmb_frame) ||
> resp_len % sizeof(struct rpmb_frame))
>
> |
> ^~~~~~
> In file included from include/linux/string.h:382,
> from include/linux/bitmap.h:13,
> from include/linux/cpumask.h:12,
> from arch/x86/include/asm/cpumask.h:5,
> from arch/x86/include/asm/msr.h:11,
> from arch/x86/include/asm/tsc.h:11,
> from arch/x86/include/asm/timex.h:6,
> from include/linux/timex.h:67,
> from include/linux/time32.h:13,
> from include/linux/time.h:60,
> from include/linux/stat.h:19,
> from include/linux/module.h:13:
> drivers/ufs/core/ufs-rpmb.c:109:43: error: invalid application of 'sizeof'
> to incomplete type 'struct rpmb_frame'
> 109 | memset(frm_resp, 0, sizeof(*frm_resp));
> | ^
> include/linux/fortify-string.h:502:42: note: in definition of macro
> '__fortify_memset_chk'
> 502 | size_t __fortify_size =
> (size_t)(size); \
> | ^~~~
> drivers/ufs/core/ufs-rpmb.c:109:17: note: in expansion of macro 'memset'
> 109 | memset(frm_resp, 0, sizeof(*frm_resp));
> | ^~~~~~
> drivers/ufs/core/ufs-rpmb.c:110:25: error: invalid use of undefined type
> 'struct rpmb_frame'
> 110 | frm_resp->req_resp = cpu_to_be16(RPMB_RESULT_READ);
> | ^~
> drivers/ufs/core/ufs-rpmb.c:110:50: error: 'RPMB_RESULT_READ' undeclared
> (first use in this function)
> 110 | frm_resp->req_resp = cpu_to_be16(RPMB_RESULT_READ);
> | ^~~~~~~~~~~~~~~~
> include/uapi/linux/swab.h:102:54: note: in definition of macro '__swab16'
> 102 | #define __swab16(x) (__u16)__builtin_bswap16((__u16)(x))
> | ^
> include/linux/byteorder/generic.h:96:21: note: in expansion of macro
> '__cpu_to_be16'
> 96 | #define cpu_to_be16 __cpu_to_be16
> | ^~~~~~~~~~~~~
> drivers/ufs/core/ufs-rpmb.c:110:38: note: in expansion of macro
> 'cpu_to_be16'
> 110 | frm_resp->req_resp = cpu_to_be16(RPMB_RESULT_READ);
> | ^~~~~~~~~~~
> drivers/ufs/core/ufs-rpmb.c: At top level:
> > > drivers/ufs/core/ufs-rpmb.c:135:5: error: redefinition of 'ufs_rpmb_probe'
> 135 | int ufs_rpmb_probe(struct ufs_hba *hba)
> | ^~~~~~~~~~~~~~
> In file included from drivers/ufs/core/ufs-rpmb.c:22:
> drivers/ufs/core/ufshcd-priv.h:424:19: note: previous definition of
> 'ufs_rpmb_probe' with type 'int(struct ufs_hba *)'
> 424 | static inline int ufs_rpmb_probe(struct ufs_hba *hba)
> | ^~~~~~~~~~~~~~
> > > drivers/ufs/core/ufs-rpmb.c:234:6: error: redefinition of
> > > 'ufs_rpmb_remove'
> 234 | void ufs_rpmb_remove(struct ufs_hba *hba)
> | ^~~~~~~~~~~~~~~
> drivers/ufs/core/ufshcd-priv.h:428:20: note: previous definition of
> 'ufs_rpmb_remove' with type 'void(struct ufs_hba *)'
> 428 | static inline void ufs_rpmb_remove(struct ufs_hba *hba)
> | ^~~~~~~~~~~~~~~
>
> Kconfig warnings: (for reference only)
> WARNING: unmet direct dependencies detected for OF_GPIO
> Depends on [n]: GPIOLIB [=y] && OF [=n] && HAS_IOMEM [=y]
> Selected by [y]:
> - GPIO_TB10X [=y] && GPIOLIB [=y] && HAS_IOMEM [=y] && (ARC_PLAT_TB10X ||
> COMPILE_TEST [=y])
> WARNING: unmet direct dependencies detected for GPIO_SYSCON
> Depends on [n]: GPIOLIB [=y] && HAS_IOMEM [=y] && MFD_SYSCON [=y] && OF
> [=n]
> Selected by [y]:
> - GPIO_SAMA5D2_PIOBU [=y] && GPIOLIB [=y] && HAS_IOMEM [=y] && MFD_SYSCON
> [=y] && OF_GPIO [=y] && (ARCH_AT91 || COMPILE_TEST [=y])
> WARNING: unmet direct dependencies detected for I2C_K1
> Depends on [n]: I2C [=y] && HAS_IOMEM [=y] && (ARCH_SPACEMIT ||
> COMPILE_TEST [=y]) && OF [=n]
> Selected by [m]:
> - MFD_SPACEMIT_P1 [=m] && HAS_IOMEM [=y] && (ARCH_SPACEMIT || COMPILE_TEST
> [=y]) && I2C [=y]
>
>
> vim +/ufs_rpmb_probe +135 drivers/ufs/core/ufs-rpmb.c
>
> 133
> 134 /* UFS RPMB device registration */
> > 135 int ufs_rpmb_probe(struct ufs_hba *hba)
> 136 {
> 137 struct ufs_rpmb_dev *ufs_rpmb, *it, *tmp;
> 138 struct rpmb_dev *rdev;
> 139 char *cid = NULL;
> 140 int region;
> 141 u32 cap;
> 142 int ret;
> 143
> 144 if (!hba->ufs_rpmb_wlun || hba->dev_info.b_advanced_rpmb_en) {
> 145 dev_info(hba->dev, "Skip OP-TEE RPMB registration\n");
> 146 return -ENODEV;
> 147 }
> 148
> 149 /* Check if device_id is available */
> 150 if (!hba->dev_info.device_id) {
> 151 dev_err(hba->dev, "UFS Device ID not available\n");
> 152 return -EINVAL;
> 153 }
> 154
> 155 INIT_LIST_HEAD(&hba->rpmbs);
> 156
> 157 struct rpmb_descr descr = {
> 158 .type = RPMB_TYPE_UFS,
> 159 .route_frames = ufs_rpmb_route_frames,
> 160 .reliable_wr_count = hba->dev_info.rpmb_io_size,
> 161 };
> 162
> 163 for (region = 0; region < ARRAY_SIZE(hba-
> >dev_info.rpmb_region_size); region++) {
> 164 cap = hba->dev_info.rpmb_region_size[region];
> 165 if (!cap)
> 166 continue;
> 167
> 168 ufs_rpmb = devm_kzalloc(hba->dev, sizeof(*ufs_rpmb),
> GFP_KERNEL);
> 169 if (!ufs_rpmb) {
> 170 ret = -ENOMEM;
> 171 goto err_out;
> 172 }
> 173
> 174 ufs_rpmb->hba = hba;
> 175 ufs_rpmb->dev.parent = &hba->ufs_rpmb_wlun-
> >sdev_gendev;
> 176 ufs_rpmb->dev.bus = &ufs_rpmb_bus_type;
> 177 ufs_rpmb->dev.release = ufs_rpmb_device_release;
> 178 dev_set_name(&ufs_rpmb->dev, "ufs_rpmb%d", region);
> 179
> 180 /* Set driver data BEFORE device_register */
> 181 dev_set_drvdata(&ufs_rpmb->dev, ufs_rpmb);
> 182
> 183 ret = device_register(&ufs_rpmb->dev);
> 184 if (ret) {
> 185 dev_err(hba->dev, "Failed to register UFS RPMB
> device %d\n", region);
> 186 put_device(&ufs_rpmb->dev);
> 187 goto err_out;
> 188 }
> 189
> 190 /* Create unique ID by appending region number to
> device_id */
> 191 cid = kasprintf(GFP_KERNEL, "%s-R%d", hba-
> >dev_info.device_id, region);
> 192 if (!cid) {
> 193 device_unregister(&ufs_rpmb->dev);
> 194 ret = -ENOMEM;
> 195 goto err_out;
> 196 }
> 197
> 198 descr.dev_id = cid;
> 199 descr.dev_id_len = strlen(cid);
> 200 descr.capacity = cap;
> 201
> 202 /* Register RPMB device */
> 203 rdev = rpmb_dev_register(&ufs_rpmb->dev, &descr);
> 204 if (IS_ERR(rdev)) {
> 205 dev_err(hba->dev, "Failed to register UFS RPMB
> device.\n");
> 206 device_unregister(&ufs_rpmb->dev);
> 207 ret = PTR_ERR(rdev);
> 208 goto err_out;
> 209 }
> 210
> 211 kfree(cid);
> 212 cid = NULL;
> 213
> 214 ufs_rpmb->rdev = rdev;
> 215 ufs_rpmb->region_id = region;
> 216
> 217 list_add_tail(&ufs_rpmb->node, &hba->rpmbs);
> 218
> 219 dev_info(hba->dev, "UFS RPMB region %d registered
> (capacity=%u)\n", region, cap);
> 220 }
> 221
> 222 return 0;
> 223 err_out:
> 224 kfree(cid);
> 225 list_for_each_entry_safe(it, tmp, &hba->rpmbs, node) {
> 226 list_del(&it->node);
> 227 device_unregister(&it->dev);
> 228 }
> 229
> 230 return ret;
> 231 }
> 232
> 233 /* UFS RPMB remove handler */
> > 234 void ufs_rpmb_remove(struct ufs_hba *hba)
> 235 {
> 236 struct ufs_rpmb_dev *ufs_rpmb, *tmp;
> 237
> 238 if (list_empty(&hba->rpmbs))
> 239 return;
> 240
> 241 /* Remove all registered RPMB devices */
> 242 list_for_each_entry_safe(ufs_rpmb, tmp, &hba->rpmbs, node) {
> 243 dev_info(hba->dev, "Removing UFS RPMB region %d\n",
> ufs_rpmb->region_id);
> 244 /* Remove from list first */
> 245 list_del(&ufs_rpmb->node);
> 246 /* Unregister device */
> 247 device_unregister(&ufs_rpmb->dev);
> 248 }
> 249
> 250 dev_info(hba->dev, "All UFS RPMB devices unregistered\n");
> 251 }
> 252
>
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v6 3/3] scsi: ufs: core: Add OP-TEE based RPMB driver for UFS devices
2025-10-26 21:25 ` [PATCH v6 3/3] scsi: ufs: core: Add OP-TEE based RPMB driver for UFS devices Bean Huo
2025-10-27 3:27 ` kernel test robot
@ 2025-10-27 14:06 ` Jens Wiklander
1 sibling, 0 replies; 9+ messages in thread
From: Jens Wiklander @ 2025-10-27 14:06 UTC (permalink / raw)
To: Bean Huo
Cc: avri.altman, avri.altman, bvanassche, alim.akhtar, jejb,
martin.petersen, can.guo, ulf.hansson, beanhuo, linux-scsi,
linux-kernel
On Sun, Oct 26, 2025 at 10:25 PM Bean Huo <beanhuo@iokpp.de> wrote:
>
> From: Bean Huo <beanhuo@micron.com>
>
> This patch adds OP-TEE based RPMB support for UFS devices. This enables secure
> RPMB operations on UFS devices through OP-TEE, providing the same functionality
> available for eMMC devices and extending kernel-based secure storage support to
> UFS-based systems.
>
> Benefits of OP-TEE based RPMB implementation:
> - Eliminates dependency on userspace supplicant for RPMB access
> - Enables early boot secure storage access (e.g., fTPM, secure UEFI variables)
> - Provides kernel-level RPMB access as soon as UFS driver is initialized
> - Removes complex initramfs dependencies and boot ordering requirements
> - Ensures reliable and deterministic secure storage operations
> - Supports both built-in and modular fTPM configurations
>
> Co-developed-by: Can Guo <can.guo@oss.qualcomm.com>
> Signed-off-by: Can Guo <can.guo@oss.qualcomm.com>
> Reviewed-by: Avri Altman <avri.altman@sandisk.com>
> Reviewed-by: Bart Van Assche <bvanassche@acm.org>
> Signed-off-by: Bean Huo <beanhuo@micron.com>
> ---
> drivers/misc/Kconfig | 2 +-
> drivers/ufs/core/Makefile | 1 +
> drivers/ufs/core/ufs-rpmb.c | 254 +++++++++++++++++++++++++++++++++
> drivers/ufs/core/ufshcd-priv.h | 13 ++
> drivers/ufs/core/ufshcd.c | 86 ++++++++++-
> include/ufs/ufs.h | 5 +
> include/ufs/ufshcd.h | 8 +-
> 7 files changed, 362 insertions(+), 7 deletions(-)
> create mode 100644 drivers/ufs/core/ufs-rpmb.c
Looks good.
Reviewed-by: Jens Wiklander <jens.wiklander@linaro.org>
Cheers,
Jens
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v6 0/3] Add OP-TEE based RPMB driver for UFS devices
2025-10-26 21:25 [PATCH v6 0/3] Add OP-TEE based RPMB driver for UFS devices Bean Huo
` (2 preceding siblings ...)
2025-10-26 21:25 ` [PATCH v6 3/3] scsi: ufs: core: Add OP-TEE based RPMB driver for UFS devices Bean Huo
@ 2025-11-06 17:29 ` Bean Huo
2025-11-06 18:21 ` Martin K. Petersen
3 siblings, 1 reply; 9+ messages in thread
From: Bean Huo @ 2025-11-06 17:29 UTC (permalink / raw)
To: avri.altman, avri.altman, bvanassche, alim.akhtar, jejb,
martin.petersen, can.guo, ulf.hansson, beanhuo, jens.wiklander
Cc: linux-scsi, linux-kernel
Hi Martin,
Do you need me to rebase this patch series? I noticed you marked it as deferred
Kind regards,
Bean
On Sun, 2025-10-26 at 22:25 +0100, Bean Huo wrote:
>
> This patch series introduces OP-TEE based RPMB (Replay Protected Memory Block)
> support for UFS devices, extending the kernel-level secure storage
> capabilities
> that are currently available for eMMC devices.
>
> Previously, OP-TEE required a userspace supplicant to access RPMB partitions,
> which created complex dependencies and reliability issues, especially during
> early boot scenarios. Recent work by Linaro has moved core supplicant
> functionality directly into the Linux kernel for eMMC devices, eliminating
> userspace dependencies and enabling immediate secure storage access. This
> series
> extends the same approach to UFS devices, which are used in enterprise and
> mobile
> applications that require secure storage capabilities.
>
> Benefits:
> - Eliminates dependency on userspace supplicant for UFS RPMB access
> - Enables early boot secure storage access (e.g., fTPM, secure UEFI variables)
> - Provides kernel-level RPMB access as soon as UFS driver is initialized
> - Removes complex initramfs dependencies and boot ordering requirements
> - Ensures reliable and deterministic secure storage operations
> - Supports both built-in and modular fTPM configurations.
>
>
> v5 -- v6:
> 1. Added a comment in ufshcd_create_device_id() to warn against
> modifying the
> device ID format without understanding its impact.
>
> v4 -- v5:
> 1. Added helper function ufshcd_create_device_id() to generate unique
> device
> identifier by combining manufacturer ID, specification version, model
> name,
> serial number (as hex), device version, and manufacture date.
> 2. Added device_id field to struct ufs_dev_info for storing allocated
> unique device
> identifier string.
> 3. Modified UFS RPMB driver to use device_id instead of just
> serial_number for creating
> unique RPMB device identifiers
> v3 -- v4:
> 1. Replaced patch "scsi: ufs: core: Remove duplicate macro definitions"
> with
> "scsi: ufs: core: Convert string descriptor format macros to enum"
> based on
> feedback from Bart Van Assche
> 2. Converted SD_ASCII_STD and SD_RAW from boolean macros to enum type for
> improved code readability
> 3. Moved ufshcd_read_string_desc() declaration from include/ufs/ufshcd.h
> to
> drivers/ufs/core/ufshcd-priv.h since it's not exported
>
> v2 -- v3:
> 1. Removed patch "rpmb: move rpmb_frame struct and constants to common
> header". since it
> has been queued in mmc tree, and added a new patch:
> "scsi: ufs: core: Remove duplicate macro definitions"
> 2. Incorporated suggestions from Jens
> 3. Added check if Advanced RPMB is enabled, if enabled we will not
> register UFS OP-TEE RPMB.
>
> v1 -- v2:
> 1. Added fix tag for patch [2/3]
> 2. Incorporated feedback and suggestions from Bart
>
> RFC v1 -- v1:
> 1. Added support for all UFS RPMB regions based on
> https://github.com/OP-TEE/optee_os/issues/7532
> 2. Incorporated feedback and suggestions from Bart
>
>
> Bean Huo (3):
> scsi: ufs: core: Convert string descriptor format macros to enum
> scsi: ufs: core: fix incorrect buffer duplication in
> ufshcd_read_string_desc()
> scsi: ufs: core: Add OP-TEE based RPMB driver for UFS devices
>
> drivers/misc/Kconfig | 2 +-
> drivers/ufs/core/Makefile | 1 +
> drivers/ufs/core/ufs-rpmb.c | 254 +++++++++++++++++++++++++++++++++
> drivers/ufs/core/ufshcd-priv.h | 27 +++-
> drivers/ufs/core/ufshcd.c | 96 +++++++++++--
> include/ufs/ufs.h | 5 +
> include/ufs/ufshcd.h | 12 +-
> 7 files changed, 376 insertions(+), 21 deletions(-)
> create mode 100644 drivers/ufs/core/ufs-rpmb.c
>
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v6 0/3] Add OP-TEE based RPMB driver for UFS devices
2025-11-06 17:29 ` [PATCH v6 0/3] " Bean Huo
@ 2025-11-06 18:21 ` Martin K. Petersen
0 siblings, 0 replies; 9+ messages in thread
From: Martin K. Petersen @ 2025-11-06 18:21 UTC (permalink / raw)
To: Bean Huo
Cc: avri.altman, avri.altman, bvanassche, alim.akhtar, jejb,
martin.petersen, can.guo, ulf.hansson, beanhuo, jens.wiklander,
linux-scsi, linux-kernel
Bean,
> Do you need me to rebase this patch series? I noticed you marked it as
> deferred
Yes, please.
--
Martin K. Petersen
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2025-11-06 18:22 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-10-26 21:25 [PATCH v6 0/3] Add OP-TEE based RPMB driver for UFS devices Bean Huo
2025-10-26 21:25 ` [PATCH v6 1/3] scsi: ufs: core: Convert string descriptor format macros to enum Bean Huo
2025-10-26 21:25 ` [PATCH v6 2/3] scsi: ufs: core: fix incorrect buffer duplication in ufshcd_read_string_desc() Bean Huo
2025-10-26 21:25 ` [PATCH v6 3/3] scsi: ufs: core: Add OP-TEE based RPMB driver for UFS devices Bean Huo
2025-10-27 3:27 ` kernel test robot
2025-10-27 10:08 ` Bean Huo
2025-10-27 14:06 ` Jens Wiklander
2025-11-06 17:29 ` [PATCH v6 0/3] " Bean Huo
2025-11-06 18:21 ` Martin K. Petersen
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox