diff options
Diffstat (limited to 'arch/tile/kernel/traps.c')
-rw-r--r-- | arch/tile/kernel/traps.c | 16 |
1 files changed, 9 insertions, 7 deletions
diff --git a/arch/tile/kernel/traps.c b/arch/tile/kernel/traps.c index bf841ca517bb..312fc134c1cb 100644 --- a/arch/tile/kernel/traps.c +++ b/arch/tile/kernel/traps.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/reboot.h> | 20 | #include <linux/reboot.h> |
21 | #include <linux/uaccess.h> | 21 | #include <linux/uaccess.h> |
22 | #include <linux/ptrace.h> | 22 | #include <linux/ptrace.h> |
23 | #include <linux/context_tracking.h> | ||
23 | #include <asm/stack.h> | 24 | #include <asm/stack.h> |
24 | #include <asm/traps.h> | 25 | #include <asm/traps.h> |
25 | #include <asm/setup.h> | 26 | #include <asm/setup.h> |
@@ -253,6 +254,7 @@ static int do_bpt(struct pt_regs *regs) | |||
253 | void __kprobes do_trap(struct pt_regs *regs, int fault_num, | 254 | void __kprobes do_trap(struct pt_regs *regs, int fault_num, |
254 | unsigned long reason) | 255 | unsigned long reason) |
255 | { | 256 | { |
257 | enum ctx_state prev_state = exception_enter(); | ||
256 | siginfo_t info = { 0 }; | 258 | siginfo_t info = { 0 }; |
257 | int signo, code; | 259 | int signo, code; |
258 | unsigned long address = 0; | 260 | unsigned long address = 0; |
@@ -261,7 +263,7 @@ void __kprobes do_trap(struct pt_regs *regs, int fault_num, | |||
261 | 263 | ||
262 | /* Handle breakpoints, etc. */ | 264 | /* Handle breakpoints, etc. */ |
263 | if (is_kernel && fault_num == INT_ILL && do_bpt(regs)) | 265 | if (is_kernel && fault_num == INT_ILL && do_bpt(regs)) |
264 | return; | 266 | goto done; |
265 | 267 | ||
266 | /* Re-enable interrupts, if they were previously enabled. */ | 268 | /* Re-enable interrupts, if they were previously enabled. */ |
267 | if (!(regs->flags & PT_FLAGS_DISABLE_IRQ)) | 269 | if (!(regs->flags & PT_FLAGS_DISABLE_IRQ)) |
@@ -275,7 +277,7 @@ void __kprobes do_trap(struct pt_regs *regs, int fault_num, | |||
275 | const char *name; | 277 | const char *name; |
276 | char buf[100]; | 278 | char buf[100]; |
277 | if (fixup_exception(regs)) /* ILL_TRANS or UNALIGN_DATA */ | 279 | if (fixup_exception(regs)) /* ILL_TRANS or UNALIGN_DATA */ |
278 | return; | 280 | goto done; |
279 | if (fault_num >= 0 && | 281 | if (fault_num >= 0 && |
280 | fault_num < ARRAY_SIZE(int_name) && | 282 | fault_num < ARRAY_SIZE(int_name) && |
281 | int_name[fault_num] != NULL) | 283 | int_name[fault_num] != NULL) |
@@ -294,7 +296,6 @@ void __kprobes do_trap(struct pt_regs *regs, int fault_num, | |||
294 | fault_num, name, regs->pc, buf); | 296 | fault_num, name, regs->pc, buf); |
295 | show_regs(regs); | 297 | show_regs(regs); |
296 | do_exit(SIGKILL); /* FIXME: implement i386 die() */ | 298 | do_exit(SIGKILL); /* FIXME: implement i386 die() */ |
297 | return; | ||
298 | } | 299 | } |
299 | 300 | ||
300 | switch (fault_num) { | 301 | switch (fault_num) { |
@@ -308,7 +309,6 @@ void __kprobes do_trap(struct pt_regs *regs, int fault_num, | |||
308 | pr_err("Unreadable instruction for INT_ILL: %#lx\n", | 309 | pr_err("Unreadable instruction for INT_ILL: %#lx\n", |
309 | regs->pc); | 310 | regs->pc); |
310 | do_exit(SIGKILL); | 311 | do_exit(SIGKILL); |
311 | return; | ||
312 | } | 312 | } |
313 | if (!special_ill(instr, &signo, &code)) { | 313 | if (!special_ill(instr, &signo, &code)) { |
314 | signo = SIGILL; | 314 | signo = SIGILL; |
@@ -319,7 +319,7 @@ void __kprobes do_trap(struct pt_regs *regs, int fault_num, | |||
319 | case INT_GPV: | 319 | case INT_GPV: |
320 | #if CHIP_HAS_TILE_DMA() | 320 | #if CHIP_HAS_TILE_DMA() |
321 | if (retry_gpv(reason)) | 321 | if (retry_gpv(reason)) |
322 | return; | 322 | goto done; |
323 | #endif | 323 | #endif |
324 | /*FALLTHROUGH*/ | 324 | /*FALLTHROUGH*/ |
325 | case INT_UDN_ACCESS: | 325 | case INT_UDN_ACCESS: |
@@ -346,7 +346,7 @@ void __kprobes do_trap(struct pt_regs *regs, int fault_num, | |||
346 | if (!state || | 346 | if (!state || |
347 | (void __user *)(regs->pc) != state->buffer) { | 347 | (void __user *)(regs->pc) != state->buffer) { |
348 | single_step_once(regs); | 348 | single_step_once(regs); |
349 | return; | 349 | goto done; |
350 | } | 350 | } |
351 | } | 351 | } |
352 | #endif | 352 | #endif |
@@ -380,7 +380,6 @@ void __kprobes do_trap(struct pt_regs *regs, int fault_num, | |||
380 | #endif | 380 | #endif |
381 | default: | 381 | default: |
382 | panic("Unexpected do_trap interrupt number %d", fault_num); | 382 | panic("Unexpected do_trap interrupt number %d", fault_num); |
383 | return; | ||
384 | } | 383 | } |
385 | 384 | ||
386 | info.si_signo = signo; | 385 | info.si_signo = signo; |
@@ -391,6 +390,9 @@ void __kprobes do_trap(struct pt_regs *regs, int fault_num, | |||
391 | if (signo != SIGTRAP) | 390 | if (signo != SIGTRAP) |
392 | trace_unhandled_signal("trap", regs, address, signo); | 391 | trace_unhandled_signal("trap", regs, address, signo); |
393 | force_sig_info(signo, &info, current); | 392 | force_sig_info(signo, &info, current); |
393 | |||
394 | done: | ||
395 | exception_exit(prev_state); | ||
394 | } | 396 | } |
395 | 397 | ||
396 | void kernel_double_fault(int dummy, ulong pc, ulong lr, ulong sp, ulong r52) | 398 | void kernel_double_fault(int dummy, ulong pc, ulong lr, ulong sp, ulong r52) |