aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/kernel/traps.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/s390/kernel/traps.c')
-rw-r--r--arch/s390/kernel/traps.c38
1 files changed, 22 insertions, 16 deletions
diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c
index a65d2e82f61..ffabcd9d336 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>
@@ -36,21 +36,17 @@
36#include <asm/system.h> 36#include <asm/system.h>
37#include <asm/uaccess.h> 37#include <asm/uaccess.h>
38#include <asm/io.h> 38#include <asm/io.h>
39#include <asm/atomic.h> 39#include <linux/atomic.h>
40#include <asm/mathemu.h> 40#include <asm/mathemu.h>
41#include <asm/cpcmd.h> 41#include <asm/cpcmd.h>
42#include <asm/lowcore.h> 42#include <asm/lowcore.h>
43#include <asm/debug.h> 43#include <asm/debug.h>
44#include "entry.h" 44#include "entry.h"
45 45
46pgm_check_handler_t *pgm_check_table[128]; 46void (*pgm_check_table[128])(struct pt_regs *, long, unsigned long);
47 47
48int show_unhandled_signals; 48int show_unhandled_signals;
49 49
50extern pgm_check_handler_t do_protection_exception;
51extern pgm_check_handler_t do_dat_exception;
52extern pgm_check_handler_t do_asce_exception;
53
54#define stack_pointer ({ void **sp; asm("la %0,0(15)" : "=&d" (sp)); sp; }) 50#define stack_pointer ({ void **sp; asm("la %0,0(15)" : "=&d" (sp)); sp; })
55 51
56#ifndef CONFIG_64BIT 52#ifndef CONFIG_64BIT
@@ -329,10 +325,17 @@ static inline void __user *get_psw_address(struct pt_regs *regs,
329 325
330void __kprobes do_per_trap(struct pt_regs *regs) 326void __kprobes do_per_trap(struct pt_regs *regs)
331{ 327{
328 siginfo_t info;
329
332 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)
333 return; 331 return;
334 if (tracehook_consider_fatal_signal(current, SIGTRAP)) 332 if (!current->ptrace)
335 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);
336} 339}
337 340
338static 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,
@@ -425,9 +428,13 @@ static void __kprobes illegal_op(struct pt_regs *regs, long pgm_int_code,
425 if (get_user(*((__u16 *) opcode), (__u16 __user *) location)) 428 if (get_user(*((__u16 *) opcode), (__u16 __user *) location))
426 return; 429 return;
427 if (*((__u16 *) opcode) == S390_BREAKPOINT_U16) { 430 if (*((__u16 *) opcode) == S390_BREAKPOINT_U16) {
428 if (tracehook_consider_fatal_signal(current, SIGTRAP)) 431 if (current->ptrace) {
429 force_sig(SIGTRAP, current); 432 info.si_signo = SIGTRAP;
430 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
431 signal = SIGILL; 438 signal = SIGILL;
432#ifdef CONFIG_MATHEMU 439#ifdef CONFIG_MATHEMU
433 } else if (opcode[0] == 0xb3) { 440 } else if (opcode[0] == 0xb3) {
@@ -489,9 +496,8 @@ static void __kprobes illegal_op(struct pt_regs *regs, long pgm_int_code,
489 496
490 497
491#ifdef CONFIG_MATHEMU 498#ifdef CONFIG_MATHEMU
492asmlinkage void specification_exception(struct pt_regs *regs, 499void specification_exception(struct pt_regs *regs, long pgm_int_code,
493 long pgm_int_code, 500 unsigned long trans_exc_code)
494 unsigned long trans_exc_code)
495{ 501{
496 __u8 opcode[6]; 502 __u8 opcode[6];
497 __u16 __user *location = NULL; 503 __u16 __user *location = NULL;
@@ -648,7 +654,7 @@ static void space_switch_exception(struct pt_regs *regs, long pgm_int_code,
648 do_trap(pgm_int_code, SIGILL, "space switch event", regs, &info); 654 do_trap(pgm_int_code, SIGILL, "space switch event", regs, &info);
649} 655}
650 656
651asmlinkage void __kprobes kernel_stack_overflow(struct pt_regs * regs) 657void __kprobes kernel_stack_overflow(struct pt_regs * regs)
652{ 658{
653 bust_spinlocks(1); 659 bust_spinlocks(1);
654 printk("Kernel stack overflow.\n"); 660 printk("Kernel stack overflow.\n");