Jan Beulich
2009-Mar-30 15:36 UTC
[Xen-devel] [PATCH] 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> --- 2009-03-27.orig/xen/arch/x86/traps.c 2009-03-27 12:40:13.000000000 +0100 +++ 2009-03-27/xen/arch/x86/traps.c 2009-03-30 15:35:30.000000000 +0200 @@ -841,7 +841,7 @@ asmlinkage void do_invalid_op(struct cpu { 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 /* 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 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); --- 2009-03-27.orig/xen/include/asm-x86/bug.h 2007-03-28 10:17:12.000000000 +0200 +++ 2009-03-27/xen/include/asm-x86/bug.h 2009-03-30 14:47:14.000000000 +0200 @@ -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__ */ --- 2009-03-27.orig/xen/include/asm-x86/x86_32/bug.h 2007-03-28 10:17:12.000000000 +0200 +++ 2009-03-27/xen/include/asm-x86/x86_32/bug.h 2009-03-30 15:25:24.000000000 +0200 @@ -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__ */ --- 2009-03-27.orig/xen/include/asm-x86/x86_64/bug.h 2007-03-28 10:17:12.000000000 +0200 +++ 2009-03-27/xen/include/asm-x86/x86_64/bug.h 2009-03-30 15:25:32.000000000 +0200 @@ -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__ */ _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel