ClangBuiltLinux/linux

error: invalid instruction arch/arm/mm/tlb-v7.S

nickdesaulniers opened this issue · 13 comments

building allyesconfig with LLVM_IAS=1:

$ ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- make LLVM=1 LLVM_IAS=1 -j71 arch/arm/mm/tlb-v7.o
...
clang-12: warning: argument unused during compilation: '-march=armv6k' [-Wunused-command-line-argument]
clang-12: warning: argument unused during compilation: '-Wa,-march=armv7-a' [-Wunused-command-line-argument]
arch/arm/mm/tlb-v7.S:35:2: error: invalid instruction
 dsb ish
 ^
arch/arm/mm/tlb-v7.S:56:2: error: invalid instruction
 dsb ish
 ^
arch/arm/mm/tlb-v7.S:69:2: error: invalid instruction
 dsb ish
 ^
arch/arm/mm/tlb-v7.S:84:2: error: invalid instruction
 dsb ish
 ^
arch/arm/mm/tlb-v7.S:85:2: error: instruction requires: data-barriers
 isb
 ^

similar to 7548bf8

diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile
index 3510503bc5e6..6e9b54714500 100644
--- a/arch/arm/mm/Makefile
+++ b/arch/arm/mm/Makefile
@@ -73,7 +73,6 @@ obj-$(CONFIG_CPU_TLB_V7)      += tlb-v7.o
 obj-$(CONFIG_CPU_TLB_FA)       += tlb-fa.o
 
 AFLAGS_tlb-v6.o                :=-Wa,-march=armv6
-AFLAGS_tlb-v7.o                :=-Wa,-march=armv7-a
 
 obj-$(CONFIG_CPU_ARM7TDMI)     += proc-arm7tdmi.o
 obj-$(CONFIG_CPU_ARM720T)      += proc-arm720.o
diff --git a/arch/arm/mm/tlb-v7.S b/arch/arm/mm/tlb-v7.S
index 1bb28d7db567..2643e2f51b6a 100644
--- a/arch/arm/mm/tlb-v7.S
+++ b/arch/arm/mm/tlb-v7.S
@@ -16,6 +16,8 @@
 #include <asm/tlbflush.h>
 #include "proc-macros.S"
 
+.arch armv7-a
+
 /*
  *     v7wbi_flush_user_tlb_range(start, end, vma)
  *

fixes the error. cc @jcai19

eh, this is pretty common due to commit aff7b4f ("ARM: Ensure ARMv6/7 mm files are built using appropriate assembler options")

tempted to mark this a dup of #957.

Note that arch/arm64/Makefile has code like:

 91 ifeq ($(CONFIG_AS_HAS_PAC), y)                                                                                                                                                                                                         
 92 asm-arch := armv8.3-a                                                                                                                                                                                                                  
 93 endif                                                                                                                                                                                                                                  
 94 endif                                                                                                                                                                                                                                  
 95                                                                                                                                                                                                                                        
 96 KBUILD_CFLAGS += $(branch-prot-flags-y)                                                                                                                                                                                                
 97                                                                                                                                                                                                                                        
 98 ifeq ($(CONFIG_AS_HAS_ARMV8_4), y)                                                                                                                                                                                                     
 99 # make sure to pass the newest target architecture to -march.                                                                                                                                                                          
100 asm-arch := armv8.4-a                                                                                                                                                                                                                  
101 endif                                                                                                                                                                                                                                  
102                                                                                                                                                                                                                                        
103 ifdef asm-arch                                                                                                                                                                                                                         
104 KBUILD_CFLAGS += -Wa,-march=$(asm-arch) \                                                                                                                                                                                              
105        -DARM64_ASM_ARCH='"$(asm-arch)"'                                                                                                                                                                                                
106 endif 

and it seems like the Kconfig checks are working, so is it the case that we support -Wa,-march= for aarch64 but not 32b arm?

Isn't the issue that -Wa,... is not used with the integrated assembler? That block was added due to the outcome of #1106.

ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- make LLVM=1 LLVM_IAS=1 -j72 defconfig enabled both

CONFIG_CPU_32v6K=y                                                                                                                                                         
CONFIG_CPU_32v7=y    

cc @arndb should those be mutually exclusive?

Modifying the kernel would involve touching at least 20 .S sources, and their Makefiles.

$ ag AFLAGS | grep march
mm/Makefile:36:AFLAGS_abort-ev6.o       :=-Wa,-march=armv6k
mm/Makefile:37:AFLAGS_abort-ev7.o       :=-Wa,-march=armv7-a
mm/Makefile:52:AFLAGS_cache-v6.o        :=-Wa,-march=armv6
mm/Makefile:53:AFLAGS_cache-v7.o        :=-Wa,-march=armv7-a
mm/Makefile:54:AFLAGS_cache-v7m.o       :=-Wa,-march=armv7-m
mm/Makefile:75:AFLAGS_tlb-v6.o          :=-Wa,-march=armv6
mm/Makefile:76:AFLAGS_tlb-v7.o          :=-Wa,-march=armv7-a
mm/Makefile:104:AFLAGS_proc-v6.o        :=-Wa,-march=armv6
mm/Makefile:105:AFLAGS_proc-v7.o        :=-Wa,-march=armv7-a
mach-npcm/Makefile:2:AFLAGS_headsmp.o           += -march=armv7-a
kernel/Makefile:102:AFLAGS_hyp-stub.o           :=-Wa,-march=armv7-a
mach-imx/Makefile:39:AFLAGS_headsmp.o :=-Wa,-march=armv7-a
mach-imx/Makefile:53:AFLAGS_suspend-imx6.o :=-Wa,-march=armv7-a
mach-imx/Makefile:58:AFLAGS_resume-imx6.o :=-Wa,-march=armv7-a
boot/compressed/Makefile:196:AFLAGS_hyp-stub.o := -Wa,-march=armv7-a
mach-at91/Makefile:17:AFLAGS_pm_suspend.o := -march=armv7-a
lib/Makefile:40:  AFLAGS_delay-loop.o           += -march=armv4
mach-mvebu/Makefile:4:AFLAGS_coherency_ll.o             := -Wa,-march=armv7-a
common/Makefile:17:AFLAGS_mcpm_head.o           := -march=armv7-a
common/Makefile:18:AFLAGS_vlock.o                       := -march=armv7-a
$ ag AFLAGS | grep march | wc -l
20
arndb commented

cc @arndb should those be mutually exclusive?

CONFIG_CPU_32v7 and CONFIG_CPU_32v6 are mutually exclusive, however CONFIG_CPU_32v6K is a special symbol that tells us that the 'K' extension of v6 is present. As 'K' is implied by ARMv7, CONFIG_CPU_32v6K is always enabled on any ARMv7 configuration.

I agree this is really confusing, but it works as designed.

@DavidSpickett at Linaro also has a patch for LLVM: https://reviews.llvm.org/D95872. I'll try to get it reviewed and tested asap.

arndb commented

I still get the "argument unused during compilation" warning, though I no longer get the "invalid instruction" errors.

I think something is still wrong here. For instance when building the kernel without my earlier patch:

clang-13 -Wp,-MMD,drivers/memory/.ti-emif-sram-pm.o.d -nostdinc -isystem /usr/lib/llvm-13/lib/clang/13.0.0/include -I/git/arm-soc/arch/arm/include -I./arch/arm/include/generated -I/git/arm-soc/include -I./include -I/git/arm-soc/arch/arm/include/uapi -I./arch/arm/include/generated/uapi -I/git/arm-soc/include/uapi -I./include/generated/uapi -include /git/arm-soc/include/linux/kconfig.h -D__KERNEL__ -mlittle-endian -fmacro-prefix-map=/git/arm-soc/= -D__ASSEMBLY__ -fno-PIE --target=arm-linux-gnueabi --prefix=/home/arnd/cross/x86_64/gcc-10.1.0-nolibc/arm-linux-gnueabi/bin/arm-linux-gnueabi- --gcc-toolchain=/home/arnd/cross/x86_64/gcc-10.1.0-nolibc/arm-linux-gnueabi -Werror=unknown-warning-option -mabi=aapcs-linux -mfpu=vfp -meabi gnu -marm -Wa,-W -D__LINUX_ARM_ARCH__=6 -march=armv6k -mtune=arm1136j-s -include asm/unified.h -msoft-float -Wa,--fatal-warnings -Wa,-march=armv7-a -I /git/arm-soc/drivers/memory -I ./drivers/memory -DMODULE -c -o drivers/memory/ti-emif-sram-pm.o /git/arm-soc/drivers/memory/ti-emif-sram-pm.S
clang: warning: argument unused during compilation: '-march=armv6k' [-Wunused-command-line-argument]

It seems that clang now accepts the "-Wa,-march=armv7" bit and correctly builds the file with that, but when we pass both "-march=" and "-Wa,-march=" options, it complains about one of them being unused.

That looks like a separate issue. Let's track it in #1315.