Skip to content

Commit 8de6327

Browse files
nickdesaulniersSasha Levin
authored and
Sasha Levin
committed
x86/bug: Merge annotate_reachable() into _BUG_FLAGS() asm
[ Upstream commit bfb1a7c ] In __WARN_FLAGS(), we had two asm statements (abbreviated): asm volatile("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. GCC explicitly documents this: > Note that the compiler can move even volatile asm instructions > relative to other code, including across jump instructions. Also, 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 compared to 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. Also remove an unnecessary unreachable() asm annotation from BUG() in favor of __builtin_unreachable(). objtool is able to track that the ud2 from BUG() terminates control flow within the function. Link: https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#Volatile Link: ClangBuiltLinux/linux#1483 Signed-off-by: Nick Desaulniers <[email protected]> Signed-off-by: Josh Poimboeuf <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Sasha Levin <[email protected]>
1 parent 4046031 commit 8de6327

File tree

2 files changed

+16
-25
lines changed

2 files changed

+16
-25
lines changed

arch/x86/include/asm/bug.h

Lines changed: 11 additions & 9 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,16 +57,16 @@ 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); \
67-
unreachable(); \
68+
_BUG_FLAGS(ASM_UD2, 0, ""); \
69+
__builtin_unreachable(); \
6870
} while (0)
6971

7072
/*
@@ -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: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -117,14 +117,6 @@ void ftrace_likely_update(struct ftrace_likely_data *f, int val,
117117
*/
118118
#define __stringify_label(n) #n
119119

120-
#define __annotate_reachable(c) ({ \
121-
asm volatile(__stringify_label(c) ":\n\t" \
122-
".pushsection .discard.reachable\n\t" \
123-
".long " __stringify_label(c) "b - .\n\t" \
124-
".popsection\n\t" : : "i" (c)); \
125-
})
126-
#define annotate_reachable() __annotate_reachable(__COUNTER__)
127-
128120
#define __annotate_unreachable(c) ({ \
129121
asm volatile(__stringify_label(c) ":\n\t" \
130122
".pushsection .discard.unreachable\n\t" \
@@ -133,24 +125,21 @@ void ftrace_likely_update(struct ftrace_likely_data *f, int val,
133125
})
134126
#define annotate_unreachable() __annotate_unreachable(__COUNTER__)
135127

136-
#define ASM_UNREACHABLE \
137-
"999:\n\t" \
138-
".pushsection .discard.unreachable\n\t" \
139-
".long 999b - .\n\t" \
128+
#define ASM_REACHABLE \
129+
"998:\n\t" \
130+
".pushsection .discard.reachable\n\t" \
131+
".long 998b - .\n\t" \
140132
".popsection\n\t"
141133

142134
/* Annotate a C jump table to allow objtool to follow the code flow */
143135
#define __annotate_jump_table __section(".rodata..c_jump_table")
144136

145137
#else
146-
#define annotate_reachable()
147138
#define annotate_unreachable()
139+
# define ASM_REACHABLE
148140
#define __annotate_jump_table
149141
#endif
150142

151-
#ifndef ASM_UNREACHABLE
152-
# define ASM_UNREACHABLE
153-
#endif
154143
#ifndef unreachable
155144
# define unreachable() do { \
156145
annotate_unreachable(); \

0 commit comments

Comments
 (0)