brintos

brintos / linux-shallow public Read only

0
0
Text · 3.3 KiB · a8d0d4b Raw
79 lines · plain
1.. SPDX-License-Identifier: GPL-2.0+2 3Floating-point API4==================5 6Kernel code is normally prohibited from using floating-point (FP) registers or7instructions, including the C float and double data types. This rule reduces8system call overhead, because the kernel does not need to save and restore the9userspace floating-point register state.10 11However, occasionally drivers or library functions may need to include FP code.12This is supported by isolating the functions containing FP code to a separate13translation unit (a separate source file), and saving/restoring the FP register14state around calls to those functions. This creates "critical sections" of15floating-point usage.16 17The reason for this isolation is to prevent the compiler from generating code18touching the FP registers outside these critical sections. Compilers sometimes19use FP registers to optimize inlined ``memcpy`` or variable assignment, as20floating-point registers may be wider than general-purpose registers.21 22Usability of floating-point code within the kernel is architecture-specific.23Additionally, because a single kernel may be configured to support platforms24both with and without a floating-point unit, FPU availability must be checked25both at build time and at run time.26 27Several architectures implement the generic kernel floating-point API from28``linux/fpu.h``, as described below. Some other architectures implement their29own unique APIs, which are documented separately.30 31Build-time API32--------------33 34Floating-point code may be built if the option ``ARCH_HAS_KERNEL_FPU_SUPPORT``35is enabled. For C code, such code must be placed in a separate file, and that36file 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 41Architectures are expected to define one or both of these variables in their42top-level Makefile as needed. For example::43 44    CC_FLAGS_FPU := -mhard-float45 46or::47 48    CC_FLAGS_NO_FPU := -msoft-float49 50Normal kernel code is assumed to use the equivalent of ``CC_FLAGS_NO_FPU``.51 52Runtime API53-----------54 55The runtime API is provided in ``linux/fpu.h``. This header cannot be included56from files implementing FP code (those with their compilation flags adjusted as57above). 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 or62        platform. The value returned by this function is not expected to change63        at runtime, so it only needs to be called once, not before every64        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 only70        valid to call ``kernel_fpu_begin()`` after a previous call to71        ``kernel_fpu_available()`` returned ``true``. These functions are only72        guaranteed to be callable from (preemptible or non-preemptible) process73        context.74 75        Preemption may be disabled inside critical sections, so their size76        should be minimized. They are *not* required to be reentrant. If the77        caller expects to nest critical sections, it must implement its own78        reference counting.79