forked from mirrors/linux
		
	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>
		
			
				
	
	
		
			78 lines
		
	
	
	
		
			3.3 KiB
		
	
	
	
		
			ReStructuredText
		
	
	
	
	
	
			
		
		
	
	
			78 lines
		
	
	
	
		
			3.3 KiB
		
	
	
	
		
			ReStructuredText
		
	
	
	
	
	
.. 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.
 |