Skip to content

Commit 473c4f0

Browse files
x86: bug.h: merge asm in __WARN_FLAGS
In __WARN_FLAGS, we had two asm statements (abbreviated): asm("ud2"); asm volatile (".pushsection .discard.reachable"); These pair of statements are used to trigger an exception, but then help objtool understand that for warnings, control flow will be restored immediately afterwards. The problem is that volatile is not a compiler barrier and no clobbers are specified to prevent instructions from subsequent statements from being scheduled by compiler before the second asm statement. This can lead to instructions from subsequent statements being emitted by the compiler before the second asm statement. Providing a scheduling model such as via -march= options enables the compiler to better schedule instructions with known latencies to hide latencies from data hazards versus inline asm statements in which latencies are not estimated. If an instruction gets scheduled by the compiler between the two asm statements, then objtool will think that it is not reachable, producing a warning. To prevent instructions from being scheduled in between the two asm statements, merge them. Signed-off-by: Nick Desaulniers <[email protected]>
1 parent f6bac24 commit 473c4f0

File tree

2 files changed

+16
-8
lines changed

2 files changed

+16
-8
lines changed

arch/x86/include/asm/bug.h

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222

2323
#ifdef CONFIG_DEBUG_BUGVERBOSE
2424

25-
#define _BUG_FLAGS(ins, flags) \
25+
#define _BUG_FLAGS(ins, flags, extra) \
2626
do { \
2727
asm_inline volatile("1:\t" ins "\n" \
2828
".pushsection __bug_table,\"aw\"\n" \
@@ -31,22 +31,24 @@ do { \
3131
"\t.word %c1" "\t# bug_entry::line\n" \
3232
"\t.word %c2" "\t# bug_entry::flags\n" \
3333
"\t.org 2b+%c3\n" \
34-
".popsection" \
34+
".popsection\n" \
35+
extra \
3536
: : "i" (__FILE__), "i" (__LINE__), \
3637
"i" (flags), \
3738
"i" (sizeof(struct bug_entry))); \
3839
} while (0)
3940

4041
#else /* !CONFIG_DEBUG_BUGVERBOSE */
4142

42-
#define _BUG_FLAGS(ins, flags) \
43+
#define _BUG_FLAGS(ins, flags, extra) \
4344
do { \
4445
asm_inline volatile("1:\t" ins "\n" \
4546
".pushsection __bug_table,\"aw\"\n" \
4647
"2:\t" __BUG_REL(1b) "\t# bug_entry::bug_addr\n" \
4748
"\t.word %c0" "\t# bug_entry::flags\n" \
4849
"\t.org 2b+%c1\n" \
49-
".popsection" \
50+
".popsection\n" \
51+
extra \
5052
: : "i" (flags), \
5153
"i" (sizeof(struct bug_entry))); \
5254
} while (0)
@@ -55,15 +57,15 @@ do { \
5557

5658
#else
5759

58-
#define _BUG_FLAGS(ins, flags) asm volatile(ins)
60+
#define _BUG_FLAGS(ins, flags, extra) asm volatile(ins)
5961

6062
#endif /* CONFIG_GENERIC_BUG */
6163

6264
#define HAVE_ARCH_BUG
6365
#define BUG() \
6466
do { \
6567
instrumentation_begin(); \
66-
_BUG_FLAGS(ASM_UD2, 0); \
68+
_BUG_FLAGS(ASM_UD2, 0, ""); \
6769
unreachable(); \
6870
} while (0)
6971

@@ -75,9 +77,9 @@ do { \
7577
*/
7678
#define __WARN_FLAGS(flags) \
7779
do { \
80+
__auto_type f = BUGFLAG_WARNING|(flags); \
7881
instrumentation_begin(); \
79-
_BUG_FLAGS(ASM_UD2, BUGFLAG_WARNING|(flags)); \
80-
annotate_reachable(); \
82+
_BUG_FLAGS(ASM_UD2, f, ASM_REACHABLE); \
8183
instrumentation_end(); \
8284
} while (0)
8385

include/linux/compiler.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,12 @@ void ftrace_likely_update(struct ftrace_likely_data *f, int val,
133133
})
134134
#define annotate_unreachable() __annotate_unreachable(__COUNTER__)
135135

136+
#define ASM_REACHABLE \
137+
"998:\n\t" \
138+
".pushsection .discard.reachable\n\t" \
139+
".long 998b - .\n\t" \
140+
".popsection\n\t"
141+
136142
#define ASM_UNREACHABLE \
137143
"999:\n\t" \
138144
".pushsection .discard.unreachable\n\t" \

0 commit comments

Comments
 (0)