• Fangrui Song's avatar
    arm64: Delete the space separator in __emit_inst · 54530dd3
    Fangrui Song authored
    [ Upstream commit c9a4ef66 ]
    
    In assembly, many instances of __emit_inst(x) expand to a directive. In
    a few places __emit_inst(x) is used as an assembler macro argument. For
    example, in arch/arm64/kvm/hyp/entry.S
    
      ALTERNATIVE(nop, SET_PSTATE_PAN(1), ARM64_HAS_PAN, CONFIG_ARM64_PAN)
    
    expands to the following by the C preprocessor:
    
      alternative_insn nop, .inst (0xd500401f | ((0) << 16 | (4) << 5) | ((!!1) << 8)), 4, 1
    
    Both comma and space are separators, with an exception that content
    inside a pair of parentheses/quotes is not split, so the clang
    integrated assembler splits the arguments to:
    
       nop, .inst, (0xd500401f | ((0) << 16 | (4) << 5) | ((!!1) << 8)), 4, 1
    
    GNU as preprocesses the input with do_scrub_chars(). Its arm64 backend
    (along with many other non-x86 backends) sees:
    
      alternative_insn nop,.inst(0xd500401f|((0)<<16|(4)<<5)|((!!1)<<8)),4,1
      # .inst(...) is parsed as one argument
    
    while its x86 backend sees:
    
      alternative_insn nop,.inst (0xd500401f|((0)<<16|(4)<<5)|((!!1)<<8)),4,1
      # The extra space before '(' makes the whole .inst (...) parsed as two arguments
    
    The non-x86 backend's behavior is considered unintentional
    (https://sourceware.org/bugzilla/show_bug.cgi?id=25750).
    So drop the space separator inside `.inst (...)` to make the clang
    integrated assembler work.
    Suggested-by: default avatarIlie Halip <ilie.halip@gmail.com>
    Signed-off-by: default avatarFangrui Song <maskray@google.com>
    Reviewed-by: default avatarMark Rutland <mark.rutland@arm.com>
    Link: https://github.com/ClangBuiltLinux/linux/issues/939Signed-off-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
    Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
    54530dd3
sysreg.h 25.4 KB