mirror of
https://github.com/torvalds/linux.git
synced 2024-11-24 21:21:41 +00:00
arch: add ARCH_HAS_KERNEL_FPU_SUPPORT
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. Link: https://lkml.kernel.org/r/20240329072441.591471-2-samuel.holland@sifive.com Signed-off-by: Samuel Holland <samuel.holland@sifive.com> Suggested-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Christoph Hellwig <hch@lst.de> Acked-by: Christian König <christian.koenig@amd.com> Cc: Alex Deucher <alexander.deucher@amd.com> Cc: Borislav Petkov (AMD) <bp@alien8.de> Cc: Catalin Marinas <catalin.marinas@arm.com> Cc: Dave Hansen <dave.hansen@linux.intel.com> Cc: Huacai Chen <chenhuacai@kernel.org> Cc: Ingo Molnar <mingo@redhat.com> Cc: Jonathan Corbet <corbet@lwn.net> Cc: Masahiro Yamada <masahiroy@kernel.org> Cc: Michael Ellerman <mpe@ellerman.id.au> Cc: Nathan Chancellor <nathan@kernel.org> Cc: Nicolas Schier <nicolas@fjasle.eu> Cc: Palmer Dabbelt <palmer@rivosinc.com> Cc: Russell King <linux@armlinux.org.uk> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: WANG Xuerui <git@xen0n.name> Cc: Will Deacon <will@kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
This commit is contained in:
parent
b11b998e98
commit
6cbd1d6d36
78
Documentation/core-api/floating-point.rst
Normal file
78
Documentation/core-api/floating-point.rst
Normal file
@ -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.
|
@ -48,6 +48,7 @@ Library functionality that is used throughout the kernel.
|
|||||||
errseq
|
errseq
|
||||||
wrappers/atomic_t
|
wrappers/atomic_t
|
||||||
wrappers/atomic_bitops
|
wrappers/atomic_bitops
|
||||||
|
floating-point
|
||||||
|
|
||||||
Low level entry and exit
|
Low level entry and exit
|
||||||
========================
|
========================
|
||||||
|
5
Makefile
5
Makefile
@ -970,6 +970,11 @@ KBUILD_CFLAGS += $(CC_FLAGS_CFI)
|
|||||||
export CC_FLAGS_CFI
|
export CC_FLAGS_CFI
|
||||||
endif
|
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)
|
ifneq ($(CONFIG_FUNCTION_ALIGNMENT),0)
|
||||||
# Set the minimal function alignment. Use the newer GCC option
|
# Set the minimal function alignment. Use the newer GCC option
|
||||||
# -fmin-function-alignment if it is available, or fall back to -falign-funtions.
|
# -fmin-function-alignment if it is available, or fall back to -falign-funtions.
|
||||||
|
@ -1594,6 +1594,12 @@ config ARCH_HAS_NONLEAF_PMD_YOUNG
|
|||||||
address translations. Page table walkers that clear the accessed bit
|
address translations. Page table walkers that clear the accessed bit
|
||||||
may use this capability to reduce their search space.
|
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 "kernel/gcov/Kconfig"
|
||||||
|
|
||||||
source "scripts/gcc-plugins/Kconfig"
|
source "scripts/gcc-plugins/Kconfig"
|
||||||
|
12
include/linux/fpu.h
Normal file
12
include/linux/fpu.h
Normal file
@ -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
|
Loading…
Reference in New Issue
Block a user