[PATCH v3 2/2] iommupt: Encode IOMMU_MMIO/IOMMU_CACHE via RISC-V Svpbmt bits

From: fangyu . yu

Date: Fri Apr 17 2026 - 10:12:22 EST


From: Fangyu Yu <fangyu.yu@xxxxxxxxxxxxxxxxx>

When the RISC-V IOMMU page table format support Svpbmt, PBMT provides
a way to tag mappings with page-based memory types. Encode memory type
via PBMT in RISC-V IOMMU PTEs:

- IOMMU_MMIO -> PBMT=IO
- !IOMMU_MMIO && !IOMMU_CACHE -> PBMT=NC
- otherwise -> PBMT=Normal (PBMT=0)

Only touch PBMT when PT_FEAT_RISCV_SVPBMT is advertised.

Signed-off-by: Fangyu Yu <fangyu.yu@xxxxxxxxxxxxxxxxx>
Reviewed-by: Jason Gunthorpe <jgg@xxxxxxxxxx>
Reviewed-by: Anup Patel <anup@xxxxxxxxxxxxxx>
Reviewed-by: Guo Ren <guoren@xxxxxxxxxx>
Reviewed-by: Nutty Liu <nutty.liu@xxxxxxxxxxx>
Reviewed-by: Kevin Tian <kevin.tian@xxxxxxxxx>
---
drivers/iommu/generic_pt/fmt/riscv.h | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/drivers/iommu/generic_pt/fmt/riscv.h b/drivers/iommu/generic_pt/fmt/riscv.h
index a7fef6266a36..2648bb57953e 100644
--- a/drivers/iommu/generic_pt/fmt/riscv.h
+++ b/drivers/iommu/generic_pt/fmt/riscv.h
@@ -64,6 +64,8 @@ enum {
RISCVPT_PPN64 = GENMASK_ULL(53, 10),
RISCVPT_PPN64_64K = GENMASK_ULL(53, 14),
RISCVPT_PBMT = GENMASK_ULL(62, 61),
+ RISCVPT_NC = BIT(61),
+ RISCVPT_IO = BIT(62),
RISCVPT_N = BIT_ULL(63),

/* Svnapot encodings for ppn[0] */
@@ -201,7 +203,8 @@ static inline void riscvpt_attr_from_entry(const struct pt_state *pts,
{
attrs->descriptor_bits =
pts->entry & (RISCVPT_R | RISCVPT_W | RISCVPT_X | RISCVPT_U |
- RISCVPT_G | RISCVPT_A | RISCVPT_D);
+ RISCVPT_G | RISCVPT_A | RISCVPT_D | RISCVPT_NC |
+ RISCVPT_IO);
}
#define pt_attr_from_entry riscvpt_attr_from_entry

@@ -237,6 +240,12 @@ static inline int riscvpt_iommu_set_prot(struct pt_common *common,
pte |= RISCVPT_R;
if (!(iommu_prot & IOMMU_NOEXEC))
pte |= RISCVPT_X;
+ if (common->features & BIT(PT_FEAT_RISCV_SVPBMT)) {
+ if (iommu_prot & IOMMU_MMIO)
+ pte |= RISCVPT_IO;
+ else if (!(iommu_prot & IOMMU_CACHE))
+ pte |= RISCVPT_NC;
+ }

/* Caller must specify a supported combination of flags */
if (unlikely((pte & (RISCVPT_X | RISCVPT_W | RISCVPT_R)) == 0))
--
2.50.1