From: Samuel Holland <samuel.holland@sifive.com>
To: linux-arm-kernel@lists.infradead.org,
linuxppc-dev@lists.ozlabs.org, x86@kernel.org,
linux-riscv@lists.infradead.org, Christoph Hellwig <hch@lst.de>
Cc: loongarch@lists.linux.dev, linux-kernel@vger.kernel.org,
amd-gfx@lists.freedesktop.org, linux-arch@vger.kernel.org,
Samuel Holland <samuel.holland@sifive.com>,
Jonathan Corbet <corbet@lwn.net>,
linux-doc@vger.kernel.org
Subject: [PATCH v2 01/14] arch: Add ARCH_HAS_KERNEL_FPU_SUPPORT
Date: Wed, 27 Dec 2023 17:41:51 -0800 [thread overview]
Message-ID: <20231228014220.3562640-2-samuel.holland@sifive.com> (raw)
In-Reply-To: <20231228014220.3562640-1-samuel.holland@sifive.com>
Several architectures provide an API to enable the FPU and run
floating-point SIMD code in kernel space. However, the function names,
header locations, and semantics are inconsistent across architectures,
and FPU support may be gated behind other Kconfig options.
Provide a standard way for architectures to declare that kernel space
FPU support is available. Architectures selecting this option must
implement what is currently the most common API (kernel_fpu_begin() and
kernel_fpu_end(), plus a new function kernel_fpu_available()) and
provide the appropriate CFLAGS for compiling floating-point C code.
Suggested-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
---
Changes in v2:
- Add documentation explaining the built-time and runtime APIs
- Add a linux/fpu.h header for generic isolation enforcement
Documentation/core-api/floating-point.rst | 78 +++++++++++++++++++++++
Documentation/core-api/index.rst | 1 +
Makefile | 5 ++
arch/Kconfig | 6 ++
include/linux/fpu.h | 12 ++++
5 files changed, 102 insertions(+)
create mode 100644 Documentation/core-api/floating-point.rst
create mode 100644 include/linux/fpu.h
diff --git a/Documentation/core-api/floating-point.rst b/Documentation/core-api/floating-point.rst
new file mode 100644
index 000000000000..a8d0d4b05052
--- /dev/null
+++ b/Documentation/core-api/floating-point.rst
@@ -0,0 +1,78 @@
+.. SPDX-License-Identifier: GPL-2.0+
+
+Floating-point API
+==================
+
+Kernel code is normally prohibited from using floating-point (FP) registers or
+instructions, including the C float and double data types. This rule reduces
+system call overhead, because the kernel does not need to save and restore the
+userspace floating-point register state.
+
+However, occasionally drivers or library functions may need to include FP code.
+This is supported by isolating the functions containing FP code to a separate
+translation unit (a separate source file), and saving/restoring the FP register
+state around calls to those functions. This creates "critical sections" of
+floating-point usage.
+
+The reason for this isolation is to prevent the compiler from generating code
+touching the FP registers outside these critical sections. Compilers sometimes
+use FP registers to optimize inlined ``memcpy`` or variable assignment, as
+floating-point registers may be wider than general-purpose registers.
+
+Usability of floating-point code within the kernel is architecture-specific.
+Additionally, because a single kernel may be configured to support platforms
+both with and without a floating-point unit, FPU availability must be checked
+both at build time and at run time.
+
+Several architectures implement the generic kernel floating-point API from
+``linux/fpu.h``, as described below. Some other architectures implement their
+own unique APIs, which are documented separately.
+
+Build-time API
+--------------
+
+Floating-point code may be built if the option ``ARCH_HAS_KERNEL_FPU_SUPPORT``
+is enabled. For C code, such code must be placed in a separate file, and that
+file must have its compilation flags adjusted using the following pattern::
+
+ CFLAGS_foo.o += $(CC_FLAGS_FPU)
+ CFLAGS_REMOVE_foo.o += $(CC_FLAGS_NO_FPU)
+
+Architectures are expected to define one or both of these variables in their
+top-level Makefile as needed. For example::
+
+ CC_FLAGS_FPU := -mhard-float
+
+or::
+
+ CC_FLAGS_NO_FPU := -msoft-float
+
+Normal kernel code is assumed to use the equivalent of ``CC_FLAGS_NO_FPU``.
+
+Runtime API
+-----------
+
+The runtime API is provided in ``linux/fpu.h``. This header cannot be included
+from files implementing FP code (those with their compilation flags adjusted as
+above). Instead, it must be included when defining the FP critical sections.
+
+.. c:function:: bool kernel_fpu_available( void )
+
+ This function reports if floating-point code can be used on this CPU or
+ platform. The value returned by this function is not expected to change
+ at runtime, so it only needs to be called once, not before every
+ critical section.
+
+.. c:function:: void kernel_fpu_begin( void )
+ void kernel_fpu_end( void )
+
+ These functions create a floating-point critical section. It is only
+ valid to call ``kernel_fpu_begin()`` after a previous call to
+ ``kernel_fpu_available()`` returned ``true``. These functions are only
+ guaranteed to be callable from (preemptible or non-preemptible) process
+ context.
+
+ Preemption may be disabled inside critical sections, so their size
+ should be minimized. They are *not* required to be reentrant. If the
+ caller expects to nest critical sections, it must implement its own
+ reference counting.
diff --git a/Documentation/core-api/index.rst b/Documentation/core-api/index.rst
index 7a3a08d81f11..974beccd671f 100644
--- a/Documentation/core-api/index.rst
+++ b/Documentation/core-api/index.rst
@@ -48,6 +48,7 @@ Library functionality that is used throughout the kernel.
errseq
wrappers/atomic_t
wrappers/atomic_bitops
+ floating-point
Low level entry and exit
========================
diff --git a/Makefile b/Makefile
index ee995fc2b0e5..79c9e0b56ab8 100644
--- a/Makefile
+++ b/Makefile
@@ -969,6 +969,11 @@ KBUILD_CFLAGS += $(CC_FLAGS_CFI)
export CC_FLAGS_CFI
endif
+# Architectures can define flags to add/remove for floating-point support
+CC_FLAGS_FPU += -D_LINUX_FPU_COMPILATION_UNIT
+export CC_FLAGS_FPU
+export CC_FLAGS_NO_FPU
+
ifneq ($(CONFIG_FUNCTION_ALIGNMENT),0)
KBUILD_CFLAGS += -falign-functions=$(CONFIG_FUNCTION_ALIGNMENT)
endif
diff --git a/arch/Kconfig b/arch/Kconfig
index f4b210ab0612..e1c01ce819ed 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -1478,6 +1478,12 @@ config ARCH_HAS_NONLEAF_PMD_YOUNG
address translations. Page table walkers that clear the accessed bit
may use this capability to reduce their search space.
+config ARCH_HAS_KERNEL_FPU_SUPPORT
+ bool
+ help
+ Architectures that select this option can run floating-point code in
+ the kernel, as described in Documentation/core-api/floating-point.rst.
+
source "kernel/gcov/Kconfig"
source "scripts/gcc-plugins/Kconfig"
diff --git a/include/linux/fpu.h b/include/linux/fpu.h
new file mode 100644
index 000000000000..2fb63e22913b
--- /dev/null
+++ b/include/linux/fpu.h
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifndef _LINUX_FPU_H
+#define _LINUX_FPU_H
+
+#ifdef _LINUX_FPU_COMPILATION_UNIT
+#error FP code must be compiled separately. See Documentation/core-api/floating-point.rst.
+#endif
+
+#include <asm/fpu.h>
+
+#endif
--
2.42.0
next prev parent reply other threads:[~2023-12-28 1:42 UTC|newest]
Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-12-28 1:41 [PATCH v2 00/14] Unified cross-architecture kernel-mode FPU API Samuel Holland
2023-12-28 1:41 ` Samuel Holland [this message]
2023-12-28 6:19 ` [PATCH v2 01/14] arch: Add ARCH_HAS_KERNEL_FPU_SUPPORT Christoph Hellwig
2023-12-28 1:41 ` [PATCH v2 02/14] ARM: Implement ARCH_HAS_KERNEL_FPU_SUPPORT Samuel Holland
2023-12-28 1:41 ` [PATCH v2 03/14] ARM: crypto: Use CC_FLAGS_FPU for NEON CFLAGS Samuel Holland
2023-12-28 1:41 ` [PATCH v2 04/14] arm64: Implement ARCH_HAS_KERNEL_FPU_SUPPORT Samuel Holland
2023-12-28 1:41 ` [PATCH v2 05/14] arm64: crypto: Use CC_FLAGS_FPU for NEON CFLAGS Samuel Holland
2023-12-28 6:19 ` Christoph Hellwig
2023-12-28 1:41 ` [PATCH v2 06/14] lib/raid6: " Samuel Holland
2023-12-28 1:41 ` [PATCH v2 07/14] LoongArch: Implement ARCH_HAS_KERNEL_FPU_SUPPORT Samuel Holland
2024-01-04 9:55 ` Huacai Chen
2024-01-04 15:58 ` Samuel Holland
2024-01-07 2:39 ` Huacai Chen
2024-01-08 9:37 ` Christoph Hellwig
2023-12-28 1:41 ` [PATCH v2 08/14] powerpc: " Samuel Holland
2023-12-28 3:19 ` Michael Ellerman
2023-12-28 1:41 ` [PATCH v2 09/14] x86: " Samuel Holland
2023-12-28 1:42 ` [PATCH v2 10/14] riscv: Add support for kernel-mode FPU Samuel Holland
2023-12-28 6:20 ` Christoph Hellwig
2024-01-10 14:51 ` Palmer Dabbelt
2023-12-28 1:42 ` [PATCH v2 11/14] drm/amd/display: Only use hard-float, not altivec on powerpc Samuel Holland
2023-12-28 1:42 ` [PATCH v2 12/14] drm/amd/display: Use ARCH_HAS_KERNEL_FPU_SUPPORT Samuel Holland
2023-12-28 6:20 ` Christoph Hellwig
2023-12-28 1:42 ` [PATCH v2 13/14] selftests/fpu: Move FP code to a separate translation unit Samuel Holland
2023-12-28 6:20 ` Christoph Hellwig
2023-12-28 1:42 ` [PATCH v2 14/14] selftests/fpu: Allow building on other architectures Samuel Holland
2024-01-03 14:27 ` [PATCH v2 00/14] Unified cross-architecture kernel-mode FPU API Alex Deucher
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20231228014220.3562640-2-samuel.holland@sifive.com \
--to=samuel.holland@sifive.com \
--cc=amd-gfx@lists.freedesktop.org \
--cc=corbet@lwn.net \
--cc=hch@lst.de \
--cc=linux-arch@vger.kernel.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-doc@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-riscv@lists.infradead.org \
--cc=linuxppc-dev@lists.ozlabs.org \
--cc=loongarch@lists.linux.dev \
--cc=x86@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).