From 9613736d852dce2376a848e6e9af091c422a947e Mon Sep 17 00:00:00 2001 From: Samuel Holland Date: Fri, 29 Mar 2024 00:18:29 -0700 Subject: selftests/fpu: move FP code to a separate translation unit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This ensures no compiler-generated floating-point code can appear outside kernel_fpu_{begin,end}() sections, and some architectures enforce this separation. Link: https://lkml.kernel.org/r/20240329072441.591471-15-samuel.holland@sifive.com Signed-off-by: Samuel Holland Reviewed-by: Christoph Hellwig Acked-by: Christian König Cc: Alex Deucher Cc: Borislav Petkov (AMD) Cc: Catalin Marinas Cc: Dave Hansen Cc: Huacai Chen Cc: Ingo Molnar Cc: Jonathan Corbet Cc: Masahiro Yamada Cc: Michael Ellerman Cc: Nathan Chancellor Cc: Nicolas Schier Cc: Palmer Dabbelt Cc: Russell King Cc: Thomas Gleixner Cc: WANG Xuerui Cc: Will Deacon Signed-off-by: Andrew Morton --- lib/test_fpu_glue.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 lib/test_fpu_glue.c (limited to 'lib/test_fpu_glue.c') diff --git a/lib/test_fpu_glue.c b/lib/test_fpu_glue.c new file mode 100644 index 000000000000..85963d7be826 --- /dev/null +++ b/lib/test_fpu_glue.c @@ -0,0 +1,59 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Test cases for using floating point operations inside a kernel module. + * + * This tests kernel_fpu_begin() and kernel_fpu_end() functions, especially + * when userland has modified the floating point control registers. The kernel + * state might depend on the state set by the userland thread that was active + * before a syscall. + * + * To facilitate the test, this module registers file + * /sys/kernel/debug/selftest_helpers/test_fpu, which when read causes a + * sequence of floating point operations. If the operations fail, either the + * read returns error status or the kernel crashes. + * If the operations succeed, the read returns "1\n". + */ + +#include +#include +#include +#include + +#include "test_fpu.h" + +static int test_fpu_get(void *data, u64 *val) +{ + int status = -EINVAL; + + kernel_fpu_begin(); + status = test_fpu(); + kernel_fpu_end(); + + *val = 1; + return status; +} + +DEFINE_DEBUGFS_ATTRIBUTE(test_fpu_fops, test_fpu_get, NULL, "%lld\n"); +static struct dentry *selftest_dir; + +static int __init test_fpu_init(void) +{ + selftest_dir = debugfs_create_dir("selftest_helpers", NULL); + if (!selftest_dir) + return -ENOMEM; + + debugfs_create_file_unsafe("test_fpu", 0444, selftest_dir, NULL, + &test_fpu_fops); + + return 0; +} + +static void __exit test_fpu_exit(void) +{ + debugfs_remove(selftest_dir); +} + +module_init(test_fpu_init); +module_exit(test_fpu_exit); + +MODULE_LICENSE("GPL"); -- cgit v1.2.3-59-g8ed1b From 790a4a3dd1039ee07e7bb5854dcc7ccfbb40c876 Mon Sep 17 00:00:00 2001 From: Samuel Holland Date: Fri, 29 Mar 2024 00:18:30 -0700 Subject: selftests/fpu: allow building on other architectures MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Now that ARCH_HAS_KERNEL_FPU_SUPPORT provides a common way to compile and run floating-point code, this test is no longer x86-specific. Link: https://lkml.kernel.org/r/20240329072441.591471-16-samuel.holland@sifive.com Signed-off-by: Samuel Holland Reviewed-by: Christoph Hellwig Acked-by: Christian König Cc: Alex Deucher Cc: Borislav Petkov (AMD) Cc: Catalin Marinas Cc: Dave Hansen Cc: Huacai Chen Cc: Ingo Molnar Cc: Jonathan Corbet Cc: Masahiro Yamada Cc: Michael Ellerman Cc: Nathan Chancellor Cc: Nicolas Schier Cc: Palmer Dabbelt Cc: Russell King Cc: Thomas Gleixner Cc: WANG Xuerui Cc: Will Deacon Signed-off-by: Andrew Morton --- lib/Kconfig.debug | 2 +- lib/Makefile | 25 ++----------------------- lib/test_fpu_glue.c | 5 ++++- 3 files changed, 7 insertions(+), 25 deletions(-) (limited to 'lib/test_fpu_glue.c') diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index c1c1b19525a5..f4384fd60a76 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -2926,7 +2926,7 @@ config TEST_FREE_PAGES config TEST_FPU tristate "Test floating point operations in kernel space" - depends on X86 && !KCOV_INSTRUMENT_ALL + depends on ARCH_HAS_KERNEL_FPU_SUPPORT && !KCOV_INSTRUMENT_ALL help Enable this option to add /sys/kernel/debug/selftest_helpers/test_fpu which will trigger a sequence of floating point operations. This is used diff --git a/lib/Makefile b/lib/Makefile index 87f8803587ae..3b1769045651 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -110,31 +110,10 @@ CFLAGS_test_fprobe.o += $(CC_FLAGS_FTRACE) obj-$(CONFIG_FPROBE_SANITY_TEST) += test_fprobe.o obj-$(CONFIG_TEST_OBJPOOL) += test_objpool.o -# -# CFLAGS for compiling floating point code inside the kernel. x86/Makefile turns -# off the generation of FPU/SSE* instructions for kernel proper but FPU_FLAGS -# get appended last to CFLAGS and thus override those previous compiler options. -# -FPU_CFLAGS := -msse -msse2 -ifdef CONFIG_CC_IS_GCC -# Stack alignment mismatch, proceed with caution. -# GCC < 7.1 cannot compile code using `double` and -mpreferred-stack-boundary=3 -# (8B stack alignment). -# See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53383 -# -# The "-msse" in the first argument is there so that the -# -mpreferred-stack-boundary=3 build error: -# -# -mpreferred-stack-boundary=3 is not between 4 and 12 -# -# can be triggered. Otherwise gcc doesn't complain. -FPU_CFLAGS += -mhard-float -FPU_CFLAGS += $(call cc-option,-msse -mpreferred-stack-boundary=3,-mpreferred-stack-boundary=4) -endif - obj-$(CONFIG_TEST_FPU) += test_fpu.o test_fpu-y := test_fpu_glue.o test_fpu_impl.o -CFLAGS_test_fpu_impl.o += $(FPU_CFLAGS) +CFLAGS_test_fpu_impl.o += $(CC_FLAGS_FPU) +CFLAGS_REMOVE_test_fpu_impl.o += $(CC_FLAGS_NO_FPU) # Some KUnit files (hooks.o) need to be built-in even when KUnit is a module, # so we can't just use obj-$(CONFIG_KUNIT). diff --git a/lib/test_fpu_glue.c b/lib/test_fpu_glue.c index 85963d7be826..eef282a2715f 100644 --- a/lib/test_fpu_glue.c +++ b/lib/test_fpu_glue.c @@ -17,7 +17,7 @@ #include #include #include -#include +#include #include "test_fpu.h" @@ -38,6 +38,9 @@ static struct dentry *selftest_dir; static int __init test_fpu_init(void) { + if (!kernel_fpu_available()) + return -EINVAL; + selftest_dir = debugfs_create_dir("selftest_helpers", NULL); if (!selftest_dir) return -ENOMEM; -- cgit v1.2.3-59-g8ed1b