From: Ard Biesheuvel ardb@kernel.org
On arm64, generic kernel mode FPU support, as used by the AMD GPU driver, involves dropping the -mgeneral-regs-only compiler flag, as that flag makes the use of double and float C types impossible.
However, dropping that flag allows the compiler to use FPU and SIMD registers in other ways too, and for this reason, arm64 only permits doing so in strictly controlled contexts, i.e., isolated compilation units that get called from inside a kernel_neon_begin() and kernel_neon_end() pair.
The users of the generic kernel mode FPU API lack such strict checks, and this may result in userland FP/SIMD state to get corrupted, given that touching FP/SIMD registers outside of a kernel_neon_begin/end pair does not fault, but silently operates on the userland state without preserving it.
So disable this feature for the time being. This reverts commits
71883ae35278 arm64: implement ARCH_HAS_KERNEL_FPU_SUPPORT 7177089525d9 arm64: crypto: use CC_FLAGS_FPU for NEON CFLAGS 4be073931cd8 lib/raid6: use CC_FLAGS_FPU for NEON CFLAGS
Cc: stable@vger.kernel.org # v6.12+ Signed-off-by: Ard Biesheuvel ardb@kernel.org --- arch/arm64/Kconfig | 1 - arch/arm64/Makefile | 9 +----- arch/arm64/include/asm/fpu.h | 15 --------- arch/arm64/lib/Makefile | 6 ++-- lib/raid6/Makefile | 33 ++++++++++++++------ 5 files changed, 28 insertions(+), 36 deletions(-)
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index b81ab5fbde57..abf70929f675 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -32,7 +32,6 @@ config ARM64 select ARCH_HAS_GCOV_PROFILE_ALL select ARCH_HAS_GIGANTIC_PAGE select ARCH_HAS_KCOV - select ARCH_HAS_KERNEL_FPU_SUPPORT if KERNEL_MODE_NEON select ARCH_HAS_KEEPINITRD select ARCH_HAS_MEMBARRIER_SYNC_CORE select ARCH_HAS_MEM_ENCRYPT diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile index 73a10f65ce8b..82209cc52a5a 100644 --- a/arch/arm64/Makefile +++ b/arch/arm64/Makefile @@ -33,14 +33,7 @@ ifeq ($(CONFIG_BROKEN_GAS_INST),y) $(warning Detected assembler with broken .inst; disassembly will be unreliable) endif
-# The GCC option -ffreestanding is required in order to compile code containing -# ARM/NEON intrinsics in a non C99-compliant environment (such as the kernel) -CC_FLAGS_FPU := -ffreestanding -# Enable <arm_neon.h> -CC_FLAGS_FPU += -isystem $(shell $(CC) -print-file-name=include) -CC_FLAGS_NO_FPU := -mgeneral-regs-only - -KBUILD_CFLAGS += $(CC_FLAGS_NO_FPU) \ +KBUILD_CFLAGS += -mgeneral-regs-only \ $(compat_vdso) $(cc_has_k_constraint) KBUILD_CFLAGS += $(call cc-disable-warning, psabi) KBUILD_AFLAGS += $(compat_vdso) diff --git a/arch/arm64/include/asm/fpu.h b/arch/arm64/include/asm/fpu.h deleted file mode 100644 index 2ae50bdce59b..000000000000 --- a/arch/arm64/include/asm/fpu.h +++ /dev/null @@ -1,15 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright (C) 2023 SiFive - */ - -#ifndef __ASM_FPU_H -#define __ASM_FPU_H - -#include <asm/neon.h> - -#define kernel_fpu_available() cpu_has_neon() -#define kernel_fpu_begin() kernel_neon_begin() -#define kernel_fpu_end() kernel_neon_end() - -#endif /* ! __ASM_FPU_H */ diff --git a/arch/arm64/lib/Makefile b/arch/arm64/lib/Makefile index 633e5223d944..291b616ab511 100644 --- a/arch/arm64/lib/Makefile +++ b/arch/arm64/lib/Makefile @@ -7,8 +7,10 @@ lib-y := clear_user.o delay.o copy_from_user.o \
ifeq ($(CONFIG_KERNEL_MODE_NEON), y) obj-$(CONFIG_XOR_BLOCKS) += xor-neon.o -CFLAGS_xor-neon.o += $(CC_FLAGS_FPU) -CFLAGS_REMOVE_xor-neon.o += $(CC_FLAGS_NO_FPU) +CFLAGS_REMOVE_xor-neon.o += -mgeneral-regs-only +CFLAGS_xor-neon.o += -ffreestanding +# Enable <arm_neon.h> +CFLAGS_xor-neon.o += -isystem $(shell $(CC) -print-file-name=include) endif
lib-$(CONFIG_ARCH_HAS_UACCESS_FLUSHCACHE) += uaccess_flushcache.o diff --git a/lib/raid6/Makefile b/lib/raid6/Makefile index 5be0a4e60ab1..903e287c50c8 100644 --- a/lib/raid6/Makefile +++ b/lib/raid6/Makefile @@ -34,6 +34,25 @@ CFLAGS_REMOVE_vpermxor8.o += -msoft-float endif endif
+# The GCC option -ffreestanding is required in order to compile code containing +# ARM/NEON intrinsics in a non C99-compliant environment (such as the kernel) +ifeq ($(CONFIG_KERNEL_MODE_NEON),y) +NEON_FLAGS := -ffreestanding +# Enable <arm_neon.h> +NEON_FLAGS += -isystem $(shell $(CC) -print-file-name=include) +ifeq ($(ARCH),arm) +NEON_FLAGS += -march=armv7-a -mfloat-abi=softfp -mfpu=neon +endif +CFLAGS_recov_neon_inner.o += $(NEON_FLAGS) +ifeq ($(ARCH),arm64) +CFLAGS_REMOVE_recov_neon_inner.o += -mgeneral-regs-only +CFLAGS_REMOVE_neon1.o += -mgeneral-regs-only +CFLAGS_REMOVE_neon2.o += -mgeneral-regs-only +CFLAGS_REMOVE_neon4.o += -mgeneral-regs-only +CFLAGS_REMOVE_neon8.o += -mgeneral-regs-only +endif +endif + quiet_cmd_unroll = UNROLL $@ cmd_unroll = $(AWK) -v N=$* -f $(src)/unroll.awk < $< > $@
@@ -57,16 +76,10 @@ targets += vpermxor1.c vpermxor2.c vpermxor4.c vpermxor8.c $(obj)/vpermxor%.c: $(src)/vpermxor.uc $(src)/unroll.awk FORCE $(call if_changed,unroll)
-CFLAGS_neon1.o += $(CC_FLAGS_FPU) -CFLAGS_neon2.o += $(CC_FLAGS_FPU) -CFLAGS_neon4.o += $(CC_FLAGS_FPU) -CFLAGS_neon8.o += $(CC_FLAGS_FPU) -CFLAGS_recov_neon_inner.o += $(CC_FLAGS_FPU) -CFLAGS_REMOVE_neon1.o += $(CC_FLAGS_NO_FPU) -CFLAGS_REMOVE_neon2.o += $(CC_FLAGS_NO_FPU) -CFLAGS_REMOVE_neon4.o += $(CC_FLAGS_NO_FPU) -CFLAGS_REMOVE_neon8.o += $(CC_FLAGS_NO_FPU) -CFLAGS_REMOVE_recov_neon_inner.o += $(CC_FLAGS_NO_FPU) +CFLAGS_neon1.o += $(NEON_FLAGS) +CFLAGS_neon2.o += $(NEON_FLAGS) +CFLAGS_neon4.o += $(NEON_FLAGS) +CFLAGS_neon8.o += $(NEON_FLAGS) targets += neon1.c neon2.c neon4.c neon8.c $(obj)/neon%.c: $(src)/neon.uc $(src)/unroll.awk FORCE $(call if_changed,unroll)
linux-stable-mirror@lists.linaro.org