]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
iommupt: Encode IOMMU_MMIO/IOMMU_CACHE via RISC-V Svpbmt bits
authorFangyu Yu <fangyu.yu@linux.alibaba.com>
Fri, 17 Apr 2026 14:07:46 +0000 (22:07 +0800)
committerJoerg Roedel <joerg.roedel@amd.com>
Mon, 11 May 2026 08:04:38 +0000 (10:04 +0200)
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@linux.alibaba.com>
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Reviewed-by: Guo Ren <guoren@kernel.org>
Reviewed-by: Nutty Liu <nutty.liu@hotmail.com>
Reviewed-by: Kevin Tian <kevin.tian@intel.com>
Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
drivers/iommu/generic_pt/fmt/riscv.h

index a7fef6266a36a67122e3338d6b3dd09cef33cf14..2648bb57953e3814c7368200605f648c3aac82c0 100644 (file)
@@ -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))