[S390] Use diag308 subcodes 3 and 6 for reboot and dump when possible.
[powerpc.git] / arch / s390 / kernel / traps.c
index 49dec83..52b8342 100644 (file)
 #include <linux/timer.h>
 #include <linux/mm.h>
 #include <linux/smp.h>
-#include <linux/smp_lock.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/delay.h>
 #include <linux/module.h>
+#include <linux/kdebug.h>
 #include <linux/kallsyms.h>
 #include <linux/reboot.h>
 #include <linux/kprobes.h>
 #include <linux/bug.h>
+#include <linux/utsname.h>
 #include <asm/system.h>
 #include <asm/uaccess.h>
 #include <asm/io.h>
@@ -40,7 +41,6 @@
 #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);
@@ -70,20 +70,6 @@ static int kstack_depth_to_print = 12;
 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
@@ -183,9 +169,16 @@ void show_stack(struct task_struct *task, unsigned long *sp)
  */
 void dump_stack(void)
 {
+       printk("CPU: %d %s %s %.*s\n",
+              task_thread_info(current)->cpu, print_tainted(),
+              init_utsname()->release,
+              (int)strcspn(init_utsname()->version, " "),
+              init_utsname()->version);
+       printk("Process %s (pid: %d, task: %p, ksp: %p)\n",
+              current->comm, current->pid, current,
+              (void *) current->thread.ksp);
        show_stack(NULL, NULL);
 }
-
 EXPORT_SYMBOL(dump_stack);
 
 static inline int mask_bits(struct pt_regs *regs, unsigned long bits)
@@ -268,19 +261,30 @@ void die(const char * str, struct pt_regs * regs, long err)
 {
        static int die_counter;
 
+       oops_enter();
        debug_stop_all();
        console_verbose();
        spin_lock_irq(&die_lock);
        bust_spinlocks(1);
-       printk("%s: %04lx [#%d]\n", str, err & 0xffff, ++die_counter);
-        show_regs(regs);
+       printk("%s: %04lx [#%d] ", str, err & 0xffff, ++die_counter);
+#ifdef CONFIG_PREEMPT
+       printk("PREEMPT ");
+#endif
+#ifdef CONFIG_SMP
+       printk("SMP");
+#endif
+       printk("\n");
+       notify_die(DIE_OOPS, str, regs, err, current->thread.trap_no, SIGSEGV);
+       show_regs(regs);
        bust_spinlocks(0);
-        spin_unlock_irq(&die_lock);
+       add_taint(TAINT_DIE);
+       spin_unlock_irq(&die_lock);
        if (in_interrupt())
                panic("Fatal exception in interrupt");
        if (panic_on_oops)
                panic("Fatal exception: panic_on_oops");
-        do_exit(SIGSEGV);
+       oops_exit();
+       do_exit(SIGSEGV);
 }
 
 static void inline
@@ -331,7 +335,7 @@ static void __kprobes inline do_trap(long interruption_code, int signr,
                else {
                        enum bug_trap_type btt;
 
-                       btt = report_bug(regs->psw.addr & PSW_ADDR_INSN);
+                       btt = report_bug(regs->psw.addr & PSW_ADDR_INSN, regs);
                        if (btt == BUG_TRAP_TYPE_WARN)
                                return;
                        die(str, regs, interruption_code);