diff options
author | Ingo Molnar <mingo@elte.hu> | 2009-02-13 03:47:24 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-02-13 03:47:24 -0500 |
commit | f268fe7333ccd16e3e5b7de0be1df201e40a8e7c (patch) | |
tree | bd4c6e60283f983f95e8529a7af7562a1f3b4abf /arch/x86 | |
parent | a56cdcb662032a732f7c4f35cc5a9acf37759d8c (diff) | |
parent | 0464ac9ebd90cfd5792d3c1158af848281b7eb09 (diff) |
Merge branch 'x86/mm' into x86/core
Diffstat (limited to 'arch/x86')
-rw-r--r-- | arch/x86/mm/fault.c | 21 |
1 files changed, 16 insertions, 5 deletions
diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c index 2a9ea3aee493..94c4e7262197 100644 --- a/arch/x86/mm/fault.c +++ b/arch/x86/mm/fault.c | |||
@@ -782,6 +782,15 @@ static inline int access_error(unsigned long error_code, int write, | |||
782 | return 0; | 782 | return 0; |
783 | } | 783 | } |
784 | 784 | ||
785 | static int fault_in_kernel_space(unsigned long address) | ||
786 | { | ||
787 | #ifdef CONFIG_X86_32 | ||
788 | return address >= TASK_SIZE; | ||
789 | #else /* !CONFIG_X86_32 */ | ||
790 | return address >= TASK_SIZE64; | ||
791 | #endif /* CONFIG_X86_32 */ | ||
792 | } | ||
793 | |||
785 | /* | 794 | /* |
786 | * This routine handles page faults. It determines the address, | 795 | * This routine handles page faults. It determines the address, |
787 | * and the problem, and then passes it off to one of the appropriate | 796 | * and the problem, and then passes it off to one of the appropriate |
@@ -822,11 +831,7 @@ void __kprobes do_page_fault(struct pt_regs *regs, unsigned long error_code) | |||
822 | * (error_code & 4) == 0, and that the fault was not a | 831 | * (error_code & 4) == 0, and that the fault was not a |
823 | * protection error (error_code & 9) == 0. | 832 | * protection error (error_code & 9) == 0. |
824 | */ | 833 | */ |
825 | #ifdef CONFIG_X86_32 | 834 | if (unlikely(fault_in_kernel_space(address))) { |
826 | if (unlikely(address >= TASK_SIZE)) { | ||
827 | #else | ||
828 | if (unlikely(address >= TASK_SIZE64)) { | ||
829 | #endif | ||
830 | if (!(error_code & (PF_RSVD|PF_USER|PF_PROT)) && | 835 | if (!(error_code & (PF_RSVD|PF_USER|PF_PROT)) && |
831 | vmalloc_fault(address) >= 0) | 836 | vmalloc_fault(address) >= 0) |
832 | return; | 837 | return; |
@@ -898,6 +903,12 @@ void __kprobes do_page_fault(struct pt_regs *regs, unsigned long error_code) | |||
898 | return; | 903 | return; |
899 | } | 904 | } |
900 | down_read(&mm->mmap_sem); | 905 | down_read(&mm->mmap_sem); |
906 | } else { | ||
907 | /* | ||
908 | * The above down_read_trylock() might have succeeded in which | ||
909 | * case we'll have missed the might_sleep() from down_read(). | ||
910 | */ | ||
911 | might_sleep(); | ||
901 | } | 912 | } |
902 | 913 | ||
903 | vma = find_vma(mm, address); | 914 | vma = find_vma(mm, address); |