Merge branch 'for-linus' of ssh://master.kernel.org/pub/scm/linux/kernel/git/ieee1394...
[pandora-kernel.git] / arch / i386 / kernel / traps.c
index 2b30dbf..af0d3f7 100644 (file)
@@ -94,11 +94,7 @@ asmlinkage void spurious_interrupt_bug(void);
 asmlinkage void machine_check(void);
 
 int kstack_depth_to_print = 24;
-#ifdef CONFIG_STACK_UNWIND
-static int call_trace = 1;
-#else
-#define call_trace (-1)
-#endif
+static unsigned int code_bytes = 64;
 ATOMIC_NOTIFIER_HEAD(i386die_chain);
 
 int register_die_notifier(struct notifier_block *nb)
@@ -152,33 +148,6 @@ static inline unsigned long print_context_stack(struct thread_info *tinfo,
        return ebp;
 }
 
-struct ops_and_data {
-       struct stacktrace_ops *ops;
-       void *data;
-};
-
-static asmlinkage int
-dump_trace_unwind(struct unwind_frame_info *info, void *data)
-{
-       struct ops_and_data *oad = (struct ops_and_data *)data;
-       int n = 0;
-       unsigned long sp = UNW_SP(info);
-
-       if (arch_unw_user_mode(info))
-               return -1;
-       while (unwind(info) == 0 && UNW_PC(info)) {
-               n++;
-               oad->ops->address(oad->data, UNW_PC(info));
-               if (arch_unw_user_mode(info))
-                       break;
-               if ((sp & ~(PAGE_SIZE - 1)) == (UNW_SP(info) & ~(PAGE_SIZE - 1))
-                   && sp > UNW_SP(info))
-                       break;
-               sp = UNW_SP(info);
-       }
-       return n;
-}
-
 #define MSG(msg) ops->warning(data, msg)
 
 void dump_trace(struct task_struct *task, struct pt_regs *regs,
@@ -190,41 +159,6 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs,
        if (!task)
                task = current;
 
-       if (call_trace >= 0) {
-               int unw_ret = 0;
-               struct unwind_frame_info info;
-               struct ops_and_data oad = { .ops = ops, .data = data };
-
-               if (regs) {
-                       if (unwind_init_frame_info(&info, task, regs) == 0)
-                               unw_ret = dump_trace_unwind(&info, &oad);
-               } else if (task == current)
-                       unw_ret = unwind_init_running(&info, dump_trace_unwind,
-                                                     &oad);
-               else {
-                       if (unwind_init_blocked(&info, task) == 0)
-                               unw_ret = dump_trace_unwind(&info, &oad);
-               }
-               if (unw_ret > 0) {
-                       if (call_trace == 1 && !arch_unw_user_mode(&info)) {
-                               ops->warning_symbol(data,
-                                            "DWARF2 unwinder stuck at %s",
-                                            UNW_PC(&info));
-                               if (UNW_SP(&info) >= PAGE_OFFSET) {
-                                       MSG("Leftover inexact backtrace:");
-                                       stack = (void *)UNW_SP(&info);
-                                       if (!stack)
-                                               return;
-                                       ebp = UNW_FP(&info);
-                               } else
-                                       MSG("Full inexact backtrace again:");
-                       } else if (call_trace >= 1)
-                               return;
-                       else
-                               MSG("Full inexact backtrace again:");
-               } else
-                       MSG("Inexact backtrace:");
-       }
        if (!stack) {
                unsigned long dummy;
                stack = &dummy;
@@ -358,10 +292,11 @@ void show_registers(struct pt_regs *regs)
        int i;
        int in_kernel = 1;
        unsigned long esp;
-       unsigned short ss;
+       unsigned short ss, gs;
 
        esp = (unsigned long) (&regs->esp);
        savesegment(ss, ss);
+       savesegment(gs, gs);
        if (user_mode_vm(regs)) {
                in_kernel = 0;
                esp = regs->esp;
@@ -380,8 +315,8 @@ void show_registers(struct pt_regs *regs)
                regs->eax, regs->ebx, regs->ecx, regs->edx);
        printk(KERN_EMERG "esi: %08lx   edi: %08lx   ebp: %08lx   esp: %08lx\n",
                regs->esi, regs->edi, regs->ebp, esp);
-       printk(KERN_EMERG "ds: %04x   es: %04x   ss: %04x\n",
-               regs->xds & 0xffff, regs->xes & 0xffff, ss);
+       printk(KERN_EMERG "ds: %04x   es: %04x   fs: %04x  gs: %04x  ss: %04x\n",
+              regs->xds & 0xffff, regs->xes & 0xffff, regs->xfs & 0xffff, gs, ss);
        printk(KERN_EMERG "Process %.*s (pid: %d, ti=%p task=%p task.ti=%p)",
                TASK_COMM_LEN, current->comm, current->pid,
                current_thread_info(), current, current->thread_info);
@@ -391,7 +326,8 @@ void show_registers(struct pt_regs *regs)
         */
        if (in_kernel) {
                u8 *eip;
-               int code_bytes = 64;
+               unsigned int code_prologue = code_bytes * 43 / 64;
+               unsigned int code_len = code_bytes;
                unsigned char c;
 
                printk("\n" KERN_EMERG "Stack: ");
@@ -399,14 +335,14 @@ void show_registers(struct pt_regs *regs)
 
                printk(KERN_EMERG "Code: ");
 
-               eip = (u8 *)regs->eip - 43;
+               eip = (u8 *)regs->eip - code_prologue;
                if (eip < (u8 *)PAGE_OFFSET ||
                        probe_kernel_address(eip, c)) {
                        /* try starting at EIP */
                        eip = (u8 *)regs->eip;
-                       code_bytes = 32;
+                       code_len = code_len - code_prologue + 1;
                }
-               for (i = 0; i < code_bytes; i++, eip++) {
+               for (i = 0; i < code_len; i++, eip++) {
                        if (eip < (u8 *)PAGE_OFFSET ||
                                probe_kernel_address(eip, c)) {
                                printk(" Bad EIP value.");
@@ -1259,18 +1195,12 @@ static int __init kstack_setup(char *s)
 }
 __setup("kstack=", kstack_setup);
 
-#ifdef CONFIG_STACK_UNWIND
-static int __init call_trace_setup(char *s)
+static int __init code_bytes_setup(char *s)
 {
-       if (strcmp(s, "old") == 0)
-               call_trace = -1;
-       else if (strcmp(s, "both") == 0)
-               call_trace = 0;
-       else if (strcmp(s, "newfallback") == 0)
-               call_trace = 1;
-       else if (strcmp(s, "new") == 2)
-               call_trace = 2;
+       code_bytes = simple_strtoul(s, NULL, 0);
+       if (code_bytes > 8192)
+               code_bytes = 8192;
+
        return 1;
 }
-__setup("call_trace=", call_trace_setup);
-#endif
+__setup("code_bytes=", code_bytes_setup);