Commit 68fb3ca0 authored by Linus Torvalds's avatar Linus Torvalds

update workarounds for gcc "asm goto" issue

In commit 4356e9f8 ("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: default avatarJakub 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: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 339e2fca
...@@ -67,10 +67,9 @@ ...@@ -67,10 +67,9 @@
/* /*
* GCC 'asm goto' with outputs miscompiles certain code sequences: * GCC 'asm goto' with outputs miscompiles certain code sequences:
* *
* https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110420 * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113921
* https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110422
* *
* Work it around via the same compiler barrier quirk that we used * Work around it via the same compiler barrier quirk that we used
* to use for the old 'asm goto' workaround. * to use for the old 'asm goto' workaround.
* *
* Also, always mark such 'asm goto' statements as volatile: all * Also, always mark such 'asm goto' statements as volatile: all
...@@ -80,8 +79,10 @@ ...@@ -80,8 +79,10 @@
* *
* https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98619 * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98619
*/ */
#ifdef CONFIG_GCC_ASM_GOTO_OUTPUT_WORKAROUND
#define asm_goto_output(x...) \ #define asm_goto_output(x...) \
do { asm volatile goto(x); asm (""); } while (0) do { asm volatile goto(x); asm (""); } while (0)
#endif
#if defined(CONFIG_ARCH_USE_BUILTIN_BSWAP) #if defined(CONFIG_ARCH_USE_BUILTIN_BSWAP)
#define __HAVE_BUILTIN_BSWAP32__ #define __HAVE_BUILTIN_BSWAP32__
......
...@@ -362,8 +362,15 @@ struct ftrace_likely_data { ...@@ -362,8 +362,15 @@ struct ftrace_likely_data {
#define __member_size(p) __builtin_object_size(p, 1) #define __member_size(p) __builtin_object_size(p, 1)
#endif #endif
/*
* Some versions of gcc do not mark 'asm goto' volatile:
*
* https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103979
*
* We do it here by hand, because it doesn't hurt.
*/
#ifndef asm_goto_output #ifndef asm_goto_output
#define asm_goto_output(x...) asm goto(x) #define asm_goto_output(x...) asm volatile goto(x)
#endif #endif
#ifdef CONFIG_CC_HAS_ASM_INLINE #ifdef CONFIG_CC_HAS_ASM_INLINE
......
...@@ -89,6 +89,15 @@ config CC_HAS_ASM_GOTO_TIED_OUTPUT ...@@ -89,6 +89,15 @@ config CC_HAS_ASM_GOTO_TIED_OUTPUT
# Detect buggy gcc and clang, fixed in gcc-11 clang-14. # Detect buggy gcc and clang, fixed in gcc-11 clang-14.
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) 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)
config GCC_ASM_GOTO_OUTPUT_WORKAROUND
bool
depends on CC_IS_GCC && CC_HAS_ASM_GOTO_OUTPUT
# Fixed in GCC 14, 13.3, 12.4 and 11.5
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113921
default y if GCC_VERSION < 110500
default y if GCC_VERSION >= 120000 && GCC_VERSION < 120400
default y if GCC_VERSION >= 130000 && GCC_VERSION < 130300
config TOOLS_SUPPORT_RELR config TOOLS_SUPPORT_RELR
def_bool $(success,env "CC=$(CC)" "LD=$(LD)" "NM=$(NM)" "OBJCOPY=$(OBJCOPY)" $(srctree)/scripts/tools-support-relr.sh) def_bool $(success,env "CC=$(CC)" "LD=$(LD)" "NM=$(NM)" "OBJCOPY=$(OBJCOPY)" $(srctree)/scripts/tools-support-relr.sh)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment