11
11
#include <linux/kprobes.h> /* __kprobes, ... */
12
12
#include <linux/mmiotrace.h> /* kmmio_handler, ... */
13
13
#include <linux/perf_event.h> /* perf_sw_event */
14
+ #include <linux/hugetlb.h> /* hstate_index_to_shift */
14
15
15
16
#include <asm/traps.h> /* dotraplinkage, ... */
16
17
#include <asm/pgalloc.h> /* pgd_*(), ... */
@@ -160,15 +161,20 @@ is_prefetch(struct pt_regs *regs, unsigned long error_code, unsigned long addr)
160
161
161
162
static void
162
163
force_sig_info_fault (int si_signo , int si_code , unsigned long address ,
163
- struct task_struct * tsk )
164
+ struct task_struct * tsk , int fault )
164
165
{
166
+ unsigned lsb = 0 ;
165
167
siginfo_t info ;
166
168
167
169
info .si_signo = si_signo ;
168
170
info .si_errno = 0 ;
169
171
info .si_code = si_code ;
170
172
info .si_addr = (void __user * )address ;
171
- info .si_addr_lsb = si_code == BUS_MCEERR_AR ? PAGE_SHIFT : 0 ;
173
+ if (fault & VM_FAULT_HWPOISON_LARGE )
174
+ lsb = hstate_index_to_shift (VM_FAULT_GET_HINDEX (fault ));
175
+ if (fault & VM_FAULT_HWPOISON )
176
+ lsb = PAGE_SHIFT ;
177
+ info .si_addr_lsb = lsb ;
172
178
173
179
force_sig_info (si_signo , & info , tsk );
174
180
}
@@ -722,7 +728,7 @@ __bad_area_nosemaphore(struct pt_regs *regs, unsigned long error_code,
722
728
tsk -> thread .error_code = error_code | (address >= TASK_SIZE );
723
729
tsk -> thread .trap_no = 14 ;
724
730
725
- force_sig_info_fault (SIGSEGV , si_code , address , tsk );
731
+ force_sig_info_fault (SIGSEGV , si_code , address , tsk , 0 );
726
732
727
733
return ;
728
734
}
@@ -807,14 +813,14 @@ do_sigbus(struct pt_regs *regs, unsigned long error_code, unsigned long address,
807
813
tsk -> thread .trap_no = 14 ;
808
814
809
815
#ifdef CONFIG_MEMORY_FAILURE
810
- if (fault & VM_FAULT_HWPOISON ) {
816
+ if (fault & ( VM_FAULT_HWPOISON | VM_FAULT_HWPOISON_LARGE ) ) {
811
817
printk (KERN_ERR
812
818
"MCE: Killing %s:%d due to hardware memory corruption fault at %lx\n" ,
813
819
tsk -> comm , tsk -> pid , address );
814
820
code = BUS_MCEERR_AR ;
815
821
}
816
822
#endif
817
- force_sig_info_fault (SIGBUS , code , address , tsk );
823
+ force_sig_info_fault (SIGBUS , code , address , tsk , fault );
818
824
}
819
825
820
826
static noinline void
@@ -824,7 +830,8 @@ mm_fault_error(struct pt_regs *regs, unsigned long error_code,
824
830
if (fault & VM_FAULT_OOM ) {
825
831
out_of_memory (regs , error_code , address );
826
832
} else {
827
- if (fault & (VM_FAULT_SIGBUS |VM_FAULT_HWPOISON ))
833
+ if (fault & (VM_FAULT_SIGBUS |VM_FAULT_HWPOISON |
834
+ VM_FAULT_HWPOISON_LARGE ))
828
835
do_sigbus (regs , error_code , address , fault );
829
836
else
830
837
BUG ();
0 commit comments