aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/mm/fault.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2009-10-17 03:58:25 -0400
committerIngo Molnar <mingo@elte.hu>2009-10-17 03:58:25 -0400
commitbb3c3e807140816b5f5fd4840473ee52a916ad4f (patch)
tree9e8a69d266a7df86ca16177eefffab4b4e910753 /arch/x86/mm/fault.c
parent595c36490deb49381dc51231a3d5e6b66786ed27 (diff)
parent012abeea669ea49636cf952d13298bb68654146a (diff)
Merge commit 'v2.6.32-rc5' into perf/probes
Conflicts: kernel/trace/trace_event_profile.c Merge reason: update to -rc5 and resolve conflict. Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/mm/fault.c')
-rw-r--r--arch/x86/mm/fault.c19
1 files changed, 15 insertions, 4 deletions
diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c
index 923ea3fb7037..8f4e2ac93928 100644
--- a/arch/x86/mm/fault.c
+++ b/arch/x86/mm/fault.c
@@ -168,6 +168,7 @@ force_sig_info_fault(int si_signo, int si_code, unsigned long address,
168 info.si_errno = 0; 168 info.si_errno = 0;
169 info.si_code = si_code; 169 info.si_code = si_code;
170 info.si_addr = (void __user *)address; 170 info.si_addr = (void __user *)address;
171 info.si_addr_lsb = si_code == BUS_MCEERR_AR ? PAGE_SHIFT : 0;
171 172
172 force_sig_info(si_signo, &info, tsk); 173 force_sig_info(si_signo, &info, tsk);
173} 174}
@@ -791,10 +792,12 @@ out_of_memory(struct pt_regs *regs, unsigned long error_code,
791} 792}
792 793
793static void 794static void
794do_sigbus(struct pt_regs *regs, unsigned long error_code, unsigned long address) 795do_sigbus(struct pt_regs *regs, unsigned long error_code, unsigned long address,
796 unsigned int fault)
795{ 797{
796 struct task_struct *tsk = current; 798 struct task_struct *tsk = current;
797 struct mm_struct *mm = tsk->mm; 799 struct mm_struct *mm = tsk->mm;
800 int code = BUS_ADRERR;
798 801
799 up_read(&mm->mmap_sem); 802 up_read(&mm->mmap_sem);
800 803
@@ -810,7 +813,15 @@ do_sigbus(struct pt_regs *regs, unsigned long error_code, unsigned long address)
810 tsk->thread.error_code = error_code; 813 tsk->thread.error_code = error_code;
811 tsk->thread.trap_no = 14; 814 tsk->thread.trap_no = 14;
812 815
813 force_sig_info_fault(SIGBUS, BUS_ADRERR, address, tsk); 816#ifdef CONFIG_MEMORY_FAILURE
817 if (fault & VM_FAULT_HWPOISON) {
818 printk(KERN_ERR
819 "MCE: Killing %s:%d due to hardware memory corruption fault at %lx\n",
820 tsk->comm, tsk->pid, address);
821 code = BUS_MCEERR_AR;
822 }
823#endif
824 force_sig_info_fault(SIGBUS, code, address, tsk);
814} 825}
815 826
816static noinline void 827static noinline void
@@ -820,8 +831,8 @@ mm_fault_error(struct pt_regs *regs, unsigned long error_code,
820 if (fault & VM_FAULT_OOM) { 831 if (fault & VM_FAULT_OOM) {
821 out_of_memory(regs, error_code, address); 832 out_of_memory(regs, error_code, address);
822 } else { 833 } else {
823 if (fault & VM_FAULT_SIGBUS) 834 if (fault & (VM_FAULT_SIGBUS|VM_FAULT_HWPOISON))
824 do_sigbus(regs, error_code, address); 835 do_sigbus(regs, error_code, address, fault);
825 else 836 else
826 BUG(); 837 BUG();
827 } 838 }