lkml.org 
[lkml]   [2020]   [Dec]   [14]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.9 105/105] compiler.h: fix barrier_data() on clang
    Date
    From: Arvind Sankar <nivedita@alum.mit.edu>

    commit 3347acc6fcd4ee71ad18a9ff9d9dac176b517329 upstream.

    Commit 815f0ddb346c ("include/linux/compiler*.h: make compiler-*.h
    mutually exclusive") neglected to copy barrier_data() from
    compiler-gcc.h into compiler-clang.h.

    The definition in compiler-gcc.h was really to work around clang's more
    aggressive optimization, so this broke barrier_data() on clang, and
    consequently memzero_explicit() as well.

    For example, this results in at least the memzero_explicit() call in
    lib/crypto/sha256.c:sha256_transform() being optimized away by clang.

    Fix this by moving the definition of barrier_data() into compiler.h.

    Also move the gcc/clang definition of barrier() into compiler.h,
    __memory_barrier() is icc-specific (and barrier() is already defined
    using it in compiler-intel.h) and doesn't belong in compiler.h.

    [rdunlap@infradead.org: fix ALPHA builds when SMP is not enabled]

    Link: https://lkml.kernel.org/r/20201101231835.4589-1-rdunlap@infradead.org
    Fixes: 815f0ddb346c ("include/linux/compiler*.h: make compiler-*.h mutually exclusive")
    Signed-off-by: Arvind Sankar <nivedita@alum.mit.edu>
    Signed-off-by: Randy Dunlap <rdunlap@infradead.org>
    Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
    Tested-by: Nick Desaulniers <ndesaulniers@google.com>
    Reviewed-by: Nick Desaulniers <ndesaulniers@google.com>
    Reviewed-by: Kees Cook <keescook@chromium.org>
    Cc: <stable@vger.kernel.org>
    Link: https://lkml.kernel.org/r/20201014212631.207844-1-nivedita@alum.mit.edu
    Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
    Signed-off-by: Nick Desaulniers <ndesaulniers@google.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    ---
    include/asm-generic/barrier.h | 1 +
    include/linux/compiler-clang.h | 6 ------
    include/linux/compiler-gcc.h | 19 -------------------
    include/linux/compiler.h | 18 ++++++++++++++++--
    4 files changed, 17 insertions(+), 27 deletions(-)

    --- a/include/asm-generic/barrier.h
    +++ b/include/asm-generic/barrier.h
    @@ -13,6 +13,7 @@

    #ifndef __ASSEMBLY__

    +#include <linux/compiler.h>
    #include <asm/rwonce.h>

    #ifndef nop
    --- a/include/linux/compiler-clang.h
    +++ b/include/linux/compiler-clang.h
    @@ -52,12 +52,6 @@
    #define COMPILER_HAS_GENERIC_BUILTIN_OVERFLOW 1
    #endif

    -/* The following are for compatibility with GCC, from compiler-gcc.h,
    - * and may be redefined here because they should not be shared with other
    - * compilers, like ICC.
    - */
    -#define barrier() __asm__ __volatile__("" : : : "memory")
    -
    #if __has_feature(shadow_call_stack)
    # define __noscs __attribute__((__no_sanitize__("shadow-call-stack")))
    #endif
    --- a/include/linux/compiler-gcc.h
    +++ b/include/linux/compiler-gcc.h
    @@ -15,25 +15,6 @@
    # error Sorry, your compiler is too old - please upgrade it.
    #endif

    -/* Optimization barrier */
    -
    -/* The "volatile" is due to gcc bugs */
    -#define barrier() __asm__ __volatile__("": : :"memory")
    -/*
    - * This version is i.e. to prevent dead stores elimination on @ptr
    - * where gcc and llvm may behave differently when otherwise using
    - * normal barrier(): while gcc behavior gets along with a normal
    - * barrier(), llvm needs an explicit input variable to be assumed
    - * clobbered. The issue is as follows: while the inline asm might
    - * access any memory it wants, the compiler could have fit all of
    - * @ptr into memory registers instead, and since @ptr never escaped
    - * from that, it proved that the inline asm wasn't touching any of
    - * it. This version works well with both compilers, i.e. we're telling
    - * the compiler that the inline asm absolutely may see the contents
    - * of @ptr. See also: https://llvm.org/bugs/show_bug.cgi?id=15495
    - */
    -#define barrier_data(ptr) __asm__ __volatile__("": :"r"(ptr) :"memory")
    -
    /*
    * This macro obfuscates arithmetic on a variable address so that gcc
    * shouldn't recognize the original var, and make assumptions about it.
    --- a/include/linux/compiler.h
    +++ b/include/linux/compiler.h
    @@ -80,11 +80,25 @@ void ftrace_likely_update(struct ftrace_

    /* Optimization barrier */
    #ifndef barrier
    -# define barrier() __memory_barrier()
    +/* The "volatile" is due to gcc bugs */
    +# define barrier() __asm__ __volatile__("": : :"memory")
    #endif

    #ifndef barrier_data
    -# define barrier_data(ptr) barrier()
    +/*
    + * This version is i.e. to prevent dead stores elimination on @ptr
    + * where gcc and llvm may behave differently when otherwise using
    + * normal barrier(): while gcc behavior gets along with a normal
    + * barrier(), llvm needs an explicit input variable to be assumed
    + * clobbered. The issue is as follows: while the inline asm might
    + * access any memory it wants, the compiler could have fit all of
    + * @ptr into memory registers instead, and since @ptr never escaped
    + * from that, it proved that the inline asm wasn't touching any of
    + * it. This version works well with both compilers, i.e. we're telling
    + * the compiler that the inline asm absolutely may see the contents
    + * of @ptr. See also: https://llvm.org/bugs/show_bug.cgi?id=15495
    + */
    +# define barrier_data(ptr) __asm__ __volatile__("": :"r"(ptr) :"memory")
    #endif

    /* workaround for GCC PR82365 if needed */

    \
     
     \ /
      Last update: 2020-12-14 19:12    [W:5.717 / U:1.292 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site