diff options
Diffstat (limited to 'arch/tile/kernel/traps.c')
| -rw-r--r-- | arch/tile/kernel/traps.c | 15 |
1 files changed, 12 insertions, 3 deletions
diff --git a/arch/tile/kernel/traps.c b/arch/tile/kernel/traps.c index 2bb6602a1ee7..73cff814ac57 100644 --- a/arch/tile/kernel/traps.c +++ b/arch/tile/kernel/traps.c | |||
| @@ -200,7 +200,7 @@ void __kprobes do_trap(struct pt_regs *regs, int fault_num, | |||
| 200 | { | 200 | { |
| 201 | siginfo_t info = { 0 }; | 201 | siginfo_t info = { 0 }; |
| 202 | int signo, code; | 202 | int signo, code; |
| 203 | unsigned long address; | 203 | unsigned long address = 0; |
| 204 | bundle_bits instr; | 204 | bundle_bits instr; |
| 205 | 205 | ||
| 206 | /* Re-enable interrupts. */ | 206 | /* Re-enable interrupts. */ |
| @@ -223,6 +223,10 @@ void __kprobes do_trap(struct pt_regs *regs, int fault_num, | |||
| 223 | } | 223 | } |
| 224 | 224 | ||
| 225 | switch (fault_num) { | 225 | switch (fault_num) { |
| 226 | case INT_MEM_ERROR: | ||
| 227 | signo = SIGBUS; | ||
| 228 | code = BUS_OBJERR; | ||
| 229 | break; | ||
| 226 | case INT_ILL: | 230 | case INT_ILL: |
| 227 | if (copy_from_user(&instr, (void __user *)regs->pc, | 231 | if (copy_from_user(&instr, (void __user *)regs->pc, |
| 228 | sizeof(instr))) { | 232 | sizeof(instr))) { |
| @@ -289,7 +293,10 @@ void __kprobes do_trap(struct pt_regs *regs, int fault_num, | |||
| 289 | address = regs->pc; | 293 | address = regs->pc; |
| 290 | break; | 294 | break; |
| 291 | #ifdef __tilegx__ | 295 | #ifdef __tilegx__ |
| 292 | case INT_ILL_TRANS: | 296 | case INT_ILL_TRANS: { |
| 297 | /* Avoid a hardware erratum with the return address stack. */ | ||
| 298 | fill_ra_stack(); | ||
| 299 | |||
| 293 | signo = SIGSEGV; | 300 | signo = SIGSEGV; |
| 294 | code = SEGV_MAPERR; | 301 | code = SEGV_MAPERR; |
| 295 | if (reason & SPR_ILL_TRANS_REASON__I_STREAM_VA_RMASK) | 302 | if (reason & SPR_ILL_TRANS_REASON__I_STREAM_VA_RMASK) |
| @@ -297,6 +304,7 @@ void __kprobes do_trap(struct pt_regs *regs, int fault_num, | |||
| 297 | else | 304 | else |
| 298 | address = 0; /* FIXME: GX: single-step for address */ | 305 | address = 0; /* FIXME: GX: single-step for address */ |
| 299 | break; | 306 | break; |
| 307 | } | ||
| 300 | #endif | 308 | #endif |
| 301 | default: | 309 | default: |
| 302 | panic("Unexpected do_trap interrupt number %d", fault_num); | 310 | panic("Unexpected do_trap interrupt number %d", fault_num); |
| @@ -308,7 +316,8 @@ void __kprobes do_trap(struct pt_regs *regs, int fault_num, | |||
| 308 | info.si_addr = (void __user *)address; | 316 | info.si_addr = (void __user *)address; |
| 309 | if (signo == SIGILL) | 317 | if (signo == SIGILL) |
| 310 | info.si_trapno = fault_num; | 318 | info.si_trapno = fault_num; |
| 311 | trace_unhandled_signal("trap", regs, address, signo); | 319 | if (signo != SIGTRAP) |
| 320 | trace_unhandled_signal("trap", regs, address, signo); | ||
| 312 | force_sig_info(signo, &info, current); | 321 | force_sig_info(signo, &info, current); |
| 313 | } | 322 | } |
| 314 | 323 | ||
