Skip to content

Commit 68fb3ca

Browse files
committed
update workarounds for gcc "asm goto" issue
In commit 4356e9f ("work around gcc bugs with 'asm goto' with outputs") I did the gcc workaround unconditionally, because the cause of the bad code generation wasn't entirely clear. In the meantime, Jakub Jelinek debugged the issue, and has come up with a fix in gcc [2], which also got backported to the still maintained branches of gcc-11, gcc-12 and gcc-13. Note that while the fix technically wasn't in the original gcc-14 branch, Jakub says: "while it is true that no GCC 14 snapshots until today (or whenever the fix will be committed) have the fix, for GCC trunk it is up to the distros to use the latest snapshot if they use it at all and would allow better testing of the kernel code without the workaround, so that if there are other issues they won't be discovered years later. Most userland code doesn't actually use asm goto with outputs..." so we will consider gcc-14 to be fixed - if somebody is using gcc snapshots of the gcc-14 before the fix, they should upgrade. Note that while the bug goes back to gcc-11, in practice other gcc changes seem to have effectively hidden it since gcc-12.1 as per a bisect by Jakub. So even a gcc-14 snapshot without the fix likely doesn't show actual problems. Also, make the default 'asm_goto_output()' macro mark the asm as volatile by hand, because of an unrelated gcc issue [1] where it doesn't match the documented behavior ("asm goto is always volatile"). Link: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103979 [1] Link: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113921 [2] Link: https://lore.kernel.org/all/20240208220604.140859-1-seanjc@google.com/ Requested-by: Jakub Jelinek <jakub@redhat.com> Cc: Uros Bizjak <ubizjak@gmail.com> Cc: Nick Desaulniers <ndesaulniers@google.com> Cc: Sean Christopherson <seanjc@google.com> Cc: Andrew Pinski <quic_apinski@quicinc.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
1 parent 339e2fc commit 68fb3ca

File tree

3 files changed

+21
-4
lines changed

3 files changed

+21
-4
lines changed

include/linux/compiler-gcc.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,10 +67,9 @@
6767
/*
6868
* GCC 'asm goto' with outputs miscompiles certain code sequences:
6969
*
70-
* https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110420
71-
* https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110422
70+
* https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113921
7271
*
73-
* Work it around via the same compiler barrier quirk that we used
72+
* Work around it via the same compiler barrier quirk that we used
7473
* to use for the old 'asm goto' workaround.
7574
*
7675
* Also, always mark such 'asm goto' statements as volatile: all
@@ -80,8 +79,10 @@
8079
*
8180
* https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98619
8281
*/
82+
#ifdef CONFIG_GCC_ASM_GOTO_OUTPUT_WORKAROUND
8383
#define asm_goto_output(x...) \
8484
do { asm volatile goto(x); asm (""); } while (0)
85+
#endif
8586

8687
#if defined(CONFIG_ARCH_USE_BUILTIN_BSWAP)
8788
#define __HAVE_BUILTIN_BSWAP32__

include/linux/compiler_types.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -362,8 +362,15 @@ struct ftrace_likely_data {
362362
#define __member_size(p) __builtin_object_size(p, 1)
363363
#endif
364364

365+
/*
366+
* Some versions of gcc do not mark 'asm goto' volatile:
367+
*
368+
* https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103979
369+
*
370+
* We do it here by hand, because it doesn't hurt.
371+
*/
365372
#ifndef asm_goto_output
366-
#define asm_goto_output(x...) asm goto(x)
373+
#define asm_goto_output(x...) asm volatile goto(x)
367374
#endif
368375

369376
#ifdef CONFIG_CC_HAS_ASM_INLINE

init/Kconfig

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,15 @@ config CC_HAS_ASM_GOTO_TIED_OUTPUT
8989
# Detect buggy gcc and clang, fixed in gcc-11 clang-14.
9090
def_bool $(success,echo 'int foo(int *x) { asm goto (".long (%l[bar]) - .": "+m"(*x) ::: bar); return *x; bar: return 0; }' | $CC -x c - -c -o /dev/null)
9191

92+
config GCC_ASM_GOTO_OUTPUT_WORKAROUND
93+
bool
94+
depends on CC_IS_GCC && CC_HAS_ASM_GOTO_OUTPUT
95+
# Fixed in GCC 14, 13.3, 12.4 and 11.5
96+
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113921
97+
default y if GCC_VERSION < 110500
98+
default y if GCC_VERSION >= 120000 && GCC_VERSION < 120400
99+
default y if GCC_VERSION >= 130000 && GCC_VERSION < 130300
100+
92101
config TOOLS_SUPPORT_RELR
93102
def_bool $(success,env "CC=$(CC)" "LD=$(LD)" "NM=$(NM)" "OBJCOPY=$(OBJCOPY)" $(srctree)/scripts/tools-support-relr.sh)
94103

0 commit comments

Comments
 (0)