Floating-point API

Kernel code is normally prohibited from using floating-point (FP) registers orinstructions, including the C float and double data types. This rule reducessystem call overhead, because the kernel does not need to save and restore theuserspace 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 separatetranslation unit (a separate source file), and saving/restoring the FP registerstate around calls to those functions. This creates “critical sections” offloating-point usage.

The reason for this isolation is to prevent the compiler from generating codetouching the FP registers outside these critical sections. Compilers sometimesuse FP registers to optimize inlinedmemcpy or variable assignment, asfloating-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 platformsboth with and without a floating-point unit, FPU availability must be checkedboth at build time and at run time.

Several architectures implement the generic kernel floating-point API fromlinux/fpu.h, as described below. Some other architectures implement theirown unique APIs, which are documented separately.

Build-time API

Floating-point code may be built if the optionARCH_HAS_KERNEL_FPU_SUPPORTis enabled. For C code, such code must be placed in a separate file, and thatfile 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 theirtop-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 ofCC_FLAGS_NO_FPU.

Runtime API

The runtime API is provided inlinux/fpu.h. This header cannot be includedfrom files implementing FP code (those with their compilation flags adjusted asabove). Instead, it must be included when defining the FP critical sections.

boolkernel_fpu_available(void)

This function reports if floating-point code can be used on this CPU orplatform. The value returned by this function is not expected to changeat runtime, so it only needs to be called once, not before everycritical section.

voidkernel_fpu_begin(void)
voidkernel_fpu_end(void)

These functions create a floating-point critical section. It is onlyvalid to callkernel_fpu_begin() after a previous call tokernel_fpu_available() returnedtrue. These functions are onlyguaranteed to be callable from (preemptible or non-preemptible) processcontext.

Preemption may be disabled inside critical sections, so their sizeshould be minimized. They arenot required to be reentrant. If thecaller expects to nest critical sections, it must implement its ownreference counting.