diff options
author | Keir Fraser <keir.fraser@citrix.com> | 2009-03-31 13:23:11 +0100 |
---|---|---|
committer | Keir Fraser <keir.fraser@citrix.com> | 2009-03-31 13:23:11 +0100 |
commit | 7f6385949637051d1529431d7acd59e1677318c8 (patch) | |
tree | 17dba712c8f5b7b8a4a4f25591edb5e3efa29f9f | |
parent | ed25dad906fd3bec60fa79bc124afb3e854d67f0 (diff) | |
download | xen-7f6385949637051d1529431d7acd59e1677318c8.tar.gz xen-7f6385949637051d1529431d7acd59e1677318c8.tar.bz2 xen-7f6385949637051d1529431d7acd59e1677318c8.zip |
x86: unify BUG() & Co, reduce overhead on x86-64
Since it's only the string pointer representations that differ between
i386 and x86-64, abstract out those and make everything else shared.
While touching this code, also use
- proper instructions rather than a mixture of such and raw .byte/
.long/.quad data emissions,
- PC-relative pointers on x86-64 to cut the amount of storage (and
in particular cache space) needed for string references by half.
Signed-off-by: Jan Beulich <jbeulich@novell.com>
-rw-r--r-- | xen/arch/x86/traps.c | 14 | ||||
-rw-r--r-- | xen/include/asm-x86/bug.h | 24 | ||||
-rw-r--r-- | xen/include/asm-x86/x86_32/bug.h | 29 | ||||
-rw-r--r-- | xen/include/asm-x86/x86_64/bug.h | 31 |
4 files changed, 40 insertions, 58 deletions
diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c index eb18792539..c085655735 100644 --- a/xen/arch/x86/traps.c +++ b/xen/arch/x86/traps.c @@ -841,7 +841,7 @@ asmlinkage void do_invalid_op(struct cpu_user_regs *regs) { struct bug_frame bug; struct bug_frame_str bug_str; - char *filename, *predicate, *eip = (char *)regs->eip; + const char *filename, *predicate, *eip = (char *)regs->eip; unsigned long fixup; int id, lineno; @@ -873,11 +873,13 @@ asmlinkage void do_invalid_op(struct cpu_user_regs *regs) /* WARN, BUG or ASSERT: decode the filename pointer and line number. */ if ( !is_kernel(eip) || __copy_from_user(&bug_str, eip, sizeof(bug_str)) || - memcmp(bug_str.mov, BUG_MOV_STR, sizeof(bug_str.mov)) ) + (bug_str.mov != 0xbc) ) goto die; + filename = bug_str(bug_str, eip); eip += sizeof(bug_str); - filename = is_kernel(bug_str.str) ? (char *)bug_str.str : "<unknown>"; + if ( !is_kernel(filename) ) + filename = "<unknown>"; lineno = bug.id >> 2; if ( id == BUGFRAME_warn ) @@ -900,11 +902,13 @@ asmlinkage void do_invalid_op(struct cpu_user_regs *regs) ASSERT(id == BUGFRAME_assert); if ( !is_kernel(eip) || __copy_from_user(&bug_str, eip, sizeof(bug_str)) || - memcmp(bug_str.mov, BUG_MOV_STR, sizeof(bug_str.mov)) ) + (bug_str.mov != 0xbc) ) goto die; + predicate = bug_str(bug_str, eip); eip += sizeof(bug_str); - predicate = is_kernel(bug_str.str) ? (char *)bug_str.str : "<unknown>"; + if ( !is_kernel(predicate) ) + predicate = "<unknown>"; printk("Assertion '%s' failed at %.50s:%d\n", predicate, filename, lineno); DEBUGGER_trap_fatal(TRAP_invalid_op, regs); diff --git a/xen/include/asm-x86/bug.h b/xen/include/asm-x86/bug.h index 975576185c..df64549e44 100644 --- a/xen/include/asm-x86/bug.h +++ b/xen/include/asm-x86/bug.h @@ -18,4 +18,28 @@ struct bug_frame { #define BUGFRAME_bug 2 #define BUGFRAME_assert 3 +#define dump_execution_state() \ + asm volatile ( \ + "ud2 ; ret $0" \ + : : "i" (BUGFRAME_dump) ) + +#define WARN() \ + asm volatile ( \ + "ud2 ; ret %0" BUG_STR(1) \ + : : "i" (BUGFRAME_warn | (__LINE__<<2)), \ + "i" (__FILE__) ) + +#define BUG() \ + asm volatile ( \ + "ud2 ; ret %0" BUG_STR(1) \ + : : "i" (BUGFRAME_bug | (__LINE__<<2)), \ + "i" (__FILE__) ) + +#define assert_failed(p) \ + asm volatile ( \ + "ud2 ; ret %0" BUG_STR(1) BUG_STR(2) \ + : : "i" (BUGFRAME_assert | (__LINE__<<2)), \ + "i" (__FILE__), "i" (#p) ) + + #endif /* __X86_BUG_H__ */ diff --git a/xen/include/asm-x86/x86_32/bug.h b/xen/include/asm-x86/x86_32/bug.h index 20a9137063..dfb5955296 100644 --- a/xen/include/asm-x86/x86_32/bug.h +++ b/xen/include/asm-x86/x86_32/bug.h @@ -2,33 +2,10 @@ #define __X86_32_BUG_H__ struct bug_frame_str { - unsigned char mov[1]; + unsigned char mov; unsigned long str; } __attribute__((packed)); -#define BUG_MOV_STR "\xbc" - -#define dump_execution_state() \ - asm volatile ( \ - "ud2 ; ret $%c0" \ - : : "i" (BUGFRAME_dump) ) - -#define WARN() \ - asm volatile ( \ - "ud2 ; ret $%c0 ; .byte 0xbc ; .long %c1" \ - : : "i" (BUGFRAME_warn | (__LINE__<<2)), \ - "i" (__FILE__) ) - -#define BUG() \ - asm volatile ( \ - "ud2 ; ret $%c0 ; .byte 0xbc ; .long %c1" \ - : : "i" (BUGFRAME_bug | (__LINE__<<2)), \ - "i" (__FILE__) ) - -#define assert_failed(p) \ - asm volatile ( \ - "ud2 ; ret $%c0 ; .byte 0xbc ; .long %c1" \ - " ; .byte 0xbc ; .long %c2" \ - : : "i" (BUGFRAME_assert | (__LINE__<<2)), \ - "i" (__FILE__), "i" (#p) ) +#define bug_str(b, eip) ((const char *)(b).str) +#define BUG_STR(n) "; movl %" #n ", %%esp" #endif /* __X86_32_BUG_H__ */ diff --git a/xen/include/asm-x86/x86_64/bug.h b/xen/include/asm-x86/x86_64/bug.h index 3fa5debfa7..ecae455b83 100644 --- a/xen/include/asm-x86/x86_64/bug.h +++ b/xen/include/asm-x86/x86_64/bug.h @@ -2,33 +2,10 @@ #define __X86_64_BUG_H__ struct bug_frame_str { - unsigned char mov[2]; - unsigned long str; + unsigned char mov; + signed int str_disp; } __attribute__((packed)); -#define BUG_MOV_STR "\x48\xbc" - -#define dump_execution_state() \ - asm volatile ( \ - "ud2 ; ret $%c0" \ - : : "i" (BUGFRAME_dump) ) - -#define WARN() \ - asm volatile ( \ - "ud2 ; ret $%c0 ; .byte 0x48,0xbc ; .quad %c1" \ - : : "i" (BUGFRAME_warn | (__LINE__<<2)), \ - "i" (__FILE__) ) - -#define BUG() \ - asm volatile ( \ - "ud2 ; ret $%c0 ; .byte 0x48,0xbc ; .quad %c1" \ - : : "i" (BUGFRAME_bug | (__LINE__<<2)), \ - "i" (__FILE__) ) - -#define assert_failed(p) \ - asm volatile ( \ - "ud2 ; ret $%c0 ; .byte 0x48,0xbc ; .quad %c1" \ - " ; .byte 0x48,0xbc ; .quad %c2" \ - : : "i" (BUGFRAME_assert | (__LINE__<<2)), \ - "i" (__FILE__), "i" (#p) ) +#define bug_str(b, rip) ((const char *)(rip) + (b).str_disp) +#define BUG_STR(n) "; movl %" #n " - ., %%esp" #endif /* __X86_64_BUG_H__ */ |