1*bdcfeac3SKonstantin Belousov.\" SPDX-License-Identifier: BSD-2-Clause 2*bdcfeac3SKonstantin Belousov.\" 3*bdcfeac3SKonstantin Belousov.\" Copyright 2026 The FreeBSD Foundation. 4*bdcfeac3SKonstantin Belousov.\" 5*bdcfeac3SKonstantin Belousov.\" This documentation was written by Konstantin Belousov <kib@FreeBSD.org> 6*bdcfeac3SKonstantin Belousov.\" under sponsorship of The FreeBSD Foundation. 7*bdcfeac3SKonstantin Belousov.\" 8*bdcfeac3SKonstantin Belousov.Dd September 26, 2026 9*bdcfeac3SKonstantin Belousov.Dt SYSARCH.X86 2 i386 10*bdcfeac3SKonstantin Belousov.Os 11*bdcfeac3SKonstantin Belousov.Sh NAME 12*bdcfeac3SKonstantin Belousov.Nm sysarch.x86 13*bdcfeac3SKonstantin Belousov.Nd architecture-dependent system call on x86 14*bdcfeac3SKonstantin Belousov.Sh LIBRARY 15*bdcfeac3SKonstantin Belousov.Lb libc 16*bdcfeac3SKonstantin Belousov.Sh SYNOPSIS 17*bdcfeac3SKonstantin Belousov.In machine/sysarch.h 18*bdcfeac3SKonstantin Belousov.Ft int 19*bdcfeac3SKonstantin Belousov.Fn sysarch "int number" "void *args" 20*bdcfeac3SKonstantin Belousov.Sh DESCRIPTION 21*bdcfeac3SKonstantin BelousovThe 22*bdcfeac3SKonstantin Belousovmanual page describes the functions provided by the 23*bdcfeac3SKonstantin Belousov.Fn sysarch 24*bdcfeac3SKonstantin Belousovsystem call on x86 architectures, that is i386 and amd64, see 25*bdcfeac3SKonstantin Belousov.Xr arch 7 . 26*bdcfeac3SKonstantin Belousov.Ss Parameter Types 27*bdcfeac3SKonstantin BelousovThe following structures are used as the arguments pointed to by the 28*bdcfeac3SKonstantin Belousov.Fa args 29*bdcfeac3SKonstantin Belousovparameter. 30*bdcfeac3SKonstantin BelousovRefer to the description of each request for the meaning of 31*bdcfeac3SKonstantin Belousovindividual fields: 32*bdcfeac3SKonstantin Belousov.Pp 33*bdcfeac3SKonstantin BelousovThe 34*bdcfeac3SKonstantin Belousov.Dv I386_GET_IOPERM 35*bdcfeac3SKonstantin Belousovand 36*bdcfeac3SKonstantin Belousov.Dv I386_SET_IOPERM 37*bdcfeac3SKonstantin Belousovrequests take a 38*bdcfeac3SKonstantin Belousov.Vt struct i386_ioperm_args , 39*bdcfeac3SKonstantin Belousovwhich is defined as follows: 40*bdcfeac3SKonstantin Belousov.Bd -literal 41*bdcfeac3SKonstantin Belousovstruct i386_ioperm_args { 42*bdcfeac3SKonstantin Belousov unsigned int start; 43*bdcfeac3SKonstantin Belousov unsigned int length; 44*bdcfeac3SKonstantin Belousov int enable; 45*bdcfeac3SKonstantin Belousov}; 46*bdcfeac3SKonstantin Belousov.Ed 47*bdcfeac3SKonstantin Belousov.Pp 48*bdcfeac3SKonstantin BelousovThe 49*bdcfeac3SKonstantin Belousov.Dv I386_GET_LDT 50*bdcfeac3SKonstantin Belousovand 51*bdcfeac3SKonstantin Belousov.Dv I386_SET_LDT 52*bdcfeac3SKonstantin Belousovrequests take a 53*bdcfeac3SKonstantin Belousov.Vt struct i386_ldt_args , 54*bdcfeac3SKonstantin Belousovwhose definition differs between i386 and amd64. 55*bdcfeac3SKonstantin BelousovThe i386 variant is: 56*bdcfeac3SKonstantin Belousov.Bd -literal 57*bdcfeac3SKonstantin Belousovstruct i386_ldt_args { 58*bdcfeac3SKonstantin Belousov unsigned int start; 59*bdcfeac3SKonstantin Belousov union descriptor *descs; 60*bdcfeac3SKonstantin Belousov unsigned int num; 61*bdcfeac3SKonstantin Belousov}; 62*bdcfeac3SKonstantin Belousov.Ed 63*bdcfeac3SKonstantin BelousovThe amd64 variant is: 64*bdcfeac3SKonstantin Belousov.Bd -literal 65*bdcfeac3SKonstantin Belousovstruct i386_ldt_args { 66*bdcfeac3SKonstantin Belousov unsigned int start; 67*bdcfeac3SKonstantin Belousov struct user_segment_descriptor *descs __packed; 68*bdcfeac3SKonstantin Belousov unsigned int num; 69*bdcfeac3SKonstantin Belousov}; 70*bdcfeac3SKonstantin Belousov.Ed 71*bdcfeac3SKonstantin Belousov.Pp 72*bdcfeac3SKonstantin BelousovThe request 73*bdcfeac3SKonstantin Belousov.Dv I386_VM86 74*bdcfeac3SKonstantin Belousovis only supported by i386 kernels and takes a 75*bdcfeac3SKonstantin Belousov.Bd -literal 76*bdcfeac3SKonstantin Belousovstruct i386_vm86_args { 77*bdcfeac3SKonstantin Belousov int sub_op; 78*bdcfeac3SKonstantin Belousov char *sub_args; 79*bdcfeac3SKonstantin Belousov}; 80*bdcfeac3SKonstantin Belousov.Ed 81*bdcfeac3SKonstantin Belousov.Pp 82*bdcfeac3SKonstantin BelousovThe 83*bdcfeac3SKonstantin Belousov.Dv I386_GET_XFPUSTATE , 84*bdcfeac3SKonstantin Belousovtakes a 85*bdcfeac3SKonstantin Belousov.Vt struct i386_get_xfpustate 86*bdcfeac3SKonstantin Belousovargument, a 87*bdcfeac3SKonstantin Belousov.Dv AMD64_GET_XFPUSTATE 88*bdcfeac3SKonstantin Belousov.Vt struct amd64_get_xfpustate 89*bdcfeac3SKonstantin Belousovargument. 90*bdcfeac3SKonstantin BelousovThe structures have the same members, but their layout differs due to 91*bdcfeac3SKonstantin Belousovpointer size differences. 92*bdcfeac3SKonstantin BelousovOnly the amd64 variant is listed for clarity. 93*bdcfeac3SKonstantin Belousov.Bd -literal 94*bdcfeac3SKonstantin Belousovstruct amd64_get_xfpustate { 95*bdcfeac3SKonstantin Belousov void *addr; 96*bdcfeac3SKonstantin Belousov int len; 97*bdcfeac3SKonstantin Belousov}; 98*bdcfeac3SKonstantin Belousov.Ed 99*bdcfeac3SKonstantin Belousov.Pp 100*bdcfeac3SKonstantin BelousovThe 101*bdcfeac3SKonstantin Belousov.Dv I386_GET_PKRU , 102*bdcfeac3SKonstantin Belousov.Dv I386_SET_PKRU , 103*bdcfeac3SKonstantin Belousovtake a 104*bdcfeac3SKonstantin Belousov.Vt struct i386_set_pkru 105*bdcfeac3SKonstantin Belousovargument, and 106*bdcfeac3SKonstantin Belousov.Dv AMD64_GET_PKRU 107*bdcfeac3SKonstantin Belousovand 108*bdcfeac3SKonstantin Belousov.Dv AMD64_SET_PKRU 109*bdcfeac3SKonstantin Belousovtake a 110*bdcfeac3SKonstantin Belousov.Vt struct amd64_set_pkru 111*bdcfeac3SKonstantin Belousovargument. 112*bdcfeac3SKonstantin BelousovThe structures have the same members, but their layout differs due to 113*bdcfeac3SKonstantin Belousovpointer size differences. 114*bdcfeac3SKonstantin BelousovOnly the amd64 variant is listed for clarity. 115*bdcfeac3SKonstantin Belousov.Bd -literal 116*bdcfeac3SKonstantin Belousovstruct amd64_set_pkru { 117*bdcfeac3SKonstantin Belousov void *addr; 118*bdcfeac3SKonstantin Belousov unsigned long len; 119*bdcfeac3SKonstantin Belousov unsigned int keyidx; 120*bdcfeac3SKonstantin Belousov int flags; 121*bdcfeac3SKonstantin Belousov}; 122*bdcfeac3SKonstantin Belousov.Ed 123*bdcfeac3SKonstantin Belousov.Ss Requests 124*bdcfeac3SKonstantin BelousovThe following requests can be specified by the 125*bdcfeac3SKonstantin Belousov.Fa number 126*bdcfeac3SKonstantin Belousovargument: 127*bdcfeac3SKonstantin Belousov.Bl -tag -width AMD64_DISABLE_TLSBASE 128*bdcfeac3SKonstantin Belousov.It Dv I386_GET_LDT 129*bdcfeac3SKonstantin BelousovQueries the specified range of LDT descriptors for the 130*bdcfeac3SKonstantin Belousovcalling process. 131*bdcfeac3SKonstantin Belousov.Pp 132*bdcfeac3SKonstantin BelousovThe request takes a pointer to the 133*bdcfeac3SKonstantin Belousov.Vt struct i386_ldt_args 134*bdcfeac3SKonstantin Belousovstructure as the 135*bdcfeac3SKonstantin Belousov.Fa args 136*bdcfeac3SKonstantin Belousovparameter. 137*bdcfeac3SKonstantin BelousovIts 138*bdcfeac3SKonstantin Belousov.Va start 139*bdcfeac3SKonstantin Belousovmember specifies the starting index, and 140*bdcfeac3SKonstantin Belousov.Va num 141*bdcfeac3SKonstantin Belousovthe number of descriptors which are queried. 142*bdcfeac3SKonstantin BelousovThe LDT descriptors in the requested range are copied into 143*bdcfeac3SKonstantin Belousovthe memory specified by the 144*bdcfeac3SKonstantin Belousov.Fa descs 145*bdcfeac3SKonstantin Belousovmember. 146*bdcfeac3SKonstantin Belousov.It Dv I386_SET_LDT 147*bdcfeac3SKonstantin BelousovSet the specified range of LDT descriptors for the calling process. 148*bdcfeac3SKonstantin Belousov.Pp 149*bdcfeac3SKonstantin BelousovLDT is process-global, all process threads share the same table. 150*bdcfeac3SKonstantin BelousovOn the other hand, if several processes share an address space, 151*bdcfeac3SKonstantin Belousovthey still each have their own LDT. 152*bdcfeac3SKonstantin Belousov.Pp 153*bdcfeac3SKonstantin BelousovThe request takes a pointer to the 154*bdcfeac3SKonstantin Belousov.Vt struct i386_ldt_args 155*bdcfeac3SKonstantin Belousovstructure as the 156*bdcfeac3SKonstantin Belousov.Fa args 157*bdcfeac3SKonstantin Belousovparameter. 158*bdcfeac3SKonstantin BelousovIts 159*bdcfeac3SKonstantin Belousov.Va start 160*bdcfeac3SKonstantin Belousovmember specifies the starting index, and 161*bdcfeac3SKonstantin Belousov.Va num 162*bdcfeac3SKonstantin Belousovthe number of descriptors which are set. 163*bdcfeac3SKonstantin BelousovThe LDT descriptors in the requested range 164*bdcfeac3SKonstantin Belousovare initialized from the structures pointed to by the 165*bdcfeac3SKonstantin Belousov.Fa descs 166*bdcfeac3SKonstantin Belousovmember. 167*bdcfeac3SKonstantin Belousov.Pp 168*bdcfeac3SKonstantin BelousovIf the 169*bdcfeac3SKonstantin Belousov.Va descs 170*bdcfeac3SKonstantin Belousovmember value is 171*bdcfeac3SKonstantin Belousov.Dv NULL, 172*bdcfeac3SKonstantin Belousovthe LDT descriptors are reset to null descriptors. 173*bdcfeac3SKonstantin BelousovIf the 174*bdcfeac3SKonstantin Belousov.Va start 175*bdcfeac3SKonstantin Belousovstarting descriptor index has the special value 176*bdcfeac3SKonstantin Belousov.Dv LDT_AUTO_ALLOC 177*bdcfeac3SKonstantin Belousovand the number of descriptors to allocate is 1, then the system looks for 178*bdcfeac3SKonstantin Belousova free descriptor index and allocates it. 179*bdcfeac3SKonstantin BelousovThe resulting index is returned as the system call return value. 180*bdcfeac3SKonstantin Belousov.Pp 181*bdcfeac3SKonstantin BelousovOnly memory read or read/write normal or expand down, and execute only 182*bdcfeac3SKonstantin Belousovor execute read segment types are allowed. 183*bdcfeac3SKonstantin BelousovAny system segments descriptors or memory conforming execute segments 184*bdcfeac3SKonstantin Belousovare rejected with the 185*bdcfeac3SKonstantin Belousov.Ev EACCESS 186*bdcfeac3SKonstantin Belousoverror. 187*bdcfeac3SKonstantin Belousov.Pp 188*bdcfeac3SKonstantin BelousovX86 hardware supports LDTs with up to 8192 descriptors. 189*bdcfeac3SKonstantin BelousovThis size is excessive for modern applications. 190*bdcfeac3SKonstantin BelousovThe 191*bdcfeac3SKonstantin Belousov.Dv machdep.max_ldt_segment 192*bdcfeac3SKonstantin Belousovloader tunable sets a system-global maximum LDT size 193*bdcfeac3SKonstantin Belousov(in number of descriptors). 194*bdcfeac3SKonstantin Belousov.It Dv I386_GET_IOPERM 195*bdcfeac3SKonstantin BelousovQueries the state of userspace access to the specified range of 196*bdcfeac3SKonstantin BelousovI/O ports for the calling thread. 197*bdcfeac3SKonstantin Belousov.Pp 198*bdcfeac3SKonstantin BelousovThe function takes a 199*bdcfeac3SKonstantin Belousov.Vt struct i386_ioperm_args 200*bdcfeac3SKonstantin Belousovstructure as the 201*bdcfeac3SKonstantin Belousov.Fa args 202*bdcfeac3SKonstantin Belousovargument. 203*bdcfeac3SKonstantin BelousovThe 204*bdcfeac3SKonstantin Belousov.Va start 205*bdcfeac3SKonstantin Belousovmember is the starting port number to query. 206*bdcfeac3SKonstantin BelousovUpon successful return, the 207*bdcfeac3SKonstantin Belousov.Va enable 208*bdcfeac3SKonstantin Belousovmember records the access permissions for the starting port. 209*bdcfeac3SKonstantin BelousovThe 210*bdcfeac3SKonstantin Belousov.Va length 211*bdcfeac3SKonstantin Belousovmember indicates how many ports after the starting port number 212*bdcfeac3SKonstantin Belousovhave the same access permissions. 213*bdcfeac3SKonstantin Belousov.Pp 214*bdcfeac3SKonstantin BelousovFor instance, if 215*bdcfeac3SKonstantin Belousov.Va start 216*bdcfeac3SKonstantin Belousovwas set to 10, 217*bdcfeac3SKonstantin Belousovand the request set the 218*bdcfeac3SKonstantin Belousov.Va length 219*bdcfeac3SKonstantin Belousovfield to 3, with 220*bdcfeac3SKonstantin Belousov.Va enable 221*bdcfeac3SKonstantin Belousovset to 1, then access to ports 10, 11, and 12 is allowed, while 222*bdcfeac3SKonstantin Belousovaccess to port 13 is disallowed. 223*bdcfeac3SKonstantin Belousov.It Dv I386_SET_IOPERM 224*bdcfeac3SKonstantin BelousovGrants or revokes userspace access to I/O ports by modifying the TSS 225*bdcfeac3SKonstantin BelousovI/O permission bitmap for the calling thread. 226*bdcfeac3SKonstantin BelousovEach thread maintains a separate bitmap. 227*bdcfeac3SKonstantin Belousov.Pp 228*bdcfeac3SKonstantin BelousovThe function takes a 229*bdcfeac3SKonstantin Belousov.Vt struct i386_ioperm_args 230*bdcfeac3SKonstantin Belousovstructure as the 231*bdcfeac3SKonstantin Belousov.Fa args 232*bdcfeac3SKonstantin Belousovargument. 233*bdcfeac3SKonstantin BelousovDepending on the 234*bdcfeac3SKonstantin Belousov.Va enable 235*bdcfeac3SKonstantin Belousovmember value, it either grants (enables) or revokes (disables) 236*bdcfeac3SKonstantin Belousovaccess to the range of 237*bdcfeac3SKonstantin BelousovI/O ports specified by the 238*bdcfeac3SKonstantin Belousov.Va start 239*bdcfeac3SKonstantin Belousovand 240*bdcfeac3SKonstantin Belousov.Va length 241*bdcfeac3SKonstantin Belousovmembers. 242*bdcfeac3SKonstantin Belousov.Pp 243*bdcfeac3SKonstantin BelousovThere is total of 65536 ports, so the set of ports specified must fit 244*bdcfeac3SKonstantin Belousovinto the 0..65535 range. 245*bdcfeac3SKonstantin Belousov.Pp 246*bdcfeac3SKonstantin BelousovThe call requires super-user privileges. 247*bdcfeac3SKonstantin Belousov.It Dv I386_VM86 248*bdcfeac3SKonstantin BelousovExecute CPU instructions in virtual 8086 (VM86) mode. 249*bdcfeac3SKonstantin BelousovThis function is only supported by i386 kernels as VM86 mode 250*bdcfeac3SKonstantin Belousovis not supported in long mode. 251*bdcfeac3SKonstantin BelousovTo use this request, the additional header 252*bdcfeac3SKonstantin Belousov.In machine/vm86.h 253*bdcfeac3SKonstantin Belousovmust be included which exists only for i386. 254*bdcfeac3SKonstantin Belousov.Pp 255*bdcfeac3SKonstantin BelousovThe request takes a 256*bdcfeac3SKonstantin Belousov.Vt struct i386_vm86_args 257*bdcfeac3SKonstantin Belousovstructure as the 258*bdcfeac3SKonstantin Belousov.Fa args 259*bdcfeac3SKonstantin Belousovargument. 260*bdcfeac3SKonstantin BelousovIts 261*bdcfeac3SKonstantin Belousov.Va sub_op 262*bdcfeac3SKonstantin Belousovmember specifies one of the following sub-requests: 263*bdcfeac3SKonstantin Belousov.Pp 264*bdcfeac3SKonstantin Belousov.Bl -tag -width VM86_SET_VME 265*bdcfeac3SKonstantin Belousov.It Dv VM86_INIT 266*bdcfeac3SKonstantin BelousovInitialize the VM86 in-kernel extended pcb. 267*bdcfeac3SKonstantin BelousovWithout this initialization, VM86 mode cannot be entered. 268*bdcfeac3SKonstantin Belousov.Pp 269*bdcfeac3SKonstantin BelousovThe sub-request takes the 270*bdcfeac3SKonstantin Belousov.Vt struct vm86_init_args 271*bdcfeac3SKonstantin Belousovadditional argument pointed to by the 272*bdcfeac3SKonstantin Belousov.Fa sub_args 273*bdcfeac3SKonstantin Belousovpointer in the 274*bdcfeac3SKonstantin Belousov.Vt struct i386_vm86_args 275*bdcfeac3SKonstantin Belousovstructure. 276*bdcfeac3SKonstantin Belousov.Pp 277*bdcfeac3SKonstantin BelousovCurrently only the 278*bdcfeac3SKonstantin Belousov.Va int_map 279*bdcfeac3SKonstantin Belousovmember of the structure is implemented. 280*bdcfeac3SKonstantin BelousovEach bit N in the 281*bdcfeac3SKonstantin Belousov.Va int_map 282*bdcfeac3SKonstantin Belousovbit-string set to 1 causes a 283*bdcfeac3SKonstantin Belousov.Dv SIGTRAP 284*bdcfeac3SKonstantin Belousovsignal to be delivered to the thread on the execution 285*bdcfeac3SKonstantin Belousovof the 286*bdcfeac3SKonstantin Belousov.Dv INT N 287*bdcfeac3SKonstantin Belousovinstruction. 288*bdcfeac3SKonstantin BelousovOtherwise, if the bit is zero, the execution of the 289*bdcfeac3SKonstantin Belousov.Dv INT N 290*bdcfeac3SKonstantin Belousovinstruction is reflected to VM86 mode to the interrupt 291*bdcfeac3SKonstantin Belousovhandler as designated by the real-mode interrupt table. 292*bdcfeac3SKonstantin Belousov.It Dv VM86_SET_VME 293*bdcfeac3SKonstantin BelousovReserved but not implemented. 294*bdcfeac3SKonstantin Belousov.It Dv VM86_GET_VME 295*bdcfeac3SKonstantin BelousovReturns the state of the VME extensions. 296*bdcfeac3SKonstantin BelousovThe 297*bdcfeac3SKonstantin Belousov.Va sub_args 298*bdcfeac3SKonstantin Belousovmust point to a 299*bdcfeac3SKonstantin Belousov.Vt struct vm86_vme_args 300*bdcfeac3SKonstantin Belousovstructure. 301*bdcfeac3SKonstantin Belousov.It Dv VM86_INTCALL 302*bdcfeac3SKonstantin BelousovArrange execution in VM86 mode as if the specified interrupt 303*bdcfeac3SKonstantin Belousovwas delivered. 304*bdcfeac3SKonstantin BelousovTakes a 305*bdcfeac3SKonstantin Belousov.Vt struct vm86_intcall_args 306*bdcfeac3SKonstantin Belousovargument as the 307*bdcfeac3SKonstantin Belousov.Va sub_args 308*bdcfeac3SKonstantin Belousovpointer. 309*bdcfeac3SKonstantin BelousovThe 310*bdcfeac3SKonstantin Belousov.Va intnum 311*bdcfeac3SKonstantin Belousovmember of it provides the interrupt number to emulate delivery of, 312*bdcfeac3SKonstantin Belousovand the 313*bdcfeac3SKonstantin Belousov.Va vmf 314*bdcfeac3SKonstantin Belousovgives the VM86 mode machine context to load for the interrupt 315*bdcfeac3SKonstantin Belousovhandler. 316*bdcfeac3SKonstantin Belousov.El 317*bdcfeac3SKonstantin Belousov.Pp 318*bdcfeac3SKonstantin BelousovTo switch thread to the VM86 execution mode, several preparations 319*bdcfeac3SKonstantin Belousovmust be done: 320*bdcfeac3SKonstantin Belousov.Bl -dash 321*bdcfeac3SKonstantin Belousov.It 322*bdcfeac3SKonstantin BelousovAn alternative signal stack must be created, since otherwise signal 323*bdcfeac3SKonstantin Belousovdelivery in VM86 mode would try to use VM86 stack. 324*bdcfeac3SKonstantin BelousovSee 325*bdcfeac3SKonstantin Belousov.Xr sigaltstack 2 . 326*bdcfeac3SKonstantin Belousov.It 327*bdcfeac3SKonstantin BelousovThe VM86 mode kernel state must be initialized with the 328*bdcfeac3SKonstantin Belousov.Dv VM86_INIT 329*bdcfeac3SKonstantin Belousovsub-request. 330*bdcfeac3SKonstantin Belousov.It 331*bdcfeac3SKonstantin BelousovThe memory must be mapped in the first megabyte of the user address 332*bdcfeac3SKonstantin Belousovspace, which will be accessible to the VM86 mode execution. 333*bdcfeac3SKonstantin Belousov.It 334*bdcfeac3SKonstantin BelousovSignal handlers must be established that can handle VM86 exceptions. 335*bdcfeac3SKonstantin BelousovMost importantly, the 336*bdcfeac3SKonstantin Belousov.Dv SIGSEGV 337*bdcfeac3SKonstantin Belousovhandler must be provided to assist VM86 code to handle exits due to 338*bdcfeac3SKonstantin BelousovIOPL-sensitive instructions. 339*bdcfeac3SKonstantin Belousov.It 340*bdcfeac3SKonstantin BelousovFinally, the VM86 mode can be entered by switching to the context 341*bdcfeac3SKonstantin Belousovwith %eflags register having the 342*bdcfeac3SKonstantin Belousov.Dv eflags.VM 343*bdcfeac3SKonstantin Belousovbit set. 344*bdcfeac3SKonstantin BelousovThis can be done, among other ways, by loading the full 345*bdcfeac3SKonstantin Belousovmachine context with the 346*bdcfeac3SKonstantin Belousov.Xr sigreturn 2 347*bdcfeac3SKonstantin Belousovsystem call. 348*bdcfeac3SKonstantin Belousov.El 349*bdcfeac3SKonstantin Belousov.Pp 350*bdcfeac3SKonstantin BelousovThe thread continues to execute in VM86 mode until a signal 351*bdcfeac3SKonstantin Belousovis delivered to it. 352*bdcfeac3SKonstantin BelousovNote that exceptions generate appropriate signals the same as 353*bdcfeac3SKonstantin Belousovfor protected execution mode. 354*bdcfeac3SKonstantin Belousov.Pp 355*bdcfeac3SKonstantin BelousovSee 356*bdcfeac3SKonstantin Belousov.Pa src:tools/tests/vm86 357*bdcfeac3SKonstantin Belousovfor a minimal example for a VM86 monitor and sample code. 358*bdcfeac3SKonstantin Belousov.It Dv I386_GET_FSBASE 359*bdcfeac3SKonstantin BelousovRead the 32-bit fsbase context value for the calling thread into a 360*bdcfeac3SKonstantin Belousov.Vt uint32_t 361*bdcfeac3SKonstantin Belousovvariable pointed to by the 362*bdcfeac3SKonstantin Belousov.Fa args 363*bdcfeac3SKonstantin Belousovargument. 364*bdcfeac3SKonstantin Belousov.It Dv I386_SET_FSBASE 365*bdcfeac3SKonstantin BelousovSet the 32-bit fsbase context value for the calling thread. 366*bdcfeac3SKonstantin BelousovThe 367*bdcfeac3SKonstantin Belousov.Fa args 368*bdcfeac3SKonstantin Belousovargument must point to a 369*bdcfeac3SKonstantin Belousov.Vt int32_t 370*bdcfeac3SKonstantin Belousovvariable that has the new fsbase value stored. 371*bdcfeac3SKonstantin Belousov.Pp 372*bdcfeac3SKonstantin BelousovThe fsbase is maintained by writing the fsbase value into the 373*bdcfeac3SKonstantin Belousovbase field of the user 32-bit %fs GDT descriptor, which has index 2. 374*bdcfeac3SKonstantin Belousov.It Dv I386_GET_GSBASE 375*bdcfeac3SKonstantin BelousovRead the 32-bit gsbase context value for the calling thread into a 376*bdcfeac3SKonstantin Belousov.Vt int32_t 377*bdcfeac3SKonstantin Belousovvariable pointed to by the 378*bdcfeac3SKonstantin Belousov.Fa args 379*bdcfeac3SKonstantin Belousovargument. 380*bdcfeac3SKonstantin Belousov.It Dv I386_SET_GSBASE 381*bdcfeac3SKonstantin BelousovSet the 32-bit gsbase context value for the calling thread. 382*bdcfeac3SKonstantin BelousovThe 383*bdcfeac3SKonstantin Belousov.Fa args 384*bdcfeac3SKonstantin Belousovargument must point to a 385*bdcfeac3SKonstantin Belousov.Vt int32_t 386*bdcfeac3SKonstantin Belousovvariable that has the new gsbase value stored. 387*bdcfeac3SKonstantin Belousov.Pp 388*bdcfeac3SKonstantin BelousovThe gsbase is maintained by writing the gsbase value into the 389*bdcfeac3SKonstantin Belousovbase field of the user 32-bit %gs GDT descriptor, which has index 3. 390*bdcfeac3SKonstantin Belousov.It Dv I386_GET_XFPUSTATE 391*bdcfeac3SKonstantin BelousovSame as 392*bdcfeac3SKonstantin Belousov.Dv AMD64_GET_XFPUSTATE , 393*bdcfeac3SKonstantin Belousovbut takes the address of the 394*bdcfeac3SKonstantin Belousov.Vt struct i386_get_xfpustate 395*bdcfeac3SKonstantin Belousovstructure as the 396*bdcfeac3SKonstantin Belousov.Fa args 397*bdcfeac3SKonstantin Belousovargument. 398*bdcfeac3SKonstantin Belousov.It Dv I386_SET_PKRU 399*bdcfeac3SKonstantin BelousovProvided only when running i386 binaries on the amd64 host kernel. 400*bdcfeac3SKonstantin Belousov.Pp 401*bdcfeac3SKonstantin BelousovSee description of the 402*bdcfeac3SKonstantin Belousov.Dv AMD64_SET_PKRU 403*bdcfeac3SKonstantin Belousovrequest. 404*bdcfeac3SKonstantin Belousov.It Dv I386_CLEAR_PKRU 405*bdcfeac3SKonstantin BelousovProvided only when running i386 binaries on the amd64 host kernel. 406*bdcfeac3SKonstantin Belousov.Pp 407*bdcfeac3SKonstantin BelousovSee description of the 408*bdcfeac3SKonstantin Belousov.Dv AMD64_CLEAR_PKRU 409*bdcfeac3SKonstantin Belousovrequest. 410*bdcfeac3SKonstantin Belousov.It Dv I386_SET_SPLITLOCK 411*bdcfeac3SKonstantin BelousovChange the requesting thread splitlock detection control. 412*bdcfeac3SKonstantin BelousovFor i386 binaries, the function is only available when running 413*bdcfeac3SKonstantin Belousovon the amd64 host kernel. 414*bdcfeac3SKonstantin Belousov.Pp 415*bdcfeac3SKonstantin BelousovThe argument must point to the 32bit 416*bdcfeac3SKonstantin Belousov.Vt int 417*bdcfeac3SKonstantin Belousovvariable, holding one of the following values: 418*bdcfeac3SKonstantin Belousov.Bl -tag 419*bdcfeac3SKonstantin Belousov.It Dv 0 420*bdcfeac3SKonstantin BelousovDisable detection of split locking. 421*bdcfeac3SKonstantin Belousov.It Dv 1 422*bdcfeac3SKonstantin BelousovEnable detection of split locking. 423*bdcfeac3SKonstantin Belousov.El 424*bdcfeac3SKonstantin Belousov.Pp 425*bdcfeac3SKonstantin BelousovThe split lock is the situation where the read-modify-write atomic 426*bdcfeac3SKonstantin Belousovinstruction is performed on the memory location that is split over 427*bdcfeac3SKonstantin Belousovmore than one CPU cache line. 428*bdcfeac3SKonstantin BelousovSome CPUs can be configured to generate the Alignment Fault exception 429*bdcfeac3SKonstantin Belousov.Ql #AC 430*bdcfeac3SKonstantin Belousovif split locking is detected. 431*bdcfeac3SKonstantin BelousovThe request makes it possible for the thread to control the detector. 432*bdcfeac3SKonstantin Belousov.Pp 433*bdcfeac3SKonstantin BelousovThe 434*bdcfeac3SKonstantin Belousov.Xr _umtx_op 2 435*bdcfeac3SKonstantin Belousovoperations that pass unaligned locks to kernel requests returns 436*bdcfeac3SKonstantin Belousov.Ev EFAULT 437*bdcfeac3SKonstantin Belousovwhen splitlock detection is enabled. 438*bdcfeac3SKonstantin Belousov.Pp 439*bdcfeac3SKonstantin BelousovPresence of the detector can be queried with the 440*bdcfeac3SKonstantin Belousov.Dv hw.splitlock 441*bdcfeac3SKonstantin Belousov.Xr sysctl 2 442*bdcfeac3SKonstantin BelousovMIB. 443*bdcfeac3SKonstantin Belousov.It Dv I386_GET_SPLITLOCK 444*bdcfeac3SKonstantin BelousovReturns the state of the splitlock detection control. 445*bdcfeac3SKonstantin BelousovFor i386 binaries, the function is only available when running 446*bdcfeac3SKonstantin Belousovon the amd64 host kernel. 447*bdcfeac3SKonstantin Belousov.Pp 448*bdcfeac3SKonstantin BelousovThe argument must point to the 32bit 449*bdcfeac3SKonstantin Belousov.Vt int 450*bdcfeac3SKonstantin Belousovvariable. 451*bdcfeac3SKonstantin BelousovThe function writes the value 0 if the control is disabled 452*bdcfeac3SKonstantin Belousovand 1 if enabled. 453*bdcfeac3SKonstantin Belousov.Pp 454*bdcfeac3SKonstantin Belousov.It Dv AMD64_GET_FSBASE 455*bdcfeac3SKonstantin BelousovReturns the value of the 456*bdcfeac3SKonstantin Belousov.Dv fsbase 457*bdcfeac3SKonstantin Belousovregister for the calling thread. 458*bdcfeac3SKonstantin BelousovThe 459*bdcfeac3SKonstantin Belousov.Fa args 460*bdcfeac3SKonstantin Belousovargument must point to the 64bit 461*bdcfeac3SKonstantin Belousov.Vt unsigned long variable 462*bdcfeac3SKonstantin Belousovwhere the value is written. 463*bdcfeac3SKonstantin Belousov.Pp 464*bdcfeac3SKonstantin BelousovOn CPUs that do not support the 465*bdcfeac3SKonstantin Belousov.Dv RDFSBASE 466*bdcfeac3SKonstantin Belousovinstruction, the call is the only 467*bdcfeac3SKonstantin Belousovway to read the current value of fsbase. 468*bdcfeac3SKonstantin Belousov.It Dv AMD64_SET_FSBASE 469*bdcfeac3SKonstantin BelousovSets the 470*bdcfeac3SKonstantin Belousov.Dv fsbase 471*bdcfeac3SKonstantin Belousovregister to the 64bit value pointed to by the 472*bdcfeac3SKonstantin Belousov.Fa args 473*bdcfeac3SKonstantin Belousovargument. 474*bdcfeac3SKonstantin Belousov.Pp 475*bdcfeac3SKonstantin BelousovThe value is checked to not point outside of the allowed user address 476*bdcfeac3SKonstantin Belousovspace, which is subset of possible canonical addresses. 477*bdcfeac3SKonstantin BelousovIf the 478*bdcfeac3SKonstantin Belousov.Dv WRFSBASE 479*bdcfeac3SKonstantin Belousovinstruction is supported, the fsbase register can 480*bdcfeac3SKonstantin Belousovbe updated either by the call or by the instruction. 481*bdcfeac3SKonstantin BelousovFor 64bit processes, the fsbase register is always restored on return 482*bdcfeac3SKonstantin Belousovto user mode from kernel calls or interrupts, regardless of the value 483*bdcfeac3SKonstantin Belousovof the %fs segment register. 484*bdcfeac3SKonstantin Belousov.It Dv AMD64_GET_GSBASE 485*bdcfeac3SKonstantin BelousovGet the 486*bdcfeac3SKonstantin Belousov.Dv gsbase 487*bdcfeac3SKonstantin Belousovregister, see description of 488*bdcfeac3SKonstantin Belousov.Dv AMD64_GET_FSBASE . 489*bdcfeac3SKonstantin Belousov.It Dv AMD64_SET_GSBASE 490*bdcfeac3SKonstantin BelousovSet the 491*bdcfeac3SKonstantin Belousov.Dv gsbase 492*bdcfeac3SKonstantin Belousovregister, see description of 493*bdcfeac3SKonstantin Belousov.Dv AMD64_GET_GSBASE . 494*bdcfeac3SKonstantin Belousov.It Dv AMD64_GET_XFPUSTATE 495*bdcfeac3SKonstantin BelousovFills the extended FPU state as defined by the architecture and the 496*bdcfeac3SKonstantin Belousovrunning CPU hardware into the memory described by the 497*bdcfeac3SKonstantin Belousov.Vt struct amd64_get_xfpustate 498*bdcfeac3SKonstantin Belousovstructure. 499*bdcfeac3SKonstantin BelousovThe 500*bdcfeac3SKonstantin Belousov.Fa args 501*bdcfeac3SKonstantin Belousovargument must point to the structure, the extended state (that is, full 502*bdcfeac3SKonstantin BelousovXSAVE area excluding the legacy region) is written to the 503*bdcfeac3SKonstantin Belousov.Va addr 504*bdcfeac3SKonstantin Belousovup to the 505*bdcfeac3SKonstantin Belousov.Va len 506*bdcfeac3SKonstantin Belousovbytes. 507*bdcfeac3SKonstantin BelousovIf the 508*bdcfeac3SKonstantin Belousov.Va len 509*bdcfeac3SKonstantin Belousovmember value is smaller then the XSAVE area size, the result is truncated. 510*bdcfeac3SKonstantin Belousov.It Dv AMD64_SET_PKRU 511*bdcfeac3SKonstantin BelousovSet the 4bit protection key for the page table entries used to map 512*bdcfeac3SKonstantin Belousovthe given userspace virtual address range. 513*bdcfeac3SKonstantin Belousov.Pp 514*bdcfeac3SKonstantin BelousovThe request takes the 515*bdcfeac3SKonstantin Belousov.Vt struct amd64_set_pkru 516*bdcfeac3SKonstantin Belousovstructure pointed to by the 517*bdcfeac3SKonstantin Belousov.Fa args 518*bdcfeac3SKonstantin Belousovparameter. 519*bdcfeac3SKonstantin BelousovThe 520*bdcfeac3SKonstantin Belousov.Va addr 521*bdcfeac3SKonstantin Belousovand 522*bdcfeac3SKonstantin Belousov.Va len 523*bdcfeac3SKonstantin Belousovmembers of the structure specify starting address and the length in bytes 524*bdcfeac3SKonstantin Belousovof the region. 525*bdcfeac3SKonstantin BelousovThe 526*bdcfeac3SKonstantin Belousov.Va keyidx 527*bdcfeac3SKonstantin Belousovmember value must be between 0 and 15 and provides the protection key 528*bdcfeac3SKonstantin Belousovindex applied to the region. 529*bdcfeac3SKonstantin BelousovThe 530*bdcfeac3SKonstantin Belousov.Va flags 531*bdcfeac3SKonstantin Belousovmember is or-ed with the following flags: 532*bdcfeac3SKonstantin Belousov.Bl -tag -width AMD64_PKRU_PERSIST 533*bdcfeac3SKonstantin Belousov.It Dv AMD64_PKRU_EXCL 534*bdcfeac3SKonstantin BelousovRequires that no protection key was assigned to the specified range, 535*bdcfeac3SKonstantin Belousovor previously assigned key cleared. 536*bdcfeac3SKonstantin BelousovIf some key was already applied to any part of the range, the call 537*bdcfeac3SKonstantin Belousovfails with the 538*bdcfeac3SKonstantin Belousov.Ev EBUSY 539*bdcfeac3SKonstantin Belousoverror. 540*bdcfeac3SKonstantin Belousov.It Dv AMD64_PKRU_PERSIST 541*bdcfeac3SKonstantin BelousovMakes the assigned key persistent. 542*bdcfeac3SKonstantin BelousovIt is automatically re-applied to any new mapping created in the range. 543*bdcfeac3SKonstantin Belousov.El 544*bdcfeac3SKonstantin Belousov.Pp 545*bdcfeac3SKonstantin BelousovProtection keys feature is optional and depends on CPU implementing it. 546*bdcfeac3SKonstantin BelousovUse the 547*bdcfeac3SKonstantin Belousov.Dv CPUID 548*bdcfeac3SKonstantin Belousovinstruction to check its availability. 549*bdcfeac3SKonstantin Belousov.Pp 550*bdcfeac3SKonstantin BelousovThe request is used to implement the 551*bdcfeac3SKonstantin Belousov.Xr x86_pkru_protect_range 3 552*bdcfeac3SKonstantin Belousovfunction. 553*bdcfeac3SKonstantin Belousov.It Dv AMD64_CLEAR_PKRU 554*bdcfeac3SKonstantin BelousovClear any protection keys assigned to the specified region. 555*bdcfeac3SKonstantin Belousov.Pp 556*bdcfeac3SKonstantin BelousovThe request takes the 557*bdcfeac3SKonstantin Belousov.Vt struct amd64_set_pkru 558*bdcfeac3SKonstantin Belousovstructure pointed to by the 559*bdcfeac3SKonstantin Belousov.Fa args 560*bdcfeac3SKonstantin Belousovparameter. 561*bdcfeac3SKonstantin BelousovThe 562*bdcfeac3SKonstantin Belousov.Va addr 563*bdcfeac3SKonstantin Belousovand 564*bdcfeac3SKonstantin Belousov.Va len 565*bdcfeac3SKonstantin Belousovmembers of the structure specify starting address and the length in bytes 566*bdcfeac3SKonstantin Belousovof the region. 567*bdcfeac3SKonstantin BelousovOther structure members are ignored. 568*bdcfeac3SKonstantin Belousov.Pp 569*bdcfeac3SKonstantin BelousovThe request is used to implement the 570*bdcfeac3SKonstantin Belousov.Xr x86_pkru_unprotect_range 3 571*bdcfeac3SKonstantin Belousovfunction. 572*bdcfeac3SKonstantin Belousov.It Dv AMD64_GET_TLSBASE 573*bdcfeac3SKonstantin BelousovAMD64 only. 574*bdcfeac3SKonstantin Belousov.Pp 575*bdcfeac3SKonstantin BelousovReturns the current TLSBASE value for the calling thread. 576*bdcfeac3SKonstantin BelousovThe 577*bdcfeac3SKonstantin Belousov.Fa args 578*bdcfeac3SKonstantin Belousovargument must point to the 64bit 579*bdcfeac3SKonstantin Belousov.Vt unsigned long 580*bdcfeac3SKonstantin Belousovvariable where the value is written to. 581*bdcfeac3SKonstantin Belousov.It Dv AMD64_SET_TLSBASE 582*bdcfeac3SKonstantin BelousovSets the TLSBASE and the fsbase register values for the calling thread. 583*bdcfeac3SKonstantin BelousovThe 584*bdcfeac3SKonstantin Belousov.Fa args 585*bdcfeac3SKonstantin Belousovargument must point to the 64bit 586*bdcfeac3SKonstantin Belousov.Vt unsigned long 587*bdcfeac3SKonstantin Belousovvariable where the value is taken from. 588*bdcfeac3SKonstantin Belousov.Pp 589*bdcfeac3SKonstantin BelousovThe TLSBASE value is written into the 590*bdcfeac3SKonstantin Belousov.Dv fsbase 591*bdcfeac3SKonstantin Belousovregister before a signal handler is invoked. 592*bdcfeac3SKonstantin BelousovThe current fsbase value is saved, and then restored 593*bdcfeac3SKonstantin Belousovupon return from the signal handler. 594*bdcfeac3SKonstantin BelousovUse of TLSBASE makes it possible for programs that modify 595*bdcfeac3SKonstantin Belousovthe fsbase register using the 596*bdcfeac3SKonstantin Belousov.Dv WRFSBASE 597*bdcfeac3SKonstantin Belousovinstruction to reliably access 598*bdcfeac3SKonstantin Belousovthread-local variables in signal handlers. 599*bdcfeac3SKonstantin Belousov.Pp 600*bdcfeac3SKonstantin BelousovTLSBASE is set up by the 601*bdcfeac3SKonstantin Belousov.Fx 602*bdcfeac3SKonstantin BelousovC runtime environment on thread startup. 603*bdcfeac3SKonstantin Belousov.It Dv AMD64_DISABLE_TLSBASE 604*bdcfeac3SKonstantin BelousovDisables loading the fsbase register from TLSBASE value on 605*bdcfeac3SKonstantin Belousova signal handler invocation. 606*bdcfeac3SKonstantin BelousovThe argument 607*bdcfeac3SKonstantin Belousov.Fa args 608*bdcfeac3SKonstantin Belousovis ignored. 609*bdcfeac3SKonstantin Belousov.Pp 610*bdcfeac3SKonstantin BelousovThe call allows to undo the effect of the 611*bdcfeac3SKonstantin Belousov.Dv AMD64_SET_TLSBASE , 612*bdcfeac3SKonstantin Belousovmaking signal handlers retain the value of fsbase from the 613*bdcfeac3SKonstantin Belousovinterrupted context. 614*bdcfeac3SKonstantin BelousovBy default, tlsbase is disabled after the 615*bdcfeac3SKonstantin Belousov.Xr execve 2 616*bdcfeac3SKonstantin Belousovsyscall activated a new image. 617*bdcfeac3SKonstantin Belousov.El 618*bdcfeac3SKonstantin Belousov.Sh RETURN VALUES 619*bdcfeac3SKonstantin BelousovFor all requests except 620*bdcfeac3SKonstantin Belousov.Dv I386_GET_LDT 621*bdcfeac3SKonstantin Belousovand 622*bdcfeac3SKonstantin Belousov.Dv I386_SET_LDT , 623*bdcfeac3SKonstantin Belousovupon successful completion, the value 0 is returned; otherwise the 624*bdcfeac3SKonstantin Belousovvalue -1 is returned and the global variable 625*bdcfeac3SKonstantin Belousov.Va errno 626*bdcfeac3SKonstantin Belousovis set to indicate the error. 627*bdcfeac3SKonstantin Belousov.Pp 628*bdcfeac3SKonstantin BelousovThe 629*bdcfeac3SKonstantin Belousov.Dv I386_SET_LDT 630*bdcfeac3SKonstantin Belousovrequest returns the starting index of the descriptors range it operated 631*bdcfeac3SKonstantin Belousovon, on success. 632*bdcfeac3SKonstantin BelousovIn particular, the index of the automatically allocated descriptor is 633*bdcfeac3SKonstantin Belousovreported this way. 634*bdcfeac3SKonstantin BelousovOtherwise, -1 is returned and 635*bdcfeac3SKonstantin Belousov.Va errno 636*bdcfeac3SKonstantin Belousovis set. 637*bdcfeac3SKonstantin Belousov.Pp 638*bdcfeac3SKonstantin BelousovThe 639*bdcfeac3SKonstantin Belousov.Dv I386_GET_LDT 640*bdcfeac3SKonstantin Belousovrequest returns 0 if the specified descriptors range is completely 641*bdcfeac3SKonstantin Belousovoutside the allocated LDT. 642*bdcfeac3SKonstantin BelousovOn any other error, -1 is returned and 643*bdcfeac3SKonstantin Belousov.Va errno 644*bdcfeac3SKonstantin Belousovis set. 645*bdcfeac3SKonstantin BelousovOtherwise the number of reported descriptors is returned as the syscall 646*bdcfeac3SKonstantin Belousovreturn value. 647*bdcfeac3SKonstantin Belousov.Sh SEE ALSO 648*bdcfeac3SKonstantin Belousov.Xr i386_get_ioperm 2 , 649*bdcfeac3SKonstantin Belousov.Xr i386_get_ldt 2 , 650*bdcfeac3SKonstantin Belousov.Xr i386_vm86 2 , 651*bdcfeac3SKonstantin Belousov.Xr sysarch 2 , 652*bdcfeac3SKonstantin Belousov.Xr pkru 3 , 653*bdcfeac3SKonstantin Belousov.Xr arch 7 654*bdcfeac3SKonstantin Belousov.Sh HISTORY 655*bdcfeac3SKonstantin BelousovThe manual page appeared in 656*bdcfeac3SKonstantin Belousov.Fx 16.0 . 657*bdcfeac3SKonstantin Belousov.Sh AUTHORS 658*bdcfeac3SKonstantin BelousovThe manual page was written by 659*bdcfeac3SKonstantin Belousov.An Konstantin Belousov Aq Mt kib@FreeBSD.org . 660