lkml.org 
[lkml]   [2020]   [Feb]   [14]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH AUTOSEL 5.4 335/459] arm64: fix alternatives with LLVM's integrated assembler
    Date
    From: Sami Tolvanen <samitolvanen@google.com>

    [ Upstream commit c54f90c2627cc316d365e3073614731e17dbc631 ]

    LLVM's integrated assembler fails with the following error when
    building KVM:

    <inline asm>:12:6: error: expected absolute expression
    .if kvm_update_va_mask == 0
    ^
    <inline asm>:21:6: error: expected absolute expression
    .if kvm_update_va_mask == 0
    ^
    <inline asm>:24:2: error: unrecognized instruction mnemonic
    NOT_AN_INSTRUCTION
    ^
    LLVM ERROR: Error parsing inline asm

    These errors come from ALTERNATIVE_CB and __ALTERNATIVE_CFG,
    which test for the existence of the callback parameter in inline
    assembly using the following expression:

    " .if " __stringify(cb) " == 0\n"

    This works with GNU as, but isn't supported by LLVM. This change
    splits __ALTERNATIVE_CFG and ALTINSTR_ENTRY into separate macros
    to fix the LLVM build.

    Link: https://github.com/ClangBuiltLinux/linux/issues/472
    Signed-off-by: Sami Tolvanen <samitolvanen@google.com>
    Tested-by: Nick Desaulniers <ndesaulniers@google.com>
    Reviewed-by: Kees Cook <keescook@chromium.org>
    Signed-off-by: Will Deacon <will@kernel.org>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    arch/arm64/include/asm/alternative.h | 32 ++++++++++++++++++----------
    1 file changed, 21 insertions(+), 11 deletions(-)

    diff --git a/arch/arm64/include/asm/alternative.h b/arch/arm64/include/asm/alternative.h
    index b9f8d787eea9f..324e7d5ab37ed 100644
    --- a/arch/arm64/include/asm/alternative.h
    +++ b/arch/arm64/include/asm/alternative.h
    @@ -35,13 +35,16 @@ void apply_alternatives_module(void *start, size_t length);
    static inline void apply_alternatives_module(void *start, size_t length) { }
    #endif

    -#define ALTINSTR_ENTRY(feature,cb) \
    +#define ALTINSTR_ENTRY(feature) \
    " .word 661b - .\n" /* label */ \
    - " .if " __stringify(cb) " == 0\n" \
    " .word 663f - .\n" /* new instruction */ \
    - " .else\n" \
    + " .hword " __stringify(feature) "\n" /* feature bit */ \
    + " .byte 662b-661b\n" /* source len */ \
    + " .byte 664f-663f\n" /* replacement len */
    +
    +#define ALTINSTR_ENTRY_CB(feature, cb) \
    + " .word 661b - .\n" /* label */ \
    " .word " __stringify(cb) "- .\n" /* callback */ \
    - " .endif\n" \
    " .hword " __stringify(feature) "\n" /* feature bit */ \
    " .byte 662b-661b\n" /* source len */ \
    " .byte 664f-663f\n" /* replacement len */
    @@ -62,15 +65,14 @@ static inline void apply_alternatives_module(void *start, size_t length) { }
    *
    * Alternatives with callbacks do not generate replacement instructions.
    */
    -#define __ALTERNATIVE_CFG(oldinstr, newinstr, feature, cfg_enabled, cb) \
    +#define __ALTERNATIVE_CFG(oldinstr, newinstr, feature, cfg_enabled) \
    ".if "__stringify(cfg_enabled)" == 1\n" \
    "661:\n\t" \
    oldinstr "\n" \
    "662:\n" \
    ".pushsection .altinstructions,\"a\"\n" \
    - ALTINSTR_ENTRY(feature,cb) \
    + ALTINSTR_ENTRY(feature) \
    ".popsection\n" \
    - " .if " __stringify(cb) " == 0\n" \
    ".pushsection .altinstr_replacement, \"a\"\n" \
    "663:\n\t" \
    newinstr "\n" \
    @@ -78,17 +80,25 @@ static inline void apply_alternatives_module(void *start, size_t length) { }
    ".popsection\n\t" \
    ".org . - (664b-663b) + (662b-661b)\n\t" \
    ".org . - (662b-661b) + (664b-663b)\n" \
    - ".else\n\t" \
    + ".endif\n"
    +
    +#define __ALTERNATIVE_CFG_CB(oldinstr, feature, cfg_enabled, cb) \
    + ".if "__stringify(cfg_enabled)" == 1\n" \
    + "661:\n\t" \
    + oldinstr "\n" \
    + "662:\n" \
    + ".pushsection .altinstructions,\"a\"\n" \
    + ALTINSTR_ENTRY_CB(feature, cb) \
    + ".popsection\n" \
    "663:\n\t" \
    "664:\n\t" \
    - ".endif\n" \
    ".endif\n"

    #define _ALTERNATIVE_CFG(oldinstr, newinstr, feature, cfg, ...) \
    - __ALTERNATIVE_CFG(oldinstr, newinstr, feature, IS_ENABLED(cfg), 0)
    + __ALTERNATIVE_CFG(oldinstr, newinstr, feature, IS_ENABLED(cfg))

    #define ALTERNATIVE_CB(oldinstr, cb) \
    - __ALTERNATIVE_CFG(oldinstr, "NOT_AN_INSTRUCTION", ARM64_CB_PATCH, 1, cb)
    + __ALTERNATIVE_CFG_CB(oldinstr, ARM64_CB_PATCH, 1, cb)
    #else

    #include <asm/assembler.h>
    --
    2.20.1
    \
     
     \ /
      Last update: 2020-02-14 18:24    [W:2.610 / U:4.708 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site