aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/mm/fault.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/mm/fault.c')
-rw-r--r--arch/x86/mm/fault.c62
1 files changed, 31 insertions, 31 deletions
diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c
index e4440d0abf81..621afb6343dc 100644
--- a/arch/x86/mm/fault.c
+++ b/arch/x86/mm/fault.c
@@ -240,7 +240,8 @@ void dump_pagetable(unsigned long address)
240 pud = pud_offset(pgd, address); 240 pud = pud_offset(pgd, address);
241 if (bad_address(pud)) goto bad; 241 if (bad_address(pud)) goto bad;
242 printk("PUD %lx ", pud_val(*pud)); 242 printk("PUD %lx ", pud_val(*pud));
243 if (!pud_present(*pud)) goto ret; 243 if (!pud_present(*pud) || pud_large(*pud))
244 goto ret;
244 245
245 pmd = pmd_offset(pud, address); 246 pmd = pmd_offset(pud, address);
246 if (bad_address(pmd)) goto bad; 247 if (bad_address(pmd)) goto bad;
@@ -427,6 +428,16 @@ static noinline void pgtable_bad(unsigned long address, struct pt_regs *regs,
427} 428}
428#endif 429#endif
429 430
431static int spurious_fault_check(unsigned long error_code, pte_t *pte)
432{
433 if ((error_code & PF_WRITE) && !pte_write(*pte))
434 return 0;
435 if ((error_code & PF_INSTR) && !pte_exec(*pte))
436 return 0;
437
438 return 1;
439}
440
430/* 441/*
431 * Handle a spurious fault caused by a stale TLB entry. This allows 442 * Handle a spurious fault caused by a stale TLB entry. This allows
432 * us to lazily refresh the TLB when increasing the permissions of a 443 * us to lazily refresh the TLB when increasing the permissions of a
@@ -456,20 +467,21 @@ static int spurious_fault(unsigned long address,
456 if (!pud_present(*pud)) 467 if (!pud_present(*pud))
457 return 0; 468 return 0;
458 469
470 if (pud_large(*pud))
471 return spurious_fault_check(error_code, (pte_t *) pud);
472
459 pmd = pmd_offset(pud, address); 473 pmd = pmd_offset(pud, address);
460 if (!pmd_present(*pmd)) 474 if (!pmd_present(*pmd))
461 return 0; 475 return 0;
462 476
477 if (pmd_large(*pmd))
478 return spurious_fault_check(error_code, (pte_t *) pmd);
479
463 pte = pte_offset_kernel(pmd, address); 480 pte = pte_offset_kernel(pmd, address);
464 if (!pte_present(*pte)) 481 if (!pte_present(*pte))
465 return 0; 482 return 0;
466 483
467 if ((error_code & PF_WRITE) && !pte_write(*pte)) 484 return spurious_fault_check(error_code, pte);
468 return 0;
469 if ((error_code & PF_INSTR) && !pte_exec(*pte))
470 return 0;
471
472 return 1;
473} 485}
474 486
475/* 487/*
@@ -508,6 +520,10 @@ static int vmalloc_fault(unsigned long address)
508 pmd_t *pmd, *pmd_ref; 520 pmd_t *pmd, *pmd_ref;
509 pte_t *pte, *pte_ref; 521 pte_t *pte, *pte_ref;
510 522
523 /* Make sure we are in vmalloc area */
524 if (!(address >= VMALLOC_START && address < VMALLOC_END))
525 return -1;
526
511 /* Copy kernel mappings over when needed. This can also 527 /* Copy kernel mappings over when needed. This can also
512 happen within a race in page table update. In the later 528 happen within a race in page table update. In the later
513 case just flush. */ 529 case just flush. */
@@ -603,6 +619,9 @@ void __kprobes do_page_fault(struct pt_regs *regs, unsigned long error_code)
603 */ 619 */
604#ifdef CONFIG_X86_32 620#ifdef CONFIG_X86_32
605 if (unlikely(address >= TASK_SIZE)) { 621 if (unlikely(address >= TASK_SIZE)) {
622#else
623 if (unlikely(address >= TASK_SIZE64)) {
624#endif
606 if (!(error_code & (PF_RSVD|PF_USER|PF_PROT)) && 625 if (!(error_code & (PF_RSVD|PF_USER|PF_PROT)) &&
607 vmalloc_fault(address) >= 0) 626 vmalloc_fault(address) >= 0)
608 return; 627 return;
@@ -618,6 +637,8 @@ void __kprobes do_page_fault(struct pt_regs *regs, unsigned long error_code)
618 goto bad_area_nosemaphore; 637 goto bad_area_nosemaphore;
619 } 638 }
620 639
640
641#ifdef CONFIG_X86_32
621 /* It's safe to allow irq's after cr2 has been saved and the vmalloc 642 /* It's safe to allow irq's after cr2 has been saved and the vmalloc
622 fault has been handled. */ 643 fault has been handled. */
623 if (regs->flags & (X86_EFLAGS_IF|VM_MASK)) 644 if (regs->flags & (X86_EFLAGS_IF|VM_MASK))
@@ -630,28 +651,6 @@ void __kprobes do_page_fault(struct pt_regs *regs, unsigned long error_code)
630 if (in_atomic() || !mm) 651 if (in_atomic() || !mm)
631 goto bad_area_nosemaphore; 652 goto bad_area_nosemaphore;
632#else /* CONFIG_X86_64 */ 653#else /* CONFIG_X86_64 */
633 if (unlikely(address >= TASK_SIZE64)) {
634 /*
635 * Don't check for the module range here: its PML4
636 * is always initialized because it's shared with the main
637 * kernel text. Only vmalloc may need PML4 syncups.
638 */
639 if (!(error_code & (PF_RSVD|PF_USER|PF_PROT)) &&
640 ((address >= VMALLOC_START && address < VMALLOC_END))) {
641 if (vmalloc_fault(address) >= 0)
642 return;
643 }
644
645 /* Can handle a stale RO->RW TLB */
646 if (spurious_fault(address, error_code))
647 return;
648
649 /*
650 * Don't take the mm semaphore here. If we fixup a prefetch
651 * fault we could otherwise deadlock.
652 */
653 goto bad_area_nosemaphore;
654 }
655 if (likely(regs->flags & X86_EFLAGS_IF)) 654 if (likely(regs->flags & X86_EFLAGS_IF))
656 local_irq_enable(); 655 local_irq_enable();
657 656
@@ -959,11 +958,12 @@ void vmalloc_sync_all(void)
959 for (address = start; address <= VMALLOC_END; address += PGDIR_SIZE) { 958 for (address = start; address <= VMALLOC_END; address += PGDIR_SIZE) {
960 if (!test_bit(pgd_index(address), insync)) { 959 if (!test_bit(pgd_index(address), insync)) {
961 const pgd_t *pgd_ref = pgd_offset_k(address); 960 const pgd_t *pgd_ref = pgd_offset_k(address);
961 unsigned long flags;
962 struct page *page; 962 struct page *page;
963 963
964 if (pgd_none(*pgd_ref)) 964 if (pgd_none(*pgd_ref))
965 continue; 965 continue;
966 spin_lock(&pgd_lock); 966 spin_lock_irqsave(&pgd_lock, flags);
967 list_for_each_entry(page, &pgd_list, lru) { 967 list_for_each_entry(page, &pgd_list, lru) {
968 pgd_t *pgd; 968 pgd_t *pgd;
969 pgd = (pgd_t *)page_address(page) + pgd_index(address); 969 pgd = (pgd_t *)page_address(page) + pgd_index(address);
@@ -972,7 +972,7 @@ void vmalloc_sync_all(void)
972 else 972 else
973 BUG_ON(pgd_page_vaddr(*pgd) != pgd_page_vaddr(*pgd_ref)); 973 BUG_ON(pgd_page_vaddr(*pgd) != pgd_page_vaddr(*pgd_ref));
974 } 974 }
975 spin_unlock(&pgd_lock); 975 spin_unlock_irqrestore(&pgd_lock, flags);
976 set_bit(pgd_index(address), insync); 976 set_bit(pgd_index(address), insync);
977 } 977 }
978 if (address == start) 978 if (address == start)