aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/checklist.yml1
-rw-r--r--Makefile8
-rw-r--r--Makefile.inc124
-rw-r--r--ObsoleteFiles.inc3
-rw-r--r--bin/df/df.16
-rw-r--r--bin/ps/ps.16
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/dtrace.154
-rw-r--r--contrib/bsnmp/lib/snmpclient.c12
-rw-r--r--contrib/bsnmp/lib/snmpclient.h1
-rw-r--r--contrib/bsnmp/lib/snmppriv.h1
-rw-r--r--contrib/bsnmp/snmpd/main.c17
-rw-r--r--contrib/bsnmp/snmpd/trans_lsock.c2
-rw-r--r--contrib/elftoolchain/libelf/elf_open.35
-rw-r--r--contrib/elftoolchain/libelf/gelf_xlatetof.311
-rw-r--r--contrib/libbegemot/rpoll.c22
-rw-r--r--lib/libc/gen/fdopendir.c10
-rw-r--r--lib/libc/powerpc64/gen/_ctx_start.S14
-rw-r--r--lib/libc/powerpc64/gen/makecontext.c3
-rw-r--r--lib/libc/stdio/fdopen.c18
-rw-r--r--lib/libc/stdio/freopen.c10
-rw-r--r--lib/libc/tests/sys/Makefile4
-rw-r--r--lib/libc/tests/sys/swapcontext_test.c63
-rw-r--r--lib/libfetch/common.c7
-rw-r--r--lib/ncurses/tinfo/Makefile9
-rw-r--r--libexec/rc/rc4
-rwxr-xr-xlibexec/rc/rc.d/hostname4
-rwxr-xr-xlibexec/rc/rc.d/pf2
-rwxr-xr-xlibexec/rc/rc.d/routing2
-rwxr-xr-xlibexec/rc/rc.d/zfs8
-rwxr-xr-xlibexec/rc/rc.d/zfsbe2
-rw-r--r--libexec/rc/rc.shutdown4
-rw-r--r--libexec/rc/rc.subr4
-rw-r--r--libexec/rc/tests/rc_subr_test.sh4
-rw-r--r--release/Makefile2
-rwxr-xr-xrelease/amd64/make-memstick.sh7
-rw-r--r--release/amd64/mkisoimages.sh13
-rwxr-xr-xrelease/arm64/make-memstick.sh5
-rw-r--r--release/arm64/mkisoimages.sh13
-rwxr-xr-xrelease/i386/make-memstick.sh9
-rw-r--r--release/i386/mkisoimages.sh5
-rw-r--r--release/packages/Makefile.package193
-rw-r--r--release/packages/certctl.ucl9
-rw-r--r--release/packages/clang-all.ucl1
-rwxr-xr-xrelease/packages/generate-ucl.lua155
-rwxr-xr-xrelease/packages/generate-ucl.sh102
-rw-r--r--release/packages/lld-all.ucl1
-rw-r--r--release/packages/lldb-all.ucl1
-rw-r--r--release/packages/ssh-all.ucl1
-rw-r--r--release/packages/template.ucl6
-rw-r--r--release/packages/ucl/acct-all.ucl4
-rw-r--r--release/packages/ucl/acpi-all.ucl4
-rw-r--r--release/packages/ucl/amd-all.ucl4
-rw-r--r--release/packages/ucl/apm-all.ucl4
-rw-r--r--release/packages/ucl/at-all.ucl4
-rw-r--r--release/packages/ucl/audit-all.ucl4
-rw-r--r--release/packages/ucl/autofs-all.ucl4
-rw-r--r--release/packages/ucl/bhyve-all.ucl4
-rw-r--r--release/packages/ucl/blocklist-all.ucl4
-rw-r--r--release/packages/ucl/bluetooth-all.ucl4
-rw-r--r--release/packages/ucl/bootloader-all.ucl4
-rw-r--r--release/packages/ucl/bsdinstall-all.ucl4
-rw-r--r--release/packages/ucl/bsnmp-all.ucl4
-rw-r--r--release/packages/ucl/caroot-all.ucl4
-rw-r--r--release/packages/ucl/caroot.ucl10
-rw-r--r--release/packages/ucl/ccdconfig-all.ucl5
-rw-r--r--release/packages/ucl/certctl-all.ucl4
-rw-r--r--release/packages/ucl/certctl.ucl6
-rw-r--r--release/packages/ucl/clang-all.ucl5
-rw-r--r--release/packages/ucl/clang.ucl11
-rw-r--r--release/packages/ucl/clibs-all.ucl4
-rw-r--r--release/packages/ucl/clibs.ucl (renamed from release/packages/clibs.ucl)0
-rw-r--r--release/packages/ucl/console-tools-all.ucl4
-rw-r--r--release/packages/ucl/cron-all.ucl4
-rw-r--r--release/packages/ucl/csh-all.ucl4
-rw-r--r--release/packages/ucl/ctf-tools-all.ucl4
-rw-r--r--release/packages/ucl/ctl-all.ucl4
-rw-r--r--release/packages/ucl/cxgbe-tools-all.ucl4
-rw-r--r--release/packages/ucl/devd-all.ucl4
-rw-r--r--release/packages/ucl/devmatch-all.ucl4
-rw-r--r--release/packages/ucl/dhclient-all.ucl4
-rw-r--r--release/packages/ucl/dma-all.ucl4
-rw-r--r--release/packages/ucl/docs-all.ucl4
-rw-r--r--release/packages/ucl/dtb-all.ucl4
-rw-r--r--release/packages/ucl/dtrace-all.ucl4
-rw-r--r--release/packages/ucl/dwatch-all.ucl4
-rw-r--r--release/packages/ucl/ee-all.ucl4
-rw-r--r--release/packages/ucl/efi-tools-all.ucl4
-rw-r--r--release/packages/ucl/examples-all.ucl4
-rw-r--r--release/packages/ucl/fd-all.ucl4
-rw-r--r--release/packages/ucl/fetch-all.ucl4
-rw-r--r--release/packages/ucl/firmware-iwm-all.ucl4
-rw-r--r--release/packages/ucl/ftp-all.ucl4
-rw-r--r--release/packages/ucl/ftpd-all.ucl4
-rw-r--r--release/packages/ucl/fwget-all.ucl4
-rw-r--r--release/packages/ucl/games-all.ucl4
-rw-r--r--release/packages/ucl/geom-all.ucl4
-rw-r--r--release/packages/ucl/ggate-all.ucl4
-rw-r--r--release/packages/ucl/hast-all.ucl4
-rw-r--r--release/packages/ucl/hostapd-all.ucl4
-rw-r--r--release/packages/ucl/hyperv-tools-all.ucl4
-rw-r--r--release/packages/ucl/inetd-all.ucl4
-rw-r--r--release/packages/ucl/ipf-all.ucl4
-rw-r--r--release/packages/ucl/ipfw-all.ucl4
-rw-r--r--release/packages/ucl/iscsi-all.ucl6
-rw-r--r--release/packages/ucl/jail-all.ucl4
-rw-r--r--release/packages/ucl/kerberos-all.ucl4
-rw-r--r--release/packages/ucl/kerberos-lib-all.ucl4
-rw-r--r--release/packages/ucl/kernel-all.ucl4
-rw-r--r--release/packages/ucl/lib9p-all.ucl5
-rw-r--r--release/packages/ucl/libarchive-all.ucl4
-rw-r--r--release/packages/ucl/libbegemot-all.ucl5
-rw-r--r--release/packages/ucl/libblocksruntime-all.ucl4
-rw-r--r--release/packages/ucl/libbsdstat-all.ucl5
-rw-r--r--release/packages/ucl/libbsm-all.ucl6
-rw-r--r--release/packages/ucl/libbz2-all.ucl5
-rw-r--r--release/packages/ucl/libcasper-all.ucl5
-rw-r--r--release/packages/ucl/libcompat-all.ucl4
-rw-r--r--release/packages/ucl/libcompiler_rt-all.ucl4
-rw-r--r--release/packages/ucl/libcuse-all.ucl5
-rw-r--r--release/packages/ucl/libdwarf-all.ucl6
-rw-r--r--release/packages/ucl/libevent1-all.ucl4
-rw-r--r--release/packages/ucl/libexecinfo-all.ucl5
-rw-r--r--release/packages/ucl/libipt-all.ucl6
-rw-r--r--release/packages/ucl/libldns-all.ucl6
-rw-r--r--release/packages/ucl/liblzma-all.ucl5
-rw-r--r--release/packages/ucl/libmagic-all.ucl5
-rw-r--r--release/packages/ucl/libopencsd-all.ucl5
-rw-r--r--release/packages/ucl/libpathconv-all.ucl5
-rw-r--r--release/packages/ucl/librpcsec_gss-all.ucl5
-rw-r--r--release/packages/ucl/librss-all.ucl5
-rw-r--r--release/packages/ucl/libsdp-all.ucl5
-rw-r--r--release/packages/ucl/libsqlite3-all.ucl4
-rw-r--r--release/packages/ucl/libstdbuf-all.ucl6
-rw-r--r--release/packages/ucl/libstdthreads-all.ucl4
-rw-r--r--release/packages/ucl/libthread_db-all.ucl5
-rw-r--r--release/packages/ucl/libucl-all.ucl5
-rw-r--r--release/packages/ucl/libufs-all.ucl8
-rw-r--r--release/packages/ucl/libvgl-all.ucl13
-rw-r--r--release/packages/ucl/libvmmapi-all.ucl4
-rw-r--r--release/packages/ucl/liby-all.ucl5
-rw-r--r--release/packages/ucl/libyaml-all.ucl5
-rw-r--r--release/packages/ucl/libzfs-all.ucl5
-rw-r--r--release/packages/ucl/lld-all.ucl6
-rw-r--r--release/packages/ucl/lldb-all.ucl6
-rw-r--r--release/packages/ucl/locales-all.ucl4
-rw-r--r--release/packages/ucl/lp-all.ucl4
-rw-r--r--release/packages/ucl/manuals-all.ucl4
-rw-r--r--release/packages/ucl/mlx-tools-all.ucl4
-rw-r--r--release/packages/ucl/mtree-all.ucl4
-rw-r--r--release/packages/ucl/natd-all.ucl4
-rw-r--r--release/packages/ucl/netmap-all.ucl4
-rw-r--r--release/packages/ucl/newsyslog-all.ucl4
-rw-r--r--release/packages/ucl/nfs-all.ucl4
-rw-r--r--release/packages/ucl/ntp-all.ucl4
-rw-r--r--release/packages/ucl/nuageinit-all.ucl4
-rw-r--r--release/packages/ucl/nvme-tools-all.ucl4
-rw-r--r--release/packages/ucl/openssl-all.ucl4
-rw-r--r--release/packages/ucl/openssl-lib-all.ucl4
-rw-r--r--release/packages/ucl/periodic-all.ucl4
-rw-r--r--release/packages/ucl/periodic.ucl6
-rw-r--r--release/packages/ucl/pf-all.ucl4
-rw-r--r--release/packages/ucl/pkg-bootstrap-all.ucl4
-rw-r--r--release/packages/ucl/ppp-all.ucl5
-rw-r--r--release/packages/ucl/quotacheck-all.ucl8
-rw-r--r--release/packages/ucl/rc-all.ucl4
-rw-r--r--release/packages/ucl/rcmds-all.ucl7
-rw-r--r--release/packages/ucl/rcmds.ucl8
-rw-r--r--release/packages/ucl/rdma-all.ucl1
-rw-r--r--release/packages/ucl/rescue-all.ucl4
-rw-r--r--release/packages/ucl/resolvconf-all.ucl4
-rw-r--r--release/packages/ucl/runtime-all.ucl4
-rw-r--r--release/packages/ucl/runtime.ucl (renamed from release/packages/runtime.ucl)0
-rw-r--r--release/packages/ucl/sendmail-all.ucl4
-rw-r--r--release/packages/ucl/smbutils-all.ucl4
-rw-r--r--release/packages/ucl/src-all.ucl5
-rw-r--r--release/packages/ucl/src-sys-all.ucl5
-rw-r--r--release/packages/ucl/ssh-all.ucl5
-rw-r--r--release/packages/ucl/syscons-data-all.ucl4
-rw-r--r--release/packages/ucl/syslogd-all.ucl4
-rw-r--r--release/packages/ucl/tcpd-all.ucl4
-rw-r--r--release/packages/ucl/telnet-all.ucl4
-rw-r--r--release/packages/ucl/tests-all.ucl4
-rw-r--r--release/packages/ucl/toolchain-all.ucl4
-rw-r--r--release/packages/ucl/ufs-all.ucl4
-rw-r--r--release/packages/ucl/unbound-all.ucl5
-rw-r--r--release/packages/ucl/utilities-all.ucl4
-rw-r--r--release/packages/ucl/utilities.ucl (renamed from release/packages/utilities.ucl)0
-rw-r--r--release/packages/ucl/vi-all.ucl4
-rw-r--r--release/packages/ucl/vt-data-all.ucl4
-rw-r--r--release/packages/ucl/wpa-all.ucl4
-rw-r--r--release/packages/ucl/yp-all.ucl7
-rw-r--r--release/packages/ucl/zfs-all.ucl4
-rw-r--r--release/packages/ucl/zoneinfo-all.ucl5
-rw-r--r--release/packages/unbound-all.ucl1
-rw-r--r--release/powerpc/mkisoimages.sh5
-rwxr-xr-xrelease/riscv/make-memstick.sh5
-rw-r--r--release/riscv/mkisoimages.sh13
-rw-r--r--release/scripts/tools.subr13
-rw-r--r--release/tools/vmimage.subr7
-rw-r--r--sbin/ifconfig/ifconfig.822
-rw-r--r--sbin/mount/mount.86
-rw-r--r--sbin/pfctl/parse.y62
-rw-r--r--sbin/pfctl/pfctl.85
-rw-r--r--sbin/pfctl/pfctl.c57
-rw-r--r--sbin/pfctl/pfctl.h2
-rw-r--r--sbin/pfctl/pfctl_optimize.c31
-rw-r--r--sbin/pfctl/pfctl_parser.c5
-rw-r--r--sbin/pfctl/pfctl_parser.h1
-rw-r--r--sbin/pfctl/pfctl_radix.c13
-rw-r--r--sbin/pfctl/pfctl_table.c32
-rw-r--r--sbin/pfctl/tests/files/pf0088.in2
-rw-r--r--sbin/pfctl/tests/files/pf0088.ok2
-rw-r--r--sbin/pfctl/tests/files/pf1072.fail1
-rw-r--r--sbin/pfctl/tests/files/pf1072.in1
-rw-r--r--sbin/pfctl/tests/pfctl_test_list.inc1
-rw-r--r--sbin/route/route_netlink.c1
-rw-r--r--sbin/savecore/savecore.86
-rw-r--r--share/man/man4/Makefile9
-rw-r--r--share/man/man4/dtrace_dtrace.4191
-rw-r--r--share/man/man4/dtrace_fbt.4332
-rw-r--r--share/man/man4/dtrace_kinst.412
-rw-r--r--share/man/man4/dtrace_profile.4129
-rw-r--r--share/man/man4/hwt.43
-rw-r--r--share/man/man4/md.44
-rw-r--r--share/man/man4/snd_uaudio.436
-rw-r--r--share/man/man4/ufshci.4181
-rw-r--r--share/man/man5/pf.conf.522
-rw-r--r--share/man/man5/rc.conf.56
-rw-r--r--share/man/man5/src.conf.536
-rw-r--r--share/man/man5/style.Makefile.58
-rw-r--r--share/man/man7/Makefile1
-rw-r--r--share/man/man7/arch.711
-rw-r--r--share/man/man7/d.7287
-rw-r--r--share/man/man7/intro.75
-rw-r--r--share/man/man7/tracing.715
-rw-r--r--share/man/man8/nanobsd.88
-rw-r--r--share/man/man9/vnode.94
-rw-r--r--share/mk/local.sys.machine.mk4
-rw-r--r--share/termcap/termcap23
-rw-r--r--stand/libsa/zfs/zfsimpl.c52
-rw-r--r--sys/amd64/amd64/apic_vector.S6
-rw-r--r--sys/amd64/amd64/mem.c4
-rw-r--r--sys/amd64/amd64/minidump_machdep.c10
-rw-r--r--sys/amd64/amd64/pmap.c238
-rw-r--r--sys/amd64/amd64/trap.c2
-rw-r--r--sys/amd64/include/param.h5
-rw-r--r--sys/amd64/include/pmap.h20
-rw-r--r--sys/amd64/include/vmparam.h41
-rw-r--r--sys/amd64/pt/pt.c978
-rw-r--r--sys/amd64/pt/pt.h49
-rw-r--r--sys/amd64/vmm/intel/vmx_support.S6
-rw-r--r--sys/arm/arm/pmap-v6.c32
-rw-r--r--sys/arm64/arm64/pmap.c86
-rw-r--r--sys/cddl/boot/zfs/zfsimpl.h2
-rw-r--r--sys/compat/linuxkpi/common/include/linux/slab.h2
-rw-r--r--sys/compat/linuxkpi/common/src/linux_page.c5
-rw-r--r--sys/conf/files13
-rw-r--r--sys/dev/gpio/gpiobus.c24
-rw-r--r--sys/dev/md/md.c6
-rw-r--r--sys/dev/mgb/if_mgb.c2
-rw-r--r--sys/dev/mlx5/mlx5_accel/ipsec.h8
-rw-r--r--sys/dev/mlx5/mlx5_accel/mlx5_ipsec_rxtx.c16
-rw-r--r--sys/dev/mlx5/mlx5_en/mlx5_en_hw_tls_rx.c3
-rw-r--r--sys/dev/mlx5/mlx5_en/mlx5_en_rx.c2
-rw-r--r--sys/dev/qlnx/qlnxe/qlnx_os.c6
-rw-r--r--sys/dev/ufshci/ufshci_private.h4
-rw-r--r--sys/dev/ufshci/ufshci_req_sdb.c45
-rw-r--r--sys/dev/usb/controller/xhci_pci.c7
-rw-r--r--sys/fs/fdescfs/fdesc_vnops.c9
-rw-r--r--sys/fs/msdosfs/msdosfs_vnops.c21
-rw-r--r--sys/fs/p9fs/p9fs_vnops.c8
-rw-r--r--sys/fs/udf/ecma167-udf.h4
-rw-r--r--sys/fs/udf/udf_vfsops.c7
-rw-r--r--sys/fs/udf/udf_vnops.c48
-rw-r--r--sys/i386/conf/GENERIC2
-rw-r--r--sys/i386/conf/GENERIC-NODEBUG2
-rw-r--r--sys/i386/conf/LINT1
-rw-r--r--sys/i386/conf/MINIMAL2
-rw-r--r--sys/i386/conf/PAE2
-rw-r--r--sys/i386/i386/pmap.c12
-rw-r--r--sys/kern/kern_descrip.c2
-rw-r--r--sys/kern/subr_asan.c3
-rw-r--r--sys/kern/subr_trap.c5
-rw-r--r--sys/kern/sys_generic.c6
-rw-r--r--sys/kern/vfs_cache.c13
-rw-r--r--sys/modules/Makefile2
-rw-r--r--sys/modules/pt/Makefile8
-rw-r--r--sys/modules/qlnx/qlnxe/Makefile1
-rw-r--r--sys/net/ethernet.h6
-rw-r--r--sys/net/if_ethersubr.c5
-rw-r--r--sys/net/if_lagg.c1
-rw-r--r--sys/net/pfvar.h6
-rw-r--r--sys/net80211/ieee80211_hostap.c7
-rw-r--r--sys/net80211/ieee80211_ht.c13
-rw-r--r--sys/net80211/ieee80211_vht.c4
-rw-r--r--sys/net80211/ieee80211_vht.h3
-rw-r--r--sys/netinet6/raw_ip6.c3
-rw-r--r--sys/netipsec/ipsec.c6
-rw-r--r--sys/netipsec/ipsec_offload.c25
-rw-r--r--sys/netipsec/ipsec_offload.h16
-rw-r--r--sys/netipsec/key.c2
-rw-r--r--sys/netlink/netlink_message_parser.h3
-rw-r--r--sys/netpfil/ipfilter/netinet/ip_fil_freebsd.c5
-rw-r--r--sys/netpfil/pf/if_pflog.c4
-rw-r--r--sys/netpfil/pf/if_pfsync.c11
-rw-r--r--sys/netpfil/pf/pf.c48
-rw-r--r--sys/netpfil/pf/pf.h3
-rw-r--r--sys/netpfil/pf/pf_ioctl.c52
-rw-r--r--sys/netpfil/pf/pf_lb.c165
-rw-r--r--sys/netpfil/pf/pf_table.c74
-rw-r--r--sys/powerpc/aim/mmu_oea.c3
-rw-r--r--sys/powerpc/aim/mmu_oea64.c3
-rw-r--r--sys/powerpc/aim/mmu_radix.c4
-rw-r--r--sys/powerpc/include/pcb.h10
-rw-r--r--sys/powerpc/include/ucontext.h2
-rw-r--r--sys/powerpc/powerpc/exec_machdep.c39
-rw-r--r--sys/powerpc/powerpc/fpu.c30
-rw-r--r--sys/riscv/riscv/pmap.c2
-rw-r--r--sys/sys/exterrvar.h1
-rw-r--r--sys/sys/param.h2
-rw-r--r--sys/vm/swap_pager.c23
-rw-r--r--sys/vm/vm_domainset.c16
-rw-r--r--sys/vm/vm_kern.c9
-rw-r--r--sys/vm/vm_pagequeue.h6
-rwxr-xr-xtests/ci/tools/freebsdci9
-rw-r--r--tests/sys/kern/Makefile1
-rw-r--r--tests/sys/kern/exterr_test.c108
-rwxr-xr-xtests/sys/netinet6/addr6.sh25
-rw-r--r--tests/sys/netpfil/pf/anchor.sh4
-rw-r--r--tests/sys/netpfil/pf/nat.sh33
-rw-r--r--tests/sys/netpfil/pf/nat64.py15
-rw-r--r--tests/sys/netpfil/pf/rdr.sh2
-rw-r--r--tests/sys/netpfil/pf/route_to.sh117
-rw-r--r--tests/sys/netpfil/pf/utils.subr101
-rw-r--r--tools/test/stress2/misc/all.exclude8
-rwxr-xr-xtools/test/stress2/misc/fullpath2.sh2
-rwxr-xr-xtools/test/stress2/misc/syzkaller80.sh320
-rwxr-xr-xtools/test/stress2/misc/syzkaller81.sh72
-rw-r--r--usr.bin/du/du.16
-rw-r--r--usr.bin/find/find.12
-rw-r--r--usr.bin/fortune/datfiles/freebsd-tips2
-rw-r--r--usr.bin/iscsictl/iscsictl.86
-rw-r--r--usr.bin/last/last.16
-rw-r--r--usr.bin/netstat/netstat.136
-rw-r--r--usr.bin/nfsstat/nfsstat.14
-rw-r--r--usr.bin/procstat/procstat.16
-rw-r--r--usr.bin/sed/sed.111
-rw-r--r--usr.bin/sockstat/sockstat.16
-rw-r--r--usr.bin/sockstat/sockstat.c74
-rw-r--r--usr.bin/top/top.13
-rw-r--r--usr.bin/vmstat/vmstat.86
-rw-r--r--usr.bin/w/w.16
-rw-r--r--usr.bin/wc/wc.16
-rw-r--r--usr.sbin/arp/arp.86
-rwxr-xr-xusr.sbin/bluetooth/bluetooth-config/bluetooth-config.sh8
-rwxr-xr-xusr.sbin/bsdinstall/scripts/wlanconfig8
-rw-r--r--usr.sbin/bsnmpd/tools/bsnmptools/bsnmpget.c6
-rw-r--r--usr.sbin/bsnmpd/tools/libbsnmptools/bsnmptools.c9
-rw-r--r--usr.sbin/bsnmpd/tools/libbsnmptools/bsnmptools.h1
-rw-r--r--usr.sbin/certctl/certctl.810
-rwxr-xr-xusr.sbin/certctl/certctl.sh22
-rw-r--r--usr.sbin/efitable/efitable.84
-rw-r--r--usr.sbin/fwget/Makefile2
-rw-r--r--usr.sbin/fwget/fwget.814
-rwxr-xr-xusr.sbin/fwget/fwget.sh6
-rw-r--r--usr.sbin/fwget/usb/Makefile10
-rwxr-xr-xusr.sbin/fwget/usb/usb43
-rwxr-xr-xusr.sbin/fwget/usb/usb_ralink12
-rw-r--r--usr.sbin/gstat/gstat.82
-rw-r--r--usr.sbin/inetd/inetd.conf4
-rw-r--r--usr.sbin/lastlogin/lastlogin.84
-rw-r--r--usr.sbin/makefs/ffs.c2
-rw-r--r--usr.sbin/makefs/tests/makefs_msdos_tests.sh2
-rw-r--r--usr.sbin/sesutil/sesutil.86
374 files changed, 5448 insertions, 1311 deletions
diff --git a/.github/workflows/checklist.yml b/.github/workflows/checklist.yml
index f5c3ea599abf..7f7b0d51f46e 100644
--- a/.github/workflows/checklist.yml
+++ b/.github/workflows/checklist.yml
@@ -89,6 +89,7 @@ jobs:
/* Loop for each key in "checklist". */
for (const c in checklist)
msg += "- " + c + "<sup>" + checklist[c].join(", ") + "</sup>\n";
+ msg += "\nPlease review CONTRIBUTING.md, then update and push your branch again.\n"
comment_func({
owner: context.repo.owner,
diff --git a/Makefile b/Makefile
index 4afec2a80c60..383430307495 100644
--- a/Makefile
+++ b/Makefile
@@ -103,7 +103,7 @@
#
# See src/UPDATING `COMMON ITEMS' for more complete information.
#
-# If TARGET=machine (e.g. powerpc, arm64, ...) is specified you can
+# If TARGET=machine (e.g. powerpc64, arm64, ...) is specified you can
# cross build world for other machine types using the buildworld target,
# and once the world is built you can cross build a kernel using the
# buildkernel target.
@@ -530,8 +530,7 @@ worlds: .PHONY
# Don't build rarely used, semi-supported architectures unless requested.
#
.if defined(EXTRA_TARGETS)
-# powerpcspe excluded from main list until clang fixed
-EXTRA_ARCHES_powerpc= powerpcspe
+EXTRA_ARCHES_powerpc= powerpc powerpcspe
.endif
TARGETS?= ${TARGET_MACHINE_LIST}
_UNIVERSE_TARGETS= ${TARGETS}
@@ -546,8 +545,7 @@ TOOLCHAINS_amd64= amd64-${_GCC_VERSION}
TOOLCHAINS_arm= armv7-${_GCC_VERSION}
TOOLCHAINS_arm64= aarch64-${_GCC_VERSION}
TOOLCHAINS_i386= i386-${_GCC_VERSION}
-TOOLCHAINS_powerpc= powerpc-${_GCC_VERSION} powerpc64-${_GCC_VERSION}
-TOOLCHAIN_powerpc64= powerpc64-${_GCC_VERSION}
+TOOLCHAINS_powerpc= powerpc64-${_GCC_VERSION}
TOOLCHAINS_riscv= riscv64-${_GCC_VERSION}
.endif
diff --git a/Makefile.inc1 b/Makefile.inc1
index d366be09f497..010f5ac2bb55 100644
--- a/Makefile.inc1
+++ b/Makefile.inc1
@@ -2130,11 +2130,10 @@ create-source-src-package: _pkgbootstrap .PHONY
PKGNAME "src" \
PKGGENNAME "src" \
VERSION "${PKG_VERSION}" \
- DESC "FreeBSD Kernel Sources" \
- COMMENT "FreeBSD Userland Sources" \
PKG_NAME_PREFIX "${PKG_NAME_PREFIX}" \
PKG_MAINTAINER "${PKG_MAINTAINER}" \
PKG_WWW "${PKG_WWW}" \
+ UCLFILES "${SRCDIR}/release/packages/ucl" \
${SRCDIR}/release/packages/template.ucl \
${SSTAGEDIR}/src.ucl
${PKG_CMD} -o ABI=${PKG_ABI} \
@@ -2155,13 +2154,12 @@ create-source-src-sys-package: _pkgbootstrap .PHONY
> ${SSTAGEDIR}/src-sys.plist
${SRCDIR}/release/packages/generate-ucl.lua \
PKGNAME "src-sys" \
- PKGGENNAME "src" \
+ PKGGENNAME "src-sys" \
VERSION "${PKG_VERSION}" \
- DESC "FreeBSD Kernel Sources" \
- COMMENT "FreeBSD Kernel Sources" \
PKG_NAME_PREFIX "${PKG_NAME_PREFIX}" \
PKG_MAINTAINER "${PKG_MAINTAINER}" \
PKG_WWW "${PKG_WWW}" \
+ UCLFILES "${SRCDIR}/release/packages/ucl" \
${SRCDIR}/release/packages/template.ucl \
${SSTAGEDIR}/src-sys.ucl
${PKG_CMD} -o ABI=${PKG_ABI} \
@@ -2226,12 +2224,12 @@ create-dtb-package:
@if [ -f ${KSTAGEDIR}/${DISTDIR}/dtb.plist ]; then \
${SRCDIR}/release/packages/generate-ucl.lua \
PKGNAME "dtb" \
+ PKGGENNAME "dtb" \
VERSION "${PKG_VERSION}" \
- COMMENT "FreeBSD Devicetree Blobs" \
- DESC "FreeBSD Devicetree Blobs" \
PKG_NAME_PREFIX "${PKG_NAME_PREFIX}" \
PKG_MAINTAINER "${PKG_MAINTAINER}" \
PKG_WWW "${PKG_WWW}" \
+ UCLFILES "${SRCDIR}/release/packages/ucl" \
${SRCDIR}/release/packages/template.ucl \
${KSTAGEDIR}/${DISTDIR}/dtb.ucl ; \
awk -F\" ' \
@@ -2257,13 +2255,15 @@ create-kernel-packages-flavor${flavor:C,^""$,${_default_flavor},}: _pkgbootstrap
-v kernel=yes -v _kernconf=${INSTALLKERNEL} ; \
${SRCDIR}/release/packages/generate-ucl.lua \
PKGNAME "kernel-${INSTALLKERNEL:tl}${flavor}" \
+ PKGGENNAME "kernel" \
VERSION "${PKG_VERSION}" \
KERNELDIR "kernel" \
- COMMENT "FreeBSD ${INSTALLKERNEL} kernel ${flavor}" \
- DESC "FreeBSD ${INSTALLKERNEL} kernel ${flavor}" \
+ KERNEL_NAME "${INSTALLKERNEL}" \
+ KERNEL_FLAVOR "${flavor}" \
PKG_NAME_PREFIX "${PKG_NAME_PREFIX}" \
PKG_MAINTAINER "${PKG_MAINTAINER}" \
PKG_WWW "${PKG_WWW}" \
+ UCLFILES "${SRCDIR}/release/packages/ucl" \
${SRCDIR}/release/packages/template.ucl \
${KSTAGEDIR}/${DISTDIR}/kernel.${INSTALLKERNEL}${flavor}.ucl ; \
awk -F\" ' \
@@ -2296,14 +2296,14 @@ create-kernel-packages-extra-flavor${flavor:C,^""$,${_default_flavor},}-${_kerne
PKGNAME "kernel-${_kernel:tl}${flavor}" \
PKGGENNAME "kernel" \
FORCEINCLUDE "kernel${flavor}" \
- UCLFILES "${SRCDIR}/release/packages/" \
VERSION "${PKG_VERSION}" \
+ KERNEL_NAME "${_kernel:tl}" \
+ KERNEL_FLAVOR "${flavor}" \
KERNELDIR "kernel.${_kernel}" \
- DESC "FreeBSD ${_kernel} kernel ${flavor}" \
- COMMENT "FreeBSD ${_kernel} kernel ${flavor}" \
PKG_NAME_PREFIX "${PKG_NAME_PREFIX}" \
PKG_MAINTAINER "${PKG_MAINTAINER}" \
PKG_WWW "${PKG_WWW}" \
+ UCLFILES "${SRCDIR}/release/packages/ucl" \
${SRCDIR}/release/packages/template.ucl \
${KSTAGEDIR}/kernel.${_kernel}/kernel.${_kernel}${flavor}.ucl ; \
awk -F\" ' \
diff --git a/ObsoleteFiles.inc b/ObsoleteFiles.inc
index a5e41d9ac6d6..e5a3da94e127 100644
--- a/ObsoleteFiles.inc
+++ b/ObsoleteFiles.inc
@@ -51,6 +51,9 @@
# xargs -n1 | sort | uniq -d;
# done
+# 20250716: Remove an old manual page, vn(4) was removed in FreeBSD 5.0
+OLD_FILES+=usr/share/man/man4/vn.4.gz
+
# 20250710: share: Delete bitrotted make_*_driver.sh scripts
OLD_FILES+=usr/share/examples/drivers/README
OLD_FILES+=usr/share/examples/drivers/make_device_driver.sh
diff --git a/bin/df/df.1 b/bin/df/df.1
index ceb1bb45babf..2de72e4e3bb2 100644
--- a/bin/df/df.1
+++ b/bin/df/df.1
@@ -26,7 +26,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd March 29, 2023
+.Dd July 16, 2025
.Dt DF 1
.Os
.Sh NAME
@@ -65,7 +65,7 @@ Generate output via
.Xr libxo 3
in a selection of different human and machine readable formats.
See
-.Xr xo_parse_args 3
+.Xr xo_options 7
for details on command line arguments.
.It Fl a
Show all mount points, including those that were mounted with the
@@ -264,7 +264,7 @@ each file or directory name or disk label
.Xr getmntinfo 3 ,
.Xr libxo 3 ,
.Xr localeconv 3 ,
-.Xr xo_parse_args 3 ,
+.Xr xo_options 7 ,
.Xr fstab 5 ,
.Xr mount 8 ,
.Xr pstat 8 ,
diff --git a/bin/ps/ps.1 b/bin/ps/ps.1
index 1c964157f53f..542004453658 100644
--- a/bin/ps/ps.1
+++ b/bin/ps/ps.1
@@ -33,7 +33,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd May 06, 2025
+.Dd July 16, 2025
.Dt PS 1
.Os
.Sh NAME
@@ -194,7 +194,7 @@ Generate output via
.Xr libxo 3
in a selection of different human and machine readable formats.
See
-.Xr xo_parse_args 3
+.Xr xo_options 7
for details on command line arguments.
The default is the traditional text style output.
.It Fl A
@@ -925,7 +925,7 @@ Display information on all system processes:
.Xr kvm 3 ,
.Xr libxo 3 ,
.Xr strftime 3 ,
-.Xr xo_parse_args 3 ,
+.Xr xo_options 7 ,
.Xr mac 4 ,
.Xr procfs 4 ,
.Xr pstat 8 ,
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/dtrace.1 b/cddl/contrib/opensolaris/cmd/dtrace/dtrace.1
index 1836707d72df..da8cbd9ffe50 100644
--- a/cddl/contrib/opensolaris/cmd/dtrace/dtrace.1
+++ b/cddl/contrib/opensolaris/cmd/dtrace/dtrace.1
@@ -20,7 +20,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd June 14, 2025
+.Dd July 16, 2025
.Dt DTRACE 1
.Os
.Sh NAME
@@ -617,6 +617,52 @@ Same as the
flag.
.It Sy dynvarsize Ns = Ns Ar size
Size of the dynamic variable space.
+.Sm off
+.It Sy evaltime = Cm exec | preinit | postinit | main
+.Sm on
+Process create mode.
+When using
+.Fl c Ar cmd
+to start a command,
+.Nm
+will first stop the newly started
+.Ar cmd ,
+evaluate the
+.Xr d 7
+program,
+and then resume the
+.Ar cmd .
+The
+.Cm evaltime
+option controls the exact moment when this happens.
+.Pp
+The following table describes supported modes.
+.Bl -column -offset indent "postinit" "D Program Evaluation Time"
+.It Sy Mode Ta Sy D Program Evaluation Time
+.It Cm exec Ta
+Right at the first instruction of the command
+.Ar cmd
+execution.
+.It Cm preinit Ta
+Before
+.Xr elf 5 Ap s
+.Dq .init
+sections.
+.It Cm postinit Ta
+After
+.Xr elf 5 Ap s
+.Dq .init
+sections.
+Default on
+.Fx .
+.It Cm main Ta
+Before the first instruction of the
+.Fn main
+function.
+.El
+.Pp
+Usually, there is no reason to change the default mode,
+but it might be handy in situations such as shared library tracing.
.It Sy flowindent
Turn on flow indentation.
Same as the
@@ -1221,18 +1267,24 @@ Invalid command line options or arguments were specified.
.El
.Sh SEE ALSO
.Xr cpp 1 ,
+.Xr dwatch 1 ,
.Xr dtrace_audit 4 ,
+.Xr dtrace_dtrace 4 ,
+.Xr dtrace_fbt 4 ,
.Xr dtrace_io 4 ,
.Xr dtrace_ip 4 ,
.Xr dtrace_kinst 4 ,
.Xr dtrace_lockstat 4 ,
.Xr dtrace_proc 4 ,
+.Xr dtrace_profile 4 ,
.Xr dtrace_sched 4 ,
.Xr dtrace_sctp 4 ,
.Xr dtrace_tcp 4 ,
.Xr dtrace_udp 4 ,
.Xr dtrace_udplite 4 ,
.Xr elf 5 ,
+.Xr d 7 ,
+.Xr tracing 7 ,
.Xr SDT 9
.Rs
.%T Solaris Dynamic Tracing Guide
diff --git a/contrib/bsnmp/lib/snmpclient.c b/contrib/bsnmp/lib/snmpclient.c
index b312a37ed3ed..d5d4af998a0c 100644
--- a/contrib/bsnmp/lib/snmpclient.c
+++ b/contrib/bsnmp/lib/snmpclient.c
@@ -981,14 +981,8 @@ open_client_local(const char *path)
char *ptr;
int stype;
- if (snmp_client.chost == NULL) {
- if ((snmp_client.chost = malloc(1 + sizeof(DEFAULT_LOCAL)))
- == NULL) {
- seterr(&snmp_client, "%s", strerror(errno));
- return (-1);
- }
- strcpy(snmp_client.chost, DEFAULT_LOCAL);
- }
+ if (snmp_client.chost == NULL && path == NULL)
+ path = SNMP_DEFAULT_LOCAL;
if (path != NULL) {
if ((ptr = malloc(1 + strlen(path))) == NULL) {
seterr(&snmp_client, "%s", strerror(errno));
@@ -1012,7 +1006,7 @@ open_client_local(const char *path)
snprintf(snmp_client.local_path, sizeof(snmp_client.local_path),
"%s", SNMP_LOCAL_PATH);
- if (mkstemp(snmp_client.local_path) == -1) {
+ if (mktemp(snmp_client.local_path) == NULL) {
seterr(&snmp_client, "%s", strerror(errno));
(void)close(snmp_client.fd);
snmp_client.fd = -1;
diff --git a/contrib/bsnmp/lib/snmpclient.h b/contrib/bsnmp/lib/snmpclient.h
index a19bdb2ea653..662dc7c4a204 100644
--- a/contrib/bsnmp/lib/snmpclient.h
+++ b/contrib/bsnmp/lib/snmpclient.h
@@ -40,6 +40,7 @@
#define SNMP_STRERROR_LEN 200
+#define SNMP_DEFAULT_LOCAL "/var/run/snmpd.sock"
#define SNMP_LOCAL_PATH "/tmp/snmpXXXXXXXXXXXXXX"
diff --git a/contrib/bsnmp/lib/snmppriv.h b/contrib/bsnmp/lib/snmppriv.h
index 5b66992ca985..6ed51cf39369 100644
--- a/contrib/bsnmp/lib/snmppriv.h
+++ b/contrib/bsnmp/lib/snmppriv.h
@@ -44,4 +44,3 @@ enum snmp_code snmp_pdu_decrypt(const struct snmp_pdu *);
#define DEFAULT_HOST "localhost"
#define DEFAULT_PORT "snmp"
-#define DEFAULT_LOCAL "/var/run/snmp.sock"
diff --git a/contrib/bsnmp/snmpd/main.c b/contrib/bsnmp/snmpd/main.c
index 928b84121f82..c77572934d24 100644
--- a/contrib/bsnmp/snmpd/main.c
+++ b/contrib/bsnmp/snmpd/main.c
@@ -42,6 +42,7 @@
#include <sys/un.h>
#include <sys/ucred.h>
#include <sys/uio.h>
+#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
@@ -1509,7 +1510,7 @@ main(int argc, char *argv[])
{
int opt;
FILE *fp;
- int background = 1;
+ bool background = true;
struct tport *p;
const char *prefix = "snmpd";
struct lmodule *m;
@@ -1526,11 +1527,6 @@ main(int argc, char *argv[])
NULL
};
- snmp_printf = snmp_printf_func;
- snmp_error = snmp_error_func;
- snmp_debug = snmp_debug_func;
- asn_error = asn_error_func;
-
while ((opt = getopt(argc, argv, "c:dD:e:hI:l:m:p:")) != EOF)
switch (opt) {
@@ -1539,7 +1535,7 @@ main(int argc, char *argv[])
break;
case 'd':
- background = 0;
+ background = false;
break;
case 'D':
@@ -1601,6 +1597,13 @@ main(int argc, char *argv[])
break;
}
+ if (background) {
+ snmp_printf = snmp_printf_func;
+ snmp_error = snmp_error_func;
+ snmp_debug = snmp_debug_func;
+ asn_error = asn_error_func;
+ }
+
openlog(prefix, LOG_PID | (background ? 0 : LOG_PERROR), LOG_USER);
setlogmask(LOG_UPTO(debug.logpri - 1));
diff --git a/contrib/bsnmp/snmpd/trans_lsock.c b/contrib/bsnmp/snmpd/trans_lsock.c
index fa3bd34d14f0..ca2311be7cc3 100644
--- a/contrib/bsnmp/snmpd/trans_lsock.c
+++ b/contrib/bsnmp/snmpd/trans_lsock.c
@@ -417,7 +417,7 @@ lsock_send(struct tport *tp, const u_char *buf, size_t len,
}
}
- return (sendto(peer->input.fd, buf, len, 0, addr, addrlen));
+ return (sendto(peer->input.fd, buf, len, MSG_NOSIGNAL, addr, addrlen));
}
static void
diff --git a/contrib/elftoolchain/libelf/elf_open.3 b/contrib/elftoolchain/libelf/elf_open.3
index 054036a24935..896bf8455ae5 100644
--- a/contrib/elftoolchain/libelf/elf_open.3
+++ b/contrib/elftoolchain/libelf/elf_open.3
@@ -23,11 +23,12 @@
.\"
.\" $Id: elf_open.3 3743 2019-06-12 19:36:30Z jkoshy $
.\"
-.Dd June 12, 2019
+.Dd July 15, 2025
.Dt ELF_OPEN 3
.Os
.Sh NAME
-.Nm elf_open
+.Nm elf_open ,
+.Nm elf_openmemory
.Nd open ELF objects and ar(1) archives
.Sh LIBRARY
.Lb libelf
diff --git a/contrib/elftoolchain/libelf/gelf_xlatetof.3 b/contrib/elftoolchain/libelf/gelf_xlatetof.3
index 2e5ee0fe15e0..4a7b25c99b5a 100644
--- a/contrib/elftoolchain/libelf/gelf_xlatetof.3
+++ b/contrib/elftoolchain/libelf/gelf_xlatetof.3
@@ -23,13 +23,16 @@
.\"
.\" $Id: gelf_xlatetof.3 3639 2018-10-14 14:07:02Z jkoshy $
.\"
-.Dd October 11, 2018
+.Dd July 15, 2025
.Dt GELF_XLATETOF 3
.Os
.Sh NAME
-.Nm elf32_xlate ,
-.Nm elf64_xlate ,
-.Nm gelf_xlate
+.Nm elf32_xlatetof ,
+.Nm elf32_xlatetom ,
+.Nm elf64_xlatetof ,
+.Nm elf64_xlatetom ,
+.Nm gelf_xlatetof ,
+.Nm gelf_xlatetom
.Nd translate data between files and memory
.Sh LIBRARY
.Lb libelf
diff --git a/contrib/libbegemot/rpoll.c b/contrib/libbegemot/rpoll.c
index c61b84057eba..f5ce43140205 100644
--- a/contrib/libbegemot/rpoll.c
+++ b/contrib/libbegemot/rpoll.c
@@ -285,8 +285,8 @@ poll_register(int fd, poll_f func, void *arg, int mask)
poll_unblocksig();
if(rpoll_trace)
- fprintf(stderr, "poll_register(%d, %p, %p, %#x)->%tu",
- fd, (void *)func, (void *)arg, mask, p - regs);
+ fprintf(stderr, "%s(%d, %p, %p, %#x)->%tu\n", __func__, fd,
+ (void *)func, (void *)arg, mask, p - regs);
return p - regs;
}
@@ -297,7 +297,7 @@ void
poll_unregister(int handle)
{
if(rpoll_trace)
- fprintf(stderr, "poll_unregister(%d)", handle);
+ fprintf(stderr, "%s(%d)\n", __func__, handle);
poll_blocksig();
@@ -399,8 +399,8 @@ poll_start_utimer(unsigned long long usecs, int repeat, timer_f func, void *arg)
resort = 1;
if(rpoll_trace)
- fprintf(stderr, "poll_start_utimer(%llu, %d, %p, %p)->%tu",
- usecs, repeat, (void *)func, (void *)arg, p - tims);
+ fprintf(stderr, "%s(%llu, %d, %p, %p)->%tu\n", __func__, usecs,
+ repeat, (void *)func, (void *)arg, p - tims);
return p - tims;
}
@@ -418,7 +418,7 @@ poll_stop_timer(int handle)
u_int i;
if(rpoll_trace)
- fprintf(stderr, "poll_stop_timer(%d)", handle);
+ fprintf(stderr, "%s(%d)\n", __func__, handle);
tims[handle].func = NULL;
tims_used--;
@@ -597,9 +597,10 @@ poll_dispatch(int wait)
if(mask) {
if(rpoll_trace)
- fprintf(stderr, "poll_dispatch() -- "
- "file %d/%d %x",
- regs[idx].fd, idx, mask);
+ fprintf(stderr,
+ "%s() -- file %d/%d %x\n",
+ __func__, regs[idx].fd,
+ idx, mask);
(*regs[idx].func)(regs[idx].fd, mask, regs[idx].arg);
}
}
@@ -617,7 +618,8 @@ poll_dispatch(int wait)
if(tims[tfd[i]].when > now)
break;
if(rpoll_trace)
- fprintf(stderr, "rpoll_dispatch() -- timeout %d",tfd[i]);
+ fprintf(stderr, "%s() -- timeout %d\n",
+ __func__, tfd[i]);
(*tims[tfd[i]].func)(tfd[i], tims[tfd[i]].arg);
if(tfd[i] < 0)
continue;
diff --git a/lib/libc/gen/fdopendir.c b/lib/libc/gen/fdopendir.c
index df6709fbcb85..9393cbe28f85 100644
--- a/lib/libc/gen/fdopendir.c
+++ b/lib/libc/gen/fdopendir.c
@@ -48,8 +48,16 @@
DIR *
fdopendir(int fd)
{
+ int flags, rc;
- if (_fcntl(fd, F_SETFD, FD_CLOEXEC) == -1)
+ flags = _fcntl(fd, F_GETFD, 0);
+ if (flags == -1)
return (NULL);
+
+ if ((flags & FD_CLOEXEC) == 0) {
+ rc = _fcntl(fd, F_SETFD, flags | FD_CLOEXEC);
+ if (rc == -1)
+ return (NULL);
+ }
return (__opendir_common(fd, DTF_HIDEW | DTF_NODUP, true));
}
diff --git a/lib/libc/powerpc64/gen/_ctx_start.S b/lib/libc/powerpc64/gen/_ctx_start.S
index c2f8abfd6486..98225f9c1138 100644
--- a/lib/libc/powerpc64/gen/_ctx_start.S
+++ b/lib/libc/powerpc64/gen/_ctx_start.S
@@ -34,6 +34,16 @@
ld %r2,8(%r14)
ld %r14,0(%r14)
#else
+ /*
+ * The stack frame was already set up in makecontext(),
+ * so we can safely use the guaranteed fields here.
+ *
+ * Note we do step on the allocated stack frame's TOC,
+ * but since we never return from this function (i.e.
+ * never restore the stack frame) this should be safe.
+ */
+ std %r2,24(%r1) /* save TOC */
+
/* Load global entry point */
mr %r12,%r14
#endif
@@ -41,6 +51,10 @@
blrl /* branch to start function */
mr %r3,%r15 /* pass pointer to ucontext as argument */
nop
+#if defined(_CALL_ELF) && _CALL_ELF != 1
+ /* Restore TOC */
+ ld %r2,24(%r1)
+#endif
bl CNAME(_ctx_done) /* branch to ctxt completion func */
/*
* we should never return from the
diff --git a/lib/libc/powerpc64/gen/makecontext.c b/lib/libc/powerpc64/gen/makecontext.c
index 75c2d40bdd60..9e3a976fa1bd 100644
--- a/lib/libc/powerpc64/gen/makecontext.c
+++ b/lib/libc/powerpc64/gen/makecontext.c
@@ -78,7 +78,7 @@ __makecontext(ucontext_t *ucp, void (*start)(void), int argc, ...)
*/
stackargs = (argc > 8) ? argc - 8 : 0;
sp = (char *) ucp->uc_stack.ss_sp + ucp->uc_stack.ss_size
- - sizeof(uintptr_t)*(stackargs + 2);
+ - sizeof(uintptr_t)*(stackargs + 6);
sp = (char *)((uintptr_t)sp & ~0x1f);
mc = &ucp->uc_mcontext;
@@ -119,6 +119,7 @@ __makecontext(ucontext_t *ucp, void (*start)(void), int argc, ...)
mc->mc_srr0 = *(uintptr_t *)_ctx_start;
#else
mc->mc_srr0 = (uintptr_t) _ctx_start;
+ mc->mc_gpr[12] = (uintptr_t) _ctx_start;/* required for prologue */
#endif
mc->mc_gpr[1] = (uintptr_t) sp; /* new stack pointer */
mc->mc_gpr[14] = (uintptr_t) start; /* r14 <- start */
diff --git a/lib/libc/stdio/fdopen.c b/lib/libc/stdio/fdopen.c
index a0d7b71df782..49ec97eda39d 100644
--- a/lib/libc/stdio/fdopen.c
+++ b/lib/libc/stdio/fdopen.c
@@ -46,7 +46,7 @@ FILE *
fdopen(int fd, const char *mode)
{
FILE *fp;
- int flags, oflags, fdflags, tmp;
+ int flags, oflags, fdflags, rc, tmp;
/*
* File descriptors are a full int, but _file is only a short.
@@ -76,9 +76,19 @@ fdopen(int fd, const char *mode)
if ((fp = __sfp()) == NULL)
return (NULL);
- if ((oflags & O_CLOEXEC) && _fcntl(fd, F_SETFD, FD_CLOEXEC) == -1) {
- fp->_flags = 0;
- return (NULL);
+ if ((oflags & O_CLOEXEC) != 0) {
+ tmp = _fcntl(fd, F_GETFD, 0);
+ if (tmp == -1) {
+ fp->_flags = 0;
+ return (NULL);
+ }
+ if ((tmp & FD_CLOEXEC) == 0) {
+ rc = _fcntl(fd, F_SETFD, tmp | FD_CLOEXEC);
+ if (rc == -1) {
+ fp->_flags = 0;
+ return (NULL);
+ }
+ }
}
fp->_flags = flags;
diff --git a/lib/libc/stdio/freopen.c b/lib/libc/stdio/freopen.c
index f0732b6d6741..048fd30b3193 100644
--- a/lib/libc/stdio/freopen.c
+++ b/lib/libc/stdio/freopen.c
@@ -55,7 +55,7 @@ freopen(const char * __restrict file, const char * __restrict mode,
FILE * __restrict fp)
{
int f;
- int dflags, flags, isopen, oflags, sverrno, wantfd;
+ int dflags, fdflags, flags, isopen, oflags, sverrno, wantfd;
if ((flags = __sflags(mode, &oflags)) == 0) {
sverrno = errno;
@@ -113,8 +113,12 @@ freopen(const char * __restrict file, const char * __restrict mode,
(void) ftruncate(fp->_file, (off_t)0);
if (!(oflags & O_APPEND))
(void) _sseek(fp, (fpos_t)0, SEEK_SET);
- if (oflags & O_CLOEXEC)
- (void) _fcntl(fp->_file, F_SETFD, FD_CLOEXEC);
+ if ((oflags & O_CLOEXEC) != 0) {
+ fdflags = _fcntl(fp->_file, F_GETFD, 0);
+ if (fdflags != -1 && (fdflags & FD_CLOEXEC) == 0)
+ (void) _fcntl(fp->_file, F_SETFD,
+ fdflags | FD_CLOEXEC);
+ }
f = fp->_file;
isopen = 0;
wantfd = -1;
diff --git a/lib/libc/tests/sys/Makefile b/lib/libc/tests/sys/Makefile
index 89d341ff400a..88f8191a16eb 100644
--- a/lib/libc/tests/sys/Makefile
+++ b/lib/libc/tests/sys/Makefile
@@ -7,11 +7,11 @@ ATF_TESTS_C+= brk_test
.endif
ATF_TESTS_C+= cpuset_test
ATF_TESTS_C+= errno_test
+ATF_TESTS_C+= swapcontext_test
ATF_TESTS_C+= queue_test
ATF_TESTS_C+= sendfile_test
-# TODO: clone, lwp_create, lwp_ctl, posix_fadvise, recvmmsg,
-# swapcontext
+# TODO: clone, lwp_create, lwp_ctl, posix_fadvise, recvmmsg
NETBSD_ATF_TESTS_C+= access_test
NETBSD_ATF_TESTS_C+= bind_test
NETBSD_ATF_TESTS_C+= chroot_test
diff --git a/lib/libc/tests/sys/swapcontext_test.c b/lib/libc/tests/sys/swapcontext_test.c
new file mode 100644
index 000000000000..f341a746e515
--- /dev/null
+++ b/lib/libc/tests/sys/swapcontext_test.c
@@ -0,0 +1,63 @@
+/*-
+ * Copyright (c) 2025 Raptor Computing Systems, LLC
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ucontext.h>
+#include <errno.h>
+
+#include <atf-c.h>
+
+#define STACK_SIZE (64ull << 10)
+
+static volatile int callback_reached = 0;
+
+static ucontext_t uctx_save, uctx_switch;
+
+static void swapcontext_callback()
+{
+ // Increment callback reached variable
+ // If this is called multiple times, we will fail the test
+ // If this is not called at all, we will fail the test
+ callback_reached++;
+}
+
+ATF_TC(swapcontext_basic);
+ATF_TC_HEAD(swapcontext_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Verify basic functionality of swapcontext");
+}
+
+ATF_TC_BODY(swapcontext_basic, tc)
+{
+ char *stack;
+ int res;
+
+ stack = malloc(STACK_SIZE);
+ ATF_REQUIRE_MSG(stack != NULL, "malloc failed: %s", strerror(errno));
+ res = getcontext(&uctx_switch);
+ ATF_REQUIRE_MSG(res == 0, "getcontext failed: %s", strerror(errno));
+
+ uctx_switch.uc_stack.ss_sp = stack;
+ uctx_switch.uc_stack.ss_size = STACK_SIZE;
+ uctx_switch.uc_link = &uctx_save;
+ makecontext(&uctx_switch, swapcontext_callback, 0);
+
+ res = swapcontext(&uctx_save, &uctx_switch);
+
+ ATF_REQUIRE_MSG(res == 0, "swapcontext failed: %s", strerror(errno));
+ ATF_REQUIRE_MSG(callback_reached == 1,
+ "callback failed, reached %d times", callback_reached);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, swapcontext_basic);
+
+ return (atf_no_error());
+}
+
diff --git a/lib/libfetch/common.c b/lib/libfetch/common.c
index 0d85ed468284..786d5647d993 100644
--- a/lib/libfetch/common.c
+++ b/lib/libfetch/common.c
@@ -277,13 +277,16 @@ conn_t *
fetch_reopen(int sd)
{
conn_t *conn;
+ int flags;
int opt = 1;
/* allocate and fill connection structure */
if ((conn = calloc(1, sizeof(*conn))) == NULL)
return (NULL);
- fcntl(sd, F_SETFD, FD_CLOEXEC);
- setsockopt(sd, SOL_SOCKET, SO_NOSIGPIPE, &opt, sizeof opt);
+ flags = fcntl(sd, F_GETFD);
+ if (flags != -1 && (flags & FD_CLOEXEC) == 0)
+ (void)fcntl(sd, F_SETFD, flags | FD_CLOEXEC);
+ (void)setsockopt(sd, SOL_SOCKET, SO_NOSIGPIPE, &opt, sizeof(opt));
conn->sd = sd;
++conn->ref;
return (conn);
diff --git a/lib/ncurses/tinfo/Makefile b/lib/ncurses/tinfo/Makefile
index 920bd6e5559c..476df54bb72a 100644
--- a/lib/ncurses/tinfo/Makefile
+++ b/lib/ncurses/tinfo/Makefile
@@ -259,10 +259,18 @@ term.h: MKterm.h.awk edit_cfg.sh Caps Caps-ncurses
sh ${NCURSES_DIR}/include/edit_cfg.sh ${NCURSES_CFG_H} $@.new
mv -f $@.new $@
+# Avoid hard-coding absolute source paths if requested.
+.if ${MK_REPRODUCIBLE_BUILD} != "no"
+NCURSES_SRCTOP=/usr/src
+.else
+NCURSES_SRCTOP=${SRCTOP}
+.endif
+
curses.h: curses.head MKkey_defs.sh Caps Caps-ncurses
cat curses.head > $@.new
AWK=${AWK} _POSIX2_VERSION=199209 sh ${NCURSES_DIR}/include/MKkey_defs.sh \
${NCURSES_DIR}/include/Caps ${NCURSES_DIR}/include/Caps-ncurses >> $@.new
+ sed -i '' 's|${SRCTOP}|${NCURSES_SRCTOP}|g' $@.new
cat ${NCURSES_DIR}/include/curses.wide >> $@.new
cat ${NCURSES_DIR}/include/curses.tail >> $@.new
mv -f $@.new $@
@@ -387,6 +395,7 @@ unctrl.h: unctrl.h.in
terminfo.5: MKterminfo.sh terminfo.head Caps
sh ${NCURSES_DIR}/man/MKterminfo.sh ${NCURSES_DIR}/man/terminfo.head \
${NCURSES_DIR}/include/Caps ${NCURSES_DIR}/man/terminfo.tail >$@
+ sed -i '' 's|${SRCTOP}|${NCURSES_SRCTOP}|g' $@
CLEANFILES+= terminfo.5
diff --git a/libexec/rc/rc b/libexec/rc/rc
index 5ed47d6eac20..db3c3e20ab44 100644
--- a/libexec/rc/rc
+++ b/libexec/rc/rc
@@ -83,9 +83,9 @@ fi
trap "_rc_conf_loaded=false; load_rc_config" ALRM
skip="-s nostart"
-if [ `/sbin/sysctl -n security.jail.jailed` -eq 1 ]; then
+if check_jail jailed; then
skip="$skip -s nojail"
- if [ `/sbin/sysctl -n security.jail.vnet` -ne 1 ]; then
+ if ! check_jail vnet; then
skip="$skip -s nojailvnet"
fi
fi
diff --git a/libexec/rc/rc.d/hostname b/libexec/rc/rc.d/hostname
index 8b26c4f60633..0bc31ccd787e 100755
--- a/libexec/rc/rc.d/hostname
+++ b/libexec/rc/rc.d/hostname
@@ -42,8 +42,8 @@ hostname_start()
# If we are not inside a jail, set the host name.
# If we are inside a jail, set the host name if it is permitted.
#
- if [ `$SYSCTL_N security.jail.jailed` -eq 1 ]; then
- if [ `$SYSCTL_N security.jail.set_hostname_allowed` -eq 0 ]; then
+ if check_jail jailed; then
+ if ! check_jail set_hostname_allowed; then
return
fi
else
diff --git a/libexec/rc/rc.d/pf b/libexec/rc/rc.d/pf
index 0b4c086db22b..46fb085e5175 100755
--- a/libexec/rc/rc.d/pf
+++ b/libexec/rc/rc.d/pf
@@ -38,7 +38,7 @@ pf_fallback()
$pf_program -f "$pf_fallback_rules_file" $pf_flags
else
warn "Loading fallback rules: $pf_fallback_rules"
- echo $pf_fallback_rules | $pf_program -f - $pf_flags
+ echo "$pf_fallback_rules" | $pf_program -f - $pf_flags
fi
}
diff --git a/libexec/rc/rc.d/routing b/libexec/rc/rc.d/routing
index 893acb83cf4a..dd75604125a3 100755
--- a/libexec/rc/rc.d/routing
+++ b/libexec/rc/rc.d/routing
@@ -331,7 +331,7 @@ _check_dynamicrouting()
# copied from /etc/rc
skip="-s nostart"
- if [ `/sbin/sysctl -n security.jail.jailed` -eq 1 ]; then
+ if check_jail jailed; then
skip="$skip -s nojail"
fi
[ -n "$local_startup" ] && find_local_scripts_new
diff --git a/libexec/rc/rc.d/zfs b/libexec/rc/rc.d/zfs
index 26bf3046444b..f88f65c2ec18 100755
--- a/libexec/rc/rc.d/zfs
+++ b/libexec/rc/rc.d/zfs
@@ -18,7 +18,7 @@ required_modules="zfs"
zfs_start_jail()
{
- if [ `$SYSCTL_N security.jail.mount_allowed` -eq 1 ]; then
+ if check_jail mount_allowed; then
zfs mount -a
fi
}
@@ -34,7 +34,7 @@ zfs_start_main()
zfs_start()
{
- if [ `$SYSCTL_N security.jail.jailed` -eq 1 ]; then
+ if check_jail jailed; then
zfs_start_jail
else
zfs_start_main
@@ -54,7 +54,7 @@ zfs_poststart()
zfs_stop_jail()
{
- if [ `$SYSCTL_N security.jail.mount_allowed` -eq 1 ]; then
+ if check_jail mount_allowed; then
zfs unmount -a
fi
}
@@ -67,7 +67,7 @@ zfs_stop_main()
zfs_stop()
{
- if [ `$SYSCTL_N security.jail.jailed` -eq 1 ]; then
+ if check_jail jailed; then
zfs_stop_jail
else
zfs_stop_main
diff --git a/libexec/rc/rc.d/zfsbe b/libexec/rc/rc.d/zfsbe
index f61f3bf097f0..22d53f219679 100755
--- a/libexec/rc/rc.d/zfsbe
+++ b/libexec/rc/rc.d/zfsbe
@@ -64,7 +64,7 @@ activate_bootonce()
be_start()
{
- if [ `$SYSCTL_N security.jail.jailed` -eq 1 ]; then
+ if check_jail jailed; then
:
else
mount -p | while read _dev _mp _type _rest; do
diff --git a/libexec/rc/rc.shutdown b/libexec/rc/rc.shutdown
index 18f67f5ca124..3dfd7a7e0936 100644
--- a/libexec/rc/rc.shutdown
+++ b/libexec/rc/rc.shutdown
@@ -83,9 +83,9 @@ fi
# and perform the operation
#
rcorder_opts="-k shutdown"
-if [ `/sbin/sysctl -n security.jail.jailed` -eq 1 ]; then
+if check_jail jailed; then
rcorder_opts="$rcorder_opts -s nojail"
- if [ `/sbin/sysctl -n security.jail.vnet` -ne 1 ]; then
+ if ! check_jail vnet; then
rcorder_opts="$rcorder_opts -s nojailvnet"
fi
fi
diff --git a/libexec/rc/rc.subr b/libexec/rc/rc.subr
index 2eaf336b5220..a2e2e98a5087 100644
--- a/libexec/rc/rc.subr
+++ b/libexec/rc/rc.subr
@@ -1689,7 +1689,7 @@ $_cpusetcmd $command $rc_flags $command_args"
start)
# We cannot use protect(1) inside jails.
if [ -n "$_oomprotect" ] && [ -f "${PROTECT}" ] &&
- [ "$(sysctl -n security.jail.jailed)" -eq 0 ]; then
+ ! check_jail jailed; then
[ -z "${rc_pid}" ] && eval $_pidcmd
case $_oomprotect in
[Aa][Ll][Ll])
@@ -2671,7 +2671,7 @@ check_required_after()
}
# check_jail mib
-# Return true if security.jail.$mib exists and set to 1.
+# Return true if security.jail.$mib exists and is set to 1.
check_jail()
{
diff --git a/libexec/rc/tests/rc_subr_test.sh b/libexec/rc/tests/rc_subr_test.sh
index 60f77c2c2de3..9931389e7a02 100644
--- a/libexec/rc/tests/rc_subr_test.sh
+++ b/libexec/rc/tests/rc_subr_test.sh
@@ -52,7 +52,7 @@ oomprotect_all_body()
_rc_arg="$4"
setvar "${name}_oomprotect" all
command="/usr/sbin/daemon"
- command_args="-P $pidfile -p $_childpidfile -- /bin/sleep 5"
+ command_args="-P $pidfile -p $_childpidfile -- /bin/sleep 60"
run_rc_command "$_rc_arg"
LITERAL
@@ -92,7 +92,7 @@ oomprotect_yes_body()
setvar "${name}_oomprotect" yes
procname="/bin/sleep"
command="/usr/sbin/daemon"
- command_args="-p $pidfile -- $procname 5"
+ command_args="-p $pidfile -- $procname 60"
run_rc_command "$_rc_arg"
LITERAL
diff --git a/release/Makefile b/release/Makefile
index 84f29983b6c7..7cafd7ddb787 100644
--- a/release/Makefile
+++ b/release/Makefile
@@ -340,8 +340,8 @@ dvd: ${PKGBASE_REPO}
echo hostid_enable=\"NO\" >> ${.TARGET}/etc/rc.conf
echo debug.witness.trace=0 >> ${.TARGET}/etc/sysctl.conf
echo vfs.mountroot.timeout=\"10\" >> ${.TARGET}/boot/loader.conf
- echo loader_brand=\"install\" >> ${.TARGET}/boot/loader.conf
echo kernels_autodetect=\"NO\" >> ${.TARGET}/boot/loader.conf
+ echo loader_brand=\"install\" >> ${.TARGET}/boot/loader.conf
echo loader_menu_multi_user_prompt=\"Installer\" >> ${.TARGET}/boot/loader.conf
cp ${.CURDIR}/rc.local ${.TARGET}/etc
echo "./etc/resolv.conf type=link uname=root gname=wheel mode=0644 link=/tmp/bsdinstall_etc/resolv.conf" >> ${.TARGET}/METALOG
diff --git a/release/amd64/make-memstick.sh b/release/amd64/make-memstick.sh
index cbb80e971343..cec4b27b5b96 100755
--- a/release/amd64/make-memstick.sh
+++ b/release/amd64/make-memstick.sh
@@ -12,6 +12,7 @@
set -e
scriptdir=$(dirname $(realpath $0))
+. ${scriptdir}/../scripts/tools.subr
. ${scriptdir}/../../tools/boot/install-boot.sh
if [ "$(uname -s)" = "FreeBSD" ]; then
@@ -51,7 +52,7 @@ if [ -n "${METALOG}" ]; then
echo "./etc/rc.conf.local type=file uname=root gname=wheel mode=0644" >> ${metalogfilename}
MAKEFSARG=${metalogfilename}
fi
-makefs -D -N ${BASEBITSDIR}/etc -B little -o label=FreeBSD_Install -o version=2 ${2}.part ${MAKEFSARG}
+${MAKEFS} -D -N ${BASEBITSDIR}/etc -B little -o label=FreeBSD_Install -o version=2 ${2}.part ${MAKEFSARG}
rm ${BASEBITSDIR}/etc/fstab
rm ${BASEBITSDIR}/etc/rc.conf.local
if [ -n "${METALOG}" ]; then
@@ -67,10 +68,10 @@ else
make_esp_file ${espfilename} ${fat32min} ${BASEBITSDIR}/boot/loader.efi
fi
-mkimg -s mbr \
+${MKIMG} -s mbr \
-b ${BASEBITSDIR}/boot/mbr \
-p efi:=${espfilename} \
- -p freebsd:-"mkimg -s bsd -b ${BASEBITSDIR}/boot/boot -p freebsd-ufs:=${2}.part" \
+ -p freebsd:-"${MKIMG} -s bsd -b ${BASEBITSDIR}/boot/boot -p freebsd-ufs:=${2}.part" \
-a 2 \
-o ${2}
rm ${espfilename}
diff --git a/release/amd64/mkisoimages.sh b/release/amd64/mkisoimages.sh
index 245beb660c3f..8f7163e05261 100644
--- a/release/amd64/mkisoimages.sh
+++ b/release/amd64/mkisoimages.sh
@@ -25,20 +25,9 @@
set -e
scriptdir=$(dirname $(realpath $0))
+. ${scriptdir}/../scripts/tools.subr
. ${scriptdir}/../../tools/boot/install-boot.sh
-if [ -z $ETDUMP ]; then
- ETDUMP=etdump
-fi
-
-if [ -z $MAKEFS ]; then
- MAKEFS=makefs
-fi
-
-if [ -z $MKIMG ]; then
- MKIMG=mkimg
-fi
-
if [ "$1" = "-b" ]; then
MAKEFSARG="$4"
else
diff --git a/release/arm64/make-memstick.sh b/release/arm64/make-memstick.sh
index 90ff98b394c7..0da59c29635b 100755
--- a/release/arm64/make-memstick.sh
+++ b/release/arm64/make-memstick.sh
@@ -17,6 +17,7 @@ if [ "$(uname -s)" = "FreeBSD" ]; then
fi
scriptdir=$(dirname $(realpath $0))
+. ${scriptdir}/../scripts/tools.subr
. ${scriptdir}/../../tools/boot/install-boot.sh
if [ $# -ne 2 ]; then
@@ -51,7 +52,7 @@ if [ -n "${METALOG}" ]; then
echo "./etc/rc.conf.local type=file uname=root gname=wheel mode=0644" >> ${metalogfilename}
MAKEFSARG=${metalogfilename}
fi
-makefs -D -N ${BASEBITSDIR}/etc -B little -o label=FreeBSD_Install -o version=2 ${2}.part ${MAKEFSARG}
+${MAKEFS} -D -N ${BASEBITSDIR}/etc -B little -o label=FreeBSD_Install -o version=2 ${2}.part ${MAKEFSARG}
rm ${BASEBITSDIR}/etc/fstab
rm ${BASEBITSDIR}/etc/rc.conf.local
if [ -n "${METALOG}" ]; then
@@ -62,7 +63,7 @@ fi
espfilename=$(mktemp /tmp/efiboot.XXXXXX)
make_esp_file ${espfilename} ${fat32min} ${BASEBITSDIR}/boot/loader.efi
-mkimg -s gpt \
+${MKIMG} -s gpt \
-p efi:=${espfilename} \
-p freebsd-ufs:=${2}.part \
-o ${2}
diff --git a/release/arm64/mkisoimages.sh b/release/arm64/mkisoimages.sh
index cb58178ed4b9..46b16f0ce08d 100644
--- a/release/arm64/mkisoimages.sh
+++ b/release/arm64/mkisoimages.sh
@@ -21,20 +21,9 @@
set -e
scriptdir=$(dirname $(realpath $0))
+. ${scriptdir}/../scripts/tools.subr
. ${scriptdir}/../../tools/boot/install-boot.sh
-if [ -z $ETDUMP ]; then
- ETDUMP=etdump
-fi
-
-if [ -z $MAKEFS ]; then
- MAKEFS=makefs
-fi
-
-if [ -z $MKIMG ]; then
- MKIMG=mkimg
-fi
-
if [ "$1" = "-b" ]; then
MAKEFSARG="$4"
else
diff --git a/release/i386/make-memstick.sh b/release/i386/make-memstick.sh
index 7a20be20c026..ad2126b0a8f8 100755
--- a/release/i386/make-memstick.sh
+++ b/release/i386/make-memstick.sh
@@ -11,6 +11,9 @@
set -e
+scriptdir=$(dirname $(realpath $0))
+. ${scriptdir}/../scripts/tools.subr
+
if [ "$(uname -s)" = "FreeBSD" ]; then
PATH=/bin:/usr/bin:/sbin:/usr/sbin
export PATH
@@ -48,16 +51,16 @@ if [ -n "${METALOG}" ]; then
echo "./etc/rc.conf.local type=file uname=root gname=wheel mode=0644" >> ${metalogfilename}
MAKEFSARG=${metalogfilename}
fi
-makefs -D -N ${BASEBITSDIR}/etc -B little -o label=FreeBSD_Install -o version=2 ${2}.part ${MAKEFSARG}
+${MAKEFS} -D -N ${BASEBITSDIR}/etc -B little -o label=FreeBSD_Install -o version=2 ${2}.part ${MAKEFSARG}
rm ${BASEBITSDIR}/etc/fstab
rm ${BASEBITSDIR}/etc/rc.conf.local
if [ -n "${METALOG}" ]; then
rm ${metalogfilename}
fi
-mkimg -s mbr \
+${MKIMG} -s mbr \
-b ${BASEBITSDIR}/boot/mbr \
- -p freebsd:-"mkimg -s bsd -b ${BASEBITSDIR}/boot/boot -p freebsd-ufs:=${2}.part" \
+ -p freebsd:-"${MKIMG} -s bsd -b ${BASEBITSDIR}/boot/boot -p freebsd-ufs:=${2}.part" \
-o ${2}
rm ${2}.part
diff --git a/release/i386/mkisoimages.sh b/release/i386/mkisoimages.sh
index 8f000aae3b17..1918b36eeb44 100644
--- a/release/i386/mkisoimages.sh
+++ b/release/i386/mkisoimages.sh
@@ -24,6 +24,9 @@
set -e
+scriptdir=$(dirname $(realpath $0))
+. ${scriptdir}/../scripts/tools.subr
+
if [ "$1" = "-b" ]; then
MAKEFSARG="$4"
else
@@ -67,7 +70,7 @@ if [ -n "${METALOG}" ]; then
echo "./etc/fstab type=file uname=root gname=wheel mode=0644" >> ${metalogfilename}
MAKEFSARG=${metalogfilename}
fi
-makefs -D -N ${BASEBITSDIR}/etc -t cd9660 $bootable -o rockridge -o label="$LABEL" -o publisher="$publisher" "$NAME" "$MAKEFSARG" "$@"
+${MAKEFS} -D -N ${BASEBITSDIR}/etc -t cd9660 $bootable -o rockridge -o label="$LABEL" -o publisher="$publisher" "$NAME" "$MAKEFSARG" "$@"
rm -f "$BASEBITSDIR/etc/fstab"
if [ -n "${METALOG}" ]; then
rm ${metalogfilename}
diff --git a/release/packages/Makefile.package b/release/packages/Makefile.package
deleted file mode 100644
index c2427aa16945..000000000000
--- a/release/packages/Makefile.package
+++ /dev/null
@@ -1,193 +0,0 @@
-#
-#
-
-acct_COMMENT= System Accounting Utilities
-acct_DESC= System Accounting Utilities
-acpi_COMMENT= ACPI Utilities
-acpi_DESC= ACPI Utilities
-amd_COMMENT= AMD Utilities
-amd_DESC= AMD Utilities
-apm_COMMENT= APM Utilities
-apm_DESC= APM Utilities
-at_COMMENT= AT Utilities
-at_DESC= AT Utilities
-audit_COMMENT= OpenBSM auditing utilities
-audit_DESC= OpenBSM auditing utilities
-autofs_COMMENT= Autofs Utilities
-autofs_DESC= Autofs Utilities
-bhyve_COMMENT= Bhyve Utilities
-bhyve_DESC= Bhyve Utilities
-blocklist_COMMENT= Blocklist Utilities
-blocklist_DESC= Blocklist Utilities
-bluetooth_COMMENT= Bluetooth Utilities
-bluetooth_DESC= Bluetooth Utilities
-bootloader_COMMENT= Bootloader
-bootloader_DESC= Bootloader and configuration files
-bsdinstall_COMMENT= BSDInstall Utilities
-bsdinstall_DESC= BSDInstall Utilities
-bsnmp_COMMENT= BSNMP Utilities
-bsnmp_DESC= BSNMP Utilities
-caroot_COMMENT= SSL Certificates
-caroot_DESC= SSL Certificates
-clang_COMMENT= Clang Utilities
-clang_DESC= Clang Utilities
-clibs_COMMENT= Core C Libraries
-clibs_DESC= Core C Libraries
-certctl_COMMENT= SSL Certificate Utility
-certctl_DESC= SSL Certificate Utility
-console-tools_COMMENT= Console Utilities
-console-tools_DESC= Console Utilities
-cron_COMMENT= cron(8) and crontab(1)
-cron_DESC= cron(8) and crontab(1)
-csh_COMMENT= C Shell
-csh_DESC= C Shell
-ctf-tools_COMMENT= CTF Utilities
-ctf-tools_DESC= CTF Utilities
-cxgbe-tools_COMMENT= Chelsio cxbge Utilities
-cxgbe-tools_DESC= Chelsio cxbge Utilities
-devd_COMMENT= Devd Utility and scripts
-devd_DESC= Devd Utility and scripts
-devmatch_COMMENT= Devmatch Utility
-devmatch_DESC= Devmatch Utility
-dhclient_COMMENT= DHCP Client
-dhclient_DESC= DHCP Client
-dma_COMMENT= DMA Mail Agent Utilities
-dma_DESC= DMA Mail Agent Utilities
-docs_COMMENT= Documentation
-docs_DESC= Documentation
-dtrace_COMMENT= Dtrace Utilities
-dtrace_DESC= Dtrace Utilities
-dwatch_COMMENT= Dwatch Utilities
-dwatch_DESC= Dwatch Utilities
-ee_COMMENT= Easy Editor Utilities
-ee_DESC= Easy Editor Utilities
-efi-tools_COMMENT= UEFI Utilities
-efi-tools_DESC= UEFI Utilities
-examples_COMMENT= Examples in /usr/share/examples
-examples_DESC= Examples in /usr/share/examples
-fd_COMMENT= Floppy disk support
-fd_DESC= Floppy disk support
-fetch_COMMENT= Fetch Utility
-fetch_DESC= Fetch Utility
-firmware-iwm_DESC= iwm(4) firmwares
-firmware-iwm_COMMENT= iwm(4) firmwares
-ftp_COMMENT= FTP Utilities
-ftp_DESC= FTP Utilities
-ftpd_COMMENT= FTP Daemon
-ftpd_DESC= FTP Daemon
-fwget_COMMENT= FWGET Utility
-fwget_DESC= FWGET Utility
-games_COMMENT= Games
-games_DESC= Games
-geom_COMMENT= GEOM Utilitites
-geom_DESC= GEOM Utilitites
-ggate_COMMENT= GEOM Gate Utilities
-ggate_DESC= GEOM Gate Utilities
-hast_COMMENT= Highly Available Storage daemon
-hast_DESC= Highly Available Storage daemon
-hostapd_COMMENT= 802.11 Access Point Daemon an Utilities
-hostapd_DESC= 802.11 Access Point Daemon an Utilities
-hyperv-tools_COMMENT= Microsoft HyperV Utilities
-hyperv-tools_DESC= Microsoft HyperV Utilities
-inetd_COMMENT= Internet super-server
-inetd_DESC= Internet super-server
-jail_COMMENT= Jail Utilities
-jail_DESC= Jail Utilities
-jail-debug_DESCR= Debugging Symbols
-jail-development_DESCR=Development Files
-jail-profile_DESCR= Profiling Libraries
-jail-lib32_DESCR= 32-bit Libraries
-jail-lib32-debug_DESCR=32-bit Debugging Symbols
-jail-lib32-development_DESCR=32-bit Development Files
-jail-lib32-profile_DESCR=32-bit Profiling Libraries
-kerberos_COMMENT= Kerberos Utilities
-kerberos_DESC= Kerberos Utilities
-kerberos-lib_COMMENT= Kerberos Libraries
-kerberos-lib_DESC= Kerberos Libraries
-kernel_COMMENT= FreeBSD Kernel
-kernel_DESC= FreeBSD Kernel
-lp_COMMENT= Printer subsystem
-lp_DESC= Printer subsystem
-manuals_COMMENT= Manual Pages
-manuals_DESC= Manual Pages
-mlx-tools_COMMENT= Mellanox Utilities
-mlx-tools_DESC= Mellanox Utilities
-mtree_COMMENT= MTREE Files
-mtree_DESC= MTREE Files
-netmap_COMMENT= Netmap Library and Utilities
-netmap_DESC= Netmap Library and Utilities
-newsyslog_COMMENT= Newsyslog Utility
-newsyslog_DESC= Newsyslog Utility
-nfs_COMMENT= NFS Utilities
-nfs_DESC= NFS Utilities
-ntp_COMMENT= Network Time Protocol server and client
-ntp_DESC= Network Time Protocol server and client
-nuageinit_COMMENT= CloudInit support scripts
-nuageinit_DESC= CloudInit support scripts
-nvme-tools_COMMENT= NVME Utilities
-nvme-tools_DESC= NVME Utilities
-openssl_COMMENT= OpenSSL Utility
-openssl_DESC= OpenSSL Utility
-openssl-lib_COMMENT= OpenSSL Libraries
-openssl-lib_DESC= OpenSSL Libraries
-pkg-bootstrap_COMMENT= pkg bootstrap Utility
-pkg-bootstrap_DESC= pkg bootstrap Utility
-periodic_COMMENT= Periodic Utility
-periodic_DESC= Periodic Utility
-rc_COMMENT= RC Scripts
-rc_DESC= RC Scripts
-rcmds_COMMENT= BSD/SunOS remote status commands
-rcmds_DESC=\
-The BSD/SunOS remote status commands, which can be used to query or interact\
-with remote hosts over the network. This includes the command-line utilities\
-rwho, ruptime, rup, rusers and rwall and the daemons rwhod, rpc.rstatd,\
-rpc.rusersd, and rpc.rwalld.
-rdma_COMMENT= RDMA Utilities
-rdma_DESC= RDMA Utilities
-rescue_COMMENT= Rescue Utilities
-rescue_DESC= Rescue Utilities
-resolvconf_COMMENT= Resolvconf Utility and scripts
-resolvconf_DESC= Resolvconf Utility and scripts
-runtime_COMMENT= FreeBSD Base System
-runtime_DESC= FreeBSD Base System
-runtime-debug_DESCR= Debugging Symbols
-runtime-development_DESCR=Development Files
-runtime-profile_DESCR= Profiling Libraries
-runtime-lib32_DESCR= 32-bit Libraries
-runtime-lib32-debug_DESCR=32-bit Debugging Symbols
-runtime-lib32-development_DESCR=32-bit Development Files
-runtime-lib32-profile_DESCR=32-bit Profiling Libraries
-sendmail_COMMENT= Sendmail Utilities
-sendmail_DESC= Sendmail Utilities
-smbutils_COMMENT= SMB Utilities
-smbutils_DESC= SMB Utilities
-ssh_COMMENT= Secure Shell Utilities
-ssh_DESC= Secure Shell Utilities
-syscons_COMMENT= Syscons Console
-syscons_DESC= Syscons Console
-syslogd_COMMENT= Syslog Daemon
-syslogd_DESC= Syslog Daemon
-tcpd_COMMENT= TCP Wrapper utilities
-tcpd_DESC= TCP Wrapper utilities
-telnet_COMMENT= Telnet client
-telnet_DESC= Telnet client
-tests_COMMENT= Test Suite
-tests_DESC= Test Suite
-toolchain_COMMENT= Utilities for program development
-toolchain_DESC= Utilities for program development
-ufs_COMMENT= UFS Libraries and Utilities
-ufs_DESC= UFS Libraries and Utilities
-unbound_COMMENT= Unbound DNS Resolver
-unbound_DESC= Unbound DNS Resolver
-utilities_COMMENT= Non-vital programs and libraries
-utilities_DESC= Non-vital programs and libraries
-vi_COMMENT= Vi Editor
-vi_DESC= Vi Editor
-vt_COMMENT= VT fonts and keyboard files
-vt_DESC= VT fonts and keyboard files
-wpa_COMMENT= 802.11 Supplicant
-wpa_DESC= 802.11 Supplicant
-yp_COMMENT= Yellow Pages programs
-yp_DESC= Yellow Pages programs
-zfs_COMMENT= ZFS Libraries and Utilities
-zfs_DESC= ZFS Libraries and Utilities
diff --git a/release/packages/certctl.ucl b/release/packages/certctl.ucl
deleted file mode 100644
index 664a6d139585..000000000000
--- a/release/packages/certctl.ucl
+++ /dev/null
@@ -1,9 +0,0 @@
-scripts: {
- # XXX If pkg picks up a mechanism to detect in the post-install script
- # files being added or removed, we should use it instead to gate the
- # rehash.
- post-install = <<EOD
- [ -x /usr/sbin/certctl ] && env DESTDIR=${PKG_ROOTDIR} \
- /usr/sbin/certctl rehash
-EOD
-}
diff --git a/release/packages/clang-all.ucl b/release/packages/clang-all.ucl
deleted file mode 100644
index 41a697ebe53d..000000000000
--- a/release/packages/clang-all.ucl
+++ /dev/null
@@ -1 +0,0 @@
-licenses = [ NCSA ]
diff --git a/release/packages/generate-ucl.lua b/release/packages/generate-ucl.lua
index ae6ee58dd84a..3d91d11bc42f 100755
--- a/release/packages/generate-ucl.lua
+++ b/release/packages/generate-ucl.lua
@@ -3,33 +3,174 @@
--[[ usage:
generare-ucl.lua [<variablename> <variablevalue>]... <sourceucl> <destucl>
-In the <destucl> files the variable <variablename> (in the form ${variablename}
-in the <sourceucl>) will be expanded to <variablevalue>.
-
-The undefined variables will reamin unmofifier "${variablename}"
+Build a package's UCL configuration by loading the template UCL file
+<sourceucl>, replacing any $VARIABLES in the UCL based on the provided
+variables, then writing the result to <destucl>.
]]--
local ucl = require("ucl")
+-- Give subpackages a special comment and description suffix to indicate what
+-- they contain, so e.g. "foo-man" has " (manual pages)" appended to its
+-- comment. This avoids having to create a separate ucl files for every
+-- subpackage just to set this.
+--
+-- Note that this is not a key table because the order of the pattern matches
+-- is important.
+pkg_suffixes = {
+ {
+ "%-dev%-lib32$", "(32-bit development files)",
+ "This package contains development files for compiling "..
+ "32-bit applications on a 64-bit host."
+ },
+ {
+ "%-dbg%-lib32$", "(32-bit debugging symbols)",
+ "This package contains 32-bit external debugging symbols "..
+ "for use with a source-level debugger.",
+ },
+ {
+ "%-man%-lib32$", "(32-bit manual pages)",
+ "This package contains the online manual pages for 32-bit "..
+ "components on a 64-bit host.",
+ },
+ {
+ "%-lib32$", "(32-bit libraries)",
+ "This package contains 32-bit libraries for running 32-bit "..
+ "applications on a 64-bit host.",
+ },
+ {
+ "%-dev$", "(development files)",
+ "This package contains development files for "..
+ "compiling applications."
+ },
+ {
+ "%-man$", "(manual pages)",
+ "This package contains the online manual pages."
+ },
+ {
+ "%-dbg$", "(debugging symbols)",
+ "This package contains external debugging symbols for use "..
+ "with a source-level debugger.",
+ },
+}
+
+function add_suffixes(obj)
+ local pkgname = obj["name"]
+ for _,pattern in pairs(pkg_suffixes) do
+ if pkgname:match(pattern[1]) ~= nil then
+ obj["comment"] = obj["comment"] .. " " .. pattern[2]
+ obj["desc"] = obj["desc"] .. "\n\n" .. pattern[3]
+ return
+ end
+ end
+end
+
+-- Hardcode a list of packages which don't get the automatic pkggenname
+-- dependency because the base package doesn't exist. We should have a better
+-- way to handle this.
+local no_gen_deps = {
+ ["libcompat-dev"] = true,
+ ["libcompat-dev-lib32"] = true,
+ ["libcompat-man"] = true,
+ ["libcompiler_rt-dev"] = true,
+ ["libcompiler_rt-dev-lib32"] = true,
+ ["liby-dev"] = true,
+ ["liby-dev-lib32"] = true,
+}
+
+-- Return true if the package 'pkgname' should have a dependency on the package
+-- pkggenname.
+function add_gen_dep(pkgname, pkggenname)
+ if pkgname == pkggenname then
+ return false
+ end
+ if pkgname == nil or pkggenname == nil then
+ return false
+ end
+ if no_gen_deps[pkgname] ~= nil then
+ return false
+ end
+ if pkggenname == "kernel" then
+ return false
+ end
+
+ return true
+end
+
+local pkgname = nil
+local pkggenname = nil
+local pkgprefix = nil
+local pkgversion = nil
+
+-- This parser is the output UCL we want to build.
+local parser = ucl.parser()
+
+-- Set any $VARIABLES from the command line in the parser. This causes ucl to
+-- automatically replace them when we load the source ucl.
if #arg < 2 or #arg % 2 ~= 0 then
io.stderr:write(arg[0] .. ": expected an even number of arguments, got " .. #arg)
os.exit(1)
end
-local parser = ucl.parser()
for i = 2, #arg - 2, 2 do
- parser:register_variable(arg[i - 1], arg[i])
+ local varname = arg[i - 1]
+ local varvalue = arg[i]
+
+ if varname == "PKGNAME" and #varvalue > 0 then
+ pkgname = varvalue
+ elseif varname == "PKGGENNAME" and #varvalue > 0 then
+ pkggenname = varvalue
+ elseif varname == "VERSION" and #varvalue > 0 then
+ pkgversion = varvalue
+ elseif varname == "PKG_NAME_PREFIX" and #varvalue > 0 then
+ pkgprefix = varvalue
+ end
+
+ parser:register_variable(varname, varvalue)
end
+
+-- Load the source ucl file.
local res,err = parser:parse_file(arg[#arg - 1])
if not res then
io.stderr:write(arg[0] .. ": fail to parse("..arg[#arg - 1].."): "..err)
os.exit(1)
end
+
+local obj = parser:get_object()
+
+-- If pkgname is different from pkggenname, add a dependency on pkggenname.
+-- This means that e.g. -dev packages depend on their respective base package.
+if add_gen_dep(pkgname, pkggenname) then
+ if obj["deps"] == nil then
+ obj["deps"] = {}
+ end
+ obj["deps"][pkggenname] = {
+ ["version"] = pkgversion,
+ ["origin"] = "base"
+ }
+end
+
+-- If PKG_NAME_PREFIX is provided, rewrite the names of dependency packages.
+-- We can't do this in UCL since variable substitution doesn't work in array
+-- keys.
+if pkgprefix ~= nil and obj["deps"] ~= nil then
+ newdeps = {}
+ for dep, opts in pairs(obj["deps"]) do
+ local newdep = pkgprefix .. "-" .. dep
+ newdeps[newdep] = opts
+ end
+ obj["deps"] = newdeps
+end
+
+-- Add comment and desc suffix.
+add_suffixes(obj)
+
+-- Write the output file.
local f,err = io.open(arg[#arg], "w")
if not f then
io.stderr:write(arg[0] .. ": fail to open("..arg[#arg].."): ".. err)
os.exit(1)
end
-local obj = parser:get_object()
+
f:write(ucl.to_format(obj, 'ucl', true))
f:close()
diff --git a/release/packages/generate-ucl.sh b/release/packages/generate-ucl.sh
index b7d7bad35023..3078185a3c4e 100755
--- a/release/packages/generate-ucl.sh
+++ b/release/packages/generate-ucl.sh
@@ -3,8 +3,8 @@
#
main() {
- desc=
- comment=
+ outname=""
+ origname=""
debug=
uclsource=
while getopts "do:s:u:" arg; do
@@ -31,73 +31,26 @@ main() {
shift $(( ${OPTIND} - 1 ))
case "${outname}" in
- bootloader)
- pkgdeps=""
- ;;
- certctl)
- pkgdeps="caroot openssl"
- ;;
- clang)
- pkgdeps="lld libcompiler_rt-dev"
- ;;
- periodic)
- pkgdeps="cron"
- ;;
- rcmds)
- # the RPC daemons require rpcbind
- pkgdeps="utilities"
- ;;
-
- # -dev packages that have no corresponding non-dev package
- # as a dependency.
- libcompat-dev|libcompiler_rt-dev|liby-dev)
- outname=${outname%%-dev}
- _descr="Development Files"
- ;;
- libcompat-lib32_dev|libcompiler_rt-lib32_dev|liby-lib32_dev)
- outname=${outname%%-lib32_dev}
- _descr="32-bit Libraries, Development Files"
- ;;
- libcompat-man|libelftc-man)
- outname=${outname%%-man}
- _descr="Manual Pages"
+ *-dev)
+ outname="${outname%%-dev}"
;;
- utilities)
- uclfile="${uclfile}"
+ *-dbg)
+ outname="${outname%%-dbg}"
;;
- runtime)
- outname="runtime"
- _descr="$(make -C ${srctree}/release/packages -f Makefile.package -V ${outname}_DESCR)"
+ *-dev-lib32)
+ outname="${outname%%-dev-lib32}"
;;
- *-lib32_dev)
- outname="${outname%%-lib32_dev}"
- _descr="32-bit Libraries, Development Files"
- pkgdeps="${outname}"
+ *-dbg-lib32)
+ outname="${outname%%-dbg-lib32}"
;;
- *-lib32_dbg)
- outname="${outname%%-lib32_dbg}"
- _descr="32-bit Libraries, Debugging Symbols"
- pkgdeps="${outname}"
+ *-man-lib32)
+ outname="${outname%%-man-lib32}"
;;
*-lib32)
outname="${outname%%-lib32}"
- _descr="32-bit Libraries"
- pkgdeps="${outname}"
- ;;
- *-dev)
- outname="${outname%%-dev}"
- _descr="Development Files"
- pkgdeps="${outname}"
- ;;
- *-dbg)
- outname="${outname%%-dbg}"
- _descr="Debugging Symbols"
- pkgdeps="${outname}"
;;
*-man)
outname="${outname%%-man}"
- _descr="Manual Pages"
- pkgdeps="${outname}"
;;
${origname})
;;
@@ -107,22 +60,16 @@ main() {
;;
esac
- desc="$(make -C ${srctree}/release/packages -f Makefile.package -V ${outname}_DESC)"
- comment="$(make -C ${srctree}/release/packages -f Makefile.package -V ${outname}_COMMENT)"
-
uclsource="${srctree}/release/packages/template.ucl"
if [ -n "${debug}" ]; then
echo ""
echo "==============================================================="
echo "DEBUG:"
- echo "_descr=${_descr}"
echo "outname=${outname}"
echo "origname=${origname}"
echo "srctree=${srctree}"
echo "uclfile=${uclfile}"
- echo "desc=${desc}"
- echo "comment=${comment}"
echo "vital=${vital}"
echo "cp ${uclsource} -> ${uclfile}"
echo "==============================================================="
@@ -131,38 +78,17 @@ main() {
echo ""
fi
- [ -z "${comment}" ] && comment="${outname} package"
- [ -n "${_descr}" ] && comment="${comment} (${_descr})"
- [ -z "${desc}" ] && desc="${outname} package"
-
- cp "${uclsource}" "${uclfile}"
- if [ -n "${pkgdeps}" ]; then
- echo 'deps: {' >> ${uclfile}
- for dep in ${pkgdeps}; do
- cat <<EOF >> ${uclfile}
- ${PKG_NAME_PREFIX}-${dep}: {
- origin: "base",
- version: "${PKG_VERSION}"
- }
-EOF
- done
- echo '}' >> ${uclfile}
- fi
cap_arg="$( make -f ${srctree}/share/mk/bsd.endian.mk -VCAP_MKDB_ENDIAN )"
${srctree}/release/packages/generate-ucl.lua \
VERSION "${PKG_VERSION}" \
PKGNAME "${origname}" \
PKGGENNAME "${outname}" \
PKG_NAME_PREFIX "${PKG_NAME_PREFIX}" \
- COMMENT "${comment}" \
- DESC "${desc}" \
CAP_MKDB_ENDIAN "${cap_arg}" \
PKG_WWW "${PKG_WWW}" \
PKG_MAINTAINER "${PKG_MAINTAINER}" \
- UCLFILES "${srctree}/release/packages/" \
- ${uclfile} ${uclfile}
-
- return 0
+ UCLFILES "${srctree}/release/packages/ucl" \
+ ${uclsource} ${uclfile}
}
main "${@}"
diff --git a/release/packages/lld-all.ucl b/release/packages/lld-all.ucl
deleted file mode 100644
index 41a697ebe53d..000000000000
--- a/release/packages/lld-all.ucl
+++ /dev/null
@@ -1 +0,0 @@
-licenses = [ NCSA ]
diff --git a/release/packages/lldb-all.ucl b/release/packages/lldb-all.ucl
deleted file mode 100644
index 41a697ebe53d..000000000000
--- a/release/packages/lldb-all.ucl
+++ /dev/null
@@ -1 +0,0 @@
-licenses = [ NCSA ]
diff --git a/release/packages/ssh-all.ucl b/release/packages/ssh-all.ucl
deleted file mode 100644
index 4f78d80fa68e..000000000000
--- a/release/packages/ssh-all.ucl
+++ /dev/null
@@ -1 +0,0 @@
-licenses = [ ISCL ]
diff --git a/release/packages/template.ucl b/release/packages/template.ucl
index a65f58868118..faa48effe1ad 100644
--- a/release/packages/template.ucl
+++ b/release/packages/template.ucl
@@ -4,7 +4,7 @@
name = "${PKG_NAME_PREFIX}-${PKGNAME}"
origin = "base"
version = "${VERSION}"
-comment = "${COMMENT}"
+comment = "${PKGNAME} package"
categories = [ base ]
maintainer = "${PKG_MAINTAINER}"
www = "${PKG_WWW}"
@@ -12,8 +12,8 @@ prefix = "/"
licenselogic = "single"
licenses = [ BSD2CLAUSE ]
desc = <<EOD
-${DESC}
+${PKGNAME} package
EOD
-.include(try=true,duplicate=rewrite) "${UCLFILES}/${PKGGENNAME}-all.ucl"
+.include(try=false,duplicate=rewrite) "${UCLFILES}/${PKGGENNAME}-all.ucl"
.include(try=true,duplicate=rewrite) "${UCLFILES}/${PKGNAME}.ucl"
.include(try=true,duplicate=rewrite) "${UCLFILES}/${FORCEINCLUDE}.ucl"
diff --git a/release/packages/ucl/acct-all.ucl b/release/packages/ucl/acct-all.ucl
new file mode 100644
index 000000000000..ac4bd8868511
--- /dev/null
+++ b/release/packages/ucl/acct-all.ucl
@@ -0,0 +1,4 @@
+comment = "System Accounting Utilities"
+desc = <<EOD
+System Accounting Utilities
+EOD
diff --git a/release/packages/ucl/acpi-all.ucl b/release/packages/ucl/acpi-all.ucl
new file mode 100644
index 000000000000..70ea39fc3862
--- /dev/null
+++ b/release/packages/ucl/acpi-all.ucl
@@ -0,0 +1,4 @@
+comment = "ACPI Utilities"
+desc = <<EOD
+ACPI Utilities
+EOD
diff --git a/release/packages/ucl/amd-all.ucl b/release/packages/ucl/amd-all.ucl
new file mode 100644
index 000000000000..e2bc7cfc1b2a
--- /dev/null
+++ b/release/packages/ucl/amd-all.ucl
@@ -0,0 +1,4 @@
+comment = "AMD Utilities"
+desc = <<EOD
+AMD Utilities
+EOD
diff --git a/release/packages/ucl/apm-all.ucl b/release/packages/ucl/apm-all.ucl
new file mode 100644
index 000000000000..bf1b40000805
--- /dev/null
+++ b/release/packages/ucl/apm-all.ucl
@@ -0,0 +1,4 @@
+comment = "APM Utilities"
+desc = <<EOD
+APM Utilities
+EOD
diff --git a/release/packages/ucl/at-all.ucl b/release/packages/ucl/at-all.ucl
new file mode 100644
index 000000000000..c15642737b36
--- /dev/null
+++ b/release/packages/ucl/at-all.ucl
@@ -0,0 +1,4 @@
+comment = "AT Utilities"
+desc = <<EOD
+AT Utilities
+EOD
diff --git a/release/packages/ucl/audit-all.ucl b/release/packages/ucl/audit-all.ucl
new file mode 100644
index 000000000000..e0f3d4bf1675
--- /dev/null
+++ b/release/packages/ucl/audit-all.ucl
@@ -0,0 +1,4 @@
+comment = "OpenBSM auditing utilities"
+desc = <<EOD
+OpenBSM auditing utilities
+EOD
diff --git a/release/packages/ucl/autofs-all.ucl b/release/packages/ucl/autofs-all.ucl
new file mode 100644
index 000000000000..0e3e8d2336ca
--- /dev/null
+++ b/release/packages/ucl/autofs-all.ucl
@@ -0,0 +1,4 @@
+comment = "Autofs Utilities"
+desc = <<EOD
+Autofs Utilities
+EOD
diff --git a/release/packages/ucl/bhyve-all.ucl b/release/packages/ucl/bhyve-all.ucl
new file mode 100644
index 000000000000..2b20ca9a716f
--- /dev/null
+++ b/release/packages/ucl/bhyve-all.ucl
@@ -0,0 +1,4 @@
+comment = "Bhyve Utilities"
+desc = <<EOD
+Bhyve Utilities
+EOD
diff --git a/release/packages/ucl/blocklist-all.ucl b/release/packages/ucl/blocklist-all.ucl
new file mode 100644
index 000000000000..03330a417af9
--- /dev/null
+++ b/release/packages/ucl/blocklist-all.ucl
@@ -0,0 +1,4 @@
+comment = "Blocklist Utilities"
+desc = <<EOD
+Blocklist Utilities
+EOD
diff --git a/release/packages/ucl/bluetooth-all.ucl b/release/packages/ucl/bluetooth-all.ucl
new file mode 100644
index 000000000000..c139d9056a14
--- /dev/null
+++ b/release/packages/ucl/bluetooth-all.ucl
@@ -0,0 +1,4 @@
+comment = "Bluetooth Utilities"
+desc = <<EOD
+Bluetooth Utilities
+EOD
diff --git a/release/packages/ucl/bootloader-all.ucl b/release/packages/ucl/bootloader-all.ucl
new file mode 100644
index 000000000000..c5690e85c7ba
--- /dev/null
+++ b/release/packages/ucl/bootloader-all.ucl
@@ -0,0 +1,4 @@
+comment = "Bootloader"
+desc = <<EOD
+Bootloader and configuration files
+EOD
diff --git a/release/packages/ucl/bsdinstall-all.ucl b/release/packages/ucl/bsdinstall-all.ucl
new file mode 100644
index 000000000000..4c4586dcc702
--- /dev/null
+++ b/release/packages/ucl/bsdinstall-all.ucl
@@ -0,0 +1,4 @@
+comment = "BSDInstall Utilities"
+desc = <<EOD
+BSDInstall Utilities
+EOD
diff --git a/release/packages/ucl/bsnmp-all.ucl b/release/packages/ucl/bsnmp-all.ucl
new file mode 100644
index 000000000000..9b80310c0617
--- /dev/null
+++ b/release/packages/ucl/bsnmp-all.ucl
@@ -0,0 +1,4 @@
+comment = "BSNMP Utilities"
+desc = <<EOD
+BSNMP Utilities
+EOD
diff --git a/release/packages/ucl/caroot-all.ucl b/release/packages/ucl/caroot-all.ucl
new file mode 100644
index 000000000000..151c1f18ae39
--- /dev/null
+++ b/release/packages/ucl/caroot-all.ucl
@@ -0,0 +1,4 @@
+comment = "SSL Certificates"
+desc = <<EOD
+SSL Certificates
+EOD
diff --git a/release/packages/ucl/caroot.ucl b/release/packages/ucl/caroot.ucl
new file mode 100644
index 000000000000..4d2b52d300fc
--- /dev/null
+++ b/release/packages/ucl/caroot.ucl
@@ -0,0 +1,10 @@
+deps {
+ "certctl": {
+ version = "${VERSION}"
+ origin = "base"
+ }
+}
+scripts: {
+ post-install = "/usr/sbin/certctl -D${PKG_ROOTDIR}/ rehash"
+ post-uninstall = "/usr/sbin/certctl -D${PKG_ROOTDIR}/ rehash"
+}
diff --git a/release/packages/ucl/ccdconfig-all.ucl b/release/packages/ucl/ccdconfig-all.ucl
new file mode 100644
index 000000000000..76ba9d64db61
--- /dev/null
+++ b/release/packages/ucl/ccdconfig-all.ucl
@@ -0,0 +1,5 @@
+comment = "Concatenated disk driver (ccd) configuration utility"
+desc = <<EOD
+ccdconfig(8) is used to configure the concatenated disk driver, ccd(4).
+ccdconfig(8) may also be started on boot using the "ccd" rc(8) service.
+EOD
diff --git a/release/packages/ucl/certctl-all.ucl b/release/packages/ucl/certctl-all.ucl
new file mode 100644
index 000000000000..b4bc5ae261c5
--- /dev/null
+++ b/release/packages/ucl/certctl-all.ucl
@@ -0,0 +1,4 @@
+comment = "SSL Certificate Utility"
+desc = <<EOD
+SSL Certificate Utility
+EOD
diff --git a/release/packages/ucl/certctl.ucl b/release/packages/ucl/certctl.ucl
new file mode 100644
index 000000000000..7f7adec83159
--- /dev/null
+++ b/release/packages/ucl/certctl.ucl
@@ -0,0 +1,6 @@
+deps {
+ "openssl": {
+ version = "${VERSION}"
+ origin = "base"
+ }
+}
diff --git a/release/packages/ucl/clang-all.ucl b/release/packages/ucl/clang-all.ucl
new file mode 100644
index 000000000000..3f79f0acb229
--- /dev/null
+++ b/release/packages/ucl/clang-all.ucl
@@ -0,0 +1,5 @@
+comment = "Clang Utilities"
+desc = <<EOD
+Clang Utilities
+EOD
+licenses = [ NCSA ]
diff --git a/release/packages/ucl/clang.ucl b/release/packages/ucl/clang.ucl
new file mode 100644
index 000000000000..956b769a1ee7
--- /dev/null
+++ b/release/packages/ucl/clang.ucl
@@ -0,0 +1,11 @@
+deps {
+ "lld" {
+ version = "${VERSION}"
+ origin = "base"
+ }
+
+ "libcompiler_rt-dev" {
+ version = "${VERSION}"
+ origin = "base"
+ }
+}
diff --git a/release/packages/ucl/clibs-all.ucl b/release/packages/ucl/clibs-all.ucl
new file mode 100644
index 000000000000..69ae018d4d1f
--- /dev/null
+++ b/release/packages/ucl/clibs-all.ucl
@@ -0,0 +1,4 @@
+comment = "Core C Libraries"
+desc = <<EOD
+Core C Libraries
+EOD
diff --git a/release/packages/clibs.ucl b/release/packages/ucl/clibs.ucl
index 093fbb60248a..093fbb60248a 100644
--- a/release/packages/clibs.ucl
+++ b/release/packages/ucl/clibs.ucl
diff --git a/release/packages/ucl/console-tools-all.ucl b/release/packages/ucl/console-tools-all.ucl
new file mode 100644
index 000000000000..53f31b2a9937
--- /dev/null
+++ b/release/packages/ucl/console-tools-all.ucl
@@ -0,0 +1,4 @@
+comment = "Console Utilities"
+desc = <<EOD
+Console Utilities
+EOD
diff --git a/release/packages/ucl/cron-all.ucl b/release/packages/ucl/cron-all.ucl
new file mode 100644
index 000000000000..d9edf6bfde52
--- /dev/null
+++ b/release/packages/ucl/cron-all.ucl
@@ -0,0 +1,4 @@
+comment = "cron(8) and crontab(1)"
+desc = <<EOD
+cron(8) and crontab(1)
+EOD
diff --git a/release/packages/ucl/csh-all.ucl b/release/packages/ucl/csh-all.ucl
new file mode 100644
index 000000000000..df4dc71f8dd5
--- /dev/null
+++ b/release/packages/ucl/csh-all.ucl
@@ -0,0 +1,4 @@
+comment = "C Shell"
+desc = <<EOD
+C Shell
+EOD
diff --git a/release/packages/ucl/ctf-tools-all.ucl b/release/packages/ucl/ctf-tools-all.ucl
new file mode 100644
index 000000000000..38ca769f6109
--- /dev/null
+++ b/release/packages/ucl/ctf-tools-all.ucl
@@ -0,0 +1,4 @@
+comment = "CTF Utilities"
+desc = <<EOD
+CTF Utilities
+EOD
diff --git a/release/packages/ucl/ctl-all.ucl b/release/packages/ucl/ctl-all.ucl
new file mode 100644
index 000000000000..d24ffabea1a0
--- /dev/null
+++ b/release/packages/ucl/ctl-all.ucl
@@ -0,0 +1,4 @@
+comment = "CAM Target Layer"
+desc = <<EOD
+The CAM Target Layer allows CAM to export storage targets, e.g. via iSCSI.
+EOD
diff --git a/release/packages/ucl/cxgbe-tools-all.ucl b/release/packages/ucl/cxgbe-tools-all.ucl
new file mode 100644
index 000000000000..e2f6132f7ef9
--- /dev/null
+++ b/release/packages/ucl/cxgbe-tools-all.ucl
@@ -0,0 +1,4 @@
+comment = "Chelsio cxbge Utilities"
+desc = <<EOD
+Chelsio cxbge Utilities
+EOD
diff --git a/release/packages/ucl/devd-all.ucl b/release/packages/ucl/devd-all.ucl
new file mode 100644
index 000000000000..dc7d162a1930
--- /dev/null
+++ b/release/packages/ucl/devd-all.ucl
@@ -0,0 +1,4 @@
+comment = "Devd Utility and scripts"
+desc = <<EOD
+Devd Utility and scripts
+EOD
diff --git a/release/packages/ucl/devmatch-all.ucl b/release/packages/ucl/devmatch-all.ucl
new file mode 100644
index 000000000000..02dc903fd422
--- /dev/null
+++ b/release/packages/ucl/devmatch-all.ucl
@@ -0,0 +1,4 @@
+comment = "Devmatch Utility"
+desc = <<EOD
+Devmatch Utility
+EOD
diff --git a/release/packages/ucl/dhclient-all.ucl b/release/packages/ucl/dhclient-all.ucl
new file mode 100644
index 000000000000..6785366aea5e
--- /dev/null
+++ b/release/packages/ucl/dhclient-all.ucl
@@ -0,0 +1,4 @@
+comment = "DHCP Client"
+desc = <<EOD
+DHCP Client
+EOD
diff --git a/release/packages/ucl/dma-all.ucl b/release/packages/ucl/dma-all.ucl
new file mode 100644
index 000000000000..e8824acf7a36
--- /dev/null
+++ b/release/packages/ucl/dma-all.ucl
@@ -0,0 +1,4 @@
+comment = "DMA Mail Agent Utilities"
+desc = <<EOD
+DMA Mail Agent Utilities
+EOD
diff --git a/release/packages/ucl/docs-all.ucl b/release/packages/ucl/docs-all.ucl
new file mode 100644
index 000000000000..7159d3f8f4ec
--- /dev/null
+++ b/release/packages/ucl/docs-all.ucl
@@ -0,0 +1,4 @@
+comment = "Documentation"
+desc = <<EOD
+Documentation
+EOD
diff --git a/release/packages/ucl/dtb-all.ucl b/release/packages/ucl/dtb-all.ucl
new file mode 100644
index 000000000000..cc5c1c60f062
--- /dev/null
+++ b/release/packages/ucl/dtb-all.ucl
@@ -0,0 +1,4 @@
+comment = "FreeBSD Devicetree Blobs"
+desc = <<EOD
+FreeBSD Devicetree Blobs
+EOD
diff --git a/release/packages/ucl/dtrace-all.ucl b/release/packages/ucl/dtrace-all.ucl
new file mode 100644
index 000000000000..fb36816123c5
--- /dev/null
+++ b/release/packages/ucl/dtrace-all.ucl
@@ -0,0 +1,4 @@
+comment = "Dtrace Utilities"
+desc = <<EOD
+Dtrace Utilities
+EOD
diff --git a/release/packages/ucl/dwatch-all.ucl b/release/packages/ucl/dwatch-all.ucl
new file mode 100644
index 000000000000..5f7e0fb764ce
--- /dev/null
+++ b/release/packages/ucl/dwatch-all.ucl
@@ -0,0 +1,4 @@
+comment = "Dwatch Utilities"
+desc = <<EOD
+Dwatch Utilities
+EOD
diff --git a/release/packages/ucl/ee-all.ucl b/release/packages/ucl/ee-all.ucl
new file mode 100644
index 000000000000..c003942ad3a9
--- /dev/null
+++ b/release/packages/ucl/ee-all.ucl
@@ -0,0 +1,4 @@
+comment = "Easy Editor Utilities"
+desc = <<EOD
+Easy Editor Utilities
+EOD
diff --git a/release/packages/ucl/efi-tools-all.ucl b/release/packages/ucl/efi-tools-all.ucl
new file mode 100644
index 000000000000..51d5e12189dd
--- /dev/null
+++ b/release/packages/ucl/efi-tools-all.ucl
@@ -0,0 +1,4 @@
+comment = "UEFI Utilities"
+desc = <<EOD
+UEFI Utilities
+EOD
diff --git a/release/packages/ucl/examples-all.ucl b/release/packages/ucl/examples-all.ucl
new file mode 100644
index 000000000000..93f0aee16187
--- /dev/null
+++ b/release/packages/ucl/examples-all.ucl
@@ -0,0 +1,4 @@
+comment = "Examples in /usr/share/examples"
+desc = <<EOD
+Examples in /usr/share/examples
+EOD
diff --git a/release/packages/ucl/fd-all.ucl b/release/packages/ucl/fd-all.ucl
new file mode 100644
index 000000000000..7092449174e3
--- /dev/null
+++ b/release/packages/ucl/fd-all.ucl
@@ -0,0 +1,4 @@
+comment = "Floppy disk support"
+desc = <<EOD
+Utilities for formatting and managing floppy disks supported by fdc(4).
+EOD
diff --git a/release/packages/ucl/fetch-all.ucl b/release/packages/ucl/fetch-all.ucl
new file mode 100644
index 000000000000..f9a3e03e6fa4
--- /dev/null
+++ b/release/packages/ucl/fetch-all.ucl
@@ -0,0 +1,4 @@
+comment = "Fetch Utility"
+desc = <<EOD
+Fetch Utility
+EOD
diff --git a/release/packages/ucl/firmware-iwm-all.ucl b/release/packages/ucl/firmware-iwm-all.ucl
new file mode 100644
index 000000000000..6fec27c15351
--- /dev/null
+++ b/release/packages/ucl/firmware-iwm-all.ucl
@@ -0,0 +1,4 @@
+comment = "iwm(4) firmwares"
+desc = <<EOD
+iwm(4) firmwares
+EOD
diff --git a/release/packages/ucl/ftp-all.ucl b/release/packages/ucl/ftp-all.ucl
new file mode 100644
index 000000000000..6275bc46e657
--- /dev/null
+++ b/release/packages/ucl/ftp-all.ucl
@@ -0,0 +1,4 @@
+comment = "FTP Utilities"
+desc = <<EOD
+FTP Utilities
+EOD
diff --git a/release/packages/ucl/ftpd-all.ucl b/release/packages/ucl/ftpd-all.ucl
new file mode 100644
index 000000000000..cbaa078123d5
--- /dev/null
+++ b/release/packages/ucl/ftpd-all.ucl
@@ -0,0 +1,4 @@
+comment = "FTP Daemon"
+desc = <<EOD
+FTP Daemon
+EOD
diff --git a/release/packages/ucl/fwget-all.ucl b/release/packages/ucl/fwget-all.ucl
new file mode 100644
index 000000000000..7a6f9dff5cc9
--- /dev/null
+++ b/release/packages/ucl/fwget-all.ucl
@@ -0,0 +1,4 @@
+comment = "FWGET Utility"
+desc = <<EOD
+FWGET Utility
+EOD
diff --git a/release/packages/ucl/games-all.ucl b/release/packages/ucl/games-all.ucl
new file mode 100644
index 000000000000..747638fe6a8f
--- /dev/null
+++ b/release/packages/ucl/games-all.ucl
@@ -0,0 +1,4 @@
+comment = "Games"
+desc = <<EOD
+Games
+EOD
diff --git a/release/packages/ucl/geom-all.ucl b/release/packages/ucl/geom-all.ucl
new file mode 100644
index 000000000000..6d80b4458f64
--- /dev/null
+++ b/release/packages/ucl/geom-all.ucl
@@ -0,0 +1,4 @@
+comment = "GEOM Utilitites"
+desc = <<EOD
+GEOM Utilitites
+EOD
diff --git a/release/packages/ucl/ggate-all.ucl b/release/packages/ucl/ggate-all.ucl
new file mode 100644
index 000000000000..0d0b984b440e
--- /dev/null
+++ b/release/packages/ucl/ggate-all.ucl
@@ -0,0 +1,4 @@
+comment = "GEOM Gate Utilities"
+desc = <<EOD
+GEOM Gate Utilities
+EOD
diff --git a/release/packages/ucl/hast-all.ucl b/release/packages/ucl/hast-all.ucl
new file mode 100644
index 000000000000..b2441ddb6866
--- /dev/null
+++ b/release/packages/ucl/hast-all.ucl
@@ -0,0 +1,4 @@
+comment = "Highly Available Storage daemon"
+desc = <<EOD
+Highly Available Storage daemon
+EOD
diff --git a/release/packages/ucl/hostapd-all.ucl b/release/packages/ucl/hostapd-all.ucl
new file mode 100644
index 000000000000..c2e0d0c0bd11
--- /dev/null
+++ b/release/packages/ucl/hostapd-all.ucl
@@ -0,0 +1,4 @@
+comment = "802.11 Access Point Daemon an Utilities"
+desc = <<EOD
+802.11 Access Point Daemon an Utilities
+EOD
diff --git a/release/packages/ucl/hyperv-tools-all.ucl b/release/packages/ucl/hyperv-tools-all.ucl
new file mode 100644
index 000000000000..e16fd5b4b053
--- /dev/null
+++ b/release/packages/ucl/hyperv-tools-all.ucl
@@ -0,0 +1,4 @@
+comment = "Microsoft HyperV Utilities"
+desc = <<EOD
+Microsoft HyperV Utilities
+EOD
diff --git a/release/packages/ucl/inetd-all.ucl b/release/packages/ucl/inetd-all.ucl
new file mode 100644
index 000000000000..731769bdc399
--- /dev/null
+++ b/release/packages/ucl/inetd-all.ucl
@@ -0,0 +1,4 @@
+comment = "Internet super-server"
+desc = <<EOD
+Internet super-server
+EOD
diff --git a/release/packages/ucl/ipf-all.ucl b/release/packages/ucl/ipf-all.ucl
new file mode 100644
index 000000000000..bd1bec5232de
--- /dev/null
+++ b/release/packages/ucl/ipf-all.ucl
@@ -0,0 +1,4 @@
+comment = "IP Filter (ipf) packet filter management tools"
+desc = <<EOD
+IP Filter (ipf) is a stateful packet filter for IPv4 and IPv6 networks.
+EOD
diff --git a/release/packages/ucl/ipfw-all.ucl b/release/packages/ucl/ipfw-all.ucl
new file mode 100644
index 000000000000..0884d48aa071
--- /dev/null
+++ b/release/packages/ucl/ipfw-all.ucl
@@ -0,0 +1,4 @@
+comment = "ipfw (IP firewall) management utilities"
+desc = <<EOD
+ipfw provides stateful packet filtering, NAT and traffic shaping for IP traffic.
+EOD
diff --git a/release/packages/ucl/iscsi-all.ucl b/release/packages/ucl/iscsi-all.ucl
new file mode 100644
index 000000000000..e81961cb40a5
--- /dev/null
+++ b/release/packages/ucl/iscsi-all.ucl
@@ -0,0 +1,6 @@
+comment = "iSCSI target, initiator, and management tools"
+desc = <<EOD
+iSCSI allows a block device to be exported from one system to another over a
+network. This package provides the iSCSI target and initiator and associated
+management tools.
+EOD
diff --git a/release/packages/ucl/jail-all.ucl b/release/packages/ucl/jail-all.ucl
new file mode 100644
index 000000000000..da844b500ad5
--- /dev/null
+++ b/release/packages/ucl/jail-all.ucl
@@ -0,0 +1,4 @@
+comment = "Jail Utilities"
+desc = <<EOD
+Jail Utilities
+EOD
diff --git a/release/packages/ucl/kerberos-all.ucl b/release/packages/ucl/kerberos-all.ucl
new file mode 100644
index 000000000000..6fb7f059296b
--- /dev/null
+++ b/release/packages/ucl/kerberos-all.ucl
@@ -0,0 +1,4 @@
+comment = "Kerberos Utilities"
+desc = <<EOD
+Kerberos Utilities
+EOD
diff --git a/release/packages/ucl/kerberos-lib-all.ucl b/release/packages/ucl/kerberos-lib-all.ucl
new file mode 100644
index 000000000000..ab769ee16f96
--- /dev/null
+++ b/release/packages/ucl/kerberos-lib-all.ucl
@@ -0,0 +1,4 @@
+comment = "Kerberos Libraries"
+desc = <<EOD
+Kerberos Libraries
+EOD
diff --git a/release/packages/ucl/kernel-all.ucl b/release/packages/ucl/kernel-all.ucl
new file mode 100644
index 000000000000..31671602a947
--- /dev/null
+++ b/release/packages/ucl/kernel-all.ucl
@@ -0,0 +1,4 @@
+comment = "FreeBSD ${KERNEL_NAME} Kernel ${KERNEL_FLAVOR}"
+desc = <<EOD
+FreeBSD ${KERNEL_NAME} Kernel ${KERNEL_FLAVOR}
+EOD
diff --git a/release/packages/ucl/lib9p-all.ucl b/release/packages/ucl/lib9p-all.ucl
new file mode 100644
index 000000000000..76a5b8de4596
--- /dev/null
+++ b/release/packages/ucl/lib9p-all.ucl
@@ -0,0 +1,5 @@
+comment = "9P network protocol library"
+desc = <<EOD
+lib9p implements the server side of the 9p2000, 9p2000.u and 9p2000.L revisions
+of the 9P protocol
+EOD
diff --git a/release/packages/ucl/libarchive-all.ucl b/release/packages/ucl/libarchive-all.ucl
new file mode 100644
index 000000000000..9b98404b3235
--- /dev/null
+++ b/release/packages/ucl/libarchive-all.ucl
@@ -0,0 +1,4 @@
+comment = "Archive handling library"
+desc = <<EOD
+libarchive allows applications to read and write archive files of various types.
+EOD
diff --git a/release/packages/ucl/libbegemot-all.ucl b/release/packages/ucl/libbegemot-all.ucl
new file mode 100644
index 000000000000..7a2f19df8e0e
--- /dev/null
+++ b/release/packages/ucl/libbegemot-all.ucl
@@ -0,0 +1,5 @@
+comment = "rpoll(3) interface for event-driven I/O"
+desc = <<EOD
+libbegemot provides rpoll(3), a simplified interface for handling event-driven
+I/O programming.
+EOD
diff --git a/release/packages/ucl/libblocksruntime-all.ucl b/release/packages/ucl/libblocksruntime-all.ucl
new file mode 100644
index 000000000000..818c32174a6c
--- /dev/null
+++ b/release/packages/ucl/libblocksruntime-all.ucl
@@ -0,0 +1,4 @@
+comment = "LLVM BlocksRuntime library"
+desc = <<EOD
+The LLVM libBlocksRuntime library.
+EOD
diff --git a/release/packages/ucl/libbsdstat-all.ucl b/release/packages/ucl/libbsdstat-all.ucl
new file mode 100644
index 000000000000..4db0059827a0
--- /dev/null
+++ b/release/packages/ucl/libbsdstat-all.ucl
@@ -0,0 +1,5 @@
+comment = "Periodic statistics library"
+desc = <<EOD
+libbsdstat is a library for managing and display periodically collected
+statistics.
+EOD
diff --git a/release/packages/ucl/libbsm-all.ucl b/release/packages/ucl/libbsm-all.ucl
new file mode 100644
index 000000000000..0a60ada09075
--- /dev/null
+++ b/release/packages/ucl/libbsm-all.ucl
@@ -0,0 +1,6 @@
+comment = "Basic Security Module (BSM) audit library"
+desc = <<EOD
+The libbsm library routines provide an interface to BSM audit record streams,
+allowing both the parsing of existing audit streams, as well as the creation of
+new audit records and streams.
+EOD
diff --git a/release/packages/ucl/libbz2-all.ucl b/release/packages/ucl/libbz2-all.ucl
new file mode 100644
index 000000000000..c8141bcb1d11
--- /dev/null
+++ b/release/packages/ucl/libbz2-all.ucl
@@ -0,0 +1,5 @@
+comment = "bzip2 compression library"
+desc = <<EOD
+libbz2 allows applications to compress and decompress data using the bzip2
+compression algorithm.
+EOD
diff --git a/release/packages/ucl/libcasper-all.ucl b/release/packages/ucl/libcasper-all.ucl
new file mode 100644
index 000000000000..b25a82a32050
--- /dev/null
+++ b/release/packages/ucl/libcasper-all.ucl
@@ -0,0 +1,5 @@
+comment = "Casper library"
+desc = <<EOD
+The libcasper library provides for the control of application capabilities
+through the casper process.
+EOD
diff --git a/release/packages/ucl/libcompat-all.ucl b/release/packages/ucl/libcompat-all.ucl
new file mode 100644
index 000000000000..a562f155dc5f
--- /dev/null
+++ b/release/packages/ucl/libcompat-all.ucl
@@ -0,0 +1,4 @@
+comment = "Compatibility library"
+desc = <<EOD
+libcompat provides implementations of some obsolete library functions.
+EOD
diff --git a/release/packages/ucl/libcompiler_rt-all.ucl b/release/packages/ucl/libcompiler_rt-all.ucl
new file mode 100644
index 000000000000..f21e629ac88c
--- /dev/null
+++ b/release/packages/ucl/libcompiler_rt-all.ucl
@@ -0,0 +1,4 @@
+comment = "LLVM compiler_rt library"
+desc = <<EOD
+The libcompiler_rt library from LLVM.
+EOD
diff --git a/release/packages/ucl/libcuse-all.ucl b/release/packages/ucl/libcuse-all.ucl
new file mode 100644
index 000000000000..de972d4b8d3a
--- /dev/null
+++ b/release/packages/ucl/libcuse-all.ucl
@@ -0,0 +1,5 @@
+comment = "Userland character device library"
+desc = <<EOD
+The libcuse library contains functions to create a character device in
+userspace.
+EOD
diff --git a/release/packages/ucl/libdwarf-all.ucl b/release/packages/ucl/libdwarf-all.ucl
new file mode 100644
index 000000000000..4226dbfee592
--- /dev/null
+++ b/release/packages/ucl/libdwarf-all.ucl
@@ -0,0 +1,6 @@
+comment = "DWARF access library"
+desc = <<EOD
+The DWARF Access Library provides functions that allow an application to read
+and write debugging information in object files. The format of debugging
+information accessible through this API is defined by the DWARF standard.
+EOD
diff --git a/release/packages/ucl/libevent1-all.ucl b/release/packages/ucl/libevent1-all.ucl
new file mode 100644
index 000000000000..511e077233d2
--- /dev/null
+++ b/release/packages/ucl/libevent1-all.ucl
@@ -0,0 +1,4 @@
+comment = "Private libevent1 library"
+desc = <<EOD
+A private library used by applications in the base system.
+EOD
diff --git a/release/packages/ucl/libexecinfo-all.ucl b/release/packages/ucl/libexecinfo-all.ucl
new file mode 100644
index 000000000000..8a0c110381be
--- /dev/null
+++ b/release/packages/ucl/libexecinfo-all.ucl
@@ -0,0 +1,5 @@
+comment = "NetBSD stack backtrace library"
+desc = <<EOD
+libexecinfo provides the backtrace(3) interface to allow an application to
+examine its current call stack.
+EOD
diff --git a/release/packages/ucl/libipt-all.ucl b/release/packages/ucl/libipt-all.ucl
new file mode 100644
index 000000000000..eb0ef6a32d40
--- /dev/null
+++ b/release/packages/ucl/libipt-all.ucl
@@ -0,0 +1,6 @@
+comment = "Intel(R) Processor Trace decoder library"
+desc = <<EOD
+The Intel Processor Trace (Intel PT) Decoder Library is Intel's reference
+implementation for decoding Intel PT. It can be used as a standalone library
+or it can be partially or fully integrated into your tool.
+EOD
diff --git a/release/packages/ucl/libldns-all.ucl b/release/packages/ucl/libldns-all.ucl
new file mode 100644
index 000000000000..55de2701bbb8
--- /dev/null
+++ b/release/packages/ucl/libldns-all.ucl
@@ -0,0 +1,6 @@
+comment="NLnet Labs LDNS library"
+desc = <<EOD
+The goal of ldns is to simplify DNS programming in C. ldns supports all
+low-level DNS and DNSSEC operations. It also defines a higher level API which
+allows a programmer to for instance create or sign packets.
+EOD
diff --git a/release/packages/ucl/liblzma-all.ucl b/release/packages/ucl/liblzma-all.ucl
new file mode 100644
index 000000000000..0b1bfcbcecc6
--- /dev/null
+++ b/release/packages/ucl/liblzma-all.ucl
@@ -0,0 +1,5 @@
+comment = "XZ LZMA library"
+desc = <<EOD
+liblzma allows applications to compress and decompress data using the XZ
+compression algorithm.
+EOD
diff --git a/release/packages/ucl/libmagic-all.ucl b/release/packages/ucl/libmagic-all.ucl
new file mode 100644
index 000000000000..2a29aacb260d
--- /dev/null
+++ b/release/packages/ucl/libmagic-all.ucl
@@ -0,0 +1,5 @@
+comment = "Magic number recognition library"
+desc = <<EOD
+libmagic allows an application to identity data using the magic(5) magic number
+database.
+EOD
diff --git a/release/packages/ucl/libopencsd-all.ucl b/release/packages/ucl/libopencsd-all.ucl
new file mode 100644
index 000000000000..af46292dceed
--- /dev/null
+++ b/release/packages/ucl/libopencsd-all.ucl
@@ -0,0 +1,5 @@
+comment = "ARM CoreSight Trace Decode Library"
+desc = <<EOD
+This library provides an API suitable for the decode of ARM CoreSight
+trace streams.
+EOD
diff --git a/release/packages/ucl/libpathconv-all.ucl b/release/packages/ucl/libpathconv-all.ucl
new file mode 100644
index 000000000000..872d34a24e6a
--- /dev/null
+++ b/release/packages/ucl/libpathconv-all.ucl
@@ -0,0 +1,5 @@
+comment = "Library for handling relative and absolute pathnames"
+desc = <<EOD
+libpathconv provides the abs2rel() and rel2abs() functions to convert between
+absolute and relative pathnames.
+EOD
diff --git a/release/packages/ucl/librpcsec_gss-all.ucl b/release/packages/ucl/librpcsec_gss-all.ucl
new file mode 100644
index 000000000000..67f481e9e9b5
--- /dev/null
+++ b/release/packages/ucl/librpcsec_gss-all.ucl
@@ -0,0 +1,5 @@
+comment = "RPC GSS-API authentication library"
+desc = <<EOD
+librpcsec_gss provides an API to allow applications to interact with the
+RPCSEC_GSS security mechanism.
+EOD
diff --git a/release/packages/ucl/librss-all.ucl b/release/packages/ucl/librss-all.ucl
new file mode 100644
index 000000000000..3c09025356a8
--- /dev/null
+++ b/release/packages/ucl/librss-all.ucl
@@ -0,0 +1,5 @@
+comment = "Receive-side scaling library"
+desc = <<EOD
+The librss library and the functions it provides are used for both fetching the
+system RSS configuration and interacting with RSS aware sockets.
+EOD
diff --git a/release/packages/ucl/libsdp-all.ucl b/release/packages/ucl/libsdp-all.ucl
new file mode 100644
index 000000000000..31f04e089470
--- /dev/null
+++ b/release/packages/ucl/libsdp-all.ucl
@@ -0,0 +1,5 @@
+comment = "Bluetooth Service Discovery Protocol library"
+desc = <<EOD
+libsdp allows applications to interact with the Bluetooth Service Discovery
+Protocol.
+EOD
diff --git a/release/packages/ucl/libsqlite3-all.ucl b/release/packages/ucl/libsqlite3-all.ucl
new file mode 100644
index 000000000000..55ac00863bf1
--- /dev/null
+++ b/release/packages/ucl/libsqlite3-all.ucl
@@ -0,0 +1,4 @@
+comment = "Private SQLite library"
+desc = <<EOD
+A private version of SQLite for use by applications in the base system.
+EOD
diff --git a/release/packages/ucl/libstdbuf-all.ucl b/release/packages/ucl/libstdbuf-all.ucl
new file mode 100644
index 000000000000..d85f2d3b70f2
--- /dev/null
+++ b/release/packages/ucl/libstdbuf-all.ucl
@@ -0,0 +1,6 @@
+comment = "Preloaded library to change standard streams initial buffering"
+desc = <<EOD
+The libstdbuf library is meant to be preloaded with the LD_PRELOAD environment
+variable to as to change the initial buffering of standard input, standard
+output and standard error streams.
+EOD
diff --git a/release/packages/ucl/libstdthreads-all.ucl b/release/packages/ucl/libstdthreads-all.ucl
new file mode 100644
index 000000000000..5af147ea5ca7
--- /dev/null
+++ b/release/packages/ucl/libstdthreads-all.ucl
@@ -0,0 +1,4 @@
+comment = "C11 threading library"
+desc = <<EOD
+libstdthreads provides the thread-control interface defined in the C99 standard.
+EOD
diff --git a/release/packages/ucl/libthread_db-all.ucl b/release/packages/ucl/libthread_db-all.ucl
new file mode 100644
index 000000000000..ba2164a3f211
--- /dev/null
+++ b/release/packages/ucl/libthread_db-all.ucl
@@ -0,0 +1,5 @@
+comment = "Library for interacting with threaded processes"
+desc = <<EOD
+libthread_db is used by the debugger to examine and interact with a
+multithreaded process being debugger.
+EOD
diff --git a/release/packages/ucl/libucl-all.ucl b/release/packages/ucl/libucl-all.ucl
new file mode 100644
index 000000000000..d04c2109df06
--- /dev/null
+++ b/release/packages/ucl/libucl-all.ucl
@@ -0,0 +1,5 @@
+comment = "Private Universal Configuration Library (UCL) library"
+desc = <<EOD
+A private library for reading and writing UCL files, for used by applications
+in the base system.
+EOD
diff --git a/release/packages/ucl/libufs-all.ucl b/release/packages/ucl/libufs-all.ucl
new file mode 100644
index 000000000000..d86a84bbd637
--- /dev/null
+++ b/release/packages/ucl/libufs-all.ucl
@@ -0,0 +1,8 @@
+comment = "Low-level access to UFS filesystems"
+desc = <<EOD
+The libufs library and the functions it provides are used for implementing
+utilities which need to access a UFS file system at a low level from userland.
+Facilities provided are used to implement utilities such as newfs(8) and
+dumpfs(8). The libufs library is designed to be simple, and to provide
+functions that are traditionally useful to have.
+EOD
diff --git a/release/packages/ucl/libvgl-all.ucl b/release/packages/ucl/libvgl-all.ucl
new file mode 100644
index 000000000000..fea63d807de0
--- /dev/null
+++ b/release/packages/ucl/libvgl-all.ucl
@@ -0,0 +1,13 @@
+comment = "Video Graphics Library"
+desc = <<EOD
+libvgl is a library that enables the programmer access to the graphics modes
+supported by the console driver (syscons). The library takes care of
+programming the actual video hardware, and provides a number of simple
+functions to do various graphic operations. There is also support for a mouse
+via the standard mouse system in FreeBSD, including the ability to
+transparently have a mouse pointer superimposed on the graphic image currently
+being worked on. The library takes care of screen switching by storing the
+current image in memory before switching to another virtual console, and
+restoring when the user switches back. This allows several graphic
+applications at once, but on different virtual consoles.
+EOD
diff --git a/release/packages/ucl/libvmmapi-all.ucl b/release/packages/ucl/libvmmapi-all.ucl
new file mode 100644
index 000000000000..976fb1bfce47
--- /dev/null
+++ b/release/packages/ucl/libvmmapi-all.ucl
@@ -0,0 +1,4 @@
+comment = "Front-end to vmm(4) virtualization driver"
+desc = <<EOD
+libvmmapi provides an interface for applications to access the vmm(4) driver.
+EOD
diff --git a/release/packages/ucl/liby-all.ucl b/release/packages/ucl/liby-all.ucl
new file mode 100644
index 000000000000..575aeda0a1ef
--- /dev/null
+++ b/release/packages/ucl/liby-all.ucl
@@ -0,0 +1,5 @@
+comment = "YACC library"
+desc = <<EOD
+liby provides default implementations of main() and yyerror() for use with
+applications which use yacc(1).
+EOD
diff --git a/release/packages/ucl/libyaml-all.ucl b/release/packages/ucl/libyaml-all.ucl
new file mode 100644
index 000000000000..f98a5a39362f
--- /dev/null
+++ b/release/packages/ucl/libyaml-all.ucl
@@ -0,0 +1,5 @@
+comment = "Private YAML library"
+desc = <<EOD
+The libprivateyaml library is used by the FreeBSD base system to parse YAML
+files. This library is not intended for use outside of the base system.
+EOD
diff --git a/release/packages/ucl/libzfs-all.ucl b/release/packages/ucl/libzfs-all.ucl
new file mode 100644
index 000000000000..bd53521f3aa0
--- /dev/null
+++ b/release/packages/ucl/libzfs-all.ucl
@@ -0,0 +1,5 @@
+comment = "ZFS filesystem library"
+desc = <<EOD
+libzfs allows applications to manage ZFS pools and filesystems. Several
+libraries which libzfs requires are also provided.
+EOD
diff --git a/release/packages/ucl/lld-all.ucl b/release/packages/ucl/lld-all.ucl
new file mode 100644
index 000000000000..03daf1b235e6
--- /dev/null
+++ b/release/packages/ucl/lld-all.ucl
@@ -0,0 +1,6 @@
+comment = "ELF linker from the LLVM project"
+desc = <<EOD
+ld.lld is the ELF linker provided by LLVM.
+EOD
+
+licenses = [ NCSA ]
diff --git a/release/packages/ucl/lldb-all.ucl b/release/packages/ucl/lldb-all.ucl
new file mode 100644
index 000000000000..da481c026981
--- /dev/null
+++ b/release/packages/ucl/lldb-all.ucl
@@ -0,0 +1,6 @@
+comment = "LLVM debugger"
+desc = <<EOD
+lldb is a source-level debugger from the LLVM project.
+EOD
+
+licenses = [ NCSA ]
diff --git a/release/packages/ucl/locales-all.ucl b/release/packages/ucl/locales-all.ucl
new file mode 100644
index 000000000000..6fc53ab10fca
--- /dev/null
+++ b/release/packages/ucl/locales-all.ucl
@@ -0,0 +1,4 @@
+comment = "Locale definitions"
+desc = <<EOD
+Provides the locale definitions (LC_*) for supported locales.
+EOD
diff --git a/release/packages/ucl/lp-all.ucl b/release/packages/ucl/lp-all.ucl
new file mode 100644
index 000000000000..c400038458d0
--- /dev/null
+++ b/release/packages/ucl/lp-all.ucl
@@ -0,0 +1,4 @@
+comment = "Printer subsystem"
+desc = <<EOD
+Printer subsystem
+EOD
diff --git a/release/packages/ucl/manuals-all.ucl b/release/packages/ucl/manuals-all.ucl
new file mode 100644
index 000000000000..9acfd90159ae
--- /dev/null
+++ b/release/packages/ucl/manuals-all.ucl
@@ -0,0 +1,4 @@
+comment = "Manual Pages"
+desc = <<EOD
+Manual Pages
+EOD
diff --git a/release/packages/ucl/mlx-tools-all.ucl b/release/packages/ucl/mlx-tools-all.ucl
new file mode 100644
index 000000000000..4af47252c71d
--- /dev/null
+++ b/release/packages/ucl/mlx-tools-all.ucl
@@ -0,0 +1,4 @@
+comment = "Mellanox Utilities"
+desc = <<EOD
+Mellanox Utilities
+EOD
diff --git a/release/packages/ucl/mtree-all.ucl b/release/packages/ucl/mtree-all.ucl
new file mode 100644
index 000000000000..b921c51a6afb
--- /dev/null
+++ b/release/packages/ucl/mtree-all.ucl
@@ -0,0 +1,4 @@
+comment = "MTREE Files"
+desc = <<EOD
+MTREE Files
+EOD
diff --git a/release/packages/ucl/natd-all.ucl b/release/packages/ucl/natd-all.ucl
new file mode 100644
index 000000000000..db5103c1d591
--- /dev/null
+++ b/release/packages/ucl/natd-all.ucl
@@ -0,0 +1,4 @@
+comment = "Network Address Translation (NAT) daemon for ipfw"
+desc = <<EOD
+natd provides userland NAT support for ipfw using divert(4) sockets.
+EOD
diff --git a/release/packages/ucl/netmap-all.ucl b/release/packages/ucl/netmap-all.ucl
new file mode 100644
index 000000000000..e0c0c65b8fb8
--- /dev/null
+++ b/release/packages/ucl/netmap-all.ucl
@@ -0,0 +1,4 @@
+comment = "Netmap Library and Utilities"
+desc = <<EOD
+Netmap Library and Utilities
+EOD
diff --git a/release/packages/ucl/newsyslog-all.ucl b/release/packages/ucl/newsyslog-all.ucl
new file mode 100644
index 000000000000..e52b34dbdcba
--- /dev/null
+++ b/release/packages/ucl/newsyslog-all.ucl
@@ -0,0 +1,4 @@
+comment = "Newsyslog Utility"
+desc = <<EOD
+Newsyslog Utility
+EOD
diff --git a/release/packages/ucl/nfs-all.ucl b/release/packages/ucl/nfs-all.ucl
new file mode 100644
index 000000000000..a53d2f028975
--- /dev/null
+++ b/release/packages/ucl/nfs-all.ucl
@@ -0,0 +1,4 @@
+comment = "NFS Utilities"
+desc = <<EOD
+NFS Utilities
+EOD
diff --git a/release/packages/ucl/ntp-all.ucl b/release/packages/ucl/ntp-all.ucl
new file mode 100644
index 000000000000..c01ae91c31cf
--- /dev/null
+++ b/release/packages/ucl/ntp-all.ucl
@@ -0,0 +1,4 @@
+comment = "Network Time Protocol server and client"
+desc = <<EOD
+Network Time Protocol server and client
+EOD
diff --git a/release/packages/ucl/nuageinit-all.ucl b/release/packages/ucl/nuageinit-all.ucl
new file mode 100644
index 000000000000..4d510b799fa7
--- /dev/null
+++ b/release/packages/ucl/nuageinit-all.ucl
@@ -0,0 +1,4 @@
+comment = "CloudInit support scripts"
+desc = <<EOD
+CloudInit support scripts
+EOD
diff --git a/release/packages/ucl/nvme-tools-all.ucl b/release/packages/ucl/nvme-tools-all.ucl
new file mode 100644
index 000000000000..5863af2d5e34
--- /dev/null
+++ b/release/packages/ucl/nvme-tools-all.ucl
@@ -0,0 +1,4 @@
+comment = "NVME Utilities"
+desc = <<EOD
+NVME Utilities
+EOD
diff --git a/release/packages/ucl/openssl-all.ucl b/release/packages/ucl/openssl-all.ucl
new file mode 100644
index 000000000000..8dd2da021f0a
--- /dev/null
+++ b/release/packages/ucl/openssl-all.ucl
@@ -0,0 +1,4 @@
+comment = "OpenSSL Utility"
+desc = <<EOD
+OpenSSL Utility
+EOD
diff --git a/release/packages/ucl/openssl-lib-all.ucl b/release/packages/ucl/openssl-lib-all.ucl
new file mode 100644
index 000000000000..c81dd44855cd
--- /dev/null
+++ b/release/packages/ucl/openssl-lib-all.ucl
@@ -0,0 +1,4 @@
+comment = "OpenSSL Libraries"
+desc = <<EOD
+OpenSSL Libraries
+EOD
diff --git a/release/packages/ucl/periodic-all.ucl b/release/packages/ucl/periodic-all.ucl
new file mode 100644
index 000000000000..569bf8d829c4
--- /dev/null
+++ b/release/packages/ucl/periodic-all.ucl
@@ -0,0 +1,4 @@
+comment = "Periodic Utility"
+desc = <<EOD
+Periodic Utility
+EOD
diff --git a/release/packages/ucl/periodic.ucl b/release/packages/ucl/periodic.ucl
new file mode 100644
index 000000000000..6f85d2ab744b
--- /dev/null
+++ b/release/packages/ucl/periodic.ucl
@@ -0,0 +1,6 @@
+deps {
+ "cron" {
+ version = "${VERSION}"
+ origin = "base"
+ }
+}
diff --git a/release/packages/ucl/pf-all.ucl b/release/packages/ucl/pf-all.ucl
new file mode 100644
index 000000000000..4b58fa4f6364
--- /dev/null
+++ b/release/packages/ucl/pf-all.ucl
@@ -0,0 +1,4 @@
+comment = "OpenBSD packet filter"
+desc = <<EOD
+pf is an advanced stateful packet filter developed by the OpenBSD project.
+EOD
diff --git a/release/packages/ucl/pkg-bootstrap-all.ucl b/release/packages/ucl/pkg-bootstrap-all.ucl
new file mode 100644
index 000000000000..9ca6ccd2af58
--- /dev/null
+++ b/release/packages/ucl/pkg-bootstrap-all.ucl
@@ -0,0 +1,4 @@
+comment = "pkg bootstrap Utility"
+desc = <<EOD
+pkg bootstrap Utility
+EOD
diff --git a/release/packages/ucl/ppp-all.ucl b/release/packages/ucl/ppp-all.ucl
new file mode 100644
index 000000000000..454e54b7b872
--- /dev/null
+++ b/release/packages/ucl/ppp-all.ucl
@@ -0,0 +1,5 @@
+comment = "Userland PPP implementation"
+desc = <<EOD
+ppp(8) is a userland implementations of the Point to Point Protocol for serial
+lines and Ethernet (PPPoE).
+EOD
diff --git a/release/packages/ucl/quotacheck-all.ucl b/release/packages/ucl/quotacheck-all.ucl
new file mode 100644
index 000000000000..18b2c3d9bd5c
--- /dev/null
+++ b/release/packages/ucl/quotacheck-all.ucl
@@ -0,0 +1,8 @@
+comment = "Filesystem quota consistency checker"
+desc = <<EOD
+The quotacheck utility examines each file system, builds a table of current
+disk usage, and compares this table against that recorded in the disk quota
+file for the file system. If any inconsistencies are detected, both the quota
+file and the current system copy of the incorrect quotas are updated (the
+latter only occurs if an active file system is checked).
+EOD
diff --git a/release/packages/ucl/rc-all.ucl b/release/packages/ucl/rc-all.ucl
new file mode 100644
index 000000000000..04ed0dafacf0
--- /dev/null
+++ b/release/packages/ucl/rc-all.ucl
@@ -0,0 +1,4 @@
+comment = "RC Scripts"
+desc = <<EOD
+RC Scripts
+EOD
diff --git a/release/packages/ucl/rcmds-all.ucl b/release/packages/ucl/rcmds-all.ucl
new file mode 100644
index 000000000000..db51d52ed246
--- /dev/null
+++ b/release/packages/ucl/rcmds-all.ucl
@@ -0,0 +1,7 @@
+comment = "BSD/SunOS remote status commands"
+desc = <<EOD
+The BSD/SunOS remote status commands, which can be used to query or interact
+with remote hosts over the network. This includes the command-line utilities
+rwho, ruptime, rup, rusers and rwall and the daemons rwhod, rpc.rstatd,
+rpc.rusersd, and rpc.rwalld.
+EOD
diff --git a/release/packages/ucl/rcmds.ucl b/release/packages/ucl/rcmds.ucl
new file mode 100644
index 000000000000..88a4916675dc
--- /dev/null
+++ b/release/packages/ucl/rcmds.ucl
@@ -0,0 +1,8 @@
+deps {
+ # The RPC daemons require rpcbind.
+ "utilities" {
+ version = "${VERSION}"
+ origin = "base"
+ }
+}
+
diff --git a/release/packages/ucl/rdma-all.ucl b/release/packages/ucl/rdma-all.ucl
new file mode 100644
index 000000000000..313c2b7d17e0
--- /dev/null
+++ b/release/packages/ucl/rdma-all.ucl
@@ -0,0 +1 @@
+comment = "RDMA Utilities"
diff --git a/release/packages/ucl/rescue-all.ucl b/release/packages/ucl/rescue-all.ucl
new file mode 100644
index 000000000000..da870079bbb7
--- /dev/null
+++ b/release/packages/ucl/rescue-all.ucl
@@ -0,0 +1,4 @@
+comment = "Rescue Utilities"
+desc = <<EOD
+Rescue Utilities
+EOD
diff --git a/release/packages/ucl/resolvconf-all.ucl b/release/packages/ucl/resolvconf-all.ucl
new file mode 100644
index 000000000000..a2d2e0debfa1
--- /dev/null
+++ b/release/packages/ucl/resolvconf-all.ucl
@@ -0,0 +1,4 @@
+comment = "Resolvconf Utility and scripts"
+desc = <<EOD
+Resolvconf Utility and scripts
+EOD
diff --git a/release/packages/ucl/runtime-all.ucl b/release/packages/ucl/runtime-all.ucl
new file mode 100644
index 000000000000..f614a3ef3d43
--- /dev/null
+++ b/release/packages/ucl/runtime-all.ucl
@@ -0,0 +1,4 @@
+comment = "FreeBSD Base System"
+desc = <<EOD
+FreeBSD Base System
+EOD
diff --git a/release/packages/runtime.ucl b/release/packages/ucl/runtime.ucl
index b04bc32f33cc..b04bc32f33cc 100644
--- a/release/packages/runtime.ucl
+++ b/release/packages/ucl/runtime.ucl
diff --git a/release/packages/ucl/sendmail-all.ucl b/release/packages/ucl/sendmail-all.ucl
new file mode 100644
index 000000000000..2711e33a31a8
--- /dev/null
+++ b/release/packages/ucl/sendmail-all.ucl
@@ -0,0 +1,4 @@
+comment = "Sendmail Utilities"
+desc = <<EOD
+Sendmail Utilities
+EOD
diff --git a/release/packages/ucl/smbutils-all.ucl b/release/packages/ucl/smbutils-all.ucl
new file mode 100644
index 000000000000..779179ca3875
--- /dev/null
+++ b/release/packages/ucl/smbutils-all.ucl
@@ -0,0 +1,4 @@
+comment = "SMB Utilities"
+desc = <<EOD
+SMB Utilities
+EOD
diff --git a/release/packages/ucl/src-all.ucl b/release/packages/ucl/src-all.ucl
new file mode 100644
index 000000000000..15b2b7d5b29d
--- /dev/null
+++ b/release/packages/ucl/src-all.ucl
@@ -0,0 +1,5 @@
+comment = "System userland source code"
+desc = <<EOD
+The source code used to rebuild the system, located in /usr/src.
+This package includes everything except the kernel source code.
+EOD
diff --git a/release/packages/ucl/src-sys-all.ucl b/release/packages/ucl/src-sys-all.ucl
new file mode 100644
index 000000000000..9b1c5b64bfbb
--- /dev/null
+++ b/release/packages/ucl/src-sys-all.ucl
@@ -0,0 +1,5 @@
+comment = "System kernel source code"
+desc = <<EOD
+The source code used to rebuild the system, located in /usr/src.
+This package includes the kernel source code.
+EOD
diff --git a/release/packages/ucl/ssh-all.ucl b/release/packages/ucl/ssh-all.ucl
new file mode 100644
index 000000000000..8159391eab08
--- /dev/null
+++ b/release/packages/ucl/ssh-all.ucl
@@ -0,0 +1,5 @@
+comment = "Secure Shell Utilities"
+desc = <<EOD
+Secure Shell Utilities
+EOD
+licenses = [ ISCL ]
diff --git a/release/packages/ucl/syscons-data-all.ucl b/release/packages/ucl/syscons-data-all.ucl
new file mode 100644
index 000000000000..9f59bfd60588
--- /dev/null
+++ b/release/packages/ucl/syscons-data-all.ucl
@@ -0,0 +1,4 @@
+comment = "syscons(4) fonts and keymaps"
+desc = <<EOD
+Fonts and keymaps for use with the legacy syscons(4) video console driver.
+EOD
diff --git a/release/packages/ucl/syslogd-all.ucl b/release/packages/ucl/syslogd-all.ucl
new file mode 100644
index 000000000000..0f82c31fdf0f
--- /dev/null
+++ b/release/packages/ucl/syslogd-all.ucl
@@ -0,0 +1,4 @@
+comment = "Syslog Daemon"
+desc = <<EOD
+Syslog Daemon
+EOD
diff --git a/release/packages/ucl/tcpd-all.ucl b/release/packages/ucl/tcpd-all.ucl
new file mode 100644
index 000000000000..13b7449af267
--- /dev/null
+++ b/release/packages/ucl/tcpd-all.ucl
@@ -0,0 +1,4 @@
+comment = "TCP Wrapper utilities"
+desc = <<EOD
+TCP Wrapper utilities
+EOD
diff --git a/release/packages/ucl/telnet-all.ucl b/release/packages/ucl/telnet-all.ucl
new file mode 100644
index 000000000000..e235b0d776eb
--- /dev/null
+++ b/release/packages/ucl/telnet-all.ucl
@@ -0,0 +1,4 @@
+comment = "Telnet client"
+desc = <<EOD
+Telnet client
+EOD
diff --git a/release/packages/ucl/tests-all.ucl b/release/packages/ucl/tests-all.ucl
new file mode 100644
index 000000000000..39bd365bee5b
--- /dev/null
+++ b/release/packages/ucl/tests-all.ucl
@@ -0,0 +1,4 @@
+comment = "Test Suite"
+desc = <<EOD
+Test Suite
+EOD
diff --git a/release/packages/ucl/toolchain-all.ucl b/release/packages/ucl/toolchain-all.ucl
new file mode 100644
index 000000000000..dd6517745722
--- /dev/null
+++ b/release/packages/ucl/toolchain-all.ucl
@@ -0,0 +1,4 @@
+comment = "Utilities for program development"
+desc = <<EOD
+Utilities for program development.
+EOD
diff --git a/release/packages/ucl/ufs-all.ucl b/release/packages/ucl/ufs-all.ucl
new file mode 100644
index 000000000000..48f9975e0dbd
--- /dev/null
+++ b/release/packages/ucl/ufs-all.ucl
@@ -0,0 +1,4 @@
+comment = "UFS Libraries and Utilities"
+desc = <<EOD
+UFS Libraries and Utilities
+EOD
diff --git a/release/packages/ucl/unbound-all.ucl b/release/packages/ucl/unbound-all.ucl
new file mode 100644
index 000000000000..700c9e4cf9d0
--- /dev/null
+++ b/release/packages/ucl/unbound-all.ucl
@@ -0,0 +1,5 @@
+comment = "Unbound DNS Resolver"
+desc = <<EOD
+Unbound DNS Resolver
+EOD
+licenses = [ BSD4CLAUSE ]
diff --git a/release/packages/ucl/utilities-all.ucl b/release/packages/ucl/utilities-all.ucl
new file mode 100644
index 000000000000..aeb82b0cfed5
--- /dev/null
+++ b/release/packages/ucl/utilities-all.ucl
@@ -0,0 +1,4 @@
+comment = "Non-vital programs and libraries"
+desc = <<EOD
+Non-vital programs and libraries
+EOD
diff --git a/release/packages/utilities.ucl b/release/packages/ucl/utilities.ucl
index 4eb98cae292a..4eb98cae292a 100644
--- a/release/packages/utilities.ucl
+++ b/release/packages/ucl/utilities.ucl
diff --git a/release/packages/ucl/vi-all.ucl b/release/packages/ucl/vi-all.ucl
new file mode 100644
index 000000000000..c2ad2f8e95eb
--- /dev/null
+++ b/release/packages/ucl/vi-all.ucl
@@ -0,0 +1,4 @@
+comment = "Vi Editor"
+desc = <<EOD
+Vi Editor
+EOD
diff --git a/release/packages/ucl/vt-data-all.ucl b/release/packages/ucl/vt-data-all.ucl
new file mode 100644
index 000000000000..4142b2eeae70
--- /dev/null
+++ b/release/packages/ucl/vt-data-all.ucl
@@ -0,0 +1,4 @@
+comment = "vt(4) fonts and keymaps"
+desc = <<EOD
+Fonts and keymaps for use with the vt(4) video console driver.
+EOD
diff --git a/release/packages/ucl/wpa-all.ucl b/release/packages/ucl/wpa-all.ucl
new file mode 100644
index 000000000000..e5ad7f36db95
--- /dev/null
+++ b/release/packages/ucl/wpa-all.ucl
@@ -0,0 +1,4 @@
+comment = "802.11 Supplicant"
+desc = <<EOD
+802.11 Supplicant
+EOD
diff --git a/release/packages/ucl/yp-all.ucl b/release/packages/ucl/yp-all.ucl
new file mode 100644
index 000000000000..9e17cd108d84
--- /dev/null
+++ b/release/packages/ucl/yp-all.ucl
@@ -0,0 +1,7 @@
+comment = "Yellow Pages (YP) / Network Information Service (NIS)"
+desc = <<EOD
+YP, also called NIS, is a network protocol for sharing name service
+information across machines on a network. This packages contains the YP
+server, YP management utilities, the YP-LDAP gateway (ypldap), YP client
+utilities and a sample Makefile for building the YP database.
+EOD
diff --git a/release/packages/ucl/zfs-all.ucl b/release/packages/ucl/zfs-all.ucl
new file mode 100644
index 000000000000..f4178acc481c
--- /dev/null
+++ b/release/packages/ucl/zfs-all.ucl
@@ -0,0 +1,4 @@
+comment = "ZFS Libraries and Utilities"
+desc = <<EOD
+ZFS Libraries and Utilities
+EOD
diff --git a/release/packages/ucl/zoneinfo-all.ucl b/release/packages/ucl/zoneinfo-all.ucl
new file mode 100644
index 000000000000..39991bf144e6
--- /dev/null
+++ b/release/packages/ucl/zoneinfo-all.ucl
@@ -0,0 +1,5 @@
+comment = "Timezone database"
+desc = <<EOD
+The timezone database allows applications to convert dates and times between
+UTC and local timezones.
+EOD
diff --git a/release/packages/unbound-all.ucl b/release/packages/unbound-all.ucl
deleted file mode 100644
index 78bb1f284ff2..000000000000
--- a/release/packages/unbound-all.ucl
+++ /dev/null
@@ -1 +0,0 @@
-licenses = [ BSD4CLAUSE ]
diff --git a/release/powerpc/mkisoimages.sh b/release/powerpc/mkisoimages.sh
index ba7c32f87bee..9d83390f1a4e 100644
--- a/release/powerpc/mkisoimages.sh
+++ b/release/powerpc/mkisoimages.sh
@@ -24,6 +24,9 @@
set -e
+scriptdir=$(dirname $(realpath $0))
+. ${scriptdir}/../scripts/tools.subr
+
if [ "$1" = "-b" ]; then
MAKEFSARG="$4"
else
@@ -107,7 +110,7 @@ echo "/dev/iso9660/$LABEL / cd9660 ro 0 0" > "$BASEBITSDIR/etc/fstab"
if [ -n "${METALOG}" ]; then
echo "./etc/fstab type=file uname=root gname=wheel mode=0644" >> ${metalogfilename}
fi
-makefs -D -N ${BASEBITSDIR}/etc -t cd9660 $bootable -o rockridge -o label="$LABEL" -o publisher="$publisher" "$NAME" "$MAKEFSARG" "$@"
+${MAKEFS} -D -N ${BASEBITSDIR}/etc -t cd9660 $bootable -o rockridge -o label="$LABEL" -o publisher="$publisher" "$NAME" "$MAKEFSARG" "$@"
rm -f "$BASEBITSDIR/etc/fstab"
if [ n "$bootable" ]; then
rm $BOOTBLOCK
diff --git a/release/riscv/make-memstick.sh b/release/riscv/make-memstick.sh
index 90ff98b394c7..0da59c29635b 100755
--- a/release/riscv/make-memstick.sh
+++ b/release/riscv/make-memstick.sh
@@ -17,6 +17,7 @@ if [ "$(uname -s)" = "FreeBSD" ]; then
fi
scriptdir=$(dirname $(realpath $0))
+. ${scriptdir}/../scripts/tools.subr
. ${scriptdir}/../../tools/boot/install-boot.sh
if [ $# -ne 2 ]; then
@@ -51,7 +52,7 @@ if [ -n "${METALOG}" ]; then
echo "./etc/rc.conf.local type=file uname=root gname=wheel mode=0644" >> ${metalogfilename}
MAKEFSARG=${metalogfilename}
fi
-makefs -D -N ${BASEBITSDIR}/etc -B little -o label=FreeBSD_Install -o version=2 ${2}.part ${MAKEFSARG}
+${MAKEFS} -D -N ${BASEBITSDIR}/etc -B little -o label=FreeBSD_Install -o version=2 ${2}.part ${MAKEFSARG}
rm ${BASEBITSDIR}/etc/fstab
rm ${BASEBITSDIR}/etc/rc.conf.local
if [ -n "${METALOG}" ]; then
@@ -62,7 +63,7 @@ fi
espfilename=$(mktemp /tmp/efiboot.XXXXXX)
make_esp_file ${espfilename} ${fat32min} ${BASEBITSDIR}/boot/loader.efi
-mkimg -s gpt \
+${MKIMG} -s gpt \
-p efi:=${espfilename} \
-p freebsd-ufs:=${2}.part \
-o ${2}
diff --git a/release/riscv/mkisoimages.sh b/release/riscv/mkisoimages.sh
index cb58178ed4b9..46b16f0ce08d 100644
--- a/release/riscv/mkisoimages.sh
+++ b/release/riscv/mkisoimages.sh
@@ -21,20 +21,9 @@
set -e
scriptdir=$(dirname $(realpath $0))
+. ${scriptdir}/../scripts/tools.subr
. ${scriptdir}/../../tools/boot/install-boot.sh
-if [ -z $ETDUMP ]; then
- ETDUMP=etdump
-fi
-
-if [ -z $MAKEFS ]; then
- MAKEFS=makefs
-fi
-
-if [ -z $MKIMG ]; then
- MKIMG=mkimg
-fi
-
if [ "$1" = "-b" ]; then
MAKEFSARG="$4"
else
diff --git a/release/scripts/tools.subr b/release/scripts/tools.subr
new file mode 100644
index 000000000000..e818f0a55410
--- /dev/null
+++ b/release/scripts/tools.subr
@@ -0,0 +1,13 @@
+#!/bin/sh
+#-
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2025 The FreeBSD Foundation
+#
+# This software was developed by Klara, Inc.
+# under sponsorship from the FreeBSD Foundation.
+#
+
+: ${ETDUMP:=etdump}
+: ${MAKEFS:=makefs}
+: ${MKIMG:=mkimg}
diff --git a/release/tools/vmimage.subr b/release/tools/vmimage.subr
index ce0ea03c096c..eb816018e9d3 100644
--- a/release/tools/vmimage.subr
+++ b/release/tools/vmimage.subr
@@ -6,6 +6,7 @@
#
scriptdir=$(dirname $(realpath $0))
+. ${scriptdir}/../scripts/tools.subr
. ${scriptdir}/../../tools/boot/install-boot.sh
export PATH="/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin:/usr/local/sbin"
@@ -209,11 +210,11 @@ buildfs() {
case "${VMFS}" in
ufs)
- cd ${DESTDIR} && makefs ${MAKEFSARGS} -o label=rootfs -o version=2 -o softupdates=1 \
+ cd ${DESTDIR} && ${MAKEFS} ${MAKEFSARGS} -o label=rootfs -o version=2 -o softupdates=1 \
${VMBASE} .${NO_ROOT:+/METALOG}
;;
zfs)
- cd ${DESTDIR} && makefs -t zfs ${MAKEFSARGS} \
+ cd ${DESTDIR} && ${MAKEFS} -t zfs ${MAKEFSARGS} \
-o poolname=zroot -o bootfs=zroot/ROOT/default -o rootpath=/ \
-o fs=zroot\;mountpoint=none \
-o fs=zroot/ROOT\;mountpoint=none \
@@ -342,7 +343,7 @@ vm_create_disk() {
buildfs
echo "Building final disk image... Please wait."
- mkimg -s ${PARTSCHEME} -f ${VMFORMAT} \
+ ${MKIMG} -s ${PARTSCHEME} -f ${VMFORMAT} \
${BOOTPARTS} \
${SWAPOPT} \
${CONFIG_DRIVE} \
diff --git a/sbin/ifconfig/ifconfig.8 b/sbin/ifconfig/ifconfig.8
index 3fb8b5f02b76..6c61af48abec 100644
--- a/sbin/ifconfig/ifconfig.8
+++ b/sbin/ifconfig/ifconfig.8
@@ -28,7 +28,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd July 5, 2025
+.Dd July 11, 2025
.Dt IFCONFIG 8
.Os
.Sh NAME
@@ -2878,16 +2878,6 @@ interfaces previously configured with
Another name for the
.Fl tunnel
parameter.
-.It Cm accept_rev_ethip_ver
-Set a flag to accept both correct EtherIP packets and ones
-with reversed version field.
-Enabled by default.
-This is for backward compatibility with
-.Fx 6.1 ,
-6.2, 6.3, 7.0, and 7.1.
-.It Cm -accept_rev_ethip_ver
-Clear a flag
-.Cm accept_rev_ethip_ver .
.It Cm ignore_source
Set a flag to accept encapsulated packets destined to this host
independently from source address.
@@ -2896,16 +2886,6 @@ from the load balancers.
.It Cm -ignore_source
Clear a flag
.Cm ignore_source .
-.It Cm send_rev_ethip_ver
-Set a flag to send EtherIP packets with reversed version
-field intentionally.
-Disabled by default.
-This is for backward compatibility with
-.Fx 6.1 ,
-6.2, 6.3, 7.0, and 7.1.
-.It Cm -send_rev_ethip_ver
-Clear a flag
-.Cm send_rev_ethip_ver .
.El
.Ss GRE Tunnel Parameters
The following parameters apply to GRE tunnel interfaces,
diff --git a/sbin/mount/mount.8 b/sbin/mount/mount.8
index b584d71ea567..7bfc21ea41d5 100644
--- a/sbin/mount/mount.8
+++ b/sbin/mount/mount.8
@@ -28,7 +28,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd April 30, 2025
+.Dd July 16, 2025
.Dt MOUNT 8
.Os
.Sh NAME
@@ -80,7 +80,7 @@ Generate output via
.Xr libxo 3
in a selection of different human and machine readable formats.
See
-.Xr xo_parse_args 3
+.Xr xo_options 7
for details on command line arguments.
.It Fl a
All the file systems described in
@@ -573,7 +573,7 @@ support for a particular file system might be provided either on a static
.Xr acl 3 ,
.Xr getmntinfo 3 ,
.Xr libxo 3 ,
-.Xr xo_parse_args 3 ,
+.Xr xo_options 7 ,
.Xr cd9660 4 ,
.Xr devfs 4 ,
.Xr ext2fs 4 ,
diff --git a/sbin/pfctl/parse.y b/sbin/pfctl/parse.y
index 28f461bf715d..358fa909fc50 100644
--- a/sbin/pfctl/parse.y
+++ b/sbin/pfctl/parse.y
@@ -367,6 +367,7 @@ static struct node_fairq_opts fairq_opts;
static struct node_state_opt *keep_state_defaults = NULL;
static struct pfctl_watermarks syncookie_opts;
+int validate_range(uint8_t, uint16_t, uint16_t);
int disallow_table(struct node_host *, const char *);
int disallow_urpf_failed(struct node_host *, const char *);
int disallow_alias(struct node_host *, const char *);
@@ -3231,8 +3232,7 @@ logopts : logopt { $$ = $1; }
logopt : ALL { $$.log = PF_LOG_ALL; $$.logif = 0; }
| MATCHES { $$.log = PF_LOG_MATCHES; $$.logif = 0; }
- | USER { $$.log = PF_LOG_SOCKET_LOOKUP; $$.logif = 0; }
- | GROUP { $$.log = PF_LOG_SOCKET_LOOKUP; $$.logif = 0; }
+ | USER { $$.log = PF_LOG_USER; $$.logif = 0; }
| TO string {
const char *errstr;
u_int i;
@@ -3825,9 +3825,14 @@ port_item : portrange {
err(1, "port_item: calloc");
$$->port[0] = $1.a;
$$->port[1] = $1.b;
- if ($1.t)
+ if ($1.t) {
$$->op = PF_OP_RRG;
- else
+ if (validate_range($$->op, $$->port[0],
+ $$->port[1])) {
+ yyerror("invalid port range");
+ YYERROR;
+ }
+ } else
$$->op = PF_OP_EQ;
$$->next = NULL;
$$->tail = $$;
@@ -3844,6 +3849,10 @@ port_item : portrange {
$$->port[0] = $2.a;
$$->port[1] = $2.b;
$$->op = $1;
+ if (validate_range($$->op, $$->port[0], $$->port[1])) {
+ yyerror("invalid port range");
+ YYERROR;
+ }
$$->next = NULL;
$$->tail = $$;
}
@@ -3859,6 +3868,10 @@ port_item : portrange {
$$->port[0] = $1.a;
$$->port[1] = $3.a;
$$->op = $2;
+ if (validate_range($$->op, $$->port[0], $$->port[1])) {
+ yyerror("invalid port range");
+ YYERROR;
+ }
$$->next = NULL;
$$->tail = $$;
}
@@ -5197,6 +5210,19 @@ yyerror(const char *fmt, ...)
}
int
+validate_range(uint8_t op, uint16_t p1, uint16_t p2)
+{
+ uint16_t a = ntohs(p1);
+ uint16_t b = ntohs(p2);
+
+ if ((op == PF_OP_RRG && a > b) || /* 34:12, i.e. none */
+ (op == PF_OP_IRG && a >= b) || /* 34><12, i.e. none */
+ (op == PF_OP_XRG && a > b)) /* 34<>22, i.e. all */
+ return 1;
+ return 0;
+}
+
+int
disallow_table(struct node_host *h, const char *fmt)
{
for (; h != NULL; h = h->next)
@@ -5324,6 +5350,10 @@ filter_consistent(struct pfctl_rule *r, int anchor_call)
"synproxy state or modulate state");
problems++;
}
+ if ((r->keep_state == PF_STATE_SYNPROXY) && (r->direction != PF_IN))
+ fprintf(stderr, "%s:%d: warning: "
+ "synproxy used for inbound rules only, "
+ "ignored for outbound\n", file->name, yylval.lineno);
if (r->rule_flag & PFRULE_AFTO && r->rt) {
if (r->rt != PF_ROUTETO && r->rt != PF_REPLYTO) {
yyerror("dup-to "
@@ -5458,7 +5488,7 @@ process_tabledef(char *name, struct table_opts *opts, int popts)
name);
else
yyerror("cannot define table %s: %s", name,
- pfr_strerror(errno));
+ pf_strerror(errno));
goto _error;
}
@@ -6014,8 +6044,14 @@ apply_rdr_ports(struct pfctl_rule *r, struct pfctl_pool *rpool, struct redirspec
if (!rs->rport.b && rs->rport.t) {
rpool->proxy_port[1] = ntohs(rs->rport.a) +
(ntohs(r->dst.port[1]) - ntohs(r->dst.port[0]));
- } else
+ } else {
+ if (validate_range(rs->rport.t, rs->rport.a,
+ rs->rport.b)) {
+ yyerror("invalid rdr-to port range");
+ return (1);
+ }
r->rdr.proxy_port[1] = ntohs(rs->rport.b);
+ }
if (rs->pool_opts.staticport) {
yyerror("the 'static-port' option is only valid with nat rules");
@@ -7202,19 +7238,11 @@ mv_rules(struct pfctl_ruleset *src, struct pfctl_ruleset *dst)
struct pfctl_rule *r;
for (i = 0; i < PF_RULESET_MAX; ++i) {
- while ((r = TAILQ_FIRST(src->rules[i].active.ptr))
- != NULL) {
- TAILQ_REMOVE(src->rules[i].active.ptr, r, entries);
- TAILQ_INSERT_TAIL(dst->rules[i].active.ptr, r, entries);
+ TAILQ_FOREACH(r, src->rules[i].active.ptr, entries)
dst->anchor->match++;
- }
+ TAILQ_CONCAT(dst->rules[i].active.ptr, src->rules[i].active.ptr, entries);
src->anchor->match = 0;
- while ((r = TAILQ_FIRST(src->rules[i].inactive.ptr))
- != NULL) {
- TAILQ_REMOVE(src->rules[i].inactive.ptr, r, entries);
- TAILQ_INSERT_TAIL(dst->rules[i].inactive.ptr,
- r, entries);
- }
+ TAILQ_CONCAT(dst->rules[i].inactive.ptr, src->rules[i].inactive.ptr, entries);
}
}
diff --git a/sbin/pfctl/pfctl.8 b/sbin/pfctl/pfctl.8
index 508dcc6ea8d4..f582c6301124 100644
--- a/sbin/pfctl/pfctl.8
+++ b/sbin/pfctl/pfctl.8
@@ -487,7 +487,10 @@ Show the contents of the source tracking table.
Show filter information (statistics and counters).
When used together with
.Fl v ,
-source tracking statistics are also shown.
+source tracking statistics, the firewall's 32-bit hostid number and the
+main ruleset's MD5 checksum for use with
+.Xr pfsync 4
+are also shown.
.It Fl s Cm Running
Show the running status and provide a non-zero exit status when disabled.
.It Fl s Cm labels
diff --git a/sbin/pfctl/pfctl.c b/sbin/pfctl/pfctl.c
index 8d2b556d7085..2015e0a09549 100644
--- a/sbin/pfctl/pfctl.c
+++ b/sbin/pfctl/pfctl.c
@@ -131,8 +131,8 @@ int pfctl_walk_get(int, struct pfioc_ruleset *, void *);
int pfctl_walk_anchors(int, int, const char *,
int(*)(int, struct pfioc_ruleset *, void *), void *);
struct pfr_anchors *
- pfctl_get_anchors(int, char *, int);
-int pfctl_recurse(int, int, char *,
+ pfctl_get_anchors(int, const char *, int);
+int pfctl_recurse(int, int, const char *,
int(*)(int, int, struct pfr_anchoritem *));
int pfctl_call_clearrules(int, int, struct pfr_anchoritem *);
int pfctl_call_cleartables(int, int, struct pfr_anchoritem *);
@@ -1340,17 +1340,12 @@ pfctl_show_rules(int dev, char *path, int opts, enum pfctl_show format,
u_int32_t mnr, nr;
memset(&prs, 0, sizeof(prs));
- if ((ret = pfctl_get_rulesets(pfh, npath, &mnr)) != 0) {
- if (ret == EINVAL)
- fprintf(stderr, "Anchor '%s' "
- "not found.\n", anchorname);
- else
- errc(1, ret, "DIOCGETRULESETS");
- }
+ if ((ret = pfctl_get_rulesets(pfh, npath, &mnr)) != 0)
+ errx(1, "%s", pf_strerror(ret));
for (nr = 0; nr < mnr; ++nr) {
if ((ret = pfctl_get_ruleset(pfh, npath, nr, &prs)) != 0)
- errc(1, ret, "DIOCGETRULESET");
+ errx(1, "%s", pf_strerror(ret));
INDENT(depth, !(opts & PF_OPT_VERBOSE));
printf("anchor \"%s\" all {\n", prs.name);
pfctl_show_rules(dev, npath, opts,
@@ -1365,14 +1360,14 @@ pfctl_show_rules(int dev, char *path, int opts, enum pfctl_show format,
if (opts & PF_OPT_SHOWALL) {
ret = pfctl_get_rules_info_h(pfh, &ri, PF_PASS, path);
if (ret != 0) {
- warnc(ret, "DIOCGETRULES");
+ warnx("%s", pf_strerror(ret));
goto error;
}
header++;
}
ret = pfctl_get_rules_info_h(pfh, &ri, PF_SCRUB, path);
if (ret != 0) {
- warnc(ret, "DIOCGETRULES");
+ warnx("%s", pf_strerror(ret));
goto error;
}
if (opts & PF_OPT_SHOWALL) {
@@ -1565,12 +1560,12 @@ pfctl_show_nat(int dev, const char *path, int opts, char *anchorname, int depth,
fprintf(stderr, "NAT anchor '%s' "
"not found.\n", anchorname);
else
- errc(1, ret, "DIOCGETRULESETS");
+ errx(1, "%s", pf_strerror(ret));
}
for (nr = 0; nr < mnr; ++nr) {
if ((ret = pfctl_get_ruleset(pfh, npath, nr, &prs)) != 0)
- errc(1, ret, "DIOCGETRULESET");
+ errx(1, "%s", pf_strerror(ret));
INDENT(depth, !(opts & PF_OPT_VERBOSE));
printf("nat-anchor \"%s\" all {\n", prs.name);
pfctl_show_nat(dev, npath, opts,
@@ -2962,13 +2957,8 @@ pfctl_walk_anchors(int dev, int opts, const char *anchor,
int ret;
memset(&pr, 0, sizeof(pr));
- if ((ret = pfctl_get_rulesets(pfh, anchor, &mnr)) != 0) {
- if (ret == EINVAL)
- fprintf(stderr, "Anchor '%s' not found.\n", anchor);
- else
- errc(1, ret, "DIOCGETRULESETS");
- return (-1);
- }
+ if ((ret = pfctl_get_rulesets(pfh, anchor, &mnr)) != 0)
+ errx(1, "%s", pf_strerror(ret));
for (nr = 0; nr < mnr; ++nr) {
char sub[MAXPATHLEN];
@@ -2998,20 +2988,23 @@ pfctl_show_anchors(int dev, int opts, char *anchor)
}
struct pfr_anchors *
-pfctl_get_anchors(int dev, char *anchor, int opts)
+pfctl_get_anchors(int dev, const char *anchor, int opts)
{
struct pfioc_ruleset pr;
static struct pfr_anchors anchors;
+ char anchorbuf[PATH_MAX];
char *n;
SLIST_INIT(&anchors);
memset(&pr, 0, sizeof(pr));
if (*anchor != '\0') {
- n = dirname(anchor);
+ strlcpy(anchorbuf, anchor, sizeof(anchorbuf));
+ n = dirname(anchorbuf);
if (n[0] != '.' && n[1] != '\0')
strlcpy(pr.path, n, sizeof(pr.path));
- n = basename(anchor);
+ strlcpy(anchorbuf, anchor, sizeof(anchorbuf));
+ n = basename(anchorbuf);
if (n != NULL)
strlcpy(pr.name, n, sizeof(pr.name));
}
@@ -3061,7 +3054,7 @@ pfctl_call_clearanchors(int dev, int opts, struct pfr_anchoritem *pfra)
}
int
-pfctl_recurse(int dev, int opts, char *anchorname,
+pfctl_recurse(int dev, int opts, const char *anchorname,
int(*walkf)(int, int, struct pfr_anchoritem *))
{
int rv = 0;
@@ -3643,3 +3636,17 @@ main(int argc, char *argv[])
exit(exit_val);
}
+
+char *
+pf_strerror(int errnum)
+{
+ switch (errnum) {
+ case ESRCH:
+ return "Table does not exist.";
+ case EINVAL:
+ case ENOENT:
+ return "Anchor does not exist.";
+ default:
+ return strerror(errnum);
+ }
+}
diff --git a/sbin/pfctl/pfctl.h b/sbin/pfctl/pfctl.h
index 5b5b3d3e5fff..afecc78086e0 100644
--- a/sbin/pfctl/pfctl.h
+++ b/sbin/pfctl/pfctl.h
@@ -83,7 +83,7 @@ void *pfr_buf_next(struct pfr_buffer *, const void *);
int pfr_buf_grow(struct pfr_buffer *, int);
int pfr_buf_load(struct pfr_buffer *, char *, int,
int (*)(struct pfr_buffer *, char *, int, int), int);
-char *pfr_strerror(int);
+char *pf_strerror(int);
int pfi_get_ifaces(const char *, struct pfi_kif *, int *);
int pfi_clr_istats(const char *, int *, int);
diff --git a/sbin/pfctl/pfctl_optimize.c b/sbin/pfctl/pfctl_optimize.c
index e727324bbf40..1d2a60555f19 100644
--- a/sbin/pfctl/pfctl_optimize.c
+++ b/sbin/pfctl/pfctl_optimize.c
@@ -723,11 +723,7 @@ reorder_rules(struct pfctl *pf, struct superblock *block, int depth)
* it based on a more optimal skipstep order.
*/
TAILQ_INIT(&head);
- while ((por = TAILQ_FIRST(&block->sb_rules))) {
- TAILQ_REMOVE(&block->sb_rules, por, por_entry);
- TAILQ_INSERT_TAIL(&head, por, por_entry);
- }
-
+ TAILQ_CONCAT(&head, &block->sb_rules, por_entry);
while (!TAILQ_EMPTY(&head)) {
largest = 1;
@@ -748,11 +744,7 @@ reorder_rules(struct pfctl *pf, struct superblock *block, int depth)
* Nothing useful left. Leave remaining rules in order.
*/
DEBUG("(%d) no more commonality for skip steps", depth);
- while ((por = TAILQ_FIRST(&head))) {
- TAILQ_REMOVE(&head, por, por_entry);
- TAILQ_INSERT_TAIL(&block->sb_rules, por,
- por_entry);
- }
+ TAILQ_CONCAT(&block->sb_rules, &head, por_entry);
} else {
/*
* There is commonality. Extract those common rules
@@ -863,10 +855,7 @@ block_feedback(struct pfctl *pf, struct superblock *block)
*/
TAILQ_INIT(&queue);
- while ((por1 = TAILQ_FIRST(&block->sb_rules)) != NULL) {
- TAILQ_REMOVE(&block->sb_rules, por1, por_entry);
- TAILQ_INSERT_TAIL(&queue, por1, por_entry);
- }
+ TAILQ_CONCAT(&queue, &block->sb_rules, por_entry);
while ((por1 = TAILQ_FIRST(&queue)) != NULL) {
TAILQ_REMOVE(&queue, por1, por_entry);
@@ -903,13 +892,13 @@ load_feedback_profile(struct pfctl *pf, struct superblocks *superblocks)
struct pf_opt_queue queue;
struct pfctl_rules_info rules;
struct pfctl_rule a, b, rule;
- int nr, mnr;
+ int nr, mnr, ret;
TAILQ_INIT(&queue);
TAILQ_INIT(&prof_superblocks);
- if (pfctl_get_rules_info_h(pf->h, &rules, PF_PASS, "")) {
- warn("DIOCGETRULES");
+ if ((ret = pfctl_get_rules_info_h(pf->h, &rules, PF_PASS, "")) != 0) {
+ warnx("%s", pf_strerror(ret));
return (1);
}
mnr = rules.nr;
@@ -924,7 +913,7 @@ load_feedback_profile(struct pfctl *pf, struct superblocks *superblocks)
if (pfctl_get_rule_h(pf->h, nr, rules.ticket, "", PF_PASS,
&rule, anchor_call)) {
- warn("DIOCGETRULENV");
+ warnx("%s", pf_strerror(ret));
free(por);
return (1);
}
@@ -1259,7 +1248,7 @@ add_opt_table(struct pfctl *pf, struct pf_opt_tbl **tbl, sa_family_t af,
/* This is just a temporary table name */
snprintf((*tbl)->pt_name, sizeof((*tbl)->pt_name), "%s%d",
- PF_OPT_TABLE_PREFIX, tablenum++);
+ PF_OPTIMIZER_TABLE_PFX, tablenum++);
DEBUG("creating table <%s>", (*tbl)->pt_name);
}
@@ -1326,9 +1315,9 @@ pf_opt_create_table(struct pfctl *pf, struct pf_opt_tbl *tbl)
/* Now we have to pick a table name that isn't used */
again:
DEBUG("translating temporary table <%s> to <%s%x_%d>", tbl->pt_name,
- PF_OPT_TABLE_PREFIX, table_identifier, tablenum);
+ PF_OPTIMIZER_TABLE_PFX, table_identifier, tablenum);
snprintf(tbl->pt_name, sizeof(tbl->pt_name), "%s%x_%d",
- PF_OPT_TABLE_PREFIX, table_identifier, tablenum);
+ PF_OPTIMIZER_TABLE_PFX, table_identifier, tablenum);
PFRB_FOREACH(t, &table_buffer) {
if (strcasecmp(t->pfrt_name, tbl->pt_name) == 0) {
/* Collision. Try again */
diff --git a/sbin/pfctl/pfctl_parser.c b/sbin/pfctl/pfctl_parser.c
index bd2c10c8080f..f2eb75135609 100644
--- a/sbin/pfctl/pfctl_parser.c
+++ b/sbin/pfctl/pfctl_parser.c
@@ -928,7 +928,7 @@ print_rule(struct pfctl_rule *r, const char *anchor_call, int verbose, int numer
printf("%sall", count++ ? ", " : "");
if (r->log & PF_LOG_MATCHES)
printf("%smatches", count++ ? ", " : "");
- if (r->log & PF_LOG_SOCKET_LOOKUP)
+ if (r->log & PF_LOG_USER)
printf("%suser", count++ ? ", " : "");
if (r->logif)
printf("%sto pflog%u", count++ ? ", " : "",
@@ -1483,7 +1483,8 @@ ifa_load(void)
err(1, "getifaddrs");
for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
- if (!(ifa->ifa_addr->sa_family == AF_INET ||
+ if (ifa->ifa_addr == NULL ||
+ !(ifa->ifa_addr->sa_family == AF_INET ||
ifa->ifa_addr->sa_family == AF_INET6 ||
ifa->ifa_addr->sa_family == AF_LINK))
continue;
diff --git a/sbin/pfctl/pfctl_parser.h b/sbin/pfctl/pfctl_parser.h
index 778105c2b96d..7a3c0c2a523f 100644
--- a/sbin/pfctl/pfctl_parser.h
+++ b/sbin/pfctl/pfctl_parser.h
@@ -263,7 +263,6 @@ struct pf_opt_tbl {
struct node_tinithead pt_nodes;
struct pfr_buffer *pt_buf;
};
-#define PF_OPT_TABLE_PREFIX "__automatic_"
/* optimizer pf_rule container */
struct pf_opt_rule {
diff --git a/sbin/pfctl/pfctl_radix.c b/sbin/pfctl/pfctl_radix.c
index 21191259adff..00e4207d377b 100644
--- a/sbin/pfctl/pfctl_radix.c
+++ b/sbin/pfctl/pfctl_radix.c
@@ -461,16 +461,3 @@ pfr_next_token(char buf[BUF_SIZE], FILE *fp)
buf[i] = '\0';
return (1);
}
-
-char *
-pfr_strerror(int errnum)
-{
- switch (errnum) {
- case ESRCH:
- return "Table does not exist";
- case ENOENT:
- return "Anchor or Ruleset does not exist";
- default:
- return strerror(errnum);
- }
-}
diff --git a/sbin/pfctl/pfctl_table.c b/sbin/pfctl/pfctl_table.c
index 0b52f88eafbb..f583f5ef8e79 100644
--- a/sbin/pfctl/pfctl_table.c
+++ b/sbin/pfctl/pfctl_table.c
@@ -61,7 +61,6 @@ static int load_addr(struct pfr_buffer *, int, char *[], char *, int, int);
static void print_addrx(struct pfr_addr *, struct pfr_addr *, int);
static int nonzero_astats(struct pfr_astats *);
static void print_astats(struct pfr_astats *, int);
-static void radix_perror(void);
static void xprintf(int, const char *, ...);
static void print_iface(struct pfi_kif *, int);
@@ -75,14 +74,14 @@ static const char *istats_text[2][2][2] = {
{ { "In6/Pass:", "In6/Block:" }, { "Out6/Pass:", "Out6/Block:" } }
};
-#define RVTEST(fct) do { \
- if ((!(opts & PF_OPT_NOACTION) || \
- (opts & PF_OPT_DUMMYACTION)) && \
- (fct)) { \
- if ((opts & PF_OPT_RECURSE) == 0) \
- radix_perror(); \
- goto _error; \
- } \
+#define RVTEST(fct) do { \
+ if ((!(opts & PF_OPT_NOACTION) || \
+ (opts & PF_OPT_DUMMYACTION)) && \
+ (fct)) { \
+ if ((opts & PF_OPT_RECURSE) == 0) \
+ warnx("%s", pf_strerror(errno)); \
+ goto _error; \
+ } \
} while (0)
#define CREATE_TABLE do { \
@@ -93,7 +92,7 @@ static const char *istats_text[2][2][2] = {
(opts & PF_OPT_DUMMYACTION)) && \
(pfr_add_table(&table, &nadd, flags)) && \
(errno != EPERM)) { \
- radix_perror(); \
+ warnx("%s", pf_strerror(errno)); \
goto _error; \
} \
if (nadd) { \
@@ -559,13 +558,6 @@ print_astats(struct pfr_astats *as, int dns)
(unsigned long long)as->pfras_bytes[dir][op]);
}
-void
-radix_perror(void)
-{
- extern char *__progname;
- fprintf(stderr, "%s: %s.\n", __progname, pfr_strerror(errno));
-}
-
int
pfctl_define_table(char *name, int flags, int addrs, const char *anchor,
struct pfr_buffer *ab, u_int32_t ticket)
@@ -647,10 +639,8 @@ pfctl_show_ifaces(const char *filter, int opts)
for (;;) {
pfr_buf_grow(&b, b.pfrb_size);
b.pfrb_size = b.pfrb_msize;
- if (pfi_get_ifaces(filter, b.pfrb_caddr, &b.pfrb_size)) {
- radix_perror();
- exit(1);
- }
+ if (pfi_get_ifaces(filter, b.pfrb_caddr, &b.pfrb_size))
+ errx(1, "%s", pf_strerror(errno));
if (b.pfrb_size <= b.pfrb_msize)
break;
}
diff --git a/sbin/pfctl/tests/files/pf0088.in b/sbin/pfctl/tests/files/pf0088.in
index 4700b6916b7e..a85aa84a30bb 100644
--- a/sbin/pfctl/tests/files/pf0088.in
+++ b/sbin/pfctl/tests/files/pf0088.in
@@ -16,7 +16,7 @@ pass to 10.0.0.2 keep state
block from 10.0.0.3 to 10.0.0.2
pass to 10.0.0.2 modulate state
block from 10.0.0.3 to 10.0.0.2
-pass to 10.0.0.2 synproxy state
+pass in to 10.0.0.2 synproxy state
pass out proto tcp from 10.0.0.4 to 10.0.0.5 keep state
diff --git a/sbin/pfctl/tests/files/pf0088.ok b/sbin/pfctl/tests/files/pf0088.ok
index 47251a4503dd..801056a4ab46 100644
--- a/sbin/pfctl/tests/files/pf0088.ok
+++ b/sbin/pfctl/tests/files/pf0088.ok
@@ -11,7 +11,7 @@ pass inet from any to 10.0.0.2 flags S/SA keep state
block drop inet from 10.0.0.3 to 10.0.0.2
pass inet from any to 10.0.0.2 flags S/SA modulate state
block drop inet from 10.0.0.3 to 10.0.0.2
-pass inet from any to 10.0.0.2 flags S/SA synproxy state
+pass in inet from any to 10.0.0.2 flags S/SA synproxy state
pass out inet proto tcp from 10.0.0.4 to 10.0.0.5 flags S/SA keep state
pass out inet proto tcp from 10.0.0.4 to 10.0.0.5 port = http flags S/SA keep state
pass out all flags S/SA keep state
diff --git a/sbin/pfctl/tests/files/pf1072.fail b/sbin/pfctl/tests/files/pf1072.fail
new file mode 100644
index 000000000000..06ef5ae457e5
--- /dev/null
+++ b/sbin/pfctl/tests/files/pf1072.fail
@@ -0,0 +1 @@
+invalid port range
diff --git a/sbin/pfctl/tests/files/pf1072.in b/sbin/pfctl/tests/files/pf1072.in
new file mode 100644
index 000000000000..e09e92388ce1
--- /dev/null
+++ b/sbin/pfctl/tests/files/pf1072.in
@@ -0,0 +1 @@
+pass in proto tcp from any port 500:100 to any
diff --git a/sbin/pfctl/tests/pfctl_test_list.inc b/sbin/pfctl/tests/pfctl_test_list.inc
index 51729bc9adad..3a68cc06ec74 100644
--- a/sbin/pfctl/tests/pfctl_test_list.inc
+++ b/sbin/pfctl/tests/pfctl_test_list.inc
@@ -180,3 +180,4 @@ PFCTL_TEST(1068, "max-pkt-rate")
PFCTL_TEST(1069, "max-pkt-size")
PFCTL_TEST_FAIL(1070, "include line number")
PFCTL_TEST(1071, "mask length on (lo0)")
+PFCTL_TEST_FAIL(1072, "Invalid port range")
diff --git a/sbin/route/route_netlink.c b/sbin/route/route_netlink.c
index 631c2860b547..ba22a2ec1e22 100644
--- a/sbin/route/route_netlink.c
+++ b/sbin/route/route_netlink.c
@@ -738,6 +738,7 @@ print_nlmsg(struct nl_helper *h, struct nlmsghdr *hdr, struct snl_msg_info *cinf
print_nlmsg_generic(h, hdr, cinfo);
}
+ fflush(stdout);
snl_clear_lb(&h->ss_cmd);
}
diff --git a/sbin/savecore/savecore.8 b/sbin/savecore/savecore.8
index 53d2360719dd..1fb79c51f98d 100644
--- a/sbin/savecore/savecore.8
+++ b/sbin/savecore/savecore.8
@@ -25,7 +25,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd April 4, 2022
+.Dd July 16, 2025
.Dt SAVECORE 8
.Os
.Sh NAME
@@ -69,7 +69,7 @@ Generate output via
.Xr libxo 3
in a selection of different human and machine readable formats.
See
-.Xr xo_parse_args 3
+.Xr xo_options 7
for details on command line arguments.
.It Fl C
Check to see if a dump exists,
@@ -193,7 +193,7 @@ is meant to be called near the end of the initialization file
.Xr zstd 1 ,
.Xr getbootfile 3 ,
.Xr libxo 3 ,
-.Xr xo_parse_args 3 ,
+.Xr xo_options 7 ,
.Xr mem 4 ,
.Xr textdump 4 ,
.Xr tar 5 ,
diff --git a/share/man/man4/Makefile b/share/man/man4/Makefile
index 7c8a8f3afc45..505e83a67369 100644
--- a/share/man/man4/Makefile
+++ b/share/man/man4/Makefile
@@ -594,6 +594,7 @@ MAN= aac.4 \
tws.4 \
udp.4 \
udplite.4 \
+ ${_ufshci.4} \
unionfs.4 \
ure.4 \
vale.4 \
@@ -746,7 +747,6 @@ MLINKS+=lge.4 if_lge.4
MLINKS+=lo.4 loop.4
MLINKS+=lp.4 plip.4
MLINKS+=malo.4 if_malo.4
-MLINKS+=md.4 vn.4
MLINKS+=mem.4 kmem.4
MLINKS+=mfi.4 mfi_linux.4 \
mfi.4 mfip.4
@@ -938,6 +938,10 @@ MLINKS+=hwt.4 spe.4
.endif
.endif
+.if ${MACHINE_CPUARCH} == "amd64" || ${MACHINE_CPUARCH} == "aarch64"
+_ufshci.4= ufshci.4
+.endif
+
.if ${MACHINE_CPUARCH} == "amd64" || ${MACHINE_CPUARCH} == "i386" || \
${MACHINE_CPUARCH} == "aarch64"
_gve.4= gve.4
@@ -980,11 +984,14 @@ _ccd.4= ccd.4
.if ${MK_CDDL} != "no"
_dtrace_provs= dtrace_audit.4 \
+ dtrace_dtrace.4 \
+ dtrace_fbt.4 \
dtrace_io.4 \
dtrace_ip.4 \
dtrace_kinst.4 \
dtrace_lockstat.4 \
dtrace_proc.4 \
+ dtrace_profile.4 \
dtrace_sched.4 \
dtrace_sctp.4 \
dtrace_tcp.4 \
diff --git a/share/man/man4/dtrace_dtrace.4 b/share/man/man4/dtrace_dtrace.4
new file mode 100644
index 000000000000..b8c31005b47e
--- /dev/null
+++ b/share/man/man4/dtrace_dtrace.4
@@ -0,0 +1,191 @@
+.\"
+.\" SPDX-License-Identifier: BSD-2-Clause
+.\"
+.\" Copyright (c) 2025 Mateusz Piotrowski <0mp@FreeBSD.org>
+.\"
+.Dd July 14, 2025
+.Dt DTRACE_DTRACE 4
+.Os
+.Sh NAME
+.Nm dtrace_dtrace
+.Nd a DTrace provider for BEGIN, END, and ERROR probes
+.Sh SYNOPSIS
+.Nm dtrace Ns Cm :::BEGIN
+.Nm dtrace Ns Cm :::END
+.Nm dtrace Ns Cm :::ERROR
+.Sh DESCRIPTION
+The
+.Nm dtrace
+provider implements three special probes related to the life cycle of the
+DTrace program itself.
+.Ss dtrace:::BEGIN
+The
+.Nm dtrace Ns Cm :::BEGIN
+probe fires at the beginning of a
+.Xr dtrace 1 ,
+program before tracing has begun.
+It provides a convenient place for initializing variables
+and printing column headers.
+.Pp
+Variables such as
+.Va stack
+or
+.Va execname
+cannot be relied upon in the execution context of the
+.Nm dtrace Ns Cm :::BEGIN
+probe.
+.Ss dtrace:::END
+The
+.Nm dtrace Ns Cm :::END
+probe fires at the end of a
+.Xr dtrace 1
+program, when all tracing has stopped.
+.Ss dtrace:::ERROR
+The
+.Nm dtrace Ns Cm :::ERROR
+probe fires when an unexpected runtime error occurs in another probe.
+.Pp
+The following table describes the arguments to
+.Nm dtrace Ns Cm :::ERROR .
+.Bl -column -offset indent "Argument" "Definition"
+.It Sy Argument Ta Sy Definition
+.It Fa arg1 Ta Enabled probe identifier (EPID)
+of the probe where the runtime error occurred
+.It Fa arg2 Ta Index of the action statement that caused the error
+.It Fa arg3 Ta DIF offset into the action if available (otherwise -1)
+.It Fa arg4 Ta Fault type
+.It Fa arg5 Ta Accessed address (or 0 if not applicable) when
+.Va arg4
+is of fault type
+.Dv DTRACEFLT_BADADDR , DTRACEFLT_BADALIGN , DTRACEFLT_KPRIV ,
+or
+.Dv DTRACEFLT_UPRIV
+.El
+.Pp
+The fault types are:
+.Bl -tag -offset indent -width "DTRACEFLT_NOSCRATCH" -compact
+.It Dv DTRACEFLT_UNKNOWN
+Unknown fault
+.It Dv DTRACEFLT_BADADDR
+Bad address
+.It Dv DTRACEFLT_BADALIGN
+Bad alignment
+.It Dv DTRACEFLT_ILLOP
+Illegal operation
+.It Dv DTRACEFLT_DIVZERO
+Divide-by-zero
+.It Dv DTRACEFLT_NOSCRATCH
+Out of scratch space
+.It Dv DTRACEFLT_KPRIV
+Illegal kernel access
+.It Dv DTRACEFLT_UPRIV
+Illegal user access
+.It Dv DTRACEFLT_TUPOFLOW
+Tuple stack overflow
+.It Dv DTRACEFLT_BADSTACK
+Bad stack
+.El
+.Sh FILES
+.Bl -tag -width '<sys/dtrace.h>'
+.It In sys/dtrace.h
+The header file containing the definitions of DTrace fault types.
+.El
+.Sh EXAMPLES
+.Ss Example 1 : Custom Column Headers
+The following script uses the
+.Nm dtrace Ns Cm :::BEGIN
+probe to print column headers.
+Note the pragma line setting the
+.Ql quiet
+option to disable the default column headers.
+.Bd -literal -offset 2n
+#pragma D option quiet
+
+dtrace:::BEGIN
+{
+ printf(" %12s %-20s %-20s %s\en",
+ "DELTA(us)", "OLD", "NEW", "TIMESTAMP");
+}
+.Ed
+.Ss Example 2 : Handling Runtime Errors with dtrace:::ERROR
+The following script causes a runtime error by dereferencing a pointer
+on address
+.Ad 19930908
+in the
+.Cm BEGIN
+probe.
+As a result, the
+.Cm ERROR
+probe fires and prints out
+.Dq Oops
+along with the probe arguments.
+At that point, the program ends and fires the
+.Cm END
+probe.
+.\" It might look weird to define ERROR first, but that is on purpose.
+.\" This way the probe IDs and EPIDs are a bit more mixed up
+.\" and are easier to understand.
+.Bd -literal -offset 2n
+ERROR
+{
+ printf("Oops\en");
+ printf("EPID (arg1): %d\en", arg1);
+ printf("Action index (arg2): %d\en", arg2);
+ printf("DIF offset (arg3): %d\en", arg3);
+ printf("Fault type (arg4): %d\en", arg4);
+ printf("Accessed address (arg5): %X\en", arg5);
+ exit(1);
+}
+BEGIN
+{
+ *(int *)0x19931101;
+}
+END {
+ printf("Bye");
+}
+.Ed
+.Pp
+This script will result in the following output:
+.Bd -literal -offset 2n
+CPU ID FUNCTION:NAME
+ 2 3 :ERROR Oops
+EPID (arg1): 2
+Action index (arg2): 1
+DIF offset (arg3): 16
+Fault type: 1
+arg5: 19931101
+
+dtrace: error on enabled probe ID 2 (ID 1: dtrace:::BEGIN): invalid address (0x19931101) in action #1 at DIF offset 16
+ 2 2 :END Bye
+.Ed
+.Sh SEE ALSO
+.Xr dtrace 1 ,
+.Xr tracing 7
+.Rs
+.%B The illumos Dynamic Tracing Guide
+.%O Chapter dtrace Provider
+.%D 2008
+.%U https://illumos.org/books/dtrace/chp-dtrace.html
+.Re
+.Sh AUTHORS
+This manual page was written by
+.An Mateusz Piotrowski Aq Mt 0mp@FreeBSD.org .
+.Sh CAVEATS
+The
+.Nm dtrace Ns Cm :::ERROR
+probe arguments cannot be accessed through the typed
+.Va args[]
+array.
+.Pp
+.Xr dtrace 1
+will not fire the
+.Nm dtrace Ns Cm :::ERROR
+probe recursively.
+If an error occurs in one of the action statements of the
+.Nm dtrace Ns Cm :::ERROR ,
+then
+.Xr dtrace 1
+will abort further processing of
+the
+.Nm dtrace Ns Cm :::ERROR
+probe's actions.
diff --git a/share/man/man4/dtrace_fbt.4 b/share/man/man4/dtrace_fbt.4
new file mode 100644
index 000000000000..3e35bb8c5bbc
--- /dev/null
+++ b/share/man/man4/dtrace_fbt.4
@@ -0,0 +1,332 @@
+.\"
+.\" SPDX-License-Identifier: BSD-2-Clause
+.\"
+.\" Copyright (c) 2025 Mateusz Piotrowski <0mp@FreeBSD.org>
+.\"
+.Dd July 16, 2025
+.Dt DTRACE_FBT 4
+.Os
+.Sh NAME
+.Nm dtrace_fbt
+.Nd a DTrace provider for dynamic kernel tracing based on function boundaries
+.Sh SYNOPSIS
+.Nm fbt Ns Cm \&: Ns Ar module Ns Cm \&: Ns Ar function Ns Cm \&:entry
+.Nm fbt Ns Cm \&: Ns Ar module Ns Cm \&: Ns Ar function Ns Cm \&:return
+.Sh DESCRIPTION
+The Function Boundary Tracing
+.Pq Nm fbt
+provider instruments the entry and return of almost every kernel function
+corresponding to an
+.Xr elf 5
+symbol in the kernel and loaded kernel modules.
+.Pp
+.Nm fbt Ns Cm \&: Ns Ar module Ns Cm \&: Ns Ar function Ns Cm \&:entry
+fires whenever the
+.Ar function
+is called.
+.Nm fbt Ns Cm \&: Ns Ar module Ns Cm \&: Ns Ar function Ns Cm \&:return
+fires when the
+.Ar function
+returns.
+.Pp
+The
+.Ar module
+in the probe description is either the name of the loaded kernel module
+or
+.Ql kernel
+for functions compiled into the kernel.
+.Ss Function Boundary Instrumentation
+The
+.Nm fbt
+will always instrument a function's entry, but
+its return will be intsrumented so long as it can find a
+.Ql ret
+instruction.
+.Pp
+In some cases,
+.Nm fbt
+cannot instrument a function's entry and/or return.
+Refer to subsection
+.Sx Frame Pointer
+for more details.
+.Ss Probe Arguments
+The arguments of the entry probe
+.Pq Nm fbt Ns Cm \&: Ns Ar module Ns Cm \&: Ns Ar function Ns Cm \&:entry
+are the arguments of the traced function call.
+.Bl -column -offset indent "Entry Probe Argument" "Definition"
+.It Sy Entry Probe Argument Ta Sy Definition
+.It Fa args[0] Ta Function's first argument, typed
+.Pq e.g., Xr malloc 9 Ap s Ft size_t Fa size
+.It Fa args[1] Ta Function's second argument, typed
+.Pq e.g., Xr malloc 9 Ap s Ft struct malloc_type Fa *type
+.It Fa args[2] Ta Function's third argument, typed
+.Pq e.g., Xr malloc 9 Ap s Ft int Fa flags
+.It Fa ... Ta ...
+.El
+.Pp
+The arguments of the return probe
+.Pq Nm fbt Ns Cm \&: Ns Ar module Ns Cm \&: Ns Ar function Ns Cm \&:return
+are
+.Fa args[0]
+.Po
+the offset of the firing return instruction within the function;
+useful to tell apart two different return statements in a single function
+.Pc
+and
+.Fa args[1]
+.Pq the return value, if any .
+.Bl -column -offset indent "Return Probe Argument" "Definition"
+.It Sy Return Probe Argument Ta Sy Definition
+.It Fa args[0] Ta Offset of the traced return instruction
+.It Fa args[1] Ta Function's return value
+.Po e.g., a kernel virtual address if returning from a successful
+.Xr malloc 9
+.Pc
+.El
+.Pp
+Subsection
+.Sx Example 2 : Getting Details About Probe's Arguments
+shows how to get probe's argument count and types directly with
+.Xr dtrace 1
+without having to resort to the reading function's source code
+or documentation.
+.Sh EXAMPLES
+.Ss Example 1 : Listing Available FBT Probes
+The following example shows how to list all the available
+.Nm fbt
+probes.
+.Bd -literal -offset 2n
+# dtrace -l -P fbt
+ ID PROVIDER MODULE FUNCTION NAME
+[...]
+31868 fbt kernel hammer_time entry
+31869 fbt kernel hammer_time return
+[...]
+.Ed
+.Pp
+Since
+.Fn hammer_time
+is a part of the kernel and not a separate loaded module, the
+.Ar module
+column displays
+.Ql kernel .
+.Ss Example 2 : Getting Details About Probe's Arguments
+The following example shows how to generate a program stability report of
+.Xr malloc 9 Ap s
+entry and return probes.
+Those reports are useful to view
+the probe's number of arguments and their types.
+.Bd -literal -offset 2n
+# dtrace -l -v -n fbt::malloc:entry
+[...]
+ Argument Types
+ args[0]: size_t
+ args[1]: struct malloc_type *
+ args[2]: int
+.Ed
+.Pp
+The count and types of
+.Nm fbt Ns Cm \&::malloc:entry
+arguments
+match the function signature of
+.Xr malloc 9 :
+.Va args[0]
+is
+.Ft size_t ,
+.Va args[1]
+is
+.Ft "struct malloc_type *" ,
+and
+.Va "args[2]"
+is
+.Ft int .
+.Bd -literal -offset 2n
+# dtrace -l -v -n fbt::malloc:return
+[...]
+ Argument Types
+ args[0]: int
+ args[1]: void *
+.Ed
+.Pp
+The
+.Cm return
+probe reports two arguments and their types:
+the return instruction offset
+.Pq the usual Ft int
+and the function's return value, which in this case is
+.Ft void * ,
+as
+.Xr malloc 9
+returns a kernel virtual address.
+.Ss Example 3 : Counting Kernel Slab Memory Allocation by Function
+.Bd -literal -offset 2n
+# dtrace -n 'fbt::kmem*:entry { @[probefunc] = count(); }'
+dtrace: description 'fbt::kmem*:entry ' matched 47 probes
+^C
+ kmem_alloc_contig 1
+ kmem_alloc_contig_domainset 1
+ kmem_cache_reap_active 1
+ kmem_alloc_contig_pages 2
+ kmem_free 2
+ kmem_std_destructor 19
+ kmem_std_constructor 26
+ kmem_cache_free 151
+ kmem_cache_alloc 181
+.Ed
+.Ss Example 4 : Counting Kernel Slab Memory Allocation by Calling Function
+.Bd -literal -offset 2n
+# dtrace -q -n 'fbt::kmem*:entry { @[caller] = count(); } END { printa("%40a %@16d\en", @); }'
+^C
+ kernel`contigmalloc+0x33 1
+ kernel`free+0xd3 1
+ kernel`kmem_alloc_contig+0x29 1
+kernel`kmem_alloc_contig_domainset+0x19a 1
+ zfs.ko`arc_reap_cb_check+0x16 1
+.Ed
+.Ss Example 5 : Counting Kernel malloc()'s by Calling Function
+.Bd -literal -offset 2n
+# dtrace -q -n 'fbt::malloc:entry { @[caller] = count(); } END { printa("%45a %@16d\en", @); }'
+^C
+ kernel`devclass_get_devices+0xa8 1
+ kernel`sys_ioctl+0xb7 1
+ dtrace.ko`dtrace_ioctl+0x15c1 1
+ dtrace.ko`dtrace_ioctl+0x972 2
+ dtrace.ko`dtrace_dof_create+0x35 2
+ kernel`kern_poll_kfds+0x2f0 4
+ kernel`kern_poll_kfds+0x28a 19
+.Ed
+.Ss Example 6 : Counting Kernel malloc()'s by Kernel Stack Trace
+.Bd -literal -offset 2n
+# dtrace -q -n 'fbt::malloc:entry { @[stack()] = count(); }'
+^C
+ dtrace.ko`dtrace_dof_create+0x35
+ dtrace.ko`dtrace_ioctl+0x827
+ kernel`devfs_ioctl+0xd1
+ kernel`VOP_IOCTL_APV+0x2a
+ kernel`vn_ioctl+0xb6
+ kernel`devfs_ioctl_f+0x1e
+ kernel`kern_ioctl+0x286
+ kernel`sys_ioctl+0x12f
+ kernel`amd64_syscall+0x169
+ kernel`0xffffffff81092b0b
+ 2
+.Ed
+.Ss Example 7 : Summarizing vmem_alloc()'s by Arena Name and Size Distribution
+.Bd -literal -offset 2n
+# dtrace -q -n 'fbt::vmem_alloc:entry { @[args[0]->vm_name] = quantize(arg1); }'
+^C
+
+ kernel arena dom
+ value ------------- Distribution ------------- count
+ 2048 | 0
+ 4096 |@@@@@@@@@@@@@@@@@@@@@@@@@@@ 4
+ 8192 |@@@@@@@@@@@@@ 2
+ 16384 | 0
+.Ed
+.Ss Example 8 : Measuring Total Time Spent Executing a Function
+This DTrace script measures the total time spent in
+.Fn vm_page*
+kernel functions.
+The
+.Fn quantize
+aggregation organizes the measurements into power-of-two buckets,
+providing a time distribution in nanoseconds for each function.
+.Bd -literal -offset 2n
+fbt::vm_page*:entry {
+ self->start = timestamp;
+}
+
+fbt::vm_page*:return /self->start/ {
+ @[probefunc] = quantize(timestamp - self->start);
+ self->start = 0;
+}
+.Ed
+.Sh SEE ALSO
+.Xr dtrace 1 ,
+.Xr dtrace_kinst 4 ,
+.Xr tracing 7
+.Rs
+.%A Brendan Gregg
+.%A Jim Mauro
+.%B DTrace: Dynamic Tracing in Oracle Solaris, Mac OS X and FreeBSD
+.%I Prentice Hall
+.%P pp. 898\(en903
+.%D 2011
+.%U https://www.brendangregg.com/dtracebook/
+.Re
+.Rs
+.%B The illumos Dynamic Tracing Guide
+.%O Chapter fbt Provider
+.%D 2008
+.%U https://illumos.org/books/dtrace/chp-fbt.html#chp-fbt
+.Re
+.Sh AUTHORS
+This manual page was written by
+.An Mateusz Piotrowski Aq Mt 0mp@FreeBSD.org .
+.Sh CAVEATS
+.Ss Stability and Portability
+.Nm fbt
+probes are by definition tightly coupled to kernel code; if the code underlying
+a script changes, the script may fail to run or may produce incorrect results.
+Scripts written for one version of
+.Fx
+might not work on others,
+and almost certainly will not work on other operating systems.
+.Pp
+Individual
+.Nm fbt
+probes often do not correspond nicely to logical system events.
+For example, consider a DTrace script which prints the destination
+address of every IP packet as the kernel hands them over
+to the network card driver (NIC).
+An
+.Nm fbt Ns -based
+implementation of such a script is a discouragingly difficult task:
+it involves instrumenting at least four different functions in different parts
+of the IPv4 and IPv6 code.
+At the same time, with the
+.Xr dtrace_ip 4
+provider the script is a simple one-liner:
+.Dl dtrace -n 'ip:::send {printf("%s", args[2]->ip_daddr);}'
+.Pp
+Make sure to review available
+.Xr dtrace 1
+providers first
+before implementing a custom script with the
+.Nm fbt
+provider.
+If none of the DTrace providers offer the desired probes,
+consider adding new statically-defined tracing probes
+.Pq Xr SDT 9 .
+.Ss Frame Pointer
+Inline functions are not instrumentable by
+.Nm fbt
+as they lack a frame pointer.
+A developer might explicitly disable inlining by adding the
+.Ql __noinline
+attribute to a function definition,
+but of course this requires a recompilation of the kernel.
+Building the kernel with
+.Fl fno-omit-frame-pointer
+is another way of preserving frame pointers.
+Note, that sometimes compilers will omit the frame pointer in leaf functions,
+even when configured with
+.Fl fno-omit-frame-pointer .
+.Pp
+Function returns via a tail call are also not instrumentable by
+.Nm fbt .
+As a result,
+a function might have an entry probe
+and a mix of instrumented and uninstrumentable returns.
+.Pp
+Use
+.Xr dtrace_kinst 4
+to trace arbitrary instructions inside kernel functions
+and work around some of the
+limitations
+of
+.Nm fbt .
+.Ss Tracing DTrace
+The
+.Nm fbt
+provider cannot attach to functions inside DTrace provider kernel modules.
diff --git a/share/man/man4/dtrace_kinst.4 b/share/man/man4/dtrace_kinst.4
index 9debbc1bd106..c2187689749b 100644
--- a/share/man/man4/dtrace_kinst.4
+++ b/share/man/man4/dtrace_kinst.4
@@ -22,7 +22,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd February 27, 2023
+.Dd July 16, 2025
.Dt DTRACE_KINST 4
.Os
.Sh NAME
@@ -43,10 +43,13 @@ creates probes on-demand, meaning it searches for and parses the function's
instructions each time
.Xr dtrace 1
is run, and not at module load time.
-This is in contrast to FBT's load-time parsing, since
+This is in contrast to
+.Xr dtrace_fbt 4 Ap s
+load-time parsing, since
.Nm kinst
can potentially create thousands of probes for just a single function, instead
-of up to two (entry and return) in the case of FBT.
+of up to two (entry and return) in the case of
+.Xr dtrace_fbt 4 .
A result of this is that
.Cm dtrace -l -P kinst
will not match any probes.
@@ -79,7 +82,8 @@ Trace all instructions in
# dtrace -n 'kinst::amd64_syscall:'
.Ed
.Sh SEE ALSO
-.Xr dtrace 1
+.Xr dtrace 1 ,
+.Xr dtrace_fbt 4
.Sh HISTORY
The
.Nm kinst
diff --git a/share/man/man4/dtrace_profile.4 b/share/man/man4/dtrace_profile.4
new file mode 100644
index 000000000000..07f86663d60a
--- /dev/null
+++ b/share/man/man4/dtrace_profile.4
@@ -0,0 +1,129 @@
+.\"
+.\" SPDX-License-Identifier: BSD-2-Clause
+.\"
+.\" Copyright (c) 2025 Mateusz Piotrowski <0mp@FreeBSD.org>
+.\"
+.Dd July 14, 2025
+.Dt DTRACE_PROFILE 4
+.Os
+.Sh NAME
+.Nm dtrace_profile
+.Nd a DTrace provider for firing probes at a given time interval
+.Sh SYNOPSIS
+.Nm profile Ns Cm :::profile- Ns Ar rate Ns Op Ar unit
+.Nm profile Ns Cm :::tick- Ns Ar rate Ns Op Ar unit
+.Sh DESCRIPTION
+The
+.Nm profile
+provider implements three special probes related to the life cycle of the
+DTrace program itself.
+.Ss Probes
+The
+.Nm profile Ns Cm :::profile
+probes fire on all CPUs and are suitable for measuring the whole system
+periodically.
+.Pp
+The
+.Nm profile Ns Cm :::tick
+probes fire on a single CPU, potentially a different one every time.
+They are useful, e.g., for printing partial results periodically.
+.Ss Rate and Time Units
+The
+.Nm profile
+provider probes will fire at the specified
+.Ar rate .
+.Pp
+The default unit is
+.Cm hz .
+The
+.Nm profile
+provider supports the following time units:
+.Bl -column -offset indent "ns, nsec" "Definition"
+.It Sy Time Unit Ta Sy Definition
+.It Cm ns , nsec Ta nanoseconds
+.It Cm us , usec Ta microseconds
+.It Cm ms , msec Ta milliseconds
+.It Cm s , sec Ta seconds
+.It Cm m , min Ta minutes
+.It Cm h , hour Ta hours
+.It Cm d , day Ta days
+.It Cm hz Ta Hertz (frequency per second)
+.El
+.Ss Probe Arguments
+The arguments of the
+.Nm profile
+provider probes
+are:
+.Bl -tag -width arg0
+.It Va arg0
+The PC (program counter) in the kernel when the probe triggered,
+or 0 if the process was not in the kernel at that time.
+.It Va arg1
+The PC in the user process when the probe triggered,
+or 0 if the process was in the kernel when the probe triggered.
+.El
+.Pp
+Use arguments
+.Va arg0
+and
+.Va arg1
+to tell if the
+.Nm profile
+provider probe fired in the kernel or in the userspace context.
+.Sh IMPLEMENTATION NOTES
+The
+.Xr sysctl 8
+variable
+.Va kern.dtrace.profile.aframes
+controls the number of skipped artificial frames for
+the
+.Nm profile
+provider.
+.Sh EXAMPLES
+.Ss Example 1 : Profiling On-CPU Kernel Stack Traces
+The following DTrace one-liner uses the
+.Nm profile
+provider to collect stack traces over 60 seconds.
+.\" XXX: Keep on one line for easier copy-pasting.
+.Bd -literal -offset indent
+dtrace -x stackframes=100 -n 'profile-197 /arg0/ {@[stack()] = count();} tick-60s {exit(0);}
+.Ed
+.Pp
+The system is profiled at the 197 Hz to avoid sampling in lockstep
+with other periodic activities.
+This unnatural frequency minimizes the chance of overlapping with other events.
+.Pp
+Option
+.Fl x Cm stackframes=100
+increases the maximum number of kernel stack frames to unwind during
+.Fn stack .
+.Pp
+Checking if
+.Ar arg0
+is not zero makes sure that profiling happens
+when the program is in the kernel context.
+.Pp
+Refer to
+.Lk https://www.brendangregg.com/flamegraphs.html
+to learn about generating flame graphs from the obtained stack traces.
+.Sh SEE ALSO
+.Xr dtrace 1 ,
+.Xr tracing 7
+.Rs
+.%B The illumos Dynamic Tracing Guide
+.%O Chapter profile Provider
+.%D 2008
+.%U https://www.illumos.org/books/dtrace/chp-profile.html
+.Re
+.Rs
+.%A Brendan Gregg
+.%A Jim Mauro
+.%B DTrace: Dynamic Tracing in Oracle Solaris, Mac OS X and FreeBSD
+.%I Prentice Hall
+.%P pp. 24\(en25
+.%D 2011
+.%U https://www.brendangregg.com/dtracebook/
+.Re
+.Sh AUTHORS
+This manual page was written by
+.An Mateusz Piotrowski Aq Mt 0mp@FreeBSD.org .
diff --git a/share/man/man4/hwt.4 b/share/man/man4/hwt.4
index df02a4672f36..299332c72542 100644
--- a/share/man/man4/hwt.4
+++ b/share/man/man4/hwt.4
@@ -3,7 +3,7 @@
.\"
.\" SPDX-License-Identifier: BSD-2-Clause
.\"
-.Dd July 7, 2025
+.Dd July 12, 2025
.Dt HWT 4
.Os
.Sh NAME
@@ -131,6 +131,7 @@ For SPE-only, the kernel is waiting for userspace to notify that it has copied
out a buffer to avoid data loss/overwriting buffers.
.El
.Sh SEE ALSO
+.Xr tracing 7 ,
.Xr hwt 8
.Sh HISTORY
The
diff --git a/share/man/man4/md.4 b/share/man/man4/md.4
index 0c99d61f8392..1da26ddda037 100644
--- a/share/man/man4/md.4
+++ b/share/man/man4/md.4
@@ -5,7 +5,7 @@
.\" this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
.\" ----------------------------------------------------------------------------
.\"
-.Dd January 8, 2020
+.Dd July 16, 2025
.Dt MD 4
.Os
.Sh NAME
@@ -158,7 +158,7 @@ installation process.
The
.Nm
driver did a hostile takeover of the
-.Xr vn 4
+.Sy vn
driver in
.Fx 5.0 .
.Sh AUTHORS
diff --git a/share/man/man4/snd_uaudio.4 b/share/man/man4/snd_uaudio.4
index 00329a6d8e40..7193c85fa4f0 100644
--- a/share/man/man4/snd_uaudio.4
+++ b/share/man/man4/snd_uaudio.4
@@ -1,3 +1,6 @@
+.\"
+.\" SPDX-License-Identifier: BSD-2-Clause
+.\"
.\" $NetBSD: uaudio.4,v 1.15 2002/02/12 19:53:57 jdolecek Exp $
.\"
.\" Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -27,32 +30,30 @@
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd February 15, 2025
+.Dd July 17, 2025
.Dt SND_UAUDIO 4
.Os
.Sh NAME
.Nm snd_uaudio
.Nd USB audio and MIDI device driver
.Sh SYNOPSIS
-To compile this driver into the kernel, place the following lines in your
-kernel configuration file:
-.Bd -ragged -offset indent
.Cd "device sound"
.Cd "device usb"
.Cd "device snd_uaudio"
-.Ed
.Pp
-Alternatively, to load the driver as a module at boot time, place the
-following line in
-.Xr loader.conf 5 :
-.Bd -literal -offset indent
-snd_uaudio_load="YES"
-.Ed
-.Sh DESCRIPTION
-The
-.Nm
-driver provides support for USB audio class devices and USB MIDI class devices.
+In
+.Xr rc.conf 5 :
+.Cd kld_list="snd_uaudio"
.Pp
+In
+.Xr sysctl.conf 5 :
+.Cd hw.usb.uaudio.buffer_ms
+.Cd hw.usb.uaudio.default_bits
+.Cd hw.usb.uaudio.default_channels
+.Cd hw.usb.uaudio.default_rate
+.Cd hw.usb.uaudio.handle_hid
+.Cd hw.usb.uaudio.debug
+.Sh DESCRIPTION
A USB audio device consists of a number of components: input terminals (e.g.\&
USB digital input), output terminals (e.g.\& speakers), and a number of units
in between (e.g.\& volume control).
@@ -68,6 +69,11 @@ sample rate and sample size.
Refer to the
.Ql USB Audio Class Specification
for more information.
+.Sh HARDWARE
+The
+.Nm
+driver provides support for USB audio class devices and
+USB MIDI class devices.
.Sh SYSCTL VARIABLES
The following settings can be entered at the
.Xr loader 8
diff --git a/share/man/man4/ufshci.4 b/share/man/man4/ufshci.4
new file mode 100644
index 000000000000..d008afbf8ace
--- /dev/null
+++ b/share/man/man4/ufshci.4
@@ -0,0 +1,181 @@
+.\"
+.\" Copyright (c) 2025, Samsung Electronics Co., Ltd.
+.\"
+.\" SPDX-License-Identifier: BSD-2-Clause
+.\"
+.\" ufshci driver man page.
+.\"
+.\" Author: Jaeyoon Choi <j_yoon.choi@samsung.com>
+.\"
+.Dd June 24, 2025
+.Dt UFSHCI 4
+.Os
+.Sh NAME
+.Nm ufshci
+.Nd Universal Flash Storage Host Controller Interface driver
+.Sh SYNOPSIS
+To compile this driver into the kernel,
+place the following line in the kernel configuration file:
+.Bd -ragged -offset indent
+.Cd "device ufshci"
+.Ed
+.Pp
+Or, to load the driver as a module at boot, place the following line in
+.Xr loader.conf 5 :
+.Bd -literal -offset indent
+ufshci_load="YES"
+.Ed
+.Sh DESCRIPTION
+Universal Flash Storage (UFS) is a low-power, high-performance storage
+standard composed of a host controller and a single target device.
+The
+.Nm
+initializes both the host controller and the target device, and handles I/O.
+It currently supports the UFS/UFSHCI 4.1 specification and all earlier
+revisions.
+.Pp
+The driver currently provides:
+.Bl -bullet
+.It
+Initialization of the host controller and the target device
+.It
+Handling of UFS Interconnect (UIC) commands
+.It
+Support for UTP Transfer Requests (UTR) and UTP Task Management Requests (UTMR)
+.It
+Support for the SCSI command set
+.It
+Operation in the legacy single-doorbell queue mode
+.It
+Support for the PCI Express bus
+.El
+.Pp
+After initialization, the controller is registered with the
+.Xr cam 4
+subsystem and its logical unit appears as the device node
+.Pa /dev/daX .
+.Pp
+The driver is under active development; upcoming work includes full
+UFS 4.1 feature coverage, additional power-management modes, and
+ACPI/FDT-based attach support.
+.Sh CONFIGURATION
+The
+.Nm
+driver currently operates with a single doorbell (one I/O-queue), so any
+tunables that change the queue count are ignored.
+When Multi-Circular Queue (MCQ) support is added and multiple queues
+become available, the following queue count tunable values will take effect:
+.Pp
+To force a single I/O queue pair shared by all CPUs, set the following
+tunable value in loader.conf(5):
+.Bd -literal -offset indent
+hw.ufshci.per_cpu_io_queues=0
+.Ed
+.Pp
+To assign more than one CPU per I/O queue pair, thereby reducing the
+number of MSI-X vectors consumed by the device, set the following tunable
+value in loader.conf(5):
+.Bd -literal -offset indent
+hw.ufshci.min_cpus_per_ioq=X
+.Ed
+.Pp
+To change the I/O command timeout value (in seconds), set the following tunable
+value in loader.conf(5):
+.Bd -literal -offset indent
+hw.ufshci.timeout_period=X
+.Ed
+.Pp
+To change the I/O command retry count, set the following tunable value in
+loader.conf(5):
+.Bd -literal -offset indent
+hw.ufshci.retry_count=X
+.Ed
+.Pp
+To force the driver to use legacy INTx interrupts, set the following tunable
+value in loader.conf(5):
+.br
+(Note: until MCQ support is available the driver always uses legacy INTx, so
+this value effectively remains 1)
+.Bd -literal -offset indent
+hw.ufshci.force_intx=1
+.Ed
+.Sh SYSCTL VARIABLES
+The following controller-level
+.Xr sysctl 8
+nodes are currently implemented:
+.Bl -tag -width indent
+.It Va dev.ufshci.0.num_failures
+(R) Number of command failures for the entire controller.
+.It Va dev.ufshci.0.num_retries
+(R) Number of command retries for the entire controller.
+.It Va dev.ufshci.0.num_intr_handler_calls
+(R) Number of times the interrupt handler has been called.
+.It Va dev.ufshci.0.num_cmds
+(R) Total number of commands issued by the controller.
+.It Va dev.ufshci.0.timeout_period
+(RW) Configured timeout period (in seconds).
+.It Va dev.ufshci.0.cap
+(R) Host controller capabilities register value.
+.It Va dev.ufshci.0.num_io_queues
+(R) Number of I/O-queue pairs.
+.It Va dev.ufshci.0.io_queue_mode
+(R) Indicates single doorbell mode or multi circular queue mode.
+.It Va dev.ufshci.0.minor_version
+(R) Host controller minor version.
+.It Va dev.ufshci.0.major_version
+(R) Host controller major version.
+.It Va dev.ufshci.0.utmrq.num_failures
+(R) Number of failed UTP task-management requests.
+.It Va dev.ufshci.0.utmrq.ioq.num_retries
+(R) Number of retried UTP task-management requests.
+.It Va dev.ufshci.0.utmrq.num_intr_handler_calls
+(R) Number of interrupt handler calls caused by UTP task-management requests.
+.It Va dev.ufshci.0.utmrq.num_cmds
+(R) Number of UTP task-management requests issued.
+.It Va dev.ufshci.0.utmrq.cq_head
+(R) Current location of the UTP task-management completion queue head.
+.It Va dev.ufshci.0.utmrq.sq_tail
+(R) Current location of the UTP task-management submission queue tail.
+.It Va dev.ufshci.0.utmrq.sq_head
+(R) Current location of the UTP task-management submission queue head.
+.It Va dev.ufshci.0.utmrq.num_trackers
+(R) Number of trackers in the UTP task-management queue.
+.It Va dev.ufshci.0.utmrq.num_entries
+(R) Number of entries in the UTP task-management queue.
+.It Va dev.ufshci.0.ioq.0.num_failures
+(R) Number of failed UTP transfer requests.
+.It Va dev.ufshci.0.ioq.0.num_retries
+(R) Number of retried UTP transfer requests.
+.It Va dev.ufshci.0.ioq.0.num_intr_handler_calls
+(R) Number of interrupt-handler calls caused by UTP transfer requests.
+.It Va dev.ufshci.0.ioq.0.num_cmds
+(R) Number of UTP transfer requests issued.
+.It Va dev.ufshci.0.ioq.0.cq_head
+(R) Current location of the UTP transfer completion queue head.
+.It Va dev.ufshci.0.ioq.0.sq_tail
+(R) Current location of the UTP transfer submission queue tail.
+.It Va dev.ufshci.0.ioq.0.sq_head
+(R) Current location of the UTP transfer submission queue head.
+.It Va dev.ufshci.0.ioq.0.num_trackers
+(R) Number of trackers in the UTP transfer queue.
+.It Va dev.ufshci.0.ioq.0.num_entries
+(R) Number of entries in the UTP transfer queue.
+.El
+.Sh SEE ALSO
+.Xr cam 4 ,
+.Xr pci 4 ,
+.Xr disk 9
+.Sh HISTORY
+The
+.Nm
+driver first appeared in
+.Fx 15.0 .
+.Sh AUTHORS
+.An -nosplit
+The
+.Nm
+driver was developed by Samsung Electronics and originally written by
+.An Jaeyoon Choi Aq Mt j_yoon.choi@samsung.com .
+.Pp
+This manual page was written by
+.An Jaeyoon Choi Aq Mt j_yoon.choi@samsung.com .
diff --git a/share/man/man5/pf.conf.5 b/share/man/man5/pf.conf.5
index fe848b030484..11e22ebc78bf 100644
--- a/share/man/man5/pf.conf.5
+++ b/share/man/man5/pf.conf.5
@@ -27,7 +27,7 @@
.\" ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd July 2, 2025
+.Dd July 9, 2025
.Dt PF.CONF 5
.Os
.Sh NAME
@@ -2047,6 +2047,21 @@ connections:
block out proto { tcp, udp } all
pass out proto { tcp, udp } all user { < 1000, dhartmei }
.Ed
+.Pp
+The example below permits users with uid between 1000 and 1500
+to open connections:
+.Bd -literal -offset indent
+block out proto tcp all
+pass out proto tcp from self user { 999 >< 1501 }
+.Ed
+.Pp
+The
+.Sq \&:
+operator, which works for port number matching, does not work for
+.Cm user
+and
+.Cm group
+match.
.It Xo Ar flags Aq Ar a
.Pf / Ns Aq Ar b
.No \*(Ba / Ns Aq Ar b
@@ -2107,10 +2122,10 @@ options, or scrubbed with
will also not be recoverable from intermediate packets.
Such connections will stall and time out.
.It Xo Ar icmp-type Aq Ar type
-.Ar code Aq Ar code
+.Ar Op code Aq Ar code
.Xc
.It Xo Ar icmp6-type Aq Ar type
-.Ar code Aq Ar code
+.Ar Op code Aq Ar code
.Xc
This rule only applies to ICMP or ICMPv6 packets with the specified type
and code.
@@ -2559,6 +2574,7 @@ will not work if
.Xr pf 4
operates on a
.Xr bridge 4 .
+Also they act on incoming SYN packets only.
.Pp
Example:
.Bd -literal -offset indent
diff --git a/share/man/man5/rc.conf.5 b/share/man/man5/rc.conf.5
index 2fd63e4f743d..de2181d638d1 100644
--- a/share/man/man5/rc.conf.5
+++ b/share/man/man5/rc.conf.5
@@ -22,7 +22,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd May 21, 2025
+.Dd July 15, 2025
.Dt RC.CONF 5
.Os
.Sh NAME
@@ -1164,8 +1164,8 @@ and
is not found.
Multiple rules can be set as follows:
.Bd -literal
-pf_fallback_rules="\\
- block drop log all\\
+pf_fallback_rules="
+ block drop log all
pass in quick on em0"
.Pp
.Ed
diff --git a/share/man/man5/src.conf.5 b/share/man/man5/src.conf.5
index 63e9f471f1f1..a3db00aed42f 100644
--- a/share/man/man5/src.conf.5
+++ b/share/man/man5/src.conf.5
@@ -1,5 +1,5 @@
.\" DO NOT EDIT-- this file is @generated by tools/build/options/makeman.
-.Dd July 5, 2025
+.Dd July 14, 2025
.Dt SRC.CONF 5
.Os
.Sh NAME
@@ -493,7 +493,7 @@ Do not build
.Xr cxgbetool 8
.Pp
This is a default setting on
-arm/armv7, powerpc/powerpc and riscv/riscv64.
+arm/armv7 and riscv/riscv64.
.It Va WITH_CXGBETOOL
Build
.Xr cxgbetool 8
@@ -655,7 +655,7 @@ and
.Xr efivar 8 .
.Pp
This is a default setting on
-i386/i386, powerpc/powerpc, powerpc/powerpc64 and powerpc/powerpc64le.
+i386/i386, powerpc/powerpc64 and powerpc/powerpc64le.
.It Va WITH_EFI
Build
.Xr efivar 3
@@ -687,7 +687,7 @@ Build Flattened Device Tree support as part of the base system.
This includes the device tree compiler (dtc) and libfdt support library.
.Pp
This is a default setting on
-arm/armv7, arm64/aarch64, powerpc/powerpc, powerpc/powerpc64, powerpc/powerpc64le and riscv/riscv64.
+arm/armv7, arm64/aarch64, powerpc/powerpc64, powerpc/powerpc64le and riscv/riscv64.
.It Va WITHOUT_FILE
Do not build
.Xr file 1
@@ -750,7 +750,7 @@ Do not build HTML docs.
Do not build or install HyperV utilities.
.Pp
This is a default setting on
-arm/armv7, powerpc/powerpc, powerpc/powerpc64, powerpc/powerpc64le and riscv/riscv64.
+arm/armv7, powerpc/powerpc64, powerpc/powerpc64le and riscv/riscv64.
.It Va WITH_HYPERV
Build or install HyperV utilities.
.Pp
@@ -916,7 +916,7 @@ On 64-bit platforms, do not build 32-bit library set and a
runtime linker.
.Pp
This is a default setting on
-arm/armv7, i386/i386, powerpc/powerpc, powerpc/powerpc64le and riscv/riscv64.
+arm/armv7, i386/i386, powerpc/powerpc64le and riscv/riscv64.
.It Va WITH_LIB32
On 64-bit platforms, build the 32-bit library set and a
.Nm ld-elf32.so.1
@@ -935,7 +935,7 @@ arm/armv7 and riscv/riscv64.
Build the LLDB debugger.
.Pp
This is a default setting on
-amd64/amd64, arm64/aarch64, i386/i386, powerpc/powerpc, powerpc/powerpc64 and powerpc/powerpc64le.
+amd64/amd64, arm64/aarch64, i386/i386, powerpc/powerpc64 and powerpc/powerpc64le.
.It Va WITHOUT_LLD_BOOTSTRAP
Do not build the LLD linker during the bootstrap phase of
the build.
@@ -1038,7 +1038,7 @@ with support for verification based on certificates obtained from UEFI.
Disable inclusion of GELI crypto support in the boot chain binaries.
.Pp
This is a default setting on
-powerpc/powerpc, powerpc/powerpc64 and powerpc/powerpc64le.
+powerpc/powerpc64 and powerpc/powerpc64le.
.It Va WITH_LOADER_GELI
Build GELI bootloader support.
.Pp
@@ -1048,7 +1048,7 @@ amd64/amd64, arm/armv7, arm64/aarch64, i386/i386 and riscv/riscv64.
Do not build the 32-bit UEFI loader.
.Pp
This is a default setting on
-arm/armv7, arm64/aarch64, i386/i386, powerpc/powerpc, powerpc/powerpc64, powerpc/powerpc64le and riscv/riscv64.
+arm/armv7, arm64/aarch64, i386/i386, powerpc/powerpc64, powerpc/powerpc64le and riscv/riscv64.
.It Va WITH_LOADER_IA32
Build the 32-bit UEFI loader.
.Pp
@@ -1058,7 +1058,7 @@ amd64/amd64.
Do not build kboot, a linuxboot environment loader
.Pp
This is a default setting on
-arm/armv7, i386/i386, powerpc/powerpc, powerpc/powerpc64le and riscv/riscv64.
+arm/armv7, i386/i386, powerpc/powerpc64le and riscv/riscv64.
.It Va WITH_LOADER_KBOOT
Build kboot, a linuxboot environment loader
.Pp
@@ -1068,7 +1068,7 @@ amd64/amd64, arm64/aarch64 and powerpc/powerpc64.
Do not build LUA bindings for the boot loader.
.Pp
This is a default setting on
-powerpc/powerpc, powerpc/powerpc64 and powerpc/powerpc64le.
+powerpc/powerpc64 and powerpc/powerpc64le.
.It Va WITH_LOADER_LUA
Build LUA bindings for the boot loader.
.Pp
@@ -1083,7 +1083,7 @@ amd64/amd64, arm/armv7, arm64/aarch64, i386/i386 and riscv/riscv64.
Build openfirmware bootloader components.
.Pp
This is a default setting on
-powerpc/powerpc, powerpc/powerpc64 and powerpc/powerpc64le.
+powerpc/powerpc64 and powerpc/powerpc64le.
.It Va WITHOUT_LOADER_PXEBOOT
Do not build pxeboot on i386/amd64.
When the pxeboot is too large, or unneeded, it may be disabled with this option.
@@ -1104,7 +1104,7 @@ amd64/amd64, arm64/aarch64, i386/i386, powerpc/powerpc64le and riscv/riscv64.
Build ubldr.
.Pp
This is a default setting on
-arm/armv7, powerpc/powerpc and powerpc/powerpc64.
+arm/armv7 and powerpc/powerpc64.
.It Va WITH_LOADER_VERBOSE
Build with extra verbose debugging in the loader.
May explode already nearly too large loader over the limit.
@@ -1309,7 +1309,7 @@ Do not build
.Xr mlx5tool 8
.Pp
This is a default setting on
-arm/armv7, powerpc/powerpc and riscv/riscv64.
+arm/armv7 and riscv/riscv64.
.It Va WITH_MLX5TOOL
Build
.Xr mlx5tool 8
@@ -1401,7 +1401,7 @@ Build the
InfiniBand software stack, including kernel modules and userspace libraries.
.Pp
This is a default setting on
-amd64/amd64, arm64/aarch64, i386/i386, powerpc/powerpc, powerpc/powerpc64, powerpc/powerpc64le and riscv/riscv64.
+amd64/amd64, arm64/aarch64, i386/i386, powerpc/powerpc64, powerpc/powerpc64le and riscv/riscv64.
.It Va WITH_OFED_EXTRA
Build the non-essential components of the
.Dq "OpenFabrics Enterprise Distribution"
@@ -1412,7 +1412,7 @@ Enable building LDAP support for kerberos using an openldap client from ports.
Do not build LLVM's OpenMP runtime.
.Pp
This is a default setting on
-arm/armv7 and powerpc/powerpc.
+arm/armv7.
.It Va WITH_OPENMP
Build LLVM's OpenMP runtime.
.Pp
@@ -1465,7 +1465,7 @@ is set explicitly)
Do not include kernel TLS support in OpenSSL.
.Pp
This is a default setting on
-arm/armv7, i386/i386, powerpc/powerpc and riscv/riscv64.
+arm/armv7, i386/i386 and riscv/riscv64.
.It Va WITH_OPENSSL_KTLS
Include kernel TLS support in OpenSSL.
.Pp
@@ -1502,7 +1502,7 @@ Do not build dynamically linked binaries as
Position-Independent Executable (PIE).
.Pp
This is a default setting on
-arm/armv7, i386/i386 and powerpc/powerpc.
+arm/armv7 and i386/i386.
.It Va WITH_PIE
Build dynamically linked binaries as
Position-Independent Executable (PIE).
diff --git a/share/man/man5/style.Makefile.5 b/share/man/man5/style.Makefile.5
index cc5d2f6bb28a..fe8754924575 100644
--- a/share/man/man5/style.Makefile.5
+++ b/share/man/man5/style.Makefile.5
@@ -1,3 +1,6 @@
+.\"
+.\" SPDX-License-Identifier: BSD-3-Clause
+.\"
.\" Copyright (c) 2002-2003, 2023 David O'Brien <obrien@FreeBSD.org>
.\" All rights reserved.
.\"
@@ -30,10 +33,7 @@
.Os
.Sh NAME
.Nm style.Makefile
-.Nd
-.Fx
-.Pa Makefile
-file style guide
+.Nd FreeBSD Makefile style guide
.Sh DESCRIPTION
This file specifies the preferred style for makefiles in the
.Fx
diff --git a/share/man/man7/Makefile b/share/man/man7/Makefile
index 7daa0ffed8ea..1e50242a1754 100644
--- a/share/man/man7/Makefile
+++ b/share/man/man7/Makefile
@@ -6,6 +6,7 @@ MAN= arch.7 \
bsd.snmpmod.mk.7 \
build.7 \
c.7 \
+ d.7 \
clocks.7 \
crypto.7 \
development.7 \
diff --git a/share/man/man7/arch.7 b/share/man/man7/arch.7
index 91f6953370d9..fe4e8055a8b1 100644
--- a/share/man/man7/arch.7
+++ b/share/man/man7/arch.7
@@ -24,7 +24,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd April 12, 2025
+.Dd July 14, 2025
.Dt ARCH 7
.Os
.Sh NAME
@@ -67,8 +67,7 @@ and
should be avoided.
.Pp
On some architectures, e.g.,
-.Dv powerpc
-and AIM variants of
+AIM variants of
.Dv powerpc64 ,
the kernel uses a separate address space.
On other architectures, kernel and a user mode process share a
@@ -88,9 +87,6 @@ release to support each architecture.
.It aarch64 Ta 11.0
.It amd64 Ta 5.1
.It armv7 Ta 12.0
-.It i386 Ta 1.0
-.It powerpc Ta 6.0
-.It powerpcspe Ta 12.0
.It powerpc64 Ta 9.0
.It powerpc64le Ta 13.0
.It riscv64 Ta 12.0
@@ -104,6 +100,7 @@ Discontinued architectures are shown in the following table.
.It armeb Ta 8.0 Ta 11.4
.It armv6 Ta 10.0 Ta 14.x
.It ia64 Ta 5.0 Ta 10.4
+.It i386 Ta 1.0 Ta 14.x
.It mips Ta 8.0 Ta 13.5
.It mipsel Ta 9.0 Ta 13.5
.It mipselhf Ta 12.0 Ta 13.5
@@ -114,6 +111,8 @@ Discontinued architectures are shown in the following table.
.It mips64elhf Ta 12.0 Ta 13.5
.It mips64hf Ta 12.0 Ta 13.5
.It pc98 Ta 2.2 Ta 11.4
+.It powerpc Ta 6.0 Ta 14.x
+.It powerpcspe Ta 12.0 Ta 14.x
.It riscv64sf Ta 12.0 Ta 13.5
.It sparc64 Ta 5.0 Ta 12.4
.El
diff --git a/share/man/man7/d.7 b/share/man/man7/d.7
new file mode 100644
index 000000000000..f4686d98b1d1
--- /dev/null
+++ b/share/man/man7/d.7
@@ -0,0 +1,287 @@
+.\"
+.\" SPDX-License-Identifier: BSD-2-Clause
+.\"
+.\" Copyright (c) 2025 Mateusz Piotrowski <0mp@FreeBSD.org>
+.\"
+.Dd June 14, 2025
+.Dt D 7
+.Os
+.Sh NAME
+.Nm D
+.Nd DTrace scripting language overview
+.Sh SYNOPSIS
+.Sm off
+.Ar provider Cm \&:
+.Ar module Cm \&:
+.Ar function Cm \&:
+.Ar name
+.Sm on
+.Sm off
+.Oo
+.Cm /
+.Ar predicate
+.Cm /
+.Sm on
+.Oc
+.Op Cm \&{ Ns Ar action Ns Cm \&}
+.Sh DESCRIPTION
+.Nm D
+is the
+.Xr dtrace 1
+scripting language.
+This manual provides a brief reference of the
+.Nm
+language and scripting.
+.Pp
+This manual page serves as a short reference of the language.
+Refer to books listed in
+.Sx SEE ALSO
+for a complete reference.
+.Sh PROBE'S DESCRIPTION
+A probe's description consists of four elements:
+.Sm off
+.D1 Ar provider Ns Cm \&: Ns Ar module Cm \&: Ar function Cm \&: Ar name
+.Sm on
+.Pp
+The exact meaning of
+.Ar module ,
+.Ar function ,
+and
+.Ar name
+depends on
+.Ar provider .
+.Sh USER-DEFINED VARIABLE TYPES
+.Bl -column "thread-local" "Syntax"
+.It Sy Type Ta Sy Syntax
+.It global Ta Va variable_name
+.It thread-local Ta Sy self-> Ns Va variable_name
+.It clause-local Ta Sy this-> Ns Va variable_name
+.It aggregate Ta Sy @ Ns Va variable_name
+.El
+.Pp
+.Em Tips :
+.Bl -dash -compact
+.It
+Always use the variable type with the smallest scope
+to minimize processing overhead.
+.It
+Use aggregate variables instead of global variables when possible.
+Aggregate variables are multi-CPU safe in contrast to global variables.
+.El
+.Sh BUILT-IN VARIABLES
+.Ss Probe Arguments
+.Bl -tag -width "arg0, ..., arg9"
+.It Va args[]
+The array of typed probe arguments.
+.It Va arg0 , ... , arg9
+The untyped probe arguments represented as 64-bit unsigned integers.
+Only the first ten arguments are available this way.
+.El
+.Ss Probe Information
+.Bl -tag -width probeprov
+.It Va epid
+The enabled probe ID which uniquely identifies an enabled probe.
+An enabled probe is defined by its probe ID, its predicates, and its actions.
+.It Va id
+The probe ID which uniquely identifies a probe available to DTrace.
+.It Va probeprov
+The
+.Ar provider
+in the probe's description
+.Sm off
+.Pq Ar provider Cm \&: Ar module Cm \&: Ar function Cm \&: Ar name
+.Sm on .
+.It Va probemod
+The
+.Ar module
+in the probe's description
+.Sm off
+.Pq Ar provider Cm \&: Ar module Cm \&: Ar function Cm \&: Ar name
+.Sm on .
+.It Va probefunc
+The
+.Ar function
+in the probe's description
+.Sm off
+.Pq Ar provider Cm \&: Ar module Cm \&: Ar function Cm \&: Ar name
+.Sm on .
+.It Va probename
+The
+.Ar name
+in the probe's description
+.Sm off
+.Pq Ar provider Cm \&: Ar module Cm \&: Ar function Cm \&: Ar name
+.Sm on .
+.El
+.Ss Process Information
+.Bl -tag -width execname
+.It Va execargs
+The process arguments.
+Effectively,
+.Ql curthread->td_proc->p_args .
+.It Va execname
+The name of the current process.
+Effectively,
+.Ql curthread->td_proc->p_comm .
+.It Va gid
+The group ID of the current process.
+.It Va pid
+The process ID of the current process.
+.It Va ppid
+The parent process ID of the current process.
+.It Va uid
+The user ID of the current process.
+.El
+.Ss Thread Information
+.Bl -tag -width curlwpsinfo
+.It Va uregs[]
+The saved user-mode register values.
+.It Va cpu
+The ID of the current CPU.
+.It Va stackdepth
+The kernel stack frame depth.
+.It Va ustackdepth
+The userspace counterpart of
+.Va stackdepth .
+.It Va tid
+The thread ID.
+Depending on the context,
+this can be either the ID of a kernel thread or a thread in a user process.
+.It Va errno
+The
+.Xr errno 2
+value of the last system call performed by the current thread.
+.It Va curlwpsinfo
+A pointer to the
+.Vt lwpsinfo_t
+representation of the current thread.
+Refer to
+.Xr dtrace_proc 4
+for more details.
+.It Va curpsinfo
+A pointer to the
+.Vt psinfo_t
+representation of the current process.
+Refer to
+.Xr dtrace_proc 4
+for more details.
+.It Va curthread
+A pointer to the thread struct that is currently on-CPU.
+E.g.,
+.Ql curthread->td_name
+returns the thread name.
+The
+.In sys/proc.h
+header documents all members of
+.Vt struct thread .
+.It Va caller
+The address of the kernel thread instruction at the time of execution
+of the current probe.
+.It Va ucaller
+The userspace counterpart of
+.Va caller .
+.El
+.Ss Timestamps
+.Bl -tag -width walltimestamp
+.It Va timestamp
+The number of nanoseconds since boot.
+Suitable for calculating relative time differences of elapsed time and latency.
+.It Va vtimestamp
+The number of nanoseconds that the current thread spent on CPU.
+The counter is not increased during handling of a fired DTrace probe.
+Suitable for calculating relative time differences of on-CPU time.
+.It Va walltimestamp
+The number of nanoseconds since the Epoch
+.Pq 1970-01-01T00+00:00 .
+Suitable for timestamping logs.
+.El
+.Sh BUILT-IN FUNCTIONS
+.Ss Aggregation Functions
+.Bl -tag -compact -width "llquantize(value, factor, low, high, nsteps)"
+.It Fn avg value
+Average
+.It Fn count
+Count
+.It Fn llquantize value factor low high nsteps
+Log-linear quantization
+.It Fn lquantize value low high nsteps
+Linear quantization
+.It Fn max value
+Maximum
+.It Fn min value
+Minimum
+.It Fn quantize value
+Power-of-two frequency distribution
+.It Fn stddev value
+Standard deviation
+.It Fn sum value
+Sum
+.El
+.Ss Kernel Destructive Functions
+By default,
+.Xr dtrace 1
+does not permit the use of destructive actions.
+.Bl -tag -width "chill(nanoseconds)"
+.It Fn breakpoint
+Set a kernel breakpoint and transfer control to
+the
+.Xr ddb 4
+kernel debugger.
+.It Fn chill nanoseconds
+Spin on the CPU for the specified number of
+.Fa nanoseconds .
+.It Fn panic
+Panic the kernel.
+.El
+.Sh FILES
+.Bl -tag -width /usr/share/dtrace
+.It Pa /usr/share/dtrace
+DTrace scripts shipped with
+.Fx
+base.
+.El
+.Sh SEE ALSO
+.Xr awk 1 ,
+.Xr dtrace 1 ,
+.Xr tracing 7
+.Rs
+.%B The illumos Dynamic Tracing Guide
+.%D 2008
+.%U https://illumos.org/books/dtrace/
+.Re
+.Rs
+.%A Brendan Gregg
+.%A Jim Mauro
+.%B DTrace: Dynamic Tracing in Oracle Solaris, Mac OS X and FreeBSD
+.%I Prentice Hall
+.%D 2011
+.%U https://www.brendangregg.com/dtracebook/
+.Re
+.Rs
+.%A George Neville-Neil
+.%A Jonathan Anderson
+.%A Graeme Jenkinson
+.%A Brian Kidney
+.%A Domagoj Stolfa
+.%A Arun Thomas
+.%A Robert N. M. Watson
+.%C Cambridge, United Kingdom
+.%D August 2018
+.%T Univeristy of Cambridge Computer Laboratory
+.%R OpenDTrace Specification version 1.0
+.%U https://www.cl.cam.ac.uk/techreports/UCAM-CL-TR-924.pdf
+.Re
+.Sh HISTORY
+This manual page first appeared in
+.Fx 15.0 .
+.Sh AUTHORS
+.An -nosplit
+This manual page was written by
+.An Mateusz Piotrowski Aq Mt 0mp@FreeBSD.org .
+.Sh BUGS
+The
+.Va cwd
+variable which typically provides the current working directory is
+not supported on
+.Fx
+at the moment.
diff --git a/share/man/man7/intro.7 b/share/man/man7/intro.7
index d889c2dd299f..43e48de87bc5 100644
--- a/share/man/man7/intro.7
+++ b/share/man/man7/intro.7
@@ -25,7 +25,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd June 23, 2025
+.Dd July 14, 2025
.Dt INTRO 7
.Os
.Sh NAME
@@ -49,6 +49,9 @@ system timekeeping clocks available in
.It Xr crypto 7
cryptographic algorithms provided by OpenCrypto in
.Fx
+.It Xr d 7
+.Xr dtrace 1
+scripting language overview
.It Xr development 7
development introduction to
.Fx
diff --git a/share/man/man7/tracing.7 b/share/man/man7/tracing.7
index 0bd64f197084..7085bac78385 100644
--- a/share/man/man7/tracing.7
+++ b/share/man/man7/tracing.7
@@ -3,12 +3,12 @@
.\"
.\" Copyright (c) 2025 Mateusz Piotrowski <0mp@FreeBSD.org>
.\"
-.Dd June 19, 2025
+.Dd July 12, 2025
.Dt TRACING 7
.Os
.Sh NAME
.Nm tracing
-.Nd introduction to tracing and performance monitoring facilities
+.Nd introduction to FreeBSD tracing and performance monitoring
.Sh DESCRIPTION
.Fx
features a large variety of tracing and performance monitoring facilities.
@@ -34,7 +34,6 @@ for more details.
is a user-friendly wrapper for DTrace.
It simplifies common DTrace usage patterns and requires less expert knowledge
to operate.
-.Pp
.Ss Userland Tracing
.Xr truss 1
traces system calls.
@@ -55,7 +54,8 @@ it asynchronously logs entries to a trace file configured with
.Xr ktrace 2
(typically
.Pa ktrace.out ) ,
-and it can log other types of kernel events, such as page faults and name lookups
+and it can log other types of kernel events, such as page faults
+and name lookups
.Po refer to
.Fl t
in
@@ -73,11 +73,14 @@ It comes in handy for some niche purposes during kernel development.
It lets kernel programmers log events to a global ring buffer,
which can later be dumped using
.Xr ktrdump 8 .
+.Ss Hardware-Accelerated Tracing
+.Xr hwt 4
+is a kernel trace framework providing infrastructure
+for hardware-assisted tracing.
.Ss Hardware Counters
-.Pp
.Xr pmcstat 8 ,
and its kernel counterpart,
-.Xr hwmpc 4 ,
+.Xr hwpmc 4 ,
is the
.Fx
facility for conducting performance measurements with hardware counters.
diff --git a/share/man/man8/nanobsd.8 b/share/man/man8/nanobsd.8
index 2ba072541ada..838f9ddc9afa 100644
--- a/share/man/man8/nanobsd.8
+++ b/share/man/man8/nanobsd.8
@@ -1,3 +1,6 @@
+.\"
+.\" SPDX-License-Identifier: BSD-2-Clause
+.\"
.\" Copyright (c) 2006 Daniel Gerzo <danger@FreeBSD.org>
.\" All rights reserved.
.\"
@@ -22,13 +25,12 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd November 10, 2024
+.Dd July 14, 2025
.Dt NANOBSD 8
.Os
.Sh NAME
.Nm nanobsd.sh
-.Nd utility used to create a FreeBSD system image suitable for embedded
-applications
+.Nd create an embedded FreeBSD system image
.Sh SYNOPSIS
.Nm
.Op Fl BbfhIiKknqvWwX
diff --git a/share/man/man9/vnode.9 b/share/man/man9/vnode.9
index 5dd087725e92..d17492668298 100644
--- a/share/man/man9/vnode.9
+++ b/share/man/man9/vnode.9
@@ -24,7 +24,7 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd October 9, 2024
+.Dd July 15, 2025
.Dt VNODE 9
.Os
.Sh NAME
@@ -113,7 +113,7 @@ The
function declarations and definitions are generated from
.Pa sys/kern/vnode_if.src
by the
-.Pa sys/tools/vndoe_if.awk
+.Pa sys/tools/vnode_if.awk
script.
The interfaces are documented in their respective manual pages like
.Xr VOP_READ 9
diff --git a/share/mk/local.sys.machine.mk b/share/mk/local.sys.machine.mk
index 5e40dfe805f9..961362cb048a 100644
--- a/share/mk/local.sys.machine.mk
+++ b/share/mk/local.sys.machine.mk
@@ -7,9 +7,9 @@ TARGET_MACHINE_LIST?= amd64 arm arm64 i386 powerpc riscv
MACHINE_ARCH_host?= ${_HOST_ARCH}
MACHINE_ARCH_host32?= ${_HOST_ARCH32}
-MACHINE_ARCH_LIST_arm?= armv7 ${EXTRA_ARCHES_arm}
+MACHINE_ARCH_LIST_arm?= armv7
MACHINE_ARCH_LIST_arm64?= aarch64
-MACHINE_ARCH_LIST_powerpc?= powerpc powerpc64 powerpc64le ${EXTRA_ARCHES_powerpc}
+MACHINE_ARCH_LIST_powerpc?= powerpc64 powerpc64le ${EXTRA_ARCHES_powerpc}
MACHINE_ARCH_LIST_riscv?= riscv64
.for m in ${TARGET_MACHINE_LIST}
diff --git a/share/termcap/termcap b/share/termcap/termcap
index 9704d85c942f..46b89d0b3ddf 100644
--- a/share/termcap/termcap
+++ b/share/termcap/termcap
@@ -3549,8 +3549,7 @@ ti931|ti 931:\
# using \EPC\\ and \EPD\\, but I don't think there is a
# capability for that.
ti703|ti707|Texas Instruments Silent 703/707, 80 cols:\
- :am:hc:os:xn:\
- :co#80:it#8:\
+ :am:hc:os:xn:co#80:\
:do=\n:le=\b:cr=\r:nd= :bl=^G:ta=\t:is=\EPC\\:
ti703-w|ti707-w|Texas Instruments Silent 703/707, 132 cols:\
:co#132:is=\EPD\\:tc=ti703:
@@ -4808,6 +4807,26 @@ alacritty+common|base fragment for alacritty:\
:te=\E[?1049l\E[23;0;0t:ti=\E[?1049h\E[22;0;0t:\
:ts=\E]2;:ue=\E[24m:up=\E[A:us=\E[4m:vb=\E[?5h\E[?5l:\
:ve=\E[?12l\E[?25h:vi=\E[?25l:vs=\E[?12;25h:
+
+# From Tim Culverhouse <tim@timculverhouse.com>
+xterm-ghostty|ghostty|Ghostty:\
+ :am:hs:km:mi:ms:xn:\
+ :co#80:it#8:li#24:\
+ :AL=\E[%dL:DC=\E[%dP:DL=\E[%dM:DO=\E[%dB:IC=\E[%d@:\
+ :LE=\E[%dD:RI=\E[%dC:SF=\E[%dS:SR=\E[%dT:UP=\E[%dA:\
+ :ae=\E(B:al=\E[L:as=\E(0:bl=^G:bt=\E[Z:cd=\E[J:ce=\E[K:\
+ :cl=\E[H\E[2J:cm=\E[%i%d;%dH:cr=\r:cs=\E[%i%d;%dr:\
+ :ct=\E[3g:dc=\E[P:dl=\E[M:do=\n:ds=\E]2;\007:ec=\E[%dX:\
+ :ei=\E[4l:fs=^G:ho=\E[H:ic=\E[@:im=\E[4h:k1=\EOP:k2=\EOQ:\
+ :k3=\EOR:k4=\EOS:k5=\E[15~:k6=\E[17~:k7=\E[18~:k8=\E[19~:\
+ :k9=\E[20~:kD=\E[3~:kI=\E[2~:kN=\E[6~:kP=\E[5~:kb=\177:\
+ :kd=\EOB:ke=\E[?1l\E>:kh=\EOH:kl=\EOD:kr=\EOC:\
+ :ks=\E[?1h\E=:ku=\EOA:le=^H:mb=\E[5m:md=\E[1m:me=\E[0m:\
+ :mh=\E[2m:mr=\E[7m:nd=\E[C:rc=\E8:sc=\E7:se=\E[27m:sf=\n:\
+ :so=\E[7m:sr=\EM:st=\EH:ta=^I:te=\E[?1049l:ti=\E[?1049h:\
+ :ts=\E]2;:ue=\E[24m:up=\E[A:us=\E[4m:vb=\E[?5h\E[?5l:\
+ :ve=\E[?12l\E[?25h:vi=\E[?25l:vs=\E[?12;25h:
+
#
# END OF TERMCAP
# ------------------------
diff --git a/stand/libsa/zfs/zfsimpl.c b/stand/libsa/zfs/zfsimpl.c
index c7dc72561eff..971d71d098d3 100644
--- a/stand/libsa/zfs/zfsimpl.c
+++ b/stand/libsa/zfs/zfsimpl.c
@@ -1106,7 +1106,8 @@ vdev_insert(vdev_t *top_vdev, vdev_t *vdev)
}
static int
-vdev_from_nvlist(spa_t *spa, uint64_t top_guid, const nvlist_t *nvlist)
+vdev_from_nvlist(spa_t *spa, uint64_t top_guid, uint64_t txg,
+ const nvlist_t *nvlist)
{
vdev_t *top_vdev, *vdev;
nvlist_t **kids = NULL;
@@ -1120,6 +1121,7 @@ vdev_from_nvlist(spa_t *spa, uint64_t top_guid, const nvlist_t *nvlist)
return (rc);
top_vdev->v_spa = spa;
top_vdev->v_top = top_vdev;
+ top_vdev->v_txg = txg;
vdev_insert(spa->spa_root_vdev, top_vdev);
}
@@ -1163,7 +1165,7 @@ done:
static int
vdev_init_from_label(spa_t *spa, const nvlist_t *nvlist)
{
- uint64_t pool_guid, top_guid;
+ uint64_t pool_guid, top_guid, txg;
nvlist_t *vdevs;
int rc;
@@ -1171,13 +1173,15 @@ vdev_init_from_label(spa_t *spa, const nvlist_t *nvlist)
NULL, &pool_guid, NULL) ||
nvlist_find(nvlist, ZPOOL_CONFIG_TOP_GUID, DATA_TYPE_UINT64,
NULL, &top_guid, NULL) ||
+ nvlist_find(nvlist, ZPOOL_CONFIG_POOL_TXG, DATA_TYPE_UINT64,
+ NULL, &txg, NULL) != 0 ||
nvlist_find(nvlist, ZPOOL_CONFIG_VDEV_TREE, DATA_TYPE_NVLIST,
NULL, &vdevs, NULL)) {
printf("ZFS: can't find vdev details\n");
return (ENOENT);
}
- rc = vdev_from_nvlist(spa, top_guid, vdevs);
+ rc = vdev_from_nvlist(spa, top_guid, txg, vdevs);
nvlist_destroy(vdevs);
return (rc);
}
@@ -1267,6 +1271,21 @@ vdev_update_from_nvlist(uint64_t top_guid, const nvlist_t *nvlist)
return (rc);
}
+/*
+ * Shall not be called on root vdev, that is not linked into zfs_vdevs.
+ * See comment in vdev_create().
+ */
+static void
+vdev_free(struct vdev *vdev)
+{
+ struct vdev *kid, *safe;
+
+ STAILQ_FOREACH_SAFE(kid, &vdev->v_children, v_childlink, safe)
+ vdev_free(kid);
+ STAILQ_REMOVE(&zfs_vdevs, vdev, vdev, v_alllink);
+ free(vdev);
+}
+
static int
vdev_init_from_nvlist(spa_t *spa, const nvlist_t *nvlist)
{
@@ -1313,9 +1332,10 @@ vdev_init_from_nvlist(spa_t *spa, const nvlist_t *nvlist)
vdev = vdev_find(guid);
/*
* Top level vdev is missing, create it.
+ * XXXGL: how can this happen?
*/
if (vdev == NULL)
- rc = vdev_from_nvlist(spa, guid, kids[i]);
+ rc = vdev_from_nvlist(spa, guid, 0, kids[i]);
else
rc = vdev_update_from_nvlist(guid, kids[i]);
if (rc != 0)
@@ -2006,8 +2026,7 @@ vdev_probe(vdev_phys_read_t *_read, vdev_phys_write_t *_write, void *priv,
vdev_t *vdev;
nvlist_t *nvl;
uint64_t val;
- uint64_t guid;
- uint64_t pool_txg, pool_guid;
+ uint64_t guid, pool_guid, top_guid, txg;
const char *pool_name;
int rc, namelen;
@@ -2063,7 +2082,9 @@ vdev_probe(vdev_phys_read_t *_read, vdev_phys_write_t *_write, void *priv,
}
if (nvlist_find(nvl, ZPOOL_CONFIG_POOL_TXG, DATA_TYPE_UINT64,
- NULL, &pool_txg, NULL) != 0 ||
+ NULL, &txg, NULL) != 0 ||
+ nvlist_find(nvl, ZPOOL_CONFIG_TOP_GUID, DATA_TYPE_UINT64,
+ NULL, &top_guid, NULL) != 0 ||
nvlist_find(nvl, ZPOOL_CONFIG_POOL_GUID, DATA_TYPE_UINT64,
NULL, &pool_guid, NULL) != 0 ||
nvlist_find(nvl, ZPOOL_CONFIG_POOL_NAME, DATA_TYPE_STRING,
@@ -2098,9 +2119,22 @@ vdev_probe(vdev_phys_read_t *_read, vdev_phys_write_t *_write, void *priv,
nvlist_destroy(nvl);
return (ENOMEM);
}
+ } else {
+ struct vdev *kid;
+
+ STAILQ_FOREACH(kid, &spa->spa_root_vdev->v_children,
+ v_childlink)
+ if (kid->v_guid == top_guid && kid->v_txg < txg) {
+ printf("ZFS: pool %s vdev %s ignoring stale "
+ "label from txg 0x%jx, using 0x%jx@0x%jx\n",
+ spa->spa_name, kid->v_name,
+ kid->v_txg, guid, txg);
+ STAILQ_REMOVE(&spa->spa_root_vdev->v_children,
+ kid, vdev, v_childlink);
+ vdev_free(kid);
+ break;
+ }
}
- if (pool_txg > spa->spa_txg)
- spa->spa_txg = pool_txg;
/*
* Get the vdev tree and create our in-core copy of it.
diff --git a/sys/amd64/amd64/apic_vector.S b/sys/amd64/amd64/apic_vector.S
index 6e51ebff298a..5bb877a174f7 100644
--- a/sys/amd64/amd64/apic_vector.S
+++ b/sys/amd64/amd64/apic_vector.S
@@ -49,12 +49,6 @@
#include <machine/specialreg.h>
#include <x86/apicreg.h>
-#ifdef SMP
-#define LK lock ;
-#else
-#define LK
-#endif
-
.text
SUPERALIGN_TEXT
/* End Of Interrupt to APIC */
diff --git a/sys/amd64/amd64/mem.c b/sys/amd64/amd64/mem.c
index 413b7c74890e..851f2df0e6e1 100644
--- a/sys/amd64/amd64/mem.c
+++ b/sys/amd64/amd64/mem.c
@@ -105,8 +105,8 @@ memrw(struct cdev *dev, struct uio *uio, int flags)
* PAGE_SIZE, the uiomove() call does not
* access past the end of the direct map.
*/
- if (v >= DMAP_MIN_ADDRESS &&
- v < DMAP_MIN_ADDRESS + dmaplimit) {
+ if (v >= kva_layout.dmap_low &&
+ v < kva_layout.dmap_high) {
error = uiomove((void *)v, c, uio);
break;
}
diff --git a/sys/amd64/amd64/minidump_machdep.c b/sys/amd64/amd64/minidump_machdep.c
index 6d0917e16099..43bf81a991bf 100644
--- a/sys/amd64/amd64/minidump_machdep.c
+++ b/sys/amd64/amd64/minidump_machdep.c
@@ -186,7 +186,7 @@ cpu_minidumpsys(struct dumperinfo *di, const struct minidumpstate *state)
* tables, so care must be taken to read each entry only once.
*/
pmapsize = 0;
- for (va = VM_MIN_KERNEL_ADDRESS; va < kva_end; ) {
+ for (va = kva_layout.km_low; va < kva_end; ) {
/*
* We always write a page, even if it is zero. Each
* page written corresponds to 1GB of space
@@ -279,9 +279,9 @@ cpu_minidumpsys(struct dumperinfo *di, const struct minidumpstate *state)
mdhdr.msgbufsize = mbp->msg_size;
mdhdr.bitmapsize = round_page(BITSET_SIZE(vm_page_dump_pages));
mdhdr.pmapsize = pmapsize;
- mdhdr.kernbase = VM_MIN_KERNEL_ADDRESS;
- mdhdr.dmapbase = DMAP_MIN_ADDRESS;
- mdhdr.dmapend = DMAP_MAX_ADDRESS;
+ mdhdr.kernbase = kva_layout.km_low;
+ mdhdr.dmapbase = kva_layout.dmap_low;
+ mdhdr.dmapend = kva_layout.dmap_high;
mdhdr.dumpavailsize = round_page(sizeof(dump_avail));
dump_init_header(di, &kdh, KERNELDUMPMAGIC, KERNELDUMP_AMD64_VERSION,
@@ -323,7 +323,7 @@ cpu_minidumpsys(struct dumperinfo *di, const struct minidumpstate *state)
/* Dump kernel page directory pages */
bzero(fakepd, sizeof(fakepd));
- for (va = VM_MIN_KERNEL_ADDRESS; va < kva_end; va += NBPDP) {
+ for (va = kva_layout.km_low; va < kva_end; va += NBPDP) {
ii = pmap_pml4e_index(va);
pml4 = (uint64_t *)PHYS_TO_DMAP(KPML4phys) + ii;
pdp = (uint64_t *)PHYS_TO_DMAP(*pml4 & PG_FRAME);
diff --git a/sys/amd64/amd64/pmap.c b/sys/amd64/amd64/pmap.c
index 9c985df13ddf..2c7777e608b9 100644
--- a/sys/amd64/amd64/pmap.c
+++ b/sys/amd64/amd64/pmap.c
@@ -415,7 +415,7 @@ SYSCTL_INT(_machdep, OID_AUTO, nkpt, CTLFLAG_RD, &nkpt, 0,
static int ndmpdp;
vm_paddr_t dmaplimit;
-vm_offset_t kernel_vm_end = VM_MIN_KERNEL_ADDRESS;
+vm_offset_t kernel_vm_end = VM_MIN_KERNEL_ADDRESS_LA48;
pt_entry_t pg_nx;
static SYSCTL_NODE(_vm, OID_AUTO, pmap, CTLFLAG_RD | CTLFLAG_MPSAFE, 0,
@@ -475,11 +475,36 @@ _Static_assert(DMPML4I + NDMPML4E <= KMSANSHADPML4I, "direct map overflow");
static pml4_entry_t *kernel_pml4;
static u_int64_t DMPDphys; /* phys addr of direct mapped level 2 */
static u_int64_t DMPDPphys; /* phys addr of direct mapped level 3 */
+static u_int64_t DMPML4phys; /* ... level 4, for la57 */
static int ndmpdpphys; /* number of DMPDPphys pages */
vm_paddr_t kernphys; /* phys addr of start of bootstrap data */
vm_paddr_t KERNend; /* and the end */
+struct kva_layout_s kva_layout = {
+ .kva_min = KV4ADDR(PML4PML4I, 0, 0, 0),
+ .dmap_low = KV4ADDR(DMPML4I, 0, 0, 0),
+ .dmap_high = KV4ADDR(DMPML4I + NDMPML4E, 0, 0, 0),
+ .lm_low = KV4ADDR(LMSPML4I, 0, 0, 0),
+ .lm_high = KV4ADDR(LMEPML4I + 1, 0, 0, 0),
+ .km_low = KV4ADDR(KPML4BASE, 0, 0, 0),
+ .km_high = KV4ADDR(KPML4BASE + NKPML4E - 1, NPDPEPG - 1,
+ NPDEPG - 1, NPTEPG - 1),
+ .rec_pt = KV4ADDR(PML4PML4I, 0, 0, 0),
+};
+
+struct kva_layout_s kva_layout_la57 = {
+ .kva_min = KV5ADDR(NPML5EPG / 2, 0, 0, 0, 0), /* == rec_pt */
+ .dmap_low = KV5ADDR(DMPML5I, 0, 0, 0, 0),
+ .dmap_high = KV5ADDR(DMPML5I + NDMPML5E, 0, 0, 0, 0),
+ .lm_low = KV4ADDR(LMSPML4I, 0, 0, 0),
+ .lm_high = KV4ADDR(LMEPML4I + 1, 0, 0, 0),
+ .km_low = KV4ADDR(KPML4BASE, 0, 0, 0),
+ .km_high = KV4ADDR(KPML4BASE + NKPML4E - 1, NPDPEPG - 1,
+ NPDEPG - 1, NPTEPG - 1),
+ .rec_pt = KV5ADDR(PML5PML5I, 0, 0, 0, 0),
+};
+
/*
* pmap_mapdev support pre initialization (i.e. console)
*/
@@ -549,8 +574,8 @@ static int pmap_flags = PMAP_PDE_SUPERPAGE; /* flags for x86 pmaps */
static vmem_t *large_vmem;
static u_int lm_ents;
-#define PMAP_ADDRESS_IN_LARGEMAP(va) ((va) >= LARGEMAP_MIN_ADDRESS && \
- (va) < LARGEMAP_MIN_ADDRESS + NBPML4 * (u_long)lm_ents)
+#define PMAP_ADDRESS_IN_LARGEMAP(va) ((va) >= kva_layout.lm_low && \
+ (va) < kva_layout.lm_high)
int pmap_pcid_enabled = 1;
SYSCTL_INT(_vm_pmap, OID_AUTO, pcid_enabled, CTLFLAG_RDTUN | CTLFLAG_NOFETCH,
@@ -1336,7 +1361,7 @@ static pdp_entry_t *pmap_pti_pdpe(vm_offset_t va);
static pd_entry_t *pmap_pti_pde(vm_offset_t va);
static void pmap_pti_wire_pte(void *pte);
static int pmap_remove_pde(pmap_t pmap, pd_entry_t *pdq, vm_offset_t sva,
- bool remove_pt, struct spglist *free, struct rwlock **lockp);
+ bool demote_kpde, struct spglist *free, struct rwlock **lockp);
static int pmap_remove_pte(pmap_t pmap, pt_entry_t *ptq, vm_offset_t sva,
pd_entry_t ptepde, struct spglist *free, struct rwlock **lockp);
static vm_page_t pmap_remove_pt_page(pmap_t pmap, vm_offset_t va);
@@ -1722,7 +1747,7 @@ create_pagetables(vm_paddr_t *firstaddr)
{
pd_entry_t *pd_p;
pdp_entry_t *pdp_p;
- pml4_entry_t *p4_p;
+ pml4_entry_t *p4_p, *p4d_p;
pml5_entry_t *p5_p;
uint64_t DMPDkernphys;
vm_paddr_t pax;
@@ -1732,7 +1757,7 @@ create_pagetables(vm_paddr_t *firstaddr)
vm_offset_t kasankernbase;
int kasankpdpi, kasankpdi, nkasanpte;
#endif
- int i, j, ndm1g, nkpdpe, nkdmpde;
+ int i, j, ndm1g, nkpdpe, nkdmpde, ndmpml4phys;
TSENTER();
/* Allocate page table pages for the direct map */
@@ -1740,15 +1765,30 @@ create_pagetables(vm_paddr_t *firstaddr)
if (ndmpdp < 4) /* Minimum 4GB of dirmap */
ndmpdp = 4;
ndmpdpphys = howmany(ndmpdp, NPDPEPG);
- if (ndmpdpphys > NDMPML4E) {
- /*
- * Each NDMPML4E allows 512 GB, so limit to that,
- * and then readjust ndmpdp and ndmpdpphys.
- */
- printf("NDMPML4E limits system to %d GB\n", NDMPML4E * 512);
- Maxmem = atop(NDMPML4E * NBPML4);
- ndmpdpphys = NDMPML4E;
- ndmpdp = NDMPML4E * NPDEPG;
+ if (la57) {
+ ndmpml4phys = howmany(ndmpdpphys, NPML4EPG);
+ if (ndmpml4phys > NDMPML5E) {
+ printf("NDMPML5E limits system to %ld GB\n",
+ (u_long)NDMPML5E * NBPML5 / 1024 / 1024 / 1024);
+ Maxmem = atop(NDMPML5E * NBPML5);
+ ndmpml4phys = NDMPML5E;
+ ndmpdpphys = ndmpml4phys * NPML4EPG;
+ ndmpdp = ndmpdpphys * NPDEPG;
+ }
+ DMPML4phys = allocpages(firstaddr, ndmpml4phys);
+ } else {
+ if (ndmpdpphys > NDMPML4E) {
+ /*
+ * Each NDMPML4E allows 512 GB, so limit to
+ * that, and then readjust ndmpdp and
+ * ndmpdpphys.
+ */
+ printf("NDMPML4E limits system to %d GB\n",
+ NDMPML4E * 512);
+ Maxmem = atop(NDMPML4E * NBPML4);
+ ndmpdpphys = NDMPML4E;
+ ndmpdp = NDMPML4E * NPDEPG;
+ }
}
DMPDPphys = allocpages(firstaddr, ndmpdpphys);
ndm1g = 0;
@@ -1773,7 +1813,13 @@ create_pagetables(vm_paddr_t *firstaddr)
dmaplimit = (vm_paddr_t)ndmpdp << PDPSHIFT;
/* Allocate pages. */
+ if (la57) {
+ KPML5phys = allocpages(firstaddr, 1);
+ p5_p = (pml5_entry_t *)KPML5phys;
+ }
KPML4phys = allocpages(firstaddr, 1);
+ p4_p = (pml4_entry_t *)KPML4phys;
+
KPDPphys = allocpages(firstaddr, NKPML4E);
#ifdef KASAN
KASANPDPphys = allocpages(firstaddr, NKASANPML4E);
@@ -1893,6 +1939,16 @@ create_pagetables(vm_paddr_t *firstaddr)
}
/*
+ * Connect the Direct Map slots up to the PML4.
+ * pml5 entries for DMAP are handled below in global pml5 loop.
+ */
+ p4d_p = la57 ? (pml4_entry_t *)DMPML4phys : &p4_p[DMPML4I];
+ for (i = 0; i < ndmpdpphys; i++) {
+ p4d_p[i] = (DMPDPphys + ptoa(i)) | X86_PG_RW | X86_PG_V |
+ pg_nx;
+ }
+
+ /*
* Instead of using a 1G page for the memory containing the kernel,
* use 2M pages with read-only and no-execute permissions. (If using 1G
* pages, this will partially overwrite the PDPEs above.)
@@ -1911,11 +1967,6 @@ create_pagetables(vm_paddr_t *firstaddr)
}
}
- /* And recursively map PML4 to itself in order to get PTmap */
- p4_p = (pml4_entry_t *)KPML4phys;
- p4_p[PML4PML4I] = KPML4phys;
- p4_p[PML4PML4I] |= X86_PG_RW | X86_PG_V | pg_nx;
-
#ifdef KASAN
/* Connect the KASAN shadow map slots up to the PML4. */
for (i = 0; i < NKASANPML4E; i++) {
@@ -1938,25 +1989,15 @@ create_pagetables(vm_paddr_t *firstaddr)
}
#endif
- /* Connect the Direct Map slots up to the PML4. */
- for (i = 0; i < ndmpdpphys; i++) {
- p4_p[DMPML4I + i] = DMPDPphys + ptoa(i);
- p4_p[DMPML4I + i] |= X86_PG_RW | X86_PG_V | pg_nx;
- }
-
/* Connect the KVA slots up to the PML4 */
for (i = 0; i < NKPML4E; i++) {
p4_p[KPML4BASE + i] = KPDPphys + ptoa(i);
p4_p[KPML4BASE + i] |= X86_PG_RW | X86_PG_V;
}
- kernel_pml4 = (pml4_entry_t *)PHYS_TO_DMAP(KPML4phys);
-
if (la57) {
/* XXXKIB bootstrap KPML5phys page is lost */
- KPML5phys = allocpages(firstaddr, 1);
- for (i = 0, p5_p = (pml5_entry_t *)KPML5phys; i < NPML5EPG;
- i++) {
+ for (i = 0; i < NPML5EPG; i++) {
if (i == PML5PML5I) {
/*
* Recursively map PML5 to itself in
@@ -1964,6 +2005,10 @@ create_pagetables(vm_paddr_t *firstaddr)
*/
p5_p[i] = KPML5phys | X86_PG_RW | X86_PG_A |
X86_PG_M | X86_PG_V | pg_nx;
+ } else if (i >= DMPML5I && i < DMPML5I + NDMPML5E) {
+ /* Connect DMAP pml4 pages to PML5. */
+ p5_p[i] = (DMPML4phys + ptoa(i - DMPML5I)) |
+ X86_PG_RW | X86_PG_V | pg_nx;
} else if (i == pmap_pml5e_index(UPT_MAX_ADDRESS)) {
p5_p[i] = KPML4phys | X86_PG_RW | X86_PG_A |
X86_PG_M | X86_PG_V;
@@ -1971,6 +2016,10 @@ create_pagetables(vm_paddr_t *firstaddr)
p5_p[i] = 0;
}
}
+ } else {
+ /* Recursively map PML4 to itself in order to get PTmap */
+ p4_p[PML4PML4I] = KPML4phys;
+ p4_p[PML4PML4I] |= X86_PG_RW | X86_PG_V | pg_nx;
}
TSEXIT();
}
@@ -2024,7 +2073,7 @@ pmap_bootstrap(vm_paddr_t *firstaddr)
*/
virtual_avail = (vm_offset_t)KERNSTART + round_2mpage(KERNend -
(vm_paddr_t)kernphys);
- virtual_end = VM_MAX_KERNEL_ADDRESS;
+ virtual_end = kva_layout.km_high;
/*
* Enable PG_G global pages, then switch to the kernel page
@@ -2046,9 +2095,13 @@ pmap_bootstrap(vm_paddr_t *firstaddr)
* Initialize the kernel pmap (which is statically allocated).
* Count bootstrap data as being resident in case any of this data is
* later unmapped (using pmap_remove()) and freed.
+ *
+ * DMAP_TO_PHYS()/PHYS_TO_DMAP() are functional only after
+ * kva_layout is fixed.
*/
PMAP_LOCK_INIT(kernel_pmap);
if (la57) {
+ kva_layout = kva_layout_la57;
vtoptem = ((1ul << (NPTEPGSHIFT + NPDEPGSHIFT + NPDPEPGSHIFT +
NPML4EPGSHIFT + NPML5EPGSHIFT)) - 1) << 3;
PTmap = (vm_offset_t)P5Tmap;
@@ -2059,6 +2112,7 @@ pmap_bootstrap(vm_paddr_t *firstaddr)
kernel_pmap->pm_cr3 = KPML5phys;
pmap_pt_page_count_adj(kernel_pmap, 1); /* top-level page */
} else {
+ kernel_pml4 = (pml4_entry_t *)PHYS_TO_DMAP(KPML4phys);
kernel_pmap->pm_pmltop = kernel_pml4;
kernel_pmap->pm_cr3 = KPML4phys;
}
@@ -2420,6 +2474,7 @@ pmap_init(void)
{
struct pmap_preinit_mapping *ppim;
vm_page_t m, mpte;
+ pml4_entry_t *pml4e;
int error, i, ret, skz63;
/* L1TF, reserve page @0 unconditionally */
@@ -2559,18 +2614,19 @@ pmap_init(void)
printf("pmap: large map %u PML4 slots (%lu GB)\n",
lm_ents, (u_long)lm_ents * (NBPML4 / 1024 / 1024 / 1024));
if (lm_ents != 0) {
- large_vmem = vmem_create("large", LARGEMAP_MIN_ADDRESS,
- (vmem_size_t)lm_ents * NBPML4, PAGE_SIZE, 0, M_WAITOK);
+ large_vmem = vmem_create("large", kva_layout.lm_low,
+ (vmem_size_t)kva_layout.lm_high - kva_layout.lm_low,
+ PAGE_SIZE, 0, M_WAITOK);
if (large_vmem == NULL) {
printf("pmap: cannot create large map\n");
lm_ents = 0;
}
for (i = 0; i < lm_ents; i++) {
m = pmap_large_map_getptp_unlocked();
- /* XXXKIB la57 */
- kernel_pml4[LMSPML4I + i] = X86_PG_V |
- X86_PG_RW | X86_PG_A | X86_PG_M | pg_nx |
- VM_PAGE_TO_PHYS(m);
+ pml4e = pmap_pml4e(kernel_pmap, kva_layout.lm_low +
+ (u_long)i * NBPML4);
+ *pml4e = X86_PG_V | X86_PG_RW | X86_PG_A | X86_PG_M |
+ pg_nx | VM_PAGE_TO_PHYS(m);
}
}
}
@@ -3899,7 +3955,7 @@ pmap_kextract(vm_offset_t va)
pd_entry_t pde;
vm_paddr_t pa;
- if (va >= DMAP_MIN_ADDRESS && va < DMAP_MAX_ADDRESS) {
+ if (va >= kva_layout.dmap_low && va < kva_layout.dmap_high) {
pa = DMAP_TO_PHYS(va);
} else if (PMAP_ADDRESS_IN_LARGEMAP(va)) {
pa = pmap_large_map_kextract(va);
@@ -4040,7 +4096,7 @@ pmap_qremove(vm_offset_t sva, int count)
* enough to one of those pmap_enter() calls for it to
* be caught up in a promotion.
*/
- KASSERT(va >= VM_MIN_KERNEL_ADDRESS, ("usermode va %lx", va));
+ KASSERT(va >= kva_layout.km_low, ("usermode va %lx", va));
KASSERT((*vtopde(va) & X86_PG_PS) == 0,
("pmap_qremove on promoted va %#lx", va));
@@ -4328,21 +4384,13 @@ void
pmap_pinit_pml5(vm_page_t pml5pg)
{
pml5_entry_t *pm_pml5;
+ int i;
pm_pml5 = (pml5_entry_t *)PHYS_TO_DMAP(VM_PAGE_TO_PHYS(pml5pg));
-
- /*
- * Add pml5 entry at top of KVA pointing to existing pml4 table,
- * entering all existing kernel mappings into level 5 table.
- */
- pm_pml5[pmap_pml5e_index(UPT_MAX_ADDRESS)] = KPML4phys | X86_PG_V |
- X86_PG_RW | X86_PG_A | X86_PG_M;
-
- /*
- * Install self-referential address mapping entry.
- */
- pm_pml5[PML5PML5I] = VM_PAGE_TO_PHYS(pml5pg) |
- X86_PG_RW | X86_PG_V | X86_PG_M | X86_PG_A;
+ for (i = 0; i < NPML5EPG / 2; i++)
+ pm_pml5[i] = 0;
+ for (; i < NPML5EPG; i++)
+ pm_pml5[i] = kernel_pmap->pm_pmltop[i];
}
static void
@@ -4899,8 +4947,8 @@ pmap_release(pmap_t pmap)
m = PHYS_TO_VM_PAGE(DMAP_TO_PHYS((vm_offset_t)pmap->pm_pmltop));
if (pmap_is_la57(pmap)) {
- pmap->pm_pmltop[pmap_pml5e_index(UPT_MAX_ADDRESS)] = 0;
- pmap->pm_pmltop[PML5PML5I] = 0;
+ for (i = NPML5EPG / 2; i < NPML5EPG; i++)
+ pmap->pm_pmltop[i] = 0;
} else {
for (i = 0; i < NKPML4E; i++) /* KVA */
pmap->pm_pmltop[KPML4BASE + i] = 0;
@@ -4942,7 +4990,7 @@ pmap_release(pmap_t pmap)
static int
kvm_size(SYSCTL_HANDLER_ARGS)
{
- unsigned long ksize = VM_MAX_KERNEL_ADDRESS - VM_MIN_KERNEL_ADDRESS;
+ unsigned long ksize = kva_layout.km_high - kva_layout.km_low;
return sysctl_handle_long(oidp, &ksize, 0, req);
}
@@ -4953,7 +5001,7 @@ SYSCTL_PROC(_vm, OID_AUTO, kvm_size, CTLTYPE_LONG | CTLFLAG_RD | CTLFLAG_MPSAFE,
static int
kvm_free(SYSCTL_HANDLER_ARGS)
{
- unsigned long kfree = VM_MAX_KERNEL_ADDRESS - kernel_vm_end;
+ unsigned long kfree = kva_layout.km_high - kernel_vm_end;
return sysctl_handle_long(oidp, &kfree, 0, req);
}
@@ -5031,7 +5079,7 @@ pmap_page_array_startup(long pages)
vm_page_array_size = pages;
- start = VM_MIN_KERNEL_ADDRESS;
+ start = kva_layout.km_low;
end = start + pages * sizeof(struct vm_page);
for (va = start; va < end; va += NBPDR) {
pfn = first_page + (va - start) / sizeof(struct vm_page);
@@ -6067,8 +6115,8 @@ pmap_demote_pde_mpte(pmap_t pmap, pd_entry_t *pde, vm_offset_t va,
* so the direct map region is the only part of the
* kernel address space that must be handled here.
*/
- KASSERT(!in_kernel || (va >= DMAP_MIN_ADDRESS &&
- va < DMAP_MAX_ADDRESS),
+ KASSERT(!in_kernel || (va >= kva_layout.dmap_low &&
+ va < kva_layout.dmap_high),
("pmap_demote_pde: No saved mpte for va %#lx", va));
/*
@@ -6165,8 +6213,7 @@ pmap_demote_pde_mpte(pmap_t pmap, pd_entry_t *pde, vm_offset_t va,
* pmap_remove_kernel_pde: Remove a kernel superpage mapping.
*/
static void
-pmap_remove_kernel_pde(pmap_t pmap, pd_entry_t *pde, vm_offset_t va,
- bool remove_pt)
+pmap_remove_kernel_pde(pmap_t pmap, pd_entry_t *pde, vm_offset_t va)
{
pd_entry_t newpde;
vm_paddr_t mptepa;
@@ -6174,12 +6221,8 @@ pmap_remove_kernel_pde(pmap_t pmap, pd_entry_t *pde, vm_offset_t va,
KASSERT(pmap == kernel_pmap, ("pmap %p is not kernel_pmap", pmap));
PMAP_LOCK_ASSERT(pmap, MA_OWNED);
- if (remove_pt)
- mpte = pmap_remove_pt_page(pmap, va);
- else
- mpte = vm_radix_lookup(&pmap->pm_root, pmap_pde_pindex(va));
- if (mpte == NULL)
- panic("pmap_remove_kernel_pde: Missing pt page.");
+ mpte = pmap_remove_pt_page(pmap, va);
+ KASSERT(mpte != NULL, ("pmap_remove_kernel_pde: missing pt page"));
mptepa = VM_PAGE_TO_PHYS(mpte);
newpde = mptepa | X86_PG_M | X86_PG_A | X86_PG_RW | X86_PG_V;
@@ -6209,7 +6252,7 @@ pmap_remove_kernel_pde(pmap_t pmap, pd_entry_t *pde, vm_offset_t va,
* pmap_remove_pde: do the things to unmap a superpage in a process
*/
static int
-pmap_remove_pde(pmap_t pmap, pd_entry_t *pdq, vm_offset_t sva, bool remove_pt,
+pmap_remove_pde(pmap_t pmap, pd_entry_t *pdq, vm_offset_t sva, bool demote_kpde,
struct spglist *free, struct rwlock **lockp)
{
struct md_page *pvh;
@@ -6249,9 +6292,7 @@ pmap_remove_pde(pmap_t pmap, pd_entry_t *pdq, vm_offset_t sva, bool remove_pt,
pmap_delayed_invl_page(m);
}
}
- if (pmap == kernel_pmap) {
- pmap_remove_kernel_pde(pmap, pdq, sva, remove_pt);
- } else {
+ if (pmap != kernel_pmap) {
mpte = pmap_remove_pt_page(pmap, sva);
if (mpte != NULL) {
KASSERT(vm_page_any_valid(mpte),
@@ -6262,6 +6303,14 @@ pmap_remove_pde(pmap_t pmap, pd_entry_t *pdq, vm_offset_t sva, bool remove_pt,
mpte->ref_count = 0;
pmap_add_delayed_free_list(mpte, free, false);
}
+ } else if (demote_kpde) {
+ pmap_remove_kernel_pde(pmap, pdq, sva);
+ } else {
+ mpte = vm_radix_lookup(&pmap->pm_root, pmap_pde_pindex(sva));
+ if (vm_page_any_valid(mpte)) {
+ mpte->valid = 0;
+ pmap_zero_page(mpte);
+ }
}
return (pmap_unuse_pt(pmap, sva, *pmap_pdpe(pmap, sva), free));
}
@@ -7183,7 +7232,7 @@ pmap_enter(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot,
PG_RW = pmap_rw_bit(pmap);
va = trunc_page(va);
- KASSERT(va <= VM_MAX_KERNEL_ADDRESS, ("pmap_enter: toobig"));
+ KASSERT(va <= kva_layout.km_high, ("pmap_enter: toobig"));
KASSERT(va < UPT_MIN_ADDRESS || va >= UPT_MAX_ADDRESS,
("pmap_enter: invalid to pmap_enter page table pages (va: 0x%lx)",
va));
@@ -7573,8 +7622,8 @@ pmap_enter_pde(pmap_t pmap, vm_offset_t va, pd_entry_t newpde, u_int flags,
* the mapping is not from kernel_pmap, then
* a reserved PT page could be freed.
*/
- (void)pmap_remove_pde(pmap, pde, va,
- pmap != kernel_pmap, &free, lockp);
+ (void)pmap_remove_pde(pmap, pde, va, false, &free,
+ lockp);
if ((oldpde & PG_G) == 0)
pmap_invalidate_pde_page(pmap, va, oldpde);
} else {
@@ -7584,10 +7633,9 @@ pmap_enter_pde(pmap_t pmap, vm_offset_t va, pd_entry_t newpde, u_int flags,
* before any changes to mappings are
* made. Abort on failure.
*/
- mt = PHYS_TO_VM_PAGE(*pde & PG_FRAME);
- if (pmap_insert_pt_page(pmap, mt, false, false)) {
- if (pdpg != NULL)
- pdpg->ref_count--;
+ mt = PHYS_TO_VM_PAGE(oldpde & PG_FRAME);
+ if (pmap_insert_pt_page(pmap, mt, false,
+ false)) {
CTR1(KTR_PMAP,
"pmap_enter_pde: cannot ins kern ptp va %#lx",
va);
@@ -9550,7 +9598,7 @@ pmap_unmapdev(void *p, vm_size_t size)
va = (vm_offset_t)p;
/* If we gave a direct map region in pmap_mapdev, do nothing */
- if (va >= DMAP_MIN_ADDRESS && va < DMAP_MAX_ADDRESS)
+ if (va >= kva_layout.dmap_low && va < kva_layout.dmap_high)
return;
offset = va & PAGE_MASK;
size = round_page(offset + size);
@@ -9649,6 +9697,8 @@ pmap_demote_pdpe(pmap_t pmap, pdp_entry_t *pdpe, vm_offset_t va, vm_page_t m)
void
pmap_page_set_memattr(vm_page_t m, vm_memattr_t ma)
{
+ if (m->md.pat_mode == ma)
+ return;
m->md.pat_mode = ma;
@@ -9668,6 +9718,9 @@ pmap_page_set_memattr_noflush(vm_page_t m, vm_memattr_t ma)
{
int error;
+ if (m->md.pat_mode == ma)
+ return;
+
m->md.pat_mode = ma;
if ((m->flags & PG_FICTITIOUS) != 0)
@@ -9724,7 +9777,7 @@ pmap_change_prot(vm_offset_t va, vm_size_t size, vm_prot_t prot)
int error;
/* Only supported within the kernel map. */
- if (va < VM_MIN_KERNEL_ADDRESS)
+ if (va < kva_layout.km_low)
return (EINVAL);
PMAP_LOCK(kernel_pmap);
@@ -9755,7 +9808,7 @@ pmap_change_props_locked(vm_offset_t va, vm_size_t size, vm_prot_t prot,
* Only supported on kernel virtual addresses, including the direct
* map but excluding the recursive map.
*/
- if (base < DMAP_MIN_ADDRESS)
+ if (base < kva_layout.dmap_low)
return (EINVAL);
/*
@@ -9778,7 +9831,7 @@ pmap_change_props_locked(vm_offset_t va, vm_size_t size, vm_prot_t prot,
pte_bits |= X86_PG_RW;
}
if ((prot & VM_PROT_EXECUTE) == 0 ||
- va < VM_MIN_KERNEL_ADDRESS) {
+ va < kva_layout.km_low) {
pde_bits |= pg_nx;
pte_bits |= pg_nx;
}
@@ -9874,7 +9927,7 @@ pmap_change_props_locked(vm_offset_t va, vm_size_t size, vm_prot_t prot,
pmap_pte_props(pdpe, pde_bits, pde_mask);
changed = true;
}
- if (tmpva >= VM_MIN_KERNEL_ADDRESS &&
+ if (tmpva >= kva_layout.km_low &&
(*pdpe & PG_PS_FRAME) < dmaplimit) {
if (pa_start == pa_end) {
/* Start physical address run. */
@@ -9904,7 +9957,7 @@ pmap_change_props_locked(vm_offset_t va, vm_size_t size, vm_prot_t prot,
pmap_pte_props(pde, pde_bits, pde_mask);
changed = true;
}
- if (tmpva >= VM_MIN_KERNEL_ADDRESS &&
+ if (tmpva >= kva_layout.km_low &&
(*pde & PG_PS_FRAME) < dmaplimit) {
if (pa_start == pa_end) {
/* Start physical address run. */
@@ -9932,7 +9985,7 @@ pmap_change_props_locked(vm_offset_t va, vm_size_t size, vm_prot_t prot,
pmap_pte_props(pte, pte_bits, pte_mask);
changed = true;
}
- if (tmpva >= VM_MIN_KERNEL_ADDRESS &&
+ if (tmpva >= kva_layout.km_low &&
(*pte & PG_FRAME) < dmaplimit) {
if (pa_start == pa_end) {
/* Start physical address run. */
@@ -10904,8 +10957,8 @@ pmap_large_unmap(void *svaa, vm_size_t len)
struct spglist spgf;
sva = (vm_offset_t)svaa;
- if (len == 0 || sva + len < sva || (sva >= DMAP_MIN_ADDRESS &&
- sva + len <= DMAP_MIN_ADDRESS + dmaplimit))
+ if (len == 0 || sva + len < sva || (sva >= kva_layout.dmap_low &&
+ sva + len < kva_layout.dmap_high))
return;
SLIST_INIT(&spgf);
@@ -11151,11 +11204,10 @@ pmap_large_map_wb(void *svap, vm_size_t len)
sva = (vm_offset_t)svap;
eva = sva + len;
pmap_large_map_wb_fence();
- if (sva >= DMAP_MIN_ADDRESS && eva <= DMAP_MIN_ADDRESS + dmaplimit) {
+ if (sva >= kva_layout.dmap_low && eva < kva_layout.dmap_high) {
pmap_large_map_flush_range(sva, len);
} else {
- KASSERT(sva >= LARGEMAP_MIN_ADDRESS &&
- eva <= LARGEMAP_MIN_ADDRESS + lm_ents * NBPML4,
+ KASSERT(sva >= kva_layout.lm_low && eva < kva_layout.lm_high,
("pmap_large_map_wb: not largemap %#lx %#lx", sva, len));
pmap_large_map_wb_large(sva, eva);
}
@@ -11196,8 +11248,8 @@ pmap_pti_init(void)
VM_OBJECT_WLOCK(pti_obj);
pml4_pg = pmap_pti_alloc_page();
pti_pml4 = (pml4_entry_t *)PHYS_TO_DMAP(VM_PAGE_TO_PHYS(pml4_pg));
- for (va = VM_MIN_KERNEL_ADDRESS; va <= VM_MAX_KERNEL_ADDRESS &&
- va >= VM_MIN_KERNEL_ADDRESS && va > NBPML4; va += NBPML4) {
+ for (va = kva_layout.km_low; va <= kva_layout.km_high &&
+ va >= kva_layout.km_low && va > NBPML4; va += NBPML4) {
pdpe = pmap_pti_pdpe(va);
pmap_pti_wire_pte(pdpe);
}
diff --git a/sys/amd64/amd64/trap.c b/sys/amd64/amd64/trap.c
index 09ac0a67dbef..eefddad2f142 100644
--- a/sys/amd64/amd64/trap.c
+++ b/sys/amd64/amd64/trap.c
@@ -769,7 +769,7 @@ trap_pfault(struct trapframe *frame, bool usermode, int *signo, int *ucode)
return (-1);
}
}
- if (eva >= VM_MIN_KERNEL_ADDRESS) {
+ if (eva >= kva_layout.km_low) {
/*
* Don't allow user-mode faults in kernel address space.
*/
diff --git a/sys/amd64/include/param.h b/sys/amd64/include/param.h
index 8db314fa034d..1bbb302259d6 100644
--- a/sys/amd64/include/param.h
+++ b/sys/amd64/include/param.h
@@ -146,8 +146,9 @@
#define amd64_btop(x) ((unsigned long)(x) >> PAGE_SHIFT)
#define amd64_ptob(x) ((unsigned long)(x) << PAGE_SHIFT)
-#define INKERNEL(va) (((va) >= DMAP_MIN_ADDRESS && (va) < DMAP_MAX_ADDRESS) \
- || ((va) >= VM_MIN_KERNEL_ADDRESS && (va) < VM_MAX_KERNEL_ADDRESS))
+#define INKERNEL(va) \
+ (((va) >= kva_layout.dmap_low && (va) < kva_layout.dmap_high) || \
+ ((va) >= kva_layout.km_low && (va) < kva_layout.km_high))
#ifdef SMP
#define SC_TABLESIZE 1024 /* Must be power of 2. */
diff --git a/sys/amd64/include/pmap.h b/sys/amd64/include/pmap.h
index 7d3e91bcd9b9..08e96027a5ed 100644
--- a/sys/amd64/include/pmap.h
+++ b/sys/amd64/include/pmap.h
@@ -169,11 +169,12 @@
* the recursive page table map.
*/
#define NDMPML4E 8
+#define NDMPML5E 32
/*
- * These values control the layout of virtual memory. The starting address
- * of the direct map, which is controlled by DMPML4I, must be a multiple of
- * its size. (See the PHYS_TO_DMAP() and DMAP_TO_PHYS() macros.)
+ * These values control the layout of virtual memory. The starting
+ * address of the direct map is controlled by DMPML4I on LA48 and
+ * DMPML5I on LA57.
*
* Note: KPML4I is the index of the (single) level 4 page that maps
* the KVA that holds KERNBASE, while KPML4BASE is the index of the
@@ -191,6 +192,7 @@
#define KPML4BASE (NPML4EPG-NKPML4E) /* KVM at highest addresses */
#define DMPML4I rounddown(KPML4BASE-NDMPML4E, NDMPML4E) /* Below KVM */
+#define DMPML5I (NPML5EPG / 2 + 1)
#define KPML4I (NPML4EPG-1)
#define KPDPI (NPDPEPG-2) /* kernbase at -2GB */
@@ -548,6 +550,18 @@ pmap_pml5e_index(vm_offset_t va)
return ((va >> PML5SHIFT) & ((1ul << NPML5EPGSHIFT) - 1));
}
+struct kva_layout_s {
+ vm_offset_t kva_min;
+ vm_offset_t dmap_low; /* DMAP_MIN_ADDRESS */
+ vm_offset_t dmap_high; /* DMAP_MAX_ADDRESS */
+ vm_offset_t lm_low; /* LARGEMAP_MIN_ADDRESS */
+ vm_offset_t lm_high; /* LARGEMAP_MAX_ADDRESS */
+ vm_offset_t km_low; /* VM_MIN_KERNEL_ADDRESS */
+ vm_offset_t km_high; /* VM_MAX_KERNEL_ADDRESS */
+ vm_offset_t rec_pt;
+};
+extern struct kva_layout_s kva_layout;
+
#endif /* !LOCORE */
#endif /* !_MACHINE_PMAP_H_ */
diff --git a/sys/amd64/include/vmparam.h b/sys/amd64/include/vmparam.h
index 0cd9bb4fa7a4..e4cc05cbb889 100644
--- a/sys/amd64/include/vmparam.h
+++ b/sys/amd64/include/vmparam.h
@@ -163,6 +163,7 @@
* Virtual addresses of things. Derived from the page directory and
* page table indexes from pmap.h for precision.
*
+ * LA48:
* 0x0000000000000000 - 0x00007fffffffffff user map
* 0x0000800000000000 - 0xffff7fffffffffff does not exist (hole)
* 0xffff800000000000 - 0xffff804020100fff recursive page table (512GB slot)
@@ -175,18 +176,29 @@
* 0xfffffc0000000000 - 0xfffffdffffffffff 2TB KMSAN shadow map, optional
* 0xfffffe0000000000 - 0xffffffffffffffff 2TB kernel map
*
+ * LA57:
+ * 0x0000000000000000 - 0x00ffffffffffffff user map
+ * 0x0100000000000000 - 0xf0ffffffffffffff does not exist (hole)
+ * 0xff00000000000000 - 0xff00ffffffffffff recursive page table (2048TB slot)
+ * 0xff01000000000000 - 0xff20ffffffffffff direct map (32 x 2048TB slots)
+ * 0xff21000000000000 - 0xffff807fffffffff unused
+ * 0xffff808000000000 - 0xffff847fffffffff large map (can be tuned up)
+ * 0xffff848000000000 - 0xfffff77fffffffff unused (large map extends there)
+ * 0xfffff60000000000 - 0xfffff7ffffffffff 2TB KMSAN origin map, optional
+ * 0xfffff78000000000 - 0xfffff7bfffffffff 512GB KASAN shadow map, optional
+ * 0xfffff80000000000 - 0xfffffbffffffffff 4TB unused
+ * 0xfffffc0000000000 - 0xfffffdffffffffff 2TB KMSAN shadow map, optional
+ * 0xfffffe0000000000 - 0xffffffffffffffff 2TB kernel map
+ *
* Within the kernel map:
*
* 0xfffffe0000000000 vm_page_array
* 0xffffffff80000000 KERNBASE
*/
-#define VM_MIN_KERNEL_ADDRESS KV4ADDR(KPML4BASE, 0, 0, 0)
-#define VM_MAX_KERNEL_ADDRESS KV4ADDR(KPML4BASE + NKPML4E - 1, \
- NPDPEPG-1, NPDEPG-1, NPTEPG-1)
-
-#define DMAP_MIN_ADDRESS KV4ADDR(DMPML4I, 0, 0, 0)
-#define DMAP_MAX_ADDRESS KV4ADDR(DMPML4I + NDMPML4E, 0, 0, 0)
+#define VM_MIN_KERNEL_ADDRESS_LA48 KV4ADDR(KPML4BASE, 0, 0, 0)
+#define VM_MIN_KERNEL_ADDRESS kva_layout.km_low
+#define VM_MAX_KERNEL_ADDRESS kva_layout.km_high
#define KASAN_MIN_ADDRESS KV4ADDR(KASANPML4I, 0, 0, 0)
#define KASAN_MAX_ADDRESS KV4ADDR(KASANPML4I + NKASANPML4E, 0, 0, 0)
@@ -199,9 +211,6 @@
#define KMSAN_ORIG_MAX_ADDRESS KV4ADDR(KMSANORIGPML4I + NKMSANORIGPML4E, \
0, 0, 0)
-#define LARGEMAP_MIN_ADDRESS KV4ADDR(LMSPML4I, 0, 0, 0)
-#define LARGEMAP_MAX_ADDRESS KV4ADDR(LMEPML4I + 1, 0, 0, 0)
-
/*
* Formally kernel mapping starts at KERNBASE, but kernel linker
* script leaves first PDE reserved. For legacy BIOS boot, kernel is
@@ -239,21 +248,21 @@
* vt fb startup needs to be reworked.
*/
#define PHYS_IN_DMAP(pa) (dmaplimit == 0 || (pa) < dmaplimit)
-#define VIRT_IN_DMAP(va) ((va) >= DMAP_MIN_ADDRESS && \
- (va) < (DMAP_MIN_ADDRESS + dmaplimit))
+#define VIRT_IN_DMAP(va) \
+ ((va) >= kva_layout.dmap_low && (va) < kva_layout.dmap_low + dmaplimit)
#define PMAP_HAS_DMAP 1
-#define PHYS_TO_DMAP(x) ({ \
+#define PHYS_TO_DMAP(x) __extension__ ({ \
KASSERT(PHYS_IN_DMAP(x), \
("physical address %#jx not covered by the DMAP", \
(uintmax_t)x)); \
- (x) | DMAP_MIN_ADDRESS; })
+ (x) + kva_layout.dmap_low; })
-#define DMAP_TO_PHYS(x) ({ \
+#define DMAP_TO_PHYS(x) __extension__ ({ \
KASSERT(VIRT_IN_DMAP(x), \
("virtual address %#jx not covered by the DMAP", \
(uintmax_t)x)); \
- (x) & ~DMAP_MIN_ADDRESS; })
+ (x) - kva_layout.dmap_low; })
/*
* amd64 maps the page array into KVA so that it can be more easily
@@ -274,7 +283,7 @@
*/
#ifndef VM_KMEM_SIZE_MAX
#define VM_KMEM_SIZE_MAX ((VM_MAX_KERNEL_ADDRESS - \
- VM_MIN_KERNEL_ADDRESS + 1) * 3 / 5)
+ kva_layout.km_low + 1) * 3 / 5)
#endif
/* initial pagein size of beginning of executable file */
diff --git a/sys/amd64/pt/pt.c b/sys/amd64/pt/pt.c
new file mode 100644
index 000000000000..c7b75767680a
--- /dev/null
+++ b/sys/amd64/pt/pt.c
@@ -0,0 +1,978 @@
+/*
+ * Copyright (c) 2025 Bojan Novković <bnovkov@freebsd.org>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+/*
+ * hwt(4) Intel Processor Trace (PT) backend
+ *
+ * Driver Design Overview
+ *
+ * - Since PT is configured on a per-core basis, the driver uses
+ * 'smp_rendezvous' to start and disable tracing on each target core.
+ * - PT-specific resources are stored in a 'struct pt_ctx' context structure for
+ * each traced CPU core or thread. Upon initialization, a ToPA configuration
+ * is generated for each 'pt_ctx' structure using the HWT tracing buffers.
+ * The HWT tracing buffer is split into 4K ToPA entries. Currently, each
+ * 4K ToPA entry is configured to trigger an interrupt after it is filled.
+ * - The PT driver uses the XSAVE/XRSTOR PT extensions to load and save all
+ * relevant PT registers. Every time a traced thread is switched
+ * out or in, its state will be saved to or loaded from its corresponding
+ * 'pt_ctx' context.
+ * - When tracing starts, the PT hardware will start writing data into the
+ * tracing buffer. When a TOPA_INT entry is filled, it will trigger an
+ * interrupt before continuing. The interrupt handler will then fetch the
+ * last valid tracing buffer offset and enqueue a HWT_RECORD_BUFFER record.
+ * The driver is currently configured to use the NMI interrupt line.
+ * - The userspace PT backend waits for incoming HWT_RECORD_BUFFER records
+ * and uses the offsets to decode data from the tracing buffer.
+ *
+ * Future improvements and limitations
+ *
+ * - We currently configure the PT hardware to trigger an interrupt whenever
+ * a 4K ToPA entry is filled. While this is fine when tracing smaller
+ * functions or infrequent code paths, this will generate too much interrupt
+ * traffic when tracing hotter functions. A proper solution for this issue
+ * should estimate the amount of data generated by the current configuration
+ * and use it to determine interrupt frequency.
+ *
+ * - Support for more tracing options and PT features.
+ *
+ */
+
+#include <sys/systm.h>
+#include <sys/hwt.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/malloc.h>
+#include <sys/module.h>
+#include <sys/mutex.h>
+#include <sys/sdt.h>
+#include <sys/smp.h>
+#include <sys/taskqueue.h>
+
+#include <vm/vm.h>
+#include <vm/vm_page.h>
+
+#include <machine/atomic.h>
+#include <machine/cpufunc.h>
+#include <machine/fpu.h>
+#include <machine/smp.h>
+#include <machine/specialreg.h>
+
+#include <x86/apicvar.h>
+#include <x86/x86_var.h>
+
+#include <dev/hwt/hwt_context.h>
+#include <dev/hwt/hwt_vm.h>
+#include <dev/hwt/hwt_backend.h>
+#include <dev/hwt/hwt_config.h>
+#include <dev/hwt/hwt_cpu.h>
+#include <dev/hwt/hwt_record.h>
+#include <dev/hwt/hwt_thread.h>
+
+#include <amd64/pt/pt.h>
+
+#ifdef PT_DEBUG
+#define dprintf(fmt, ...) printf(fmt, ##__VA_ARGS__)
+#else
+#define dprintf(fmt, ...)
+#endif
+#define PT_SUPPORTED_FLAGS \
+ (RTIT_CTL_MTCEN | RTIT_CTL_CR3FILTER | RTIT_CTL_DIS_TNT | \
+ RTIT_CTL_USER | RTIT_CTL_OS | RTIT_CTL_BRANCHEN)
+#define PT_XSAVE_MASK (XFEATURE_ENABLED_X87 | XFEATURE_ENABLED_SSE)
+#define PT_XSTATE_BV (PT_XSAVE_MASK | XFEATURE_ENABLED_PT)
+#define PT_MAX_IP_RANGES 2
+
+#define PT_TOPA_MASK_PTRS 0x7f
+#define PT_TOPA_PAGE_MASK 0xffffff80
+#define PT_TOPA_PAGE_SHIFT 7
+
+#define CPUID_PT_LEAF 0x14
+
+MALLOC_DEFINE(M_PT, "pt", "Intel Processor Trace");
+
+SDT_PROVIDER_DEFINE(pt);
+SDT_PROBE_DEFINE(pt, , , topa__intr);
+
+TASKQUEUE_FAST_DEFINE_THREAD(pt);
+
+static void pt_send_buffer_record(void *arg, int pending __unused);
+static int pt_topa_intr(struct trapframe *tf);
+
+/*
+ * Intel Processor Trace XSAVE-managed state.
+ */
+struct pt_ext_area {
+ uint64_t rtit_ctl;
+ uint64_t rtit_output_base;
+ uint64_t rtit_output_mask_ptrs;
+ uint64_t rtit_status;
+ uint64_t rtit_cr3_match;
+ uint64_t rtit_addr0_a;
+ uint64_t rtit_addr0_b;
+ uint64_t rtit_addr1_a;
+ uint64_t rtit_addr1_b;
+};
+
+struct pt_buffer {
+ uint64_t *topa_hw; /* ToPA table entries. */
+ size_t size;
+ struct mtx lock; /* Lock for fields below. */
+ vm_offset_t offset;
+ uint64_t wrap_count;
+ int curpage;
+};
+
+struct pt_ctx {
+ int id;
+ struct pt_buffer buf; /* ToPA buffer metadata */
+ struct task task; /* ToPA buffer notification task */
+ struct hwt_context *hwt_ctx;
+ uint8_t *save_area; /* PT XSAVE area */
+};
+/* PT tracing contexts used for CPU mode. */
+static struct pt_ctx *pt_pcpu_ctx;
+
+enum pt_cpu_state {
+ PT_DISABLED = 0,
+ PT_STOPPED,
+ PT_ACTIVE
+};
+
+static struct pt_cpu {
+ struct pt_ctx *ctx; /* active PT tracing context */
+ enum pt_cpu_state state; /* used as part of trace stop protocol */
+} *pt_pcpu;
+
+/*
+ * PT-related CPUID bits.
+ */
+static struct pt_cpu_info {
+ uint32_t l0_eax;
+ uint32_t l0_ebx;
+ uint32_t l0_ecx;
+ uint32_t l1_eax;
+ uint32_t l1_ebx;
+ size_t xsave_area_size;
+ size_t xstate_hdr_offset;
+ size_t pt_xsave_offset;
+} pt_info __read_mostly;
+
+static bool initialized = false;
+static int cpu_mode_ctr = 0;
+
+static __inline enum pt_cpu_state
+pt_cpu_get_state(int cpu_id)
+{
+ return (atomic_load_int(&pt_pcpu[cpu_id].state));
+}
+
+static __inline void
+pt_cpu_set_state(int cpu_id, enum pt_cpu_state state)
+{
+ atomic_store_int(&pt_pcpu[cpu_id].state, state);
+}
+
+static __inline struct xstate_hdr *
+pt_ctx_get_xstate_hdr(struct pt_ctx *ctx)
+{
+ return ((struct xstate_hdr *)(ctx->save_area +
+ pt_info.xstate_hdr_offset));
+}
+
+
+static __inline struct pt_ext_area *
+pt_ctx_get_ext_area(struct pt_ctx *ctx)
+{
+ return ((struct pt_ext_area *)(ctx->save_area +
+ pt_info.pt_xsave_offset));
+}
+
+/*
+ * Updates current trace buffer offset from the
+ * ToPA MSRs. Records if the trace buffer wrapped.
+ */
+static __inline void
+pt_update_buffer(struct pt_buffer *buf)
+{
+ uint64_t reg;
+ int curpage;
+
+ /* Update buffer offset. */
+ reg = rdmsr(MSR_IA32_RTIT_OUTPUT_MASK_PTRS);
+ curpage = (reg & PT_TOPA_PAGE_MASK) >> PT_TOPA_PAGE_SHIFT;
+ mtx_lock_spin(&buf->lock);
+ /* Check if the output wrapped. */
+ if (buf->curpage > curpage)
+ buf->wrap_count++;
+ buf->curpage = curpage;
+ buf->offset = reg >> 32;
+ mtx_unlock_spin(&buf->lock);
+
+ dprintf("%s: wrap_cnt: %lu, curpage: %d, offset: %zu\n", __func__,
+ buf->wrap_count, buf->curpage, buf->offset);
+}
+
+static __inline void
+pt_fill_buffer_record(int id, struct pt_buffer *buf,
+ struct hwt_record_entry *rec)
+{
+ rec->record_type = HWT_RECORD_BUFFER;
+ rec->buf_id = id;
+ rec->curpage = buf->curpage;
+ rec->offset = buf->offset + (buf->wrap_count * buf->size);
+}
+
+/*
+ * Enables or disables tracing on curcpu
+ * using the XSAVE/XRSTOR PT extensions.
+ */
+static void
+pt_cpu_toggle_local(uint8_t *save_area, bool enable)
+{
+ u_long xcr0, cr0;
+ u_long xss;
+
+ cr0 = rcr0();
+ if (cr0 & CR0_TS)
+ clts();
+ xcr0 = rxcr(XCR0);
+ if ((xcr0 & PT_XSAVE_MASK) != PT_XSAVE_MASK)
+ load_xcr(XCR0, xcr0 | PT_XSAVE_MASK);
+ xss = rdmsr(MSR_IA32_XSS);
+ wrmsr(MSR_IA32_XSS, xss | XFEATURE_ENABLED_PT);
+
+ if (!enable) {
+ KASSERT((rdmsr(MSR_IA32_RTIT_CTL) & RTIT_CTL_TRACEEN) != 0,
+ ("%s: PT is disabled", __func__));
+ xsaves(save_area, XFEATURE_ENABLED_PT);
+ } else {
+ KASSERT((rdmsr(MSR_IA32_RTIT_CTL) & RTIT_CTL_TRACEEN) == 0,
+ ("%s: PT is enabled", __func__));
+ xrstors(save_area, XFEATURE_ENABLED_PT);
+ }
+ wrmsr(MSR_IA32_XSS, xss);
+ if ((xcr0 & PT_XSAVE_MASK) != PT_XSAVE_MASK)
+ load_xcr(XCR0, xcr0);
+ if (cr0 & CR0_TS)
+ load_cr0(cr0);
+}
+
+/*
+ * Starts PT tracing on 'curcpu'.
+ */
+static void
+pt_cpu_start(void *dummy)
+{
+ struct pt_cpu *cpu;
+
+ cpu = &pt_pcpu[curcpu];
+ MPASS(cpu->ctx != NULL);
+
+ dprintf("%s: curcpu %d\n", __func__, curcpu);
+ load_cr4(rcr4() | CR4_XSAVE);
+ wrmsr(MSR_IA32_RTIT_STATUS, 0);
+ pt_cpu_set_state(curcpu, PT_ACTIVE);
+ pt_cpu_toggle_local(cpu->ctx->save_area, true);
+}
+
+/*
+ * Stops PT tracing on 'curcpu'.
+ * Updates trace buffer offset to ensure
+ * any data generated between the last interrupt
+ * and the trace stop gets picked up by userspace.
+ */
+static void
+pt_cpu_stop(void *dummy)
+{
+ struct pt_cpu *cpu;
+ struct pt_ctx *ctx;
+
+ /* Shutdown may occur before PT gets properly configured. */
+ if (pt_cpu_get_state(curcpu) == PT_DISABLED)
+ return;
+
+ cpu = &pt_pcpu[curcpu];
+ ctx = cpu->ctx;
+ MPASS(ctx != NULL);
+ dprintf("%s: curcpu %d\n", __func__, curcpu);
+
+ pt_cpu_set_state(curcpu, PT_STOPPED);
+ pt_cpu_toggle_local(cpu->ctx->save_area, false);
+ pt_update_buffer(&ctx->buf);
+}
+
+/*
+ * Prepares the Table of Physical Addresses (ToPA) metadata for 'pt_ctx'.
+ * The HWT trace buffer is split into 4K ToPA table entries and used
+ * as a circular buffer, meaning that the last ToPA entry points to
+ * the first ToPA entry. Each entry is configured to raise an
+ * interrupt after being filled.
+ */
+static int
+pt_topa_prepare(struct pt_ctx *ctx, struct hwt_vm *vm)
+{
+ struct pt_buffer *buf;
+ size_t topa_size;
+ int i;
+
+ topa_size = TOPA_SIZE_4K;
+ buf = &ctx->buf;
+
+ KASSERT(buf->topa_hw == NULL,
+ ("%s: ToPA info already exists", __func__));
+ buf->topa_hw = mallocarray(vm->npages + 1, sizeof(uint64_t), M_PT,
+ M_ZERO | M_WAITOK);
+ dprintf("%s: ToPA virt addr %p\n", __func__, buf->topa_hw);
+ buf->size = vm->npages * PAGE_SIZE;
+ for (i = 0; i < vm->npages; i++) {
+ buf->topa_hw[i] = VM_PAGE_TO_PHYS(vm->pages[i]) | topa_size;
+ /*
+ * XXX: TOPA_INT should ideally be set according to
+ * expected amount of incoming trace data. Too few TOPA_INT
+ * entries will not trigger interrupts often enough when tracing
+ * smaller functions.
+ */
+ buf->topa_hw[i] |= TOPA_INT;
+ }
+ buf->topa_hw[vm->npages] = (uint64_t)vtophys(buf->topa_hw) | TOPA_END;
+
+ return (0);
+}
+
+/*
+ * Configures IP filtering for trace generation.
+ * A maximum of 2 ranges can be specified due to
+ * limitations imposed by the XSAVE/XRSTOR PT extensions.
+ */
+static int
+pt_configure_ranges(struct pt_ctx *ctx, struct pt_cpu_config *cfg)
+{
+ struct pt_ext_area *pt_ext;
+ int nranges_supp, n, error = 0;
+
+ pt_ext = pt_ctx_get_ext_area(ctx);
+ if (pt_info.l0_ebx & CPUPT_IPF) {
+ nranges_supp = (pt_info.l1_eax & CPUPT_NADDR_M) >>
+ CPUPT_NADDR_S;
+
+ if (nranges_supp > PT_IP_FILTER_MAX_RANGES)
+ nranges_supp = PT_IP_FILTER_MAX_RANGES;
+ n = cfg->nranges;
+ if (n > nranges_supp) {
+ printf("%s: %d IP filtering ranges requested, CPU "
+ "supports %d, truncating\n",
+ __func__, n, nranges_supp);
+ n = nranges_supp;
+ }
+
+ switch (n) {
+ case 2:
+ pt_ext->rtit_ctl |= (1UL << RTIT_CTL_ADDR_CFG_S(1));
+ pt_ext->rtit_addr1_a = cfg->ip_ranges[1].start;
+ pt_ext->rtit_addr1_b = cfg->ip_ranges[1].end;
+ case 1:
+ pt_ext->rtit_ctl |= (1UL << RTIT_CTL_ADDR_CFG_S(0));
+ pt_ext->rtit_addr0_a = cfg->ip_ranges[0].start;
+ pt_ext->rtit_addr0_b = cfg->ip_ranges[0].end;
+ break;
+ default:
+ error = (EINVAL);
+ break;
+ };
+ } else
+ error = (ENXIO);
+
+ return (error);
+}
+
+static int
+pt_init_ctx(struct pt_ctx *pt_ctx, struct hwt_vm *vm, int ctx_id)
+{
+
+ dprintf("%s: ctx id %d\n", __func__, ctx_id);
+
+ KASSERT(pt_ctx->buf.topa_hw == NULL,
+ ("%s: active ToPA buffer in context %p\n", __func__, pt_ctx));
+
+ memset(pt_ctx, 0, sizeof(struct pt_ctx));
+ mtx_init(&pt_ctx->buf.lock, "pttopa", NULL, MTX_SPIN);
+ pt_ctx->save_area = malloc_aligned(pt_info.xsave_area_size, 64,
+ M_PT, M_NOWAIT | M_ZERO);
+ if (pt_ctx->save_area == NULL)
+ return (ENOMEM);
+ dprintf("%s: preparing ToPA buffer\n", __func__);
+ if (pt_topa_prepare(pt_ctx, vm) != 0) {
+ dprintf("%s: failed to prepare ToPA buffer\n", __func__);
+ free(pt_ctx->save_area, M_PT);
+ return (ENOMEM);
+ }
+
+ pt_ctx->id = ctx_id;
+ TASK_INIT(&pt_ctx->task, 0, pt_send_buffer_record, pt_ctx);
+
+ return (0);
+}
+
+static void
+pt_deinit_ctx(struct pt_ctx *pt_ctx)
+{
+
+ if (pt_ctx->buf.topa_hw != NULL)
+ free(pt_ctx->buf.topa_hw, M_PT);
+ if (pt_ctx->save_area != NULL)
+ free(pt_ctx->save_area, M_PT);
+ memset(pt_ctx, 0, sizeof(*pt_ctx));
+ pt_ctx->buf.topa_hw = NULL;
+}
+
+/*
+ * HWT backend configuration method.
+ *
+ * Checks and translates the user-defined configuration to a
+ * set of PT tracing features. Uses the feature set to initialize
+ * the tracing context for the target CPU or thread.
+ */
+static int
+pt_backend_configure(struct hwt_context *ctx, int cpu_id, int thread_id)
+{
+ struct hwt_cpu *hwt_cpu;
+ struct hwt_thread *thr;
+ struct pt_ctx *pt_ctx;
+ struct pt_cpu_config *cfg;
+ struct pt_ext_area *pt_ext;
+ struct xstate_hdr *hdr;
+ int error;
+
+ dprintf("%s\n", __func__);
+
+ cfg = (struct pt_cpu_config *)ctx->config;
+ pt_ctx = NULL;
+
+ /* Clear any flags we don't support yet. */
+ cfg->rtit_ctl &= PT_SUPPORTED_FLAGS;
+ if (cfg->rtit_ctl & RTIT_CTL_MTCEN) {
+ if ((pt_info.l0_ebx & CPUPT_MTC) == 0) {
+ printf("%s: CPU does not support generating MTC "
+ "packets\n", __func__);
+ return (ENXIO);
+ }
+ }
+
+ if (cfg->rtit_ctl & RTIT_CTL_CR3FILTER) {
+ if ((pt_info.l0_ebx & CPUPT_CR3) == 0) {
+ printf("%s: CPU does not support CR3 filtering\n",
+ __func__);
+ return (ENXIO);
+ }
+ }
+
+ if (cfg->rtit_ctl & RTIT_CTL_DIS_TNT) {
+ if ((pt_info.l0_ebx & CPUPT_DIS_TNT) == 0) {
+ printf("%s: CPU does not support TNT\n", __func__);
+ return (ENXIO);
+ }
+ }
+ /* TODO: support for more config bits. */
+
+ if (ctx->mode == HWT_MODE_CPU) {
+ TAILQ_FOREACH(hwt_cpu, &ctx->cpus, next) {
+ if (hwt_cpu->cpu_id != cpu_id)
+ continue;
+ pt_ctx = &pt_pcpu_ctx[cpu_id];
+ break;
+ }
+ } else {
+ TAILQ_FOREACH(thr, &ctx->threads, next) {
+ if (thr->thread_id != thread_id)
+ continue;
+ KASSERT(thr->private != NULL,
+ ("%s: hwt thread private"
+ " not set, thr %p",
+ __func__, thr));
+ pt_ctx = (struct pt_ctx *)thr->private;
+ break;
+ }
+ }
+ if (pt_ctx == NULL)
+ return (ENOENT);
+
+ dprintf("%s: preparing MSRs\n", __func__);
+ pt_ext = pt_ctx_get_ext_area(pt_ctx);
+ hdr = pt_ctx_get_xstate_hdr(pt_ctx);
+
+ pt_ext->rtit_ctl |= cfg->rtit_ctl;
+ if (cfg->nranges != 0) {
+ dprintf("%s: preparing IPF ranges\n", __func__);
+ if ((error = pt_configure_ranges(pt_ctx, cfg)) != 0)
+ return (error);
+ }
+ pt_ctx->hwt_ctx = ctx;
+ pt_ext->rtit_ctl |= RTIT_CTL_TOPA;
+ pt_ext->rtit_output_base = (uint64_t)vtophys(pt_ctx->buf.topa_hw);
+ pt_ext->rtit_output_mask_ptrs = PT_TOPA_MASK_PTRS;
+ hdr->xstate_bv = XFEATURE_ENABLED_PT;
+ hdr->xstate_xcomp_bv = XFEATURE_ENABLED_PT |
+ XSTATE_XCOMP_BV_COMPACT;
+ pt_ext->rtit_ctl |= RTIT_CTL_TRACEEN;
+ pt_pcpu[cpu_id].ctx = pt_ctx;
+ pt_cpu_set_state(cpu_id, PT_STOPPED);
+
+ return (0);
+}
+
+/*
+ * hwt backend trace start operation. CPU affine.
+ */
+static void
+pt_backend_enable(struct hwt_context *ctx, int cpu_id)
+{
+ if (ctx->mode == HWT_MODE_CPU)
+ return;
+
+ KASSERT(curcpu == cpu_id,
+ ("%s: attempting to start PT on another cpu", __func__));
+ pt_cpu_start(NULL);
+ CPU_SET(cpu_id, &ctx->cpu_map);
+}
+
+/*
+ * hwt backend trace stop operation. CPU affine.
+ */
+static void
+pt_backend_disable(struct hwt_context *ctx, int cpu_id)
+{
+ struct pt_cpu *cpu;
+
+ if (ctx->mode == HWT_MODE_CPU)
+ return;
+
+ KASSERT(curcpu == cpu_id,
+ ("%s: attempting to disable PT on another cpu", __func__));
+ pt_cpu_stop(NULL);
+ CPU_CLR(cpu_id, &ctx->cpu_map);
+ cpu = &pt_pcpu[cpu_id];
+ cpu->ctx = NULL;
+}
+
+/*
+ * hwt backend trace start operation for remote CPUs.
+ */
+static int
+pt_backend_enable_smp(struct hwt_context *ctx)
+{
+
+ dprintf("%s\n", __func__);
+ if (ctx->mode == HWT_MODE_CPU &&
+ atomic_swap_32(&cpu_mode_ctr, 1) != 0)
+ return (-1);
+
+ KASSERT(ctx->mode == HWT_MODE_CPU,
+ ("%s: should only be used for CPU mode", __func__));
+ smp_rendezvous_cpus(ctx->cpu_map, NULL, pt_cpu_start, NULL, NULL);
+
+ return (0);
+}
+
+/*
+ * hwt backend trace stop operation for remote CPUs.
+ */
+static int
+pt_backend_disable_smp(struct hwt_context *ctx)
+{
+
+ dprintf("%s\n", __func__);
+ if (ctx->mode == HWT_MODE_CPU &&
+ atomic_swap_32(&cpu_mode_ctr, 0) == 0)
+ return (-1);
+
+ if (CPU_EMPTY(&ctx->cpu_map)) {
+ dprintf("%s: empty cpu map\n", __func__);
+ return (-1);
+ }
+ smp_rendezvous_cpus(ctx->cpu_map, NULL, pt_cpu_stop, NULL, NULL);
+
+ return (0);
+}
+
+/*
+ * HWT backend initialization method.
+ *
+ * Installs the ToPA interrupt handler and initializes
+ * the tracing contexts used for HWT_MODE_CPU.
+ */
+static int
+pt_backend_init(struct hwt_context *ctx)
+{
+ struct hwt_cpu *hwt_cpu;
+ int error;
+
+ dprintf("%s\n", __func__);
+ if (ctx->mode == HWT_MODE_CPU) {
+ TAILQ_FOREACH(hwt_cpu, &ctx->cpus, next) {
+ error = pt_init_ctx(&pt_pcpu_ctx[hwt_cpu->cpu_id],
+ hwt_cpu->vm, hwt_cpu->cpu_id);
+ if (error)
+ return (error);
+ }
+ }
+
+ return (0);
+}
+
+/*
+ * HWT backend teardown method.
+ *
+ * Removes the ToPA interrupt handler, stops tracing on all active CPUs,
+ * and releases all previously allocated ToPA metadata.
+ */
+static int
+pt_backend_deinit(struct hwt_context *ctx)
+{
+ struct pt_ctx *pt_ctx;
+ struct hwt_thread *thr;
+ int cpu_id;
+
+ dprintf("%s\n", __func__);
+
+ pt_backend_disable_smp(ctx);
+ if (ctx->mode == HWT_MODE_THREAD) {
+ TAILQ_FOREACH(thr, &ctx->threads, next) {
+ KASSERT(thr->private != NULL,
+ ("%s: thr->private not set", __func__));
+ pt_ctx = (struct pt_ctx *)thr->private;
+ pt_deinit_ctx(pt_ctx);
+ }
+ } else {
+ CPU_FOREACH(cpu_id) {
+ if (!CPU_ISSET(cpu_id, &ctx->cpu_map))
+ continue;
+ if (pt_pcpu[cpu_id].ctx != NULL) {
+ KASSERT(pt_pcpu[cpu_id].ctx ==
+ &pt_pcpu_ctx[cpu_id],
+ ("%s: CPU mode tracing with non-cpu mode PT"
+ "context active",
+ __func__));
+ pt_pcpu[cpu_id].ctx = NULL;
+ }
+ pt_ctx = &pt_pcpu_ctx[cpu_id];
+ pt_deinit_ctx(pt_ctx);
+ memset(&pt_pcpu[cpu_id], 0, sizeof(struct pt_cpu));
+ }
+ }
+
+ return (0);
+}
+
+/*
+ * Fetches current offset into the tracing buffer.
+ */
+static int
+pt_backend_read(struct hwt_vm *vm, int *curpage, vm_offset_t *curpage_offset,
+ uint64_t *data)
+{
+ struct pt_buffer *buf;
+
+ if (vm->ctx->mode == HWT_MODE_THREAD)
+ buf = &((struct pt_ctx *)vm->thr->private)->buf;
+ else
+ buf = &pt_pcpu[vm->cpu->cpu_id].ctx->buf;
+ mtx_lock_spin(&buf->lock);
+ *curpage = buf->curpage;
+ *curpage_offset = buf->offset + (buf->wrap_count * vm->ctx->bufsize);
+ mtx_unlock_spin(&buf->lock);
+
+ return (0);
+}
+
+/*
+ * HWT thread creation hook.
+ * Allocates and associates a 'struct pt_ctx' for a given hwt thread.
+ */
+static int
+pt_backend_alloc_thread(struct hwt_thread *thr)
+{
+ struct pt_ctx *pt_ctx;
+ int error;
+
+ /* Omit M_WAITOK since this might get invoked a non-sleepable context */
+ pt_ctx = malloc(sizeof(*pt_ctx), M_PT, M_NOWAIT | M_ZERO);
+ if (pt_ctx == NULL)
+ return (ENOMEM);
+
+ error = pt_init_ctx(pt_ctx, thr->vm, thr->thread_id);
+ if (error)
+ return (error);
+
+ thr->private = pt_ctx;
+ return (0);
+}
+/*
+ * HWT thread teardown hook.
+ */
+static void
+pt_backend_free_thread(struct hwt_thread *thr)
+{
+ struct pt_ctx *ctx;
+
+ ctx = (struct pt_ctx *)thr->private;
+
+ pt_deinit_ctx(ctx);
+ free(ctx, M_PT);
+}
+
+static void
+pt_backend_dump(int cpu_id)
+{
+}
+
+static struct hwt_backend_ops pt_ops = {
+ .hwt_backend_init = pt_backend_init,
+ .hwt_backend_deinit = pt_backend_deinit,
+
+ .hwt_backend_configure = pt_backend_configure,
+
+ .hwt_backend_enable = pt_backend_enable,
+ .hwt_backend_disable = pt_backend_disable,
+
+#ifdef SMP
+ .hwt_backend_enable_smp = pt_backend_enable_smp,
+ .hwt_backend_disable_smp = pt_backend_disable_smp,
+#endif
+
+ .hwt_backend_read = pt_backend_read,
+ .hwt_backend_dump = pt_backend_dump,
+
+ .hwt_backend_thread_alloc = pt_backend_alloc_thread,
+ .hwt_backend_thread_free = pt_backend_free_thread,
+};
+
+static struct hwt_backend backend = {
+ .ops = &pt_ops,
+ .name = "pt",
+ .kva_req = 1,
+};
+
+/*
+ * Reads the latest valid trace buffer offset and enqueues
+ * a HWT_RECORD_BUFFER record.
+ * Used as a taskqueue routine from the ToPA interrupt handler.
+ */
+static void
+pt_send_buffer_record(void *arg, int pending __unused)
+{
+ struct hwt_record_entry record;
+ struct pt_ctx *ctx = (struct pt_ctx *)arg;
+
+ /* Prepare buffer record. */
+ mtx_lock_spin(&ctx->buf.lock);
+ pt_fill_buffer_record(ctx->id, &ctx->buf, &record);
+ mtx_unlock_spin(&ctx->buf.lock);
+ hwt_record_ctx(ctx->hwt_ctx, &record, M_ZERO | M_NOWAIT);
+}
+static void
+pt_topa_status_clear(void)
+{
+ uint64_t reg;
+
+ reg = rdmsr(MSR_IA_GLOBAL_STATUS_RESET);
+ reg &= ~GLOBAL_STATUS_FLAG_TRACETOPAPMI;
+ reg |= GLOBAL_STATUS_FLAG_TRACETOPAPMI;
+ wrmsr(MSR_IA_GLOBAL_STATUS_RESET, reg);
+}
+
+/*
+ * ToPA PMI handler.
+ *
+ * Invoked every time a ToPA entry marked with TOPA_INT is filled.
+ * Uses taskqueue to enqueue a buffer record for userspace.
+ * Re-enables the PC interrupt line as long as tracing is active.
+ */
+static int
+pt_topa_intr(struct trapframe *tf)
+{
+ struct pt_buffer *buf;
+ struct pt_ctx *ctx;
+ uint64_t reg;
+
+ SDT_PROBE0(pt, , , topa__intr);
+
+ if (pt_cpu_get_state(curcpu) != PT_ACTIVE) {
+ return (0);
+ }
+ reg = rdmsr(MSR_IA_GLOBAL_STATUS);
+ if ((reg & GLOBAL_STATUS_FLAG_TRACETOPAPMI) == 0) {
+ /* ACK spurious or leftover interrupt. */
+ pt_topa_status_clear();
+ return (1);
+ }
+
+ ctx = pt_pcpu[curcpu].ctx;
+ buf = &ctx->buf;
+ KASSERT(buf->topa_hw != NULL,
+ ("%s: ToPA PMI interrupt with invalid buffer", __func__));
+
+ pt_cpu_toggle_local(ctx->save_area, false);
+ pt_update_buffer(buf);
+ pt_topa_status_clear();
+ taskqueue_enqueue_flags(taskqueue_pt, &ctx->task,
+ TASKQUEUE_FAIL_IF_PENDING);
+
+ if (pt_cpu_get_state(curcpu) == PT_ACTIVE) {
+ pt_cpu_toggle_local(ctx->save_area, true);
+ lapic_reenable_pcint();
+ }
+ return (1);
+}
+
+/*
+ * Module initialization.
+ *
+ * Saves all PT-related cpuid info, registers itself as a HWT backend,
+ * and allocates metadata required to keep track of tracing operations
+ * on each CPU.
+ */
+static int
+pt_init(void)
+{
+ u_int cp[4];
+ int error;
+
+ dprintf("pt: Enumerating part 1\n");
+ cpuid_count(CPUID_PT_LEAF, 0, cp);
+ dprintf("pt: Maximum valid sub-leaf Index: %x\n", cp[0]);
+ dprintf("pt: ebx %x\n", cp[1]);
+ dprintf("pt: ecx %x\n", cp[2]);
+
+ pt_info.l0_eax = cp[0];
+ pt_info.l0_ebx = cp[1];
+ pt_info.l0_ecx = cp[2];
+
+ dprintf("pt: Enumerating part 2\n");
+ cpuid_count(CPUID_PT_LEAF, 1, cp);
+ dprintf("pt: eax %x\n", cp[0]);
+ dprintf("pt: ebx %x\n", cp[1]);
+
+ pt_info.l1_eax = cp[0];
+ pt_info.l1_ebx = cp[1];
+
+ error = hwt_backend_register(&backend);
+ if (error != 0) {
+ printf("pt: unable to register hwt backend, error %d\n", error);
+ return (error);
+ }
+ pt_pcpu = mallocarray(mp_ncpus, sizeof(struct pt_cpu), M_PT,
+ M_ZERO | M_WAITOK);
+ pt_pcpu_ctx = mallocarray(mp_ncpus, sizeof(struct pt_ctx), M_PT,
+ M_ZERO | M_WAITOK);
+
+ nmi_register_handler(pt_topa_intr);
+ if (!lapic_enable_pcint()) {
+ nmi_remove_handler(pt_topa_intr);
+ hwt_backend_unregister(&backend);
+ free(pt_pcpu, M_PT);
+ free(pt_pcpu_ctx, M_PT);
+ pt_pcpu = NULL;
+ pt_pcpu_ctx = NULL;
+ printf("pt: failed to setup interrupt line\n");
+ return (error);
+ }
+ initialized = true;
+
+ return (0);
+}
+
+/*
+ * Checks whether the CPU support Intel PT and
+ * initializes XSAVE area info.
+ *
+ * The driver relies on XSAVE/XRSTOR PT extensions,
+ * Table of Physical Addresses (ToPA) support, and
+ * support for multiple ToPA entries.
+ */
+static bool
+pt_supported(void)
+{
+ u_int cp[4];
+
+ if ((cpu_stdext_feature & CPUID_STDEXT_PROCTRACE) == 0) {
+ printf("pt: CPU does not support Intel Processor Trace\n");
+ return (false);
+ }
+ if ((cpu_feature2 & CPUID2_XSAVE) == 0) {
+ printf("pt: XSAVE is not supported\n");
+ return (false);
+ }
+ if (!xsave_extfeature_supported(XFEATURE_ENABLED_PT, true)) {
+ printf("pt: CPU does not support managing PT state using XSAVE\n");
+ return (false);
+ }
+ if (!xsave_extension_supported(CPUID_EXTSTATE_XSAVEC)) {
+ printf("pt: XSAVE compaction is not supported\n");
+ return (false);
+ }
+ if (!xsave_extension_supported(CPUID_EXTSTATE_XSAVES)) {
+ printf("pt: CPU does not support XSAVES/XRSTORS\n");
+ return (false);
+ }
+
+ /* Require ToPA support. */
+ cpuid_count(CPUID_PT_LEAF, 0, cp);
+ if ((cp[2] & CPUPT_TOPA) == 0) {
+ printf("pt: ToPA is not supported\n");
+ return (false);
+ }
+ if ((cp[2] & CPUPT_TOPA_MULTI) == 0) {
+ printf("pt: multiple ToPA outputs are not supported\n");
+ return (false);
+ }
+
+ pt_info.xstate_hdr_offset = xsave_area_hdr_offset();
+ pt_info.xsave_area_size = xsave_area_size(PT_XSTATE_BV, true, true);
+ pt_info.pt_xsave_offset = xsave_area_offset(PT_XSTATE_BV,
+ XFEATURE_ENABLED_PT, true, true);
+
+ return (true);
+}
+
+static void
+pt_deinit(void)
+{
+ if (!initialized)
+ return;
+ nmi_remove_handler(pt_topa_intr);
+ lapic_disable_pcint();
+ hwt_backend_unregister(&backend);
+ free(pt_pcpu, M_PT);
+ free(pt_pcpu_ctx, M_PT);
+ pt_pcpu = NULL;
+ initialized = false;
+}
+
+static int
+pt_modevent(module_t mod, int type, void *data)
+{
+ switch (type) {
+ case MOD_LOAD:
+ if (!pt_supported() || pt_init() != 0) {
+ return (ENXIO);
+ }
+ break;
+ case MOD_UNLOAD:
+ pt_deinit();
+ break;
+ default:
+ break;
+ }
+
+ return (0);
+}
+
+static moduledata_t pt_mod = { "intel_pt", pt_modevent, NULL };
+
+DECLARE_MODULE(intel_pt, pt_mod, SI_SUB_DRIVERS, SI_ORDER_FIRST);
+MODULE_DEPEND(intel_pt, hwt, 1, 1, 1);
+MODULE_VERSION(intel_pt, 1);
diff --git a/sys/amd64/pt/pt.h b/sys/amd64/pt/pt.h
new file mode 100644
index 000000000000..2423afdf22e9
--- /dev/null
+++ b/sys/amd64/pt/pt.h
@@ -0,0 +1,49 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2023 Bojan Novković <bnovkov@freebsd.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _AMD64_PT_PT_H_
+#define _AMD64_PT_PT_H_
+
+#include <sys/types.h>
+
+#include <x86/include/specialreg.h>
+
+#define PT_IP_FILTER_MAX_RANGES (2) /* Intel SDM Vol. 3C, 33-29 */
+
+struct pt_cpu_config {
+ uint64_t rtit_ctl;
+ register_t cr3_filter;
+ int nranges;
+ struct ipf_range {
+ vm_offset_t start;
+ vm_offset_t end;
+ } ip_ranges[PT_IP_FILTER_MAX_RANGES];
+ uint32_t mtc_freq;
+ uint32_t cyc_thresh;
+ uint32_t psb_freq;
+};
+#endif /* !_AMD64_PT_PT_H_ */
diff --git a/sys/amd64/vmm/intel/vmx_support.S b/sys/amd64/vmm/intel/vmx_support.S
index f393f160b101..130130b64541 100644
--- a/sys/amd64/vmm/intel/vmx_support.S
+++ b/sys/amd64/vmm/intel/vmx_support.S
@@ -32,12 +32,6 @@
#include "vmx_assym.h"
-#ifdef SMP
-#define LK lock ;
-#else
-#define LK
-#endif
-
/* Be friendly to DTrace FBT's prologue/epilogue pattern matching */
#define VENTER push %rbp ; mov %rsp,%rbp
#define VLEAVE pop %rbp
diff --git a/sys/arm/arm/pmap-v6.c b/sys/arm/arm/pmap-v6.c
index 92eb0589f80b..78883296c5b7 100644
--- a/sys/arm/arm/pmap-v6.c
+++ b/sys/arm/arm/pmap-v6.c
@@ -5767,7 +5767,7 @@ pmap_page_set_memattr(vm_page_t m, vm_memattr_t ma)
CTR5(KTR_PMAP, "%s: page %p - 0x%08X oma: %d, ma: %d", __func__, m,
VM_PAGE_TO_PHYS(m), oma, ma);
- if ((m->flags & PG_FICTITIOUS) != 0)
+ if (ma == oma || (m->flags & PG_FICTITIOUS) != 0)
return;
#if 0
/*
@@ -5784,22 +5784,20 @@ pmap_page_set_memattr(vm_page_t m, vm_memattr_t ma)
* If page is not mapped by sf buffer, map the page
* transient and do invalidation.
*/
- if (ma != oma) {
- pa = VM_PAGE_TO_PHYS(m);
- sched_pin();
- pc = get_pcpu();
- cmap2_pte2p = pc->pc_cmap2_pte2p;
- mtx_lock(&pc->pc_cmap_lock);
- if (pte2_load(cmap2_pte2p) != 0)
- panic("%s: CMAP2 busy", __func__);
- pte2_store(cmap2_pte2p, PTE2_KERN_NG(pa, PTE2_AP_KRW,
- vm_memattr_to_pte2(ma)));
- dcache_wbinv_poc((vm_offset_t)pc->pc_cmap2_addr, pa, PAGE_SIZE);
- pte2_clear(cmap2_pte2p);
- tlb_flush((vm_offset_t)pc->pc_cmap2_addr);
- sched_unpin();
- mtx_unlock(&pc->pc_cmap_lock);
- }
+ pa = VM_PAGE_TO_PHYS(m);
+ sched_pin();
+ pc = get_pcpu();
+ cmap2_pte2p = pc->pc_cmap2_pte2p;
+ mtx_lock(&pc->pc_cmap_lock);
+ if (pte2_load(cmap2_pte2p) != 0)
+ panic("%s: CMAP2 busy", __func__);
+ pte2_store(cmap2_pte2p, PTE2_KERN_NG(pa, PTE2_AP_KRW,
+ vm_memattr_to_pte2(ma)));
+ dcache_wbinv_poc((vm_offset_t)pc->pc_cmap2_addr, pa, PAGE_SIZE);
+ pte2_clear(cmap2_pte2p);
+ tlb_flush((vm_offset_t)pc->pc_cmap2_addr);
+ sched_unpin();
+ mtx_unlock(&pc->pc_cmap_lock);
}
/*
diff --git a/sys/arm64/arm64/pmap.c b/sys/arm64/arm64/pmap.c
index d2e56a270f54..a09da794e77d 100644
--- a/sys/arm64/arm64/pmap.c
+++ b/sys/arm64/arm64/pmap.c
@@ -497,7 +497,8 @@ static bool pmap_pv_insert_l3c(pmap_t pmap, vm_offset_t va, vm_page_t m,
struct rwlock **lockp);
static void pmap_remove_kernel_l2(pmap_t pmap, pt_entry_t *l2, vm_offset_t va);
static int pmap_remove_l2(pmap_t pmap, pt_entry_t *l2, vm_offset_t sva,
- pd_entry_t l1e, struct spglist *free, struct rwlock **lockp);
+ pd_entry_t l1e, bool demote_kl2e, struct spglist *free,
+ struct rwlock **lockp);
static int pmap_remove_l3(pmap_t pmap, pt_entry_t *l3, vm_offset_t sva,
pd_entry_t l2e, struct spglist *free, struct rwlock **lockp);
static bool pmap_remove_l3c(pmap_t pmap, pt_entry_t *l3p, vm_offset_t va,
@@ -3847,8 +3848,7 @@ pmap_remove_kernel_l2(pmap_t pmap, pt_entry_t *l2, vm_offset_t va)
PMAP_LOCK_ASSERT(pmap, MA_OWNED);
ml3 = pmap_remove_pt_page(pmap, va);
- if (ml3 == NULL)
- panic("pmap_remove_kernel_l2: Missing pt page");
+ KASSERT(ml3 != NULL, ("pmap_remove_kernel_l2: missing pt page"));
ml3pa = VM_PAGE_TO_PHYS(ml3);
newl2 = PHYS_TO_PTE(ml3pa) | L2_TABLE;
@@ -3873,8 +3873,8 @@ pmap_remove_kernel_l2(pmap_t pmap, pt_entry_t *l2, vm_offset_t va)
* pmap_remove_l2: Do the things to unmap a level 2 superpage.
*/
static int
-pmap_remove_l2(pmap_t pmap, pt_entry_t *l2, vm_offset_t sva,
- pd_entry_t l1e, struct spglist *free, struct rwlock **lockp)
+pmap_remove_l2(pmap_t pmap, pt_entry_t *l2, vm_offset_t sva, pd_entry_t l1e,
+ bool demote_kl2e, struct spglist *free, struct rwlock **lockp)
{
struct md_page *pvh;
pt_entry_t old_l2;
@@ -3910,9 +3910,7 @@ pmap_remove_l2(pmap_t pmap, pt_entry_t *l2, vm_offset_t sva,
vm_page_aflag_clear(mt, PGA_WRITEABLE);
}
}
- if (pmap == kernel_pmap) {
- pmap_remove_kernel_l2(pmap, l2, sva);
- } else {
+ if (pmap != kernel_pmap) {
ml3 = pmap_remove_pt_page(pmap, sva);
if (ml3 != NULL) {
KASSERT(vm_page_any_valid(ml3),
@@ -3923,6 +3921,14 @@ pmap_remove_l2(pmap_t pmap, pt_entry_t *l2, vm_offset_t sva,
ml3->ref_count = 0;
pmap_add_delayed_free_list(ml3, free, false);
}
+ } else if (demote_kl2e) {
+ pmap_remove_kernel_l2(pmap, l2, sva);
+ } else {
+ ml3 = vm_radix_lookup(&pmap->pm_root, pmap_l2_pindex(sva));
+ if (vm_page_any_valid(ml3)) {
+ ml3->valid = 0;
+ pmap_zero_page(ml3);
+ }
}
return (pmap_unuse_pt(pmap, sva, l1e, free));
}
@@ -4232,7 +4238,7 @@ pmap_remove1(pmap_t pmap, vm_offset_t sva, vm_offset_t eva, bool map_delete)
if ((l3_paddr & ATTR_DESCR_MASK) == L2_BLOCK) {
if (sva + L2_SIZE == va_next && eva >= va_next) {
pmap_remove_l2(pmap, l2, sva, pmap_load(l1),
- &free, &lock);
+ true, &free, &lock);
continue;
} else if (pmap_demote_l2_locked(pmap, l2, sva,
&lock) == NULL)
@@ -5747,33 +5753,51 @@ pmap_enter_l2(pmap_t pmap, vm_offset_t va, pd_entry_t new_l2, u_int flags,
}
}
SLIST_INIT(&free);
- if ((old_l2 & ATTR_DESCR_MASK) == L2_BLOCK)
+ if ((old_l2 & ATTR_DESCR_MASK) == L2_BLOCK) {
(void)pmap_remove_l2(pmap, l2, va,
- pmap_load(pmap_l1(pmap, va)), &free, lockp);
- else
+ pmap_load(pmap_l1(pmap, va)), false, &free, lockp);
+ } else {
+ if (ADDR_IS_KERNEL(va)) {
+ /*
+ * Try to save the ptp in the trie
+ * before any changes to mappings are
+ * made. Abort on failure.
+ */
+ mt = PTE_TO_VM_PAGE(old_l2);
+ if (pmap_insert_pt_page(pmap, mt, false,
+ false)) {
+ CTR1(KTR_PMAP,
+ "pmap_enter_l2: cannot ins kern ptp va %#lx",
+ va);
+ return (KERN_RESOURCE_SHORTAGE);
+ }
+ /*
+ * Both pmap_remove_l2() and
+ * pmap_remove_l3_range() will zero fill
+ * the L3 kernel page table page.
+ */
+ }
pmap_remove_l3_range(pmap, old_l2, va, va + L2_SIZE,
&free, lockp);
+ if (ADDR_IS_KERNEL(va)) {
+ /*
+ * The TLB could have an intermediate
+ * entry for the L3 kernel page table
+ * page, so request an invalidation at
+ * all levels after clearing the
+ * L2_TABLE entry.
+ */
+ pmap_clear(l2);
+ pmap_s1_invalidate_page(pmap, va, false);
+ }
+ }
+ KASSERT(pmap_load(l2) == 0,
+ ("pmap_enter_l2: non-zero L2 entry %p", l2));
if (!ADDR_IS_KERNEL(va)) {
vm_page_free_pages_toq(&free, true);
- KASSERT(pmap_load(l2) == 0,
- ("pmap_enter_l2: non-zero L2 entry %p", l2));
} else {
KASSERT(SLIST_EMPTY(&free),
("pmap_enter_l2: freed kernel page table page"));
-
- /*
- * Both pmap_remove_l2() and pmap_remove_l3_range()
- * will leave the kernel page table page zero filled.
- * Nonetheless, the TLB could have an intermediate
- * entry for the kernel page table page, so request
- * an invalidation at all levels after clearing
- * the L2_TABLE entry.
- */
- mt = PTE_TO_VM_PAGE(pmap_load(l2));
- if (pmap_insert_pt_page(pmap, mt, false, false))
- panic("pmap_enter_l2: trie insert failed");
- pmap_clear(l2);
- pmap_s1_invalidate_page(pmap, va, false);
}
}
@@ -8045,6 +8069,8 @@ pmap_unmapbios(void *p, vm_size_t size)
void
pmap_page_set_memattr(vm_page_t m, vm_memattr_t ma)
{
+ if (m->md.pv_memattr == ma)
+ return;
m->md.pv_memattr = ma;
@@ -8424,8 +8450,8 @@ pmap_demote_l2_abort(pmap_t pmap, vm_offset_t va, pt_entry_t *l2,
struct spglist free;
SLIST_INIT(&free);
- (void)pmap_remove_l2(pmap, l2, va, pmap_load(pmap_l1(pmap, va)), &free,
- lockp);
+ (void)pmap_remove_l2(pmap, l2, va, pmap_load(pmap_l1(pmap, va)), true,
+ &free, lockp);
vm_page_free_pages_toq(&free, true);
}
diff --git a/sys/cddl/boot/zfs/zfsimpl.h b/sys/cddl/boot/zfs/zfsimpl.h
index 0ce38384abbf..83d964360343 100644
--- a/sys/cddl/boot/zfs/zfsimpl.h
+++ b/sys/cddl/boot/zfs/zfsimpl.h
@@ -2019,6 +2019,7 @@ typedef struct vdev {
vdev_list_t v_children; /* children of this vdev */
const char *v_name; /* vdev name */
uint64_t v_guid; /* vdev guid */
+ uint64_t v_txg; /* most recent transaction */
uint64_t v_id; /* index in parent */
uint64_t v_psize; /* physical device capacity */
int v_ashift; /* offset to block shift */
@@ -2048,7 +2049,6 @@ typedef struct spa {
STAILQ_ENTRY(spa) spa_link; /* link in global pool list */
char *spa_name; /* pool name */
uint64_t spa_guid; /* pool guid */
- uint64_t spa_txg; /* most recent transaction */
struct uberblock *spa_uberblock; /* best uberblock so far */
vdev_t *spa_root_vdev; /* toplevel vdev container */
objset_phys_t *spa_mos; /* MOS for this pool */
diff --git a/sys/compat/linuxkpi/common/include/linux/slab.h b/sys/compat/linuxkpi/common/include/linux/slab.h
index f3a840d9bf4b..efa5c8cb67b3 100644
--- a/sys/compat/linuxkpi/common/include/linux/slab.h
+++ b/sys/compat/linuxkpi/common/include/linux/slab.h
@@ -45,7 +45,7 @@
MALLOC_DECLARE(M_KMALLOC);
-#define kvzalloc(size, flags) kmalloc(size, (flags) | __GFP_ZERO)
+#define kvzalloc(size, flags) kvmalloc(size, (flags) | __GFP_ZERO)
#define kvcalloc(n, size, flags) kvmalloc_array(n, size, (flags) | __GFP_ZERO)
#define kzalloc(size, flags) kmalloc(size, (flags) | __GFP_ZERO)
#define kzalloc_node(size, flags, node) kmalloc_node(size, (flags) | __GFP_ZERO, node)
diff --git a/sys/compat/linuxkpi/common/src/linux_page.c b/sys/compat/linuxkpi/common/src/linux_page.c
index ebb92eacbf9a..628af17df853 100644
--- a/sys/compat/linuxkpi/common/src/linux_page.c
+++ b/sys/compat/linuxkpi/common/src/linux_page.c
@@ -106,6 +106,7 @@ linux_alloc_pages(gfp_t flags, unsigned int order)
if ((flags & M_ZERO) != 0)
req |= VM_ALLOC_ZERO;
+
if (order == 0 && (flags & GFP_DMA32) == 0) {
page = vm_page_alloc_noobj(req);
if (page == NULL)
@@ -113,6 +114,10 @@ linux_alloc_pages(gfp_t flags, unsigned int order)
} else {
vm_paddr_t pmax = (flags & GFP_DMA32) ?
BUS_SPACE_MAXADDR_32BIT : BUS_SPACE_MAXADDR;
+
+ if ((flags & __GFP_NORETRY) != 0)
+ req |= VM_ALLOC_NORECLAIM;
+
retry:
page = vm_page_alloc_noobj_contig(req, npages, 0, pmax,
PAGE_SIZE, 0, VM_MEMATTR_DEFAULT);
diff --git a/sys/conf/files b/sys/conf/files
index 74d251c2b608..dd0d390962f2 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -3227,6 +3227,19 @@ dev/uart/uart_if.m optional uart
dev/uart/uart_subr.c optional uart
dev/uart/uart_tty.c optional uart
#
+# Universal Flash Storage Host Controller Interface drivers
+#
+dev/ufshci/ufshci.c optional ufshci
+dev/ufshci/ufshci_ctrlr.c optional ufshci
+dev/ufshci/ufshci_ctrlr_cmd.c optional ufshci
+dev/ufshci/ufshci_dev.c optional ufshci
+dev/ufshci/ufshci_pci.c optional ufshci
+dev/ufshci/ufshci_req_queue.c optional ufshci
+dev/ufshci/ufshci_req_sdb.c optional ufshci
+dev/ufshci/ufshci_sim.c optional ufshci
+dev/ufshci/ufshci_sysctl.c optional ufshci
+dev/ufshci/ufshci_uic_cmd.c optional ufshci
+#
# USB controller drivers
#
dev/usb/controller/musb_otg.c optional musb
diff --git a/sys/dev/gpio/gpiobus.c b/sys/dev/gpio/gpiobus.c
index ab7f13177969..764bcb7e6ee8 100644
--- a/sys/dev/gpio/gpiobus.c
+++ b/sys/dev/gpio/gpiobus.c
@@ -110,10 +110,9 @@ gpio_alloc_intr_resource(device_t consumer_dev, int *rid, u_int alloc_flags,
res = bus_alloc_resource(consumer_dev, SYS_RES_IRQ, rid, irq, irq, 1,
alloc_flags);
if (res == NULL) {
- intr_free_intr_map_data((struct intr_map_data *)gpio_data);
+ intr_unmap_irq(irq);
return (NULL);
}
- rman_set_virtual(res, gpio_data);
return (res);
}
#else
@@ -866,6 +865,25 @@ gpiobus_alloc_resource(device_t bus, device_t child, int type, int *rid,
end, count, flags));
}
+static int
+gpiobus_release_resource(device_t dev, device_t child, struct resource *r)
+{
+ int err;
+#ifdef INTRNG
+ u_int irq;
+
+ irq = rman_get_start(r);
+ MPASS(irq == rman_get_end(r));
+#endif
+ err = bus_generic_rman_release_resource(dev, child, r);
+ if (err != 0)
+ return (err);
+#ifdef INTRNG
+ intr_unmap_irq(irq);
+#endif
+ return (0);
+}
+
static struct resource_list *
gpiobus_get_resource_list(device_t bus __unused, device_t child)
{
@@ -1060,7 +1078,7 @@ static device_method_t gpiobus_methods[] = {
DEVMETHOD(bus_get_resource, bus_generic_rl_get_resource),
DEVMETHOD(bus_set_resource, bus_generic_rl_set_resource),
DEVMETHOD(bus_alloc_resource, gpiobus_alloc_resource),
- DEVMETHOD(bus_release_resource, bus_generic_rman_release_resource),
+ DEVMETHOD(bus_release_resource, gpiobus_release_resource),
DEVMETHOD(bus_activate_resource, bus_generic_rman_activate_resource),
DEVMETHOD(bus_deactivate_resource, bus_generic_rman_deactivate_resource),
DEVMETHOD(bus_get_resource_list, gpiobus_get_resource_list),
diff --git a/sys/dev/md/md.c b/sys/dev/md/md.c
index 741a7c013f7d..29dc0c880e3a 100644
--- a/sys/dev/md/md.c
+++ b/sys/dev/md/md.c
@@ -11,9 +11,9 @@
*/
/*-
- * The following functions are based on the vn(4) driver: mdstart_swap(),
- * mdstart_vnode(), mdcreate_swap(), mdcreate_vnode() and mddestroy(),
- * and as such under the following copyright:
+ * The following functions are based on the historical vn(4) driver:
+ * mdstart_swap(), mdstart_vnode(), mdcreate_swap(), mdcreate_vnode()
+ * and mddestroy(), and as such under the following copyright:
*
* Copyright (c) 1988 University of Utah.
* Copyright (c) 1990, 1993
diff --git a/sys/dev/mgb/if_mgb.c b/sys/dev/mgb/if_mgb.c
index 1240d0f84415..409f34167df0 100644
--- a/sys/dev/mgb/if_mgb.c
+++ b/sys/dev/mgb/if_mgb.c
@@ -1435,7 +1435,7 @@ mgb_hw_teardown(struct mgb_softc *sc)
/* Stop MAC */
CSR_CLEAR_REG(sc, MGB_MAC_RX, MGB_MAC_ENBL);
- CSR_WRITE_REG(sc, MGB_MAC_TX, MGB_MAC_ENBL);
+ CSR_CLEAR_REG(sc, MGB_MAC_TX, MGB_MAC_ENBL);
if ((err = mgb_wait_for_bits(sc, MGB_MAC_RX, MGB_MAC_DSBL, 0)))
return (err);
if ((err = mgb_wait_for_bits(sc, MGB_MAC_TX, MGB_MAC_DSBL, 0)))
diff --git a/sys/dev/mlx5/mlx5_accel/ipsec.h b/sys/dev/mlx5/mlx5_accel/ipsec.h
index 361b9f72d873..c3f3a2372482 100644
--- a/sys/dev/mlx5/mlx5_accel/ipsec.h
+++ b/sys/dev/mlx5/mlx5_accel/ipsec.h
@@ -260,8 +260,8 @@ int mlx5e_accel_ipsec_fs_rx_tables_create(struct mlx5e_priv *priv);
void mlx5e_accel_ipsec_fs_rx_catchall_rules_destroy(struct mlx5e_priv *priv);
int mlx5e_accel_ipsec_fs_rx_catchall_rules(struct mlx5e_priv *priv);
int mlx5_accel_ipsec_rx_tag_add(if_t ifp, struct mlx5e_rq_mbuf *mr);
-void mlx5e_accel_ipsec_handle_rx_cqe(struct mbuf *mb, struct mlx5_cqe64 *cqe,
- struct mlx5e_rq_mbuf *mr);
+void mlx5e_accel_ipsec_handle_rx_cqe(if_t ifp, struct mbuf *mb,
+ struct mlx5_cqe64 *cqe, struct mlx5e_rq_mbuf *mr);
static inline int mlx5e_accel_ipsec_flow(struct mlx5_cqe64 *cqe)
{
@@ -269,12 +269,12 @@ static inline int mlx5e_accel_ipsec_flow(struct mlx5_cqe64 *cqe)
}
static inline void
-mlx5e_accel_ipsec_handle_rx(struct mbuf *mb, struct mlx5_cqe64 *cqe,
+mlx5e_accel_ipsec_handle_rx(if_t ifp, struct mbuf *mb, struct mlx5_cqe64 *cqe,
struct mlx5e_rq_mbuf *mr)
{
u32 ipsec_meta_data = be32_to_cpu(cqe->ft_metadata);
if (MLX5_IPSEC_METADATA_MARKER(ipsec_meta_data))
- mlx5e_accel_ipsec_handle_rx_cqe(mb, cqe, mr);
+ mlx5e_accel_ipsec_handle_rx_cqe(ifp, mb, cqe, mr);
}
#endif /* __MLX5_ACCEL_IPSEC_H__ */
diff --git a/sys/dev/mlx5/mlx5_accel/mlx5_ipsec_rxtx.c b/sys/dev/mlx5/mlx5_accel/mlx5_ipsec_rxtx.c
index 0883cfb2d510..5dccb8bc2b87 100644
--- a/sys/dev/mlx5/mlx5_accel/mlx5_ipsec_rxtx.c
+++ b/sys/dev/mlx5/mlx5_accel/mlx5_ipsec_rxtx.c
@@ -24,11 +24,14 @@
*
*/
+#include "opt_ipsec.h"
+
#include <sys/mbuf.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netipsec/keydb.h>
#include <netipsec/ipsec_offload.h>
+#include <netipsec/xform.h>
#include <dev/mlx5/qp.h>
#include <dev/mlx5/mlx5_en/en.h>
#include <dev/mlx5/mlx5_accel/ipsec.h>
@@ -48,7 +51,8 @@ mlx5_accel_ipsec_rx_tag_add(if_t ifp, struct mlx5e_rq_mbuf *mr)
return (0);
mtag = (struct ipsec_accel_in_tag *)m_tag_get(
- PACKET_TAG_IPSEC_ACCEL_IN, sizeof(*mtag), M_NOWAIT);
+ PACKET_TAG_IPSEC_ACCEL_IN, sizeof(struct ipsec_accel_in_tag) -
+ __offsetof(struct ipsec_accel_in_tag, xh), M_NOWAIT);
if (mtag == NULL)
return (-ENOMEM);
mr->ipsec_mtag = mtag;
@@ -56,8 +60,8 @@ mlx5_accel_ipsec_rx_tag_add(if_t ifp, struct mlx5e_rq_mbuf *mr)
}
void
-mlx5e_accel_ipsec_handle_rx_cqe(struct mbuf *mb, struct mlx5_cqe64 *cqe,
- struct mlx5e_rq_mbuf *mr)
+mlx5e_accel_ipsec_handle_rx_cqe(if_t ifp, struct mbuf *mb,
+ struct mlx5_cqe64 *cqe, struct mlx5e_rq_mbuf *mr)
{
struct ipsec_accel_in_tag *mtag;
u32 drv_spi;
@@ -65,10 +69,12 @@ mlx5e_accel_ipsec_handle_rx_cqe(struct mbuf *mb, struct mlx5_cqe64 *cqe,
drv_spi = MLX5_IPSEC_METADATA_HANDLE(be32_to_cpu(cqe->ft_metadata));
mtag = mr->ipsec_mtag;
WARN_ON(mtag == NULL);
- mr->ipsec_mtag = NULL;
if (mtag != NULL) {
mtag->drv_spi = drv_spi;
- m_tag_prepend(mb, &mtag->tag);
+ if (ipsec_accel_fill_xh(ifp, drv_spi, &mtag->xh)) {
+ m_tag_prepend(mb, &mtag->tag);
+ mr->ipsec_mtag = NULL;
+ }
}
}
diff --git a/sys/dev/mlx5/mlx5_en/mlx5_en_hw_tls_rx.c b/sys/dev/mlx5/mlx5_en/mlx5_en_hw_tls_rx.c
index 4de451f1b039..89d2010656c5 100644
--- a/sys/dev/mlx5/mlx5_en/mlx5_en_hw_tls_rx.c
+++ b/sys/dev/mlx5/mlx5_en/mlx5_en_hw_tls_rx.c
@@ -659,7 +659,8 @@ mlx5e_tls_rx_set_params(void *ctx, struct inpcb *inp, const struct tls_session_p
return (EINVAL);
MLX5_SET64(sw_tls_rx_cntx, ctx, param.initial_record_number, tls_sn_he);
- MLX5_SET(sw_tls_rx_cntx, ctx, param.resync_tcp_sn, tcp_sn_he);
+ MLX5_SET(sw_tls_rx_cntx, ctx, param.resync_tcp_sn, 0);
+ MLX5_SET(sw_tls_rx_cntx, ctx, progress.next_record_tcp_sn, tcp_sn_he);
return (0);
}
diff --git a/sys/dev/mlx5/mlx5_en/mlx5_en_rx.c b/sys/dev/mlx5/mlx5_en/mlx5_en_rx.c
index 6b53db6fea23..eb569488631a 100644
--- a/sys/dev/mlx5/mlx5_en/mlx5_en_rx.c
+++ b/sys/dev/mlx5/mlx5_en/mlx5_en_rx.c
@@ -467,7 +467,7 @@ mlx5e_build_rx_mbuf(struct mlx5_cqe64 *cqe, struct mlx5e_rq *rq,
break;
}
- mlx5e_accel_ipsec_handle_rx(mb, cqe, mr);
+ mlx5e_accel_ipsec_handle_rx(ifp, mb, cqe, mr);
}
static inline void
diff --git a/sys/dev/qlnx/qlnxe/qlnx_os.c b/sys/dev/qlnx/qlnxe/qlnx_os.c
index 05ec69a70dfe..9d23d5df1d2b 100644
--- a/sys/dev/qlnx/qlnxe/qlnx_os.c
+++ b/sys/dev/qlnx/qlnxe/qlnx_os.c
@@ -30,6 +30,8 @@
* Author : David C Somayajulu, Cavium, Inc., San Jose, CA 95131.
*/
+#include "opt_inet.h"
+
#include <sys/cdefs.h>
#include "qlnx_os.h"
#include "bcm_osal.h"
@@ -2778,7 +2780,7 @@ qlnx_ioctl(if_t ifp, u_long cmd, caddr_t data)
if (!p_ptt) {
QL_DPRINT1(ha, "ecore_ptt_acquire failed\n");
- ret = -1;
+ ret = ERESTART;
break;
}
@@ -2789,7 +2791,7 @@ qlnx_ioctl(if_t ifp, u_long cmd, caddr_t data)
ecore_ptt_release(p_hwfn, p_ptt);
if (ret) {
- ret = -1;
+ ret = ENODEV;
break;
}
diff --git a/sys/dev/ufshci/ufshci_private.h b/sys/dev/ufshci/ufshci_private.h
index cac743884ee6..ac58d44102a0 100644
--- a/sys/dev/ufshci/ufshci_private.h
+++ b/sys/dev/ufshci/ufshci_private.h
@@ -149,6 +149,8 @@ struct ufshci_hw_queue {
bus_dmamap_t queuemem_map;
bus_addr_t req_queue_addr;
+ bus_addr_t *ucd_bus_addr;
+
uint32_t num_entries;
uint32_t num_trackers;
@@ -198,8 +200,6 @@ struct ufshci_req_queue {
bus_dma_tag_t dma_tag_payload;
bus_dmamap_t ucdmem_map;
-
- bus_addr_t ucd_addr;
};
struct ufshci_device {
diff --git a/sys/dev/ufshci/ufshci_req_sdb.c b/sys/dev/ufshci/ufshci_req_sdb.c
index 4670281d367a..b1f303afaef5 100644
--- a/sys/dev/ufshci/ufshci_req_sdb.c
+++ b/sys/dev/ufshci/ufshci_req_sdb.c
@@ -48,6 +48,29 @@ ufshci_req_sdb_cmd_desc_destroy(struct ufshci_req_queue *req_queue)
}
}
+static void
+ufshci_ucd_map(void *arg, bus_dma_segment_t *seg, int nseg, int error)
+{
+ struct ufshci_hw_queue *hwq = arg;
+ int i;
+
+ if (error != 0) {
+ printf("ufshci: Failed to map UCD, error = %d\n", error);
+ return;
+ }
+
+ if (hwq->num_trackers != nseg) {
+ printf(
+ "ufshci: Failed to map UCD, num_trackers = %d, nseg = %d\n",
+ hwq->num_trackers, nseg);
+ return;
+ }
+
+ for (i = 0; i < nseg; i++) {
+ hwq->ucd_bus_addr[i] = seg[i].ds_addr;
+ }
+}
+
static int
ufshci_req_sdb_cmd_desc_construct(struct ufshci_req_queue *req_queue,
uint32_t num_entries, struct ufshci_controller *ctrlr)
@@ -55,7 +78,6 @@ ufshci_req_sdb_cmd_desc_construct(struct ufshci_req_queue *req_queue,
struct ufshci_hw_queue *hwq = &req_queue->hwq[UFSHCI_SDB_Q];
struct ufshci_tracker *tr;
size_t ucd_allocsz, payload_allocsz;
- uint64_t ucdmem_phys;
uint8_t *ucdmem;
int i, error;
@@ -71,10 +93,11 @@ ufshci_req_sdb_cmd_desc_construct(struct ufshci_req_queue *req_queue,
* Allocate physical memory for UTP Command Descriptor (UCD)
* Note: UFSHCI UCD format is restricted to 128-byte alignment.
*/
- error = bus_dma_tag_create(bus_get_dma_tag(ctrlr->dev), 128,
- ctrlr->page_size, BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL,
- ucd_allocsz, howmany(ucd_allocsz, ctrlr->page_size),
- ctrlr->page_size, 0, NULL, NULL, &req_queue->dma_tag_ucd);
+ error = bus_dma_tag_create(bus_get_dma_tag(ctrlr->dev), 128, 0,
+ BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL, ucd_allocsz,
+ howmany(ucd_allocsz, sizeof(struct ufshci_utp_cmd_desc)),
+ sizeof(struct ufshci_utp_cmd_desc), 0, NULL, NULL,
+ &req_queue->dma_tag_ucd);
if (error != 0) {
ufshci_printf(ctrlr, "request cmd desc tag create failed %d\n",
error);
@@ -88,7 +111,7 @@ ufshci_req_sdb_cmd_desc_construct(struct ufshci_req_queue *req_queue,
}
if (bus_dmamap_load(req_queue->dma_tag_ucd, req_queue->ucdmem_map,
- ucdmem, ucd_allocsz, ufshci_single_map, &ucdmem_phys, 0) != 0) {
+ ucdmem, ucd_allocsz, ufshci_ucd_map, hwq, 0) != 0) {
ufshci_printf(ctrlr, "failed to load cmd desc memory\n");
bus_dmamem_free(req_queue->dma_tag_ucd, req_queue->ucd,
req_queue->ucdmem_map);
@@ -96,7 +119,6 @@ ufshci_req_sdb_cmd_desc_construct(struct ufshci_req_queue *req_queue,
}
req_queue->ucd = (struct ufshci_utp_cmd_desc *)ucdmem;
- req_queue->ucd_addr = ucdmem_phys;
/*
* Allocate physical memory for PRDT
@@ -128,10 +150,9 @@ ufshci_req_sdb_cmd_desc_construct(struct ufshci_req_queue *req_queue,
tr->slot_state = UFSHCI_SLOT_STATE_FREE;
tr->ucd = (struct ufshci_utp_cmd_desc *)ucdmem;
- tr->ucd_bus_addr = ucdmem_phys;
+ tr->ucd_bus_addr = hwq->ucd_bus_addr[i];
ucdmem += sizeof(struct ufshci_utp_cmd_desc);
- ucdmem_phys += sizeof(struct ufshci_utp_cmd_desc);
hwq->act_tr[i] = tr;
}
@@ -175,6 +196,11 @@ ufshci_req_sdb_construct(struct ufshci_controller *ctrlr,
req_queue->hwq = malloc(sizeof(struct ufshci_hw_queue), M_UFSHCI,
M_ZERO | M_NOWAIT);
hwq = &req_queue->hwq[UFSHCI_SDB_Q];
+ hwq->num_entries = req_queue->num_entries;
+ hwq->num_trackers = req_queue->num_trackers;
+ req_queue->hwq->ucd_bus_addr = malloc(sizeof(bus_addr_t) *
+ req_queue->num_trackers,
+ M_UFSHCI, M_ZERO | M_NOWAIT);
mtx_init(&hwq->qlock, "ufshci req_queue lock", NULL, MTX_DEF);
@@ -277,6 +303,7 @@ ufshci_req_sdb_destroy(struct ufshci_controller *ctrlr,
if (mtx_initialized(&hwq->qlock))
mtx_destroy(&hwq->qlock);
+ free(req_queue->hwq->ucd_bus_addr, M_UFSHCI);
free(req_queue->hwq, M_UFSHCI);
}
diff --git a/sys/dev/usb/controller/xhci_pci.c b/sys/dev/usb/controller/xhci_pci.c
index b50e33ea36ce..d5cfd228a429 100644
--- a/sys/dev/usb/controller/xhci_pci.c
+++ b/sys/dev/usb/controller/xhci_pci.c
@@ -99,6 +99,11 @@ xhci_pci_match(device_t self)
return ("AMD Starship USB 3.0 controller");
case 0x149c1022:
return ("AMD Matisse USB 3.0 controller");
+ case 0x15b61022:
+ case 0x15b71022:
+ return ("AMD Raphael/Granite Ridge USB 3.1 controller");
+ case 0x15b81022:
+ return ("AMD Raphael/Granite Ridge USB 2.0 controller");
case 0x15e01022:
case 0x15e11022:
return ("AMD Raven USB 3.1 controller");
@@ -109,6 +114,8 @@ xhci_pci_match(device_t self)
return ("AMD 300 Series USB 3.1 controller");
case 0x43d51022:
return ("AMD 400 Series USB 3.1 controller");
+ case 0x43f71022:
+ return ("AMD 600 Series USB 3.2 controller");
case 0x78121022:
case 0x78141022:
case 0x79141022:
diff --git a/sys/fs/fdescfs/fdesc_vnops.c b/sys/fs/fdescfs/fdesc_vnops.c
index 676ea5de12b8..58a22b8bdc50 100644
--- a/sys/fs/fdescfs/fdesc_vnops.c
+++ b/sys/fs/fdescfs/fdesc_vnops.c
@@ -547,6 +547,8 @@ fdesc_readdir(struct vop_readdir_args *ap)
fmp = VFSTOFDESC(ap->a_vp->v_mount);
if (ap->a_ncookies != NULL)
*ap->a_ncookies = 0;
+ if (ap->a_eofflag != NULL)
+ *ap->a_eofflag = 0;
off = (int)uio->uio_offset;
if (off != uio->uio_offset || off < 0 || (u_int)off % UIO_MX != 0 ||
@@ -559,7 +561,12 @@ fdesc_readdir(struct vop_readdir_args *ap)
fcnt = i - 2; /* The first two nodes are `.' and `..' */
FILEDESC_SLOCK(fdp);
- while (i < fdp->fd_nfiles + 2 && uio->uio_resid >= UIO_MX) {
+ while (uio->uio_resid >= UIO_MX) {
+ if (i >= fdp->fd_nfiles + 2) {
+ if (ap->a_eofflag != NULL)
+ *ap->a_eofflag = 1;
+ break;
+ }
bzero((caddr_t)dp, UIO_MX);
switch (i) {
case 0: /* `.' */
diff --git a/sys/fs/msdosfs/msdosfs_vnops.c b/sys/fs/msdosfs/msdosfs_vnops.c
index 5db61c8951f6..33e0d94954d7 100644
--- a/sys/fs/msdosfs/msdosfs_vnops.c
+++ b/sys/fs/msdosfs/msdosfs_vnops.c
@@ -1521,6 +1521,9 @@ msdosfs_readdir(struct vop_readdir_args *ap)
ap->a_vp, uio, ap->a_cred, ap->a_eofflag);
#endif
+ if (ap->a_eofflag != NULL)
+ *ap->a_eofflag = 0;
+
/*
* msdosfs_readdir() won't operate properly on regular files since
* it does i/o only with the filesystem vnode, and hence can
@@ -1614,8 +1617,11 @@ msdosfs_readdir(struct vop_readdir_args *ap)
on = (offset - bias) & pmp->pm_crbomask;
n = min(pmp->pm_bpcluster - on, uio->uio_resid);
diff = dep->de_FileSize - (offset - bias);
- if (diff <= 0)
- break;
+ if (diff <= 0) {
+ if (ap->a_eofflag != NULL)
+ *ap->a_eofflag = 1;
+ goto out;
+ }
n = min(n, diff);
error = pcbmap(dep, lbn, &bn, &cn, &blsize);
if (error)
@@ -1646,6 +1652,8 @@ msdosfs_readdir(struct vop_readdir_args *ap)
*/
if (dentp->deName[0] == SLOT_EMPTY) {
brelse(bp);
+ if (ap->a_eofflag != NULL)
+ *ap->a_eofflag = 1;
goto out;
}
/*
@@ -1743,15 +1751,6 @@ out:
uio->uio_offset = off;
- /*
- * Set the eofflag (NFS uses it)
- */
- if (ap->a_eofflag) {
- if (dep->de_FileSize - (offset - bias) <= 0)
- *ap->a_eofflag = 1;
- else
- *ap->a_eofflag = 0;
- }
return (error);
}
diff --git a/sys/fs/p9fs/p9fs_vnops.c b/sys/fs/p9fs/p9fs_vnops.c
index 56bf766ef801..227e2b93883e 100644
--- a/sys/fs/p9fs/p9fs_vnops.c
+++ b/sys/fs/p9fs/p9fs_vnops.c
@@ -1784,6 +1784,9 @@ p9fs_readdir(struct vop_readdir_args *ap)
return (EBADF);
}
+ if (ap->a_eofflag != NULL)
+ *ap->a_eofflag = 0;
+
io_buffer = uma_zalloc(p9fs_io_buffer_zone, M_WAITOK);
/* We haven't reached the end yet. read more. */
@@ -1801,8 +1804,11 @@ p9fs_readdir(struct vop_readdir_args *ap)
count = p9_client_readdir(vofid, (char *)io_buffer,
diroffset, count);
- if (count == 0)
+ if (count == 0) {
+ if (ap->a_eofflag != NULL)
+ *ap->a_eofflag = 1;
break;
+ }
if (count < 0) {
error = EIO;
diff --git a/sys/fs/udf/ecma167-udf.h b/sys/fs/udf/ecma167-udf.h
index 839bbec08254..19e114763cac 100644
--- a/sys/fs/udf/ecma167-udf.h
+++ b/sys/fs/udf/ecma167-udf.h
@@ -243,7 +243,7 @@ struct part_map_spare {
uint8_t n_st; /* Number of Sparing Tables */
uint8_t reserved1;
uint32_t st_size;
- uint32_t st_loc[1];
+ uint32_t st_loc[];
} __packed;
union udf_pmap {
@@ -266,7 +266,7 @@ struct udf_sparing_table {
uint16_t rt_l; /* Relocation Table len */
uint8_t reserved[2];
uint32_t seq_num;
- struct spare_map_entry entries[1];
+ struct spare_map_entry entries[];
} __packed;
/* Partition Descriptor [3/10.5] */
diff --git a/sys/fs/udf/udf_vfsops.c b/sys/fs/udf/udf_vfsops.c
index c7438147c0a0..c5ef1f686093 100644
--- a/sys/fs/udf/udf_vfsops.c
+++ b/sys/fs/udf/udf_vfsops.c
@@ -81,6 +81,7 @@
#include <sys/fcntl.h>
#include <sys/iconv.h>
#include <sys/kernel.h>
+#include <sys/limits.h>
#include <sys/malloc.h>
#include <sys/mount.h>
#include <sys/namei.h>
@@ -729,7 +730,7 @@ udf_fhtovp(struct mount *mp, struct fid *fhp, int flags, struct vnode **vpp)
struct ifid *ifhp;
struct vnode *nvp;
struct udf_node *np;
- off_t fsize;
+ uint64_t fsize;
int error;
ifhp = (struct ifid *)fhp;
@@ -741,6 +742,10 @@ udf_fhtovp(struct mount *mp, struct fid *fhp, int flags, struct vnode **vpp)
np = VTON(nvp);
fsize = le64toh(np->fentry->inf_len);
+ if (fsize > OFF_MAX) {
+ *vpp = NULLVP;
+ return (EIO);
+ }
*vpp = nvp;
vnode_create_vobject(*vpp, fsize, curthread);
diff --git a/sys/fs/udf/udf_vnops.c b/sys/fs/udf/udf_vnops.c
index 88bf4917a851..37889241e8c3 100644
--- a/sys/fs/udf/udf_vnops.c
+++ b/sys/fs/udf/udf_vnops.c
@@ -39,6 +39,7 @@
#include <sys/conf.h>
#include <sys/buf.h>
#include <sys/iconv.h>
+#include <sys/limits.h>
#include <sys/mount.h>
#include <sys/vnode.h>
#include <sys/dirent.h>
@@ -182,11 +183,14 @@ udf_access(struct vop_access_args *a)
}
static int
-udf_open(struct vop_open_args *ap) {
+udf_open(struct vop_open_args *ap)
+{
struct udf_node *np = VTON(ap->a_vp);
- off_t fsize;
+ uint64_t fsize;
fsize = le64toh(np->fentry->inf_len);
+ if (fsize > OFF_MAX)
+ return (EIO);
vnode_create_vobject(ap->a_vp, fsize, ap->a_td);
return 0;
}
@@ -314,12 +318,13 @@ udf_getattr(struct vop_getattr_args *a)
* that directories consume at least one logical block,
* make it appear so.
*/
- if (fentry->logblks_rec != 0) {
- vap->va_size =
- le64toh(fentry->logblks_rec) * node->udfmp->bsize;
- } else {
+ vap->va_size = le64toh(fentry->logblks_rec);
+ if (vap->va_size == 0)
vap->va_size = node->udfmp->bsize;
- }
+ else if (vap->va_size > UINT64_MAX / node->udfmp->bsize)
+ vap->va_size = UINT64_MAX;
+ else
+ vap->va_size *= node->udfmp->bsize;
} else {
vap->va_size = le64toh(fentry->inf_len);
}
@@ -446,6 +451,7 @@ udf_read(struct vop_read_args *ap)
struct buf *bp;
uint8_t *data;
daddr_t lbn, rablock;
+ uint64_t len;
off_t diff, fsize;
ssize_t n;
int error = 0;
@@ -471,7 +477,12 @@ udf_read(struct vop_read_args *ap)
return (error);
}
- fsize = le64toh(node->fentry->inf_len);
+ len = le64toh(node->fentry->inf_len);
+ if (len > OFF_MAX) {
+ /* too big, just cap to the requested length */
+ len = uio->uio_resid;
+ }
+ fsize = len;
udfmp = node->udfmp;
do {
lbn = lblkno(udfmp, uio->uio_offset);
@@ -783,6 +794,7 @@ udf_readdir(struct vop_readdir_args *a)
struct udf_uiodir uiodir;
struct udf_dirstream *ds;
uint64_t *cookies = NULL;
+ uint64_t len;
int ncookies;
int error = 0;
@@ -811,8 +823,12 @@ udf_readdir(struct vop_readdir_args *a)
* Iterate through the file id descriptors. Give the parent dir
* entry special attention.
*/
- ds = udf_opendir(node, uio->uio_offset, le64toh(node->fentry->inf_len),
- node->udfmp);
+ len = le64toh(node->fentry->inf_len);
+ if (len > INT_MAX) {
+ /* too big, just cap to INT_MAX */
+ len = INT_MAX;
+ }
+ ds = udf_opendir(node, uio->uio_offset, len, node->udfmp);
while ((fid = udf_getfid(ds)) != NULL) {
/* XXX Should we return an error on a bad fid? */
@@ -904,7 +920,8 @@ udf_readlink(struct vop_readlink_args *ap)
struct udf_node *node;
void *buf;
char *cp;
- int error, len, root;
+ uint64_t len;
+ int error, root;
/*
* A symbolic link in UDF is a list of variable-length path
@@ -914,6 +931,8 @@ udf_readlink(struct vop_readlink_args *ap)
vp = ap->a_vp;
node = VTON(vp);
len = le64toh(node->fentry->inf_len);
+ if (len > MAXPATHLEN)
+ return (EIO);
buf = malloc(len, M_DEVBUF, M_WAITOK);
iov[0].iov_len = len;
iov[0].iov_base = buf;
@@ -1116,13 +1135,14 @@ udf_lookup(struct vop_cachedlookup_args *a)
struct udf_mnt *udfmp;
struct fileid_desc *fid = NULL;
struct udf_dirstream *ds;
+ uint64_t fsize;
u_long nameiop;
u_long flags;
char *nameptr;
long namelen;
ino_t id = 0;
int offset, error = 0;
- int fsize, lkflags, ltype, numdirpasses;
+ int lkflags, ltype, numdirpasses;
dvp = a->a_dvp;
node = VTON(dvp);
@@ -1133,6 +1153,10 @@ udf_lookup(struct vop_cachedlookup_args *a)
nameptr = a->a_cnp->cn_nameptr;
namelen = a->a_cnp->cn_namelen;
fsize = le64toh(node->fentry->inf_len);
+ if (fsize > INT_MAX) {
+ /* too big, just cap to INT_MAX */
+ fsize = INT_MAX;
+ }
/*
* If this is a LOOKUP and we've already partially searched through
diff --git a/sys/i386/conf/GENERIC b/sys/i386/conf/GENERIC
index e7d460af21d4..f577cd07ac7c 100644
--- a/sys/i386/conf/GENERIC
+++ b/sys/i386/conf/GENERIC
@@ -17,6 +17,8 @@
# in NOTES.
#
+#NO_UNIVERSE
+
cpu I486_CPU
cpu I586_CPU
cpu I686_CPU
diff --git a/sys/i386/conf/GENERIC-NODEBUG b/sys/i386/conf/GENERIC-NODEBUG
index ea07613a796f..a93304481b5f 100644
--- a/sys/i386/conf/GENERIC-NODEBUG
+++ b/sys/i386/conf/GENERIC-NODEBUG
@@ -25,6 +25,8 @@
# in NOTES.
#
+#NO_UNIVERSE
+
include GENERIC
include "std.nodebug"
diff --git a/sys/i386/conf/LINT b/sys/i386/conf/LINT
index 41207eb63cb9..2e947202f723 100644
--- a/sys/i386/conf/LINT
+++ b/sys/i386/conf/LINT
@@ -1,3 +1,4 @@
+#NO_UNIVERSE
include "../../conf/NOTES"
include "../../x86/conf/NOTES"
diff --git a/sys/i386/conf/MINIMAL b/sys/i386/conf/MINIMAL
index 2a06eb84bff8..8019617ca4d4 100644
--- a/sys/i386/conf/MINIMAL
+++ b/sys/i386/conf/MINIMAL
@@ -31,6 +31,8 @@
# in NOTES.
#
+#NO_UNIVERSE
+
cpu I486_CPU
cpu I586_CPU
cpu I686_CPU
diff --git a/sys/i386/conf/PAE b/sys/i386/conf/PAE
index a39d32d77106..72af9e9a9eec 100644
--- a/sys/i386/conf/PAE
+++ b/sys/i386/conf/PAE
@@ -2,6 +2,8 @@
# PAE -- Generic kernel configuration file for FreeBSD/i386 PAE
#
+#NO_UNIVERSE
+
include GENERIC
ident PAE-GENERIC
diff --git a/sys/i386/i386/pmap.c b/sys/i386/i386/pmap.c
index 465b4d0f365b..b44f5e08bbcf 100644
--- a/sys/i386/i386/pmap.c
+++ b/sys/i386/i386/pmap.c
@@ -876,14 +876,16 @@ __CONCAT(PMTYPE, init_pat)(void)
#ifdef PMAP_PAE_COMP
static void *
-pmap_pdpt_allocf(uma_zone_t zone, vm_size_t bytes, int domain, uint8_t *flags,
- int wait)
+pmap_pdpt_allocf(uma_zone_t zone, vm_size_t bytes, int domain, uint8_t *sflagsp,
+ int flags)
{
/* Inform UMA that this allocator uses kernel_map/object. */
- *flags = UMA_SLAB_KERNEL;
+ *sflagsp = UMA_SLAB_KERNEL;
+ /* contig allocations cannot be NEVERFREED */
+ flags &= ~M_NEVERFREED;
return ((void *)kmem_alloc_contig_domainset(DOMAINSET_FIXED(domain),
- bytes, wait, 0x0ULL, 0xffffffffULL, 1, 0, VM_MEMATTR_DEFAULT));
+ bytes, flags, 0x0ULL, 0xffffffffULL, 1, 0, VM_MEMATTR_DEFAULT));
}
#endif
@@ -5617,6 +5619,8 @@ __CONCAT(PMTYPE, unmapdev)(void *p, vm_size_t size)
static void
__CONCAT(PMTYPE, page_set_memattr)(vm_page_t m, vm_memattr_t ma)
{
+ if (m->md.pat_mode == ma)
+ return;
m->md.pat_mode = ma;
if ((m->flags & PG_FICTITIOUS) != 0)
diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c
index 93bdd41d1515..a27ab33b34da 100644
--- a/sys/kern/kern_descrip.c
+++ b/sys/kern/kern_descrip.c
@@ -557,8 +557,10 @@ open_to_fde_flags(int open_flags, bool sticky_orb)
{ .f = O_CLOFORK, .t = UF_FOCLOSE },
{ .f = O_RESOLVE_BENEATH, .t = UF_RESOLVE_BENEATH },
};
+#if defined(__clang__) && __clang_major__ >= 19
_Static_assert(open_to_fde_flags_s[nitems(open_to_fde_flags_s) - 1].f ==
O_RESOLVE_BENEATH, "O_RESOLVE_BENEATH must be last, for sticky_orb");
+#endif
return (flags_trans(open_to_fde_flags_s, nitems(open_to_fde_flags_s) -
(sticky_orb ? 0 : 1), open_flags));
diff --git a/sys/kern/subr_asan.c b/sys/kern/subr_asan.c
index 0edb631d1475..464efda1e91a 100644
--- a/sys/kern/subr_asan.c
+++ b/sys/kern/subr_asan.c
@@ -263,8 +263,7 @@ kasan_mark(const void *addr, size_t size, size_t redzsize, uint8_t code)
if (__predict_false(!kasan_enabled))
return;
- if ((vm_offset_t)addr >= DMAP_MIN_ADDRESS &&
- (vm_offset_t)addr < DMAP_MAX_ADDRESS)
+ if (kasan_md_unsupported((vm_offset_t)addr))
return;
KASSERT((vm_offset_t)addr >= VM_MIN_KERNEL_ADDRESS &&
diff --git a/sys/kern/subr_trap.c b/sys/kern/subr_trap.c
index 18388ae5f232..bac7d0080c71 100644
--- a/sys/kern/subr_trap.c
+++ b/sys/kern/subr_trap.c
@@ -338,8 +338,9 @@ ast_handler(struct thread *td, struct trapframe *framep, bool dtor)
td->td_ast = 0;
}
- CTR3(KTR_SYSC, "ast: thread %p (pid %d, %s)", td, td->td_proc->p_pid,
- td->td_proc->p_comm);
+ CTR3(KTR_SYSC, "ast: thread %p (pid %d, %s)", td,
+ td->td_proc == NULL ? -1 : td->td_proc->p_pid,
+ td->td_proc == NULL ? "" : td->td_proc->p_comm);
KASSERT(framep == NULL || TRAPF_USERMODE(framep),
("ast in kernel mode"));
diff --git a/sys/kern/sys_generic.c b/sys/kern/sys_generic.c
index 94e44d888181..b472aaea89e6 100644
--- a/sys/kern/sys_generic.c
+++ b/sys/kern/sys_generic.c
@@ -2309,6 +2309,12 @@ sys_exterrctl(struct thread *td, struct exterrctl_args *uap)
return (EINVAL);
td->td_pflags2 &= ~TDP2_UEXTERR;
return (0);
+ case EXTERRCTL_UD:
+ /*
+ * Important: this code must always return EINVAL and never any
+ * extended error, for testing purposes.
+ */
+ /* FALLTHROUGH */
default:
return (EINVAL);
}
diff --git a/sys/kern/vfs_cache.c b/sys/kern/vfs_cache.c
index 3d455b3874cc..89c1d779f04c 100644
--- a/sys/kern/vfs_cache.c
+++ b/sys/kern/vfs_cache.c
@@ -332,7 +332,8 @@ SDT_PROBE_DEFINE2(vfs, namecache, evict_negative, done, "struct vnode *",
"char *");
SDT_PROBE_DEFINE1(vfs, namecache, symlink, alloc__fail, "size_t");
-SDT_PROBE_DEFINE3(vfs, fplookup, lookup, done, "struct nameidata", "int", "bool");
+SDT_PROBE_DEFINE3(vfs, fplookup, lookup, done, "struct nameidata *", "int",
+ "enum cache_fpl_status");
SDT_PROBE_DECLARE(vfs, namei, lookup, entry);
SDT_PROBE_DECLARE(vfs, namei, lookup, return);
@@ -6420,15 +6421,11 @@ out:
cache_fpl_smr_assert_not_entered(&fpl);
cache_fpl_assert_status(&fpl);
*status = fpl.status;
- if (SDT_PROBES_ENABLED()) {
- SDT_PROBE3(vfs, fplookup, lookup, done, ndp, fpl.line, fpl.status);
- if (fpl.status == CACHE_FPL_STATUS_HANDLED)
- SDT_PROBE4(vfs, namei, lookup, return, error, ndp->ni_vp, true,
- ndp);
- }
-
+ SDT_PROBE3(vfs, fplookup, lookup, done, ndp, fpl.line, fpl.status);
if (__predict_true(fpl.status == CACHE_FPL_STATUS_HANDLED)) {
MPASS(error != CACHE_FPL_FAILED);
+ SDT_PROBE4(vfs, namei, lookup, return, error, ndp->ni_vp, true,
+ ndp);
if (error != 0) {
cache_fpl_cleanup_cnp(fpl.cnp);
MPASS(fpl.dvp == NULL);
diff --git a/sys/modules/Makefile b/sys/modules/Makefile
index 9922796f8a1d..7cb6e2124326 100644
--- a/sys/modules/Makefile
+++ b/sys/modules/Makefile
@@ -326,6 +326,7 @@ SUBDIR= \
proto \
pseudofs \
${_pst} \
+ ${_pt} \
pty \
puc \
pwm \
@@ -842,6 +843,7 @@ _iwx= iwx
_ixl= ixl
_nvdimm= nvdimm
_pms= pms
+_pt= pt
_qat= qat
.if ${MK_SOURCELESS_UCODE} != "no"
_qatfw= qatfw
diff --git a/sys/modules/pt/Makefile b/sys/modules/pt/Makefile
new file mode 100644
index 000000000000..416b072face9
--- /dev/null
+++ b/sys/modules/pt/Makefile
@@ -0,0 +1,8 @@
+
+.PATH: ${SRCTOP}/sys/amd64/pt
+
+KMOD= pt
+SRCS= pt.c pt.h device_if.h bus_if.h
+SRCS+= opt_hwpmc_hooks.h opt_kstack_pages.h
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/qlnx/qlnxe/Makefile b/sys/modules/qlnx/qlnxe/Makefile
index 3d8415cf0e57..2a44ae6ddde5 100644
--- a/sys/modules/qlnx/qlnxe/Makefile
+++ b/sys/modules/qlnx/qlnxe/Makefile
@@ -58,6 +58,7 @@ SRCS+=qlnx_rdma.c
SRCS+=qlnx_ioctl.c
SRCS+=qlnx_os.c
+SRCS+=opt_inet.h
SRCS+= ${LINUXKPI_GENSRCS}
diff --git a/sys/net/ethernet.h b/sys/net/ethernet.h
index cf4f75bd0b6c..01485cf26e06 100644
--- a/sys/net/ethernet.h
+++ b/sys/net/ethernet.h
@@ -62,6 +62,8 @@ struct ether_header {
u_char ether_shost[ETHER_ADDR_LEN];
u_short ether_type;
} __packed;
+_Static_assert(sizeof(struct ether_header) == ETHER_HDR_LEN,
+ "size of struct ether_header is wrong");
/*
* Structure of a 48-bit Ethernet address.
@@ -69,6 +71,8 @@ struct ether_header {
struct ether_addr {
u_char octet[ETHER_ADDR_LEN];
} __packed;
+_Static_assert(sizeof(struct ether_addr) == ETHER_ADDR_LEN,
+ "size of struct ether_addr is wrong");
#define ETHER_IS_MULTICAST(addr) (*(addr) & 0x01) /* is address mcast/bcast? */
#define ETHER_IS_IPV6_MULTICAST(addr) \
@@ -112,6 +116,8 @@ struct ether_vlan_header {
uint16_t evl_tag;
uint16_t evl_proto;
} __packed;
+_Static_assert(sizeof(struct ether_vlan_header) == ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN,
+ "size of struct ether_vlan_header is wrong");
#define EVL_VLID_MASK 0x0FFF
#define EVL_PRI_MASK 0xE000
diff --git a/sys/net/if_ethersubr.c b/sys/net/if_ethersubr.c
index 7be4dfac23e7..3ae0c01c0efc 100644
--- a/sys/net/if_ethersubr.c
+++ b/sys/net/if_ethersubr.c
@@ -92,11 +92,6 @@
#include <crypto/sha1.h>
-#ifdef CTASSERT
-CTASSERT(sizeof (struct ether_header) == ETHER_ADDR_LEN * 2 + 2);
-CTASSERT(sizeof (struct ether_addr) == ETHER_ADDR_LEN);
-#endif
-
VNET_DEFINE(pfil_head_t, link_pfil_head); /* Packet filter hooks */
/* netgraph node hooks for ng_ether(4) */
diff --git a/sys/net/if_lagg.c b/sys/net/if_lagg.c
index 9867a718e148..5b52bfa80e3b 100644
--- a/sys/net/if_lagg.c
+++ b/sys/net/if_lagg.c
@@ -718,6 +718,7 @@ lagg_capabilities(struct lagg_softc *sc)
sc->sc_ifp->if_capenable = ena;
sc->sc_ifp->if_capenable2 = ena2;
sc->sc_ifp->if_hwassist = hwa;
+ (void)if_hw_tsomax_update(sc->sc_ifp, &hw_tsomax);
getmicrotime(&sc->sc_ifp->if_lastchange);
if (sc->sc_ifflags & IFF_DEBUG)
diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h
index 36fab1a03ee6..452a8eb4024b 100644
--- a/sys/net/pfvar.h
+++ b/sys/net/pfvar.h
@@ -1370,7 +1370,6 @@ struct pf_kruleset {
struct pf_krulequeue queues[2];
struct {
struct pf_krulequeue *ptr;
- struct pf_krule **ptr_array;
u_int32_t rcount;
u_int32_t ticket;
int open;
@@ -2500,7 +2499,7 @@ int pfr_match_addr(struct pfr_ktable *, struct pf_addr *, sa_family_t);
void pfr_update_stats(struct pfr_ktable *, struct pf_addr *, sa_family_t,
u_int64_t, int, int, int);
int pfr_pool_get(struct pfr_ktable *, int *, struct pf_addr *, sa_family_t,
- pf_addr_filter_func_t);
+ pf_addr_filter_func_t, bool);
void pfr_dynaddr_update(struct pfr_ktable *, struct pfi_dynaddr *);
struct pfr_ktable *
pfr_attach_table(struct pf_kruleset *, char *);
@@ -2534,6 +2533,8 @@ int pfr_ina_rollback(struct pfr_table *, u_int32_t, int *, int);
int pfr_ina_commit(struct pfr_table *, u_int32_t, int *, int *, int);
int pfr_ina_define(struct pfr_table *, struct pfr_addr *, int, int *,
int *, u_int32_t, int);
+struct pfr_ktable
+ *pfr_ktable_select_active(struct pfr_ktable *);
MALLOC_DECLARE(PFI_MTYPE);
VNET_DECLARE(struct pfi_kkif *, pfi_all);
@@ -2712,7 +2713,6 @@ u_short pf_map_addr(u_int8_t, struct pf_krule *,
u_short pf_map_addr_sn(u_int8_t, struct pf_krule *,
struct pf_addr *, struct pf_addr *,
struct pfi_kkif **nkif, struct pf_addr *,
- struct pf_ksrc_node **, struct pf_srchash **,
struct pf_kpool *, pf_sn_types_t);
int pf_get_transaddr_af(struct pf_krule *,
struct pf_pdesc *);
diff --git a/sys/net80211/ieee80211_hostap.c b/sys/net80211/ieee80211_hostap.c
index c5a478533313..9074878e17e4 100644
--- a/sys/net80211/ieee80211_hostap.c
+++ b/sys/net80211/ieee80211_hostap.c
@@ -2214,12 +2214,9 @@ hostap_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
/* VHT */
if (IEEE80211_IS_CHAN_VHT(ni->ni_chan) &&
- vhtcap != NULL &&
- vhtinfo != NULL) {
- /* XXX TODO; see below */
- net80211_vap_printf(vap, "%s: VHT TODO!\n", __func__);
+ vhtcap != NULL) {
ieee80211_vht_node_init(ni);
- ieee80211_vht_update_cap(ni, vhtcap, vhtinfo);
+ ieee80211_vht_update_cap(ni, vhtcap);
} else if (ni->ni_flags & IEEE80211_NODE_VHT)
ieee80211_vht_node_cleanup(ni);
diff --git a/sys/net80211/ieee80211_ht.c b/sys/net80211/ieee80211_ht.c
index 5ec80e3646b8..c28f124648a1 100644
--- a/sys/net80211/ieee80211_ht.c
+++ b/sys/net80211/ieee80211_ht.c
@@ -1952,6 +1952,11 @@ do { \
_RETURN_CHAN_BITS(0);
/*
+ * TODO: should we bail out if there's no htinfo?
+ * Or just treat it as if we can't do the HT20/HT40 check?
+ */
+
+ /*
* The original code was based on
* 802.11ac-2013, Table 8-183x-VHT Operation Information subfields.
* 802.11-2020, Table 9-274-VHT Operation Information subfields
@@ -1962,8 +1967,12 @@ do { \
*/
htinfo = (const struct ieee80211_ie_htinfo *)ni->ni_ies.htinfo_ie;
- ht40 = ((htinfo->hi_byte1 & IEEE80211_HTINFO_TXWIDTH) ==
- IEEE80211_HTINFO_TXWIDTH_2040);
+ if (htinfo != NULL)
+ ht40 = ((htinfo->hi_byte1 & IEEE80211_HTINFO_TXWIDTH) ==
+ IEEE80211_HTINFO_TXWIDTH_2040);
+ else
+ ht40 = false;
+
can_vht160 = can_vht80p80 = can_vht80 = false;
/* 20 Mhz */
diff --git a/sys/net80211/ieee80211_vht.c b/sys/net80211/ieee80211_vht.c
index e91977f1ef98..de0b691d4d2a 100644
--- a/sys/net80211/ieee80211_vht.c
+++ b/sys/net80211/ieee80211_vht.c
@@ -838,12 +838,10 @@ ieee80211_add_vhtinfo(uint8_t *frm, struct ieee80211_node *ni)
}
void
-ieee80211_vht_update_cap(struct ieee80211_node *ni, const uint8_t *vhtcap_ie,
- const uint8_t *vhtop_ie)
+ieee80211_vht_update_cap(struct ieee80211_node *ni, const uint8_t *vhtcap_ie)
{
ieee80211_parse_vhtcap(ni, vhtcap_ie);
- ieee80211_parse_vhtopmode(ni, vhtop_ie);
}
static struct ieee80211_channel *
diff --git a/sys/net80211/ieee80211_vht.h b/sys/net80211/ieee80211_vht.h
index 2964de63c343..a1529df4a85b 100644
--- a/sys/net80211/ieee80211_vht.h
+++ b/sys/net80211/ieee80211_vht.h
@@ -52,8 +52,7 @@ uint8_t * ieee80211_add_vhtinfo(uint8_t *frm, struct ieee80211_node *);
uint8_t *ieee80211_add_vhtcap_ch(uint8_t *, struct ieee80211vap *,
struct ieee80211_channel *);
-void ieee80211_vht_update_cap(struct ieee80211_node *,
- const uint8_t *, const uint8_t *);
+void ieee80211_vht_update_cap(struct ieee80211_node *, const uint8_t *);
struct ieee80211_channel *
ieee80211_vht_adjust_channel(struct ieee80211com *,
diff --git a/sys/netinet6/raw_ip6.c b/sys/netinet6/raw_ip6.c
index 0379ef7c789a..c90a1213bd66 100644
--- a/sys/netinet6/raw_ip6.c
+++ b/sys/netinet6/raw_ip6.c
@@ -765,8 +765,7 @@ rip6_bind(struct socket *so, struct sockaddr *nam, struct thread *td)
}
if (ifa != NULL &&
((struct in6_ifaddr *)ifa)->ia6_flags &
- (IN6_IFF_ANYCAST|IN6_IFF_NOTREADY|
- IN6_IFF_DETACHED|IN6_IFF_DEPRECATED)) {
+ (IN6_IFF_NOTREADY|IN6_IFF_DETACHED|IN6_IFF_DEPRECATED)) {
NET_EPOCH_EXIT(et);
return (EADDRNOTAVAIL);
}
diff --git a/sys/netipsec/ipsec.c b/sys/netipsec/ipsec.c
index 6bacc68b7441..92d0201b398a 100644
--- a/sys/netipsec/ipsec.c
+++ b/sys/netipsec/ipsec.c
@@ -636,8 +636,10 @@ ipsec4_in_reject1(const struct mbuf *m, struct ip *ip1, struct inpcb *inp)
#ifdef IPSEC_OFFLOAD
tag = ipsec_accel_input_tag_lookup(m);
- if (tag != NULL)
- return (0);
+ if (tag != NULL) {
+ tag->tag.m_tag_id = PACKET_TAG_IPSEC_IN_DONE;
+ __DECONST(struct mbuf *, m)->m_flags |= M_DECRYPTED;
+ }
#endif
if (ip1 == NULL) {
diff --git a/sys/netipsec/ipsec_offload.c b/sys/netipsec/ipsec_offload.c
index 467d5ded1d7a..8a09d5f37b4a 100644
--- a/sys/netipsec/ipsec_offload.c
+++ b/sys/netipsec/ipsec_offload.c
@@ -94,6 +94,7 @@ struct ifp_handle_sav {
size_t hdr_ext_size;
uint64_t cnt_octets;
uint64_t cnt_allocs;
+ struct xform_history xfh;
};
#define IFP_HS_HANDLED 0x00000001
@@ -159,6 +160,8 @@ static void ipsec_accel_drv_sa_lifetime_update_impl(struct secasvar *sav,
static int ipsec_accel_drv_sa_lifetime_fetch_impl(struct secasvar *sav,
if_t ifp, u_int drv_spi, uint64_t *octets, uint64_t *allocs);
static void ipsec_accel_ifdetach_event(void *arg, struct ifnet *ifp);
+static bool ipsec_accel_fill_xh_impl(if_t ifp, uint32_t drv_spi,
+ struct xform_history *xh);
static void
ipsec_accel_init(void *arg)
@@ -185,6 +188,7 @@ ipsec_accel_init(void *arg)
ipsec_accel_drv_sa_lifetime_update_impl;
ipsec_accel_drv_sa_lifetime_fetch_p =
ipsec_accel_drv_sa_lifetime_fetch_impl;
+ ipsec_accel_fill_xh_p = ipsec_accel_fill_xh_impl;
pctrie_init(&drv_spi_pctrie);
ipsec_accel_ifdetach_event_tag = EVENTHANDLER_REGISTER(
ifnet_departure_event, ipsec_accel_ifdetach_event, NULL,
@@ -209,6 +213,7 @@ ipsec_accel_fini(void *arg)
ipsec_accel_on_ifdown_p = NULL;
ipsec_accel_drv_sa_lifetime_update_p = NULL;
ipsec_accel_drv_sa_lifetime_fetch_p = NULL;
+ ipsec_accel_fill_xh_p = NULL;
ipsec_accel_sync_imp();
clean_unrhdr(drv_spi_unr); /* avoid panic, should go later */
clear_unrhdr(drv_spi_unr);
@@ -412,6 +417,10 @@ ipsec_accel_handle_sav(struct secasvar *sav, struct ifnet *ifp,
ihs->ifdata = priv;
ihs->flags = flags;
ihs->hdr_ext_size = esp_hdrsiz(sav);
+ memcpy(&ihs->xfh.dst, &sav->sah->saidx.dst, sizeof(ihs->xfh.dst));
+ ihs->xfh.spi = sav->spi;
+ ihs->xfh.proto = sav->sah->saidx.proto;
+ ihs->xfh.mode = sav->sah->saidx.mode;
mtx_lock(&ipsec_accel_sav_tmp);
CK_LIST_FOREACH(i, &sav->accel_ifps, sav_link) {
if (i->ifp == ifp) {
@@ -1162,4 +1171,20 @@ ipsec_accel_key_setaccelif_impl(struct secasvar *sav)
return (m);
}
+static bool
+ipsec_accel_fill_xh_impl(if_t ifp, uint32_t drv_spi, struct xform_history *xh)
+{
+ struct ifp_handle_sav *i;
+
+ if (drv_spi < IPSEC_ACCEL_DRV_SPI_MIN ||
+ drv_spi > IPSEC_ACCEL_DRV_SPI_MAX)
+ return (false);
+
+ i = DRVSPI_SA_PCTRIE_LOOKUP(&drv_spi_pctrie, drv_spi);
+ if (i == NULL)
+ return (false);
+ memcpy(xh, &i->xfh, sizeof(*xh));
+ return (true);
+}
+
#endif /* IPSEC_OFFLOAD */
diff --git a/sys/netipsec/ipsec_offload.h b/sys/netipsec/ipsec_offload.h
index 904fe6252396..ae60eaa8ae78 100644
--- a/sys/netipsec/ipsec_offload.h
+++ b/sys/netipsec/ipsec_offload.h
@@ -30,6 +30,7 @@
#include <sys/errno.h>
#include <net/if.h>
#include <net/if_var.h>
+#include <netipsec/xform.h>
struct secpolicy;
struct secasvar;
@@ -42,6 +43,7 @@ struct ipsec_accel_out_tag {
struct ipsec_accel_in_tag {
struct m_tag tag;
+ struct xform_history xh; /* Must be first to mimic IPSEC_IN_DONE */
uint16_t drv_spi;
};
@@ -66,6 +68,8 @@ extern void (*ipsec_accel_drv_sa_lifetime_update_p)(struct secasvar *sav,
if_t ifp, u_int drv_spi, uint64_t octets, uint64_t allocs);
extern int (*ipsec_accel_drv_sa_lifetime_fetch_p)(struct secasvar *sav,
if_t ifp, u_int drv_spi, uint64_t *octets, uint64_t *allocs);
+extern bool (*ipsec_accel_fill_xh_p)(if_t ifp, uint32_t drv_spi,
+ struct xform_history *xh);
#ifdef IPSEC_OFFLOAD
/*
@@ -158,6 +162,16 @@ ipsec_accel_key_setaccelif(struct secasvar *sav)
return (NULL);
}
+static inline bool
+ipsec_accel_fill_xh(if_t ifp, uint32_t drv_spi, struct xform_history *xh)
+{
+ bool (*p)(if_t ifp, uint32_t drv_spi, struct xform_history *xh);
+
+ p = atomic_load_ptr(&ipsec_accel_fill_xh_p);
+ if (p != NULL)
+ return (p(ifp, drv_spi, xh));
+ return (false);
+}
#else
#define ipsec_accel_sa_newkey(a)
@@ -168,6 +182,7 @@ ipsec_accel_key_setaccelif(struct secasvar *sav)
#define ipsec_accel_sync()
#define ipsec_accel_is_accel_sav(a)
#define ipsec_accel_key_setaccelif(a)
+#define ipsec_accel_fill_xh(a, b, c) (false)
#endif
void ipsec_accel_forget_sav_impl(struct secasvar *sav);
@@ -180,6 +195,7 @@ bool ipsec_accel_output(struct ifnet *ifp, struct mbuf *m,
struct inpcb *inp, struct secpolicy *sp, struct secasvar *sav, int af,
int mtu, int *hwassist);
void ipsec_accel_forget_sav(struct secasvar *sav);
+struct xform_history;
#else
#define ipsec_accel_input(a, b, c) (ENXIO)
#define ipsec_accel_output(a, b, c, d, e, f, g, h) ({ \
diff --git a/sys/netipsec/key.c b/sys/netipsec/key.c
index ae67d83c6d13..4ba1b49c24f0 100644
--- a/sys/netipsec/key.c
+++ b/sys/netipsec/key.c
@@ -114,6 +114,8 @@ void (*ipsec_accel_drv_sa_lifetime_update_p)(struct secasvar *sav, if_t ifp,
u_int drv_spi, uint64_t octets, uint64_t allocs);
int (*ipsec_accel_drv_sa_lifetime_fetch_p)(struct secasvar *sav, if_t ifp,
u_int drv_spi, uint64_t *octets, uint64_t *allocs);
+bool (*ipsec_accel_fill_xh_p)(if_t ifp, uint32_t drv_spi,
+ struct xform_history *xh);
#endif
#define FULLMASK 0xff
diff --git a/sys/netlink/netlink_message_parser.h b/sys/netlink/netlink_message_parser.h
index 8492ecb3021b..720317ed74f3 100644
--- a/sys/netlink/netlink_message_parser.h
+++ b/sys/netlink/netlink_message_parser.h
@@ -209,7 +209,8 @@ int nlattr_get_nested(struct nlattr *nla, struct nl_pstate *npt,
int nlattr_get_nested_ptr(struct nlattr *nla, struct nl_pstate *npt,
const void *arg, void *target);
-bool nlmsg_report_err_msg(struct nl_pstate *npt, const char *fmt, ...);
+bool nlmsg_report_err_msg(struct nl_pstate *npt, const char *fmt, ...)
+ __printflike(2, 3);
#define NLMSG_REPORT_ERR_MSG(_npt, _fmt, ...) { \
nlmsg_report_err_msg(_npt, _fmt, ## __VA_ARGS__); \
diff --git a/sys/netpfil/ipfilter/netinet/ip_fil_freebsd.c b/sys/netpfil/ipfilter/netinet/ip_fil_freebsd.c
index 04850549db98..6eb6cf2a7a47 100644
--- a/sys/netpfil/ipfilter/netinet/ip_fil_freebsd.c
+++ b/sys/netpfil/ipfilter/netinet/ip_fil_freebsd.c
@@ -463,13 +463,14 @@ ipf_send_ip(fr_info_t *fin, mb_t *m)
int
ipf_send_icmp_err(int type, fr_info_t *fin, int dst)
{
- int err, hlen, xtra, iclen, ohlen, avail, code;
+ int err, hlen, xtra, iclen, ohlen, avail;
struct in_addr dst4;
struct icmp *icmp;
struct mbuf *m;
i6addr_t dst6;
void *ifp;
#ifdef USE_INET6
+ int code;
ip6_t *ip6;
#endif
ip_t *ip, *ip2;
@@ -477,8 +478,8 @@ ipf_send_icmp_err(int type, fr_info_t *fin, int dst)
if ((type < 0) || (type >= ICMP_MAXTYPE))
return (-1);
- code = fin->fin_icode;
#ifdef USE_INET6
+ code = fin->fin_icode;
/* See NetBSD ip_fil_netbsd.c r1.4: */
if ((code < 0) || (code >= sizeof(icmptoicmp6unreach)/sizeof(int)))
return (-1);
diff --git a/sys/netpfil/pf/if_pflog.c b/sys/netpfil/pf/if_pflog.c
index 0a84f9d680ac..cb96d2fcc44c 100644
--- a/sys/netpfil/pf/if_pflog.c
+++ b/sys/netpfil/pf/if_pflog.c
@@ -284,9 +284,9 @@ pflog_packet(uint8_t action, u_int8_t reason,
* state lock, since this leads to unsafe LOR.
* These conditions are very very rare, however.
*/
- if (trigger->log & PF_LOG_SOCKET_LOOKUP && !pd->lookup.done && lookupsafe)
+ if (trigger->log & PF_LOG_USER && !pd->lookup.done && lookupsafe)
pd->lookup.done = pf_socket_lookup(pd);
- if (pd->lookup.done > 0)
+ if (trigger->log & PF_LOG_USER && pd->lookup.done > 0)
hdr.uid = pd->lookup.uid;
else
hdr.uid = -1;
diff --git a/sys/netpfil/pf/if_pfsync.c b/sys/netpfil/pf/if_pfsync.c
index 2391edaf1a5a..4e03584b8f85 100644
--- a/sys/netpfil/pf/if_pfsync.c
+++ b/sys/netpfil/pf/if_pfsync.c
@@ -532,6 +532,7 @@ pfsync_state_import(union pfsync_state_union *sp, int flags, int msg_version)
struct pf_kpooladdr *rpool_first;
int error;
uint8_t rt = 0;
+ int n = 0;
PF_RULES_RASSERT();
@@ -557,10 +558,12 @@ pfsync_state_import(union pfsync_state_union *sp, int flags, int msg_version)
*/
if (sp->pfs_1301.rule != htonl(-1) && sp->pfs_1301.anchor == htonl(-1) &&
(flags & (PFSYNC_SI_IOCTL | PFSYNC_SI_CKSUM)) && ntohl(sp->pfs_1301.rule) <
- pf_main_ruleset.rules[PF_RULESET_FILTER].active.rcount)
- r = pf_main_ruleset.rules[
- PF_RULESET_FILTER].active.ptr_array[ntohl(sp->pfs_1301.rule)];
- else
+ pf_main_ruleset.rules[PF_RULESET_FILTER].active.rcount) {
+ TAILQ_FOREACH(r, pf_main_ruleset.rules[
+ PF_RULESET_FILTER].active.ptr, entries)
+ if (ntohl(sp->pfs_1301.rule) == n++)
+ break;
+ } else
r = &V_pf_default_rule;
/*
diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c
index d5f01e5c4956..009f7e4d78b1 100644
--- a/sys/netpfil/pf/pf.c
+++ b/sys/netpfil/pf/pf.c
@@ -5901,18 +5901,17 @@ pf_test_rule(struct pf_krule **rm, struct pf_kstate **sm,
M_SETFIB(pd->m, pd->act.rtableid);
if (r->rt) {
- struct pf_ksrc_node *sn = NULL;
- struct pf_srchash *snh = NULL;
/*
* Set act.rt here instead of in pf_rule_to_actions() because
* it is applied only from the last pass rule.
*/
pd->act.rt = r->rt;
- /* Don't use REASON_SET, pf_map_addr increases the reason counters */
- ctx.reason = pf_map_addr_sn(pd->af, r, pd->src, &pd->act.rt_addr,
- &pd->act.rt_kif, NULL, &sn, &snh, &(r->route), PF_SN_ROUTE);
- if (ctx.reason != 0)
+ if ((transerror = pf_map_addr_sn(pd->af, r, pd->src,
+ &pd->act.rt_addr, &pd->act.rt_kif, NULL, &(r->route),
+ PF_SN_ROUTE)) != PFRES_MATCH) {
+ REASON_SET(&ctx.reason, transerror);
goto cleanup;
+ }
}
if (pd->virtual_proto != PF_VPROTO_FRAGMENT &&
@@ -6056,9 +6055,16 @@ pf_create_state(struct pf_krule *r, struct pf_test_ctx *ctx,
/* src node for translation rule */
if (ctx->nr != NULL) {
KASSERT(ctx->nat_pool != NULL, ("%s: nat_pool is NULL", __func__));
+ /*
+ * The NAT addresses are chosen during ruleset parsing.
+ * The new afto code stores post-nat addresses in nsaddr.
+ * The old nat code (also used for new nat-to rules) creates
+ * state keys and stores addresses in them.
+ */
if ((ctx->nat_pool->opts & PF_POOL_STICKYADDR) &&
(sn_reason = pf_insert_src_node(sns, snhs, ctx->nr,
- &ctx->sk->addr[pd->sidx], pd->af, &ctx->nk->addr[1], NULL,
+ ctx->sk ? &(ctx->sk->addr[pd->sidx]) : pd->src, pd->af,
+ ctx->nk ? &(ctx->nk->addr[1]) : &(pd->nsaddr), NULL,
PF_SN_NAT)) != 0 ) {
REASON_SET(&ctx->reason, sn_reason);
goto csfailed;
@@ -6213,7 +6219,7 @@ pf_create_state(struct pf_krule *r, struct pf_test_ctx *ctx,
if (ctx->tag > 0)
s->tag = ctx->tag;
if (pd->proto == IPPROTO_TCP && (tcp_get_flags(th) & (TH_SYN|TH_ACK)) ==
- TH_SYN && r->keep_state == PF_STATE_SYNPROXY) {
+ TH_SYN && r->keep_state == PF_STATE_SYNPROXY && pd->dir == PF_IN) {
pf_set_protostate(s, PF_PEER_SRC, PF_TCPS_PROXY_SRC);
pf_undo_nat(ctx->nr, pd, bip_sum);
s->src.seqhi = arc4random();
@@ -9062,6 +9068,9 @@ pf_route(struct pf_krule *r, struct ifnet *oifp,
goto bad;
}
+ if (r->rt == PF_DUPTO)
+ skip_test = true;
+
if (pd->dir == PF_IN && !skip_test) {
if (pf_test(AF_INET, PF_OUT, PFIL_FWD, ifp, &m0, inp,
&pd->act) != PF_PASS) {
@@ -9364,6 +9373,9 @@ pf_route6(struct pf_krule *r, struct ifnet *oifp,
goto bad;
}
+ if (r->rt == PF_DUPTO)
+ skip_test = true;
+
if (pd->dir == PF_IN && !skip_test) {
if (pf_test(AF_INET6, PF_OUT, PFIL_FWD | PF_PFIL_NOREFRAGMENT,
ifp, &m0, inp, &pd->act) != PF_PASS) {
@@ -10052,6 +10064,8 @@ pf_setup_pdesc(sa_family_t af, int dir, struct pf_pdesc *pd, struct mbuf **m0,
pd->didx = (dir == PF_IN) ? 1 : 0;
pd->af = pd->naf = af;
+ PF_RULES_ASSERT();
+
TAILQ_INIT(&pd->sctp_multihome_jobs);
if (default_actions != NULL)
memcpy(&pd->act, default_actions, sizeof(pd->act));
@@ -10127,6 +10141,12 @@ pf_setup_pdesc(sa_family_t af, int dir, struct pf_pdesc *pd, struct mbuf **m0,
}
h = mtod(pd->m, struct ip6_hdr *);
+ if (pd->m->m_pkthdr.len <
+ sizeof(struct ip6_hdr) + ntohs(h->ip6_plen)) {
+ *action = PF_DROP;
+ REASON_SET(reason, PFRES_SHORT);
+ return (-1);
+ }
if (pf_walk_header6(pd, h, reason) != PF_PASS) {
*action = PF_DROP;
@@ -10465,35 +10485,30 @@ pf_test(sa_family_t af, int dir, int pflags, struct ifnet *ifp, struct mbuf **m0
PF_RULES_RLOCK_TRACKER;
KASSERT(dir == PF_IN || dir == PF_OUT, ("%s: bad direction %d\n", __func__, dir));
M_ASSERTPKTHDR(*m0);
+ NET_EPOCH_ASSERT();
if (!V_pf_status.running)
return (PF_PASS);
- PF_RULES_RLOCK();
-
kif = (struct pfi_kkif *)ifp->if_pf_kif;
if (__predict_false(kif == NULL)) {
DPFPRINTF(PF_DEBUG_URGENT,
("%s: kif == NULL, if_xname %s\n",
__func__, ifp->if_xname));
- PF_RULES_RUNLOCK();
return (PF_DROP);
}
if (kif->pfik_flags & PFI_IFLAG_SKIP) {
- PF_RULES_RUNLOCK();
return (PF_PASS);
}
if ((*m0)->m_flags & M_SKIP_FIREWALL) {
- PF_RULES_RUNLOCK();
return (PF_PASS);
}
if (__predict_false(! M_WRITABLE(*m0))) {
*m0 = m_unshare(*m0, M_NOWAIT);
if (*m0 == NULL) {
- PF_RULES_RUNLOCK();
return (PF_DROP);
}
}
@@ -10506,12 +10521,10 @@ pf_test(sa_family_t af, int dir, int pflags, struct ifnet *ifp, struct mbuf **m0
ifp = ifnet_byindexgen(pd.pf_mtag->if_index,
pd.pf_mtag->if_idxgen);
if (ifp == NULL || ifp->if_flags & IFF_DYING) {
- PF_RULES_RUNLOCK();
m_freem(*m0);
*m0 = NULL;
return (PF_PASS);
}
- PF_RULES_RUNLOCK();
(ifp->if_output)(ifp, *m0, sintosa(&pd.pf_mtag->dst), NULL);
*m0 = NULL;
return (PF_PASS);
@@ -10526,11 +10539,12 @@ pf_test(sa_family_t af, int dir, int pflags, struct ifnet *ifp, struct mbuf **m0
/* But only once. We may see the packet multiple times (e.g.
* PFIL_IN/PFIL_OUT). */
pf_dummynet_flag_remove(pd.m, pd.pf_mtag);
- PF_RULES_RUNLOCK();
return (PF_PASS);
}
+ PF_RULES_RLOCK();
+
if (pf_setup_pdesc(af, dir, &pd, m0, &action, &reason,
kif, default_actions) == -1) {
if (action != PF_PASS)
diff --git a/sys/netpfil/pf/pf.h b/sys/netpfil/pf/pf.h
index 2009d2907985..cfff58064922 100644
--- a/sys/netpfil/pf/pf.h
+++ b/sys/netpfil/pf/pf.h
@@ -140,7 +140,7 @@ enum { PF_ADDR_ADDRMASK, PF_ADDR_NOROUTE, PF_ADDR_DYNIFTL,
#define PF_LOG 0x01
#define PF_LOG_ALL 0x02
-#define PF_LOG_SOCKET_LOOKUP 0x04
+#define PF_LOG_USER 0x04
#define PF_LOG_FORCE 0x08
#define PF_LOG_MATCHES 0x10
@@ -490,6 +490,7 @@ struct pf_osfp_ioctl {
#define PF_ANCHOR_NAME_SIZE 64
#define PF_ANCHOR_MAXPATH (MAXPATHLEN - PF_ANCHOR_NAME_SIZE - 1)
+#define PF_OPTIMIZER_TABLE_PFX "__automatic_"
struct pf_rule {
struct pf_rule_addr src;
diff --git a/sys/netpfil/pf/pf_ioctl.c b/sys/netpfil/pf/pf_ioctl.c
index c96741023db9..3caa0d2e3b11 100644
--- a/sys/netpfil/pf/pf_ioctl.c
+++ b/sys/netpfil/pf/pf_ioctl.c
@@ -1274,7 +1274,9 @@ pf_hash_rule_addr(MD5_CTX *ctx, struct pf_rule_addr *pfr)
PF_MD5_UPD(pfr, addr.iflags);
break;
case PF_ADDR_TABLE:
- PF_MD5_UPD(pfr, addr.v.tblname);
+ if (strncmp(pfr->addr.v.tblname, PF_OPTIMIZER_TABLE_PFX,
+ strlen(PF_OPTIMIZER_TABLE_PFX)))
+ PF_MD5_UPD(pfr, addr.v.tblname);
break;
case PF_ADDR_ADDRMASK:
/* XXX ignore af? */
@@ -1357,7 +1359,7 @@ static int
pf_commit_rules(u_int32_t ticket, int rs_num, char *anchor)
{
struct pf_kruleset *rs;
- struct pf_krule *rule, **old_array, *old_rule;
+ struct pf_krule *rule, *old_rule;
struct pf_krulequeue *old_rules;
struct pf_krule_global *old_tree;
int error;
@@ -1382,13 +1384,10 @@ pf_commit_rules(u_int32_t ticket, int rs_num, char *anchor)
/* Swap rules, keep the old. */
old_rules = rs->rules[rs_num].active.ptr;
old_rcount = rs->rules[rs_num].active.rcount;
- old_array = rs->rules[rs_num].active.ptr_array;
old_tree = rs->rules[rs_num].active.tree;
rs->rules[rs_num].active.ptr =
rs->rules[rs_num].inactive.ptr;
- rs->rules[rs_num].active.ptr_array =
- rs->rules[rs_num].inactive.ptr_array;
rs->rules[rs_num].active.tree =
rs->rules[rs_num].inactive.tree;
rs->rules[rs_num].active.rcount =
@@ -1418,7 +1417,6 @@ pf_commit_rules(u_int32_t ticket, int rs_num, char *anchor)
}
rs->rules[rs_num].inactive.ptr = old_rules;
- rs->rules[rs_num].inactive.ptr_array = old_array;
rs->rules[rs_num].inactive.tree = NULL; /* important for pf_ioctl_addrule */
rs->rules[rs_num].inactive.rcount = old_rcount;
@@ -1431,9 +1429,6 @@ pf_commit_rules(u_int32_t ticket, int rs_num, char *anchor)
while ((rule = TAILQ_FIRST(old_rules)) != NULL)
pf_unlink_rule_locked(old_rules, rule);
PF_UNLNKDRULES_UNLOCK();
- if (rs->rules[rs_num].inactive.ptr_array)
- free(rs->rules[rs_num].inactive.ptr_array, M_TEMP);
- rs->rules[rs_num].inactive.ptr_array = NULL;
rs->rules[rs_num].inactive.rcount = 0;
rs->rules[rs_num].inactive.open = 0;
pf_remove_if_empty_kruleset(rs);
@@ -1456,24 +1451,11 @@ pf_setup_pfsync_matching(struct pf_kruleset *rs)
if (rs_cnt == PF_RULESET_SCRUB)
continue;
- if (rs->rules[rs_cnt].inactive.ptr_array)
- free(rs->rules[rs_cnt].inactive.ptr_array, M_TEMP);
- rs->rules[rs_cnt].inactive.ptr_array = NULL;
-
if (rs->rules[rs_cnt].inactive.rcount) {
- rs->rules[rs_cnt].inactive.ptr_array =
- mallocarray(rs->rules[rs_cnt].inactive.rcount,
- sizeof(struct pf_rule **),
- M_TEMP, M_NOWAIT);
-
- if (!rs->rules[rs_cnt].inactive.ptr_array)
- return (ENOMEM);
- }
-
- TAILQ_FOREACH(rule, rs->rules[rs_cnt].inactive.ptr,
- entries) {
- pf_hash_rule_rolling(&ctx, rule);
- (rs->rules[rs_cnt].inactive.ptr_array)[rule->nr] = rule;
+ TAILQ_FOREACH(rule, rs->rules[rs_cnt].inactive.ptr,
+ entries) {
+ pf_hash_rule_rolling(&ctx, rule);
+ }
}
}
@@ -2059,6 +2041,19 @@ pf_ioctl_getrules(struct pfioc_rule *pr)
return (0);
}
+static int
+pf_validate_range(uint8_t op, uint16_t port[2])
+{
+ uint16_t a = ntohs(port[0]);
+ uint16_t b = ntohs(port[1]);
+
+ if ((op == PF_OP_RRG && a > b) || /* 34:12, i.e. none */
+ (op == PF_OP_IRG && a >= b) || /* 34><12, i.e. none */
+ (op == PF_OP_XRG && a > b)) /* 34<>22, i.e. all */
+ return 1;
+ return 0;
+}
+
int
pf_ioctl_addrule(struct pf_krule *rule, uint32_t ticket,
uint32_t pool_ticket, const char *anchor, const char *anchor_call,
@@ -2078,6 +2073,11 @@ pf_ioctl_addrule(struct pf_krule *rule, uint32_t ticket,
#define ERROUT(x) ERROUT_FUNCTION(errout, x)
+ if (pf_validate_range(rule->src.port_op, rule->src.port))
+ ERROUT(EINVAL);
+ if (pf_validate_range(rule->dst.port_op, rule->dst.port))
+ ERROUT(EINVAL);
+
if (rule->ifname[0])
kif = pf_kkif_create(M_WAITOK);
if (rule->rcv_ifname[0])
diff --git a/sys/netpfil/pf/pf_lb.c b/sys/netpfil/pf/pf_lb.c
index 308d76c46e5b..26f7ab41eef4 100644
--- a/sys/netpfil/pf/pf_lb.c
+++ b/sys/netpfil/pf/pf_lb.c
@@ -80,7 +80,6 @@ static enum pf_test_status pf_step_into_translation_anchor(int, struct pf_test_c
struct pf_krule *);
static int pf_get_sport(struct pf_pdesc *, struct pf_krule *,
struct pf_addr *, uint16_t *, uint16_t, uint16_t,
- struct pf_ksrc_node **, struct pf_srchash **,
struct pf_kpool *, struct pf_udp_mapping **,
pf_sn_types_t);
static bool pf_islinklocal(const sa_family_t, const struct pf_addr *);
@@ -291,10 +290,8 @@ pf_match_translation(int rs_num, struct pf_test_ctx *ctx)
}
static int
-pf_get_sport(struct pf_pdesc *pd, struct pf_krule *r,
- struct pf_addr *naddr, uint16_t *nport, uint16_t low,
- uint16_t high, struct pf_ksrc_node **sn,
- struct pf_srchash **sh, struct pf_kpool *rpool,
+pf_get_sport(struct pf_pdesc *pd, struct pf_krule *r, struct pf_addr *naddr,
+ uint16_t *nport, uint16_t low, uint16_t high, struct pf_kpool *rpool,
struct pf_udp_mapping **udp_mapping, pf_sn_types_t sn_type)
{
struct pf_state_key_cmp key;
@@ -322,19 +319,24 @@ pf_get_sport(struct pf_pdesc *pd, struct pf_krule *r,
pf_addrcpy(&udp_source.addr, &pd->nsaddr, pd->af);
udp_source.port = pd->nsport;
if (udp_mapping) {
+ struct pf_ksrc_node *sn = NULL;
+ struct pf_srchash *sh = NULL;
*udp_mapping = pf_udp_mapping_find(&udp_source);
if (*udp_mapping) {
pf_addrcpy(naddr,
&(*udp_mapping)->endpoints[1].addr,
pd->af);
*nport = (*udp_mapping)->endpoints[1].port;
- /* Try to find a src_node as per pf_map_addr(). */
- if (*sn == NULL && rpool->opts & PF_POOL_STICKYADDR &&
+ /*
+ * Try to find a src_node as per pf_map_addr().
+ * XXX: Why? This code seems to do nothing.
+ */
+ if (rpool->opts & PF_POOL_STICKYADDR &&
(rpool->opts & PF_POOL_TYPEMASK) != PF_POOL_NONE)
- *sn = pf_find_src_node(&pd->nsaddr, r,
- pd->af, sh, sn_type, false);
- if (*sn != NULL)
- PF_SRC_NODE_UNLOCK(*sn);
+ sn = pf_find_src_node(&pd->nsaddr, r,
+ pd->af, &sh, sn_type, false);
+ if (sn != NULL)
+ PF_SRC_NODE_UNLOCK(sn);
return (0);
} else {
*udp_mapping = pf_udp_mapping_create(pd->af, &pd->nsaddr,
@@ -346,7 +348,7 @@ pf_get_sport(struct pf_pdesc *pd, struct pf_krule *r,
}
if (pf_map_addr_sn(pd->naf, r, &pd->nsaddr, naddr, NULL, &init_addr,
- sn, sh, rpool, sn_type))
+ rpool, sn_type))
goto failed;
if (pd->proto == IPPROTO_ICMP) {
@@ -470,9 +472,8 @@ pf_get_sport(struct pf_pdesc *pd, struct pf_krule *r,
* pick a different source address since we're out
* of free port choices for the current one.
*/
- (*sn) = NULL;
if (pf_map_addr_sn(pd->naf, r, &pd->nsaddr, naddr, NULL,
- &init_addr, sn, sh, rpool, sn_type))
+ &init_addr, rpool, sn_type))
return (1);
break;
case PF_POOL_NONE:
@@ -503,7 +504,6 @@ pf_islinklocal(const sa_family_t af, const struct pf_addr *addr)
static int
pf_get_mape_sport(struct pf_pdesc *pd, struct pf_krule *r,
struct pf_addr *naddr, uint16_t *nport,
- struct pf_ksrc_node **sn, struct pf_srchash **sh,
struct pf_udp_mapping **udp_mapping, struct pf_kpool *rpool)
{
uint16_t psmask, low, highmask;
@@ -523,16 +523,14 @@ pf_get_mape_sport(struct pf_pdesc *pd, struct pf_krule *r,
for (i = cut; i <= ahigh; i++) {
low = (i << ashift) | psmask;
- if (!pf_get_sport(pd, r,
- naddr, nport, low, low | highmask, sn, sh, rpool,
- udp_mapping, PF_SN_NAT))
+ if (!pf_get_sport(pd, r, naddr, nport, low, low | highmask,
+ rpool, udp_mapping, PF_SN_NAT))
return (0);
}
for (i = cut - 1; i > 0; i--) {
low = (i << ashift) | psmask;
- if (!pf_get_sport(pd, r,
- naddr, nport, low, low | highmask, sn, sh, rpool,
- udp_mapping, PF_SN_NAT))
+ if (!pf_get_sport(pd, r, naddr, nport, low, low | highmask,
+ rpool, udp_mapping, PF_SN_NAT))
return (0);
}
return (1);
@@ -545,6 +543,7 @@ pf_map_addr(sa_family_t af, struct pf_krule *r, struct pf_addr *saddr,
{
u_short reason = PFRES_MATCH;
struct pf_addr *raddr = NULL, *rmask = NULL;
+ struct pfr_ktable *kt;
uint64_t hashidx;
int cnt;
@@ -600,29 +599,25 @@ pf_map_addr(sa_family_t af, struct pf_krule *r, struct pf_addr *saddr,
pf_poolmask(naddr, raddr, rmask, saddr, af);
break;
case PF_POOL_RANDOM:
- if (rpool->cur->addr.type == PF_ADDR_TABLE) {
- cnt = rpool->cur->addr.p.tbl->pfrkt_cnt;
- if (cnt == 0)
- rpool->tblidx = 0;
+ if (rpool->cur->addr.type == PF_ADDR_TABLE ||
+ rpool->cur->addr.type == PF_ADDR_DYNIFTL) {
+ if (rpool->cur->addr.type == PF_ADDR_TABLE)
+ kt = rpool->cur->addr.p.tbl;
else
- rpool->tblidx = (int)arc4random_uniform(cnt);
- memset(&rpool->counter, 0, sizeof(rpool->counter));
- if (pfr_pool_get(rpool->cur->addr.p.tbl,
- &rpool->tblidx, &rpool->counter, af, NULL)) {
+ kt = rpool->cur->addr.p.dyn->pfid_kt;
+ kt = pfr_ktable_select_active(kt);
+ if (kt == NULL) {
reason = PFRES_MAPFAILED;
goto done_pool_mtx; /* unsupported */
}
- pf_addrcpy(naddr, &rpool->counter, af);
- } else if (rpool->cur->addr.type == PF_ADDR_DYNIFTL) {
- cnt = rpool->cur->addr.p.dyn->pfid_kt->pfrkt_cnt;
+ cnt = kt->pfrkt_cnt;
if (cnt == 0)
rpool->tblidx = 0;
else
rpool->tblidx = (int)arc4random_uniform(cnt);
memset(&rpool->counter, 0, sizeof(rpool->counter));
- if (pfr_pool_get(rpool->cur->addr.p.dyn->pfid_kt,
- &rpool->tblidx, &rpool->counter, af,
- pf_islinklocal)) {
+ if (pfr_pool_get(kt, &rpool->tblidx, &rpool->counter,
+ af, pf_islinklocal, false)) {
reason = PFRES_MAPFAILED;
goto done_pool_mtx; /* unsupported */
}
@@ -671,29 +666,25 @@ pf_map_addr(sa_family_t af, struct pf_krule *r, struct pf_addr *saddr,
hashidx =
pf_hash(saddr, (struct pf_addr *)&hash, &rpool->key, af);
- if (rpool->cur->addr.type == PF_ADDR_TABLE) {
- cnt = rpool->cur->addr.p.tbl->pfrkt_cnt;
- if (cnt == 0)
- rpool->tblidx = 0;
+ if (rpool->cur->addr.type == PF_ADDR_TABLE ||
+ rpool->cur->addr.type == PF_ADDR_DYNIFTL) {
+ if (rpool->cur->addr.type == PF_ADDR_TABLE)
+ kt = rpool->cur->addr.p.tbl;
else
- rpool->tblidx = (int)(hashidx % cnt);
- memset(&rpool->counter, 0, sizeof(rpool->counter));
- if (pfr_pool_get(rpool->cur->addr.p.tbl,
- &rpool->tblidx, &rpool->counter, af, NULL)) {
+ kt = rpool->cur->addr.p.dyn->pfid_kt;
+ kt = pfr_ktable_select_active(kt);
+ if (kt == NULL) {
reason = PFRES_MAPFAILED;
goto done_pool_mtx; /* unsupported */
}
- pf_addrcpy(naddr, &rpool->counter, af);
- } else if (rpool->cur->addr.type == PF_ADDR_DYNIFTL) {
- cnt = rpool->cur->addr.p.dyn->pfid_kt->pfrkt_cnt;
+ cnt = kt->pfrkt_cnt;
if (cnt == 0)
rpool->tblidx = 0;
else
rpool->tblidx = (int)(hashidx % cnt);
memset(&rpool->counter, 0, sizeof(rpool->counter));
- if (pfr_pool_get(rpool->cur->addr.p.dyn->pfid_kt,
- &rpool->tblidx, &rpool->counter, af,
- pf_islinklocal)) {
+ if (pfr_pool_get(kt, &rpool->tblidx, &rpool->counter,
+ af, pf_islinklocal, false)) {
reason = PFRES_MAPFAILED;
goto done_pool_mtx; /* unsupported */
}
@@ -710,11 +701,12 @@ pf_map_addr(sa_family_t af, struct pf_krule *r, struct pf_addr *saddr,
if (rpool->cur->addr.type == PF_ADDR_TABLE) {
if (!pfr_pool_get(rpool->cur->addr.p.tbl,
- &rpool->tblidx, &rpool->counter, af, NULL))
+ &rpool->tblidx, &rpool->counter, af, NULL, true))
goto get_addr;
} else if (rpool->cur->addr.type == PF_ADDR_DYNIFTL) {
if (!pfr_pool_get(rpool->cur->addr.p.dyn->pfid_kt,
- &rpool->tblidx, &rpool->counter, af, pf_islinklocal))
+ &rpool->tblidx, &rpool->counter, af, pf_islinklocal,
+ true))
goto get_addr;
} else if (pf_match_addr(0, raddr, rmask, &rpool->counter, af))
goto get_addr;
@@ -724,9 +716,10 @@ pf_map_addr(sa_family_t af, struct pf_krule *r, struct pf_addr *saddr,
rpool->cur = TAILQ_FIRST(&rpool->list);
else
rpool->cur = TAILQ_NEXT(rpool->cur, entries);
+ rpool->tblidx = -1;
if (rpool->cur->addr.type == PF_ADDR_TABLE) {
if (pfr_pool_get(rpool->cur->addr.p.tbl,
- &rpool->tblidx, &rpool->counter, af, NULL)) {
+ &rpool->tblidx, &rpool->counter, af, NULL, true)) {
/* table contains no address of type 'af' */
if (rpool->cur != acur)
goto try_next;
@@ -734,9 +727,9 @@ pf_map_addr(sa_family_t af, struct pf_krule *r, struct pf_addr *saddr,
goto done_pool_mtx;
}
} else if (rpool->cur->addr.type == PF_ADDR_DYNIFTL) {
- rpool->tblidx = -1;
if (pfr_pool_get(rpool->cur->addr.p.dyn->pfid_kt,
- &rpool->tblidx, &rpool->counter, af, pf_islinklocal)) {
+ &rpool->tblidx, &rpool->counter, af, pf_islinklocal,
+ true)) {
/* table contains no address of type 'af' */
if (rpool->cur != acur)
goto try_next;
@@ -764,48 +757,41 @@ pf_map_addr(sa_family_t af, struct pf_krule *r, struct pf_addr *saddr,
done_pool_mtx:
mtx_unlock(&rpool->mtx);
- if (reason) {
- counter_u64_add(V_pf_status.counters[reason], 1);
- }
-
return (reason);
}
u_short
pf_map_addr_sn(sa_family_t af, struct pf_krule *r, struct pf_addr *saddr,
struct pf_addr *naddr, struct pfi_kkif **nkif, struct pf_addr *init_addr,
- struct pf_ksrc_node **sn, struct pf_srchash **sh, struct pf_kpool *rpool,
- pf_sn_types_t sn_type)
+ struct pf_kpool *rpool, pf_sn_types_t sn_type)
{
+ struct pf_ksrc_node *sn = NULL;
+ struct pf_srchash *sh = NULL;
u_short reason = 0;
- KASSERT(*sn == NULL, ("*sn not NULL"));
-
/*
* If this is a sticky-address rule, try to find an existing src_node.
- * Request the sh to be unlocked if sn was not found, as we never
- * insert a new sn when parsing the ruleset.
*/
if (rpool->opts & PF_POOL_STICKYADDR &&
(rpool->opts & PF_POOL_TYPEMASK) != PF_POOL_NONE)
- *sn = pf_find_src_node(saddr, r, af, sh, sn_type, false);
+ sn = pf_find_src_node(saddr, r, af, &sh, sn_type, false);
- if (*sn != NULL) {
- PF_SRC_NODE_LOCK_ASSERT(*sn);
+ if (sn != NULL) {
+ PF_SRC_NODE_LOCK_ASSERT(sn);
/* If the supplied address is the same as the current one we've
* been asked before, so tell the caller that there's no other
* address to be had. */
- if (PF_AEQ(naddr, &(*sn)->raddr, af)) {
+ if (PF_AEQ(naddr, &(sn->raddr), af)) {
reason = PFRES_MAPFAILED;
goto done;
}
- pf_addrcpy(naddr, &(*sn)->raddr, af);
+ pf_addrcpy(naddr, &(sn->raddr), af);
if (nkif)
- *nkif = (*sn)->rkif;
+ *nkif = sn->rkif;
if (V_pf_status.debug >= PF_DEBUG_NOISY) {
- printf("pf_map_addr: src tracking maps ");
+ printf("%s: src tracking maps ", __func__);
pf_print_host(saddr, 0, af);
printf(" to ");
pf_print_host(naddr, 0, af);
@@ -820,14 +806,16 @@ pf_map_addr_sn(sa_family_t af, struct pf_krule *r, struct pf_addr *saddr,
* Source node has not been found. Find a new address and store it
* in variables given by the caller.
*/
- if (pf_map_addr(af, r, saddr, naddr, nkif, init_addr, rpool) != 0) {
- /* pf_map_addr() sets reason counters on its own */
+ if ((reason = pf_map_addr(af, r, saddr, naddr, nkif, init_addr,
+ rpool)) != 0) {
+ if (V_pf_status.debug >= PF_DEBUG_MISC)
+ printf("%s: pf_map_addr has failed\n", __func__);
goto done;
}
if (V_pf_status.debug >= PF_DEBUG_NOISY &&
(rpool->opts & PF_POOL_TYPEMASK) != PF_POOL_NONE) {
- printf("pf_map_addr: selected address ");
+ printf("%s: selected address ", __func__);
pf_print_host(naddr, 0, af);
if (nkif)
printf("@%s", (*nkif)->pfik_name);
@@ -835,12 +823,8 @@ pf_map_addr_sn(sa_family_t af, struct pf_krule *r, struct pf_addr *saddr,
}
done:
- if ((*sn) != NULL)
- PF_SRC_NODE_UNLOCK(*sn);
-
- if (reason) {
- counter_u64_add(V_pf_status.counters[reason], 1);
- }
+ if (sn != NULL)
+ PF_SRC_NODE_UNLOCK(sn);
return (reason);
}
@@ -890,8 +874,6 @@ pf_get_transaddr(struct pf_test_ctx *ctx, struct pf_krule *r,
{
struct pf_pdesc *pd = ctx->pd;
struct pf_addr *naddr;
- struct pf_ksrc_node *sn = NULL;
- struct pf_srchash *sh = NULL;
uint16_t *nportp;
uint16_t low, high;
u_short reason;
@@ -919,8 +901,8 @@ pf_get_transaddr(struct pf_test_ctx *ctx, struct pf_krule *r,
high = rpool->proxy_port[1];
}
if (rpool->mape.offset > 0) {
- if (pf_get_mape_sport(pd, r, naddr, nportp, &sn,
- &sh, &ctx->udp_mapping, rpool)) {
+ if (pf_get_mape_sport(pd, r, naddr, nportp,
+ &ctx->udp_mapping, rpool)) {
DPFPRINTF(PF_DEBUG_MISC,
("pf: MAP-E port allocation (%u/%u/%u)"
" failed\n",
@@ -930,8 +912,8 @@ pf_get_transaddr(struct pf_test_ctx *ctx, struct pf_krule *r,
reason = PFRES_MAPFAILED;
goto notrans;
}
- } else if (pf_get_sport(pd, r, naddr, nportp, low, high, &sn,
- &sh, rpool, &ctx->udp_mapping, PF_SN_NAT)) {
+ } else if (pf_get_sport(pd, r, naddr, nportp, low, high,
+ rpool, &ctx->udp_mapping, PF_SN_NAT)) {
DPFPRINTF(PF_DEBUG_MISC,
("pf: NAT proxy port allocation (%u-%u) failed\n",
rpool->proxy_port[0], rpool->proxy_port[1]));
@@ -1017,7 +999,7 @@ pf_get_transaddr(struct pf_test_ctx *ctx, struct pf_krule *r,
uint16_t cut, low, high, nport;
reason = pf_map_addr_sn(pd->af, r, &pd->nsaddr, naddr, NULL,
- NULL, &sn, &sh, rpool, PF_SN_NAT);
+ NULL, rpool, PF_SN_NAT);
if (reason != 0)
goto notrans;
if ((rpool->opts & PF_POOL_TYPEMASK) == PF_POOL_BITMASK)
@@ -1134,8 +1116,6 @@ pf_get_transaddr_af(struct pf_krule *r, struct pf_pdesc *pd)
struct pf_addr ndaddr, nsaddr, naddr;
u_int16_t nport = 0;
int prefixlen = 96;
- struct pf_srchash *sh = NULL;
- struct pf_ksrc_node *sns = NULL;
bzero(&nsaddr, sizeof(nsaddr));
bzero(&ndaddr, sizeof(ndaddr));
@@ -1154,9 +1134,8 @@ pf_get_transaddr_af(struct pf_krule *r, struct pf_pdesc *pd)
panic("pf_get_transaddr_af: no nat pool for source address");
/* get source address and port */
- if (pf_get_sport(pd, r, &nsaddr, &nport,
- r->nat.proxy_port[0], r->nat.proxy_port[1], &sns, &sh, &r->nat,
- NULL, PF_SN_NAT)) {
+ if (pf_get_sport(pd, r, &nsaddr, &nport, r->nat.proxy_port[0],
+ r->nat.proxy_port[1], &r->nat, NULL, PF_SN_NAT)) {
DPFPRINTF(PF_DEBUG_MISC,
("pf: af-to NAT proxy port allocation (%u-%u) failed",
r->nat.proxy_port[0], r->nat.proxy_port[1]));
@@ -1182,7 +1161,7 @@ pf_get_transaddr_af(struct pf_krule *r, struct pf_pdesc *pd)
/* get the destination address and port */
if (! TAILQ_EMPTY(&r->rdr.list)) {
if (pf_map_addr_sn(pd->naf, r, &nsaddr, &naddr, NULL, NULL,
- &sns, NULL, &r->rdr, PF_SN_NAT))
+ &r->rdr, PF_SN_NAT))
return (-1);
if (r->rdr.proxy_port[0])
pd->ndport = htons(r->rdr.proxy_port[0]);
diff --git a/sys/netpfil/pf/pf_table.c b/sys/netpfil/pf/pf_table.c
index 43e4366845a2..9c0151b7da2b 100644
--- a/sys/netpfil/pf/pf_table.c
+++ b/sys/netpfil/pf/pf_table.c
@@ -819,10 +819,10 @@ pfr_create_kentry(struct pfr_addr *ad, bool counters)
static void
pfr_destroy_kentries(struct pfr_kentryworkq *workq)
{
- struct pfr_kentry *p, *q;
+ struct pfr_kentry *p;
- for (p = SLIST_FIRST(workq); p != NULL; p = q) {
- q = SLIST_NEXT(p, pfrke_workq);
+ while ((p = SLIST_FIRST(workq)) != NULL) {
+ SLIST_REMOVE_HEAD(workq, pfrke_workq);
pfr_destroy_kentry(p);
}
}
@@ -1680,8 +1680,7 @@ pfr_ina_commit(struct pfr_table *trs, u_int32_t ticket, int *nadd,
}
if (!(flags & PFR_FLAG_DUMMY)) {
- for (p = SLIST_FIRST(&workq); p != NULL; p = q) {
- q = SLIST_NEXT(p, pfrkt_workq);
+ SLIST_FOREACH_SAFE(p, &workq, pfrkt_workq, q) {
pfr_commit_ktable(p, tzero);
}
rs->topen = 0;
@@ -1710,7 +1709,7 @@ pfr_commit_ktable(struct pfr_ktable *kt, time_t tzero)
} else if (kt->pfrkt_flags & PFR_TFLAG_ACTIVE) {
/* kt might contain addresses */
struct pfr_kentryworkq addrq, addq, changeq, delq, garbageq;
- struct pfr_kentry *p, *q, *next;
+ struct pfr_kentry *p, *q;
struct pfr_addr ad;
pfr_enqueue_addrs(shadow, &addrq, NULL, 0);
@@ -1720,7 +1719,8 @@ pfr_commit_ktable(struct pfr_ktable *kt, time_t tzero)
SLIST_INIT(&delq);
SLIST_INIT(&garbageq);
pfr_clean_node_mask(shadow, &addrq);
- SLIST_FOREACH_SAFE(p, &addrq, pfrke_workq, next) {
+ while ((p = SLIST_FIRST(&addrq)) != NULL) {
+ SLIST_REMOVE_HEAD(&addrq, pfrke_workq);
pfr_copyout_addr(&ad, p);
q = pfr_lookup_addr(kt, &ad, 1);
if (q != NULL) {
@@ -1864,8 +1864,7 @@ pfr_setflags_ktables(struct pfr_ktableworkq *workq)
{
struct pfr_ktable *p, *q;
- for (p = SLIST_FIRST(workq); p; p = q) {
- q = SLIST_NEXT(p, pfrkt_workq);
+ SLIST_FOREACH_SAFE(p, workq, pfrkt_workq, q) {
pfr_setflags_ktable(p, p->pfrkt_nflags);
}
}
@@ -2015,10 +2014,10 @@ pfr_create_ktable(struct pfr_table *tbl, time_t tzero, int attachruleset)
static void
pfr_destroy_ktables(struct pfr_ktableworkq *workq, int flushaddr)
{
- struct pfr_ktable *p, *q;
+ struct pfr_ktable *p;
- for (p = SLIST_FIRST(workq); p; p = q) {
- q = SLIST_NEXT(p, pfrkt_workq);
+ while ((p = SLIST_FIRST(workq)) != NULL) {
+ SLIST_REMOVE_HEAD(workq, pfrkt_workq);
pfr_destroy_ktable(p, flushaddr);
}
}
@@ -2074,17 +2073,16 @@ pfr_lookup_table(struct pfr_table *tbl)
(struct pfr_ktable *)tbl));
}
-int
-pfr_match_addr(struct pfr_ktable *kt, struct pf_addr *a, sa_family_t af)
+static struct pfr_kentry *
+pfr_kentry_byaddr(struct pfr_ktable *kt, struct pf_addr *a, sa_family_t af,
+ int exact)
{
struct pfr_kentry *ke = NULL;
- int match;
PF_RULES_RASSERT();
- if (!(kt->pfrkt_flags & PFR_TFLAG_ACTIVE) && kt->pfrkt_root != NULL)
- kt = kt->pfrkt_root;
- if (!(kt->pfrkt_flags & PFR_TFLAG_ACTIVE))
+ kt = pfr_ktable_select_active(kt);
+ if (kt == NULL)
return (0);
switch (af) {
@@ -2121,11 +2119,26 @@ pfr_match_addr(struct pfr_ktable *kt, struct pf_addr *a, sa_family_t af)
default:
unhandled_af(af);
}
+ if (exact && ke && KENTRY_NETWORK(ke))
+ ke = NULL;
+
+ return (ke);
+}
+
+int
+pfr_match_addr(struct pfr_ktable *kt, struct pf_addr *a, sa_family_t af)
+{
+ struct pfr_kentry *ke = NULL;
+ int match;
+
+ ke = pfr_kentry_byaddr(kt, a, af, 0);
+
match = (ke && !ke->pfrke_not);
if (match)
pfr_kstate_counter_add(&kt->pfrkt_match, 1);
else
pfr_kstate_counter_add(&kt->pfrkt_nomatch, 1);
+
return (match);
}
@@ -2135,9 +2148,8 @@ pfr_update_stats(struct pfr_ktable *kt, struct pf_addr *a, sa_family_t af,
{
struct pfr_kentry *ke = NULL;
- if (!(kt->pfrkt_flags & PFR_TFLAG_ACTIVE) && kt->pfrkt_root != NULL)
- kt = kt->pfrkt_root;
- if (!(kt->pfrkt_flags & PFR_TFLAG_ACTIVE))
+ kt = pfr_ktable_select_active(kt);
+ if (kt == NULL)
return;
switch (af) {
@@ -2281,7 +2293,7 @@ pfr_detach_table(struct pfr_ktable *kt)
int
pfr_pool_get(struct pfr_ktable *kt, int *pidx, struct pf_addr *counter,
- sa_family_t af, pf_addr_filter_func_t filter)
+ sa_family_t af, pf_addr_filter_func_t filter, bool loop_once)
{
struct pf_addr *addr, cur, mask, umask_addr;
union sockaddr_union uaddr, umask;
@@ -2306,9 +2318,8 @@ pfr_pool_get(struct pfr_ktable *kt, int *pidx, struct pf_addr *counter,
unhandled_af(af);
}
- if (!(kt->pfrkt_flags & PFR_TFLAG_ACTIVE) && kt->pfrkt_root != NULL)
- kt = kt->pfrkt_root;
- if (!(kt->pfrkt_flags & PFR_TFLAG_ACTIVE))
+ kt = pfr_ktable_select_active(kt);
+ if (kt == NULL)
return (-1);
idx = *pidx;
@@ -2327,7 +2338,7 @@ _next_block:
ke = pfr_kentry_byidx(kt, idx, af);
if (ke == NULL) {
/* we don't have this idx, try looping */
- if (loop || (ke = pfr_kentry_byidx(kt, 0, af)) == NULL) {
+ if ((loop || loop_once) || (ke = pfr_kentry_byidx(kt, 0, af)) == NULL) {
pfr_kstate_counter_add(&kt->pfrkt_nomatch, 1);
return (1);
}
@@ -2455,3 +2466,14 @@ pfr_dynaddr_update(struct pfr_ktable *kt, struct pfi_dynaddr *dyn)
unhandled_af(dyn->pfid_af);
}
}
+
+struct pfr_ktable *
+pfr_ktable_select_active(struct pfr_ktable *kt)
+{
+ if (!(kt->pfrkt_flags & PFR_TFLAG_ACTIVE) && kt->pfrkt_root != NULL)
+ kt = kt->pfrkt_root;
+ if (!(kt->pfrkt_flags & PFR_TFLAG_ACTIVE))
+ return (NULL);
+
+ return (kt);
+}
diff --git a/sys/powerpc/aim/mmu_oea.c b/sys/powerpc/aim/mmu_oea.c
index 7746b668265d..ae17b3289593 100644
--- a/sys/powerpc/aim/mmu_oea.c
+++ b/sys/powerpc/aim/mmu_oea.c
@@ -1469,6 +1469,9 @@ moea_page_set_memattr(vm_page_t m, vm_memattr_t ma)
pmap_t pmap;
u_int lo;
+ if (m->md.mdpg_cache_attrs == ma)
+ return;
+
if ((m->oflags & VPO_UNMANAGED) != 0) {
m->md.mdpg_cache_attrs = ma;
return;
diff --git a/sys/powerpc/aim/mmu_oea64.c b/sys/powerpc/aim/mmu_oea64.c
index 79cea408bb5f..796b1719b8ba 100644
--- a/sys/powerpc/aim/mmu_oea64.c
+++ b/sys/powerpc/aim/mmu_oea64.c
@@ -2134,6 +2134,9 @@ moea64_page_set_memattr(vm_page_t m, vm_memattr_t ma)
CTR3(KTR_PMAP, "%s: pa=%#jx, ma=%#x",
__func__, (uintmax_t)VM_PAGE_TO_PHYS(m), ma);
+ if (m->md.mdpg_cache_attrs == ma)
+ return;
+
if ((m->oflags & VPO_UNMANAGED) != 0) {
m->md.mdpg_cache_attrs = ma;
return;
diff --git a/sys/powerpc/aim/mmu_radix.c b/sys/powerpc/aim/mmu_radix.c
index 45f7bef8bcc9..a12142fc2d7b 100644
--- a/sys/powerpc/aim/mmu_radix.c
+++ b/sys/powerpc/aim/mmu_radix.c
@@ -5937,6 +5937,10 @@ mmu_radix_page_set_memattr(vm_page_t m, vm_memattr_t ma)
{
CTR3(KTR_PMAP, "%s(%p, %#x)", __func__, m, ma);
+
+ if (m->md.mdpg_cache_attrs == ma)
+ return;
+
m->md.mdpg_cache_attrs = ma;
/*
diff --git a/sys/powerpc/include/pcb.h b/sys/powerpc/include/pcb.h
index 050ada6b0f64..0230cf78aba7 100644
--- a/sys/powerpc/include/pcb.h
+++ b/sys/powerpc/include/pcb.h
@@ -66,16 +66,8 @@ struct pcb {
#define PCB_VECREGS 0x200 /* Process had Altivec registers initialized */
struct fpu {
union {
-#if _BYTE_ORDER == _BIG_ENDIAN
- double fpr;
- uint32_t vsr[4];
-#else
uint32_t vsr[4];
- struct {
- double padding;
- double fpr;
- };
-#endif
+ double fpr;
} fpr[32];
double fpscr; /* FPSCR stored as double for easier access */
} pcb_fpu; /* Floating point processor */
diff --git a/sys/powerpc/include/ucontext.h b/sys/powerpc/include/ucontext.h
index d35c6c773fe0..dc87edd578bc 100644
--- a/sys/powerpc/include/ucontext.h
+++ b/sys/powerpc/include/ucontext.h
@@ -41,6 +41,7 @@ typedef struct __mcontext {
int mc_flags;
#define _MC_FP_VALID 0x01
#define _MC_AV_VALID 0x02
+#define _MC_VS_VALID 0x04
int mc_onstack; /* saved onstack flag */
int mc_len; /* sizeof(__mcontext) */
__uint64_t mc_avec[32*2]; /* vector register file */
@@ -56,6 +57,7 @@ typedef struct __mcontext32 {
int mc_flags;
#define _MC_FP_VALID 0x01
#define _MC_AV_VALID 0x02
+#define _MC_VS_VALID 0x04
int mc_onstack; /* saved onstack flag */
int mc_len; /* sizeof(__mcontext) */
uint64_t mc_avec[32*2]; /* vector register file */
diff --git a/sys/powerpc/powerpc/exec_machdep.c b/sys/powerpc/powerpc/exec_machdep.c
index 1893d79f29a8..8a33d0f589a7 100644
--- a/sys/powerpc/powerpc/exec_machdep.c
+++ b/sys/powerpc/powerpc/exec_machdep.c
@@ -214,10 +214,10 @@ sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
sfpsize = sizeof(sf);
#ifdef __powerpc64__
/*
- * 64-bit PPC defines a 288 byte scratch region
- * below the stack.
+ * 64-bit PPC defines a 512 byte red zone below
+ * the existing stack (ELF ABI v2 §2.2.2.4)
*/
- rndfsize = 288 + roundup(sizeof(sf), 48);
+ rndfsize = 512 + roundup(sizeof(sf), 48);
#else
rndfsize = roundup(sizeof(sf), 16);
#endif
@@ -349,13 +349,6 @@ sys_sigreturn(struct thread *td, struct sigreturn_args *uap)
if (error != 0)
return (error);
- /*
- * Save FPU state if needed. User may have changed it on
- * signal handler
- */
- if (uc.uc_mcontext.mc_srr1 & PSL_FP)
- save_fpu(td);
-
kern_sigprocmask(td, SIG_SETMASK, &uc.uc_sigmask, NULL, 0);
CTR3(KTR_SIG, "sigreturn: return td=%p pc=%#x sp=%#x",
@@ -432,6 +425,7 @@ grab_mcontext(struct thread *td, mcontext_t *mcp, int flags)
}
if (pcb->pcb_flags & PCB_VSX) {
+ mcp->mc_flags |= _MC_VS_VALID;
for (i = 0; i < 32; i++)
memcpy(&mcp->mc_vsxfpreg[i],
&pcb->pcb_fpu.fpr[i].vsr[2], sizeof(double));
@@ -481,6 +475,7 @@ set_mcontext(struct thread *td, mcontext_t *mcp)
struct pcb *pcb;
struct trapframe *tf;
register_t tls;
+ register_t msr;
int i;
pcb = td->td_pcb;
@@ -531,6 +526,22 @@ set_mcontext(struct thread *td, mcontext_t *mcp)
tf->srr1 &= ~(PSL_FP | PSL_VSX | PSL_VEC);
pcb->pcb_flags &= ~(PCB_FPU | PCB_VSX | PCB_VEC);
+ /*
+ * Ensure the FPU is also disabled in hardware.
+ *
+ * Without this, it's possible for the register reload to fail if we
+ * don't switch to a FPU disabled context before resuming the original
+ * thread. Specifically, if the FPU/VSX unavailable exception is never
+ * hit, then whatever data is still in the FP/VSX registers when
+ * sigresume is callled will used by the resumed thread, instead of the
+ * previously saved data from the mcontext.
+ */
+ critical_enter();
+ msr = mfmsr() & ~(PSL_FP | PSL_VSX | PSL_VEC);
+ isync();
+ mtmsr(msr);
+ critical_exit();
+
if (mcp->mc_flags & _MC_FP_VALID) {
/* enable_fpu() will happen lazily on a fault */
pcb->pcb_flags |= PCB_FPREGS;
@@ -539,8 +550,12 @@ set_mcontext(struct thread *td, mcontext_t *mcp)
for (i = 0; i < 32; i++) {
memcpy(&pcb->pcb_fpu.fpr[i].fpr, &mcp->mc_fpreg[i],
sizeof(double));
- memcpy(&pcb->pcb_fpu.fpr[i].vsr[2],
- &mcp->mc_vsxfpreg[i], sizeof(double));
+ }
+ if (mcp->mc_flags & _MC_VS_VALID) {
+ for (i = 0; i < 32; i++) {
+ memcpy(&pcb->pcb_fpu.fpr[i].vsr[2],
+ &mcp->mc_vsxfpreg[i], sizeof(double));
+ }
}
}
diff --git a/sys/powerpc/powerpc/fpu.c b/sys/powerpc/powerpc/fpu.c
index 0eaff2ea4932..cc8f22f7dda3 100644
--- a/sys/powerpc/powerpc/fpu.c
+++ b/sys/powerpc/powerpc/fpu.c
@@ -64,8 +64,19 @@ save_fpu_int(struct thread *td)
* Save the floating-point registers and FPSCR to the PCB
*/
if (pcb->pcb_flags & PCB_VSX) {
- #define SFP(n) __asm ("stxvw4x " #n ", 0,%0" \
+#if _BYTE_ORDER == _BIG_ENDIAN
+ #define SFP(n) __asm("stxvw4x " #n ", 0,%0" \
:: "b"(&pcb->pcb_fpu.fpr[n]));
+#else
+ /*
+ * stxvw2x will swap words within the FP double word on LE systems,
+ * leading to corruption if VSX is used to store state and FP is
+ * subsequently used to restore state.
+ * Use stxvd2x instead.
+ */
+ #define SFP(n) __asm("stxvd2x " #n ", 0,%0" \
+ :: "b"(&pcb->pcb_fpu.fpr[n]));
+#endif
SFP(0); SFP(1); SFP(2); SFP(3);
SFP(4); SFP(5); SFP(6); SFP(7);
SFP(8); SFP(9); SFP(10); SFP(11);
@@ -76,7 +87,7 @@ save_fpu_int(struct thread *td)
SFP(28); SFP(29); SFP(30); SFP(31);
#undef SFP
} else {
- #define SFP(n) __asm ("stfd " #n ", 0(%0)" \
+ #define SFP(n) __asm("stfd " #n ", 0(%0)" \
:: "b"(&pcb->pcb_fpu.fpr[n].fpr));
SFP(0); SFP(1); SFP(2); SFP(3);
SFP(4); SFP(5); SFP(6); SFP(7);
@@ -149,8 +160,19 @@ enable_fpu(struct thread *td)
:: "b"(&pcb->pcb_fpu.fpscr));
if (pcb->pcb_flags & PCB_VSX) {
- #define LFP(n) __asm ("lxvw4x " #n ", 0,%0" \
+#if _BYTE_ORDER == _BIG_ENDIAN
+ #define LFP(n) __asm("lxvw4x " #n ", 0,%0" \
+ :: "b"(&pcb->pcb_fpu.fpr[n]));
+#else
+ /*
+ * lxvw4x will swap words within the FP double word on LE systems,
+ * leading to corruption if FP is used to store state and VSX is
+ * subsequently used to restore state.
+ * Use lxvd2x instead.
+ */
+ #define LFP(n) __asm("lxvd2x " #n ", 0,%0" \
:: "b"(&pcb->pcb_fpu.fpr[n]));
+#endif
LFP(0); LFP(1); LFP(2); LFP(3);
LFP(4); LFP(5); LFP(6); LFP(7);
LFP(8); LFP(9); LFP(10); LFP(11);
@@ -161,7 +183,7 @@ enable_fpu(struct thread *td)
LFP(28); LFP(29); LFP(30); LFP(31);
#undef LFP
} else {
- #define LFP(n) __asm ("lfd " #n ", 0(%0)" \
+ #define LFP(n) __asm("lfd " #n ", 0(%0)" \
:: "b"(&pcb->pcb_fpu.fpr[n].fpr));
LFP(0); LFP(1); LFP(2); LFP(3);
LFP(4); LFP(5); LFP(6); LFP(7);
diff --git a/sys/riscv/riscv/pmap.c b/sys/riscv/riscv/pmap.c
index 5d15bd671285..26efaecc64d1 100644
--- a/sys/riscv/riscv/pmap.c
+++ b/sys/riscv/riscv/pmap.c
@@ -4838,6 +4838,8 @@ pmap_unmapbios(void *p, vm_size_t size)
void
pmap_page_set_memattr(vm_page_t m, vm_memattr_t ma)
{
+ if (m->md.pv_memattr == ma)
+ return;
m->md.pv_memattr = ma;
diff --git a/sys/sys/exterrvar.h b/sys/sys/exterrvar.h
index 15557c614f88..7bf1d264ff5e 100644
--- a/sys/sys/exterrvar.h
+++ b/sys/sys/exterrvar.h
@@ -21,6 +21,7 @@
#define EXTERRCTL_ENABLE 1
#define EXTERRCTL_DISABLE 2
+#define EXTERRCTL_UD 3
#define EXTERRCTLF_FORCE 0x00000001
diff --git a/sys/sys/param.h b/sys/sys/param.h
index af116d6e3f7a..a8e9635242dd 100644
--- a/sys/sys/param.h
+++ b/sys/sys/param.h
@@ -74,7 +74,7 @@
* cannot include sys/param.h and should only be updated here.
*/
#undef __FreeBSD_version
-#define __FreeBSD_version 1500051
+#define __FreeBSD_version 1500052
/*
* __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD,
diff --git a/sys/vm/swap_pager.c b/sys/vm/swap_pager.c
index 86b75a2d7989..d6bd06226d04 100644
--- a/sys/vm/swap_pager.c
+++ b/sys/vm/swap_pager.c
@@ -384,8 +384,8 @@ swap_release_by_cred(vm_ooffset_t decr, struct ucred *cred)
#endif
}
-static int swap_pager_full = 2; /* swap space exhaustion (task killing) */
-static int swap_pager_almost_full = 1; /* swap space exhaustion (w/hysteresis)*/
+static bool swap_pager_full = true; /* swap space exhaustion (task killing) */
+static bool swap_pager_almost_full = true; /* swap space exhaustion (w/hysteresis) */
static struct mtx swbuf_mtx; /* to sync nsw_wcount_async */
static int nsw_wcount_async; /* limit async write buffers */
static int nsw_wcount_async_max;/* assigned maximum */
@@ -642,14 +642,14 @@ swp_sizecheck(void)
{
if (swap_pager_avail < nswap_lowat) {
- if (swap_pager_almost_full == 0) {
+ if (!swap_pager_almost_full) {
printf("swap_pager: out of swap space\n");
- swap_pager_almost_full = 1;
+ swap_pager_almost_full = true;
}
} else {
- swap_pager_full = 0;
+ swap_pager_full = false;
if (swap_pager_avail > nswap_hiwat)
- swap_pager_almost_full = 0;
+ swap_pager_almost_full = false;
}
}
@@ -958,11 +958,10 @@ swp_pager_getswapspace(int *io_npages)
swp_sizecheck();
swdevhd = TAILQ_NEXT(sp, sw_list);
} else {
- if (swap_pager_full != 2) {
+ if (!swap_pager_full) {
printf("swp_pager_getswapspace(%d): failed\n",
*io_npages);
- swap_pager_full = 2;
- swap_pager_almost_full = 1;
+ swap_pager_full = swap_pager_almost_full = true;
}
swdevhd = NULL;
}
@@ -2863,10 +2862,8 @@ swapoff_one(struct swdevt *sp, struct ucred *cred, u_int flags)
sp->sw_id = NULL;
TAILQ_REMOVE(&swtailq, sp, sw_list);
nswapdev--;
- if (nswapdev == 0) {
- swap_pager_full = 2;
- swap_pager_almost_full = 1;
- }
+ if (nswapdev == 0)
+ swap_pager_full = swap_pager_almost_full = true;
if (swdevhd == sp)
swdevhd = NULL;
mtx_unlock(&sw_dev_mtx);
diff --git a/sys/vm/vm_domainset.c b/sys/vm/vm_domainset.c
index 7b8bf4c77663..b44bdb96b0d4 100644
--- a/sys/vm/vm_domainset.c
+++ b/sys/vm/vm_domainset.c
@@ -131,8 +131,7 @@ static void
vm_domainset_iter_next(struct vm_domainset_iter *di, int *domain)
{
- KASSERT(di->di_n > 0,
- ("vm_domainset_iter_first: Invalid n %d", di->di_n));
+ KASSERT(di->di_n > 0, ("%s: Invalid n %d", __func__, di->di_n));
switch (di->di_policy) {
case DOMAINSET_POLICY_FIRSTTOUCH:
/*
@@ -149,11 +148,10 @@ vm_domainset_iter_next(struct vm_domainset_iter *di, int *domain)
vm_domainset_iter_prefer(di, domain);
break;
default:
- panic("vm_domainset_iter_first: Unknown policy %d",
- di->di_policy);
+ panic("%s: Unknown policy %d", __func__, di->di_policy);
}
KASSERT(*domain < vm_ndomains,
- ("vm_domainset_iter_next: Invalid domain %d", *domain));
+ ("%s: Invalid domain %d", __func__, *domain));
}
static void
@@ -189,13 +187,11 @@ vm_domainset_iter_first(struct vm_domainset_iter *di, int *domain)
di->di_n = di->di_domain->ds_cnt;
break;
default:
- panic("vm_domainset_iter_first: Unknown policy %d",
- di->di_policy);
+ panic("%s: Unknown policy %d", __func__, di->di_policy);
}
- KASSERT(di->di_n > 0,
- ("vm_domainset_iter_first: Invalid n %d", di->di_n));
+ KASSERT(di->di_n > 0, ("%s: Invalid n %d", __func__, di->di_n));
KASSERT(*domain < vm_ndomains,
- ("vm_domainset_iter_first: Invalid domain %d", *domain));
+ ("%s: Invalid domain %d", __func__, *domain));
}
void
diff --git a/sys/vm/vm_kern.c b/sys/vm/vm_kern.c
index 875c22d27628..e7d7b6726d2c 100644
--- a/sys/vm/vm_kern.c
+++ b/sys/vm/vm_kern.c
@@ -110,11 +110,18 @@ u_int exec_map_entry_size;
u_int exec_map_entries;
SYSCTL_ULONG(_vm, OID_AUTO, min_kernel_address, CTLFLAG_RD,
- SYSCTL_NULL_ULONG_PTR, VM_MIN_KERNEL_ADDRESS, "Min kernel address");
+#if defined(__amd64__)
+ &kva_layout.km_low, 0,
+#else
+ SYSCTL_NULL_ULONG_PTR, VM_MIN_KERNEL_ADDRESS,
+#endif
+ "Min kernel address");
SYSCTL_ULONG(_vm, OID_AUTO, max_kernel_address, CTLFLAG_RD,
#if defined(__arm__)
&vm_max_kernel_address, 0,
+#elif defined(__amd64__)
+ &kva_layout.km_high, 0,
#else
SYSCTL_NULL_ULONG_PTR, VM_MAX_KERNEL_ADDRESS,
#endif
diff --git a/sys/vm/vm_pagequeue.h b/sys/vm/vm_pagequeue.h
index cbbd27389662..9bd3b389fb60 100644
--- a/sys/vm/vm_pagequeue.h
+++ b/sys/vm/vm_pagequeue.h
@@ -260,9 +260,9 @@ struct vm_domain {
u_int vmd_inactive_shortage; /* Per-thread shortage. */
blockcount_t vmd_inactive_running; /* Number of inactive threads. */
blockcount_t vmd_inactive_starting; /* Number of threads started. */
- volatile u_int vmd_addl_shortage; /* Shortage accumulator. */
- volatile u_int vmd_inactive_freed; /* Successful inactive frees. */
- volatile u_int vmd_inactive_us; /* Microseconds for above. */
+ u_int vmd_addl_shortage; /* (a) Shortage accumulator. */
+ u_int vmd_inactive_freed; /* (a) Successful inactive frees. */
+ u_int vmd_inactive_us; /* (a) Microseconds for above. */
u_int vmd_inactive_pps; /* Exponential decay frees/second. */
int vmd_oom_seq;
int vmd_last_active_scan;
diff --git a/tests/ci/tools/freebsdci b/tests/ci/tools/freebsdci
index 7b4ce9669ab2..51bd19e2967d 100755
--- a/tests/ci/tools/freebsdci
+++ b/tests/ci/tools/freebsdci
@@ -25,9 +25,6 @@
. /etc/rc.subr
-: ${freebsdci_enable:="NO"}
-: ${freebsdci_type:="full"}
-
name="freebsdci"
desc="Run FreeBSD CI"
rcvar=freebsdci_enable
@@ -39,6 +36,11 @@ tardev=/dev/vtbd1
metadir=/meta
istar=$(file -s ${tardev} | grep "POSIX tar archive" | wc -l)
+load_rc_config $name
+: ${freebsdci_enable:="NO"}
+: ${freebsdci_type:="full"}
+PATH="${PATH}:/usr/local/sbin:/usr/local/bin"
+
auto_shutdown()
{
# NOTE: Currently RISC-V kernels lack the ability to
@@ -105,5 +107,4 @@ firstboot_ci_run()
auto_shutdown
}
-load_rc_config $name
run_rc_command "$1"
diff --git a/tests/sys/kern/Makefile b/tests/sys/kern/Makefile
index f2c24ad9dec9..336e73f29835 100644
--- a/tests/sys/kern/Makefile
+++ b/tests/sys/kern/Makefile
@@ -17,6 +17,7 @@ ATF_TESTS_C+= kern_copyin
ATF_TESTS_C+= kern_descrip_test
# One test modifies the maxfiles limit, which can cause spurious test failures.
TEST_METADATA.kern_descrip_test+= is_exclusive="true"
+ATF_TESTS_C+= exterr_test
ATF_TESTS_C+= fdgrowtable_test
ATF_TESTS_C+= getdirentries_test
ATF_TESTS_C+= jail_lookup_root
diff --git a/tests/sys/kern/exterr_test.c b/tests/sys/kern/exterr_test.c
new file mode 100644
index 000000000000..17c84c1f8ed4
--- /dev/null
+++ b/tests/sys/kern/exterr_test.c
@@ -0,0 +1,108 @@
+/*-
+ * Copyright (C) 2025 ConnectWise, LLC. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/exterrvar.h>
+#include <sys/mman.h>
+
+#include <atf-c.h>
+#include <errno.h>
+#include <exterr.h>
+#include <stdio.h>
+
+ATF_TC(gettext_extended);
+ATF_TC_HEAD(gettext_extended, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Retrieve an extended error message");
+}
+ATF_TC_BODY(gettext_extended, tc)
+{
+ char exterr[UEXTERROR_MAXLEN];
+ int r;
+
+ /*
+ * Use an invalid call to mmap() because it supports extended error
+ * messages, requires no special resources, and does not need root.
+ */
+ ATF_CHECK_ERRNO(ENOTSUP,
+ mmap(NULL, 0, PROT_MAX(PROT_READ) | PROT_WRITE, 0, -1, 0));
+ r = uexterr_gettext(exterr, sizeof(exterr));
+ ATF_CHECK_EQ(0, r);
+ printf("Extended error: %s\n", exterr);
+ /* Note: error string may need to be updated due to kernel changes */
+ ATF_CHECK(strstr(exterr, "prot is not subset of max_prot") != 0);
+}
+
+ATF_TC(gettext_noextended);
+ATF_TC_HEAD(gettext_noextended, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Fail to retrieve an extended error message because none exists");
+}
+ATF_TC_BODY(gettext_noextended, tc)
+{
+ char exterr[UEXTERROR_MAXLEN];
+ int r;
+
+ ATF_CHECK_ERRNO(EINVAL, exterrctl(EXTERRCTL_UD, 0, NULL));
+ r = uexterr_gettext(exterr, sizeof(exterr));
+ ATF_CHECK_EQ(0, r);
+ ATF_CHECK_STREQ(exterr, "");
+}
+
+ATF_TC(gettext_noextended_after_extended);
+ATF_TC_HEAD(gettext_noextended_after_extended, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "uexterr_gettext should not return a stale extended error message");
+}
+ATF_TC_BODY(gettext_noextended_after_extended, tc)
+{
+ char exterr[UEXTERROR_MAXLEN];
+ int r;
+
+ /*
+ * First do something that will create an extended error message, but
+ * ignore it.
+ */
+ ATF_CHECK_ERRNO(ENOTSUP,
+ mmap(NULL, 0, PROT_MAX(PROT_READ) | PROT_WRITE, 0, -1, 0));
+
+ /* Then do something that won't create an extended error message */
+ ATF_CHECK_ERRNO(EINVAL, exterrctl(EXTERRCTL_UD, 0, NULL));
+
+ /* Hopefully we won't see the stale extended error message */
+ r = uexterr_gettext(exterr, sizeof(exterr));
+ ATF_CHECK_EQ(0, r);
+ ATF_CHECK_STREQ(exterr, "");
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, gettext_extended);
+ ATF_TP_ADD_TC(tp, gettext_noextended);
+ ATF_TP_ADD_TC(tp, gettext_noextended_after_extended);
+
+ return (atf_no_error());
+}
diff --git a/tests/sys/netinet6/addr6.sh b/tests/sys/netinet6/addr6.sh
index 38e4bb152240..6fd66d5aa0c7 100755
--- a/tests/sys/netinet6/addr6.sh
+++ b/tests/sys/netinet6/addr6.sh
@@ -39,7 +39,32 @@ addr6_invalid_addr_cleanup()
vnet_cleanup
}
+atf_test_case "anycast_raw_addr" "cleanup"
+anycast_raw_addr_head()
+{
+ atf_set descr "a raw socket can bind to an anycast address"
+ atf_set require.user root
+}
+
+anycast_raw_addr_body()
+{
+ # lo0 needs to be up in the test jail for this test to work
+ ifconfig lo0 up
+
+ netif=$(ifconfig lo create)
+ echo $netif >netif
+ atf_check -s exit:0 ifconfig $netif inet6 2001:db8::1/128 up
+ atf_check -s exit:0 ifconfig $netif inet6 2001:db8::2/128 anycast
+ atf_check -s exit:0 -o ignore ping -c1 -S 2001:db8::2 2001:db8::1
+}
+
+anycast_raw_addr_cleanup()
+{
+ ifconfig $(cat netif) destroy
+}
+
atf_init_test_cases()
{
atf_add_test_case "addr6_invalid_addr"
+ atf_add_test_case "anycast_raw_addr"
}
diff --git a/tests/sys/netpfil/pf/anchor.sh b/tests/sys/netpfil/pf/anchor.sh
index 4692c06142df..64ca84b34c3d 100644
--- a/tests/sys/netpfil/pf/anchor.sh
+++ b/tests/sys/netpfil/pf/anchor.sh
@@ -350,9 +350,9 @@ nat_body()
jexec alcatraz pfctl -sn -a "foo/bar"
jexec alcatraz pfctl -sn -a "foo/baz"
- atf_check -s exit:0 -o match:"nat log on epair0a inet from 192.0.2.0/24 to any port = domain -> 192.0.2.1" \
+ atf_check -s exit:0 -o match:"nat log on ${epair}a inet from 192.0.2.0/24 to any port = domain -> 192.0.2.1" \
jexec alcatraz pfctl -sn -a "*"
- atf_check -s exit:0 -o match:"rdr on epair0a inet proto tcp from any to any port = echo -> 127.0.0.1 port 7" \
+ atf_check -s exit:0 -o match:"rdr on ${epair}a inet proto tcp from any to any port = echo -> 127.0.0.1 port 7" \
jexec alcatraz pfctl -sn -a "*"
}
diff --git a/tests/sys/netpfil/pf/nat.sh b/tests/sys/netpfil/pf/nat.sh
index f1fdf6405d97..16c981f97399 100644
--- a/tests/sys/netpfil/pf/nat.sh
+++ b/tests/sys/netpfil/pf/nat.sh
@@ -777,6 +777,38 @@ binat_match_cleanup()
kill $(cat ${PWD}/inetd_tester.pid)
}
+atf_test_case "empty_pool" "cleanup"
+empty_pool_head()
+{
+ atf_set descr 'NAT with empty pool'
+ atf_set require.user root
+}
+
+empty_pool_body()
+{
+ pft_init
+ setup_router_server_ipv6
+
+
+ pft_set_rules router \
+ "block" \
+ "pass inet6 proto icmp6 icmp6-type { neighbrsol, neighbradv }" \
+ "pass in on ${epair_tester}b" \
+ "pass out on ${epair_server}a inet6 from any to ${net_server_host_server} nat-to <nonexistent>" \
+
+ # pf_map_addr_sn() won't be able to pick a target address, because
+ # the table used in redireciton pool is empty. Packet will not be
+ # forwarded, error counter will be increased.
+ ping_server_check_reply exit:1
+ # Ignore warnings about not-loaded ALTQ
+ atf_check -o "match:map-failed +1 +" -x "jexec router pfctl -qvvsi 2> /dev/null"
+}
+
+empty_pool_cleanup()
+{
+ pft_cleanup
+}
+
atf_init_test_cases()
{
atf_add_test_case "exhaust"
@@ -794,4 +826,5 @@ atf_init_test_cases()
atf_add_test_case "nat_match"
atf_add_test_case "binat_compat"
atf_add_test_case "binat_match"
+ atf_add_test_case "empty_pool"
}
diff --git a/tests/sys/netpfil/pf/nat64.py b/tests/sys/netpfil/pf/nat64.py
index adae2489ce5e..5cc4713a16cc 100644
--- a/tests/sys/netpfil/pf/nat64.py
+++ b/tests/sys/netpfil/pf/nat64.py
@@ -272,3 +272,18 @@ class TestNAT64(VnetTestTemplate):
reply = self.common_test_source_addr(packet)
icmp = reply.getlayer(sp.ICMPv6EchoRequest)
assert icmp
+
+ @pytest.mark.require_user("root")
+ @pytest.mark.require_progs(["scapy"])
+ def test_bad_len(self):
+ """
+ PR 288224: we can panic if the IPv6 plen is longer than the packet length.
+ """
+ ToolsHelper.print_output("/sbin/route -6 add default 2001:db8::1")
+ import scapy.all as sp
+
+ packet = sp.IPv6(dst="64:ff9b::198.51.100.2", hlim=2, plen=512) \
+ / sp.ICMPv6EchoRequest() / sp.Raw("foo")
+ reply = sp.sr1(packet, timeout=3)
+ # We don't expect a reply to a corrupted packet
+ assert not reply
diff --git a/tests/sys/netpfil/pf/rdr.sh b/tests/sys/netpfil/pf/rdr.sh
index 4c08b4973891..f7c920bbfa8f 100644
--- a/tests/sys/netpfil/pf/rdr.sh
+++ b/tests/sys/netpfil/pf/rdr.sh
@@ -142,7 +142,7 @@ tcp_v6_pass_body()
{
tcp_v6_setup # Sets ${epair_…} variables
tcp_v6_common \
- "rdr on ${epair_one}a proto tcp from any to any port 80 -> 2001:db8:b::2 port 8000"
+ "pass in on ${epair_one}a proto tcp from any to any port 80 rdr-to 2001:db8:b::2 port 8000"
}
tcp_v6_pass_cleanup()
diff --git a/tests/sys/netpfil/pf/route_to.sh b/tests/sys/netpfil/pf/route_to.sh
index 5c0d355b8ea1..fd1653cce311 100644
--- a/tests/sys/netpfil/pf/route_to.sh
+++ b/tests/sys/netpfil/pf/route_to.sh
@@ -859,6 +859,121 @@ ttl_cleanup()
pft_cleanup
}
+
+atf_test_case "empty_pool" "cleanup"
+empty_pool_head()
+{
+ atf_set descr 'Route-to with empty pool'
+ atf_set require.user root
+}
+
+empty_pool_body()
+{
+ pft_init
+ setup_router_server_ipv6
+
+
+ pft_set_rules router \
+ "block" \
+ "pass inet6 proto icmp6 icmp6-type { neighbrsol, neighbradv }" \
+ "pass in on ${epair_tester}b route-to (${epair_server}a <nonexistent>) inet6 from any to ${net_server_host_server}" \
+ "pass out on ${epair_server}a"
+
+ # pf_map_addr_sn() won't be able to pick a target address, because
+ # the table used in redireciton pool is empty. Packet will not be
+ # forwarded, error counter will be increased.
+ ping_server_check_reply exit:1
+ # Ignore warnings about not-loaded ALTQ
+ atf_check -o "match:map-failed +1 +" -x "jexec router pfctl -qvvsi 2> /dev/null"
+}
+
+empty_pool_cleanup()
+{
+ pft_cleanup
+}
+
+
+atf_test_case "table_loop" "cleanup"
+
+table_loop_head()
+{
+ atf_set descr 'Check that iterating over tables poperly loops'
+ atf_set require.user root
+}
+
+table_loop_body()
+{
+ setup_router_server_nat64
+
+ # Clients will connect from another network behind the router.
+ # This allows for using multiple source addresses.
+ jexec router route add -6 ${net_clients_6}::/${net_clients_6_mask} ${net_tester_6_host_tester}
+ jexec router route add ${net_clients_4}.0/${net_clients_4_mask} ${net_tester_4_host_tester}
+
+ # The servers are reachable over additional IP addresses for
+ # testing of tables and subnets. The addresses are noncontinougnus
+ # for pf_map_addr() counter tests.
+ for i in 0 1 4 5; do
+ a1=$((24 + i))
+ jexec server1 ifconfig ${epair_server1}b inet ${net_server1_4}.${a1}/32 alias
+ jexec server1 ifconfig ${epair_server1}b inet6 ${net_server1_6}::42:${i}/128 alias
+ a2=$((40 + i))
+ jexec server2 ifconfig ${epair_server2}b inet ${net_server2_4}.${a2}/32 alias
+ jexec server2 ifconfig ${epair_server2}b inet6 ${net_server2_6}::42:${i}/128 alias
+ done
+
+ jexec router pfctl -e
+ pft_set_rules router \
+ "set debug loud" \
+ "set reassemble yes" \
+ "set state-policy if-bound" \
+ "table <rt_targets_1> { ${net_server1_6}::42:4/127 ${net_server1_6}::42:0/127 }" \
+ "table <rt_targets_2> { ${net_server2_6}::42:4/127 }" \
+ "pass in on ${epair_tester}b \
+ route-to { \
+ (${epair_server1}a <rt_targets_1>) \
+ (${epair_server2}a <rt_targets_2_empty>) \
+ (${epair_server2}a <rt_targets_2>) \
+ } \
+ inet6 proto tcp \
+ keep state"
+
+ # Both hosts of the pool are tables. Each table gets iterated over once,
+ # then the pool iterates to the next host, which is also iterated,
+ # then the pool loops back to the 1st host. If an empty table is found,
+ # it is skipped. Unless that's the only table, that is tested by
+ # the "empty_pool" test.
+ for port in $(seq 1 7); do
+ port=$((4200 + port))
+ atf_check -s exit:0 ${common_dir}/pft_ping.py \
+ --sendif ${epair_tester}a --replyif ${epair_tester}a \
+ --fromaddr ${net_clients_6}::1 --to ${host_server_6} \
+ --ping-type=tcp3way --send-sport=${port}
+ done
+
+ states=$(mktemp) || exit 1
+ jexec router pfctl -qvvss | normalize_pfctl_s > $states
+ cat $states
+
+ for state_regexp in \
+ "${epair_tester}b tcp ${host_server_6}\[9\] <- ${net_clients_6}::1\[4201\] .* route-to: ${net_server1_6}::42:0@${epair_server1}a" \
+ "${epair_tester}b tcp ${host_server_6}\[9\] <- ${net_clients_6}::1\[4202\] .* route-to: ${net_server1_6}::42:1@${epair_server1}a" \
+ "${epair_tester}b tcp ${host_server_6}\[9\] <- ${net_clients_6}::1\[4203\] .* route-to: ${net_server1_6}::42:4@${epair_server1}a" \
+ "${epair_tester}b tcp ${host_server_6}\[9\] <- ${net_clients_6}::1\[4204\] .* route-to: ${net_server1_6}::42:5@${epair_server1}a" \
+ "${epair_tester}b tcp ${host_server_6}\[9\] <- ${net_clients_6}::1\[4205\] .* route-to: ${net_server2_6}::42:4@${epair_server2}a" \
+ "${epair_tester}b tcp ${host_server_6}\[9\] <- ${net_clients_6}::1\[4206\] .* route-to: ${net_server2_6}::42:5@${epair_server2}a" \
+ "${epair_tester}b tcp ${host_server_6}\[9\] <- ${net_clients_6}::1\[4207\] .* route-to: ${net_server1_6}::42:0@${epair_server1}a" \
+ ; do
+ grep -qE "${state_regexp}" $states || atf_fail "State not found for '${state_regexp}'"
+ done
+}
+
+table_loop_cleanup()
+{
+ pft_cleanup
+}
+
+
atf_init_test_cases()
{
atf_add_test_case "v4"
@@ -877,4 +992,6 @@ atf_init_test_cases()
atf_add_test_case "dummynet_double"
atf_add_test_case "sticky"
atf_add_test_case "ttl"
+ atf_add_test_case "empty_pool"
+ atf_add_test_case "table_loop"
}
diff --git a/tests/sys/netpfil/pf/utils.subr b/tests/sys/netpfil/pf/utils.subr
index 6af10e80390d..3f8d437920f9 100644
--- a/tests/sys/netpfil/pf/utils.subr
+++ b/tests/sys/netpfil/pf/utils.subr
@@ -274,6 +274,107 @@ setup_router_server_ipv6()
jexec server inetd -p ${PWD}/inetd.pid $inetd_conf
}
+# Create a router and 2 server jails for nat64 and rfc5549 test cases.
+# The router is connected to servers, both are dual-stack, and to the
+# tester jail. All links are dual stack.
+setup_router_server_nat64()
+{
+ pft_init
+
+ epair_tester=$(vnet_mkepair)
+ epair_server1=$(vnet_mkepair)
+ epair_server2=$(vnet_mkepair)
+
+ # Funny how IPv4 address space is to small to even assign nice /24
+ # prefixes on all needed networks. On IPv6 we have a separate /64 for
+ # each link, loopback server, and client/SNAT pool. On IPv4 we must
+ # use small /28 prefixes, so even though we define all networks
+ # as variables we can't easily use them in tests if additional addresses
+ # are needed.
+
+ # IP addresses which can be used by the tester jail.
+ # Can be used as SNAT or as source with pft_ping.py. It is up to
+ # the test code to make them accessible from router.
+ net_clients_4=203.0.113
+ net_clients_4_mask=24
+ net_clients_6=2001:db8:44
+ net_clients_6_mask=64
+
+ # IP addresses on loopback interfaces of both servers. They can be
+ # accessed using the route-to targtet.
+ host_server_4=192.0.2.100
+ host_server_6=2001:db8:4203::100
+
+ net_tester_4=198.51.100
+ net_tester_4_mask=28
+ net_tester_4_host_router=198.51.100.1
+ net_tester_4_host_tester=198.51.100.2
+
+ net_tester_6=2001:db8:4200
+ net_tester_6_mask=64
+ net_tester_6_host_router=2001:db8:4200::1
+ net_tester_6_host_tester=2001:db8:4200::2
+
+ net_server1_4=198.51.100
+ net_server1_4_mask=28
+ net_server1_4_host_router=198.51.100.17
+ net_server1_4_host_server=198.51.100.18
+
+ net_server1_6=2001:db8:4201
+ net_server1_6_mask=64
+ net_server1_6_host_router=2001:db8:4201::1
+ net_server1_6_host_server=2001:db8:4201::2
+
+ net_server2_4=198.51.100
+ net_server2_4_mask=28
+ net_server2_4_host_router=198.51.100.33
+ net_server2_4_host_server=198.51.100.34
+
+ net_server2_6=2001:db8:4202
+ net_server2_6_mask=64
+ net_server2_6_host_router=2001:db8:4202::1
+ net_server2_6_host_server=2001:db8:4202::2
+
+ vnet_mkjail router ${epair_tester}b ${epair_server1}a ${epair_server2}a
+ jexec router ifconfig ${epair_tester}b inet ${net_tester_4_host_router}/${net_tester_4_mask} up
+ jexec router ifconfig ${epair_tester}b inet6 ${net_tester_6_host_router}/${net_tester_6_mask} up no_dad
+ jexec router ifconfig ${epair_server1}a inet ${net_server1_4_host_router}/${net_server1_4_mask} up
+ jexec router ifconfig ${epair_server1}a inet6 ${net_server1_6_host_router}/${net_server1_6_mask} up no_dad
+ jexec router ifconfig ${epair_server2}a inet ${net_server2_4_host_router}/${net_server2_4_mask} up
+ jexec router ifconfig ${epair_server2}a inet6 ${net_server2_6_host_router}/${net_server2_6_mask} up no_dad
+ jexec router sysctl net.inet.ip.forwarding=1
+ jexec router sysctl net.inet6.ip6.forwarding=1
+ jexec router pfctl -e
+
+ ifconfig ${epair_tester}a inet ${net_tester_4_host_tester}/${net_tester_4_mask} up
+ ifconfig ${epair_tester}a inet6 ${net_tester_6_host_tester}/${net_tester_6_mask} up no_dad
+ route add 0.0.0.0/0 ${net_tester_4_host_router}
+ route add -6 ::/0 ${net_tester_6_host_router}
+
+ inetd_conf=$(mktemp)
+ echo "discard stream tcp46 nowait root internal" >> $inetd_conf
+
+ vnet_mkjail server1 ${epair_server1}b
+ jexec server1 /etc/rc.d/netif start lo0
+ jexec server1 ifconfig ${epair_server1}b inet ${net_server1_4_host_server}/${net_server1_4_mask} up
+ jexec server1 ifconfig ${epair_server1}b inet6 ${net_server1_6_host_server}/${net_server1_6_mask} up no_dad
+ jexec server1 ifconfig lo0 ${host_server_4}/32 alias
+ jexec server1 ifconfig lo0 inet6 ${host_server_6}/128 alias
+ jexec server1 inetd -p ${PWD}/inetd_1.pid $inetd_conf
+ jexec server1 route add 0.0.0.0/0 ${net_server1_4_host_router}
+
+ jexec server1 route add -6 ::/0 ${net_server1_6_host_router}
+ vnet_mkjail server2 ${epair_server2}b
+ jexec server2 /etc/rc.d/netif start lo0
+ jexec server2 ifconfig ${epair_server2}b inet ${net_server2_4_host_server}/${net_server2_4_mask} up
+ jexec server2 ifconfig ${epair_server2}b inet6 ${net_server2_6_host_server}/${net_server2_6_mask} up no_dad
+ jexec server2 ifconfig lo0 ${host_server_4}/32 alias
+ jexec server2 ifconfig lo0 inet6 ${host_server_6}/128 alias
+ jexec server2 inetd -p ${PWD}/inetd_2.pid $inetd_conf
+ jexec server2 route add 0.0.0.0/0 ${net_server2_4_host_router}
+ jexec server2 route add -6 ::/0 ${net_server2_6_host_router}
+}
+
# Ping the dummy static NDP target.
# Check for pings being forwarded through the router towards the target.
ping_dummy_check_request()
diff --git a/tools/test/stress2/misc/all.exclude b/tools/test/stress2/misc/all.exclude
index f8a5ea4a91f1..54524c92eac0 100644
--- a/tools/test/stress2/misc/all.exclude
+++ b/tools/test/stress2/misc/all.exclude
@@ -16,8 +16,6 @@ fsck12.sh Waiting for fix 20230319
fsync.sh panic: Journal overflow 20190208
fuse.sh https://people.freebsd.org/~pho/stress/log/log0546.txt 20240828
fuse2.sh https://people.freebsd.org/~pho/stress/log/log0547.txt 20240828
-getrandom.sh Known DoS issue 20201107
-getrandom2.sh Known DoS issue 20200302
gjournal.sh panic: Journal overflow 20190626
gjournal2.sh panic: Journal overflow 20180125
gjournal3.sh panic: Bio not on queue 20171225
@@ -34,6 +32,7 @@ maxvnodes2.sh https://people.freebsd.org/~pho/stress/log/log0083.txt 20210329
memguard.sh https://people.freebsd.org/~pho/stress/log/log0088.txt 20210402
memguard2.sh Waiting for fix commit
memguard3.sh Waiting for fix commit
+mount7.sh https://people.freebsd.org/~pho/stress/log/log0549.txt 20240912
mlockall2.sh Unrecoverable OOM killing seen 20190203
mlockall6.sh https://people.freebsd.org/~pho/stress/log/log0430.txt 20230403
mlockall7.sh Needs further investigation 20210123
@@ -46,6 +45,7 @@ nfs16.sh panic: Failed to register NFS lock locally - error=11 20160608
nullfs28.sh Hang in "mount drain" seen 20220111
oom2.sh Hang in pfault 20180324
overcommit2.sh CAM stuck in vmwait seen 20200112
+pmc4.sh https://people.freebsd.org/~pho/stress/log/log0548.txt 20240904
pmc8.sh panic: [pmc,2749] (ri21, rc1) waiting too long for pmc to ... 20210621
rename14.sh https://people.freebsd.org/~pho/stress/log/log0433.txt 20230409
sctp2.sh panic: Queues are not empty when handling SHUTDOWN-COMPLETE 20210211
@@ -71,8 +71,12 @@ syzkaller59.sh Page fault 20220625
syzkaller65.sh panic: in_pcblookup_hash_locked: invalid local address 20230318
syzkaller66.sh panic: in_pcbconnect: inp is already connected 20230621
syzkaller67.sh panic: ASan: Invalid access, 8-byte read at ... 20230621
+syzkaller80.sh panic 20250711
+syzkaller81.sh panic 20250711
quota6.sh https://people.freebsd.org/~pho/stress/log/log0456.txt 20240707
truss3.sh WiP 20200915
+zfs18.sh https://people.freebsd.org/~pho/stress/log/log0560.txt 20241118
+zfs9.sh panic: sacked_bytes < 0 20250711
# Test not to run for other reasons:
diff --git a/tools/test/stress2/misc/fullpath2.sh b/tools/test/stress2/misc/fullpath2.sh
index e4024c32f317..f0037851482d 100755
--- a/tools/test/stress2/misc/fullpath2.sh
+++ b/tools/test/stress2/misc/fullpath2.sh
@@ -123,7 +123,7 @@ static volatile u_int *share;
#define NB 1024
#define RUNTIME 300
-/* dtrace -w -n 'fbt::*vn_fullpath1:entry {@rw[execname,probefunc] = count(); }' */
+/* dtrace -w -n 'fbt::*vn_fullpath:entry {@rw[execname,probefunc] = count(); }' */
static void
getfiles(pid_t pid)
diff --git a/tools/test/stress2/misc/syzkaller80.sh b/tools/test/stress2/misc/syzkaller80.sh
new file mode 100755
index 000000000000..31eae210d5b3
--- /dev/null
+++ b/tools/test/stress2/misc/syzkaller80.sh
@@ -0,0 +1,320 @@
+#!/bin/sh
+
+# panic: ../../../kern/uipc_usrreq.c:1256: uipc_sosend_stream_or_seqpacket: Empty stailq 0xfffffe00ffe5fc88->stqh_last is 0xfffffe00ffe5fcd0, not head's first field address
+# cpuid = 5
+# time = 1749593630
+# KDB: stack backtrace:
+# db_trace_self_wrapper() at db_trace_self_wrapper+0x2b/frame 0xfffffe00ffe5fab0
+# vpanic() at vpanic+0x136/frame 0xfffffe00ffe5fbe0
+# panic() at panic+0x43/frame 0xfffffe00ffe5fc40
+# uipc_sosend_stream_or_seqpacket() at uipc_sosend_stream_or_seqpacket+0xa39/frame 0xfffffe00ffe5fd10
+# sousrsend() at sousrsend+0x79/frame 0xfffffe00ffe5fd70
+# dofilewrite() at dofilewrite+0x81/frame 0xfffffe00ffe5fdc0
+# sys_writev() at sys_writev+0x69/frame 0xfffffe00ffe5fe00
+# amd64_syscall() at amd64_syscall+0x169/frame 0xfffffe00ffe5ff30
+# fast_syscall_common() at fast_syscall_common+0xf8/frame 0xfffffe00ffe5ff30
+# --- syscall (0, FreeBSD ELF64, syscall), rip = 0x82330181a, rsp = 0x8238dbf68, rbp = 0x8238dbf90 ---
+# KDB: enter: panic
+# [ thread pid 4484 tid 101524 ]
+# Stopped at kdb_enter+0x33: movq $0,0x122ebc2(%rip)
+# db> x/s version
+# version: FreeBSD 15.0-CURRENT #0 main-n277833-948078b65c27-dirty: Tue Jun 10 06:01:36 CEST 2025
+# pho@mercat1.netperf.freebsd.org:/usr/src/sys/amd64/compile/PHO
+# db>
+
+[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
+
+. ../default.cfg
+set -u
+prog=$(basename "$0" .sh)
+cat > /tmp/$prog.c <<EOF
+// https://syzkaller.appspot.com/bug?id=210ae0bfcef6324abfffbfaf10120b767106a990
+// autogenerated by syzkaller (https://github.com/google/syzkaller)
+// syzbot+cfcb8520b0071b548fba@syzkaller.appspotmail.com
+
+#define _GNU_SOURCE
+
+#include <sys/types.h>
+
+#include <errno.h>
+#include <pthread.h>
+#include <pwd.h>
+#include <signal.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/endian.h>
+#include <sys/syscall.h>
+#include <sys/wait.h>
+#include <time.h>
+#include <unistd.h>
+
+static unsigned long long procid;
+
+static void kill_and_wait(int pid, int* status)
+{
+ kill(pid, SIGKILL);
+ while (waitpid(-1, status, 0) != pid) {
+ }
+}
+
+static void sleep_ms(uint64_t ms)
+{
+ usleep(ms * 1000);
+}
+
+static uint64_t current_time_ms(void)
+{
+ struct timespec ts;
+ if (clock_gettime(CLOCK_MONOTONIC, &ts))
+ exit(1);
+ return (uint64_t)ts.tv_sec * 1000 + (uint64_t)ts.tv_nsec / 1000000;
+}
+
+static void thread_start(void* (*fn)(void*), void* arg)
+{
+ pthread_t th;
+ pthread_attr_t attr;
+ pthread_attr_init(&attr);
+ pthread_attr_setstacksize(&attr, 128 << 10);
+ int i = 0;
+ for (; i < 100; i++) {
+ if (pthread_create(&th, &attr, fn, arg) == 0) {
+ pthread_attr_destroy(&attr);
+ return;
+ }
+ if (errno == EAGAIN) {
+ usleep(50);
+ continue;
+ }
+ break;
+ }
+ exit(1);
+}
+
+typedef struct {
+ pthread_mutex_t mu;
+ pthread_cond_t cv;
+ int state;
+} event_t;
+
+static void event_init(event_t* ev)
+{
+ if (pthread_mutex_init(&ev->mu, 0))
+ exit(1);
+ if (pthread_cond_init(&ev->cv, 0))
+ exit(1);
+ ev->state = 0;
+}
+
+static void event_reset(event_t* ev)
+{
+ ev->state = 0;
+}
+
+static void event_set(event_t* ev)
+{
+ pthread_mutex_lock(&ev->mu);
+ if (ev->state)
+ exit(1);
+ ev->state = 1;
+ pthread_mutex_unlock(&ev->mu);
+ pthread_cond_broadcast(&ev->cv);
+}
+
+static void event_wait(event_t* ev)
+{
+ pthread_mutex_lock(&ev->mu);
+ while (!ev->state)
+ pthread_cond_wait(&ev->cv, &ev->mu);
+ pthread_mutex_unlock(&ev->mu);
+}
+
+static int event_isset(event_t* ev)
+{
+ pthread_mutex_lock(&ev->mu);
+ int res = ev->state;
+ pthread_mutex_unlock(&ev->mu);
+ return res;
+}
+
+static int event_timedwait(event_t* ev, uint64_t timeout)
+{
+ uint64_t start = current_time_ms();
+ uint64_t now = start;
+ pthread_mutex_lock(&ev->mu);
+ for (;;) {
+ if (ev->state)
+ break;
+ uint64_t remain = timeout - (now - start);
+ struct timespec ts;
+ ts.tv_sec = remain / 1000;
+ ts.tv_nsec = (remain % 1000) * 1000 * 1000;
+ pthread_cond_timedwait(&ev->cv, &ev->mu, &ts);
+ now = current_time_ms();
+ if (now - start > timeout)
+ break;
+ }
+ int res = ev->state;
+ pthread_mutex_unlock(&ev->mu);
+ return res;
+}
+
+struct thread_t {
+ int created, call;
+ event_t ready, done;
+};
+
+static struct thread_t threads[16];
+static void execute_call(int call);
+static int running;
+
+static void* thr(void* arg)
+{
+ struct thread_t* th = (struct thread_t*)arg;
+ for (;;) {
+ event_wait(&th->ready);
+ event_reset(&th->ready);
+ execute_call(th->call);
+ __atomic_fetch_sub(&running, 1, __ATOMIC_RELAXED);
+ event_set(&th->done);
+ }
+ return 0;
+}
+
+static void execute_one(void)
+{
+ if (write(1, "executing program\n", sizeof("executing program\n") - 1)) {
+ }
+ int i, call, thread;
+ for (call = 0; call < 5; call++) {
+ for (thread = 0; thread < (int)(sizeof(threads) / sizeof(threads[0]));
+ thread++) {
+ struct thread_t* th = &threads[thread];
+ if (!th->created) {
+ th->created = 1;
+ event_init(&th->ready);
+ event_init(&th->done);
+ event_set(&th->done);
+ thread_start(thr, th);
+ }
+ if (!event_isset(&th->done))
+ continue;
+ event_reset(&th->done);
+ th->call = call;
+ __atomic_fetch_add(&running, 1, __ATOMIC_RELAXED);
+ event_set(&th->ready);
+ if (call == 2)
+ break;
+ event_timedwait(&th->done, 50);
+ break;
+ }
+ }
+ for (i = 0; i < 100 && __atomic_load_n(&running, __ATOMIC_RELAXED); i++)
+ sleep_ms(1);
+}
+
+static void execute_one(void);
+
+#define WAIT_FLAGS 0
+
+static void loop(void)
+{
+ int iter = 0;
+ for (;; iter++) {
+ int pid = fork();
+ if (pid < 0)
+ exit(1);
+ if (pid == 0) {
+ execute_one();
+ exit(0);
+ }
+ int status = 0;
+ uint64_t start = current_time_ms();
+ for (;;) {
+ sleep_ms(10);
+ if (waitpid(-1, &status, WNOHANG | WAIT_FLAGS) == pid)
+ break;
+ if (current_time_ms() - start < 5000)
+ continue;
+ kill_and_wait(pid, &status);
+ break;
+ }
+ }
+}
+
+uint64_t r[2] = {0xffffffffffffffff, 0xffffffffffffffff};
+
+void execute_call(int call)
+{
+ intptr_t res = 0;
+ switch (call) {
+ case 0:
+ res = syscall(SYS_socketpair, /*domain=*/1ul, /*type=SOCK_STREAM*/ 1ul,
+ /*proto=*/0, /*fds=*/0x200000000040ul);
+ if (res != -1) {
+ r[0] = *(uint32_t*)0x200000000040;
+ r[1] = *(uint32_t*)0x200000000044;
+ }
+ break;
+ case 1:
+ memcpy((void*)0x200000000100, "\x09\x00\x10\x00", 4);
+ syscall(SYS_setsockopt, /*fd=*/r[1], /*level=*/0, /*optname=*/3,
+ /*optval=*/0x200000000100ul, /*optlen=*/4ul);
+ break;
+ case 2:
+ *(uint64_t*)0x2000000018c0 = 0;
+ *(uint32_t*)0x2000000018c8 = 0;
+ *(uint64_t*)0x2000000018d0 = 0;
+ *(uint64_t*)0x2000000018d8 = 0;
+ *(uint64_t*)0x2000000018e0 = 0x200000001880;
+ memcpy((void*)0x200000001880, "\x10\x00\x00\x00\xff\xff\x00\x00\x06", 9);
+ *(uint64_t*)0x2000000018e8 = 0x10;
+ *(uint32_t*)0x2000000018f0 = 0;
+ syscall(SYS_sendmsg, /*fd=*/r[0], /*msg=*/0x2000000018c0ul, /*f=*/0ul);
+ for (int i = 0; i < 64; i++) {
+ syscall(SYS_sendmsg, /*fd=*/r[0], /*msg=*/0x2000000018c0ul, /*f=*/0ul);
+ }
+ break;
+ case 3:
+ syscall(SYS_writev, /*fd=*/r[0], /*vec=*/0ul, /*vlen=*/0ul);
+ for (int i = 0; i < 64; i++) {
+ syscall(SYS_writev, /*fd=*/r[0], /*vec=*/0ul, /*vlen=*/0ul);
+ }
+ break;
+ case 4:
+ syscall(SYS_setsockopt, /*fd=*/(intptr_t)-1, /*level=*/0, /*optname=*/0xa,
+ /*optval=*/0ul, /*optlen=*/0ul);
+ break;
+ }
+}
+int main(void)
+{
+ syscall(SYS_mmap, /*addr=*/0x200000000000ul, /*len=*/0x1000000ul,
+ /*prot=PROT_WRITE|PROT_READ|PROT_EXEC*/ 7ul,
+ /*flags=MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE*/ 0x1012ul,
+ /*fd=*/(intptr_t)-1, /*offset=*/0ul);
+ const char* reason;
+ (void)reason;
+ for (procid = 0; procid < 4; procid++) {
+ if (fork() == 0) {
+ loop();
+ }
+ }
+ sleep(1000000);
+ return 0;
+}
+EOF
+mycc -o /tmp/$prog -Wall -Wextra -O0 /tmp/$prog.c -lpthread || exit 1
+
+work=/tmp/$prog.dir
+rm -rf $work
+mkdir $work
+cd /tmp/$prog.dir
+timeout 3m /tmp/$prog > /dev/null 2>&1
+
+rm -rf /tmp/$prog /tmp/$prog.c /tmp/$prog.core /tmp/$prog.?????? $work
+exit 0
diff --git a/tools/test/stress2/misc/syzkaller81.sh b/tools/test/stress2/misc/syzkaller81.sh
new file mode 100755
index 000000000000..e3e4ec50aeea
--- /dev/null
+++ b/tools/test/stress2/misc/syzkaller81.sh
@@ -0,0 +1,72 @@
+#!/bin/sh
+
+# panic: kern_clock_gettime: 22
+# cpuid = 1
+# time = 1750181240
+# KDB: stack backtrace:
+# db_trace_self_wrapper() at db_trace_self_wrapper+0x2b/frame 0xfffffe01a6084ba0
+# vpanic() at vpanic+0x136/frame 0xfffffe01a6084cd0
+# panic() at panic+0x43/frame 0xfffffe01a6084d30
+# kern_clock_nanosleep() at kern_clock_nanosleep+0x38f/frame 0xfffffe01a6084db0
+# sys_clock_nanosleep() at sys_clock_nanosleep+0x49/frame 0xfffffe01a6084e00
+# amd64_syscall() at amd64_syscall+0x169/frame 0xfffffe01a6084f30
+# fast_syscall_common() at fast_syscall_common+0xf8/frame 0xfffffe01a6084f30
+# --- syscall (0, FreeBSD ELF64, syscall), rip = 0x8233d281a, rsp = 0x820bfb2b8, rbp = 0x820bfb2e0 ---
+# KDB: enter: panic
+# [ thread pid 26119 tid 104417 ]
+# Stopped at kdb_enter+0x33: movq $0,0x122a7b2(%rip)
+# db> x/s version
+# version: FreeBSD 15.0-CURRENT #1 ufs-n278031-3296ff02387b: Tue Jun 17 16:40:44 CEST 2025
+# pho@mercat1.netperf.freebsd.org:/var/tmp/deviant3/sys/amd64/compile/PHO
+# db>
+
+[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
+
+. ../default.cfg
+set -u
+prog=$(basename "$0" .sh)
+cat > /tmp/$prog.c <<EOF
+// https://syzkaller.appspot.com/bug?id=5eb7636bc26fcbd20412de35ec10944233b8577d
+// autogenerated by syzkaller (https://github.com/google/syzkaller)
+// syzbot+e17e46b1f0b65027b005@syzkaller.appspotmail.com
+
+#define _GNU_SOURCE
+
+#include <pwd.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/endian.h>
+#include <sys/syscall.h>
+#include <unistd.h>
+
+int main(void)
+{
+ syscall(SYS_mmap, /*addr=*/0x200000000000ul, /*len=*/0x1000000ul,
+ /*prot=PROT_WRITE|PROT_READ|PROT_EXEC*/ 7ul,
+ /*flags=MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE*/ 0x1012ul,
+ /*fd=*/(intptr_t)-1, /*offset=*/0ul);
+ const char* reason;
+ (void)reason;
+ if (write(1, "executing program\n", sizeof("executing program\n") - 1)) {
+ }
+ *(uint64_t*)0x200000000040 = 0x10000000000;
+ *(uint64_t*)0x200000000048 = 0x4000000;
+ syscall(SYS_clock_nanosleep, /*id=*/0x10ul, /*flags=TIMER_ABSTIME*/ 1ul,
+ /*rqtp=*/0x200000000040ul, /*rmtp=*/0ul);
+ return 0;
+}
+EOF
+mycc -o /tmp/$prog -Wall -Wextra -O0 /tmp/$prog.c || exit 1
+
+work=/tmp/$prog.dir
+rm -rf $work
+mkdir $work
+cd /tmp/$prog.dir
+timeout 3m /tmp/$prog > /dev/null 2>&1
+
+rm -rf /tmp/$prog /tmp/$prog.c /tmp/$prog.core /tmp/$prog.?????? $work
+exit 0
diff --git a/usr.bin/du/du.1 b/usr.bin/du/du.1
index 37f7d7837b11..1b6d800b0285 100644
--- a/usr.bin/du/du.1
+++ b/usr.bin/du/du.1
@@ -25,7 +25,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd April 29, 2024
+.Dd July 16, 2025
.Dt DU 1
.Os
.Sh NAME
@@ -58,7 +58,7 @@ Generate output via
.Xr libxo 3
in a selection of different human and machine readable formats.
See
-.Xr xo_parse_args 3
+.Xr xo_options 7
for details on command line arguments.
.It Fl A
Display the apparent size instead of the disk usage.
@@ -225,7 +225,7 @@ Also display a grand total at the end:
.Xr chflags 2 ,
.Xr fts 3 ,
.Xr libxo 3 ,
-.Xr xo_parse_args 3 ,
+.Xr xo_options 7 ,
.Xr symlink 7 ,
.Xr quot 8
.Sh STANDARDS
diff --git a/usr.bin/find/find.1 b/usr.bin/find/find.1
index eb3fd4d0dbde..8c2d8624a82a 100644
--- a/usr.bin/find/find.1
+++ b/usr.bin/find/find.1
@@ -1156,7 +1156,7 @@ and was removed in
.At v3 .
It was rewritten for
.At v5
-and later be enhanced for the Programmer's Workbench (PWB).
+and was later enhanced for the Programmer's Workbench (PWB).
These changes were later incorporated in
.At v7 .
.Sh BUGS
diff --git a/usr.bin/fortune/datfiles/freebsd-tips b/usr.bin/fortune/datfiles/freebsd-tips
index 1e9501e3a6fb..6a2b59ff5fa7 100644
--- a/usr.bin/fortune/datfiles/freebsd-tips
+++ b/usr.bin/fortune/datfiles/freebsd-tips
@@ -555,7 +555,7 @@ Use "sysrc name=value" to add an entry and "sysrc -x name" to delete an entry.
You can upload the dmesg of your system to help developers get an overview of commonly
used hardware and peripherals for FreeBSD. Use the curl package to upload it like this:
curl -v -d "nickname=$USER" -d "description=FreeBSD/$(uname -m) on \
-$(kenv smbios.system.maker) $(kenv smbios.system.product)" -d "do=addd" \
+$(kenv smbios.system.maker) $(kenv smbios.system.product)" -d "do=add" \
--data-urlencode 'dmesg@/var/run/dmesg.boot' http://dmesgd.nycbug.org/index.cgi
%
Want to know how much memory (in bytes) your machine has installed? Let
diff --git a/usr.bin/iscsictl/iscsictl.8 b/usr.bin/iscsictl/iscsictl.8
index 74394063a007..88c79c297848 100644
--- a/usr.bin/iscsictl/iscsictl.8
+++ b/usr.bin/iscsictl/iscsictl.8
@@ -24,7 +24,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd December 27, 2018
+.Dd July 16, 2025
.Dt ISCSICTL 8
.Os
.Sh NAME
@@ -88,7 +88,7 @@ Generate output via
.Xr libxo 3
in a selection of different human and machine readable formats.
See
-.Xr xo_parse_args 3
+.Xr xo_options 7
for details on command line arguments.
.It Fl A
Add session.
@@ -190,7 +190,7 @@ Disconnect all iSCSI sessions:
.Dl Nm Fl Ra
.Sh SEE ALSO
.Xr libxo 3 ,
-.Xr xo_parse_args 3 ,
+.Xr xo_options 7 ,
.Xr iscsi 4 ,
.Xr iscsi.conf 5 ,
.Xr iscsid 8
diff --git a/usr.bin/last/last.1 b/usr.bin/last/last.1
index f3ccc6e772af..b026ed6a7921 100644
--- a/usr.bin/last/last.1
+++ b/usr.bin/last/last.1
@@ -25,7 +25,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd January 9, 2021
+.Dd July 16, 2025
.Dt LAST 1
.Os
.Sh NAME
@@ -75,7 +75,7 @@ Generate output via
.Xr libxo 3
in a selection of different human and machine readable formats.
See
-.Xr xo_parse_args 3
+.Xr xo_options 7
for details on command line arguments.
.It Fl d Ar date
Specify the snapshot date and time.
@@ -223,7 +223,7 @@ alice ttyv0 Mon Dec 7 19:18 - 22:27 (03:09)
.Xr lastcomm 1 ,
.Xr getutxent 3 ,
.Xr libxo 3 ,
-.Xr xo_parse_args 3 ,
+.Xr xo_options 7 ,
.Xr ac 8 ,
.Xr lastlogin 8
.Sh HISTORY
diff --git a/usr.bin/netstat/netstat.1 b/usr.bin/netstat/netstat.1
index 1a2c786e90aa..1931c38a1fad 100644
--- a/usr.bin/netstat/netstat.1
+++ b/usr.bin/netstat/netstat.1
@@ -25,7 +25,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd April 30, 2025
+.Dd July 16, 2025
.Dt NETSTAT 1
.Os
.Sh NAME
@@ -166,7 +166,7 @@ Generate output via
.Xr libxo 3
in a selection of different human and machine readable formats.
See
-.Xr xo_parse_args 3
+.Xr xo_options 7
for details on command line arguments.
.It Fl 4
Show IPv4 only.
@@ -416,7 +416,8 @@ When used with
or
.Fl 6 ,
limit the output to IPv4 or IPv6 routes respectively.
-This option provides details about individual nexthop addresses used in routing decisions.
+This option provides details about individual nexthop addresses
+used in routing decisions.
.It Xo
.Bk -words
.Nm netstat
@@ -430,7 +431,8 @@ When used with
or
.Fl 6 ,
restrict the output to IPv4 or IPv6 nexthop groups respectively.
-This option shows grouped nexthop entries for multipath or load-balanced routing setups.
+This option shows grouped nexthop entries for multipath or
+load-balanced routing setups.
.It Xo
.Bk -words
.Nm
@@ -926,25 +928,25 @@ binary is not available in the
.Sh EXAMPLES
Show packet traffic information (packets, bytes, errors, packet drops, etc) for
interface re0 updated every 2 seconds and exit after 5 outputs:
-.Bd -literal -offset indent
-$ netstat -w 2 -q 5 -I re0
-.Ed
+.Pp
+.Dl netstat -w 2 -q 5 -I re0
.Pp
Show statistics for ICMP on any interface:
-.Bd -literal -offset indent
-$ netstat -s -p icmp
-.Ed
+.Pp
+.Dl netstat -s -p icmp
.Pp
Show routing tables:
-.Bd -literal -offset indent
-$ netstat -r
-.Ed
+.Pp
+.Dl netstat -r
.Pp
Same as above, but without resolving numeric addresses and port numbers to
names:
-.Bd -literal -offset indent
-$ netstat -rn
-.Ed
+.Pp
+.Dl netstat -rn
+.Pp
+Show IPv4 listening sockets:
+.Pp
+.Dl netstat -4l
.Sh SEE ALSO
.Xr fstat 1 ,
.Xr nfsstat 1 ,
@@ -952,7 +954,7 @@ $ netstat -rn
.Xr ps 1 ,
.Xr sockstat 1 ,
.Xr libxo 3 ,
-.Xr xo_parse_args 3 ,
+.Xr xo_options 7 ,
.Xr bpf 4 ,
.Xr inet 4 ,
.Xr route 4 ,
diff --git a/usr.bin/nfsstat/nfsstat.1 b/usr.bin/nfsstat/nfsstat.1
index 7d641b50f1ac..a4a00586f21b 100644
--- a/usr.bin/nfsstat/nfsstat.1
+++ b/usr.bin/nfsstat/nfsstat.1
@@ -25,7 +25,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd December 28, 2023
+.Dd July 16, 2025
.Dt NFSSTAT 1
.Os
.Sh NAME
@@ -123,7 +123,7 @@ Generate output via
.Xr libxo 3
in a selection of different human and machine readable formats.
See
-.Xr xo_parse_args 3
+.Xr xo_options 7
for details on command line arguments.
.El
.Sh SEE ALSO
diff --git a/usr.bin/procstat/procstat.1 b/usr.bin/procstat/procstat.1
index 1e05e235e619..b810abf66da7 100644
--- a/usr.bin/procstat/procstat.1
+++ b/usr.bin/procstat/procstat.1
@@ -23,7 +23,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd April 7, 2022
+.Dd July 16, 2025
.Dt PROCSTAT 1
.Os
.Sh NAME
@@ -136,7 +136,7 @@ flag is specified the output is generated via
.Xr libxo 3
in a selection of different human and machine readable formats.
See
-.Xr xo_parse_args 3
+.Xr xo_options 7
for details on command line arguments.
.Pp
The following commands are available for
@@ -870,7 +870,7 @@ procstat: procstat_getprocs()
.Xr libprocstat 3 ,
.Xr libxo 3 ,
.Xr signal 3 ,
-.Xr xo_parse_args 3 ,
+.Xr xo_options 7 ,
.Xr ddb 4 ,
.Xr divert 4 ,
.Xr icmp 4 ,
diff --git a/usr.bin/sed/sed.1 b/usr.bin/sed/sed.1
index 345f673310d8..5fd894eaf78b 100644
--- a/usr.bin/sed/sed.1
+++ b/usr.bin/sed/sed.1
@@ -1,3 +1,6 @@
+.\"
+.\" SPDX-License-Identifier: BSD-3-Clause
+.\"
.\" Copyright (c) 1992, 1993
.\" The Regents of the University of California. All rights reserved.
.\"
@@ -28,7 +31,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd December 17, 2024
+.Dd June 14, 2025
.Dt SED 1
.Os
.Sh NAME
@@ -597,17 +600,17 @@ with
.Ql baz
when piped from another command:
.Bd -literal -offset indent
-echo "An alternate word, like bar, is sometimes used in examples." | sed 's/bar/baz/'
+echo "use bar in examples" | sed 's/bar/baz/'
.Ed
.Pp
Using backlashes can sometimes be hard to read and follow:
.Bd -literal -offset indent
-echo "/home/example" | sed 's/\\/home\\/example/\\/usr\\/local\\/example/'
+echo "/bin/bash" | sed 's/\\/bin\\/bash/\\/bin\\/sh/'
.Ed
.Pp
Using a different separator can be handy when working with paths:
.Bd -literal -offset indent
-echo "/home/example" | sed 's#/home/example#/usr/local/example#'
+echo "/bin/bash" | sed 's#/bin/bash#/bin/sh#'
.Ed
.Pp
Replace all occurrences of
diff --git a/usr.bin/sockstat/sockstat.1 b/usr.bin/sockstat/sockstat.1
index da658e33e542..4832a09764fd 100644
--- a/usr.bin/sockstat/sockstat.1
+++ b/usr.bin/sockstat/sockstat.1
@@ -25,7 +25,7 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd June 27, 2025
+.Dd June 30, 2025
.Dt SOCKSTAT 1
.Os
.Sh NAME
@@ -33,7 +33,7 @@
.Nd list open sockets
.Sh SYNOPSIS
.Nm
-.Op Fl 46ACcfIiLlnqSsUuv
+.Op Fl 46ACcfIiLlnqSsUuvw
.Op Fl j Ar jail
.Op Fl p Ar ports
.Op Fl P Ar protocols
@@ -119,6 +119,8 @@ Show
sockets.
.It Fl v
Verbose mode.
+.It Fl w
+Automatically size the columns.
.El
.Pp
If neither
diff --git a/usr.bin/sockstat/sockstat.c b/usr.bin/sockstat/sockstat.c
index 1a24ff67c321..d0540c54a1aa 100644
--- a/usr.bin/sockstat/sockstat.c
+++ b/usr.bin/sockstat/sockstat.c
@@ -97,6 +97,7 @@ static bool opt_s; /* Show protocol state if applicable */
static bool opt_U; /* Show remote UDP encapsulation port number */
static bool opt_u; /* Show Unix domain sockets */
static u_int opt_v; /* Verbose mode */
+static bool opt_w; /* Automatically size the columns */
/*
* Default protocols to use if no -P was defined.
@@ -1101,7 +1102,7 @@ format_unix_faddr(struct addr *faddr, char *buf, size_t bufsize) {
/* Remote peer we connect(2) to, if any. */
if (faddr->conn != 0) {
struct sock *p;
- pos += strlcpy(buf, "-> ", bufsize);
+ pos += strlcpy(SAFEBUF, "-> ", SAFESIZE);
p = RB_FIND(pcbs_t, &pcbs,
&(struct sock){ .pcb = faddr->conn });
if (__predict_false(p == NULL)) {
@@ -1132,8 +1133,7 @@ format_unix_faddr(struct addr *faddr, char *buf, size_t bufsize) {
while ((p = RB_FIND(pcbs_t, &pcbs,
&(struct sock){ .pcb = ref })) != 0) {
f = RB_FIND(files_t, &ftree,
- &(struct file){ .xf_data =
- p->socket });
+ &(struct file){ .xf_data = p->socket });
if (f != NULL) {
pos += snprintf(SAFEBUF, SAFESIZE,
"%s[%lu %d]", fref ? "" : ",",
@@ -1178,13 +1178,10 @@ calculate_sock_column_widths(struct col_widths *cw, struct sock *s)
len = strlen(s->protoname);
if (s->vflag & (INP_IPV4 | INP_IPV6))
len += 1;
- if (laddr != NULL && faddr != NULL && s->family == AF_UNIX &&
- laddr->address.ss_len == 0 && faddr->conn == 0)
- len += strlen(" (not connected)");
cw->proto = MAX(cw->proto, len);
while (laddr != NULL || faddr != NULL) {
- if (s->family == AF_UNIX) {
+ if (opt_w && s->family == AF_UNIX) {
if ((laddr == NULL) || (faddr == NULL))
errx(1, "laddr = %p or faddr = %p is NULL",
(void *)laddr, (void *)faddr);
@@ -1193,7 +1190,7 @@ calculate_sock_column_widths(struct col_widths *cw, struct sock *s)
cw->local_addr = MAX(cw->local_addr, len);
len = format_unix_faddr(faddr, NULL, 0);
cw->foreign_addr = MAX(cw->foreign_addr, len);
- } else {
+ } else if (opt_w) {
if (laddr != NULL) {
len = formataddr(&laddr->address, NULL, 0);
cw->local_addr = MAX(cw->local_addr, len);
@@ -1296,23 +1293,6 @@ calculate_sock_column_widths(struct col_widths *cw, struct sock *s)
static void
calculate_column_widths(struct col_widths *cw)
{
- cw->user = 4;
- cw->command = 10;
- cw->pid = 3;
- cw->fd = 2;
- cw->proto = 5;
- cw->local_addr = 13;
- cw->foreign_addr = 15;
- cw->pcb_kva = 18;
- cw->fib = 3;
- cw->splice_address = 14;
- cw->inp_gencnt = 2;
- cw->encaps = 6;
- cw->path_state = 10;
- cw->conn_state = 10;
- cw->stack = 5;
- cw->cc = 2;
-
int n, len;
struct file *xf;
struct sock *s;
@@ -1366,13 +1346,10 @@ display_sock(struct sock *s, struct col_widths *cw, char *buf, size_t bufsize)
faddr = s->faddr;
first = true;
- snprintf(buf, bufsize, "%s%s%s%s",
+ snprintf(buf, bufsize, "%s%s%s",
s->protoname,
s->vflag & INP_IPV4 ? "4" : "",
- s->vflag & INP_IPV6 ? "6" : "",
- (laddr != NULL && faddr != NULL &&
- s->family == AF_UNIX && laddr->address.ss_len == 0 &&
- faddr->conn == 0) ? " (not connected)" : "");
+ s->vflag & INP_IPV6 ? "6" : "");
printf(" %-*s", cw->proto, buf);
while (laddr != NULL || faddr != NULL) {
if (s->family == AF_UNIX) {
@@ -1381,23 +1358,27 @@ display_sock(struct sock *s, struct col_widths *cw, char *buf, size_t bufsize)
(void *)laddr, (void *)faddr);
if (laddr->address.ss_len > 0)
formataddr(&laddr->address, buf, bufsize);
+ else if (laddr->address.ss_len == 0 && faddr->conn == 0)
+ strlcpy(buf, "(not connected)", bufsize);
else
strlcpy(buf, "??", bufsize);
- printf(" %-*s", cw->local_addr, buf);
+ printf(" %-*.*s", cw->local_addr, cw->local_addr, buf);
if (format_unix_faddr(faddr, buf, bufsize) == 0)
strlcpy(buf, "??", bufsize);
- printf(" %-*s", cw->foreign_addr, buf);
+ printf(" %-*.*s", cw->foreign_addr,
+ cw->foreign_addr, buf);
} else {
if (laddr != NULL)
formataddr(&laddr->address, buf, bufsize);
else
strlcpy(buf, "??", bufsize);
- printf(" %-*s", cw->local_addr, buf);
+ printf(" %-*.*s", cw->local_addr, cw->local_addr, buf);
if (faddr != NULL)
formataddr(&faddr->address, buf, bufsize);
else
strlcpy(buf, "??", bufsize);
- printf(" %-*s", cw->foreign_addr, buf);
+ printf(" %-*.*s", cw->foreign_addr,
+ cw->foreign_addr, buf);
}
if (opt_A)
printf(" %#*" PRIx64, cw->pcb_kva, s->pcb);
@@ -1411,6 +1392,8 @@ display_sock(struct sock *s, struct col_widths *cw, char *buf, size_t bufsize)
if (sp != NULL)
formataddr(&sp->laddr->address,
buf, bufsize);
+ else
+ strlcpy(buf, "??", bufsize);
} else
strlcpy(buf, "??", bufsize);
printf(" %-*s", cw->splice_address, buf);
@@ -1510,6 +1493,25 @@ display(void)
err(1, "malloc()");
return;
}
+
+ cw = (struct col_widths) {
+ .user = strlen("USER"),
+ .command = 10,
+ .pid = strlen("PID"),
+ .fd = strlen("FD"),
+ .proto = strlen("PROTO"),
+ .local_addr = opt_w ? strlen("LOCAL ADDRESS") : 21,
+ .foreign_addr = opt_w ? strlen("FOREIGN ADDRESS") : 21,
+ .pcb_kva = 18,
+ .fib = strlen("FIB"),
+ .splice_address = strlen("SPLICE ADDRESS"),
+ .inp_gencnt = strlen("ID"),
+ .encaps = strlen("ENCAPS"),
+ .path_state = strlen("PATH STATE"),
+ .conn_state = strlen("CONN STATE"),
+ .stack = strlen("STACK"),
+ .cc = strlen("CC"),
+ };
calculate_column_widths(&cw);
if (!opt_q) {
@@ -1642,7 +1644,7 @@ static void
usage(void)
{
errx(1,
- "usage: sockstat [-46ACcfIiLlnqSsUuv] [-j jid] [-p ports] [-P protocols]");
+ "usage: sockstat [-46ACcfIiLlnqSsUuvw] [-j jid] [-p ports] [-P protocols]");
}
int
@@ -1721,7 +1723,7 @@ main(int argc, char *argv[])
++opt_v;
break;
case 'w':
- /* left for backward compatibility. */
+ opt_w = true;
break;
default:
usage();
diff --git a/usr.bin/top/top.1 b/usr.bin/top/top.1
index d8ef763e7a34..53b078839526 100644
--- a/usr.bin/top/top.1
+++ b/usr.bin/top/top.1
@@ -1,4 +1,4 @@
-.Dd April 1, 2025
+.Dd June 9, 2025
.Dt TOP 1
.Os
.Sh NAME
@@ -398,6 +398,7 @@ ID corresponding to the process,
USERNAME is the name of the process's owner (if
.Fl u
is specified, a UID column will be substituted for USERNAME),
+THR is the thread count, showing the number of threads a process has,
PRI is the current priority of the process,
NICE is the
.Xr nice 1
diff --git a/usr.bin/vmstat/vmstat.8 b/usr.bin/vmstat/vmstat.8
index de4176c9361c..80facb05cc35 100644
--- a/usr.bin/vmstat/vmstat.8
+++ b/usr.bin/vmstat/vmstat.8
@@ -25,7 +25,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd June 21, 2021
+.Dd July 16, 2025
.Dt VMSTAT 8
.Os
.Sh NAME
@@ -71,7 +71,7 @@ Generate output via
.Xr libxo 3
in a selection of different human and machine readable formats.
See
-.Xr xo_parse_args 3
+.Xr xo_options 7
for details on command line arguments.
.It Fl a
When used with
@@ -371,7 +371,7 @@ statistics every second.
.Xr systat 1 ,
.Xr libmemstat 3 ,
.Xr libxo 3 ,
-.Xr xo_parse_args 3 ,
+.Xr xo_options 7 ,
.Xr gstat 8 ,
.Xr iostat 8 ,
.Xr pstat 8 ,
diff --git a/usr.bin/w/w.1 b/usr.bin/w/w.1
index a92edc6f0059..159eb3370c8c 100644
--- a/usr.bin/w/w.1
+++ b/usr.bin/w/w.1
@@ -25,7 +25,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd August 24, 2020
+.Dd July 16, 2025
.Dt W 1
.Os
.Sh NAME
@@ -61,7 +61,7 @@ Generate output via
.Xr libxo 3
in a selection of different human and machine readable formats.
See
-.Xr xo_parse_args 3
+.Xr xo_options 7
for details on command line arguments.
.It Fl d
dumps out the entire process list on a per controlling
@@ -145,7 +145,7 @@ flags are no longer supported.
.Xr uptime 1 ,
.Xr who 1 ,
.Xr libxo 3 ,
-.Xr xo_parse_args 3
+.Xr xo_options 7
.Sh HISTORY
The
.Nm
diff --git a/usr.bin/wc/wc.1 b/usr.bin/wc/wc.1
index 482145c8f01f..656408794950 100644
--- a/usr.bin/wc/wc.1
+++ b/usr.bin/wc/wc.1
@@ -28,7 +28,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd April 11, 2020
+.Dd July 16, 2025
.Dt WC 1
.Os
.Sh NAME
@@ -70,7 +70,7 @@ Generate output via
.Xr libxo 3
in a selection of different human and machine readable formats.
See
-.Xr xo_parse_args 3
+.Xr xo_options 7
for details on command line arguments.
.It Fl L
Write the length of the line containing the most bytes (default) or characters
@@ -196,7 +196,7 @@ utility.
.Sh SEE ALSO
.Xr iswspace 3 ,
.Xr libxo 3 ,
-.Xr xo_parse_args 3
+.Xr xo_options 7
.Sh STANDARDS
The
.Nm
diff --git a/usr.sbin/arp/arp.8 b/usr.sbin/arp/arp.8
index d31b2b482ba3..0a171c9e36be 100644
--- a/usr.sbin/arp/arp.8
+++ b/usr.sbin/arp/arp.8
@@ -25,7 +25,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd July 13, 2020
+.Dd July 16, 2025
.Dt ARP 8
.Os
.Sh NAME
@@ -80,7 +80,7 @@ Generate output via
.Xr libxo 3
in a selection of different human and machine readable formats.
See
-.Xr xo_parse_args 3
+.Xr xo_options 7
for details on command line arguments.
.It Fl a
The program displays or, if it is used with the
@@ -183,7 +183,7 @@ character will mark the rest of the line as a comment.
.Sh SEE ALSO
.Xr inet 3 ,
.Xr libxo 3 ,
-.Xr xo_parse_args 3 ,
+.Xr xo_options 7 ,
.Xr arp 4 ,
.Xr ifconfig 8 ,
.Xr ndp 8
diff --git a/usr.sbin/bluetooth/bluetooth-config/bluetooth-config.sh b/usr.sbin/bluetooth/bluetooth-config/bluetooth-config.sh
index 48a399a82fc7..148325fcecbc 100755
--- a/usr.sbin/bluetooth/bluetooth-config/bluetooth-config.sh
+++ b/usr.sbin/bluetooth/bluetooth-config/bluetooth-config.sh
@@ -17,7 +17,7 @@ main() {
unset node device started bdaddresses retry
# Only one command at the moment is scan (+ add)
-[ "$#" -eq 1 -a "$1" = "scan" ] || print_syntax
+[ "$1" = "scan" ] || print_syntax
shift
# Get command line options
@@ -28,6 +28,12 @@ while getopts :d:n: arg; do
?) print_syntax;;
esac
done
+shift "$((OPTIND-1))"
+
+# If there's leftover parameters, print usage
+[ "$#" -eq 0 ] || print_syntax
+shift
+
# No use running without super user rights
if [ $( id -u ) -ne 0 ]; then
diff --git a/usr.sbin/bsdinstall/scripts/wlanconfig b/usr.sbin/bsdinstall/scripts/wlanconfig
index 8ac64858eaba..33d94a933f45 100755
--- a/usr.sbin/bsdinstall/scripts/wlanconfig
+++ b/usr.sbin/bsdinstall/scripts/wlanconfig
@@ -92,7 +92,7 @@ dialog_country_select()
sub(/.*domains:/, ""), /[^[:alnum:][[:space:]]/ {
n = split($0, domains)
for (i = 1; i <= n; i++)
- printf "'\''%s'\'' '\'\''", domains[i]
+ printf "'\''%s'\'' '\'\''\n", domains[i]
}
' | sort )
countries=$( echo "$input" | awk '
@@ -200,6 +200,12 @@ fi
while :; do
SCANSSID=0
+ # While wpa_supplicant may IFF_UP the interface, we do not want to rely
+ # in this. In case the script is run manually (outside the installer,
+ # e.g., for testing) wpa_supplicant may be running and the wlanN
+ # interface may be down (especially if dialog_country_select is not
+ # run successfully either) and scanning will not work.
+ f_eval_catch -d wlanconfig ifconfig "ifconfig $WLAN_IFACE up"
f_eval_catch -d wlanconfig wpa_cli "wpa_cli scan"
f_dialog_title "Scanning"
f_dialog_pause "Waiting 5 seconds to scan for wireless networks..." 5 ||
diff --git a/usr.sbin/bsnmpd/tools/bsnmptools/bsnmpget.c b/usr.sbin/bsnmpd/tools/bsnmptools/bsnmpget.c
index 9d5a693c7c68..9252e63749bb 100644
--- a/usr.sbin/bsnmpd/tools/bsnmptools/bsnmpget.c
+++ b/usr.sbin/bsnmpd/tools/bsnmptools/bsnmpget.c
@@ -1179,8 +1179,10 @@ main(int argc, char ** argv)
/* On -h (help) exit without error. */
if (opt_num == -2)
exit(0);
- else
+ else {
+ fprintf(stderr, "Error: %s\n", snmp_client.error);
exit(1);
+ }
}
oid_cnt = argc - opt_num - 1;
@@ -1239,7 +1241,7 @@ main(int argc, char ** argv)
}
if (snmp_open(NULL, NULL, NULL, NULL)) {
- warn("Failed to open snmp session");
+ fprintf(stderr, "snmp_open(3): %s\n", snmp_client.error);
snmp_tool_freeall(&snmptoolctx);
exit(1);
}
diff --git a/usr.sbin/bsnmpd/tools/libbsnmptools/bsnmptools.c b/usr.sbin/bsnmpd/tools/libbsnmptools/bsnmptools.c
index fb09e1ac785e..b4613763fff5 100644
--- a/usr.sbin/bsnmpd/tools/libbsnmptools/bsnmptools.c
+++ b/usr.sbin/bsnmpd/tools/libbsnmptools/bsnmptools.c
@@ -790,15 +790,6 @@ parse_server(char *opt_arg)
if (snmp_parse_server(&snmp_client, opt_arg) < 0)
return (-1);
- if (snmp_client.trans > SNMP_TRANS_UDP && snmp_client.chost == NULL) {
- if ((snmp_client.chost = malloc(strlen(SNMP_DEFAULT_LOCAL) + 1))
- == NULL) {
- syslog(LOG_ERR, "malloc() failed: %s", strerror(errno));
- return (-1);
- }
- strcpy(snmp_client.chost, SNMP_DEFAULT_LOCAL);
- }
-
return (2);
}
diff --git a/usr.sbin/bsnmpd/tools/libbsnmptools/bsnmptools.h b/usr.sbin/bsnmpd/tools/libbsnmptools/bsnmptools.h
index 2874f311fbd0..54a087491a4f 100644
--- a/usr.sbin/bsnmpd/tools/libbsnmptools/bsnmptools.h
+++ b/usr.sbin/bsnmpd/tools/libbsnmptools/bsnmptools.h
@@ -43,7 +43,6 @@
#define MAX_BUFF_SIZE (ASN_MAXOCTETSTRING + 50)
#define SNMP_DEFS_DIR "/usr/share/snmp/defs/"
-#define SNMP_DEFAULT_LOCAL "/var/run/snmpd.sock"
#define SNMP_MAX_REPETITIONS 10
diff --git a/usr.sbin/certctl/certctl.8 b/usr.sbin/certctl/certctl.8
index 286072c1b4d6..7e49bb89e2ac 100644
--- a/usr.sbin/certctl/certctl.8
+++ b/usr.sbin/certctl/certctl.8
@@ -24,7 +24,7 @@
.\" IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd October 10, 2023
+.Dd July 17, 2025
.Dt CERTCTL 8
.Os
.Sh NAME
@@ -38,15 +38,15 @@
.Op Fl v
.Ic untrusted
.Nm
-.Op Fl nUv
+.Op Fl cnUv
.Op Fl D Ar destdir
.Op Fl M Ar metalog
.Ic rehash
.Nm
-.Op Fl nv
+.Op Fl cnv
.Ic untrust Ar file
.Nm
-.Op Fl nv
+.Op Fl cnv
.Ic trust Ar file
.Sh DESCRIPTION
The
@@ -56,6 +56,8 @@ applications that use OpenSSL.
.Pp
Flags:
.Bl -tag -width 4n
+.It Fl c
+Copy certificates instead of linking to them.
.It Fl D Ar destdir
Specify the DESTDIR (overriding values from the environment).
.It Fl d Ar distbase
diff --git a/usr.sbin/certctl/certctl.sh b/usr.sbin/certctl/certctl.sh
index 458f5c53682f..2bde651de126 100755
--- a/usr.sbin/certctl/certctl.sh
+++ b/usr.sbin/certctl/certctl.sh
@@ -36,6 +36,7 @@ set -u
############################################################ GLOBALS
SCRIPTNAME="${0##*/}"
+LINK=-lrs
ERRORS=0
NOOP=false
UNPRIV=false
@@ -110,7 +111,6 @@ create_trusted()
{
local hash certhash otherfile otherhash
local suffix
- local link=${2:+-lrs}
hash=$(do_hash "$1") || return
certhash=$(openssl x509 -sha1 -in "$1" -noout -fingerprint)
@@ -130,7 +130,7 @@ create_trusted()
done
suffix=$(get_decimal "$CERTDESTDIR" "$hash")
verbose "Adding $hash.$suffix to trust store"
- perform install ${INSTALLFLAGS} -m 0444 ${link} \
+ perform install ${INSTALLFLAGS} -m 0444 ${LINK} \
"$(realpath "$1")" "$CERTDESTDIR/$hash.$suffix"
}
@@ -159,7 +159,6 @@ resolve_certname()
create_untrusted()
{
local srcfile filename
- local link=${2:+-lrs}
set -- $(resolve_certname "$1")
srcfile=$1
@@ -170,7 +169,7 @@ create_untrusted()
fi
verbose "Adding $filename to untrusted list"
- perform install ${INSTALLFLAGS} -m 0444 ${link} \
+ perform install ${INSTALLFLAGS} -m 0444 ${LINK} \
"$srcfile" "$UNTRUSTDESTDIR/$filename"
}
@@ -190,7 +189,7 @@ do_scan()
0)
;;
1)
- "$CFUNC" "$CFILE" link
+ "$CFUNC" "$CFILE"
;;
*)
verbose "Multiple certificates found, splitting..."
@@ -303,19 +302,20 @@ usage()
echo " List trusted certificates"
echo " $SCRIPTNAME [-v] untrusted"
echo " List untrusted certificates"
- echo " $SCRIPTNAME [-nUv] [-D <destdir>] [-d <distbase>] [-M <metalog>] rehash"
- echo " Generate hash links for all certificates"
- echo " $SCRIPTNAME [-nv] untrust <file>"
+ echo " $SCRIPTNAME [-cnUv] [-D <destdir>] [-d <distbase>] [-M <metalog>] rehash"
+ echo " Rehash all trusted and untrusted certificates"
+ echo " $SCRIPTNAME [-cnv] untrust <file>"
echo " Add <file> to the list of untrusted certificates"
- echo " $SCRIPTNAME [-nv] trust <file>"
+ echo " $SCRIPTNAME [-cnv] trust <file>"
echo " Remove <file> from the list of untrusted certificates"
exit 64
}
############################################################ MAIN
-while getopts D:d:M:nUv flag; do
+while getopts cD:d:M:nUv flag; do
case "$flag" in
+ c) LINK=-c ;;
D) DESTDIR=${OPTARG} ;;
d) DISTBASE=${OPTARG} ;;
M) METALOG=${OPTARG} ;;
@@ -334,7 +334,7 @@ fi
: ${METALOG:=${DESTDIR}/METALOG}
INSTALLFLAGS=
if "$UNPRIV" ; then
- INSTALLFLAGS="-U -M ${METALOG} -D ${DESTDIR} -o root -g wheel"
+ INSTALLFLAGS="-U -M ${METALOG} -D ${DESTDIR:-/} -o root -g wheel"
fi
: ${LOCALBASE:=$(sysctl -n user.localbase)}
: ${TRUSTPATH:=${DESTDIR}${DISTBASE}/usr/share/certs/trusted:${DESTDIR}${LOCALBASE}/share/certs:${DESTDIR}${LOCALBASE}/etc/ssl/certs}
diff --git a/usr.sbin/efitable/efitable.8 b/usr.sbin/efitable/efitable.8
index d1f4cedcdea8..bb8a9cc3d0e1 100644
--- a/usr.sbin/efitable/efitable.8
+++ b/usr.sbin/efitable/efitable.8
@@ -22,7 +22,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd June 10, 2021
+.Dd July 16, 2025
.Dt EFITABLE 8
.Os
.Sh NAME
@@ -45,7 +45,7 @@ Generate output via
.Xr libxo 3
in a selection of different human and machine readable formats.
See
-.Xr xo_parse_args 3
+.Xr xo_options 7
for details on command line arguments.
.It Fl t Ar name Fl -table Ar name
Specify the name of the table to print.
diff --git a/usr.sbin/fwget/Makefile b/usr.sbin/fwget/Makefile
index 1cdf0f18230d..4c934aee3413 100644
--- a/usr.sbin/fwget/Makefile
+++ b/usr.sbin/fwget/Makefile
@@ -2,6 +2,6 @@ PACKAGE= fwget
SCRIPTS= fwget
MAN= fwget.8
-SUBDIR= pci
+SUBDIR= pci usb
.include <bsd.prog.mk>
diff --git a/usr.sbin/fwget/fwget.8 b/usr.sbin/fwget/fwget.8
index 7b8b606cc591..86e304775e2d 100644
--- a/usr.sbin/fwget/fwget.8
+++ b/usr.sbin/fwget/fwget.8
@@ -23,7 +23,7 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd June 27, 2024
+.Dd July 7, 2025
.Dt FWGET 8
.Os
.Sh NAME
@@ -47,7 +47,11 @@ Dry run, only show needed packages
.It Fl v
Be more verbose
.It Ar subsystem
-Hardware subsystem, default pci
+Hardware subsystem(s), default is all supported subsystems.
+Space separated hardware subsystems, accepts
+.Cm pci
+and
+.Cm usb
.El
.Sh SEE ALSO
.Xr firmware 9
@@ -64,4 +68,8 @@ utility and this manual page were written by
.An Emmanuel Vadot Aq Mt manu@FreeBSD.org
for Beckhoff Automation GmbH & Co\. KG.
.Sh CAVEATS
-This utility currently only supports the pci subsystem.
+This utility currently only supports the
+.Xr pci 4
+and
+.Xr usb 4
+subsystems.
diff --git a/usr.sbin/fwget/fwget.sh b/usr.sbin/fwget/fwget.sh
index 138a2a26bfb1..de1e6fa51f0f 100755
--- a/usr.sbin/fwget/fwget.sh
+++ b/usr.sbin/fwget/fwget.sh
@@ -35,7 +35,7 @@ usage()
Usage: $(basename "$0") [options] [subsystem]
Supported subsystems
- pci
+ pci, usb
Options:
-n -- Do not install packages, only print the results
@@ -100,9 +100,9 @@ done
shift $(($OPTIND - 1))
subsystems="$@"
-# Default searching PCI subsystem
+# Default searching PCI and USB subsystem
if [ -z "${subsystems}" ]; then
- subsystems="pci"
+ subsystems="pci usb"
fi
# Fail early on unsupported subsystem
diff --git a/usr.sbin/fwget/usb/Makefile b/usr.sbin/fwget/usb/Makefile
new file mode 100644
index 000000000000..315e9c743cc8
--- /dev/null
+++ b/usr.sbin/fwget/usb/Makefile
@@ -0,0 +1,10 @@
+PACKAGE= fwget
+
+SCRIPTS=usb \
+ usb_ralink
+
+BINDIR= ${LIBEXECDIR}/fwget
+
+MAN=
+
+.include <bsd.prog.mk>
diff --git a/usr.sbin/fwget/usb/usb b/usr.sbin/fwget/usb/usb
new file mode 100755
index 000000000000..fef6bc76ba89
--- /dev/null
+++ b/usr.sbin/fwget/usb/usb
@@ -0,0 +1,43 @@
+#
+# Copyright 2023 Beckhoff Automation GmbH & Co. KG
+# Copyright 2023 Bjoern A. Zeeb
+# Copyright 2025 Jesper Schmitz Mouridsen
+
+# SPDX-License-Identifier: BSD-2-Clause
+
+
+usb_get_vendor()
+{
+ local hexvendor=$(echo $1 | sed 's/.*idVendor=\(0x[0-9a-z]*\).*/\1/')
+ case "${hexvendor}" in
+ 0x148f) echo "ralink" ;;
+ esac
+}
+
+usb_get_device()
+{
+ local hexdevice=$(echo $1 | sed 's/.*idProduct=\(0x[0-9a-z]*\).*/\1/')
+ echo "${hexdevice}"
+
+}
+
+usb_search_packages()
+{
+ local IFS
+
+ oldifs=$IFS
+ IFS=$'\n'
+ for fulldevice in $(usbconfig -l dump_device_desc); do
+ vendor=$(usb_get_vendor "${fulldevice}")
+ if [ -z "${vendor}" ]; then
+ continue
+ fi
+ device=$(usb_get_device "${fulldevice}")
+ log_verbose "Trying to match device ${device} and vendor ${vendor} with usb_${vendor}"
+ if [ -f ${LIBEXEC_PATH}/usb_${vendor} ]; then
+ . ${LIBEXEC_PATH}/usb_${vendor}
+ usb_${vendor} ${device}
+ fi
+ done
+ IFS=${oldifs}
+}
diff --git a/usr.sbin/fwget/usb/usb_ralink b/usr.sbin/fwget/usb/usb_ralink
new file mode 100755
index 000000000000..8d3135063011
--- /dev/null
+++ b/usr.sbin/fwget/usb/usb_ralink
@@ -0,0 +1,12 @@
+#
+# Copyright (c) 2025 Jesper Schmitz Mouridsen
+#
+# SPDX-License-Identifier: BSD-2-Clause
+
+usb_ralink()
+{
+
+ case "$1" in
+ 0x7601) addpkg "wifi-firmware-mt7601u-kmod"; return 1 ;;
+ esac
+}
diff --git a/usr.sbin/gstat/gstat.8 b/usr.sbin/gstat/gstat.8
index 2975a93c7fef..e882aa75b8d7 100644
--- a/usr.sbin/gstat/gstat.8
+++ b/usr.sbin/gstat/gstat.8
@@ -124,7 +124,7 @@ Quit
.Ex -std
.Sh EXAMPLES
To filter the output to only physical disks named ada0 through ada4:
-.Dl # gstat -f ada0[0-4]$
+.Dl # gstat -f ada[0-4]$
.Sh SEE ALSO
.Xr systat 1 ,
.Xr geom 4 ,
diff --git a/usr.sbin/inetd/inetd.conf b/usr.sbin/inetd/inetd.conf
index 40f1e1285af6..a8359ea793f5 100644
--- a/usr.sbin/inetd/inetd.conf
+++ b/usr.sbin/inetd/inetd.conf
@@ -7,8 +7,8 @@
#
#ftp stream tcp nowait root /usr/libexec/ftpd ftpd -l
#ftp stream tcp6 nowait root /usr/libexec/ftpd ftpd -l
-#ssh stream tcp nowait root /usr/sbin/sshd sshd -i -4
-#ssh stream tcp6 nowait root /usr/sbin/sshd sshd -i -6
+#ssh stream tcp nowait root /usr/sbin/sshd sshd -i
+#ssh stream tcp6 nowait root /usr/sbin/sshd sshd -i
#telnet stream tcp nowait root /usr/local/libexec/telnetd telnetd
#telnet stream tcp6 nowait root /usr/local/libexec/telnetd telnetd
#shell stream tcp nowait root /usr/local/sbin/rshd rshd
diff --git a/usr.sbin/lastlogin/lastlogin.8 b/usr.sbin/lastlogin/lastlogin.8
index 3b2d47fdaf76..9fd5c88d02cd 100644
--- a/usr.sbin/lastlogin/lastlogin.8
+++ b/usr.sbin/lastlogin/lastlogin.8
@@ -73,7 +73,7 @@ Generate output via
.Xr libxo 3
in a selection of different human and machine readable formats.
See
-.Xr xo_parse_args 3
+.Xr xo_options 7
for details on command line arguments.
.It Fl f Ar file
Open last login database
@@ -93,7 +93,7 @@ last login database
.Xr last 1 ,
.Xr getutxent 3 ,
.Xr libxo 3 ,
-.Xr xo_parse_args 3 ,
+.Xr xo_options 7 ,
.Xr ac 8
.Sh AUTHORS
.An -nosplit
diff --git a/usr.sbin/makefs/ffs.c b/usr.sbin/makefs/ffs.c
index 4efcd20ad91a..c0fcadf11fba 100644
--- a/usr.sbin/makefs/ffs.c
+++ b/usr.sbin/makefs/ffs.c
@@ -1056,7 +1056,7 @@ ffs_make_dirbuf(dirbuf_t *dbuf, const char *name, fsnode *node, int needswap)
reclen = DIRSIZ_SWAP(0, &de, needswap);
de.d_reclen = ufs_rw16(reclen, needswap);
- dp = (struct direct *)(dbuf->buf + dbuf->cur);
+ dp = dbuf->buf == NULL ? NULL : (struct direct *)(dbuf->buf + dbuf->cur);
llen = 0;
if (dp != NULL)
llen = DIRSIZ_SWAP(0, dp, needswap);
diff --git a/usr.sbin/makefs/tests/makefs_msdos_tests.sh b/usr.sbin/makefs/tests/makefs_msdos_tests.sh
index b36b43b3abf6..fb94429b477b 100644
--- a/usr.sbin/makefs/tests/makefs_msdos_tests.sh
+++ b/usr.sbin/makefs/tests/makefs_msdos_tests.sh
@@ -4,7 +4,7 @@
# Copyright (c) 2025 The FreeBSD Foundation
#
# This software was developed by Klara, Inc.
-# under sponsorship from the FreeBSD Foundation and the Sovereign Tech Agency.
+# under sponsorship from the FreeBSD Foundation.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
diff --git a/usr.sbin/sesutil/sesutil.8 b/usr.sbin/sesutil/sesutil.8
index 664dcab593e9..d4960b3ec6bf 100644
--- a/usr.sbin/sesutil/sesutil.8
+++ b/usr.sbin/sesutil/sesutil.8
@@ -22,7 +22,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd July 5, 2022
+.Dd July 16, 2025
.Dt SESUTIL 8
.Os
.Sh NAME
@@ -129,7 +129,7 @@ Generate output via
.Xr libxo 3
in a selection of different human and machine readable formats.
See
-.Xr xo_parse_args 3
+.Xr xo_options 7
.El
.Sh EXAMPLES
Turn off all locate LEDs:
@@ -146,7 +146,7 @@ Turn on the fault LED for a drive bay not associated with a device:
.Dl Nm Cm fault -u /dev/ses2 7 on
.Sh SEE ALSO
.Xr libxo 3 ,
-.Xr xo_parse_args 3 ,
+.Xr xo_options 7 ,
.Xr ses 4
.Sh HISTORY
The