Merge branch 'classmate' into release
[safe/jmp/linux-2.6] / arch / s390 / kernel / traps.c
index b352413..6e7ad63 100644 (file)
@@ -18,7 +18,7 @@
 #include <linux/kernel.h>
 #include <linux/string.h>
 #include <linux/errno.h>
-#include <linux/ptrace.h>
+#include <linux/tracehook.h>
 #include <linux/timer.h>
 #include <linux/mm.h>
 #include <linux/smp.h>
@@ -61,9 +61,11 @@ extern pgm_check_handler_t do_asce_exception;
 #define stack_pointer ({ void **sp; asm("la %0,0(15)" : "=&d" (sp)); sp; })
 
 #ifndef CONFIG_64BIT
+#define LONG "%08lx "
 #define FOURLONG "%08lx %08lx %08lx %08lx\n"
 static int kstack_depth_to_print = 12;
 #else /* CONFIG_64BIT */
+#define LONG "%016lx "
 #define FOURLONG "%016lx %016lx %016lx %016lx\n"
 static int kstack_depth_to_print = 20;
 #endif /* CONFIG_64BIT */
@@ -113,7 +115,7 @@ __show_trace(unsigned long sp, unsigned long low, unsigned long high)
        }
 }
 
-void show_trace(struct task_struct *task, unsigned long *stack)
+static void show_trace(struct task_struct *task, unsigned long *stack)
 {
        register unsigned long __r15 asm ("15");
        unsigned long sp;
@@ -134,7 +136,6 @@ void show_trace(struct task_struct *task, unsigned long *stack)
        else
                __show_trace(sp, S390_lowcore.thread_info,
                             S390_lowcore.thread_info + THREAD_SIZE);
-       printk("\n");
        if (!task)
                task = current;
        debug_show_held_locks(task);
@@ -156,12 +157,21 @@ void show_stack(struct task_struct *task, unsigned long *sp)
                        break;
                if (i && ((i * sizeof (long) % 32) == 0))
                        printk("\n       ");
-               printk("%p ", (void *)*stack++);
+               printk(LONG, *stack++);
        }
        printk("\n");
        show_trace(task, sp);
 }
 
+static void show_last_breaking_event(struct pt_regs *regs)
+{
+#ifdef CONFIG_64BIT
+       printk("Last Breaking-Event-Address:\n");
+       printk(" [<%016lx>] ", regs->args[0] & PSW_ADDR_INSN);
+       print_symbol("%s\n", regs->args[0] & PSW_ADDR_INSN);
+#endif
+}
+
 /*
  * The architecture-independent dump_stack generator
  */
@@ -215,6 +225,24 @@ void show_registers(struct pt_regs *regs)
        show_code(regs);
 }      
 
+void show_regs(struct pt_regs *regs)
+{
+       print_modules();
+       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_registers(regs);
+       /* Show stack backtrace if pt_regs is from kernel mode */
+       if (!(regs->psw.mask & PSW_MASK_PSTATE))
+               show_trace(NULL, (unsigned long *) regs->gprs[15]);
+       show_last_breaking_event(regs);
+}
+
 /* This is called from fs/proc/array.c */
 void task_show_regs(struct seq_file *m, struct task_struct *task)
 {
@@ -354,7 +382,7 @@ void __kprobes do_single_step(struct pt_regs *regs)
                                        SIGTRAP) == NOTIFY_STOP){
                return;
        }
-       if ((current->ptrace & PT_PTRACED) != 0)
+       if (tracehook_consider_fatal_signal(current, SIGTRAP))
                force_sig(SIGTRAP, current);
 }
 
@@ -455,7 +483,7 @@ static void illegal_op(struct pt_regs * regs, long interruption_code)
                if (get_user(*((__u16 *) opcode), (__u16 __user *) location))
                        return;
                if (*((__u16 *) opcode) == S390_BREAKPOINT_U16) {
-                       if (current->ptrace & PT_PTRACED)
+                       if (tracehook_consider_fatal_signal(current, SIGTRAP))
                                force_sig(SIGTRAP, current);
                        else
                                signal = SIGILL;