aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2009-03-31 13:23:11 +0100
committerKeir Fraser <keir.fraser@citrix.com>2009-03-31 13:23:11 +0100
commit7f6385949637051d1529431d7acd59e1677318c8 (patch)
tree17dba712c8f5b7b8a4a4f25591edb5e3efa29f9f
parented25dad906fd3bec60fa79bc124afb3e854d67f0 (diff)
downloadxen-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.c14
-rw-r--r--xen/include/asm-x86/bug.h24
-rw-r--r--xen/include/asm-x86/x86_32/bug.h29
-rw-r--r--xen/include/asm-x86/x86_64/bug.h31
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__ */