[PATCH v2] scsi: ufs: core: Fix RPMB region size detection for UFS 2.2

Alexey Charkov posted 1 patch 2 days, 21 hours ago
drivers/ufs/core/ufshcd.c | 15 +++++++++++++++
1 file changed, 15 insertions(+)
[PATCH v2] scsi: ufs: core: Fix RPMB region size detection for UFS 2.2
Posted by Alexey Charkov 2 days, 21 hours ago
Older UFS spec devices (2.2 and earlier) do not expose per-region RPMB
sizes, as only one RPMB region is supported. In such cases, the size of
the single RPMB region can be deduced from the Logical Block Count and
Logical Block Size fields in the RPMB Unit Descriptor.

Add a fallback mechanism to calculate the RPMB region size from these
fields if the device implements an older spec, so that the RPMB driver
can work with such devices - otherwise it silently skips the whole RPMB.

        Section 14.1.4.6 (RPMB Unit Descriptor)

Link: https://www.jedec.org/system/files/docs/JESD220C-2_2.pdf
Cc: stable@vger.kernel.org
Fixes: b06b8c421485 ("scsi: ufs: core: Add OP-TEE based RPMB driver for UFS devices")
Signed-off-by: Alexey Charkov <alchark@flipper.net>
---
Changes in v2:
- Comment on the expected size of the RPMB partition on UFS 2.2 (thanks Bean)
- Use a standard define for size instead of a magic number (thanks Bean)
- Link to v1: https://lore.kernel.org/r/20260129-ufs-rpmb-v1-1-691534ab723f@flipper.net
---
 drivers/ufs/core/ufshcd.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c
index 52ffd0c3aa4c..32da8ecdba72 100644
--- a/drivers/ufs/core/ufshcd.c
+++ b/drivers/ufs/core/ufshcd.c
@@ -24,6 +24,7 @@
 #include <linux/pm_opp.h>
 #include <linux/regulator/consumer.h>
 #include <linux/sched/clock.h>
+#include <linux/sizes.h>
 #include <linux/iopoll.h>
 #include <scsi/scsi_cmnd.h>
 #include <scsi/scsi_dbg.h>
@@ -5249,6 +5250,20 @@ static void ufshcd_lu_init(struct ufs_hba *hba, struct scsi_device *sdev)
 		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];
+
+		if (hba->dev_info.wspecversion <= 0x0220) {
+			/* These older spec chips have only one RPMB region,
+			 * sized between 128 kB minimum and 16 MB maximum.
+			 * No per region size fields are provided, so get it
+			 * from the logical block count and size fields for
+			 * compatibility
+			 */
+			hba->dev_info.rpmb_region_size[0] =
+				(get_unaligned_be64(desc_buf
+					+ RPMB_UNIT_DESC_PARAM_LOGICAL_BLK_COUNT)
+				<< desc_buf[RPMB_UNIT_DESC_PARAM_LOGICAL_BLK_SIZE])
+				/ SZ_128K;
+		}
 	}
 
 

---
base-commit: 5c009020744fe129e4728e71c44a6c7816c9105e
change-id: 20260129-ufs-rpmb-d198a699a40d

Best regards,
-- 
Alexey Charkov <alchark@flipper.net>
Re: [PATCH v2] scsi: ufs: core: Fix RPMB region size detection for UFS 2.2
Posted by Bart Van Assche 2 days, 13 hours ago
On 2/5/26 12:30 AM, Alexey Charkov wrote:
> @@ -5249,6 +5250,20 @@ static void ufshcd_lu_init(struct ufs_hba *hba, struct scsi_device *sdev)
>   		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];

Executing the above code if (hba->dev_info.wspecversion <= 0x0220) is
risky, isn't it?

> +		if (hba->dev_info.wspecversion <= 0x0220) {
> +			/* These older spec chips have only one RPMB region,
> +			 * sized between 128 kB minimum and 16 MB maximum.
> +			 * No per region size fields are provided, so get it
> +			 * from the logical block count and size fields for
> +			 * compatibility
> +			 */

Please follow the Linux kernel coding style for source code comments.
 From Documentation/process/coding-style.rst:

The preferred style for long (multi-line) comments is:

.. code-block:: c

	/*
	 * This is the preferred style for multi-line
	 * comments in the Linux kernel source code.
	 * Please use it consistently.
	 *
	 * Description:  A column of asterisks on the left side,
	 * with beginning and ending almost-blank lines.
	 */

Thanks,

Bart.
Re: [PATCH v2] scsi: ufs: core: Fix RPMB region size detection for UFS 2.2
Posted by Alexey Charkov 1 day, 22 hours ago
Hi Bart,

On Thu, Feb 5, 2026 at 8:08 PM Bart Van Assche <bvanassche@acm.org> wrote:
>
> On 2/5/26 12:30 AM, Alexey Charkov wrote:
> > @@ -5249,6 +5250,20 @@ static void ufshcd_lu_init(struct ufs_hba *hba, struct scsi_device *sdev)
> >               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];
>
> Executing the above code if (hba->dev_info.wspecversion <= 0x0220) is
> risky, isn't it?

I don't think so. On <=0x0220 this part of the descriptor (four bytes
at offset 0x13) should always return zeros, so a compliant device
shouldn't get confused, nor make the driver confused.

The spec there is worded a bit weirdly, but it does say clearly that
these are set to zero, and I can confirm it on the devices I have at
hand (a couple of Biwin and a Samsung one, all 2.2 spec).

The spec says (Section 14.1.4.6 RPMB Unit Descriptor, table entry for
offset 13h):
4 bytes. dEraseBlockSize. Value 00h. User-configurable: no. Erase
Block Size In number of Logical Blocks. For RPMB, Erase Block Size is
ignored; set to ‘0’

Not sure what was the rationale for giving this region a name at all,
as it is effectively reserved and zeroed out (and then change the name
and purpose of it in the next spec version anyway). But in this
context "Value 00h" is all that matters AFAICT :)

Shall I also add a comment to that effect?

> > +             if (hba->dev_info.wspecversion <= 0x0220) {
> > +                     /* These older spec chips have only one RPMB region,
> > +                      * sized between 128 kB minimum and 16 MB maximum.
> > +                      * No per region size fields are provided, so get it
> > +                      * from the logical block count and size fields for
> > +                      * compatibility
> > +                      */
>
> Please follow the Linux kernel coding style for source code comments.
>  From Documentation/process/coding-style.rst:
>
> The preferred style for long (multi-line) comments is:
>
> .. code-block:: c
>
>         /*
>          * This is the preferred style for multi-line

Right, the top empty line. Thanks for the pointer!

Best regards,
Alexey