lkml.org 
[lkml]   [2013]   [Nov]   [25]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Date
    Subject[PATCH 3.2 60/87] compiler/gcc4: Add quirk for 'asm goto' miscompilation bug
    3.2.53-rc1 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>
    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>
    ---
    --- 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 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"
    --- 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 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"
    --- 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 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"
    --- 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 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"
    --- a/arch/x86/include/asm/cpufeature.h
    +++ b/arch/x86/include/asm/cpufeature.h
    @@ -334,7 +334,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 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"
    --- a/include/linux/compiler-gcc4.h
    +++ b/include/linux/compiler-gcc4.h
    @@ -29,6 +29,21 @@
    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
    /*


    \
     
     \ /
      Last update: 2013-11-25 17:21    [W:4.025 / U:0.032 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site