diff options
author | Jeremy Fitzhardinge <jeremy@goop.org> | 2006-12-08 05:36:21 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.osdl.org> | 2006-12-08 11:28:39 -0500 |
commit | 91768d6c2bad0d2766a166f13f2f57e197de3458 (patch) | |
tree | 3857842d8635b2032c84c5e2e1b05181cd48ca65 /arch/i386/kernel/traps.c | |
parent | 7664c5a1da4711bb6383117f51b94c8dc8f3f1cd (diff) |
[PATCH] Generic BUG for i386
This makes i386 use the generic BUG machinery. There are no functional
changes from the old i386 implementation.
The main advantage in using the generic BUG machinery for i386 is that the
inlined overhead of BUG is just the ud2a instruction; the file+line(+function)
information are no longer inlined into the instruction stream. This reduces
cache pollution, and makes disassembly work properly.
Signed-off-by: Jeremy Fitzhardinge <jeremy@goop.org>
Cc: Andi Kleen <ak@muc.de>
Cc: Hugh Dickens <hugh@veritas.com>
Cc: Michael Ellerman <michael@ellerman.id.au>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/i386/kernel/traps.c')
-rw-r--r-- | arch/i386/kernel/traps.c | 41 |
1 files changed, 11 insertions, 30 deletions
diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c index 68de48e498ca..2b30dbf8d117 100644 --- a/arch/i386/kernel/traps.c +++ b/arch/i386/kernel/traps.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/unwind.h> | 30 | #include <linux/unwind.h> |
31 | #include <linux/uaccess.h> | 31 | #include <linux/uaccess.h> |
32 | #include <linux/nmi.h> | 32 | #include <linux/nmi.h> |
33 | #include <linux/bug.h> | ||
33 | 34 | ||
34 | #ifdef CONFIG_EISA | 35 | #ifdef CONFIG_EISA |
35 | #include <linux/ioport.h> | 36 | #include <linux/ioport.h> |
@@ -420,43 +421,22 @@ void show_registers(struct pt_regs *regs) | |||
420 | printk("\n"); | 421 | printk("\n"); |
421 | } | 422 | } |
422 | 423 | ||
423 | static void handle_BUG(struct pt_regs *regs) | 424 | int is_valid_bugaddr(unsigned long eip) |
424 | { | 425 | { |
425 | unsigned long eip = regs->eip; | ||
426 | unsigned short ud2; | 426 | unsigned short ud2; |
427 | 427 | ||
428 | if (eip < PAGE_OFFSET) | 428 | if (eip < PAGE_OFFSET) |
429 | return; | 429 | return 0; |
430 | if (probe_kernel_address((unsigned short *)eip, ud2)) | 430 | if (probe_kernel_address((unsigned short *)eip, ud2)) |
431 | return; | 431 | return 0; |
432 | if (ud2 != 0x0b0f) | ||
433 | return; | ||
434 | |||
435 | printk(KERN_EMERG "------------[ cut here ]------------\n"); | ||
436 | |||
437 | #ifdef CONFIG_DEBUG_BUGVERBOSE | ||
438 | do { | ||
439 | unsigned short line; | ||
440 | char *file; | ||
441 | char c; | ||
442 | |||
443 | if (probe_kernel_address((unsigned short *)(eip + 2), line)) | ||
444 | break; | ||
445 | if (probe_kernel_address((char **)(eip + 4), file) || | ||
446 | (unsigned long)file < PAGE_OFFSET || | ||
447 | probe_kernel_address(file, c)) | ||
448 | file = "<bad filename>"; | ||
449 | 432 | ||
450 | printk(KERN_EMERG "kernel BUG at %s:%d!\n", file, line); | 433 | return ud2 == 0x0b0f; |
451 | return; | ||
452 | } while (0); | ||
453 | #endif | ||
454 | printk(KERN_EMERG "Kernel BUG at [verbose debug info unavailable]\n"); | ||
455 | } | 434 | } |
456 | 435 | ||
457 | /* This is gone through when something in the kernel | 436 | /* |
458 | * has done something bad and is about to be terminated. | 437 | * This is gone through when something in the kernel has done something bad and |
459 | */ | 438 | * is about to be terminated. |
439 | */ | ||
460 | void die(const char * str, struct pt_regs * regs, long err) | 440 | void die(const char * str, struct pt_regs * regs, long err) |
461 | { | 441 | { |
462 | static struct { | 442 | static struct { |
@@ -488,7 +468,8 @@ void die(const char * str, struct pt_regs * regs, long err) | |||
488 | unsigned long esp; | 468 | unsigned long esp; |
489 | unsigned short ss; | 469 | unsigned short ss; |
490 | 470 | ||
491 | handle_BUG(regs); | 471 | report_bug(regs->eip); |
472 | |||
492 | printk(KERN_EMERG "%s: %04lx [#%d]\n", str, err & 0xffff, ++die_counter); | 473 | printk(KERN_EMERG "%s: %04lx [#%d]\n", str, err & 0xffff, ++die_counter); |
493 | #ifdef CONFIG_PREEMPT | 474 | #ifdef CONFIG_PREEMPT |
494 | printk(KERN_EMERG "PREEMPT "); | 475 | printk(KERN_EMERG "PREEMPT "); |