aboutsummaryrefslogtreecommitdiffstats
path: root/xen/include/asm-x86/bug.h
diff options
context:
space:
mode:
authorJan Beulich <jbeulich@suse.com>2013-08-23 09:19:29 +0200
committerJan Beulich <jbeulich@suse.com>2013-08-23 09:19:29 +0200
commitb5692f2ef9b6fd67c3e7b4d4f2a4bdb1d58100e5 (patch)
treebd47e9cb5456ece3f11655de913b9e766af7ddd3 /xen/include/asm-x86/bug.h
parent08d89ac8bd7f43d897cdffe85b236c71d3408e16 (diff)
downloadxen-b5692f2ef9b6fd67c3e7b4d4f2a4bdb1d58100e5.tar.gz
xen-b5692f2ef9b6fd67c3e7b4d4f2a4bdb1d58100e5.tar.bz2
xen-b5692f2ef9b6fd67c3e7b4d4f2a4bdb1d58100e5.zip
x86: move struct bug_frame instances out of line
Just like Linux did many years ago, move them into a separate (data) section, such that they no longer pollute instruction caches and TLBs. Assertion frames, requiring two pointers to be stored, occupy two slots in the array, with the second slot mimicking a frame the location pointer of which doesn't match any address within .text or .init.text (it effectively points back to the slot itself, which - being in a data section - can't be reached by non-buggy execution). Signed-off-by: Jan Beulich <jbeulich@suse.com> Acked-by: Keir Fraser <keir@xen.org>
Diffstat (limited to 'xen/include/asm-x86/bug.h')
-rw-r--r--xen/include/asm-x86/bug.h76
1 files changed, 47 insertions, 29 deletions
diff --git a/xen/include/asm-x86/bug.h b/xen/include/asm-x86/bug.h
index c1fc186be9..148975fde2 100644
--- a/xen/include/asm-x86/bug.h
+++ b/xen/include/asm-x86/bug.h
@@ -1,42 +1,60 @@
#ifndef __X86_BUG_H__
#define __X86_BUG_H__
-#include <asm/x86_64/bug.h>
+#define BUG_DISP_WIDTH 24
+#define BUG_LINE_LO_WIDTH (31 - BUG_DISP_WIDTH)
+#define BUG_LINE_HI_WIDTH (31 - BUG_DISP_WIDTH)
struct bug_frame {
- unsigned char ud2[2];
- unsigned char ret;
- unsigned short id; /* BUGFRAME_??? */
-} __attribute__((packed));
+ signed int loc_disp:BUG_DISP_WIDTH;
+ unsigned int line_hi:BUG_LINE_HI_WIDTH;
+ signed int ptr_disp:BUG_DISP_WIDTH;
+ unsigned int line_lo:BUG_LINE_LO_WIDTH;
+ signed int msg_disp[];
+};
+
+#define bug_loc(b) ((const void *)(b) + (b)->loc_disp)
+#define bug_ptr(b) ((const void *)(b) + (b)->ptr_disp)
+#define bug_line(b) ((((b)->line_hi + ((b)->loc_disp < 0)) << \
+ BUG_LINE_LO_WIDTH) + \
+ (b)->line_lo + ((b)->ptr_disp < 0))
+#define bug_msg(b) ((const char *)(b) + (b)->msg_disp[1])
#define BUGFRAME_run_fn 0
#define BUGFRAME_warn 1
#define BUGFRAME_bug 2
#define BUGFRAME_assert 3
-#define run_in_exception_handler(fn) \
- asm volatile ( \
- "ud2 ; ret %0" BUG_STR(1) \
- : : "i" (BUGFRAME_run_fn), \
- "i" (&(fn)) )
-
-#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) )
-
+#define BUG_FRAME(type, line, ptr, msg) do { \
+ BUILD_BUG_ON((line) >> (BUG_LINE_LO_WIDTH + BUG_LINE_HI_WIDTH)); \
+ asm volatile ( ".Lbug%=: ud2\n" \
+ ".pushsection .bug_frames.%c0, \"a\", @progbits\n" \
+ ".p2align 2\n" \
+ ".Lfrm%=:\n" \
+ ".long (.Lbug%= - .Lfrm%=) + %c4\n" \
+ ".long (%c1 - .Lfrm%=) + %c3\n" \
+ ".ifnes \"" msg "\", \"\"\n" \
+ ".long 0, %c2 - .Lfrm%=\n" \
+ ".endif\n" \
+ ".popsection" \
+ : \
+ : "i" (type), "i" (ptr), "i" (msg), \
+ "i" ((line & ((1 << BUG_LINE_LO_WIDTH) - 1)) \
+ << BUG_DISP_WIDTH), \
+ "i" (((line) >> BUG_LINE_LO_WIDTH) << BUG_DISP_WIDTH)); \
+} while (0)
+
+#define WARN() BUG_FRAME(BUGFRAME_warn, __LINE__, __FILE__, "")
+#define BUG() BUG_FRAME(BUGFRAME_bug, __LINE__, __FILE__, "")
+
+#define run_in_exception_handler(fn) BUG_FRAME(BUGFRAME_run_fn, 0, fn, "")
+
+#define assert_failed(msg) BUG_FRAME(BUGFRAME_assert, __LINE__, __FILE__, msg)
+
+extern const struct bug_frame __start_bug_frames[],
+ __stop_bug_frames_0[],
+ __stop_bug_frames_1[],
+ __stop_bug_frames_2[],
+ __stop_bug_frames_3[];
#endif /* __X86_BUG_H__ */