Commit 36bf96801e3a2c4efae0bb8c1897a530fc9ca13e
Committed by
Martin Schwidefsky
1 parent
585b954e1f
[S390] fix SIGBUS handling
Raise SIGBUS with a siginfo structure. Deliver BUS_ADRERR as si_code and the address of the fault in the si_addr field. Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Showing 1 changed file with 11 additions and 3 deletions Side-by-side Diff
arch/s390/mm/fault.c
... | ... | @@ -212,14 +212,21 @@ |
212 | 212 | unsigned long trans_exc_code) |
213 | 213 | { |
214 | 214 | struct task_struct *tsk = current; |
215 | + unsigned long address; | |
216 | + struct siginfo si; | |
215 | 217 | |
216 | 218 | /* |
217 | 219 | * Send a sigbus, regardless of whether we were in kernel |
218 | 220 | * or user mode. |
219 | 221 | */ |
220 | - tsk->thread.prot_addr = trans_exc_code & __FAIL_ADDR_MASK; | |
222 | + address = trans_exc_code & __FAIL_ADDR_MASK; | |
223 | + tsk->thread.prot_addr = address; | |
221 | 224 | tsk->thread.trap_no = int_code; |
222 | - force_sig(SIGBUS, tsk); | |
225 | + si.si_signo = SIGBUS; | |
226 | + si.si_errno = 0; | |
227 | + si.si_code = BUS_ADRERR; | |
228 | + si.si_addr = (void __user *) address; | |
229 | + force_sig_info(SIGBUS, &si, tsk); | |
223 | 230 | } |
224 | 231 | |
225 | 232 | #ifdef CONFIG_S390_EXEC_PROTECT |
226 | 233 | |
... | ... | @@ -279,10 +286,11 @@ |
279 | 286 | if (fault & VM_FAULT_OOM) |
280 | 287 | pagefault_out_of_memory(); |
281 | 288 | else if (fault & VM_FAULT_SIGBUS) { |
282 | - do_sigbus(regs, int_code, trans_exc_code); | |
283 | 289 | /* Kernel mode? Handle exceptions or die */ |
284 | 290 | if (!(regs->psw.mask & PSW_MASK_PSTATE)) |
285 | 291 | do_no_context(regs, int_code, trans_exc_code); |
292 | + else | |
293 | + do_sigbus(regs, int_code, trans_exc_code); | |
286 | 294 | } else |
287 | 295 | BUG(); |
288 | 296 | break; |