Merge branch 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ieee13...
[pandora-kernel.git] / arch / i386 / kernel / traps.c
index 5c0f496..6820b8d 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/kprobes.h>
 #include <linux/kexec.h>
 #include <linux/unwind.h>
+#include <linux/uaccess.h>
 
 #ifdef CONFIG_EISA
 #include <linux/ioport.h>
@@ -40,7 +41,6 @@
 
 #include <asm/processor.h>
 #include <asm/system.h>
-#include <asm/uaccess.h>
 #include <asm/io.h>
 #include <asm/atomic.h>
 #include <asm/debugreg.h>
@@ -57,6 +57,8 @@
 
 #include "mach_traps.h"
 
+int panic_on_unrecovered_nmi;
+
 asmlinkage int system_call(void);
 
 struct desc_struct default_ldt[] = { { 0, 0 }, { 0, 0 }, { 0, 0 },
@@ -351,8 +353,9 @@ void show_registers(struct pt_regs *regs)
                ss = regs->xss & 0xffff;
        }
        print_modules();
-       printk(KERN_EMERG "CPU:    %d\nEIP:    %04x:[<%08lx>]    %s VLI\n"
-                       "EFLAGS: %08lx   (%s %.*s) \n",
+       printk(KERN_EMERG "CPU:    %d\n"
+               KERN_EMERG "EIP:    %04x:[<%08lx>]    %s VLI\n"
+               KERN_EMERG "EFLAGS: %08lx   (%s %.*s)\n",
                smp_processor_id(), 0xffff & regs->xcs, regs->eip,
                print_tainted(), regs->eflags, system_utsname.release,
                (int)strcspn(system_utsname.version, " "),
@@ -373,6 +376,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);
@@ -380,9 +385,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;
@@ -403,7 +411,7 @@ static void handle_BUG(struct pt_regs *regs)
 
        if (eip < PAGE_OFFSET)
                return;
-       if (__get_user(ud2, (unsigned short __user *)eip))
+       if (probe_kernel_address((unsigned short __user *)eip, ud2))
                return;
        if (ud2 != 0x0b0f)
                return;
@@ -416,7 +424,8 @@ static void handle_BUG(struct pt_regs *regs)
                char *file;
                char c;
 
-               if (__get_user(line, (unsigned short __user *)(eip + 2)))
+               if (probe_kernel_address((unsigned short __user *)(eip + 2),
+                                       line))
                        break;
                if (__get_user(file, (char * __user *)(eip + 4)) ||
                    (unsigned long)file < PAGE_OFFSET || __get_user(c, file))