aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/mm/fault.c45
-rw-r--r--include/asm-x86/pgtable.h7
2 files changed, 23 insertions, 29 deletions
diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c
index 3f2b8962cbd0..31e8730fa246 100644
--- a/arch/x86/mm/fault.c
+++ b/arch/x86/mm/fault.c
@@ -640,24 +640,23 @@ void __kprobes do_page_fault(struct pt_regs *regs, unsigned long error_code)
640 } 640 }
641 641
642 642
643#ifdef CONFIG_X86_32
644 /* It's safe to allow irq's after cr2 has been saved and the vmalloc
645 fault has been handled. */
646 if (regs->flags & (X86_EFLAGS_IF | X86_VM_MASK))
647 local_irq_enable();
648
649 /* 643 /*
650 * If we're in an interrupt, have no user context or are running in an 644 * It's safe to allow irq's after cr2 has been saved and the
651 * atomic region then we must not take the fault. 645 * vmalloc fault has been handled.
646 *
647 * User-mode registers count as a user access even for any
648 * potential system fault or CPU buglet.
652 */ 649 */
653 if (in_atomic() || !mm) 650 if (user_mode_vm(regs)) {
654 goto bad_area_nosemaphore; 651 local_irq_enable();
655#else /* CONFIG_X86_64 */ 652 error_code |= PF_USER;
656 if (likely(regs->flags & X86_EFLAGS_IF)) 653 } else if (regs->flags & X86_EFLAGS_IF)
657 local_irq_enable(); 654 local_irq_enable();
658 655
656#ifdef CONFIG_X86_64
659 if (unlikely(error_code & PF_RSVD)) 657 if (unlikely(error_code & PF_RSVD))
660 pgtable_bad(address, regs, error_code); 658 pgtable_bad(address, regs, error_code);
659#endif
661 660
662 /* 661 /*
663 * If we're in an interrupt, have no user context or are running in an 662 * If we're in an interrupt, have no user context or are running in an
@@ -666,15 +665,9 @@ void __kprobes do_page_fault(struct pt_regs *regs, unsigned long error_code)
666 if (unlikely(in_atomic() || !mm)) 665 if (unlikely(in_atomic() || !mm))
667 goto bad_area_nosemaphore; 666 goto bad_area_nosemaphore;
668 667
669 /*
670 * User-mode registers count as a user access even for any
671 * potential system fault or CPU buglet.
672 */
673 if (user_mode_vm(regs))
674 error_code |= PF_USER;
675again: 668again:
676#endif 669 /*
677 /* When running in the kernel we expect faults to occur only to 670 * When running in the kernel we expect faults to occur only to
678 * addresses in user space. All other faults represent errors in the 671 * addresses in user space. All other faults represent errors in the
679 * kernel and should generate an OOPS. Unfortunately, in the case of an 672 * kernel and should generate an OOPS. Unfortunately, in the case of an
680 * erroneous fault occurring in a code path which already holds mmap_sem 673 * erroneous fault occurring in a code path which already holds mmap_sem
@@ -737,9 +730,6 @@ good_area:
737 goto bad_area; 730 goto bad_area;
738 } 731 }
739 732
740#ifdef CONFIG_X86_32
741survive:
742#endif
743 /* 733 /*
744 * If for any reason at all we couldn't handle the fault, 734 * If for any reason at all we couldn't handle the fault,
745 * make sure we exit gracefully rather than endlessly redo 735 * make sure we exit gracefully rather than endlessly redo
@@ -874,12 +864,11 @@ out_of_memory:
874 up_read(&mm->mmap_sem); 864 up_read(&mm->mmap_sem);
875 if (is_global_init(tsk)) { 865 if (is_global_init(tsk)) {
876 yield(); 866 yield();
877#ifdef CONFIG_X86_32 867 /*
878 down_read(&mm->mmap_sem); 868 * Re-lookup the vma - in theory the vma tree might
879 goto survive; 869 * have changed:
880#else 870 */
881 goto again; 871 goto again;
882#endif
883 } 872 }
884 873
885 printk("VM: killing process %s\n", tsk->comm); 874 printk("VM: killing process %s\n", tsk->comm);
diff --git a/include/asm-x86/pgtable.h b/include/asm-x86/pgtable.h
index 182f9d4c570f..88a53b1a17f0 100644
--- a/include/asm-x86/pgtable.h
+++ b/include/asm-x86/pgtable.h
@@ -148,8 +148,13 @@
148#ifdef CONFIG_X86_64 148#ifdef CONFIG_X86_64
149#define __PAGE_KERNEL_IDENT_LARGE_EXEC __PAGE_KERNEL_LARGE_EXEC 149#define __PAGE_KERNEL_IDENT_LARGE_EXEC __PAGE_KERNEL_LARGE_EXEC
150#else 150#else
151/*
152 * For PDE_IDENT_ATTR include USER bit. As the PDE and PTE protection
153 * bits are combined, this will alow user to access the high address mapped
154 * VDSO in the presence of CONFIG_COMPAT_VDSO
155 */
151#define PTE_IDENT_ATTR 0x003 /* PRESENT+RW */ 156#define PTE_IDENT_ATTR 0x003 /* PRESENT+RW */
152#define PDE_IDENT_ATTR 0x063 /* PRESENT+RW+DIRTY+ACCESSED */ 157#define PDE_IDENT_ATTR 0x067 /* PRESENT+RW+USER+DIRTY+ACCESSED */
153#define PGD_IDENT_ATTR 0x001 /* PRESENT (no other attributes) */ 158#define PGD_IDENT_ATTR 0x001 /* PRESENT (no other attributes) */
154#endif 159#endif
155 160