Merge to Fedora kernel-2.6.7-1.492
[linux-2.6.git] / arch / i386 / kernel / traps.c
index 3d08b2d..2703da6 100644 (file)
@@ -99,7 +99,7 @@ static int valid_stack_ptr(struct task_struct *task, void *p)
 }
 
 #ifdef CONFIG_FRAME_POINTER
-void print_context_stack(struct task_struct *task, unsigned long *stack,
+static void print_context_stack(struct task_struct *task, unsigned long *stack,
                         unsigned long ebp)
 {
        unsigned long addr;
@@ -113,16 +113,17 @@ void print_context_stack(struct task_struct *task, unsigned long *stack,
        }
 }
 #else
-void print_context_stack(struct task_struct *task, unsigned long *stack,
+static void print_context_stack(struct task_struct *task, unsigned long *stack,
                         unsigned long ebp)
 {
        unsigned long addr;
 
        while (!kstack_end(stack)) {
                addr = *stack++;
-               if (kernel_text_address(addr)) {
-                       printk(" [<%08lx>] ", addr);
-                       print_symbol("%s\n", addr);
+               if (__kernel_text_address(addr)) {
+                       printk(" [<%08lx>]", addr);
+                       print_symbol(" %s", addr);
+                       printk("\n");
                }
        }
 }
@@ -288,6 +289,7 @@ bug:
 }
 
 spinlock_t die_lock = SPIN_LOCK_UNLOCKED;
+static int die_owner = -1;
 
 void die(const char * str, struct pt_regs * regs, long err)
 {
@@ -295,7 +297,13 @@ void die(const char * str, struct pt_regs * regs, long err)
        int nl = 0;
 
        console_verbose();
-       spin_lock_irq(&die_lock);
+       local_irq_disable();
+       if (!spin_trylock(&die_lock)) {
+               if (smp_processor_id() != die_owner)
+                       spin_lock(&die_lock);
+               /* allow recursive die to fall through */
+       }
+       die_owner = smp_processor_id();
        bust_spinlocks(1);
        handle_BUG(regs);
        printk(KERN_ALERT "%s: %04lx [#%d]\n", str, err & 0xffff, ++die_counter);
@@ -314,12 +322,17 @@ void die(const char * str, struct pt_regs * regs, long err)
        if (nl)
                printk("\n");
        show_registers(regs);
+       if (netdump_func)
+               netdump_func(regs);
        bust_spinlocks(0);
+       die_owner = -1;
        spin_unlock_irq(&die_lock);
        if (in_interrupt())
                panic("Fatal exception in interrupt");
 
        if (panic_on_oops) {
+               if (netdump_func)
+                       netdump_func = NULL;
                printk(KERN_EMERG "Fatal exception: panic in 5 seconds\n");
                set_current_state(TASK_UNINTERRUPTIBLE);
                schedule_timeout(5 * HZ);
@@ -392,7 +405,7 @@ asmlinkage void do_##name(struct pt_regs * regs, long error_code) \
        info.si_signo = signr; \
        info.si_errno = 0; \
        info.si_code = sicode; \
-       info.si_addr = (void *)siaddr; \
+       info.si_addr = (void __user *)siaddr; \
        do_trap(trapnr, signr, str, 0, regs, error_code, &info); \
 }
 
@@ -409,7 +422,7 @@ asmlinkage void do_##name(struct pt_regs * regs, long error_code) \
        info.si_signo = signr; \
        info.si_errno = 0; \
        info.si_code = sicode; \
-       info.si_addr = (void *)siaddr; \
+       info.si_addr = (void __user *)siaddr; \
        do_trap(trapnr, signr, str, 1, regs, error_code, &info); \
 }
 
@@ -677,8 +690,8 @@ asmlinkage void do_debug(struct pt_regs * regs, long error_code)
        /* If this is a kernel mode trap, save the user PC on entry to 
         * the kernel, that's what the debugger can make sense of.
         */
-       info.si_addr = ((regs->xcs & 3) == 0) ? (void *)tsk->thread.eip : 
-                                               (void *)regs->eip;
+       info.si_addr = ((regs->xcs & 3) == 0) ? (void __user *)tsk->thread.eip
+                                             : (void __user *)regs->eip;
        force_sig_info(SIGTRAP, &info, tsk);
 
        /* Disable additional traps. They'll be re-enabled when
@@ -706,7 +719,7 @@ clear_TF:
  * the correct behaviour even in the presence of the asynchronous
  * IRQ13 behaviour
  */
-void math_error(void *eip)
+void math_error(void __user *eip)
 {
        struct task_struct * task;
        siginfo_t info;
@@ -765,10 +778,10 @@ void math_error(void *eip)
 asmlinkage void do_coprocessor_error(struct pt_regs * regs, long error_code)
 {
        ignore_fpu_irq = 1;
-       math_error((void *)regs->eip);
+       math_error((void __user *)regs->eip);
 }
 
-void simd_math_error(void *eip)
+void simd_math_error(void __user *eip)
 {
        struct task_struct * task;
        siginfo_t info;
@@ -822,7 +835,7 @@ asmlinkage void do_simd_coprocessor_error(struct pt_regs * regs,
        if (cpu_has_xmm) {
                /* Handle SIMD FPU exceptions on PIII+ processors. */
                ignore_fpu_irq = 1;
-               simd_math_error((void *)regs->eip);
+               simd_math_error((void __user *)regs->eip);
        } else {
                /*
                 * Handle strange cache flush from user space exception