Page MenuHomeFreeBSD

D60047.id187761.diff
No OneTemporary

D60047.id187761.diff

diff --git a/lib/libsys/Makefile.sys b/lib/libsys/Makefile.sys
--- a/lib/libsys/Makefile.sys
+++ b/lib/libsys/Makefile.sys
@@ -361,6 +361,7 @@
symlink.2 \
sync.2 \
sysarch.2 \
+ sysarch.x86.2 \
syscall.2 \
thr_exit.2 \
thr_kill.2 \
diff --git a/lib/libsys/sysarch.2 b/lib/libsys/sysarch.2
--- a/lib/libsys/sysarch.2
+++ b/lib/libsys/sysarch.2
@@ -72,7 +72,8 @@
.Sh SEE ALSO
.Xr i386_get_ioperm 2 ,
.Xr i386_get_ldt 2 ,
-.Xr i386_vm86 2
+.Xr i386_vm86 2 ,
+.Xr sysarch.x86.2
.Sh HISTORY
This manual page was taken from
.Nx .
diff --git a/lib/libsys/sysarch.x86.2 b/lib/libsys/sysarch.x86.2
new file mode 100644
--- /dev/null
+++ b/lib/libsys/sysarch.x86.2
@@ -0,0 +1,655 @@
+.\" SPDX-License-Identifier: BSD-2-Clause
+.\"
+.\" Copyright 2026 The FreeBSD Foundation.
+.\"
+.\" This documentation was written by Konstantin Belousov <kib@FreeBSD.org>
+.\" under sponsorship of The FreeBSD Foundation.
+.\"
+.Dd September 26, 2026
+.Dt SYSARCH.X86 2 i386
+.Os
+.Sh NAME
+.Nm sysarch.x86
+.Nd architecture-dependent system call on x86
+.Sh LIBRARY
+.Lb libc
+.Sh SYNOPSIS
+.In machine/sysarch.h
+.Ft int
+.Fn sysarch "int number" "void *args"
+.Sh DESCRIPTION
+The
+manual page descibes the functions provided by the
+.Fn sysarch
+system call on x86 architectures, that is i386 and amd64, see
+.Xr arch 7 .
+.Ss Parameter Types
+The following structures are used as the arguments pointed t by the
+.Fa args
+parameter.
+Refer to the description of the requests for the specification of the
+fields meaning:
+.Pp
+The
+.Dv I386_GET_IOPERM
+and
+.Dv I386_SET_IOPERM
+requests take the
+.Vt struct i386_ioperm_args ,
+which is defined as following:
+.Bd -literal
+struct i386_ioperm_args {
+ unsigned int start;
+ unsigned int length;
+ int enable;
+};
+.Ed
+.Pp
+The
+.Dv I386_GET_LDT
+and
+.Dv I386_SET_LDT
+requests take
+.Vt struct i386_ldt_args ,
+which definition differs between i386 and amd64.
+The i386 variant is
+.Bd -literal
+struct i386_ldt_args {
+ unsigned int start;
+ union descriptor *descs;
+ unsigned int num;
+};
+.Ed
+the amd64 variant is:
+.Bd -literal
+struct i386_ldt_args {
+ unsigned int start;
+ struct user_segment_descriptor *descs __packed;
+ unsigned int num;
+};
+.Ed
+.Pp
+i386-only request
+.Dv I386_VM86
+takes
+.Bd -literal
+struct i386_vm86_args {
+ int sub_op;
+ char *sub_args;
+};
+.Ed
+.Pp
+The
+.Dv I386_GET_XFPUSTATE ,
+takes the
+.Vt struct i386_get_xfpustate
+argument, and
+.Dv AMD64_GET_XFPUSTATE
+.Vt struct amd64_get_xfpustate
+argument.
+The structures have the same members, but their layout differs due to the
+pointer size differences.
+Only amd64 variant is listed for clarity.
+.Bd -literal
+struct amd64_get_xfpustate {
+ void *addr;
+ int len;
+};
+.Ed
+.Pp
+The
+.Dv I386_GET_PKRU ,
+.Dv I386_SET_PKRU ,
+take the
+.Vt struct i386_set_pkru
+argument, and
+.Dv AMD64_GET_PKRU
+and
+.Dv AMD64_SET_PKRU
+take the
+.Vt struct amd64_set_pkru
+argument.
+The structures have the same members, but their layout differs due to the
+pointer size differences.
+Only amd64 variant is listed for clarity.
+.Bd -literal
+struct amd64_set_pkru {
+ void *addr;
+ unsigned long len;
+ unsigned int keyidx;
+ int flags;
+};
+.Ed
+.Ss Requests
+The following requests can be specified by the
+.Fa number
+argument:
+.Bl -tag -width AMD64_DISABLE_TLSBASE
+.It Dv I386_GET_LDT
+Queries the specified range of the LDT descriptors for the
+calling process.
+.Pp
+The request takes the pointer to the
+.Vt struct i386_ldt_args
+structure as the
+.Fa args
+parameter.
+Its
+.Va start
+member specifies the starting index, and
+.Va num
+the number of descriptors which are queried.
+The LDT descriptor's content in the requested range is copied into
+the memory specified by the
+.Fa descs
+member.
+.It Dv I386_SET_LDT
+Set the specified range of the LDT descriptors for the calling process.
+.Pp
+LDT is process-global, all process threads share the table.
+On the other hand, if several processes share the address space,
+they still each have its own LDT.
+.Pp
+The request takes the pointer to the
+.Vt struct i386_ldt_args
+structure as the
+.Fa args
+parameter.
+Its
+.Va start
+member specifies the starting index, and
+.Va num
+the number of descriptors which are queried.
+The LDT descriptor's content in the requested range is copied into
+the memory specified by the
+.Fa descs
+member.
+.Pp
+If the
+.Va descs
+member value is
+.Dv NULL,
+the content of the specified descriptors is cleared (zeroed).
+If the
+.Va start
+starting descriptor index has the special value
+.Dv LDT_AUTO_ALLOC
+and the number of descriptors to allocate is 1, then system looks for
+some free descriptor index and allocates it.
+The resulting index is returned as the system call return value.
+.Pp
+Only memory read or read/write normal or expand down, and execute only
+or execute read segment types are allowed.
+Any system segments descriptors, or memory conforming execute segments
+are rejected with the
+.Ev EACCESS
+error.
+.Pp
+X86 hardware supports LDT sized up to 8192 descriptors.
+This size is regarded as excessive for needs of modern applications.
+The
+.Dv machdep.max_ldt_segment
+loader tunable establishes the system-global maximum size of LDT
+(in number of descriptors).
+.It Dv I386_GET_IOPERM
+Queries the state of the userspace access to the specified range
+of i/o ports for the calling thread.
+.Pp
+The function takes the pointer
+.Vt struct i386_ioperm_args
+structure as the
+.Fa args
+argument.
+The
+.Va start
+is the starting port number for which the state is queried.
+Upon successful return, the argument structure'
+.Va enable
+member records the state of the access to the starting port.
+The
+.Va length
+member indicates how many ports after the starting port number
+have the same access permissions.
+.Pp
+For instance, if the
+.Va start
+was set to 10,
+and the request set the
+.Va length
+field to 3, with
+.Va enable
+set to 1, then access to the ports 10, 11, 12 is enabled, while
+access to the port 13 is disallowed.
+.It Dv I386_SET_IOPERM
+Grants or revoke access from userspace to IO ports using the
+TSS io permission bitmap for the calling thread.
+The bitmap has the thread scope.
+.Pp
+The function takes the pointer
+.Vt struct i386_ioperm_args
+structure as the
+.Fa args
+argument.
+Depending on the
+.Va enable
+member value, it either grant (enable) or revoke (disable) access to the
+range of i/o ports specified by the
+.Va start
+and
+.Va length
+members.
+.Pp
+There is total of 65536 ports, the set of ports specified must fit into the
+0..65535 range.
+.Pp
+The call requires super-user privileges.
+.It Dv I386_VM86
+Manage the VM86 mode of execution.
+i386 only, the function is not exposed by hardware in the long mode.
+To use the request, additional header
+.In machine/vm86.h
+must be included, existing only on i386.
+.Pp
+.Pp
+The request takes the pointer to the
+.Vt struct i386_vm86_args
+structure as the
+.Fa args
+argument.
+Its
+.Va sub_op
+member specifies one of the following sub-requests:
+.Pp
+.Bl -tag -width VM86_SET_VME
+.It Dv VM86_INIT
+Initialize the vm86 in-kernel extended pcb.
+Without the initialization, the vm86 mode cannot be entered.
+.Pp
+The sub-request takes the
+.Vt struct vm86_init_args
+additional argument pointed to by the
+.Fa sub_args
+pointer in the
+.Vt struct i386_vm86_args
+structure.
+.Pp
+Currently only the
+.Va int_map
+member of the structure is implemented.
+Each bit N in the
+.Va int_map
+bit-string set to 1 causes the
+.Dv SIGTRAP
+signal to be delivered to the thread on the execution
+of the
+.Dv INT N
+instruction.
+Otherwise, if the bit is zero, the execution of the
+.Dv INT N
+instruction is reflected to the vm86 mode to the interrupt
+handler as designated by the real-mode interrupt table.
+.It Dv VM86_SET_VME
+Reserved but not implemented.
+.It Dv VM86_GET_VME
+Returns the state of the VME extensions, implemented started with
+the Pentium microarchitecture.
+The
+.Va sub_args
+must point to
+.Vt struct vm86_vme_args
+structure.
+.It Dv VM86_INTCALL
+Arrange execution in vm86 mode as if the specified interrupt
+was delivered.
+Takes the
+.Vt struct vm86_intcall_args
+argument as the
+.Va sub_args
+pointer.
+The
+.Va intnum
+member of it provides the interrupt number to emulate delivery of,
+and the
+.Va vmf
+gives the vm86 mode machine context to load for the interrupt
+handler.
+.El
+.Pp
+To switch thread to the vm86 execution mode, several preparations
+must be done:
+.Bl -dash
+.It
+The alt signal stack must be created, since otherwise signal
+delivery in vm86 mode would try to use vm86 stack.
+See
+.Xr sigaltstack 2 .
+.It
+The vm86 mode kernel state must be initialized with the
+.Dv VM86_INIT
+sub-request.
+.It
+The memory must be mapped in the first megabyte of the user address
+space, which will be accessible to the vm86 mode execution.
+.It
+Signal handlers must be established that can handle vm86 exceptions.
+Most importantly, the
+.Dv SIGSEGV
+handler must be provided to assist vm86 code to handle exits due to
+IOPL-sensitive instructions.
+.It
+Finally, the vm86 mode can be entered by switching to the context
+with %eflags register having the
+.Dv eflags.VM
+bit set.
+This can be done, among other ways, by loading the full
+machine context with the
+.Xr sigreturn 2
+system call.
+.El
+.Pp
+The thread continues to execute in vm86 mode until a signal
+is delivered to it.
+Note that exceptions generate appropriate signal same as
+for the protected execution mode.
+.Pp
+See
+.Pa src:tools/tests/vm86
+for a minimal example of the vm86 monitor and sample code.
+.It Dv I386_GET_FSBASE
+Read the 32bit fsbase context value for the calling thread into the
+32bit
+.Vt int
+variable pointed to by the
+.Fa args
+argument.
+.It Dv I386_SET_FSBASE
+Set the 32bit fsbase context value for the calling thread.
+The
+.Fa args
+argument must point to 32bit
+.Vt int
+variable that has the new fsbase value stored.
+.Pp
+The fsbase is maintained by writing the fsbase value into the
+base field of the user 32bit %fs GDT descriptor, which has index 2.
+.It Dv I386_GET_GSBASE
+Read the 32bit gsbase context value for the calling thread into the
+32bit
+.Vt int
+variable pointed to by the
+.Fa args
+argument.
+.It Dv I386_SET_GSBASE
+Set the 32bit gsbase context value for the calling thread.
+The
+.Fa args
+argument must point to 32bit
+.Vt int
+variable that has the new gsbase value stored.
+.Pp
+The gsbase is maintained by writing the gsbase value into the
+base field of the user 32bit %gs GDT descriptor, which has index 3.
+.It Dv I386_GET_XFPUSTATE
+Same as
+.Dv AMD64_GET_XFPUSTATE ,
+but takes the address of the
+.Vt struct i386_get_xfpustate
+structure as the
+.Fa args
+argument.
+.It Dv I386_SET_PKRU
+Provided only when running i386 binaries on the amd64 host kernel.
+.Pp
+See description of the
+.Dv AMD64_SET_PKRU
+request.
+.It Dv I386_CLEAR_PKRU
+Provided only when running i386 binaries on the amd64 host kernel.
+.Pp
+See description of the
+.Dv AMD64_CLEAR_PKRU
+request.
+.It Dv I386_SET_SPLITLOCK
+Change the requesting thread splitlock detection control.
+For i386 binaries, the function is only available when running
+on the amd64 host kernel.
+.Pp
+The argument must point to the 32bit
+.Vt int
+variable, holding one of the following values:
+.Bl -tag
+.It Dv 0
+Disable detection of split locking.
+.It Dv 1
+Enable detection of split locking.
+.El
+.Pp
+The split lock is the situation where the read-modify-write atomic
+instruction is performed on the memory location that is split over
+more than one CPU cache line.
+Some CPUs can be configured to generate the Alignment Fault exception
+.Ql #AC
+if split locking is detected.
+The request makes it possible for the thread to control the detector.
+.Pp
+The
+.Xr _umtx_op 2
+operations that pass unaligned locks to kernel requests returns
+.Ev EFAULT
+when splitlock detection is enabled.
+.Pp
+Presence of the detector can be queried with the
+.Dv hw.splitlock
+.Xr sysctl 2
+MIB.
+.It Dv I386_GET_SPLITLOCK
+Returns the state of the splitlock detection control.
+For i386 binaries, the function is only available when running
+on the amd64 host kernel.
+.Pp
+The argument must point to the 32bit
+.Vt int
+variable.
+The function writes the value 0 if the control is disabled
+and 1 if enabled.
+.Pp
+.It Dv AMD64_GET_FSBASE
+Returns the value of the
+.Dv fsbase
+register for the calling thread.
+The
+.Fa args
+argument must point to the 64bit
+.Vt unsigned long variable
+where the value is written.
+.Pp
+On CPUs that do not support the RDFSBASE instruction, the call is the only
+way to read the current value of fsbase.
+.It Dv AMD64_SET_FSBASE
+Sets the
+.Dv fsbase
+register to the 64bit value pointed to by the
+.Fa args
+argument.
+.Pp
+The value is checked to not point outside of the allowed user address
+space, which is subset of possible canonical addresses.
+If the WRFSBASE instruction is supported, the fsbase register can
+be updated either by the call or by the instruction.
+For 64bit processes, the fsbase register is always restored on return
+to user mode from kernel calls or interrupts, regardless of the value
+of the %fs segment register.
+.It Dv AMD64_GET_GSBASE
+Get the
+.Dv gsbase
+register, see description of
+.Dv AMD64_GET_FSBASE .
+.It Dv AMD64_SET_GSBASE
+Set the
+.Dv gsbase
+register, see description of
+.Dv AMD64_GET_GSBASE .
+.It Dv AMD64_GET_XFPUSTATE
+Fills the extended FPU state as defined by the architecture and the
+running CPU hardware into the memory described by the
+.Vt struct amd64_get_xfpustate
+structure.
+The
+.Fa args
+argument must point to the structure, the extended state (that is, full
+XSAVE area exclusing the legacy region) is written to the
+.Va addr
+up to the
+.Va len
+bytes.
+If the
+.Va len
+member value is smaller then the XSAVE area size, the result is truncated.
+.It Dv AMD64_SET_PKRU
+Set the 4bit protection key for the page table entries used to map
+the given userspace virtual address range.
+.Pp
+The request takes the
+.Vt struct amd64_set_pkru
+structure pointed to by the
+.Fa args
+parameter.
+The
+.Va addr
+and
+.Va len
+members of the structure specify starting address and the length in bytes
+of the region.
+The
+.Va keyidx
+member value must be between 0 and 15 and provides the protection key
+index applied to the region.
+The
+.Va flags
+member is or-ed with the following flags:
+.Bl -tag -width AMD64_PKRU_PERSIST
+.It Dv AMD64_PKRU_EXCL
+Requires that no protection key was assigned to the specified range,
+or previously assigned key cleared.
+If some key was already applied to any part of the range, the call
+fails with the
+.Ev EBUSY
+error.
+.It Dv AMD64_PKRU_PERSIST
+Makes the assigned key persistent.
+It is automatically re-applied to any new mapping created in the range.
+.El
+.Pp
+Protection keys feature is optional and depends on CPU implementing it.
+Use the
+.Dv CPUID
+instruction to check its availability.
+.Pp
+The request is used to implement the
+.Xr x86_pkru_protect_range 3
+function.
+.It Dv AMD64_CLEAR_PKRU
+Clear any protection keys assigned to the specified region.
+.Pp
+The request takes the
+.Vt struct amd64_set_pkru
+structure pointed to by the
+.Fa args
+parameter.
+The
+.Va addr
+and
+.Va len
+members of the structure specify starting address and the length in bytes
+of the region.
+Other structure members are ignored.
+.Pp
+The request is used to implement the
+.Xr x86_pkru_unprotect_range 3
+function.
+.It Dv AMD64_GET_TLSBASE
+AMD64 only.
+.Pp
+Returns the current TLSBASE value for the calling thread.
+The
+.Fa args
+argument must point to the 64bit
+.Vt unsigned long
+variable where the value is written to.
+.It Dv AMD64_SET_TLSBASE
+Sets the TLSBASE and the fsbase register values for the calling thread.
+The
+.Fa args
+argument must point to the 64bit
+.Vt unsigned long
+variable where the value is taken from.
+.Pp
+The TLSBASE value is written into the
+.Dv fsbase
+register before a signal handler is invoked.
+The current fsbase value is saved, and then restored
+upon return from the signal handler.
+Use of TLSBASE makes it possible for programs that modify
+the fsbase register using WRFSBASE instruction to reliably access
+thread-local variables in signal handlers.
+.Pp
+TLSBASE is set up by the
+.Fx
+C runtime environment on thread startup.
+.It Dv AMD64_DISABLE_TLSBASE
+Disables loading the fsbase register from TLSBASE value on
+a signal handler invocation.
+The argument
+.Fa args
+is ignored.
+.Pp
+The call allows to undo the effect of the
+.Dv AMD64_SET_TLSBASE ,
+making signal handlers retain the value of fsbase from the
+interrupted context.
+By default, tlsbase is disabled after the
+.Xr execve 2
+syscall activated a new image.
+.El
+.Sh RETURN VALUES
+For all requests except
+.Dv I386_GET_LDT
+and
+.Dv I386_SET_LDT ,
+upon successful completion, the value 0 is returned; otherwise the
+value -1 is returned and the global variable
+.Va errno
+is set to indicate the error.
+.Pp
+The
+.Dv I386_SET_LDT
+request returns the starting index of the descriptors range it operated
+on, on success.
+In particular, the index of the automatically allocated descriptor is
+reported this way.
+Otherwise, -1 is returned and
+.Va errno
+is set.
+.Pp
+The
+.Dv I386_GET_LDT
+request returns 0 if the specified descriptors range is completely
+outside the allocated LDT.
+On any other error, -1 is returned and
+.Va errno
+is set.
+Otherwise the number of reported descriptors is returned as the syscall
+return value.
+.Sh SEE ALSO
+.Xr i386_get_ioperm 2 ,
+.Xr i386_get_ldt 2 ,
+.Xr i386_vm86 2 ,
+.Xr sysarch 2 ,
+.Xr pkru 3 ,
+.Xr arch 7
+.Sh HISTORY
+The manual page appeared in
+.Fx 16.0 .
+.Sh AUTHORS
+The manual page was written by
+.An Konstantin Belousov Aq Mt kib@FreeBSD.org .

File Metadata

Mime Type
text/plain
Expires
Mon, Sep 28, 12:32 AM (13 h, 4 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
39772210
Default Alt Text
D60047.id187761.diff (17 KB)

Event Timeline