* 'Traps.c' handles hardware traps and faults after we have saved some
* state in 'asm.s'.
*/
-#include <linux/config.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/module.h>
#include <linux/kallsyms.h>
#include <linux/reboot.h>
+#include <linux/kprobes.h>
#include <asm/system.h>
#include <asm/uaccess.h>
#include <asm/s390_ext.h>
#include <asm/lowcore.h>
#include <asm/debug.h>
+#include <asm/kdebug.h>
/* Called from entry.S only */
extern void handle_per_exception(struct pt_regs *regs);
#ifdef CONFIG_PFAULT
extern int pfault_init(void);
extern void pfault_fini(void);
-extern void pfault_interrupt(struct pt_regs *regs, __u16 error_code);
+extern void pfault_interrupt(__u16 error_code);
static ext_int_info_t ext_int_pfault;
#endif
extern pgm_check_handler_t do_monitor_call;
static int kstack_depth_to_print = 20;
#endif /* CONFIG_64BIT */
+ATOMIC_NOTIFIER_HEAD(s390die_chain);
+
+int register_die_notifier(struct notifier_block *nb)
+{
+ return atomic_notifier_chain_register(&s390die_chain, nb);
+}
+EXPORT_SYMBOL(register_die_notifier);
+
+int unregister_die_notifier(struct notifier_block *nb)
+{
+ return atomic_notifier_chain_unregister(&s390die_chain, nb);
+}
+EXPORT_SYMBOL(unregister_die_notifier);
+
/*
* For show_trace we have tree different stack to consider:
* - the panic stack which is used if the kernel stack has overflown
unsigned long *stack;
int i;
- // debugging aid: "show_stack(NULL);" prints the
- // back trace for this cpu.
-
if (!sp)
- sp = task ? (unsigned long *) task->thread.ksp : __r15;
+ stack = task ? (unsigned long *) task->thread.ksp : __r15;
+ else
+ stack = sp;
- stack = sp;
for (i = 0; i < kstack_depth_to_print; i++) {
if (((addr_t) stack & (THREAD_SIZE-1)) == 0)
break;
*/
void dump_stack(void)
{
- show_stack(0, 0);
+ show_stack(NULL, NULL);
}
EXPORT_SYMBOL(dump_stack);
#endif
}
-static void inline do_trap(long interruption_code, int signr, char *str,
- struct pt_regs *regs, siginfo_t *info)
+static void __kprobes inline do_trap(long interruption_code, int signr,
+ char *str, struct pt_regs *regs,
+ siginfo_t *info)
{
/*
* We got all needed information from the lowcore and can
if (regs->psw.mask & PSW_MASK_PSTATE)
local_irq_enable();
+ if (notify_die(DIE_TRAP, str, regs, interruption_code,
+ interruption_code, signr) == NOTIFY_STOP)
+ return;
+
if (regs->psw.mask & PSW_MASK_PSTATE) {
struct task_struct *tsk = current;
}
}
-static inline void *get_check_address(struct pt_regs *regs)
+static inline void __user *get_check_address(struct pt_regs *regs)
{
- return (void *)((regs->psw.addr-S390_lowcore.pgm_ilc) & PSW_ADDR_INSN);
+ return (void __user *)((regs->psw.addr-S390_lowcore.pgm_ilc) & PSW_ADDR_INSN);
}
-void do_single_step(struct pt_regs *regs)
+void __kprobes do_single_step(struct pt_regs *regs)
{
+ if (notify_die(DIE_SSTEP, "sstep", regs, 0, 0,
+ SIGTRAP) == NOTIFY_STOP){
+ return;
+ }
if ((current->ptrace & PT_PTRACED) != 0)
force_sig(SIGTRAP, current);
}
info.si_signo = signr; \
info.si_errno = 0; \
info.si_code = sicode; \
- info.si_addr = (void *)siaddr; \
+ info.si_addr = siaddr; \
do_trap(interruption_code, signr, str, regs, &info); \
}
ILL_ILLOPN, get_check_address(regs))
static inline void
-do_fp_trap(struct pt_regs *regs, void *location,
+do_fp_trap(struct pt_regs *regs, void __user *location,
int fpc, long interruption_code)
{
siginfo_t si;
{
siginfo_t info;
__u8 opcode[6];
- __u16 *location;
+ __u16 __user *location;
int signal = 0;
- location = (__u16 *) get_check_address(regs);
+ location = get_check_address(regs);
/*
* We got all needed information from the lowcore and can
asmlinkage void data_exception(struct pt_regs * regs, long interruption_code)
{
- __u16 *location;
+ __u16 __user *location;
int signal = 0;
- location = (__u16 *) get_check_address(regs);
+ location = get_check_address(regs);
/*
* We got all needed information from the lowcore and can
local_irq_enable();
if (MACHINE_HAS_IEEE)
- __asm__ volatile ("stfpc %0\n\t"
- : "=m" (current->thread.fp_regs.fpc));
+ asm volatile("stfpc %0" : "=m" (current->thread.fp_regs.fpc));
#ifdef CONFIG_MATHEMU
else if (regs->psw.mask & PSW_MASK_PSTATE) {