mirror of
https://github.com/torvalds/linux.git
synced 2024-11-22 12:11:40 +00:00
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: stable@vger.kernel.org Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
This commit is contained in:
parent
c859900a84
commit
a410656643
@ -13,6 +13,13 @@
|
||||
|
||||
static pgd_t kasan_pg_dir[PTRS_PER_PGD] __initdata __aligned(PAGE_SIZE);
|
||||
|
||||
#ifdef __PAGETABLE_P4D_FOLDED
|
||||
#define __pgd_none(early, pgd) (0)
|
||||
#else
|
||||
#define __pgd_none(early, pgd) (early ? (pgd_val(pgd) == 0) : \
|
||||
(__pa(pgd_val(pgd)) == (unsigned long)__pa(kasan_early_shadow_p4d)))
|
||||
#endif
|
||||
|
||||
#ifdef __PAGETABLE_PUD_FOLDED
|
||||
#define __p4d_none(early, p4d) (0)
|
||||
#else
|
||||
@ -142,6 +149,19 @@ static pud_t *__init kasan_pud_offset(p4d_t *p4dp, unsigned long addr, int node,
|
||||
return pud_offset(p4dp, addr);
|
||||
}
|
||||
|
||||
static p4d_t *__init kasan_p4d_offset(pgd_t *pgdp, unsigned long addr, int node, bool early)
|
||||
{
|
||||
if (__pgd_none(early, pgdp_get(pgdp))) {
|
||||
phys_addr_t p4d_phys = early ?
|
||||
__pa_symbol(kasan_early_shadow_p4d) : kasan_alloc_zeroed_page(node);
|
||||
if (!early)
|
||||
memcpy(__va(p4d_phys), kasan_early_shadow_p4d, sizeof(kasan_early_shadow_p4d));
|
||||
pgd_populate(&init_mm, pgdp, (p4d_t *)__va(p4d_phys));
|
||||
}
|
||||
|
||||
return p4d_offset(pgdp, addr);
|
||||
}
|
||||
|
||||
static void __init kasan_pte_populate(pmd_t *pmdp, unsigned long addr,
|
||||
unsigned long end, int node, bool early)
|
||||
{
|
||||
@ -178,19 +198,19 @@ static void __init kasan_pud_populate(p4d_t *p4dp, unsigned long addr,
|
||||
do {
|
||||
next = pud_addr_end(addr, end);
|
||||
kasan_pmd_populate(pudp, addr, next, node, early);
|
||||
} while (pudp++, addr = next, addr != end);
|
||||
} while (pudp++, addr = next, addr != end && __pud_none(early, READ_ONCE(*pudp)));
|
||||
}
|
||||
|
||||
static void __init kasan_p4d_populate(pgd_t *pgdp, unsigned long addr,
|
||||
unsigned long end, int node, bool early)
|
||||
{
|
||||
unsigned long next;
|
||||
p4d_t *p4dp = p4d_offset(pgdp, addr);
|
||||
p4d_t *p4dp = kasan_p4d_offset(pgdp, addr, node, early);
|
||||
|
||||
do {
|
||||
next = p4d_addr_end(addr, end);
|
||||
kasan_pud_populate(p4dp, addr, next, node, early);
|
||||
} while (p4dp++, addr = next, addr != end);
|
||||
} while (p4dp++, addr = next, addr != end && __p4d_none(early, READ_ONCE(*p4dp)));
|
||||
}
|
||||
|
||||
static void __init kasan_pgd_populate(unsigned long addr, unsigned long end,
|
||||
|
Loading…
Reference in New Issue
Block a user