[RFC PATCH 28/34] arm: mm: use proper pgtable APIs for generic compile-time folded patable in kasan_init()

Yeoreum Yun yeoreum.yun at arm.com
Mon Jul 13 06:56:07 PDT 2026


We want to rework how set_pXd() and pgd_page_vaddr() behaves for
generic compile-time folded page tables by disallowing its use and
triggering a compile-time error when they're used improperly,
ensuring that the actual first-level pgtable APIs are used instead.

For this, Replace set_pgd() with set_pud() and pgd_page_vaddr() with pud_pgtable()
to setup kasan early patable since it used with LPAE and PGTABLE_LEVEL as 3

Since the first page-level is 3 to get a first page-level properly
introduce new helper pud_off_k() and replace direct dereference of
first page-table entry with pudp_get().

There should be no functional change.

Signed-off-by: Yeoreum Yun <yeoreum.yun at arm.com>
---
 arch/arm/mm/kasan_init.c | 8 +++++---
 include/linux/pgtable.h  | 5 +++++
 2 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/arch/arm/mm/kasan_init.c b/arch/arm/mm/kasan_init.c
index c6625e808bf85..31fa1b11816c7 100644
--- a/arch/arm/mm/kasan_init.c
+++ b/arch/arm/mm/kasan_init.c
@@ -211,6 +211,7 @@ void __init kasan_init(void)
 {
 	phys_addr_t pa_start, pa_end;
 	u64 i;
+	pud_t *pudp __maybe_unused;
 
 	/*
 	 * We are going to perform proper setup of shadow memory.
@@ -230,11 +231,12 @@ void __init kasan_init(void)
 	/* We need to be in the same PGD or this won't work */
 	BUILD_BUG_ON(pgd_index(KASAN_SHADOW_START) !=
 		     pgd_index(KASAN_SHADOW_END));
+	pudp = pud_off_k(KASAN_SHADOW_START);
 	memcpy(tmp_pmd_table,
-	       (void*)pgd_page_vaddr(*pgd_offset_k(KASAN_SHADOW_START)),
+	       (void*)pud_pgtable(pudp_get(pudp)),
 	       sizeof(tmp_pmd_table));
-	set_pgd(&tmp_pgd_table[pgd_index(KASAN_SHADOW_START)],
-		__pgd(__pa(tmp_pmd_table) | PMD_TYPE_TABLE | L_PGD_SWAPPER));
+	set_pud(&tmp_pgd_table[pgd_index(KASAN_SHADOW_START)],
+		__pmd(__pa(tmp_pmd_table) | PMD_TYPE_TABLE | L_PGD_SWAPPER));
 #endif
 	cpu_switch_mm(tmp_pgd_table, &init_mm);
 	local_flush_tlb_all();
diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h
index 8c093c119e5a8..4962d9764b487 100644
--- a/include/linux/pgtable.h
+++ b/include/linux/pgtable.h
@@ -155,6 +155,11 @@ static inline pgd_t *pgd_offset_pgd(pgd_t *pgd, unsigned long address)
  */
 #define pgd_offset_k(address)		pgd_offset(&init_mm, (address))
 
+static inline pud_t *pud_off_k(unsigned long va)
+{
+	return pud_offset(p4d_offset(pgd_offset_k(va), va), va);
+}
+
 /*
  * In many cases it is known that a virtual address is mapped at PMD or PTE
  * level, so instead of traversing all the page table levels, we can get a
-- 
LEVI:{C3F47F37-75D8-414A-A8BA-3980EC8A46D7}




More information about the kvm-riscv mailing list