aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/kernel/traps.c
diff options
context:
space:
mode:
authorMartin Schwidefsky <schwidefsky@de.ibm.com>2011-07-24 04:48:33 -0400
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2011-07-24 04:48:23 -0400
commit73b7d40ff1bcd44b4245c2714b88cf872fe44685 (patch)
tree970d0fa379af2c39a45fb2cd48063634eab18213 /arch/s390/kernel/traps.c
parent4fa52aa7a82f9226b3874a69816bda3af821f002 (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.c23
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
326void __kprobes do_per_trap(struct pt_regs *regs) 326void __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
334static void default_trap_handler(struct pt_regs *regs, long pgm_int_code, 341static 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) {