]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - arch/x86/kernel/traps_64.c
Merge git://git.kernel.org/pub/scm/linux/kernel/git/x86/linux-2.6-x86
[linux-2.6-omap-h63xx.git] / arch / x86 / kernel / traps_64.c
index 03888420775d03320f0cea3c40989e100fea3e7c..d11525ad81b40676cd99736cf729329993b580ab 100644 (file)
@@ -1,6 +1,4 @@
 /*
- *  linux/arch/x86-64/traps.c
- *
  *  Copyright (C) 1991, 1992  Linus Torvalds
  *  Copyright (C) 2000, 2001, 2002 Andi Kleen, SuSE Labs
  *
@@ -33,6 +31,7 @@
 #include <linux/uaccess.h>
 #include <linux/bug.h>
 #include <linux/kdebug.h>
+#include <linux/utsname.h>
 
 #if defined(CONFIG_EDAC)
 #include <linux/edac.h>
@@ -203,7 +202,7 @@ static unsigned long *in_exception_stack(unsigned cpu, unsigned long stack,
 #define MSG(txt) ops->warning(data, txt)
 
 /*
- * x86-64 can have upto three kernel stacks: 
+ * x86-64 can have up to three kernel stacks: 
  * process stack
  * interrupt stack
  * severe exception (double fault, nmi, stack fault, debug, mce) hardware stack
@@ -217,7 +216,7 @@ static inline int valid_stack_ptr(struct thread_info *tinfo, void *p)
 
 void dump_trace(struct task_struct *tsk, struct pt_regs *regs,
                unsigned long *stack,
-               struct stacktrace_ops *ops, void *data)
+               const struct stacktrace_ops *ops, void *data)
 {
        const unsigned cpu = get_cpu();
        unsigned long *irqstack_end = (unsigned long*)cpu_pda(cpu)->irqstackptr;
@@ -338,7 +337,7 @@ static void print_trace_address(void *data, unsigned long addr)
        printk_address(addr);
 }
 
-static struct stacktrace_ops print_trace_ops = {
+static const struct stacktrace_ops print_trace_ops = {
        .warning = print_trace_warning,
        .warning_symbol = print_trace_warning_symbol,
        .stack = print_trace_stack,
@@ -402,6 +401,12 @@ void show_stack(struct task_struct *tsk, unsigned long * rsp)
 void dump_stack(void)
 {
        unsigned long dummy;
+
+       printk("Pid: %d, comm: %.20s %s %s %.*s\n",
+               current->pid, current->comm, print_tainted(),
+               init_utsname()->release,
+               (int)strcspn(init_utsname()->version, " "),
+               init_utsname()->version);
        show_trace(NULL, NULL, &dummy);
 }
 
@@ -464,7 +469,7 @@ void out_of_line_bug(void)
 EXPORT_SYMBOL(out_of_line_bug);
 #endif
 
-static DEFINE_SPINLOCK(die_lock);
+static raw_spinlock_t die_lock = __RAW_SPIN_LOCK_UNLOCKED;
 static int die_owner = -1;
 static unsigned int die_nest_count;
 
@@ -476,13 +481,13 @@ unsigned __kprobes long oops_begin(void)
        oops_enter();
 
        /* racy, but better than risking deadlock. */
-       local_irq_save(flags);
+       raw_local_irq_save(flags);
        cpu = smp_processor_id();
-       if (!spin_trylock(&die_lock)) { 
+       if (!__raw_spin_trylock(&die_lock)) {
                if (cpu == die_owner) 
                        /* nested oops. should stop eventually */;
                else
-                       spin_lock(&die_lock);
+                       __raw_spin_lock(&die_lock);
        }
        die_nest_count++;
        die_owner = cpu;
@@ -496,12 +501,10 @@ void __kprobes oops_end(unsigned long flags)
        die_owner = -1;
        bust_spinlocks(0);
        die_nest_count--;
-       if (die_nest_count)
-               /* We still own the lock */
-               local_irq_restore(flags);
-       else
+       if (!die_nest_count)
                /* Nest count reaches zero, release the lock. */
-               spin_unlock_irqrestore(&die_lock, flags);
+               __raw_spin_unlock(&die_lock);
+       raw_local_irq_restore(flags);
        if (panic_on_oops)
                panic("Fatal exception");
        oops_exit();
@@ -811,6 +814,8 @@ asmlinkage __kprobes void default_do_nmi(struct pt_regs *regs)
 /* runs on IST stack. */
 asmlinkage void __kprobes do_int3(struct pt_regs * regs, long error_code)
 {
+       trace_hardirqs_fixup();
+
        if (notify_die(DIE_INT3, "int3", regs, error_code, 3, SIGTRAP) == NOTIFY_STOP) {
                return;
        }
@@ -848,6 +853,8 @@ asmlinkage void __kprobes do_debug(struct pt_regs * regs,
        struct task_struct *tsk = current;
        siginfo_t info;
 
+       trace_hardirqs_fixup();
+
        get_debugreg(condition, 6);
 
        if (notify_die(DIE_DEBUG, "debug", regs, condition, error_code,