]> git.hungrycats.org Git - linux/commitdiff
[PATCH] BUG register preservation
authorAndrew Morton <akpm@zip.com.au>
Mon, 18 Feb 2002 00:44:37 +0000 (16:44 -0800)
committerLinus Torvalds <torvalds@home.transmeta.com>
Mon, 18 Feb 2002 00:44:37 +0000 (16:44 -0800)
Here's the x86 BUG() implementation we discussed the other day.

I also have the rework of the header files which avoids
instantiation of strings in headers and saves 100-200k.
However that is only needed for gcc 2.X.  I assume that
by the time 2.6 is in use, gcc-3.x will be the preferred
compiler.

arch/i386/config.in
arch/i386/kernel/i386_ksyms.c
arch/i386/kernel/traps.c
arch/i386/mm/fault.c
include/asm-i386/page.h

index 484d3fa49e256c9a8280906ed3791a0b20a8d534..d1366bced858c2f4cd15816f8add36d544193772 100644 (file)
@@ -402,7 +402,6 @@ if [ "$CONFIG_DEBUG_KERNEL" != "n" ]; then
    bool '  Memory mapped I/O debugging' CONFIG_DEBUG_IOVIRT
    bool '  Magic SysRq key' CONFIG_MAGIC_SYSRQ
    bool '  Spinlock debugging' CONFIG_DEBUG_SPINLOCK
-   bool '  Verbose BUG() reporting (adds 70K)' CONFIG_DEBUG_BUGVERBOSE
 fi
 
 endmenu
index 5823bf1facca606d9906947d5baebaa7d7e26a31..5e21e7a4629b7b042adeb08b8b82ce9e228e60e3 100644 (file)
@@ -168,9 +168,5 @@ EXPORT_SYMBOL_NOVERS(memset);
 EXPORT_SYMBOL(atomic_dec_and_lock);
 #endif
 
-#ifdef CONFIG_DEBUG_BUGVERBOSE
-EXPORT_SYMBOL(do_BUG);
-#endif
-
 extern int is_sony_vaio_laptop;
 EXPORT_SYMBOL(is_sony_vaio_laptop);
index 7c2c2520d1c19c1871d1631c1b478c63565b99d2..d1f43dd571b15f8c318ea5f33b9beb010ffe0101 100644 (file)
@@ -237,6 +237,41 @@ bad:
        printk("\n");
 }      
 
+static void handle_BUG(struct pt_regs *regs)
+{
+       unsigned short ud2;
+       unsigned short line;
+       char *file;
+       char c;
+       unsigned long eip;
+
+       if (regs->xcs & 3)
+               goto no_bug;            /* Not in kernel */
+
+       eip = regs->eip;
+
+       if (eip < PAGE_OFFSET)
+               goto no_bug;
+       if (__get_user(ud2, (unsigned short *)eip))
+               goto no_bug;
+       if (ud2 != 0x0b0f)
+               goto no_bug;
+       if (__get_user(line, (unsigned short *)(eip + 2)))
+               goto bug;
+       if (__get_user(file, (char **)(eip + 4)) ||
+               (unsigned long)file < PAGE_OFFSET || __get_user(c, file))
+               file = "<bad filename>";
+
+       printk("kernel BUG at %s:%d!\n", file, line);
+
+no_bug:
+       return;
+
+       /* Here we know it was a BUG but file-n-line is unavailable */
+bug:
+       printk("Kernel BUG\n");
+}
+
 spinlock_t die_lock = SPIN_LOCK_UNLOCKED;
 
 void die(const char * str, struct pt_regs * regs, long err)
@@ -244,6 +279,7 @@ void die(const char * str, struct pt_regs * regs, long err)
        console_verbose();
        spin_lock_irq(&die_lock);
        bust_spinlocks(1);
+       handle_BUG(regs);
        printk("%s: %04lx\n", str, err & 0xffff);
        show_registers(regs);
        bust_spinlocks(0);
index c1f8bca8fd153b6b001d709b498fb6574dde8af8..42f8deb62b1a65fba50fc4154aa10c6c87632918 100644 (file)
@@ -126,12 +126,6 @@ void bust_spinlocks(int yes)
        }
 }
 
-void do_BUG(const char *file, int line)
-{
-       bust_spinlocks(1);
-       printk("kernel BUG at %s:%d!\n", file, line);
-}
-
 asmlinkage void do_invalid_op(struct pt_regs *, unsigned long);
 extern unsigned long idt;
 
index fe30fa8abc741a4812918dbe0ffd0af9b7f8eb61..90424fd6f6543d043f6e07ff4656c3dbee50e85c 100644 (file)
@@ -91,16 +91,18 @@ typedef struct { unsigned long pgprot; } pgprot_t;
 /*
  * Tell the user there is some problem. Beep too, so we can
  * see^H^H^Hhear bugs in early bootup as well!
+ * The offending file and line are encoded after the "officially
+ * undefined" opcode for parsing in the trap handler.
  */
 
-#ifdef CONFIG_DEBUG_BUGVERBOSE
-extern void do_BUG(const char *file, int line);
-#define BUG() do {                                     \
-       do_BUG(__FILE__, __LINE__);                     \
-       __asm__ __volatile__("ud2");                    \
-} while (0)
+#if 1  /* Set to zero for a slightly smaller kernel */
+#define BUG()                          \
+ __asm__ __volatile__( "ud2\n"         \
+                       "\t.word %c0\n" \
+                       "\t.long %c1\n" \
+                        : : "i" (__LINE__), "i" (__FILE__))
 #else
-#define BUG() __asm__ __volatile__(".byte 0x0f,0x0b")
+#define BUG() __asm__ __volatile__("ud2\n")
 #endif
 
 #define PAGE_BUG(page) do { \