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 March 7, 2018 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.Ft struct fpu_kern_ctx * 34.Fn fpu_kern_alloc_ctx "u_int flags" 35.Ft void 36.Fn fpu_kern_free_ctx "struct fpu_kern_ctx *ctx" 37.Ft void 38.Fn fpu_kern_enter "struct thread *td" "struct fpu_kern_ctx *ctx" "u_int flags" 39.Ft int 40.Fn fpu_kern_leave "struct thread *td" "struct fpu_kern_ctx *ctx" 41.Ft int 42.Fn fpu_kern_thread "u_int flags" 43.Ft int 44.Fn is_fpu_kern_thread "u_int flags" 45.Sh DESCRIPTION 46The 47.Nm 48family of functions allows the use of FPU hardware in kernel code. 49Modern FPUs are not limited to providing hardware implementation for 50floating point arithmetic; they offer advanced accelerators for cryptography 51and other computational-intensive algorithms. 52These facilities share registers with the FPU hardware. 53.Pp 54Typical kernel code does not need access to the FPU. 55Saving a large register file on each entry to the kernel would waste 56time. 57When kernel code uses the FPU, the current FPU state must be saved to 58avoid corrupting the user-mode state, and vice versa. 59.Pp 60The management of the save and restore is automatic. 61The processor catches accesses to the FPU registers 62when the non-current context tries to access them. 63Explicit calls are required for the allocation of the save area and 64the notification of the start and end of the code using the FPU. 65.Pp 66The 67.Fn fpu_kern_alloc_ctx 68function allocates the memory used by 69.Nm 70to track the use of the FPU hardware state and the related software state. 71The 72.Fn fpu_kern_alloc_ctx 73function requires the 74.Fa flags 75argument, which currently accepts the following flags: 76.Bl -tag -width ".Dv FPU_KERN_NOWAIT" -offset indent 77.It Dv FPU_KERN_NOWAIT 78Do not wait for the available memory if the request could not be satisfied 79without sleep. 80.It 0 81No special handling is required. 82.El 83.Pp 84The function returns the allocated context area, or 85.Va NULL 86if the allocation failed. 87.Pp 88The 89.Fn fpu_kern_free_ctx 90function frees the context previously allocated by 91.Fn fpu_kern_alloc_ctx . 92.Pp 93The 94.Fn fpu_kern_enter 95function designates the start of the region of kernel code where the 96use of the FPU is allowed. 97Its arguments are: 98.Bl -tag -width ".Fa ctx" -offset indent 99.It Fa td 100Currently must be 101.Va curthread . 102.It Fa ctx 103The context save area previously allocated by 104.Fn fpu_kern_alloc_ctx 105and not currently in use by another call to 106.Fn fpu_kern_enter . 107.It Fa flags 108This argument currently accepts the following flags: 109.Bl -tag -width ".Dv FPU_KERN_NORMAL" -offset indent 110.It Dv FPU_KERN_NORMAL 111Indicates that the caller intends to access the full FPU state. 112Must be specified currently. 113.It Dv FPU_KERN_KTHR 114Indicates that no saving of the current FPU state should be performed, 115if the thread called 116.Xr fpu_kern_thread 9 117function. 118This is intended to minimize code duplication in callers which 119could be used from both kernel thread and syscall contexts. 120The 121.Fn fpu_kern_leave 122function correctly handles such contexts. 123.It Dv FPU_KERN_NOCTX 124Avoid nesting save area. 125If the flag is specified, the 126.Fa ctx 127must be passed as 128.Va NULL . 129The flag should only be used for really short code blocks 130which can be executed in a critical section. 131It avoids the need to allocate the FPU context by the cost 132of increased system latency. 133.El 134.El 135.Pp 136The function does not sleep or block. 137It could cause an FPU trap during execution, and on the first FPU access 138after the function returns, as well as after each context switch. 139On i386 and amd64 this will be the 140.Nm Device Not Available 141exception (see Intel Software Developer Manual for the reference). 142.Pp 143The 144.Fn fpu_kern_leave 145function ends the region started by 146.Fn fpu_kern_enter . 147It is erroneous to use the FPU in the kernel before 148.Fn fpu_kern_enter 149or after 150.Fn fpu_kern_leave . 151The function takes the 152.Fa td 153thread argument, which currently must be 154.Va curthread , 155and the 156.Fa ctx 157context pointer, previously passed to 158.Fn fpu_kern_enter . 159After the function returns, the context may be freed or reused 160by another invocation of 161.Fn fpu_kern_enter . 162The function always returns 0. 163.Pp 164The 165.Fn fpu_kern_thread 166function enables an optimization for threads which never leave to 167the usermode. 168The current thread will reuse the usermode save area for the kernel FPU state 169instead of requiring an explicitly allocated context. 170There are no flags defined for the function, and no error states 171that the function returns. 172Once this function has been called, neither 173.Fn fpu_kern_enter 174nor 175.Fn fpu_kern_leave 176is required to be called and the fpu is available for use in the calling thread. 177.Pp 178The 179.Fn is_fpu_kern_thread 180function returns the boolean indicating whether the current thread 181entered the mode enabled by 182.Fn fpu_kern_thread . 183There is currently no flags defined for the function, the return 184value is true if the current thread have the permanent FPU save area, 185and false otherwise. 186.Sh NOTES 187The 188.Nm 189is currently implemented only for the i386, amd64, and arm64 architectures. 190.Pp 191There is no way to handle floating point exceptions raised from 192kernel mode. 193.Pp 194The unused 195.Fa flags 196arguments 197to the 198.Nm 199functions are to be extended to allow specification of the 200set of the FPU hardware state used by the code region. 201This would allow optimizations of saving and restoring the state. 202.Sh AUTHORS 203The 204.Nm 205facitily and this manual page were written by 206.An Konstantin Belousov Aq Mt kib@FreeBSD.org . 207The arm64 support was added by 208.An Andrew Turner Aq Mt andrew@FreeBSD.org . 209.Sh BUGS 210.Fn fpu_kern_leave 211should probably have type 212.Ft void 213(like 214.Fn fpu_kern_enter ) . 215