1.\" Copyright (c) 2014 2.\" Konstantin Belousov <kib@FreeBSD.org>. All rights reserved. 3.\" 4.\" Redistribution and use in source and binary forms, with or without 5.\" modification, are permitted provided that the following conditions 6.\" are met: 7.\" 1. Redistributions of source code must retain the above copyright 8.\" notice, this list of conditions and the following disclaimer. 9.\" 2. Redistributions in binary form must reproduce the above copyright 10.\" notice, this list of conditions and the following disclaimer in the 11.\" documentation and/or other materials provided with the distribution. 12.\" 13.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 14.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 15.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 16.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 17.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 18.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 19.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 20.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 21.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 22.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23.\" 24.\" $FreeBSD$ 25.\" 26.Dd October 13, 2020 27.Dt FPU_KERN 9 28.Os 29.Sh NAME 30.Nm fpu_kern 31.Nd "facility to use the FPU in the kernel" 32.Sh SYNOPSIS 33.In machine/fpu.h 34.Ft struct fpu_kern_ctx * 35.Fn fpu_kern_alloc_ctx "u_int flags" 36.Ft void 37.Fn fpu_kern_free_ctx "struct fpu_kern_ctx *ctx" 38.Ft void 39.Fn fpu_kern_enter "struct thread *td" "struct fpu_kern_ctx *ctx" "u_int flags" 40.Ft int 41.Fn fpu_kern_leave "struct thread *td" "struct fpu_kern_ctx *ctx" 42.Ft int 43.Fn fpu_kern_thread "u_int flags" 44.Ft int 45.Fn is_fpu_kern_thread "u_int flags" 46.Sh DESCRIPTION 47The 48.Nm 49family of functions allows the use of FPU hardware in kernel code. 50Modern FPUs are not limited to providing hardware implementation for 51floating point arithmetic; they offer advanced accelerators for cryptography 52and other computational-intensive algorithms. 53These facilities share registers with the FPU hardware. 54.Pp 55Typical kernel code does not need access to the FPU. 56Saving a large register file on each entry to the kernel would waste 57time. 58When kernel code uses the FPU, the current FPU state must be saved to 59avoid corrupting the user-mode state, and vice versa. 60.Pp 61The management of the save and restore is automatic. 62The processor catches accesses to the FPU registers 63when the non-current context tries to access them. 64Explicit calls are required for the allocation of the save area and 65the notification of the start and end of the code using the FPU. 66.Pp 67The 68.Fn fpu_kern_alloc_ctx 69function allocates the memory used by 70.Nm 71to track the use of the FPU hardware state and the related software state. 72The 73.Fn fpu_kern_alloc_ctx 74function requires the 75.Fa flags 76argument, which currently accepts the following flags: 77.Bl -tag -width ".Dv FPU_KERN_NOWAIT" -offset indent 78.It Dv FPU_KERN_NOWAIT 79Do not wait for the available memory if the request could not be satisfied 80without sleep. 81.It 0 82No special handling is required. 83.El 84.Pp 85The function returns the allocated context area, or 86.Va NULL 87if the allocation failed. 88.Pp 89The 90.Fn fpu_kern_free_ctx 91function frees the context previously allocated by 92.Fn fpu_kern_alloc_ctx . 93.Pp 94The 95.Fn fpu_kern_enter 96function designates the start of the region of kernel code where the 97use of the FPU is allowed. 98Its arguments are: 99.Bl -tag -width ".Fa ctx" -offset indent 100.It Fa td 101Currently must be 102.Va curthread . 103.It Fa ctx 104The context save area previously allocated by 105.Fn fpu_kern_alloc_ctx 106and not currently in use by another call to 107.Fn fpu_kern_enter . 108.It Fa flags 109This argument currently accepts the following flags: 110.Bl -tag -width ".Dv FPU_KERN_NORMAL" -offset indent 111.It Dv FPU_KERN_NORMAL 112Indicates that the caller intends to access the full FPU state. 113Must be specified currently. 114.It Dv FPU_KERN_KTHR 115Indicates that no saving of the current FPU state should be performed, 116if the thread called 117.Xr fpu_kern_thread 9 118function. 119This is intended to minimize code duplication in callers which 120could be used from both kernel thread and syscall contexts. 121The 122.Fn fpu_kern_leave 123function correctly handles such contexts. 124.It Dv FPU_KERN_NOCTX 125Avoid nesting save area. 126If the flag is specified, the 127.Fa ctx 128must be passed as 129.Va NULL . 130The flag should only be used for really short code blocks 131which can be executed in a critical section. 132It avoids the need to allocate the FPU context by the cost 133of increased system latency. 134.El 135.El 136.Pp 137The function does not sleep or block. 138It could cause an FPU trap during execution, and on the first FPU access 139after the function returns, as well as after each context switch. 140On i386 and amd64 this will be the 141.Nm Device Not Available 142exception (see Intel Software Developer Manual for the reference). 143.Pp 144The 145.Fn fpu_kern_leave 146function ends the region started by 147.Fn fpu_kern_enter . 148It is erroneous to use the FPU in the kernel before 149.Fn fpu_kern_enter 150or after 151.Fn fpu_kern_leave . 152The function takes the 153.Fa td 154thread argument, which currently must be 155.Va curthread , 156and the 157.Fa ctx 158context pointer, previously passed to 159.Fn fpu_kern_enter . 160After the function returns, the context may be freed or reused 161by another invocation of 162.Fn fpu_kern_enter . 163The function always returns 0. 164.Pp 165The 166.Fn fpu_kern_thread 167function enables an optimization for threads which never leave to 168the usermode. 169The current thread will reuse the usermode save area for the kernel FPU state 170instead of requiring an explicitly allocated context. 171There are no flags defined for the function, and no error states 172that the function returns. 173Once this function has been called, neither 174.Fn fpu_kern_enter 175nor 176.Fn fpu_kern_leave 177is required to be called and the fpu is available for use in the calling thread. 178.Pp 179The 180.Fn is_fpu_kern_thread 181function returns the boolean indicating whether the current thread 182entered the mode enabled by 183.Fn fpu_kern_thread . 184There is currently no flags defined for the function, the return 185value is true if the current thread have the permanent FPU save area, 186and false otherwise. 187.Sh NOTES 188The 189.Nm 190is currently implemented only for the i386, amd64, and arm64 architectures. 191.Pp 192There is no way to handle floating point exceptions raised from 193kernel mode. 194.Pp 195The unused 196.Fa flags 197arguments 198to the 199.Nm 200functions are to be extended to allow specification of the 201set of the FPU hardware state used by the code region. 202This would allow optimizations of saving and restoring the state. 203.Sh AUTHORS 204The 205.Nm 206facitily and this manual page were written by 207.An Konstantin Belousov Aq Mt kib@FreeBSD.org . 208The arm64 support was added by 209.An Andrew Turner Aq Mt andrew@FreeBSD.org . 210.Sh BUGS 211.Fn fpu_kern_leave 212should probably have type 213.Ft void 214(like 215.Fn fpu_kern_enter ) . 216