]> git.hungrycats.org Git - linux/commitdiff
compiler/gcc4: Add quirk for 'asm goto' miscompilation bug
authorIngo Molnar <mingo@kernel.org>
Thu, 10 Oct 2013 08:16:30 +0000 (10:16 +0200)
committerBen Hutchings <ben@decadent.org.uk>
Thu, 28 Nov 2013 14:02:03 +0000 (14:02 +0000)
commit 3f0116c3238a96bc18ad4b4acefe4e7be32fa861 upstream.

Fengguang Wu, Oleg Nesterov and Peter Zijlstra tracked down
a kernel crash to a GCC bug: GCC miscompiles certain 'asm goto'
constructs, as outlined here:

  http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58670

Implement a workaround suggested by Jakub Jelinek.

Reported-and-tested-by: Fengguang Wu <fengguang.wu@intel.com>
Reported-by: Oleg Nesterov <oleg@redhat.com>
Reported-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Suggested-by: Jakub Jelinek <jakub@redhat.com>
Reviewed-by: Richard Henderson <rth@twiddle.net>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
[bwh: Backported to 3.2:
 - Drop inapplicable changes
 - Adjust context]
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
arch/mips/include/asm/jump_label.h
arch/powerpc/include/asm/jump_label.h
arch/s390/include/asm/jump_label.h
arch/sparc/include/asm/jump_label.h
arch/x86/include/asm/cpufeature.h
arch/x86/include/asm/jump_label.h
include/linux/compiler-gcc4.h

index 1881b316ca4503b07b5998968a799e625e4a5229..b19559cf57a8e194ce07dec39ce70accc449a227 100644 (file)
@@ -22,7 +22,7 @@
 
 static __always_inline bool arch_static_branch(struct jump_label_key *key)
 {
-       asm goto("1:\tnop\n\t"
+       asm_volatile_goto("1:\tnop\n\t"
                "nop\n\t"
                ".pushsection __jump_table,  \"aw\"\n\t"
                WORD_INSN " 1b, %l[l_yes], %0\n\t"
index 938986e412f193913f9113239c73ae37c9d3f9c6..ee33888878c2273c51668312ff402c90c427da50 100644 (file)
@@ -19,7 +19,7 @@
 
 static __always_inline bool arch_static_branch(struct jump_label_key *key)
 {
-       asm goto("1:\n\t"
+       asm_volatile_goto("1:\n\t"
                 "nop\n\t"
                 ".pushsection __jump_table,  \"aw\"\n\t"
                 JUMP_ENTRY_TYPE "1b, %l[l_yes], %c0\n\t"
index 95a6cf2b5b670a83fa1f4a600484eb7e8066721a..8512d0a0fa5675dbc9b5567ab1909ae56ff6bafe 100644 (file)
@@ -15,7 +15,7 @@
 
 static __always_inline bool arch_static_branch(struct jump_label_key *key)
 {
-       asm goto("0:    brcl 0,0\n"
+       asm_volatile_goto("0:   brcl 0,0\n"
                ".pushsection __jump_table, \"aw\"\n"
                ASM_ALIGN "\n"
                ASM_PTR " 0b, %l[label], %0\n"
index fc73a82366f847f6c9821b0a10da9a35901b9cf2..e17b65bf7673b075401a525fb1cd63ee2d9de617 100644 (file)
@@ -9,7 +9,7 @@
 
 static __always_inline bool arch_static_branch(struct jump_label_key *key)
 {
-               asm goto("1:\n\t"
+               asm_volatile_goto("1:\n\t"
                         "nop\n\t"
                         "nop\n\t"
                         ".pushsection __jump_table,  \"aw\"\n\t"
index 0c3b775ab9540662b9ee15d89d156a31f94ec16f..a315f1ccbf9372bd7df574577609a5e6230943b6 100644 (file)
@@ -334,7 +334,7 @@ extern const char * const x86_power_flags[32];
 static __always_inline __pure bool __static_cpu_has(u16 bit)
 {
 #if __GNUC__ > 4 || __GNUC_MINOR__ >= 5
-               asm goto("1: jmp %l[t_no]\n"
+               asm_volatile_goto("1: jmp %l[t_no]\n"
                         "2:\n"
                         ".section .altinstructions,\"a\"\n"
                         " .long 1b - .\n"
index a32b18ce6eadae461d712a6c49b172387cdbbfd1..e12c1bc3426b78f9399165d758327e28d5af3ba2 100644 (file)
@@ -13,7 +13,7 @@
 
 static __always_inline bool arch_static_branch(struct jump_label_key *key)
 {
-       asm goto("1:"
+       asm_volatile_goto("1:"
                JUMP_LABEL_INITIAL_NOP
                ".pushsection __jump_table,  \"aw\" \n\t"
                _ASM_ALIGN "\n\t"
index dfadc96e9d63851c334885f0ec7761c8d6cfe3ff..643d6c4a5993f16a159fd359904953930518dba3 100644 (file)
    the kernel context */
 #define __cold                 __attribute__((__cold__))
 
+/*
+ * GCC 'asm goto' miscompiles certain code sequences:
+ *
+ *   http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58670
+ *
+ * Work it around via a compiler barrier quirk suggested by Jakub Jelinek.
+ * Fixed in GCC 4.8.2 and later versions.
+ *
+ * (asm goto is automatically volatile - the naming reflects this.)
+ */
+#if GCC_VERSION <= 40801
+# define asm_volatile_goto(x...)       do { asm goto(x); asm (""); } while (0)
+#else
+# define asm_volatile_goto(x...)       do { asm goto(x); } while (0)
+#endif
 
 #if __GNUC_MINOR__ >= 5
 /*