Skip to content

Commit

Permalink
x86: bug.h: merge asm in __WARN_FLAGS
Browse files Browse the repository at this point in the history
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 <ndesaulniers@google.com>
  • Loading branch information
nickdesaulniers committed Jan 27, 2022
1 parent f6bac24 commit 473c4f0
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 8 deletions.
18 changes: 10 additions & 8 deletions arch/x86/include/asm/bug.h
Expand Up @@ -22,7 +22,7 @@

#ifdef CONFIG_DEBUG_BUGVERBOSE

#define _BUG_FLAGS(ins, flags) \
#define _BUG_FLAGS(ins, flags, extra) \
do { \
asm_inline volatile("1:\t" ins "\n" \
".pushsection __bug_table,\"aw\"\n" \
Expand All @@ -31,22 +31,24 @@ do { \
"\t.word %c1" "\t# bug_entry::line\n" \
"\t.word %c2" "\t# bug_entry::flags\n" \
"\t.org 2b+%c3\n" \
".popsection" \
".popsection\n" \
extra \
: : "i" (__FILE__), "i" (__LINE__), \
"i" (flags), \
"i" (sizeof(struct bug_entry))); \
} while (0)

#else /* !CONFIG_DEBUG_BUGVERBOSE */

#define _BUG_FLAGS(ins, flags) \
#define _BUG_FLAGS(ins, flags, extra) \
do { \
asm_inline volatile("1:\t" ins "\n" \
".pushsection __bug_table,\"aw\"\n" \
"2:\t" __BUG_REL(1b) "\t# bug_entry::bug_addr\n" \
"\t.word %c0" "\t# bug_entry::flags\n" \
"\t.org 2b+%c1\n" \
".popsection" \
".popsection\n" \
extra \
: : "i" (flags), \
"i" (sizeof(struct bug_entry))); \
} while (0)
Expand All @@ -55,15 +57,15 @@ do { \

#else

#define _BUG_FLAGS(ins, flags) asm volatile(ins)
#define _BUG_FLAGS(ins, flags, extra) asm volatile(ins)

#endif /* CONFIG_GENERIC_BUG */

#define HAVE_ARCH_BUG
#define BUG() \
do { \
instrumentation_begin(); \
_BUG_FLAGS(ASM_UD2, 0); \
_BUG_FLAGS(ASM_UD2, 0, ""); \
unreachable(); \
} while (0)

Expand All @@ -75,9 +77,9 @@ do { \
*/
#define __WARN_FLAGS(flags) \
do { \
__auto_type f = BUGFLAG_WARNING|(flags); \
instrumentation_begin(); \
_BUG_FLAGS(ASM_UD2, BUGFLAG_WARNING|(flags)); \
annotate_reachable(); \
_BUG_FLAGS(ASM_UD2, f, ASM_REACHABLE); \
instrumentation_end(); \
} while (0)

Expand Down
6 changes: 6 additions & 0 deletions include/linux/compiler.h
Expand Up @@ -133,6 +133,12 @@ void ftrace_likely_update(struct ftrace_likely_data *f, int val,
})
#define annotate_unreachable() __annotate_unreachable(__COUNTER__)

#define ASM_REACHABLE \
"998:\n\t" \
".pushsection .discard.reachable\n\t" \
".long 998b - .\n\t" \
".popsection\n\t"

#define ASM_UNREACHABLE \
"999:\n\t" \
".pushsection .discard.unreachable\n\t" \
Expand Down

0 comments on commit 473c4f0

Please sign in to comment.