Skip to content

Commit 6cbd1d6

Browse files
SiFiveHollandakpm00
authored andcommitted
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/[email protected] Signed-off-by: Samuel Holland <[email protected]> Suggested-by: Christoph Hellwig <[email protected]> Reviewed-by: Christoph Hellwig <[email protected]> Acked-by: Christian König <[email protected]> Cc: Alex Deucher <[email protected]> Cc: Borislav Petkov (AMD) <[email protected]> Cc: Catalin Marinas <[email protected]> Cc: Dave Hansen <[email protected]> Cc: Huacai Chen <[email protected]> Cc: Ingo Molnar <[email protected]> Cc: Jonathan Corbet <[email protected]> Cc: Masahiro Yamada <[email protected]> Cc: Michael Ellerman <[email protected]> Cc: Nathan Chancellor <[email protected]> Cc: Nicolas Schier <[email protected]> Cc: Palmer Dabbelt <[email protected]> Cc: Russell King <[email protected]> Cc: Thomas Gleixner <[email protected]> Cc: WANG Xuerui <[email protected]> Cc: Will Deacon <[email protected]> Signed-off-by: Andrew Morton <[email protected]>
1 parent b11b998 commit 6cbd1d6

File tree

5 files changed

+102
-0
lines changed

5 files changed

+102
-0
lines changed
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
.. SPDX-License-Identifier: GPL-2.0+
2+
3+
Floating-point API
4+
==================
5+
6+
Kernel code is normally prohibited from using floating-point (FP) registers or
7+
instructions, including the C float and double data types. This rule reduces
8+
system call overhead, because the kernel does not need to save and restore the
9+
userspace floating-point register state.
10+
11+
However, occasionally drivers or library functions may need to include FP code.
12+
This is supported by isolating the functions containing FP code to a separate
13+
translation unit (a separate source file), and saving/restoring the FP register
14+
state around calls to those functions. This creates "critical sections" of
15+
floating-point usage.
16+
17+
The reason for this isolation is to prevent the compiler from generating code
18+
touching the FP registers outside these critical sections. Compilers sometimes
19+
use FP registers to optimize inlined ``memcpy`` or variable assignment, as
20+
floating-point registers may be wider than general-purpose registers.
21+
22+
Usability of floating-point code within the kernel is architecture-specific.
23+
Additionally, because a single kernel may be configured to support platforms
24+
both with and without a floating-point unit, FPU availability must be checked
25+
both at build time and at run time.
26+
27+
Several architectures implement the generic kernel floating-point API from
28+
``linux/fpu.h``, as described below. Some other architectures implement their
29+
own unique APIs, which are documented separately.
30+
31+
Build-time API
32+
--------------
33+
34+
Floating-point code may be built if the option ``ARCH_HAS_KERNEL_FPU_SUPPORT``
35+
is enabled. For C code, such code must be placed in a separate file, and that
36+
file must have its compilation flags adjusted using the following pattern::
37+
38+
CFLAGS_foo.o += $(CC_FLAGS_FPU)
39+
CFLAGS_REMOVE_foo.o += $(CC_FLAGS_NO_FPU)
40+
41+
Architectures are expected to define one or both of these variables in their
42+
top-level Makefile as needed. For example::
43+
44+
CC_FLAGS_FPU := -mhard-float
45+
46+
or::
47+
48+
CC_FLAGS_NO_FPU := -msoft-float
49+
50+
Normal kernel code is assumed to use the equivalent of ``CC_FLAGS_NO_FPU``.
51+
52+
Runtime API
53+
-----------
54+
55+
The runtime API is provided in ``linux/fpu.h``. This header cannot be included
56+
from files implementing FP code (those with their compilation flags adjusted as
57+
above). Instead, it must be included when defining the FP critical sections.
58+
59+
.. c:function:: bool kernel_fpu_available( void )
60+
61+
This function reports if floating-point code can be used on this CPU or
62+
platform. The value returned by this function is not expected to change
63+
at runtime, so it only needs to be called once, not before every
64+
critical section.
65+
66+
.. c:function:: void kernel_fpu_begin( void )
67+
void kernel_fpu_end( void )
68+
69+
These functions create a floating-point critical section. It is only
70+
valid to call ``kernel_fpu_begin()`` after a previous call to
71+
``kernel_fpu_available()`` returned ``true``. These functions are only
72+
guaranteed to be callable from (preemptible or non-preemptible) process
73+
context.
74+
75+
Preemption may be disabled inside critical sections, so their size
76+
should be minimized. They are *not* required to be reentrant. If the
77+
caller expects to nest critical sections, it must implement its own
78+
reference counting.

Documentation/core-api/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ Library functionality that is used throughout the kernel.
4848
errseq
4949
wrappers/atomic_t
5050
wrappers/atomic_bitops
51+
floating-point
5152

5253
Low level entry and exit
5354
========================

Makefile

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -970,6 +970,11 @@ KBUILD_CFLAGS += $(CC_FLAGS_CFI)
970970
export CC_FLAGS_CFI
971971
endif
972972

973+
# Architectures can define flags to add/remove for floating-point support
974+
CC_FLAGS_FPU += -D_LINUX_FPU_COMPILATION_UNIT
975+
export CC_FLAGS_FPU
976+
export CC_FLAGS_NO_FPU
977+
973978
ifneq ($(CONFIG_FUNCTION_ALIGNMENT),0)
974979
# Set the minimal function alignment. Use the newer GCC option
975980
# -fmin-function-alignment if it is available, or fall back to -falign-funtions.

arch/Kconfig

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1594,6 +1594,12 @@ config ARCH_HAS_NONLEAF_PMD_YOUNG
15941594
address translations. Page table walkers that clear the accessed bit
15951595
may use this capability to reduce their search space.
15961596

1597+
config ARCH_HAS_KERNEL_FPU_SUPPORT
1598+
bool
1599+
help
1600+
Architectures that select this option can run floating-point code in
1601+
the kernel, as described in Documentation/core-api/floating-point.rst.
1602+
15971603
source "kernel/gcov/Kconfig"
15981604

15991605
source "scripts/gcc-plugins/Kconfig"

include/linux/fpu.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/* SPDX-License-Identifier: GPL-2.0 */
2+
3+
#ifndef _LINUX_FPU_H
4+
#define _LINUX_FPU_H
5+
6+
#ifdef _LINUX_FPU_COMPILATION_UNIT
7+
#error FP code must be compiled separately. See Documentation/core-api/floating-point.rst.
8+
#endif
9+
10+
#include <asm/fpu.h>
11+
12+
#endif

0 commit comments

Comments
 (0)