aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/i386/Kconfig5
-rw-r--r--arch/i386/kernel/module.c4
-rw-r--r--arch/i386/kernel/traps.c41
-rw-r--r--arch/i386/kernel/vmlinux.lds.S2
-rw-r--r--include/asm-i386/bug.h28
-rw-r--r--lib/Kconfig.debug2
6 files changed, 42 insertions, 40 deletions
diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig
index ea70359b02d0..c2362c7ba749 100644
--- a/arch/i386/Kconfig
+++ b/arch/i386/Kconfig
@@ -49,6 +49,11 @@ config GENERIC_IOMAP
49 bool 49 bool
50 default y 50 default y
51 51
52config GENERIC_BUG
53 bool
54 default y
55 depends on BUG
56
52config GENERIC_HWEIGHT 57config GENERIC_HWEIGHT
53 bool 58 bool
54 default y 59 default y
diff --git a/arch/i386/kernel/module.c b/arch/i386/kernel/module.c
index d7d9c8b23f72..3db0a5442eb1 100644
--- a/arch/i386/kernel/module.c
+++ b/arch/i386/kernel/module.c
@@ -21,6 +21,7 @@
21#include <linux/fs.h> 21#include <linux/fs.h>
22#include <linux/string.h> 22#include <linux/string.h>
23#include <linux/kernel.h> 23#include <linux/kernel.h>
24#include <linux/bug.h>
24 25
25#if 0 26#if 0
26#define DEBUGP printk 27#define DEBUGP printk
@@ -141,10 +142,11 @@ int module_finalize(const Elf_Ehdr *hdr,
141 apply_paravirt(pseg, pseg + para->sh_size); 142 apply_paravirt(pseg, pseg + para->sh_size);
142 } 143 }
143 144
144 return 0; 145 return module_bug_finalize(hdr, sechdrs, me);
145} 146}
146 147
147void module_arch_cleanup(struct module *mod) 148void module_arch_cleanup(struct module *mod)
148{ 149{
149 alternatives_smp_module_del(mod); 150 alternatives_smp_module_del(mod);
151 module_bug_cleanup(mod);
150} 152}
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
423static void handle_BUG(struct pt_regs *regs) 424int 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 */
460void die(const char * str, struct pt_regs * regs, long err) 440void 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 ");
diff --git a/arch/i386/kernel/vmlinux.lds.S b/arch/i386/kernel/vmlinux.lds.S
index 56e6ad5cb045..16d3c7133ad7 100644
--- a/arch/i386/kernel/vmlinux.lds.S
+++ b/arch/i386/kernel/vmlinux.lds.S
@@ -57,6 +57,8 @@ SECTIONS
57 57
58 RODATA 58 RODATA
59 59
60 BUG_TABLE
61
60 . = ALIGN(4); 62 . = ALIGN(4);
61 .tracedata : AT(ADDR(.tracedata) - LOAD_OFFSET) { 63 .tracedata : AT(ADDR(.tracedata) - LOAD_OFFSET) {
62 __tracedata_start = .; 64 __tracedata_start = .;
diff --git a/include/asm-i386/bug.h b/include/asm-i386/bug.h
index 8062cdbf2587..b0fd78ca2619 100644
--- a/include/asm-i386/bug.h
+++ b/include/asm-i386/bug.h
@@ -4,20 +4,32 @@
4 4
5/* 5/*
6 * Tell the user there is some problem. 6 * Tell the user there is some problem.
7 * The offending file and line are encoded after the "officially 7 * The offending file and line are encoded encoded in the __bug_table section.
8 * undefined" opcode for parsing in the trap handler.
9 */ 8 */
10 9
11#ifdef CONFIG_BUG 10#ifdef CONFIG_BUG
12#define HAVE_ARCH_BUG 11#define HAVE_ARCH_BUG
12
13#ifdef CONFIG_DEBUG_BUGVERBOSE 13#ifdef CONFIG_DEBUG_BUGVERBOSE
14#define BUG() \ 14#define BUG() \
15 __asm__ __volatile__( "ud2\n" \ 15 do { \
16 "\t.word %c0\n" \ 16 asm volatile("1:\tud2\n" \
17 "\t.long %c1\n" \ 17 ".pushsection __bug_table,\"a\"\n" \
18 : : "i" (__LINE__), "i" (__FILE__)) 18 "2:\t.long 1b, %c0\n" \
19 "\t.word %c1, 0\n" \
20 "\t.org 2b+%c2\n" \
21 ".popsection" \
22 : : "i" (__FILE__), "i" (__LINE__), \
23 "i" (sizeof(struct bug_entry))); \
24 for(;;) ; \
25 } while(0)
26
19#else 27#else
20#define BUG() __asm__ __volatile__("ud2\n") 28#define BUG() \
29 do { \
30 asm volatile("ud2"); \
31 for(;;) ; \
32 } while(0)
21#endif 33#endif
22#endif 34#endif
23 35
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index ee46fb335d24..2c133c098607 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -285,7 +285,7 @@ config DEBUG_HIGHMEM
285config DEBUG_BUGVERBOSE 285config DEBUG_BUGVERBOSE
286 bool "Verbose BUG() reporting (adds 70K)" if DEBUG_KERNEL && EMBEDDED 286 bool "Verbose BUG() reporting (adds 70K)" if DEBUG_KERNEL && EMBEDDED
287 depends on BUG 287 depends on BUG
288 depends on ARM || ARM26 || AVR32 || M32R || M68K || SPARC32 || SPARC64 || X86_32 || FRV || SUPERH || GENERIC_BUG 288 depends on ARM || ARM26 || AVR32 || M32R || M68K || SPARC32 || SPARC64 || FRV || SUPERH || GENERIC_BUG
289 default !EMBEDDED 289 default !EMBEDDED
290 help 290 help
291 Say Y here to make BUG() panics output the file name and line number 291 Say Y here to make BUG() panics output the file name and line number