| From 3f0116c3238a96bc18ad4b4acefe4e7be32fa861 Mon Sep 17 00:00:00 2001 |
| From: Ingo Molnar <mingo@kernel.org> |
| Date: Thu, 10 Oct 2013 10:16:30 +0200 |
| Subject: compiler/gcc4: Add quirk for 'asm goto' miscompilation bug |
| |
| From: Ingo Molnar <mingo@kernel.org> |
| |
| 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> |
| Link: http://lkml.kernel.org/r/20131015062351.GA4666@gmail.com |
| Signed-off-by: Ingo Molnar <mingo@kernel.org> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| arch/arm/include/asm/jump_label.h | 2 +- |
| arch/mips/include/asm/jump_label.h | 2 +- |
| arch/powerpc/include/asm/jump_label.h | 2 +- |
| arch/s390/include/asm/jump_label.h | 2 +- |
| arch/sparc/include/asm/jump_label.h | 2 +- |
| arch/x86/include/asm/cpufeature.h | 2 +- |
| arch/x86/include/asm/jump_label.h | 2 +- |
| include/linux/compiler-gcc4.h | 15 +++++++++++++++ |
| 8 files changed, 22 insertions(+), 7 deletions(-) |
| |
| --- a/arch/arm/include/asm/jump_label.h |
| +++ b/arch/arm/include/asm/jump_label.h |
| @@ -16,7 +16,7 @@ |
| |
| 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" |
| ".pushsection __jump_table, \"aw\"\n\t" |
| ".word 1b, %l[l_yes], %c0\n\t" |
| --- a/arch/mips/include/asm/jump_label.h |
| +++ b/arch/mips/include/asm/jump_label.h |
| @@ -22,7 +22,7 @@ |
| |
| 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" |
| ".pushsection __jump_table, \"aw\"\n\t" |
| WORD_INSN " 1b, %l[l_yes], %0\n\t" |
| --- a/arch/powerpc/include/asm/jump_label.h |
| +++ b/arch/powerpc/include/asm/jump_label.h |
| @@ -19,7 +19,7 @@ |
| |
| 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" |
| ".pushsection __jump_table, \"aw\"\n\t" |
| JUMP_ENTRY_TYPE "1b, %l[l_yes], %c0\n\t" |
| --- a/arch/s390/include/asm/jump_label.h |
| +++ b/arch/s390/include/asm/jump_label.h |
| @@ -15,7 +15,7 @@ |
| |
| 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" |
| ASM_ALIGN "\n" |
| ASM_PTR " 0b, %l[label], %0\n" |
| --- a/arch/sparc/include/asm/jump_label.h |
| +++ b/arch/sparc/include/asm/jump_label.h |
| @@ -9,7 +9,7 @@ |
| |
| 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" |
| --- a/arch/x86/include/asm/cpufeature.h |
| +++ b/arch/x86/include/asm/cpufeature.h |
| @@ -365,7 +365,7 @@ extern const char * const x86_power_flag |
| 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" |
| --- a/arch/x86/include/asm/jump_label.h |
| +++ b/arch/x86/include/asm/jump_label.h |
| @@ -13,7 +13,7 @@ |
| |
| static __always_inline bool arch_static_branch(struct static_key *key) |
| { |
| - asm goto("1:" |
| + asm_volatile_goto("1:" |
| STATIC_KEY_INITIAL_NOP |
| ".pushsection __jump_table, \"aw\" \n\t" |
| _ASM_ALIGN "\n\t" |
| --- a/include/linux/compiler-gcc4.h |
| +++ b/include/linux/compiler-gcc4.h |
| @@ -65,6 +65,21 @@ |
| #define __visible __attribute__((externally_visible)) |
| #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 |
| #if GCC_VERSION >= 40400 |