Skip to content

Commit a410656

Browse files
committed
LoongArch: Make KASAN work with 5-level page-tables
Make KASAN work with 5-level page-tables, including: 1. Implement and use __pgd_none() and kasan_p4d_offset(). 2. As done in kasan_pmd_populate() and kasan_pte_populate(), restrict the loop conditions of kasan_p4d_populate() and kasan_pud_populate() to avoid unnecessary population. Cc: [email protected] Signed-off-by: Huacai Chen <[email protected]>
1 parent c859900 commit a410656

File tree

1 file changed

+23
-3
lines changed

1 file changed

+23
-3
lines changed

arch/loongarch/mm/kasan_init.c

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,13 @@
1313

1414
static pgd_t kasan_pg_dir[PTRS_PER_PGD] __initdata __aligned(PAGE_SIZE);
1515

16+
#ifdef __PAGETABLE_P4D_FOLDED
17+
#define __pgd_none(early, pgd) (0)
18+
#else
19+
#define __pgd_none(early, pgd) (early ? (pgd_val(pgd) == 0) : \
20+
(__pa(pgd_val(pgd)) == (unsigned long)__pa(kasan_early_shadow_p4d)))
21+
#endif
22+
1623
#ifdef __PAGETABLE_PUD_FOLDED
1724
#define __p4d_none(early, p4d) (0)
1825
#else
@@ -142,6 +149,19 @@ static pud_t *__init kasan_pud_offset(p4d_t *p4dp, unsigned long addr, int node,
142149
return pud_offset(p4dp, addr);
143150
}
144151

152+
static p4d_t *__init kasan_p4d_offset(pgd_t *pgdp, unsigned long addr, int node, bool early)
153+
{
154+
if (__pgd_none(early, pgdp_get(pgdp))) {
155+
phys_addr_t p4d_phys = early ?
156+
__pa_symbol(kasan_early_shadow_p4d) : kasan_alloc_zeroed_page(node);
157+
if (!early)
158+
memcpy(__va(p4d_phys), kasan_early_shadow_p4d, sizeof(kasan_early_shadow_p4d));
159+
pgd_populate(&init_mm, pgdp, (p4d_t *)__va(p4d_phys));
160+
}
161+
162+
return p4d_offset(pgdp, addr);
163+
}
164+
145165
static void __init kasan_pte_populate(pmd_t *pmdp, unsigned long addr,
146166
unsigned long end, int node, bool early)
147167
{
@@ -178,19 +198,19 @@ static void __init kasan_pud_populate(p4d_t *p4dp, unsigned long addr,
178198
do {
179199
next = pud_addr_end(addr, end);
180200
kasan_pmd_populate(pudp, addr, next, node, early);
181-
} while (pudp++, addr = next, addr != end);
201+
} while (pudp++, addr = next, addr != end && __pud_none(early, READ_ONCE(*pudp)));
182202
}
183203

184204
static void __init kasan_p4d_populate(pgd_t *pgdp, unsigned long addr,
185205
unsigned long end, int node, bool early)
186206
{
187207
unsigned long next;
188-
p4d_t *p4dp = p4d_offset(pgdp, addr);
208+
p4d_t *p4dp = kasan_p4d_offset(pgdp, addr, node, early);
189209

190210
do {
191211
next = p4d_addr_end(addr, end);
192212
kasan_pud_populate(p4dp, addr, next, node, early);
193-
} while (p4dp++, addr = next, addr != end);
213+
} while (p4dp++, addr = next, addr != end && __p4d_none(early, READ_ONCE(*p4dp)));
194214
}
195215

196216
static void __init kasan_pgd_populate(unsigned long addr, unsigned long end,

0 commit comments

Comments
 (0)