diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-05-28 15:57:01 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-05-28 15:57:01 -0400 |
| commit | a947e23a8ec04bccbfe98c5a2d64cd1f88b612d5 (patch) | |
| tree | d64bfae3af141014e93b32036ee8cb3202655ecc /arch/x86/mm/fault.c | |
| parent | 08a8b79600101fd6e13dcf05409b330e7f5b0478 (diff) | |
| parent | 9a3865b185e77d1a4ca2d8356e37c19b78168961 (diff) | |
Merge branch 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
x86, asm: Clean up desc.h a bit
x86, amd: Do not enable ARAT feature on AMD processors below family 0x12
x86: Move do_page_fault()'s error path under unlikely()
x86, efi: Retain boot service code until after switching to virtual mode
x86: Remove unnecessary check in detect_ht()
x86: Reorder mm_context_t to remove x86_64 alignment padding and thus shrink mm_struct
x86, UV: Clean up uv_tlb.c
x86, UV: Add support for SGI UV2 hub chip
x86, cpufeature: Update CPU feature RDRND to RDRAND
Diffstat (limited to 'arch/x86/mm/fault.c')
| -rw-r--r-- | arch/x86/mm/fault.c | 35 |
1 files changed, 20 insertions, 15 deletions
diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c index f7a2a054a3c..2dbf6bf4c7e 100644 --- a/arch/x86/mm/fault.c +++ b/arch/x86/mm/fault.c | |||
| @@ -823,16 +823,30 @@ do_sigbus(struct pt_regs *regs, unsigned long error_code, unsigned long address, | |||
| 823 | force_sig_info_fault(SIGBUS, code, address, tsk, fault); | 823 | force_sig_info_fault(SIGBUS, code, address, tsk, fault); |
| 824 | } | 824 | } |
| 825 | 825 | ||
| 826 | static noinline void | 826 | static noinline int |
| 827 | mm_fault_error(struct pt_regs *regs, unsigned long error_code, | 827 | mm_fault_error(struct pt_regs *regs, unsigned long error_code, |
| 828 | unsigned long address, unsigned int fault) | 828 | unsigned long address, unsigned int fault) |
| 829 | { | 829 | { |
| 830 | /* | ||
| 831 | * Pagefault was interrupted by SIGKILL. We have no reason to | ||
| 832 | * continue pagefault. | ||
| 833 | */ | ||
| 834 | if (fatal_signal_pending(current)) { | ||
| 835 | if (!(fault & VM_FAULT_RETRY)) | ||
| 836 | up_read(¤t->mm->mmap_sem); | ||
| 837 | if (!(error_code & PF_USER)) | ||
| 838 | no_context(regs, error_code, address); | ||
| 839 | return 1; | ||
| 840 | } | ||
| 841 | if (!(fault & VM_FAULT_ERROR)) | ||
| 842 | return 0; | ||
| 843 | |||
| 830 | if (fault & VM_FAULT_OOM) { | 844 | if (fault & VM_FAULT_OOM) { |
| 831 | /* Kernel mode? Handle exceptions or die: */ | 845 | /* Kernel mode? Handle exceptions or die: */ |
| 832 | if (!(error_code & PF_USER)) { | 846 | if (!(error_code & PF_USER)) { |
| 833 | up_read(¤t->mm->mmap_sem); | 847 | up_read(¤t->mm->mmap_sem); |
| 834 | no_context(regs, error_code, address); | 848 | no_context(regs, error_code, address); |
| 835 | return; | 849 | return 1; |
| 836 | } | 850 | } |
| 837 | 851 | ||
| 838 | out_of_memory(regs, error_code, address); | 852 | out_of_memory(regs, error_code, address); |
| @@ -843,6 +857,7 @@ mm_fault_error(struct pt_regs *regs, unsigned long error_code, | |||
| 843 | else | 857 | else |
| 844 | BUG(); | 858 | BUG(); |
| 845 | } | 859 | } |
| 860 | return 1; | ||
| 846 | } | 861 | } |
| 847 | 862 | ||
| 848 | static int spurious_fault_check(unsigned long error_code, pte_t *pte) | 863 | static int spurious_fault_check(unsigned long error_code, pte_t *pte) |
| @@ -1133,19 +1148,9 @@ good_area: | |||
| 1133 | */ | 1148 | */ |
| 1134 | fault = handle_mm_fault(mm, vma, address, flags); | 1149 | fault = handle_mm_fault(mm, vma, address, flags); |
| 1135 | 1150 | ||
| 1136 | if (unlikely(fault & VM_FAULT_ERROR)) { | 1151 | if (unlikely(fault & (VM_FAULT_RETRY|VM_FAULT_ERROR))) { |
| 1137 | mm_fault_error(regs, error_code, address, fault); | 1152 | if (mm_fault_error(regs, error_code, address, fault)) |
| 1138 | return; | 1153 | return; |
| 1139 | } | ||
| 1140 | |||
| 1141 | /* | ||
| 1142 | * Pagefault was interrupted by SIGKILL. We have no reason to | ||
| 1143 | * continue pagefault. | ||
| 1144 | */ | ||
| 1145 | if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current)) { | ||
| 1146 | if (!(error_code & PF_USER)) | ||
| 1147 | no_context(regs, error_code, address); | ||
| 1148 | return; | ||
| 1149 | } | 1154 | } |
| 1150 | 1155 | ||
| 1151 | /* | 1156 | /* |
