Pull sbs into release branch
[pandora-kernel.git] / arch / arm / kernel / traps.c
index f05e66b..f2114bc 100644 (file)
@@ -181,9 +181,7 @@ static void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk)
 
 void dump_stack(void)
 {
-#ifdef CONFIG_DEBUG_ERRORS
        __backtrace();
-#endif
 }
 
 EXPORT_SYMBOL(dump_stack);
@@ -204,12 +202,24 @@ void show_stack(struct task_struct *tsk, unsigned long *sp)
        barrier();
 }
 
+#ifdef CONFIG_PREEMPT
+#define S_PREEMPT " PREEMPT"
+#else
+#define S_PREEMPT ""
+#endif
+#ifdef CONFIG_SMP
+#define S_SMP " SMP"
+#else
+#define S_SMP ""
+#endif
+
 static void __die(const char *str, int err, struct thread_info *thread, struct pt_regs *regs)
 {
        struct task_struct *tsk = thread->task;
        static int die_counter;
 
-       printk("Internal error: %s: %x [#%d]\n", str, err, ++die_counter);
+       printk("Internal error: %s: %x [#%d]" S_PREEMPT S_SMP "\n",
+              str, err, ++die_counter);
        print_modules();
        __show_regs(regs);
        printk("Process %s (pid: %d, stack limit = 0x%p)\n",
@@ -232,21 +242,28 @@ NORET_TYPE void die(const char *str, struct pt_regs *regs, int err)
 {
        struct thread_info *thread = current_thread_info();
 
+       oops_enter();
+
        console_verbose();
        spin_lock_irq(&die_lock);
        bust_spinlocks(1);
        __die(str, err, thread, regs);
        bust_spinlocks(0);
+       add_taint(TAINT_DIE);
        spin_unlock_irq(&die_lock);
 
+       if (in_interrupt())
+               panic("Fatal exception in interrupt");
+
        if (panic_on_oops)
                panic("Fatal exception");
 
+       oops_exit();
        do_exit(SIGSEGV);
 }
 
-void notify_die(const char *str, struct pt_regs *regs, struct siginfo *info,
-               unsigned long err, unsigned long trap)
+void arm_notify_die(const char *str, struct pt_regs *regs,
+               struct siginfo *info, unsigned long err, unsigned long trap)
 {
        if (user_mode(regs)) {
                current->thread.error_code = err;
@@ -330,7 +347,7 @@ asmlinkage void __exception do_undefinstr(struct pt_regs *regs)
        info.si_code  = ILL_ILLOPC;
        info.si_addr  = pc;
 
-       notify_die("Oops - undefined instruction", regs, &info, 0, 6);
+       arm_notify_die("Oops - undefined instruction", regs, &info, 0, 6);
 }
 
 asmlinkage void do_unexp_fiq (struct pt_regs *regs)
@@ -384,7 +401,7 @@ static int bad_syscall(int n, struct pt_regs *regs)
        info.si_addr  = (void __user *)instruction_pointer(regs) -
                         (thumb_mode(regs) ? 2 : 4);
 
-       notify_die("Oops - bad syscall", regs, &info, n, 0);
+       arm_notify_die("Oops - bad syscall", regs, &info, n, 0);
 
        return regs->ARM_r0;
 }
@@ -428,7 +445,7 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs)
                info.si_code  = SEGV_MAPERR;
                info.si_addr  = NULL;
 
-               notify_die("branch through zero", regs, &info, 0, 0);
+               arm_notify_die("branch through zero", regs, &info, 0, 0);
                return 0;
 
        case NR(breakpoint): /* SWI BREAK_POINT */
@@ -564,7 +581,7 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs)
        info.si_addr  = (void __user *)instruction_pointer(regs) -
                         (thumb_mode(regs) ? 2 : 4);
 
-       notify_die("Oops - bad syscall(2)", regs, &info, no, 0);
+       arm_notify_die("Oops - bad syscall(2)", regs, &info, no, 0);
        return 0;
 }
 
@@ -638,7 +655,7 @@ baddataabort(int code, unsigned long instr, struct pt_regs *regs)
        info.si_code  = ILL_ILLOPC;
        info.si_addr  = (void __user *)addr;
 
-       notify_die("unknown data abort code", regs, &info, instr, 0);
+       arm_notify_die("unknown data abort code", regs, &info, instr, 0);
 }
 
 void __attribute__((noreturn)) __bug(const char *file, int line)