aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/mm/fault.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2008-12-31 02:31:57 -0500
committerIngo Molnar <mingo@elte.hu>2008-12-31 02:31:57 -0500
commita9de18eb761f7c1c860964b2e5addc1a35c7e861 (patch)
tree886e75fdfd09690cd262ca69cb7f5d1d42b48602 /arch/x86/mm/fault.c
parentb2aaf8f74cdc84a9182f6cabf198b7763bcb9d40 (diff)
parent6a94cb73064c952255336cc57731904174b2c58f (diff)
Merge branch 'linus' into stackprotector
Conflicts: arch/x86/include/asm/pda.h kernel/fork.c
Diffstat (limited to 'arch/x86/mm/fault.c')
-rw-r--r--arch/x86/mm/fault.c60
1 files changed, 26 insertions, 34 deletions
diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c
index d18ea136d8a..4c056b5d6a9 100644
--- a/arch/x86/mm/fault.c
+++ b/arch/x86/mm/fault.c
@@ -54,7 +54,7 @@
54 54
55static inline int kmmio_fault(struct pt_regs *regs, unsigned long addr) 55static inline int kmmio_fault(struct pt_regs *regs, unsigned long addr)
56{ 56{
57#ifdef CONFIG_MMIOTRACE_HOOKS 57#ifdef CONFIG_MMIOTRACE
58 if (unlikely(is_kmmio_active())) 58 if (unlikely(is_kmmio_active()))
59 if (kmmio_handler(regs, addr) == 1) 59 if (kmmio_handler(regs, addr) == 1)
60 return -1; 60 return -1;
@@ -394,7 +394,7 @@ static void show_fault_oops(struct pt_regs *regs, unsigned long error_code,
394 if (pte && pte_present(*pte) && !pte_exec(*pte)) 394 if (pte && pte_present(*pte) && !pte_exec(*pte))
395 printk(KERN_CRIT "kernel tried to execute " 395 printk(KERN_CRIT "kernel tried to execute "
396 "NX-protected page - exploit attempt? " 396 "NX-protected page - exploit attempt? "
397 "(uid: %d)\n", current->uid); 397 "(uid: %d)\n", current_uid());
398 } 398 }
399#endif 399#endif
400 400
@@ -414,6 +414,7 @@ static noinline void pgtable_bad(unsigned long address, struct pt_regs *regs,
414 unsigned long error_code) 414 unsigned long error_code)
415{ 415{
416 unsigned long flags = oops_begin(); 416 unsigned long flags = oops_begin();
417 int sig = SIGKILL;
417 struct task_struct *tsk; 418 struct task_struct *tsk;
418 419
419 printk(KERN_ALERT "%s: Corrupted page table at address %lx\n", 420 printk(KERN_ALERT "%s: Corrupted page table at address %lx\n",
@@ -424,8 +425,8 @@ static noinline void pgtable_bad(unsigned long address, struct pt_regs *regs,
424 tsk->thread.trap_no = 14; 425 tsk->thread.trap_no = 14;
425 tsk->thread.error_code = error_code; 426 tsk->thread.error_code = error_code;
426 if (__die("Bad pagetable", regs, error_code)) 427 if (__die("Bad pagetable", regs, error_code))
427 regs = NULL; 428 sig = 0;
428 oops_end(flags, regs, SIGKILL); 429 oops_end(flags, regs, sig);
429} 430}
430#endif 431#endif
431 432
@@ -593,6 +594,7 @@ void __kprobes do_page_fault(struct pt_regs *regs, unsigned long error_code)
593 594
594#ifdef CONFIG_X86_64 595#ifdef CONFIG_X86_64
595 unsigned long flags; 596 unsigned long flags;
597 int sig;
596#endif 598#endif
597 599
598 tsk = current; 600 tsk = current;
@@ -643,24 +645,23 @@ void __kprobes do_page_fault(struct pt_regs *regs, unsigned long error_code)
643 } 645 }
644 646
645 647
646#ifdef CONFIG_X86_32
647 /* It's safe to allow irq's after cr2 has been saved and the vmalloc
648 fault has been handled. */
649 if (regs->flags & (X86_EFLAGS_IF | X86_VM_MASK))
650 local_irq_enable();
651
652 /* 648 /*
653 * If we're in an interrupt, have no user context or are running in an 649 * It's safe to allow irq's after cr2 has been saved and the
654 * atomic region then we must not take the fault. 650 * vmalloc fault has been handled.
651 *
652 * User-mode registers count as a user access even for any
653 * potential system fault or CPU buglet.
655 */ 654 */
656 if (in_atomic() || !mm) 655 if (user_mode_vm(regs)) {
657 goto bad_area_nosemaphore; 656 local_irq_enable();
658#else /* CONFIG_X86_64 */ 657 error_code |= PF_USER;
659 if (likely(regs->flags & X86_EFLAGS_IF)) 658 } else if (regs->flags & X86_EFLAGS_IF)
660 local_irq_enable(); 659 local_irq_enable();
661 660
661#ifdef CONFIG_X86_64
662 if (unlikely(error_code & PF_RSVD)) 662 if (unlikely(error_code & PF_RSVD))
663 pgtable_bad(address, regs, error_code); 663 pgtable_bad(address, regs, error_code);
664#endif
664 665
665 /* 666 /*
666 * If we're in an interrupt, have no user context or are running in an 667 * If we're in an interrupt, have no user context or are running in an
@@ -669,15 +670,9 @@ void __kprobes do_page_fault(struct pt_regs *regs, unsigned long error_code)
669 if (unlikely(in_atomic() || !mm)) 670 if (unlikely(in_atomic() || !mm))
670 goto bad_area_nosemaphore; 671 goto bad_area_nosemaphore;
671 672
672 /*
673 * User-mode registers count as a user access even for any
674 * potential system fault or CPU buglet.
675 */
676 if (user_mode_vm(regs))
677 error_code |= PF_USER;
678again: 673again:
679#endif 674 /*
680 /* When running in the kernel we expect faults to occur only to 675 * When running in the kernel we expect faults to occur only to
681 * addresses in user space. All other faults represent errors in the 676 * addresses in user space. All other faults represent errors in the
682 * kernel and should generate an OOPS. Unfortunately, in the case of an 677 * kernel and should generate an OOPS. Unfortunately, in the case of an
683 * erroneous fault occurring in a code path which already holds mmap_sem 678 * erroneous fault occurring in a code path which already holds mmap_sem
@@ -740,9 +735,6 @@ good_area:
740 goto bad_area; 735 goto bad_area;
741 } 736 }
742 737
743#ifdef CONFIG_X86_32
744survive:
745#endif
746 /* 738 /*
747 * If for any reason at all we couldn't handle the fault, 739 * If for any reason at all we couldn't handle the fault,
748 * make sure we exit gracefully rather than endlessly redo 740 * make sure we exit gracefully rather than endlessly redo
@@ -866,11 +858,12 @@ no_context:
866 bust_spinlocks(0); 858 bust_spinlocks(0);
867 do_exit(SIGKILL); 859 do_exit(SIGKILL);
868#else 860#else
861 sig = SIGKILL;
869 if (__die("Oops", regs, error_code)) 862 if (__die("Oops", regs, error_code))
870 regs = NULL; 863 sig = 0;
871 /* Executive summary in case the body of the oops scrolled away */ 864 /* Executive summary in case the body of the oops scrolled away */
872 printk(KERN_EMERG "CR2: %016lx\n", address); 865 printk(KERN_EMERG "CR2: %016lx\n", address);
873 oops_end(flags, regs, SIGKILL); 866 oops_end(flags, regs, sig);
874#endif 867#endif
875 868
876/* 869/*
@@ -881,12 +874,11 @@ out_of_memory:
881 up_read(&mm->mmap_sem); 874 up_read(&mm->mmap_sem);
882 if (is_global_init(tsk)) { 875 if (is_global_init(tsk)) {
883 yield(); 876 yield();
884#ifdef CONFIG_X86_32 877 /*
885 down_read(&mm->mmap_sem); 878 * Re-lookup the vma - in theory the vma tree might
886 goto survive; 879 * have changed:
887#else 880 */
888 goto again; 881 goto again;
889#endif
890 } 882 }
891 883
892 printk("VM: killing process %s\n", tsk->comm); 884 printk("VM: killing process %s\n", tsk->comm);