[PATCH] riscv: mm: Apply T-Head PMA memory-type errata to PUD and P4D entries
From: Han Gao
Date: Wed Sep 16 2026 - 02:33:18 EST
The T-Head memory-type errata injects the PMA type bits via
ALT_THEAD_PMA() when building a page table entry. It is applied in
pfn_pte(), pfn_pmd(), pfn_pgd() and pte_modify(), but not in pfn_pud()
or pfn_p4d().
As a result, PUD-level (1GB) and, on sv57, P4D-level (512GB) huge page
mappings never carry the T-Head PMA memory-type encoding. On cores that
require the errata, such mappings fall back to the implied/default PMA
instead of the explicit cacheable type the errata mandates, so their
memory attributes can differ from every other mapping size. These leaf
entries are reachable from the linear mapping (create_pud_mapping() with
PUD_SIZE) and from huge vmap.
Mirror pfn_pmd() and run ALT_THEAD_PMA() on the protection value in
pfn_pud() and pfn_p4d() as well.
Cc: stable@xxxxxxxxxxxxxxx
Fixes: a35707c3d850 ("riscv: add memory-type errata for T-Head")
Signed-off-by: Han Gao <gaohan@xxxxxxxxxxx>
---
arch/riscv/include/asm/pgtable-64.h | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/arch/riscv/include/asm/pgtable-64.h b/arch/riscv/include/asm/pgtable-64.h
index 6e789fa58514c7dd11ef9c87050a3fa10fd4908d..1329a1ddee072dfb9a97f52bf1aad9f515aa96fe 100644
--- a/arch/riscv/include/asm/pgtable-64.h
+++ b/arch/riscv/include/asm/pgtable-64.h
@@ -212,7 +212,11 @@ static inline void pud_clear(pud_t *pudp)
static inline pud_t pfn_pud(unsigned long pfn, pgprot_t prot)
{
- return __pud((pfn << _PAGE_PFN_SHIFT) | pgprot_val(prot));
+ unsigned long prot_val = pgprot_val(prot);
+
+ ALT_THEAD_PMA(prot_val);
+
+ return __pud((pfn << _PAGE_PFN_SHIFT) | prot_val);
}
static inline unsigned long _pud_pfn(pud_t pud)
@@ -313,7 +317,11 @@ static inline void p4d_clear(p4d_t *p4d)
static inline p4d_t pfn_p4d(unsigned long pfn, pgprot_t prot)
{
- return __p4d((pfn << _PAGE_PFN_SHIFT) | pgprot_val(prot));
+ unsigned long prot_val = pgprot_val(prot);
+
+ ALT_THEAD_PMA(prot_val);
+
+ return __p4d((pfn << _PAGE_PFN_SHIFT) | prot_val);
}
static inline unsigned long _p4d_pfn(p4d_t p4d)
---
base-commit: fd73f4a6659897191fa0d40695fe370925dd3780
change-id: 20260916-fix-mm-1fb9dc07c11d
Best regards,
--
Han Gao <gaohan@xxxxxxxxxxx>