]> xenbits.xensource.com Git - xen.git/commitdiff
x86: unify BUG() & Co, reduce overhead on x86-64
authorKeir Fraser <keir.fraser@citrix.com>
Tue, 31 Mar 2009 12:23:11 +0000 (13:23 +0100)
committerKeir Fraser <keir.fraser@citrix.com>
Tue, 31 Mar 2009 12:23:11 +0000 (13:23 +0100)
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>
xen/arch/x86/traps.c
xen/include/asm-x86/bug.h
xen/include/asm-x86/x86_32/bug.h
xen/include/asm-x86/x86_64/bug.h

index eb187925399a760952e3bce744d70ab0198fe596..c0856557352c2f13c59e7f98e4168f860c79fbca 100644 (file)
@@ -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);
index 975576185c0b5649ee280ce37ada5e0ab02c3abd..df64549e4463fb7e2f800bd81b342f4718ffc803 100644 (file)
@@ -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__ */
index 20a9137063e88b7152d0b87dea9bc410481cebfb..dfb59552960d06d73f43df79555baf25f25f8b5d 100644 (file)
@@ -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__ */
index 3fa5debfa74f2ae73d9d0b33249a573c55fc8be2..ecae455b83d3abdb4c64ef86fd2fa78237558131 100644 (file)
@@ -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__ */