[PATCH] x86: add a bootparameter to reserve high linear address space
[powerpc.git] / arch / i386 / kernel / traps.c
index 3facc8f..4fcc669 100644 (file)
@@ -92,7 +92,11 @@ asmlinkage void spurious_interrupt_bug(void);
 asmlinkage void machine_check(void);
 
 static int kstack_depth_to_print = 24;
+#ifdef CONFIG_STACK_UNWIND
 static int call_trace = 1;
+#else
+#define call_trace (-1)
+#endif
 ATOMIC_NOTIFIER_HEAD(i386die_chain);
 
 int register_die_notifier(struct notifier_block *nb)
@@ -187,22 +191,21 @@ static void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs,
                        if (unwind_init_blocked(&info, task) == 0)
                                unw_ret = show_trace_unwind(&info, log_lvl);
                }
-               if (unw_ret > 0 && !arch_unw_user_mode(&info)) {
-#ifdef CONFIG_STACK_UNWIND
-                       print_symbol("DWARF2 unwinder stuck at %s\n",
-                                    UNW_PC(info.regs));
-                       if (call_trace == 1) {
-                               printk("Leftover inexact backtrace:\n");
-                               if (UNW_SP(info.regs))
-                                       stack = (void *)UNW_SP(info.regs);
-                       } else if (call_trace > 1)
+               if (unw_ret > 0) {
+                       if (call_trace == 1 && !arch_unw_user_mode(&info)) {
+                               print_symbol("DWARF2 unwinder stuck at %s\n",
+                                            UNW_PC(&info));
+                               if (UNW_SP(&info) >= PAGE_OFFSET) {
+                                       printk("Leftover inexact backtrace:\n");
+                                       stack = (void *)UNW_SP(&info);
+                               } else
+                                       printk("Full inexact backtrace again:\n");
+                       } else if (call_trace >= 1)
                                return;
                        else
                                printk("Full inexact backtrace again:\n");
-#else
+               } else
                        printk("Inexact backtrace:\n");
-#endif
-               }
        }
 
        if (task == current) {
@@ -310,6 +313,8 @@ void show_registers(struct pt_regs *regs)
         */
        if (in_kernel) {
                u8 __user *eip;
+               int code_bytes = 64;
+               unsigned char c;
 
                printk("\n" KERN_EMERG "Stack: ");
                show_stack_log_lvl(NULL, regs, (unsigned long *)esp, KERN_EMERG);
@@ -317,9 +322,12 @@ void show_registers(struct pt_regs *regs)
                printk(KERN_EMERG "Code: ");
 
                eip = (u8 __user *)regs->eip - 43;
-               for (i = 0; i < 64; i++, eip++) {
-                       unsigned char c;
-
+               if (eip < (u8 __user *)PAGE_OFFSET || __get_user(c, eip)) {
+                       /* try starting at EIP */
+                       eip = (u8 __user *)regs->eip;
+                       code_bytes = 32;
+               }
+               for (i = 0; i < code_bytes; i++, eip++) {
                        if (eip < (u8 __user *)PAGE_OFFSET || __get_user(c, eip)) {
                                printk(" Bad EIP value.");
                                break;
@@ -453,11 +461,9 @@ void die(const char * str, struct pt_regs * regs, long err)
        if (in_interrupt())
                panic("Fatal exception in interrupt");
 
-       if (panic_on_oops) {
-               printk(KERN_EMERG "Fatal exception: panic in 5 seconds\n");
-               ssleep(5);
+       if (panic_on_oops)
                panic("Fatal exception");
-       }
+
        oops_exit();
        do_exit(SIGSEGV);
 }
@@ -1243,14 +1249,18 @@ static int __init kstack_setup(char *s)
 }
 __setup("kstack=", kstack_setup);
 
+#ifdef CONFIG_STACK_UNWIND
 static int __init call_trace_setup(char *s)
 {
        if (strcmp(s, "old") == 0)
                call_trace = -1;
        else if (strcmp(s, "both") == 0)
                call_trace = 0;
-       else if (strcmp(s, "new") == 0)
+       else if (strcmp(s, "newfallback") == 0)
                call_trace = 1;
+       else if (strcmp(s, "new") == 2)
+               call_trace = 2;
        return 1;
 }
 __setup("call_trace=", call_trace_setup);
+#endif