diff options
author | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2011-07-24 04:48:33 -0400 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2011-07-24 04:48:23 -0400 |
commit | 73b7d40ff1bcd44b4245c2714b88cf872fe44685 (patch) | |
tree | 970d0fa379af2c39a45fb2cd48063634eab18213 /arch/s390/kernel/traps.c | |
parent | 4fa52aa7a82f9226b3874a69816bda3af821f002 (diff) |
[S390] use siginfo for sigtrap signals
Provide additional information on SIGTRAP by using a sig_info signal.
Use TRAP_BRKPT for breakpoints via illegal operation and TRAP_HWBKPT
for breakpoints via program event recording. Provide the address of
the instruction that caused the breakpoint via si_addr.
While we are at it get rid of tracehook_consider_fatal_signal.
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch/s390/kernel/traps.c')
-rw-r--r-- | arch/s390/kernel/traps.c | 23 |
1 files changed, 17 insertions, 6 deletions
diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c index f386e167277a..e9372c77cced 100644 --- a/arch/s390/kernel/traps.c +++ b/arch/s390/kernel/traps.c | |||
@@ -18,7 +18,7 @@ | |||
18 | #include <linux/kernel.h> | 18 | #include <linux/kernel.h> |
19 | #include <linux/string.h> | 19 | #include <linux/string.h> |
20 | #include <linux/errno.h> | 20 | #include <linux/errno.h> |
21 | #include <linux/tracehook.h> | 21 | #include <linux/ptrace.h> |
22 | #include <linux/timer.h> | 22 | #include <linux/timer.h> |
23 | #include <linux/mm.h> | 23 | #include <linux/mm.h> |
24 | #include <linux/smp.h> | 24 | #include <linux/smp.h> |
@@ -325,10 +325,17 @@ static inline void __user *get_psw_address(struct pt_regs *regs, | |||
325 | 325 | ||
326 | void __kprobes do_per_trap(struct pt_regs *regs) | 326 | void __kprobes do_per_trap(struct pt_regs *regs) |
327 | { | 327 | { |
328 | siginfo_t info; | ||
329 | |||
328 | if (notify_die(DIE_SSTEP, "sstep", regs, 0, 0, SIGTRAP) == NOTIFY_STOP) | 330 | if (notify_die(DIE_SSTEP, "sstep", regs, 0, 0, SIGTRAP) == NOTIFY_STOP) |
329 | return; | 331 | return; |
330 | if (current->ptrace) | 332 | if (!current->ptrace) |
331 | force_sig(SIGTRAP, current); | 333 | return; |
334 | info.si_signo = SIGTRAP; | ||
335 | info.si_errno = 0; | ||
336 | info.si_code = TRAP_HWBKPT; | ||
337 | info.si_addr = (void *) current->thread.per_event.address; | ||
338 | force_sig_info(SIGTRAP, &info, current); | ||
332 | } | 339 | } |
333 | 340 | ||
334 | static void default_trap_handler(struct pt_regs *regs, long pgm_int_code, | 341 | static void default_trap_handler(struct pt_regs *regs, long pgm_int_code, |
@@ -421,9 +428,13 @@ static void __kprobes illegal_op(struct pt_regs *regs, long pgm_int_code, | |||
421 | if (get_user(*((__u16 *) opcode), (__u16 __user *) location)) | 428 | if (get_user(*((__u16 *) opcode), (__u16 __user *) location)) |
422 | return; | 429 | return; |
423 | if (*((__u16 *) opcode) == S390_BREAKPOINT_U16) { | 430 | if (*((__u16 *) opcode) == S390_BREAKPOINT_U16) { |
424 | if (current->ptrace) | 431 | if (current->ptrace) { |
425 | force_sig(SIGTRAP, current); | 432 | info.si_signo = SIGTRAP; |
426 | else | 433 | info.si_errno = 0; |
434 | info.si_code = TRAP_BRKPT; | ||
435 | info.si_addr = location; | ||
436 | force_sig_info(SIGTRAP, &info, current); | ||
437 | } else | ||
427 | signal = SIGILL; | 438 | signal = SIGILL; |
428 | #ifdef CONFIG_MATHEMU | 439 | #ifdef CONFIG_MATHEMU |
429 | } else if (opcode[0] == 0xb3) { | 440 | } else if (opcode[0] == 0xb3) { |