• Nathan Chancellor's avatar
    riscv: Handle zicsr/zifencei issues between clang and binutils · e89c2e81
    Nathan Chancellor authored
    There are two related issues that appear in certain combinations with
    clang and GNU binutils.
    
    The first occurs when a version of clang that supports zicsr or zifencei
    via '-march=' [1] (i.e, >= 17.x) is used in combination with a version
    of GNU binutils that do not recognize zicsr and zifencei in the
    '-march=' value (i.e., < 2.36):
    
      riscv64-linux-gnu-ld: -march=rv64i2p0_m2p0_a2p0_c2p0_zicsr2p0_zifencei2p0: Invalid or unknown z ISA extension: 'zifencei'
      riscv64-linux-gnu-ld: failed to merge target specific data of file fs/efivarfs/file.o
      riscv64-linux-gnu-ld: -march=rv64i2p0_m2p0_a2p0_c2p0_zicsr2p0_zifencei2p0: Invalid or unknown z ISA extension: 'zifencei'
      riscv64-linux-gnu-ld: failed to merge target specific data of file fs/efivarfs/super.o
    
    The second occurs when a version of clang that does not support zicsr or
    zifencei via '-march=' (i.e., <= 16.x) is used in combination with a
    version of GNU as that defaults to a newer ISA base spec, which requires
    specifying zicsr and zifencei in the '-march=' value explicitly (i.e, >=
    2.38):
    
      ../arch/riscv/kernel/kexec_relocate.S: Assembler messages:
      ../arch/riscv/kernel/kexec_relocate.S:147: Error: unrecognized opcode `fence.i', extension `zifencei' required
      clang-12: error: assembler command failed with exit code 1 (use -v to see invocation)
    
    This is the same issue addressed by commit 6df2a016 ("riscv: fix
    build with binutils 2.38") (see [2] for additional information) but
    older versions of clang miss out on it because the cc-option check
    fails:
    
      clang-12: error: invalid arch name 'rv64imac_zicsr_zifencei', unsupported standard user-level extension 'zicsr'
      clang-12: error: invalid arch name 'rv64imac_zicsr_zifencei', unsupported standard user-level extension 'zicsr'
    
    To resolve the first issue, only attempt to add zicsr and zifencei to
    the march string when using the GNU assembler 2.38 or newer, which is
    when the default ISA spec was updated, requiring these extensions to be
    specified explicitly. LLVM implements an older version of the base
    specification for all currently released versions, so these instructions
    are available as part of the 'i' extension. If LLVM's implementation is
    updated in the future, a CONFIG_AS_IS_LLVM condition can be added to
    CONFIG_TOOLCHAIN_NEEDS_EXPLICIT_ZICSR_ZIFENCEI.
    
    To resolve the second issue, use version 2.2 of the base ISA spec when
    using an older version of clang that does not support zicsr or zifencei
    via '-march=', as that is the spec version most compatible with the one
    clang/LLVM implements and avoids the need to specify zicsr and zifencei
    explicitly due to still being a part of 'i'.
    
    [1]: https://github.com/llvm/llvm-project/commit/22e199e6afb1263c943c0c0d4498694e15bf8a16
    [2]: https://lore.kernel.org/ZAxT7T9Xy1Fo3d5W@aurel32.net/
    
    Cc: stable@vger.kernel.org
    Link: https://github.com/ClangBuiltLinux/linux/issues/1808Co-developed-by: default avatarConor Dooley <conor.dooley@microchip.com>
    Signed-off-by: default avatarConor Dooley <conor.dooley@microchip.com>
    Signed-off-by: default avatarNathan Chancellor <nathan@kernel.org>
    Acked-by: default avatarConor Dooley <conor.dooley@microchip.com>
    Link: https://lore.kernel.org/r/20230313-riscv-zicsr-zifencei-fiasco-v1-1-dd1b7840a551@kernel.orgSigned-off-by: default avatarPalmer Dabbelt <palmer@rivosinc.com>
    e89c2e81
Kconfig 21.6 KB