aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/mm/fault.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-05-28 15:57:01 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-05-28 15:57:01 -0400
commita947e23a8ec04bccbfe98c5a2d64cd1f88b612d5 (patch)
treed64bfae3af141014e93b32036ee8cb3202655ecc /arch/x86/mm/fault.c
parent08a8b79600101fd6e13dcf05409b330e7f5b0478 (diff)
parent9a3865b185e77d1a4ca2d8356e37c19b78168961 (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.c35
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
826static noinline void 826static noinline int
827mm_fault_error(struct pt_regs *regs, unsigned long error_code, 827mm_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(&current->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(&current->mm->mmap_sem); 847 up_read(&current->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
848static int spurious_fault_check(unsigned long error_code, pte_t *pte) 863static 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 /*