From nobody Fri Oct 16 23:17:16 2026 X-Original-To: dev-commits-src-main@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4j61711DyDz6vylQ for ; Fri, 16 Oct 2026 23:17:17 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id 4j6171109kz4MLF for ; Fri, 16 Oct 2026 23:17:17 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1792192637; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=UEW5VlvcmoF1GmlM9OyjVaGOyXxPirV9t+F8t2GSn+4=; b=S7L+1WlfLuxgMpEiQTM8ZXLkzvJcOkuQg+Lujh/t7tQLB797M20uXMHIVz4yT2Ei/LICTT JCSu/IRhJxHulBqd2xt26l+Bz4B8kJxCslIx/xlE0fO0XDSJf/BG10OszdT3NC5obZJdkw 0kexHF4gfKur//qcd/Gc5VaebFZEUqt1EY2Vqi2ka4J+Pe217cRNJOzx8Hskid/6R2bUYP 174iXcNwc6UcSST9eAI/saUTMbVFgeKuy6A95PllqDASQ4AuYE8De3upB3sMdXObE/m2x1 98e09011mzBwJecDsN3vg/jp4KBzlQBe5tmV5POgRSAhlPhU+5oGi8Ph/voYcw== ARC-Seal: i=1; a=rsa-sha256; d=freebsd.org; s=dkim; cv=none; t=1792192637; b=MjTBpgqhtqkJzaTrS1abJgHM3PpuT9A1hCY/ze7YDm7B7kIilOPrN+XXMxqdXWYM7Kz/Fd Uh6oRy4qcxJFBR0OiWd/x3PgNyCFB8hKVIyERvirWCIS6cho3HL1EsDnXBwnYH9B8cK1UD raAspL3tkJrVfLALuVcWWRzz1kmplJimx4fSio5W6nr5z45ZdTmv3VEuXzuWWuxwuaKDvD DH60WhYOixysLXRAh2SojKASZPaXGY8wxJZ0PhT1qoQmw61J0hYwa3UZ5126S6TZqzGWBL HSocqWiLAgnIGtIH82ho30PKpB7Y9T+yBlyKzxJA7GhpDLv75zNisZwuwZiFtQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1792192637; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=UEW5VlvcmoF1GmlM9OyjVaGOyXxPirV9t+F8t2GSn+4=; b=E5DDf/ZzBS1J2MlCps40YQbS3SCDApjmrWQ/Mz5NEVfg+hU2fnz4tVPLB9RK8TxLUGmIsZ PIMAmEnUu2ZqKfNb+zw+Z6r0YmkgQkTtkaBaHRW/Uuj73KgYowdmohRRnsWSSckkoPbGmI OtTQ/+s1Q+p1HNuYSedZDwGPfQKWEeQRb/UdXDGtV6Ijx2aeA5gffDyIaEe/GYSAFf2ooP oZY3Q+OE5ICownWDtqoVDkHZSePTaQBvT1fBWpjozuPaIL1aAPxEe/kMSa1BkXlozFMapX cGKQ0MzT6PokKkL4YY/8PW+k+BpKradodvw/LT+pX/JW+1gESgpGGdLAaMfkgQ== ARC-Authentication-Results: i=1; mx1.freebsd.org; none Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4j61710N4PzhH2 for ; Fri, 16 Oct 2026 23:17:17 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 1c3f3 by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Fri, 16 Oct 2026 23:17:16 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Konstantin Belousov Subject: git: bdcfeac3e1cb - main - sysarch.x86.2: manual page for the sysarch(2) functions on x86 List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main X-BeenThere: dev-commits-src-main@freebsd.org Sender: owner-dev-commits-src-main@FreeBSD.org List-Id: Commit messages for the main branch of the src repository List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: kib X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: bdcfeac3e1cb8ce3f05c32d8a7ad3597deb48bdf Auto-Submitted: auto-generated Date: Fri, 16 Oct 2026 23:17:16 +0000 Message-Id: <6ad2b07c.1c3f3.4e605457@gitrepo.freebsd.org> The branch main has been updated by kib: URL: https://cgit.FreeBSD.org/src/commit/?id=bdcfeac3e1cb8ce3f05c32d8a7ad3597deb48bdf commit bdcfeac3e1cb8ce3f05c32d8a7ad3597deb48bdf Author: Konstantin Belousov AuthorDate: 2026-09-26 11:03:34 +0000 Commit: Konstantin Belousov CommitDate: 2026-10-16 23:15:34 +0000 sysarch.x86.2: manual page for the sysarch(2) functions on x86 Reviewed by: ziaee Discussed with: jhb Sponsored by: The FreeBSD Foundation MFC after: 1 week Differential revision: https://reviews.freebsd.org/D60047 --- lib/libsys/sysarch.2 | 3 +- lib/libsys/x86/Makefile.sys | 3 +- lib/libsys/x86/sysarch.x86.2 | 659 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 663 insertions(+), 2 deletions(-) diff --git a/lib/libsys/sysarch.2 b/lib/libsys/sysarch.2 index 6144cd44fb37..a1d5d9c4640e 100644 --- a/lib/libsys/sysarch.2 +++ b/lib/libsys/sysarch.2 @@ -72,7 +72,8 @@ for information about their return values. .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/x86/Makefile.sys b/lib/libsys/x86/Makefile.sys index 483d1784bdc9..ec6ad113d86b 100644 --- a/lib/libsys/x86/Makefile.sys +++ b/lib/libsys/x86/Makefile.sys @@ -7,7 +7,8 @@ SRCS+= \ .if ${LIB} == "sys" MAN+= \ - pkru.3 + pkru.3 \ + sysarch.x86.2 .endif # ${LIB} == "sys" # Note: vdso support for hyperv only on amd64 diff --git a/lib/libsys/x86/sysarch.x86.2 b/lib/libsys/x86/sysarch.x86.2 new file mode 100644 index 000000000000..a1305f0ac763 --- /dev/null +++ b/lib/libsys/x86/sysarch.x86.2 @@ -0,0 +1,659 @@ +.\" SPDX-License-Identifier: BSD-2-Clause +.\" +.\" Copyright 2026 The FreeBSD Foundation. +.\" +.\" This documentation was written by Konstantin Belousov +.\" 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 describes 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 to by the +.Fa args +parameter. +Refer to the description of each request for the meaning of +individual fields: +.Pp +The +.Dv I386_GET_IOPERM +and +.Dv I386_SET_IOPERM +requests take a +.Vt struct i386_ioperm_args , +which is defined as follows: +.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 a +.Vt struct i386_ldt_args , +whose 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 +The request +.Dv I386_VM86 +is only supported by i386 kernels and takes a +.Bd -literal +struct i386_vm86_args { + int sub_op; + char *sub_args; +}; +.Ed +.Pp +The +.Dv I386_GET_XFPUSTATE , +takes a +.Vt struct i386_get_xfpustate +argument, a +.Dv AMD64_GET_XFPUSTATE +.Vt struct amd64_get_xfpustate +argument. +The structures have the same members, but their layout differs due to +pointer size differences. +Only the 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 a +.Vt struct i386_set_pkru +argument, and +.Dv AMD64_GET_PKRU +and +.Dv AMD64_SET_PKRU +take a +.Vt struct amd64_set_pkru +argument. +The structures have the same members, but their layout differs due to +pointer size differences. +Only the 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 LDT descriptors for the +calling process. +.Pp +The request takes a 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 descriptors in the requested range are copied into +the memory specified by the +.Fa descs +member. +.It Dv I386_SET_LDT +Set the specified range of LDT descriptors for the calling process. +.Pp +LDT is process-global, all process threads share the same table. +On the other hand, if several processes share an address space, +they still each have their own LDT. +.Pp +The request takes a 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 set. +The LDT descriptors in the requested range +are initialized from the structures pointed to by the +.Fa descs +member. +.Pp +If the +.Va descs +member value is +.Dv NULL, +the LDT descriptors are reset to null descriptors. +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 the system looks for +a 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 LDTs with up to 8192 descriptors. +This size is excessive for modern applications. +The +.Dv machdep.max_ldt_segment +loader tunable sets a system-global maximum LDT size +(in number of descriptors). +.It Dv I386_GET_IOPERM +Queries the state of userspace access to the specified range of +I/O ports for the calling thread. +.Pp +The function takes a +.Vt struct i386_ioperm_args +structure as the +.Fa args +argument. +The +.Va start +member is the starting port number to query. +Upon successful return, the +.Va enable +member records the access permissions for 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 +.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 ports 10, 11, and 12 is allowed, while +access to port 13 is disallowed. +.It Dv I386_SET_IOPERM +Grants or revokes userspace access to I/O ports by modifying the TSS +I/O permission bitmap for the calling thread. +Each thread maintains a separate bitmap. +.Pp +The function takes a +.Vt struct i386_ioperm_args +structure as the +.Fa args +argument. +Depending on the +.Va enable +member value, it either grants (enables) or revokes (disables) +access to the range of +I/O ports specified by the +.Va start +and +.Va length +members. +.Pp +There is total of 65536 ports, so the set of ports specified must fit +into the 0..65535 range. +.Pp +The call requires super-user privileges. +.It Dv I386_VM86 +Execute CPU instructions in virtual 8086 (VM86) mode. +This function is only supported by i386 kernels as VM86 mode +is not supported in long mode. +To use this request, the additional header +.In machine/vm86.h +must be included which exists only for i386. +.Pp +The request takes a +.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 this initialization, 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 a +.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 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. +The +.Va sub_args +must point to a +.Vt struct vm86_vme_args +structure. +.It Dv VM86_INTCALL +Arrange execution in VM86 mode as if the specified interrupt +was delivered. +Takes a +.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 +An alternative 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 signals the same as +for protected execution mode. +.Pp +See +.Pa src:tools/tests/vm86 +for a minimal example for a VM86 monitor and sample code. +.It Dv I386_GET_FSBASE +Read the 32-bit fsbase context value for the calling thread into a +.Vt uint32_t +variable pointed to by the +.Fa args +argument. +.It Dv I386_SET_FSBASE +Set the 32-bit fsbase context value for the calling thread. +The +.Fa args +argument must point to a +.Vt int32_t +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 32-bit %fs GDT descriptor, which has index 2. +.It Dv I386_GET_GSBASE +Read the 32-bit gsbase context value for the calling thread into a +.Vt int32_t +variable pointed to by the +.Fa args +argument. +.It Dv I386_SET_GSBASE +Set the 32-bit gsbase context value for the calling thread. +The +.Fa args +argument must point to a +.Vt int32_t +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 32-bit %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 +.Dv 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 +.Dv 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 excluding 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 the +.Dv 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 .