Commit 73b7d40f authored by Martin Schwidefsky's avatar Martin Schwidefsky

[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: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
parent 4fa52aa7
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/string.h> #include <linux/string.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/tracehook.h> #include <linux/ptrace.h>
#include <linux/timer.h> #include <linux/timer.h>
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/smp.h> #include <linux/smp.h>
...@@ -325,10 +325,17 @@ static inline void __user *get_psw_address(struct pt_regs *regs, ...@@ -325,10 +325,17 @@ static inline void __user *get_psw_address(struct pt_regs *regs,
void __kprobes do_per_trap(struct pt_regs *regs) void __kprobes do_per_trap(struct pt_regs *regs)
{ {
siginfo_t info;
if (notify_die(DIE_SSTEP, "sstep", regs, 0, 0, SIGTRAP) == NOTIFY_STOP) if (notify_die(DIE_SSTEP, "sstep", regs, 0, 0, SIGTRAP) == NOTIFY_STOP)
return; return;
if (current->ptrace) if (!current->ptrace)
force_sig(SIGTRAP, current); return;
info.si_signo = SIGTRAP;
info.si_errno = 0;
info.si_code = TRAP_HWBKPT;
info.si_addr = (void *) current->thread.per_event.address;
force_sig_info(SIGTRAP, &info, current);
} }
static void default_trap_handler(struct pt_regs *regs, long pgm_int_code, 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,9 +428,13 @@ static void __kprobes illegal_op(struct pt_regs *regs, long pgm_int_code,
if (get_user(*((__u16 *) opcode), (__u16 __user *) location)) if (get_user(*((__u16 *) opcode), (__u16 __user *) location))
return; return;
if (*((__u16 *) opcode) == S390_BREAKPOINT_U16) { if (*((__u16 *) opcode) == S390_BREAKPOINT_U16) {
if (current->ptrace) if (current->ptrace) {
force_sig(SIGTRAP, current); info.si_signo = SIGTRAP;
else info.si_errno = 0;
info.si_code = TRAP_BRKPT;
info.si_addr = location;
force_sig_info(SIGTRAP, &info, current);
} else
signal = SIGILL; signal = SIGILL;
#ifdef CONFIG_MATHEMU #ifdef CONFIG_MATHEMU
} else if (opcode[0] == 0xb3) { } else if (opcode[0] == 0xb3) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment