2422 Commits
Author SHA1 Message Date
Kyle Evans 78887369c4 loader.efi: devinit() just after parsing args instead
c4640126f1 ("loader.efi: Apply command-line DHCP overrides earlier")
was really good, but moving it just one statement earlier is even
better.  polarian on Libera describes a GELI setup on a system that
doesn't advertise a serial console via ConOut.  They don't have serial
input at the point that they would get prompted for the GELI passphrase,
but if we parse args just before devinit() then he can override the
console with `efibootmgr -e`.  This gives UEFI one advantage over BIOS
loader, as /boot.config isn't available to provide that kind of override
if your impediment is GELI.

We also considered reading loader.env earlier, but we have a chicken/egg
problem in that we must have probed for the ESP to be able to open() it.
We would instead need a devinit_early() and devinit_late() scheme that
allows GELI probing to be deferred until the later pass, after reading
loader.env to pick up the console override.  That's an idea I'd still
like to discuss because it's more robust than hoping that firmware won't
wipe out our efibootmgr(8) entries.

Tested by:	polarian on Libera
Reviewed by:	imp
Differential Revision:	https://reviews.freebsd.org/D60449
2026-10-07 21:16:28 -05:00
Roman Bogorodskiy 4445d03958 stand: userboot: improve userdisk error handling
Currently, userdisk_init() iterates through disks and
checks whether DIOCGSECTORSIZE and DIOCGMEDIASIZE ioctls
are available for the device. If either ioctl fails, userdisk_init()
returns ENXIO with ud_info only partially initialized.
devinit() records the failure, but loader_main() ignores
devinit()'s return value, so later code may access an
uninitialized entry.

In certain cases this code can still boot from a disk even if
userdisk_init() returns ENXIO, for example, when the first of
two disks is valid and the second errors out.

To address this issue while not breaking the current behavior, do
the following:

 - Zero-initialize the userdisk_info array and use a zero media size
   to mark disks that do not support the ioctls mentioned above or
   report an empty medium.
 - Update userdisk_print() not to print unusable disks.
 - Update userdisk_open() to return EIO for unusable disks.
 - Update extract_currdev() to pick the first usable disk
   instead of the first disk. Introduce userboot_disk_firstunit()
   for that.

Additionally, reset counters on ud_info allocation failure to prevent
accessing unallocated data.

Reviewed by:	jhb (previous version), markj
MFC after:	2 weeks
Sponsored by:	The FreeBSD Foundation
Differential Revision:	https://reviews.freebsd.org/D59262
2026-10-06 16:51:40 +00:00
Warner Losh edc51d1de5 stand: Bump version to 3.1
Sponsored by:		Netflix
2026-10-03 23:17:08 -06:00
Warner Losh 262fa4695d stand: Implement zfs_dnode_readlink in terms of zfs_dnode_sa_lookup
Get the link offset using the zfs_dnode_sa_lookup helper now.

Recently, the symbolic links we rely on in the boot loader have stopped
working.

Prior to OpenZFS commit e90badec11 ("Inherit the project ID for every
object type", Matt Turner, 2026-08-14), symbolic link information was
written at a fixed offset in the SA data. Since that commit, the
inherited PROJIDs mean that all pools with quota enabled have started
writing symbolic links with a new, non-fixed offset. Old symbolic links
remained unchanged, but new ones were written with a different
offset. At work, we have all these things: rewritten BEs, quotas, and a
dependence on symbolic links in our boot path.

This came in on 2026-08-24 OpenZFS merge (22649d4dba). This was 12
hours after stab week for August, so we didn't hit this until the
September stab week. Since the new kernel has to write links at the new
offset, the initial tests worked, but the second ones didn't.

Sponsored by:		Netflix
Differential Revision:	https://reviews.freebsd.org/D60268
2026-10-03 11:32:08 -06:00
Warner Losh f382ef1dc8 stand: update zfs_dnode_stat to use zfs_dnode_sa_lookup
Find the SA values with the zfs_dnode_sa_lookup and read out the
relevant bits for the stat buffer.

Sponsored by:		Netflix
Differential Revision:	https://reviews.freebsd.org/D60267
2026-10-03 11:32:08 -06:00
Warner Losh 8bc06ba211 stand: Lookup specific SA value in a dnode
zfs_dnode_sa_lookup will look in the bonus part of the dnode for the
requested SA values, and fall back to the spill as if it's not there.

Sponsored by:		Netflix
Differential Revision:	https://reviews.freebsd.org/D60266
2026-10-03 11:32:08 -06:00
Warner Losh 4175fa107f stand: Lookup the offsets for this SA bundle
Compute the offset for the data for this bundle and the requested data
type.

Sponsored by:		Netflix
Differential Revision:	https://reviews.freebsd.org/D60265
2026-10-03 11:32:08 -06:00
Warner Losh 32fcc66dd3 stand: Load dynamic system attribute offsets
zfs_sa_load looks up all the system attribute offsets and stores them in
the mountpoint.

Sponsored by:		Netflix
Differential Revision:	https://reviews.freebsd.org/D60264
2026-10-03 11:32:08 -06:00
Warner Losh 16cf795d3e stand: zfs_dnode_readlink move from spa to mount argument
For the dynamic system attributes, we'll need the mount argument. Adjust
zfs_dnode_readlink to take that argument.

Sponsored by:		Netflix
Differential Revision:	https://reviews.freebsd.org/D60262
2026-10-03 11:32:07 -06:00
Warner Losh ecd41c0df3 stand: zfs_dnode_stat move from spa to mount argument
When reading dynamic system attributes, we'll need the mount argument
since we can no longer hard-code the offsets. Adjust zfs_dnode_stat to
take it.

Sponsored by:		Netflix
Differential Revision:	https://reviews.freebsd.org/D60261
2026-10-03 11:32:07 -06:00
Warner Losh acbcb68c9f stand: Remove const from zfs_lookup's zfsmount argument
Dynamic system attribute layout can require modifications to the mount
structure on lookup. Drop the const to allow that.

Sponsored by:		Netflix
Differential Revision:	https://reviews.freebsd.org/D60260
2026-10-03 11:32:07 -06:00
Ahmad Khalifa f7663278c2 stand/images: remove translucent pixels around orb
Remove semi-transparent pixels around the orb. These become more
pronounced when the orb is used as the spash screen image.

While here also strip metadata.

MFC after:	3 days
Reviewed by:	tsoome
Differential Revision:	https://reviews.freebsd.org/D60163
2026-10-01 22:11:32 -04:00
Krzysztof Galazka 48b29e9e54 loader.efi: Retain standalone network configuration
DHCP initmd discovery used net_configure() to open and configure SNP,
then immediately closed the socket and released the protocol.
Selecting net0 as currdev subsequently required another exclusive
SNP attach, which may hang on some EDK II firmware.

Keep the configured socket available for ordinary network consumers
so NFS boot can reuse it. Add an explicit deconfiguration operation
and invoke it only when an initmd URL requires handing SNP back
to the firmware network stack.

Signed-off-by: Krzysztof Galazka <[email protected]>

Reviewed by:	imp
Assisted by:    Github Copilot (GPT-5.6 Sol)
Sponsored by:   Intel Corporation
Differential Revision:	https://reviews.freebsd.org/D59999
2026-09-29 21:56:48 +02:00
Krzysztof Galazka c4640126f1 loader.efi: Apply command-line DHCP overrides earlier
Ability to override DHCP options with command-line arguments
was affected by intoduction of initmd support. Initmd discovery
configures the network before loader arguments
were parsed, so a dhcp.root-path override was unavailable
during the first network configuration. Move parsing
arguments earlier and apply dhcp.root-path even if DHCP response
does not contain option 17. This allows providing a dynamic NFS
root e.g. by chain loading loader.efi from iPXE.

Signed-off-by: Krzysztof Galazka <[email protected]>

Reviewed by:	imp
Assisted by:    Github Copilot (GPT-5.6 Sol)
Sponsored by:   Intel Corporation
Differential Revision:	https://reviews.freebsd.org/D59998
2026-09-29 21:55:17 +02:00
Piotr Kubaj 081f751823 stand/powerpc/ofw: do not truncate device tree properties to 1024 bytes
When the OpenFirmware loader flattens the firmware device tree into the
FDT it hands to the kernel (usefdt=1, i.e. on every real-mode OF system
such as pSeries LPARs and QEMU pseries guests), add_node_to_fdt() clamps
every property value to 1024 bytes.  Any larger property reaches the
kernel truncated.

On QEMU pseries the PCI host bridge's "interrupt-map" is 3584 bytes
(32 slots x 4 pins x 7 cells), so only the entries for slots 0-8 survive
and the entry for slot 9 is cut in the middle.  A PCI device in slot 9
or above therefore gets no INTx routing (irq 0), and with INVARIANTS the
partial trailing entry trips the "ofw_bus_search_intrmap: truncated map"
assertion in ofw_bus_search_intrmap() during PCI attach, panicking the
kernel as soon as such a device is present.  "ibm,drc-indexes",
"ibm,drc-names" and "ibm,drc-power-domains" are cut the same way.

Drop the clamp.  fdt_setprop() already reports a property that does not
fit into the FDT buffer, so no separate limit is needed.

Fixes:	5ecf8e3852 ("Clean up some FDT-related code in the PowerPC bootloader, improving error checking and robustness. Prevents errors and crashes in FDT commands on PowerMac G5 systems.")

Differential Revision:	https://reviews.freebsd.org/D60086
2026-09-29 10:28:46 +02:00
Warner Losh 9ecc2493ca Restore booting the partition the EFI boot image was loaded from.
BSDRP images are built with "poudriere image -t firmware", which puts
gptboot.efi on the ESP instead of loader.efi.  gptboot.efi reads the GPT
bootme attribute, picks the active system partition (BSDRP1 or BSDRP2),
chainloads /boot/loader.efi from it and hands loader.efi that partition
in LoadedImage->DeviceHandle (stand/efi/boot1/boot1.c:try_boot).

Since ce9bfd7816 ("loader.efi: Refactor try_boot_device_partitions"),
find_currdev() no longer tries that device: try_boot_device_partitions()
walks the parent disk while explicitly skipping dp->pd_handle, on the
assumption that the boot image always comes from an ESP holding no root
filesystem.  When chainloaded, the partition gptboot.efi selected is
therefore the one partition never considered, and loader.efi falls
through to the first other UFS partition on the disk - the previous
system.  Every A/B upgrade silently boots the old slice.

Commit 1c85c5eea0, which introduced try_boot_device_partitions(), did
try dp itself before its siblings; the refactor dropped it.  Restore it,
keeping the sibling walk as the fallback for the normal ESP case.

Fixes: ce9bfd7816
Assisted-by: Claude Code (Fable 5, Opus 5)
Sponsored by: Netflix
2026-09-26 00:44:20 -06:00
Warner Losh b5f0e7f36a loader.efi: Be cautious about using GOPs
When we're searching for the EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID (GOPs) to
use, skip any whose Mode or Mode->Info pointers are NULL. The spec
requires these to be non-null, however, some firmwares seem to fail to
populate the Info when, for example, a monitor is not present. Work
around these bugs by skipping any GOPs with bad pointers.

PR: 288900
Sponsored by:		Netflix
Differential Revision:	https://reviews.freebsd.org/D59830
2026-09-24 01:22:25 -06:00
Warner Losh 85fb40bad5 loader.efi: Use EfiLoaderData memory type for ram disks
For the images we read into the memory, use EfiLoaderData memory type
instead of EfiReservedMemoryType. The kernel handles the former properly
and won't reallocate it. While the latter isn't necessarily mapped,
which can cause ram disks to fault when loaded. memdisk_uefi.efi
used the latter type, but also registered the device as an ACPI
RAM disk, which we don't do.

Fixes: afee781523
Sponsored by: Netflix
2026-09-24 00:59:42 -06:00
Warner Losh 772c658c66 loader: Use %u to print unsigned value
Fixes: 7055aa7a07
Sponsored by:		Netflix
2026-09-12 10:59:17 -06:00
Warner Losh 6413a870fa loader: Move some support things around, maybe lame?
Sponsored by:		Netflix
2026-09-12 10:59:17 -06:00
Warner Losh 197df29edb loader.efi: Only try to download md if we're netbooting
The only possible time we could download the initmd that the dhcp server
told us about is if we're netbooting. So only attempt to do that if the
load device for loader.efi is a network. IF you are booting off disk and
then need to snag an initmd off the network, that's a different path,
and wouldn't need to necessarily do a dhcp exchange, except to get the
IP address.

Sponsored by:		Netflix
2026-09-12 10:59:17 -06:00
Warner Losh 577ea37d6d loader.efi: Expose efi_devpath_get_mac to get mac
This is a convenient way to test if a device path is a nic or not, so
expose it to the world.

Sponsored by:		Netflix
2026-09-12 10:59:17 -06:00
Warner Losh bbee544312 loader.efi: Fix memory leak in efihttp_dev_close
Save enough context to free the host we allocated in open on close.

Fixes: 6788e42d53
Noticed by: claude + Sonet 5
Sponsored by: Netflix
2026-09-12 10:59:16 -06:00
Warner Losh 8821d42d8b loader.efi: Allow downloading of ramdisk or md to be aborted
Hitting <ESC> will now allow one to abort a (possibly mistaken)
download.

Sponsored by:		Netflix
2026-09-10 22:15:29 -06:00
Warner Losh 0ca12047be loader.efi: Eat the character used to break to OK
When we can't find root, we give the user a chance to drop to the boot
loader OK prompt. We should eat the character that's pressed to not
interfere with the interactive session.

Sponsored by:		Netflix
2026-09-10 22:15:29 -06:00
Warner Losh 08265d5ede loader: Fix starting typo
Fixes:			a22fa5ec74 ("laoder.efi: Fix error in download protcol")
Sponsored by:		Netflix
Differential Revision:	https://reviews.freebsd.org/D59434
2026-09-10 22:15:29 -06:00
Warner Losh 6de311d309 loader.efi: download DHCP initmd specified image
When we haven't downloaded an image via mem{disk,cd} and ipxe, try any
image specified by the FreeBSD-specific initmd dhcp option. This allows
direct booting of loader.efi with a detached root ramdisk filesystem.

Sponsored by:		Netflix
Differential Revision:	https://reviews.freebsd.org/D59433
2026-09-10 22:15:29 -06:00
Warner Losh d48e9bff8c loader.efi: fetch initmd specified by DHCP
Configure net0, read the DHCP-provided initmd URL, and download it
through the file API so directly booted loader.efi can construct its
root memory disk.

Sponsored by:		Netflix
Differential Revision:	https://reviews.freebsd.org/D59432
2026-09-10 22:15:29 -06:00
Warner Losh 25b58eb37a loader.efi: download md images through file API
Feed the existing decompressor from loader file descriptors as well as
iPXE callbacks, allowing arbitrary HTTP filesystem URLs to become
kernel-exportable memory disks.

Sponsored by:		Netflix
Differential Revision:	https://reviews.freebsd.org/D59431
2026-09-10 22:15:29 -06:00
Warner Losh 5bbd617cc5 loader.efi: release SNP after network configuration
Close the exclusively opened SNP protocol after loader networking
finishes so the firmware network stack can reconnect the controller and
service a subsequent HTTP request.

Sponsored by:		Netflix
Differential Revision:	https://reviews.freebsd.org/D59430
2026-09-10 22:15:28 -06:00
Warner Losh e6b997c73c loader: add standalone network configuration
Allow callers to obtain DHCP configuration without opening a network
file, enabling loader.efi to discover an initmd URL before handing the
interface back to firmware HTTP.

Differential Revision:	https://reviews.freebsd.org/D59429
Sponsored by:		Netflix
2026-09-10 22:15:28 -06:00
Warner Losh a098fd021e loader: request DHCP initmd option
Request FreeBSD RFC 3925 PEM 2238 DHCP 125 option. Use suboption 1 to
specify a ramdisk image to load and use to load the kernel and as the
root file system.

Differential Revision:	https://reviews.freebsd.org/D59428
Sponsored by:		Netflix
2026-09-10 22:15:28 -06:00
Warner Losh 6788e42d53 stand/efihttp: Support arbitrary http[N]://host[:port]/path devspecs
Until now, the "http" device only worked when firmware itself booted
loader.efi via EFI HTTP Boot: efihttp_dev_init() required a URI node on
the loader's own boot device path, and every fetch went to that same
server. Add a second form, using the parse_uri() helper from libsa/dev.c,
that works anywhere: http[N]://host[:port]/path (N is a network interface
unit, defaulting to 0). This lets a devspec like this be used as rootdev,
in loader.conf, or interactively, independent of how loader.efi itself
was booted.

Network configuration is shared, loader-wide state (the myip/netmask/
gateip/nameip globals from net.h): if something has already configured
them (e.g. tftp/nfs via net_open()), the http device just reuses those
values, applying them to EFI_IP4_CONFIG2_PROTOCOL as a static address. If
nothing has, it drives IP4Config2's own DHCP directly instead of calling
netdev's net_open(): net_open() opens the NIC's SNP
EFI_OPEN_PROTOCOL_EXCLUSIVE, which would disconnect the Mnp/Ip4/.../
HttpDxe driver chain this code depends on. That chain is also commonly
disconnected already by whatever chained us here (e.g. iPXE excludes and
exclusively opens SNP for its own raw I/O), so reconnect it explicitly
with ConnectController() before giving up.

The legacy EFI HTTP Boot path is untouched.

Sponsored by:		Netflix
Differential Revision:	https://reviews.freebsd.org/D59423
2026-09-10 22:15:28 -06:00
Warner Losh 7208b3b845 libsa: Add a generic URI-syntax devspec parser
Add parse_uri(), a helper for devices whose devspec can take a
"[N]://host[:port][/path]" form in addition to the traditional "N:path"
form. It returns EINVAL when devspec doesn't match that pattern, so a
caller's own dv_parsedev can fall back to the traditional form.

Un-static default_parsedev() so it can serve as that fallback.

Sponsored by:		Netflix
Differential Revision:	https://reviews.freebsd.org/D59422
2026-09-10 22:15:28 -06:00
Warner Losh f1163b9436 loader.efi: For ipxe booting, fall back to md when ramdisk fails
Some UEFI firmwares do not contain the RamDisk protocol. When this
happens, load the file into a md disk instead. This is less desireable
than the RamDisk (since that allows better chain-booting options), but
sufficient to boot an image as a md device for FreeBSD. While most
severs have the RamDisk protocol enabled in their builds, I have two
IoT class boards from different manufacturers that do not. Since it
works just fine with this fallback, that's preferable.

Sponsored by:		Netflix
Differential Revision:	https://reviews.freebsd.org/D59421
2026-09-10 22:15:28 -06:00
Warner Losh 96b1e04a74 loader: Add md support
Allow md devices like efi allows them.

Sponsored by:		Netflix
Differential Revision:	https://reviews.freebsd.org/D59420
2026-09-10 22:15:27 -06:00
Warner Losh 69d1595ded loader.efi: Move probing the md up to before doing bootmgr
When someone has loaded a ram disk, that's a stronger hint about what to
boot than the UEFI boot manager. Prefer it and rework a little the #ifdefs
to reduce their number.

Sponsored by:		Netflix
Differential Revision:	https://reviews.freebsd.org/D59419
2026-09-10 22:15:27 -06:00
Warner Losh 752bde7da6 loader: Allow dynmaic creation of MD disks
Augment the md device to allow creation of md devices. This is useful
when UEFI doesn't support RamDisk and in other cases where we have a
handy initrd-like image we want to use.

Sponsored by:		Netflix
Differential Revision:	https://reviews.freebsd.org/D59418
2026-09-10 22:15:27 -06:00
Warner Losh 7055aa7a07 loader: Move ramdisk export to md.c
Move the common routine to md.c and use it where we do memdisks today.

Sponsored by:		Netflix
Differential Revision:	https://reviews.freebsd.org/D59417
2026-09-10 22:15:27 -06:00
Warner Losh 4f7475ab5b loader: Small tweak to how md is configured
Only the EFI loader supports the md devices (as the moment). Create
LOADER_MD_SUPPORT and only try to compile md when that's true. For the
moment, also allow it when only MD_IMAGE_SIZE is defined, but that
will be dropped since LOADER_MD_SUPPORT is a superset.

Sponsored by:		Netflix
Reviewed by:		tsoome
Differential Revision:	https://reviews.freebsd.org/D59416
2026-09-10 22:15:27 -06:00
Warner Losh 8fae9294d6 loader: Allow this to compile w/o MD_IMAGE_SIZE defined
Slight tweak to allow md.c to be compiled when MD_IMAGE_SIZE isn't
defined.

Sponsored by:		Netflix
Reviewed by:		olivier, tsoome
Differential Revision:	https://reviews.freebsd.org/D59415
2026-09-10 22:15:27 -06:00
Andrew Turner 747c377963 arm64: Fix the CTR_EL0 field names
Use the field names from the Arm Documentation for the CTR_EL0
register. These will later be generated from a BSD Licensed JSON file
so to reduce the diff for that rename now.

Reviewed by:	Kajetan Puchalski <[email protected]>
Sponsored by:	Arm Ltd
Differential Revision:	https://reviews.freebsd.org/D59173
2026-09-08 04:05:26 +01:00
Robert Clausecker d1c07141dc manpages: Fix author e-mail address formatting
- consistently use Mt request within Aq.  This makes author
   e-mail addresses clickable in many frontends.
 - @freebsd.org -> @FreeBSD.org
 - ([email protected]) -> Aq Mt [email protected]

Event:		Berlin Hackathon 202609
MFC after:	3 days
Reviewed by:	ziaee
Differential Revision:	https://reviews.freebsd.org/D59410
2026-09-04 21:46:20 +02:00
Kyle Evans 619d092177 iuserboot: bump the interface to v6, add an accept_interpreter callback
If an explicit loader wasn't requested, then bhyveload(8) maintains a
/boot handle that it can use for swapping to a different flavor.  This
means that we expose all of the host /boot to the sandbox for the
duration of script execution.

Add a callback to ack that we're OK with the interpreter so that
bhyveload(8) can release the bootfd.  This is worth doing because it's
prior to guest script execution, so we're still running a reasonably
untainted process.

Reviewed by:	imp, jhb
Differential Revision:	https://reviews.freebsd.org/D58771
2026-09-04 10:26:35 -05:00
Warner Losh 68a4a53e82 loader.kboot.8: Use right headers
Uggg, copied this instead of using the new style.

Sponsored by:		Netflix
2026-09-01 10:26:26 -06:00
Warner Losh a0d5b130ef loader.kboot: Add man page
Sponsored by:		Netflix
2026-09-01 09:58:07 -06:00
Aryan Arora bfa36136a5 kboot: Fix file2str() buffer under-read
Signed-off-by: Aryan Arora <[email protected]>
Reviewed by: imp
Pull Request: https://github.com/freebsd/freebsd-src/pull/2359
2026-09-01 07:54:12 -06:00
Ahmad Khalifa ad9b4cc631 update email address in my copyright notices 2026-08-28 17:30:18 +03:00
Faraz Vahedi 8d29d24296 libc: Restore prior C23 include guards
To avoid any sort of POLA violation, this commit restores old
guards and defines the C23 feature test macros in addition to
them.  This is to close off whole class of possible breakage,
rather than patching it case by case.

Reported by:	dim
Reviewed by:	dim, dteske, fuz
Approved by:	dim, dteske (mentor), fuz (mentor)
MFC after:	1 month
Differential Revision: https://reviews.freebsd.org/D58911
2026-08-19 13:51:21 +03:30
Etienne Bonnand b567434a59 stand: set st_dev/st_ino in the loader's ZFS stat for veriexec
The loader's ZFS implementation never set st_dev or st_ino in
zfs_dnode_stat(). With an uninitialized struct stat, veriexec's device
comparison in lib/libsecureboot/veopen.c read stack garbage and skipped
the matching manifest entry, failing with a spurious "no entry" on ZFS
root under UEFI Secure Boot.

Rather than zeroing the device (which would break veriexec's ability to
tell apart the same path on different datasets), populate st_dev and
st_ino with the same intrinsic identifiers the kernel uses:

- st_dev = the dataset's ds_fsid_guid (as the kernel does via
  dmu_objset_fsid_guid()/dsl_dataset_fsid_guid()), already read in
  zfs_mount_dataset() and now propagated through struct zfsmount.
- st_ino = the object number resolved in zfs_lookup(), propagated
  through struct file (the loader's equivalent of the kernel's z_id).

dev_t and ino_t are 64-bit on FreeBSD, so both are assigned directly
with no hashing. A memset() at the top of zfs_dnode_stat() zeroes the
remaining fields so they no longer hold stack garbage.

Tested on 16.0-CURRENT (amd64), ZFS-on-GELI root: rebuilt and re-signed
the EFI loader; the system boots under UEFI Secure Boot with
mac_veriexec active.

(boot1 segment was modified by kevans)

PR:		295935
Sponsored by:	Defenso

Reviewed-by: kevans
Pull-Request: https://github.com/freebsd/freebsd-src/pull/2271
2026-08-18 10:47:12 -05:00