@@ -435,6 +435,7 @@ void vmalloc_sync_all(void)
435
435
static noinline int vmalloc_fault (unsigned long address )
436
436
{
437
437
pgd_t * pgd , * pgd_ref ;
438
+ p4d_t * p4d , * p4d_ref ;
438
439
pud_t * pud , * pud_ref ;
439
440
pmd_t * pmd , * pmd_ref ;
440
441
pte_t * pte , * pte_ref ;
@@ -458,17 +459,37 @@ static noinline int vmalloc_fault(unsigned long address)
458
459
if (pgd_none (* pgd )) {
459
460
set_pgd (pgd , * pgd_ref );
460
461
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
+ */
462
470
BUG_ON (pgd_page_vaddr (* pgd ) != pgd_page_vaddr (* pgd_ref ));
463
471
}
464
472
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
+
465
486
/*
466
487
* Below here mismatches are bugs because these lower tables
467
488
* are shared:
468
489
*/
469
490
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 );
472
493
if (pud_none (* pud_ref ))
473
494
return -1 ;
474
495
0 commit comments