Commit 98d809e7 authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] BUG register preservation

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.
parent acb977dc
...@@ -402,7 +402,6 @@ if [ "$CONFIG_DEBUG_KERNEL" != "n" ]; then ...@@ -402,7 +402,6 @@ if [ "$CONFIG_DEBUG_KERNEL" != "n" ]; then
bool ' Memory mapped I/O debugging' CONFIG_DEBUG_IOVIRT bool ' Memory mapped I/O debugging' CONFIG_DEBUG_IOVIRT
bool ' Magic SysRq key' CONFIG_MAGIC_SYSRQ bool ' Magic SysRq key' CONFIG_MAGIC_SYSRQ
bool ' Spinlock debugging' CONFIG_DEBUG_SPINLOCK bool ' Spinlock debugging' CONFIG_DEBUG_SPINLOCK
bool ' Verbose BUG() reporting (adds 70K)' CONFIG_DEBUG_BUGVERBOSE
fi fi
endmenu endmenu
......
...@@ -168,9 +168,5 @@ EXPORT_SYMBOL_NOVERS(memset); ...@@ -168,9 +168,5 @@ EXPORT_SYMBOL_NOVERS(memset);
EXPORT_SYMBOL(atomic_dec_and_lock); EXPORT_SYMBOL(atomic_dec_and_lock);
#endif #endif
#ifdef CONFIG_DEBUG_BUGVERBOSE
EXPORT_SYMBOL(do_BUG);
#endif
extern int is_sony_vaio_laptop; extern int is_sony_vaio_laptop;
EXPORT_SYMBOL(is_sony_vaio_laptop); EXPORT_SYMBOL(is_sony_vaio_laptop);
...@@ -237,6 +237,41 @@ void show_registers(struct pt_regs *regs) ...@@ -237,6 +237,41 @@ void show_registers(struct pt_regs *regs)
printk("\n"); 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; spinlock_t die_lock = SPIN_LOCK_UNLOCKED;
void die(const char * str, struct pt_regs * regs, long err) 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) ...@@ -244,6 +279,7 @@ void die(const char * str, struct pt_regs * regs, long err)
console_verbose(); console_verbose();
spin_lock_irq(&die_lock); spin_lock_irq(&die_lock);
bust_spinlocks(1); bust_spinlocks(1);
handle_BUG(regs);
printk("%s: %04lx\n", str, err & 0xffff); printk("%s: %04lx\n", str, err & 0xffff);
show_registers(regs); show_registers(regs);
bust_spinlocks(0); bust_spinlocks(0);
......
...@@ -126,12 +126,6 @@ void bust_spinlocks(int yes) ...@@ -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); asmlinkage void do_invalid_op(struct pt_regs *, unsigned long);
extern unsigned long idt; extern unsigned long idt;
......
...@@ -91,16 +91,18 @@ typedef struct { unsigned long pgprot; } pgprot_t; ...@@ -91,16 +91,18 @@ typedef struct { unsigned long pgprot; } pgprot_t;
/* /*
* Tell the user there is some problem. Beep too, so we can * Tell the user there is some problem. Beep too, so we can
* see^H^H^Hhear bugs in early bootup as well! * 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 #if 1 /* Set to zero for a slightly smaller kernel */
extern void do_BUG(const char *file, int line); #define BUG() \
#define BUG() do { \ __asm__ __volatile__( "ud2\n" \
do_BUG(__FILE__, __LINE__); \ "\t.word %c0\n" \
__asm__ __volatile__("ud2"); \ "\t.long %c1\n" \
} while (0) : : "i" (__LINE__), "i" (__FILE__))
#else #else
#define BUG() __asm__ __volatile__(".byte 0x0f,0x0b") #define BUG() __asm__ __volatile__("ud2\n")
#endif #endif
#define PAGE_BUG(page) do { \ #define PAGE_BUG(page) do { \
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment