Skip to content

Commit 36b3a77

Browse files
amlutoKAGA-KOKO
authored andcommitted
x86/mm/64: Tighten up vmalloc_fault() sanity checks on 5-level kernels
On a 5-level kernel, if a non-init mm has a top-level entry, it needs to match init_mm's, but the vmalloc_fault() code skipped over the BUG_ON() that would have checked it. While we're at it, get rid of the rather confusing 4-level folded "pgd" logic. Cleans-up: b50858c ("x86/mm/vmalloc: Add 5-level paging support") Signed-off-by: Andy Lutomirski <[email protected]> Signed-off-by: Thomas Gleixner <[email protected]> Cc: Konstantin Khlebnikov <[email protected]> Cc: Dave Hansen <[email protected]> Cc: Borislav Petkov <[email protected]> Cc: Neil Berrington <[email protected]> Link: https://lkml.kernel.org/r/2ae598f8c279b0a29baf75df207e6f2fdddc0a1b.1516914529.git.luto@kernel.org
1 parent 5beda7d commit 36b3a77

File tree

1 file changed

+9
-13
lines changed

1 file changed

+9
-13
lines changed

arch/x86/mm/fault.c

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -439,18 +439,13 @@ static noinline int vmalloc_fault(unsigned long address)
439439
if (pgd_none(*pgd_ref))
440440
return -1;
441441

442-
if (pgd_none(*pgd)) {
443-
set_pgd(pgd, *pgd_ref);
444-
arch_flush_lazy_mmu_mode();
445-
} else if (CONFIG_PGTABLE_LEVELS > 4) {
446-
/*
447-
* With folded p4d, pgd_none() is always false, so the pgd may
448-
* point to an empty page table entry and pgd_page_vaddr()
449-
* will return garbage.
450-
*
451-
* We will do the correct sanity check on the p4d level.
452-
*/
453-
BUG_ON(pgd_page_vaddr(*pgd) != pgd_page_vaddr(*pgd_ref));
442+
if (CONFIG_PGTABLE_LEVELS > 4) {
443+
if (pgd_none(*pgd)) {
444+
set_pgd(pgd, *pgd_ref);
445+
arch_flush_lazy_mmu_mode();
446+
} else {
447+
BUG_ON(pgd_page_vaddr(*pgd) != pgd_page_vaddr(*pgd_ref));
448+
}
454449
}
455450

456451
/* With 4-level paging, copying happens on the p4d level. */
@@ -459,7 +454,7 @@ static noinline int vmalloc_fault(unsigned long address)
459454
if (p4d_none(*p4d_ref))
460455
return -1;
461456

462-
if (p4d_none(*p4d)) {
457+
if (p4d_none(*p4d) && CONFIG_PGTABLE_LEVELS == 4) {
463458
set_p4d(p4d, *p4d_ref);
464459
arch_flush_lazy_mmu_mode();
465460
} else {
@@ -470,6 +465,7 @@ static noinline int vmalloc_fault(unsigned long address)
470465
* Below here mismatches are bugs because these lower tables
471466
* are shared:
472467
*/
468+
BUILD_BUG_ON(CONFIG_PGTABLE_LEVELS < 4);
473469

474470
pud = pud_offset(p4d, address);
475471
pud_ref = pud_offset(p4d_ref, address);

0 commit comments

Comments
 (0)