Skip to content

Commit c06c4d8

Browse files
anadavIngo Molnar
authored andcommitted
x86/objtool: Use asm macros to work around GCC inlining bugs
As described in: 77b0bf5: ("kbuild/Makefile: Prepare for using macros in inline assembly code to work around asm() related GCC inlining bugs") GCC's inlining heuristics are broken with common asm() patterns used in kernel code, resulting in the effective disabling of inlining. In the case of objtool the resulting borkage can be significant, since all the annotations of objtool are discarded during linkage and never inlined, yet GCC bogusly considers most functions affected by objtool annotations as 'too large'. The workaround is to set an assembly macro and call it from the inline assembly block. As a result GCC considers the inline assembly block as a single instruction. (Which it isn't, but that's the best we can get.) This increases the kernel size slightly: text data bss dec hex filename 18140829 10224724 2957312 31322865 1ddf2f1 ./vmlinux before 18140970 10225412 2957312 31323694 1ddf62e ./vmlinux after (+829) The number of static text symbols (i.e. non-inlined functions) is reduced: Before: 40321 After: 40302 (-19) [ mingo: Rewrote the changelog. ] Tested-by: Kees Cook <keescook@chromium.org> Signed-off-by: Nadav Amit <namit@vmware.com> Reviewed-by: Josh Poimboeuf <jpoimboe@redhat.com> Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org> Cc: Andy Lutomirski <luto@amacapital.net> Cc: Borislav Petkov <bp@alien8.de> Cc: Brian Gerst <brgerst@gmail.com> Cc: Christopher Li <sparse@chrisli.org> Cc: Denys Vlasenko <dvlasenk@redhat.com> Cc: H. Peter Anvin <hpa@zytor.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: linux-sparse@vger.kernel.org Link: http://lkml.kernel.org/r/20181003213100.189959-4-namit@vmware.com Signed-off-by: Ingo Molnar <mingo@kernel.org>
1 parent 77b0bf5 commit c06c4d8

File tree

2 files changed

+45
-13
lines changed

2 files changed

+45
-13
lines changed

arch/x86/kernel/macros.S

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,5 @@
55
* commonly used. The macros are precompiled into assmebly file which is later
66
* assembled together with each compiled file.
77
*/
8+
9+
#include <linux/compiler.h>

include/linux/compiler.h

Lines changed: 43 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -99,22 +99,13 @@ void ftrace_likely_update(struct ftrace_likely_data *f, int val,
9999
* unique, to convince GCC not to merge duplicate inline asm statements.
100100
*/
101101
#define annotate_reachable() ({ \
102-
asm volatile("%c0:\n\t" \
103-
".pushsection .discard.reachable\n\t" \
104-
".long %c0b - .\n\t" \
105-
".popsection\n\t" : : "i" (__COUNTER__)); \
102+
asm volatile("ANNOTATE_REACHABLE counter=%c0" \
103+
: : "i" (__COUNTER__)); \
106104
})
107105
#define annotate_unreachable() ({ \
108-
asm volatile("%c0:\n\t" \
109-
".pushsection .discard.unreachable\n\t" \
110-
".long %c0b - .\n\t" \
111-
".popsection\n\t" : : "i" (__COUNTER__)); \
106+
asm volatile("ANNOTATE_UNREACHABLE counter=%c0" \
107+
: : "i" (__COUNTER__)); \
112108
})
113-
#define ASM_UNREACHABLE \
114-
"999:\n\t" \
115-
".pushsection .discard.unreachable\n\t" \
116-
".long 999b - .\n\t" \
117-
".popsection\n\t"
118109
#else
119110
#define annotate_reachable()
120111
#define annotate_unreachable()
@@ -299,6 +290,45 @@ static inline void *offset_to_ptr(const int *off)
299290
return (void *)((unsigned long)off + *off);
300291
}
301292

293+
#else /* __ASSEMBLY__ */
294+
295+
#ifdef __KERNEL__
296+
#ifndef LINKER_SCRIPT
297+
298+
#ifdef CONFIG_STACK_VALIDATION
299+
.macro ANNOTATE_UNREACHABLE counter:req
300+
\counter:
301+
.pushsection .discard.unreachable
302+
.long \counter\()b -.
303+
.popsection
304+
.endm
305+
306+
.macro ANNOTATE_REACHABLE counter:req
307+
\counter:
308+
.pushsection .discard.reachable
309+
.long \counter\()b -.
310+
.popsection
311+
.endm
312+
313+
.macro ASM_UNREACHABLE
314+
999:
315+
.pushsection .discard.unreachable
316+
.long 999b - .
317+
.popsection
318+
.endm
319+
#else /* CONFIG_STACK_VALIDATION */
320+
.macro ANNOTATE_UNREACHABLE counter:req
321+
.endm
322+
323+
.macro ANNOTATE_REACHABLE counter:req
324+
.endm
325+
326+
.macro ASM_UNREACHABLE
327+
.endm
328+
#endif /* CONFIG_STACK_VALIDATION */
329+
330+
#endif /* LINKER_SCRIPT */
331+
#endif /* __KERNEL__ */
302332
#endif /* __ASSEMBLY__ */
303333

304334
#ifndef __optimize

0 commit comments

Comments
 (0)