Skip to content

Commit b50858c

Browse files
kirylIngo Molnar
authored andcommitted
x86/mm/vmalloc: Add 5-level paging support
Modify vmalloc_fault() to handle additional page table level. With 4-level paging, copying happens on p4d level, as we have pgd_none() always false if p4d_t is folded. Signed-off-by: Kirill A. Shutemov <[email protected]> Cc: Andrew Morton <[email protected]> Cc: Andy Lutomirski <[email protected]> Cc: Arnd Bergmann <[email protected]> Cc: Borislav Petkov <[email protected]> Cc: Brian Gerst <[email protected]> Cc: Dave Hansen <[email protected]> Cc: Denys Vlasenko <[email protected]> Cc: H. Peter Anvin <[email protected]> Cc: Josh Poimboeuf <[email protected]> Cc: Linus Torvalds <[email protected]> Cc: Michal Hocko <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Thomas Gleixner <[email protected]> Cc: [email protected] Cc: [email protected] Link: http://lkml.kernel.org/r/[email protected] Signed-off-by: Ingo Molnar <[email protected]>
1 parent ea3b5e6 commit b50858c

File tree

1 file changed

+24
-3
lines changed

1 file changed

+24
-3
lines changed

arch/x86/mm/fault.c

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -435,6 +435,7 @@ void vmalloc_sync_all(void)
435435
static noinline int vmalloc_fault(unsigned long address)
436436
{
437437
pgd_t *pgd, *pgd_ref;
438+
p4d_t *p4d, *p4d_ref;
438439
pud_t *pud, *pud_ref;
439440
pmd_t *pmd, *pmd_ref;
440441
pte_t *pte, *pte_ref;
@@ -458,17 +459,37 @@ static noinline int vmalloc_fault(unsigned long address)
458459
if (pgd_none(*pgd)) {
459460
set_pgd(pgd, *pgd_ref);
460461
arch_flush_lazy_mmu_mode();
461-
} else {
462+
} else if (CONFIG_PGTABLE_LEVELS > 4) {
463+
/*
464+
* With folded p4d, pgd_none() is always false, so the pgd may
465+
* point to an empty page table entry and pgd_page_vaddr()
466+
* will return garbage.
467+
*
468+
* We will do the correct sanity check on the p4d level.
469+
*/
462470
BUG_ON(pgd_page_vaddr(*pgd) != pgd_page_vaddr(*pgd_ref));
463471
}
464472

473+
/* With 4-level paging, copying happens on the p4d level. */
474+
p4d = p4d_offset(pgd, address);
475+
p4d_ref = p4d_offset(pgd_ref, address);
476+
if (p4d_none(*p4d_ref))
477+
return -1;
478+
479+
if (p4d_none(*p4d)) {
480+
set_p4d(p4d, *p4d_ref);
481+
arch_flush_lazy_mmu_mode();
482+
} else {
483+
BUG_ON(p4d_pfn(*p4d) != p4d_pfn(*p4d_ref));
484+
}
485+
465486
/*
466487
* Below here mismatches are bugs because these lower tables
467488
* are shared:
468489
*/
469490

470-
pud = pud_offset(pgd, address);
471-
pud_ref = pud_offset(pgd_ref, address);
491+
pud = pud_offset(p4d, address);
492+
pud_ref = pud_offset(p4d_ref, address);
472493
if (pud_none(*pud_ref))
473494
return -1;
474495

0 commit comments

Comments
 (0)