floating-point.rst 3.3 KB

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