lkml.org 
[lkml]   [2013]   [Oct]   [16]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[ 23/50] compiler/gcc4: Add quirk for asm goto miscompilation bug
    Date
    3.11-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    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 | 6 +++---
    arch/x86/include/asm/jump_label.h | 2 +-
    include/linux/compiler-gcc4.h | 15 +++++++++++++++
    8 files changed, 24 insertions(+), 9 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
    @@ -373,7 +373,7 @@ static __always_inline __pure bool __sta
    * Catch too early usage of this before alternatives
    * have run.
    */
    - asm goto("1: jmp %l[t_warn]\n"
    + asm_volatile_goto("1: jmp %l[t_warn]\n"
    "2:\n"
    ".section .altinstructions,\"a\"\n"
    " .long 1b - .\n"
    @@ -386,7 +386,7 @@ static __always_inline __pure bool __sta
    : : "i" (X86_FEATURE_ALWAYS) : : t_warn);
    #endif

    - 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"
    @@ -448,7 +448,7 @@ static __always_inline __pure bool _stat
    * have. Thus, we force the jump to the widest, 4-byte, signed relative
    * offset even though the last would often fit in less bytes.
    */
    - asm goto("1: .byte 0xe9\n .long %l[t_dynamic] - 2f\n"
    + asm_volatile_goto("1: .byte 0xe9\n .long %l[t_dynamic] - 2f\n"
    "2:\n"
    ".section .altinstructions,\"a\"\n"
    " .long 1b - .\n" /* src offset */
    --- 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



    \
     
     \ /
      Last update: 2013-10-16 20:21    [W:4.171 / U:0.240 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site