提交 91768d6c 编写于 作者: J Jeremy Fitzhardinge 提交者: Linus Torvalds

[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: NJeremy 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: NAndrew Morton <akpm@osdl.org>
Signed-off-by: NLinus Torvalds <torvalds@osdl.org>
上级 7664c5a1
...@@ -49,6 +49,11 @@ config GENERIC_IOMAP ...@@ -49,6 +49,11 @@ config GENERIC_IOMAP
bool bool
default y default y
config GENERIC_BUG
bool
default y
depends on BUG
config GENERIC_HWEIGHT config GENERIC_HWEIGHT
bool bool
default y default y
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/string.h> #include <linux/string.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/bug.h>
#if 0 #if 0
#define DEBUGP printk #define DEBUGP printk
...@@ -141,10 +142,11 @@ int module_finalize(const Elf_Ehdr *hdr, ...@@ -141,10 +142,11 @@ int module_finalize(const Elf_Ehdr *hdr,
apply_paravirt(pseg, pseg + para->sh_size); apply_paravirt(pseg, pseg + para->sh_size);
} }
return 0; return module_bug_finalize(hdr, sechdrs, me);
} }
void module_arch_cleanup(struct module *mod) void module_arch_cleanup(struct module *mod)
{ {
alternatives_smp_module_del(mod); alternatives_smp_module_del(mod);
module_bug_cleanup(mod);
} }
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
#include <linux/unwind.h> #include <linux/unwind.h>
#include <linux/uaccess.h> #include <linux/uaccess.h>
#include <linux/nmi.h> #include <linux/nmi.h>
#include <linux/bug.h>
#ifdef CONFIG_EISA #ifdef CONFIG_EISA
#include <linux/ioport.h> #include <linux/ioport.h>
...@@ -420,43 +421,22 @@ void show_registers(struct pt_regs *regs) ...@@ -420,43 +421,22 @@ void show_registers(struct pt_regs *regs)
printk("\n"); printk("\n");
} }
static void handle_BUG(struct pt_regs *regs) int is_valid_bugaddr(unsigned long eip)
{ {
unsigned long eip = regs->eip;
unsigned short ud2; unsigned short ud2;
if (eip < PAGE_OFFSET) if (eip < PAGE_OFFSET)
return; return 0;
if (probe_kernel_address((unsigned short *)eip, ud2)) if (probe_kernel_address((unsigned short *)eip, ud2))
return; return 0;
if (ud2 != 0x0b0f)
return;
printk(KERN_EMERG "------------[ cut here ]------------\n");
#ifdef CONFIG_DEBUG_BUGVERBOSE
do {
unsigned short line;
char *file;
char c;
if (probe_kernel_address((unsigned short *)(eip + 2), line))
break;
if (probe_kernel_address((char **)(eip + 4), file) ||
(unsigned long)file < PAGE_OFFSET ||
probe_kernel_address(file, c))
file = "<bad filename>";
printk(KERN_EMERG "kernel BUG at %s:%d!\n", file, line); return ud2 == 0x0b0f;
return;
} while (0);
#endif
printk(KERN_EMERG "Kernel BUG at [verbose debug info unavailable]\n");
} }
/* This is gone through when something in the kernel /*
* has done something bad and is about to be terminated. * This is gone through when something in the kernel has done something bad and
*/ * is about to be terminated.
*/
void die(const char * str, struct pt_regs * regs, long err) void die(const char * str, struct pt_regs * regs, long err)
{ {
static struct { static struct {
...@@ -488,7 +468,8 @@ void die(const char * str, struct pt_regs * regs, long err) ...@@ -488,7 +468,8 @@ void die(const char * str, struct pt_regs * regs, long err)
unsigned long esp; unsigned long esp;
unsigned short ss; unsigned short ss;
handle_BUG(regs); report_bug(regs->eip);
printk(KERN_EMERG "%s: %04lx [#%d]\n", str, err & 0xffff, ++die_counter); printk(KERN_EMERG "%s: %04lx [#%d]\n", str, err & 0xffff, ++die_counter);
#ifdef CONFIG_PREEMPT #ifdef CONFIG_PREEMPT
printk(KERN_EMERG "PREEMPT "); printk(KERN_EMERG "PREEMPT ");
......
...@@ -57,6 +57,8 @@ SECTIONS ...@@ -57,6 +57,8 @@ SECTIONS
RODATA RODATA
BUG_TABLE
. = ALIGN(4); . = ALIGN(4);
.tracedata : AT(ADDR(.tracedata) - LOAD_OFFSET) { .tracedata : AT(ADDR(.tracedata) - LOAD_OFFSET) {
__tracedata_start = .; __tracedata_start = .;
......
...@@ -4,20 +4,32 @@ ...@@ -4,20 +4,32 @@
/* /*
* Tell the user there is some problem. * Tell the user there is some problem.
* The offending file and line are encoded after the "officially * The offending file and line are encoded encoded in the __bug_table section.
* undefined" opcode for parsing in the trap handler.
*/ */
#ifdef CONFIG_BUG #ifdef CONFIG_BUG
#define HAVE_ARCH_BUG #define HAVE_ARCH_BUG
#ifdef CONFIG_DEBUG_BUGVERBOSE #ifdef CONFIG_DEBUG_BUGVERBOSE
#define BUG() \ #define BUG() \
__asm__ __volatile__( "ud2\n" \ do { \
"\t.word %c0\n" \ asm volatile("1:\tud2\n" \
"\t.long %c1\n" \ ".pushsection __bug_table,\"a\"\n" \
: : "i" (__LINE__), "i" (__FILE__)) "2:\t.long 1b, %c0\n" \
"\t.word %c1, 0\n" \
"\t.org 2b+%c2\n" \
".popsection" \
: : "i" (__FILE__), "i" (__LINE__), \
"i" (sizeof(struct bug_entry))); \
for(;;) ; \
} while(0)
#else #else
#define BUG() __asm__ __volatile__("ud2\n") #define BUG() \
do { \
asm volatile("ud2"); \
for(;;) ; \
} while(0)
#endif #endif
#endif #endif
......
...@@ -285,7 +285,7 @@ config DEBUG_HIGHMEM ...@@ -285,7 +285,7 @@ config DEBUG_HIGHMEM
config DEBUG_BUGVERBOSE config DEBUG_BUGVERBOSE
bool "Verbose BUG() reporting (adds 70K)" if DEBUG_KERNEL && EMBEDDED bool "Verbose BUG() reporting (adds 70K)" if DEBUG_KERNEL && EMBEDDED
depends on BUG depends on BUG
depends on ARM || ARM26 || AVR32 || M32R || M68K || SPARC32 || SPARC64 || X86_32 || FRV || SUPERH || GENERIC_BUG depends on ARM || ARM26 || AVR32 || M32R || M68K || SPARC32 || SPARC64 || FRV || SUPERH || GENERIC_BUG
default !EMBEDDED default !EMBEDDED
help help
Say Y here to make BUG() panics output the file name and line number Say Y here to make BUG() panics output the file name and line number
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册