aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorJeremy Fitzhardinge <jeremy@goop.org>2006-12-08 05:36:22 -0500
committerLinus Torvalds <torvalds@woody.osdl.org>2006-12-08 11:28:39 -0500
commitc31a0bf3e1bc581676618db7492f18798fd0a73f (patch)
tree68eb38dbc58d647c3b20cd73fb812cafe93eb663 /arch
parent91768d6c2bad0d2766a166f13f2f57e197de3458 (diff)
[PATCH] Generic BUG for x86-64
This makes x86-64 use the generic BUG machinery. The main advantage in using the generic BUG machinery for x86-64 is that the inlined overhead of BUG is just the ud2a instruction; the file+line information are no longer inlined into the instruction stream. This reduces cache pollution. 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')
-rw-r--r--arch/x86_64/Kconfig5
-rw-r--r--arch/x86_64/kernel/module.c5
-rw-r--r--arch/x86_64/kernel/traps.c36
-rw-r--r--arch/x86_64/kernel/vmlinux.lds.S2
4 files changed, 23 insertions, 25 deletions
diff --git a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig
index bfbb9bcae123..3254a616c69e 100644
--- a/arch/x86_64/Kconfig
+++ b/arch/x86_64/Kconfig
@@ -96,6 +96,11 @@ config AUDIT_ARCH
96 bool 96 bool
97 default y 97 default y
98 98
99config GENERIC_BUG
100 bool
101 default y
102 depends on BUG
103
99source "init/Kconfig" 104source "init/Kconfig"
100 105
101 106
diff --git a/arch/x86_64/kernel/module.c b/arch/x86_64/kernel/module.c
index 9d0958ff547f..a888e67f5874 100644
--- a/arch/x86_64/kernel/module.c
+++ b/arch/x86_64/kernel/module.c
@@ -23,6 +23,7 @@
23#include <linux/string.h> 23#include <linux/string.h>
24#include <linux/kernel.h> 24#include <linux/kernel.h>
25#include <linux/slab.h> 25#include <linux/slab.h>
26#include <linux/bug.h>
26 27
27#include <asm/system.h> 28#include <asm/system.h>
28#include <asm/page.h> 29#include <asm/page.h>
@@ -173,10 +174,12 @@ int module_finalize(const Elf_Ehdr *hdr,
173 lseg, lseg + locks->sh_size, 174 lseg, lseg + locks->sh_size,
174 tseg, tseg + text->sh_size); 175 tseg, tseg + text->sh_size);
175 } 176 }
176 return 0; 177
178 return module_bug_finalize(hdr, sechdrs, me);
177} 179}
178 180
179void module_arch_cleanup(struct module *mod) 181void module_arch_cleanup(struct module *mod)
180{ 182{
181 alternatives_smp_module_del(mod); 183 alternatives_smp_module_del(mod);
184 module_bug_cleanup(mod);
182} 185}
diff --git a/arch/x86_64/kernel/traps.c b/arch/x86_64/kernel/traps.c
index a1641ffdffcf..b54ccc07f379 100644
--- a/arch/x86_64/kernel/traps.c
+++ b/arch/x86_64/kernel/traps.c
@@ -31,6 +31,7 @@
31#include <linux/kexec.h> 31#include <linux/kexec.h>
32#include <linux/unwind.h> 32#include <linux/unwind.h>
33#include <linux/uaccess.h> 33#include <linux/uaccess.h>
34#include <linux/bug.h>
34 35
35#include <asm/system.h> 36#include <asm/system.h>
36#include <asm/io.h> 37#include <asm/io.h>
@@ -524,30 +525,15 @@ bad:
524 printk("\n"); 525 printk("\n");
525} 526}
526 527
527void handle_BUG(struct pt_regs *regs) 528int is_valid_bugaddr(unsigned long rip)
528{ 529{
529 struct bug_frame f; 530 unsigned short ud2;
530 long len;
531 const char *prefix = "";
532 531
533 if (user_mode(regs)) 532 if (__copy_from_user(&ud2, (const void __user *) rip, sizeof(ud2)))
534 return; 533 return 0;
535 if (__copy_from_user(&f, (const void __user *) regs->rip, 534
536 sizeof(struct bug_frame))) 535 return ud2 == 0x0b0f;
537 return; 536}
538 if (f.filename >= 0 ||
539 f.ud2[0] != 0x0f || f.ud2[1] != 0x0b)
540 return;
541 len = __strnlen_user((char *)(long)f.filename, PATH_MAX) - 1;
542 if (len < 0 || len >= PATH_MAX)
543 f.filename = (int)(long)"unmapped filename";
544 else if (len > 50) {
545 f.filename += len - 50;
546 prefix = "...";
547 }
548 printk("----------- [cut here ] --------- [please bite here ] ---------\n");
549 printk(KERN_ALERT "Kernel BUG at %s%.50s:%d\n", prefix, (char *)(long)f.filename, f.line);
550}
551 537
552#ifdef CONFIG_BUG 538#ifdef CONFIG_BUG
553void out_of_line_bug(void) 539void out_of_line_bug(void)
@@ -627,7 +613,9 @@ void die(const char * str, struct pt_regs * regs, long err)
627{ 613{
628 unsigned long flags = oops_begin(); 614 unsigned long flags = oops_begin();
629 615
630 handle_BUG(regs); 616 if (!user_mode(regs))
617 report_bug(regs->rip);
618
631 __die(str, regs, err); 619 __die(str, regs, err);
632 oops_end(flags); 620 oops_end(flags);
633 do_exit(SIGSEGV); 621 do_exit(SIGSEGV);
diff --git a/arch/x86_64/kernel/vmlinux.lds.S b/arch/x86_64/kernel/vmlinux.lds.S
index 6a1f8f491e5d..6c417788c54b 100644
--- a/arch/x86_64/kernel/vmlinux.lds.S
+++ b/arch/x86_64/kernel/vmlinux.lds.S
@@ -51,6 +51,8 @@ SECTIONS
51 51
52 RODATA 52 RODATA
53 53
54 BUG_TABLE
55
54 . = ALIGN(PAGE_SIZE); /* Align data segment to page size boundary */ 56 . = ALIGN(PAGE_SIZE); /* Align data segment to page size boundary */
55 /* Data */ 57 /* Data */
56 .data : AT(ADDR(.data) - LOAD_OFFSET) { 58 .data : AT(ADDR(.data) - LOAD_OFFSET) {