Commit bb42ad4e authored by Ingo Molnar's avatar Ingo Molnar Committed by Greg Kroah-Hartman

compiler/gcc4: Add quirk for 'asm goto' miscompilation bug

commit 3f0116c3 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: default avatarFengguang Wu <fengguang.wu@intel.com>
Reported-by: default avatarOleg Nesterov <oleg@redhat.com>
Reported-by: default avatarPeter Zijlstra <a.p.zijlstra@chello.nl>
Suggested-by: default avatarJakub Jelinek <jakub@redhat.com>
Reviewed-by: default avatarRichard Henderson <rth@twiddle.net>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Link: http://lkml.kernel.org/r/20131015062351.GA4666@gmail.comSigned-off-by: default avatarIngo Molnar <mingo@kernel.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent e2dcd671
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
static __always_inline bool arch_static_branch(struct static_key *key) static __always_inline bool arch_static_branch(struct static_key *key)
{ {
asm goto("1:\n\t" asm_volatile_goto("1:\n\t"
JUMP_LABEL_NOP "\n\t" JUMP_LABEL_NOP "\n\t"
".pushsection __jump_table, \"aw\"\n\t" ".pushsection __jump_table, \"aw\"\n\t"
".word 1b, %l[l_yes], %c0\n\t" ".word 1b, %l[l_yes], %c0\n\t"
......
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
static __always_inline bool arch_static_branch(struct static_key *key) static __always_inline bool arch_static_branch(struct static_key *key)
{ {
asm goto("1:\tnop\n\t" asm_volatile_goto("1:\tnop\n\t"
"nop\n\t" "nop\n\t"
".pushsection __jump_table, \"aw\"\n\t" ".pushsection __jump_table, \"aw\"\n\t"
WORD_INSN " 1b, %l[l_yes], %0\n\t" WORD_INSN " 1b, %l[l_yes], %0\n\t"
......
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
static __always_inline bool arch_static_branch(struct static_key *key) static __always_inline bool arch_static_branch(struct static_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" ".pushsection __jump_table, \"aw\"\n\t"
JUMP_ENTRY_TYPE "1b, %l[l_yes], %c0\n\t" JUMP_ENTRY_TYPE "1b, %l[l_yes], %c0\n\t"
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
static __always_inline bool arch_static_branch(struct static_key *key) static __always_inline bool arch_static_branch(struct static_key *key)
{ {
asm goto("0: brcl 0,0\n" asm_volatile_goto("0: brcl 0,0\n"
".pushsection __jump_table, \"aw\"\n" ".pushsection __jump_table, \"aw\"\n"
ASM_ALIGN "\n" ASM_ALIGN "\n"
ASM_PTR " 0b, %l[label], %0\n" ASM_PTR " 0b, %l[label], %0\n"
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
static __always_inline bool arch_static_branch(struct static_key *key) static __always_inline bool arch_static_branch(struct static_key *key)
{ {
asm goto("1:\n\t" asm_volatile_goto("1:\n\t"
"nop\n\t" "nop\n\t"
"nop\n\t" "nop\n\t"
".pushsection __jump_table, \"aw\"\n\t" ".pushsection __jump_table, \"aw\"\n\t"
......
...@@ -365,7 +365,7 @@ extern const char * const x86_power_flags[32]; ...@@ -365,7 +365,7 @@ extern const char * const x86_power_flags[32];
static __always_inline __pure bool __static_cpu_has(u16 bit) static __always_inline __pure bool __static_cpu_has(u16 bit)
{ {
#if __GNUC__ > 4 || __GNUC_MINOR__ >= 5 #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" "2:\n"
".section .altinstructions,\"a\"\n" ".section .altinstructions,\"a\"\n"
" .long 1b - .\n" " .long 1b - .\n"
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
static __always_inline bool arch_static_branch(struct static_key *key) static __always_inline bool arch_static_branch(struct static_key *key)
{ {
asm goto("1:" asm_volatile_goto("1:"
STATIC_KEY_INITIAL_NOP STATIC_KEY_INITIAL_NOP
".pushsection __jump_table, \"aw\" \n\t" ".pushsection __jump_table, \"aw\" \n\t"
_ASM_ALIGN "\n\t" _ASM_ALIGN "\n\t"
......
...@@ -65,6 +65,21 @@ ...@@ -65,6 +65,21 @@
#define __visible __attribute__((externally_visible)) #define __visible __attribute__((externally_visible))
#endif #endif
/*
* 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
#ifdef CONFIG_ARCH_USE_BUILTIN_BSWAP #ifdef CONFIG_ARCH_USE_BUILTIN_BSWAP
#if GCC_VERSION >= 40400 #if GCC_VERSION >= 40400
......
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