|
@@ -212,14 +212,21 @@ static noinline void do_sigbus(struct pt_regs *regs, long int_code,
|
|
|
unsigned long trans_exc_code)
|
|
|
{
|
|
|
struct task_struct *tsk = current;
|
|
|
+ unsigned long address;
|
|
|
+ struct siginfo si;
|
|
|
|
|
|
/*
|
|
|
* Send a sigbus, regardless of whether we were in kernel
|
|
|
* or user mode.
|
|
|
*/
|
|
|
- tsk->thread.prot_addr = trans_exc_code & __FAIL_ADDR_MASK;
|
|
|
+ address = trans_exc_code & __FAIL_ADDR_MASK;
|
|
|
+ tsk->thread.prot_addr = address;
|
|
|
tsk->thread.trap_no = int_code;
|
|
|
- force_sig(SIGBUS, tsk);
|
|
|
+ si.si_signo = SIGBUS;
|
|
|
+ si.si_errno = 0;
|
|
|
+ si.si_code = BUS_ADRERR;
|
|
|
+ si.si_addr = (void __user *) address;
|
|
|
+ force_sig_info(SIGBUS, &si, tsk);
|
|
|
}
|
|
|
|
|
|
#ifdef CONFIG_S390_EXEC_PROTECT
|
|
@@ -279,10 +286,11 @@ static noinline void do_fault_error(struct pt_regs *regs, long int_code,
|
|
|
if (fault & VM_FAULT_OOM)
|
|
|
pagefault_out_of_memory();
|
|
|
else if (fault & VM_FAULT_SIGBUS) {
|
|
|
- do_sigbus(regs, int_code, trans_exc_code);
|
|
|
/* Kernel mode? Handle exceptions or die */
|
|
|
if (!(regs->psw.mask & PSW_MASK_PSTATE))
|
|
|
do_no_context(regs, int_code, trans_exc_code);
|
|
|
+ else
|
|
|
+ do_sigbus(regs, int_code, trans_exc_code);
|
|
|
} else
|
|
|
BUG();
|
|
|
break;
|