aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/cross-bootstrap-tools.yml2
-rw-r--r--ObsoleteFiles.inc3
-rw-r--r--bin/cat/cat.c16
-rw-r--r--cddl/usr.sbin/zfsd/case_file.cc98
-rw-r--r--cddl/usr.sbin/zfsd/case_file.h22
-rw-r--r--cddl/usr.sbin/zfsd/tests/zfsd_unittest.cc3
-rw-r--r--cddl/usr.sbin/zfsd/vdev.h2
-rw-r--r--cddl/usr.sbin/zfsd/zfsd.858
-rw-r--r--contrib/llvm-project/clang/lib/CodeGen/CGBuiltin.cpp25
-rw-r--r--contrib/llvm-project/clang/lib/CodeGen/CGCall.cpp5
-rw-r--r--contrib/llvm-project/clang/lib/CodeGen/CGObjCGNU.cpp34
-rw-r--r--contrib/llvm-project/clang/lib/CodeGen/CodeGenModule.h3
-rw-r--r--contrib/llvm-project/clang/lib/CodeGen/CoverageMappingGen.cpp11
-rw-r--r--contrib/llvm-project/clang/lib/CodeGen/MicrosoftCXXABI.cpp12
-rw-r--r--contrib/llvm-project/clang/lib/Format/ContinuationIndenter.cpp8
-rw-r--r--contrib/llvm-project/clang/lib/Format/TokenAnnotator.cpp10
-rw-r--r--contrib/llvm-project/clang/lib/Format/UnwrappedLineParser.cpp40
-rw-r--r--contrib/llvm-project/clang/lib/StaticAnalyzer/Checkers/Taint.cpp14
-rw-r--r--contrib/llvm-project/clang/lib/StaticAnalyzer/Checkers/cert/InvalidPtrChecker.cpp6
-rw-r--r--contrib/llvm-project/libcxx/modules/std.compat/cstdlib.inc2
-rw-r--r--contrib/llvm-project/lld/ELF/Writer.cpp4
-rw-r--r--contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/LoadStoreOpt.h20
-rw-r--r--contrib/llvm-project/llvm/lib/CodeGen/CodeGenPrepare.cpp2
-rw-r--r--contrib/llvm-project/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp4
-rw-r--r--contrib/llvm-project/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp4
-rw-r--r--contrib/llvm-project/llvm/lib/CodeGen/GlobalISel/LoadStoreOpt.cpp48
-rw-r--r--contrib/llvm-project/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp9
-rw-r--r--contrib/llvm-project/llvm/lib/Target/AArch64/AArch64InstrInfo.td10
-rw-r--r--contrib/llvm-project/llvm/lib/Target/AMDGPU/SIMemoryLegalizer.cpp10
-rw-r--r--contrib/llvm-project/llvm/lib/Target/RISCV/RISCVISelLowering.cpp2
-rw-r--r--contrib/llvm-project/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp7
-rw-r--r--contrib/llvm-project/llvm/lib/Target/X86/X86ISelLowering.cpp29
-rw-r--r--contrib/llvm-project/llvm/lib/Target/X86/X86Subtarget.h3
-rw-r--r--contrib/llvm-project/llvm/lib/TargetParser/Host.cpp5
-rw-r--r--contrib/llvm-project/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp2
-rw-r--r--contrib/llvm-project/llvm/lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp3
-rw-r--r--contrib/llvm-project/openmp/runtime/src/kmp_settings.cpp2
-rw-r--r--contrib/llvm-project/openmp/runtime/src/z_Linux_util.cpp6
-rwxr-xr-xcontrib/netbsd-tests/fs/tmpfs/t_times.sh2
-rw-r--r--etc/mtree/BSD.var.dist2
-rw-r--r--lib/clang/include/VCSVersion.inc6
-rw-r--r--lib/clang/include/clang/Basic/Version.inc6
-rw-r--r--lib/clang/include/lld/Common/Version.inc2
-rw-r--r--lib/clang/include/lldb/Version/Version.inc6
-rw-r--r--lib/clang/include/llvm/Config/AsmParsers.def3
-rw-r--r--lib/clang/include/llvm/Config/AsmPrinters.def3
-rw-r--r--lib/clang/include/llvm/Config/Disassemblers.def3
-rw-r--r--lib/clang/include/llvm/Config/Targets.def3
-rw-r--r--lib/clang/include/llvm/Config/config.h4
-rw-r--r--lib/clang/include/llvm/Config/llvm-config.h8
-rw-r--r--lib/clang/include/llvm/Support/VCSRevision.h2
-rw-r--r--lib/geom/eli/geli.846
-rw-r--r--lib/libc/gen/dlopen.38
-rw-r--r--lib/libc/stdlib/cxa_thread_atexit_impl.c2
-rw-r--r--lib/libc/sys/clock_gettime.240
-rw-r--r--lib/libpfctl/libpfctl.c2
-rw-r--r--lib/libpfctl/libpfctl.h2
-rw-r--r--libexec/phttpget/phttpget.811
-rwxr-xr-xlibexec/rc/rc.d/devmatch1
-rw-r--r--libexec/rtld-elf/rtld.124
-rw-r--r--libexec/rtld-elf/rtld.c35
-rw-r--r--libexec/tftpd/tests/functional.c1
-rw-r--r--libexec/tftpd/tftp-file.h1
-rw-r--r--libexec/tftpd/tftp-io.c11
-rw-r--r--libexec/tftpd/tftp-io.h1
-rw-r--r--libexec/tftpd/tftp-options.h1
-rw-r--r--libexec/tftpd/tftp-transfer.h1
-rw-r--r--libexec/tftpd/tftp-utils.c2
-rw-r--r--libexec/tftpd/tftp-utils.h3
-rw-r--r--libexec/tftpd/tftpd.86
-rw-r--r--libexec/tftpd/tftpd.c56
-rw-r--r--release/Makefile.mirrors14
-rw-r--r--release/Makefile.vm13
-rwxr-xr-xrelease/scripts/mk-vmimage.sh3
-rw-r--r--release/tools/azure.conf2
-rw-r--r--release/tools/ec2.conf5
-rw-r--r--release/tools/gce.conf10
-rw-r--r--release/tools/oci.conf5
-rw-r--r--release/tools/openstack.conf2
-rw-r--r--release/tools/vagrant-virtualbox.conf1
-rw-r--r--release/tools/vagrant-vmware.conf1
-rw-r--r--release/tools/vmimage.subr23
-rw-r--r--sbin/newfs/newfs.86
-rw-r--r--sbin/newfs/newfs.c3
-rw-r--r--share/man/man4/Makefile1
-rw-r--r--share/man/man4/nfslockd.445
-rw-r--r--share/man/man4/smsc.412
-rw-r--r--share/man/man4/vmm.415
-rw-r--r--share/man/man9/Makefile3
-rw-r--r--share/man/man9/bitset.939
-rw-r--r--share/man/man9/cpuset.915
-rw-r--r--share/misc/bsd-family-tree25
-rw-r--r--sys/amd64/amd64/sys_machdep.c52
-rw-r--r--sys/arm/allwinner/a10_codec.c1
-rw-r--r--sys/arm/arm/sys_machdep.c27
-rw-r--r--sys/arm/broadcom/bcm2835/bcm2835_audio.c1
-rw-r--r--sys/arm/freescale/imx/imx6_ssi.c1
-rw-r--r--sys/arm/freescale/vybrid/vf_sai.c1
-rw-r--r--sys/arm/include/armreg.h2
-rw-r--r--sys/compat/linuxkpi/common/include/asm/set_memory.h21
-rw-r--r--sys/compat/linuxkpi/common/include/linux/io.h9
-rw-r--r--sys/conf/files1
-rw-r--r--sys/dev/etherswitch/ip17x/ip17x.c4
-rw-r--r--sys/dev/etherswitch/ukswitch/ukswitch.c4
-rw-r--r--sys/dev/iicbus/if_ic.c4
-rw-r--r--sys/dev/mlx5/mlx5_en/mlx5_en_main.c3
-rw-r--r--sys/dev/sound/chip.h47
-rw-r--r--sys/dev/sound/pci/atiixp.c4
-rw-r--r--sys/dev/sound/pci/csa.c1
-rw-r--r--sys/dev/sound/pci/csamidi.c1
-rw-r--r--sys/dev/sound/pci/csapcm.c1
-rw-r--r--sys/dev/sound/pci/emu10kx-midi.c1
-rw-r--r--sys/dev/sound/pci/emu10kx-pcm.c1
-rw-r--r--sys/dev/sound/pci/emu10kx.c3
-rw-r--r--sys/dev/sound/pci/hda/hdaa.c11
-rw-r--r--sys/dev/sound/pci/hda/hdaa_patches.c5
-rw-r--r--sys/dev/sound/pci/hda/hdac.h3
-rw-r--r--sys/dev/sound/pci/hdspe-pcm.c1
-rw-r--r--sys/dev/sound/pci/hdspe.c1
-rw-r--r--sys/dev/sound/pci/ich.c4
-rw-r--r--sys/dev/sound/pci/maestro3.c4
-rw-r--r--sys/dev/sound/pci/solo.c1
-rw-r--r--sys/dev/sound/pcm/channel.c201
-rw-r--r--sys/dev/sound/pcm/channel.h16
-rw-r--r--sys/dev/sound/pcm/dsp.c200
-rw-r--r--sys/dev/sound/pcm/dsp.h2
-rw-r--r--sys/dev/sound/pcm/feeder.c5
-rw-r--r--sys/dev/sound/pcm/feeder_format.c15
-rw-r--r--sys/dev/sound/pcm/feeder_matrix.c4
-rw-r--r--sys/dev/sound/pcm/feeder_volume.c2
-rw-r--r--sys/dev/sound/pcm/mixer.c44
-rw-r--r--sys/dev/sound/pcm/sndstat.c8
-rw-r--r--sys/dev/sound/pcm/sound.c481
-rw-r--r--sys/dev/sound/pcm/sound.h104
-rw-r--r--sys/dev/sound/pcm/vchan.c206
-rw-r--r--sys/dev/sound/pcm/vchan.h7
-rw-r--r--sys/dev/sound/unit.c188
-rw-r--r--sys/dev/sound/unit.h52
-rw-r--r--sys/dev/sound/usb/uaudio.c1
-rw-r--r--sys/dev/sound/usb/uaudio_pcm.c1
-rw-r--r--sys/dev/sound/version.h42
-rw-r--r--sys/dev/usb/net/if_smsc.c4
-rw-r--r--sys/dev/wg/if_wg.c3
-rw-r--r--sys/fs/nfs/nfs_var.h2
-rw-r--r--sys/fs/nfsserver/nfs_nfsdport.c12
-rw-r--r--sys/fs/nfsserver/nfs_nfsdserv.c11
-rw-r--r--sys/geom/eli/g_eli.c4
-rw-r--r--sys/i386/i386/sys_machdep.c34
-rw-r--r--sys/kern/kern_boottrace.c2
-rw-r--r--sys/kern/kern_cpuset.c40
-rw-r--r--sys/kern/kern_descrip.c6
-rw-r--r--sys/kern/kern_devctl.c6
-rw-r--r--sys/kern/kern_exec.c2
-rw-r--r--sys/kern/kern_ktrace.c43
-rw-r--r--sys/kern/kern_procctl.c4
-rw-r--r--sys/kern/kern_sig.c20
-rw-r--r--sys/kern/kern_sysctl.c6
-rw-r--r--sys/kern/kern_umtx.c30
-rw-r--r--sys/kern/sched_4bsd.c12
-rw-r--r--sys/kern/sched_ule.c10
-rw-r--r--sys/kern/subr_intr.c22
-rw-r--r--sys/kern/subr_syscall.c11
-rw-r--r--sys/kern/sys_capability.c16
-rw-r--r--sys/kern/uipc_shm.c42
-rw-r--r--sys/kern/uipc_socket.c9
-rw-r--r--sys/kern/uipc_syscalls.c29
-rw-r--r--sys/kern/vfs_cache.c2
-rw-r--r--sys/kern/vfs_lookup.c101
-rw-r--r--sys/kern/vfs_vnops.c16
-rw-r--r--sys/modules/sound/sound/Makefile2
-rw-r--r--sys/net/if.c3
-rw-r--r--sys/net/if_bridge.c48
-rw-r--r--sys/net/if_disc.c2
-rw-r--r--sys/net/if_gif.c3
-rw-r--r--sys/net/if_gre.c3
-rw-r--r--sys/net/if_me.c3
-rw-r--r--sys/net/if_tuntap.c2
-rw-r--r--sys/netgraph/ng_iface.c2
-rw-r--r--sys/netgraph/ng_pipe.c73
-rw-r--r--sys/netinet/in_fib_dxr.c89
-rw-r--r--sys/netinet/in_pcb.c4
-rw-r--r--sys/netinet/ip_fw.h2
-rw-r--r--sys/netinet6/in6.h8
-rw-r--r--sys/netpfil/pf/pf.c4
-rw-r--r--sys/sys/bitset.h14
-rw-r--r--sys/sys/capsicum.h7
-rw-r--r--sys/sys/cpuset.h1
-rw-r--r--sys/sys/domainset.h1
-rw-r--r--sys/sys/ktrace.h32
-rw-r--r--sys/sys/namei.h6
-rw-r--r--sys/sys/sdt.h37
-rw-r--r--sys/sys/soundcard.h6
-rw-r--r--sys/x86/include/apicvar.h7
-rw-r--r--tests/sys/kern/Makefile2
-rw-r--r--tests/sys/kern/ktrace_test.c522
-rw-r--r--tools/regression/iscsi/initiator-instructions.txt6
-rw-r--r--usr.bin/ctags/C.c76
-rw-r--r--usr.bin/ctags/ctags.c22
-rw-r--r--usr.bin/ctags/ctags.h11
-rw-r--r--usr.bin/ctags/fortran.c12
-rw-r--r--usr.bin/ctags/lisp.c8
-rw-r--r--usr.bin/ctags/tree.c2
-rw-r--r--usr.bin/ctags/yacc.c10
-rw-r--r--usr.bin/expand/expand.18
-rw-r--r--usr.bin/kdump/kdump.c65
-rw-r--r--usr.bin/ktrace/ktrace.122
-rw-r--r--usr.bin/ktrace/ktrace.h7
-rw-r--r--usr.bin/locate/locate/locate.rc2
-rw-r--r--usr.bin/locate/locate/updatedb.sh2
-rw-r--r--usr.bin/split/split.c4
-rw-r--r--usr.sbin/adduser/adduser.sh43
-rw-r--r--usr.sbin/bhyve/gdb.c1
-rw-r--r--usr.sbin/freebsd-update/freebsd-update.sh8
-rw-r--r--usr.sbin/pw/pw.c13
-rw-r--r--usr.sbin/pw/pw.h22
-rw-r--r--usr.sbin/pw/pw_group.c35
-rw-r--r--usr.sbin/pw/pw_user.c48
-rwxr-xr-xusr.sbin/pw/tests/pw_useradd_test.sh17
-rw-r--r--usr.sbin/rpc.lockd/lockd.c3
-rw-r--r--usr.sbin/rpc.lockd/rpc.lockd.85
220 files changed, 2710 insertions, 2014 deletions
diff --git a/.github/workflows/cross-bootstrap-tools.yml b/.github/workflows/cross-bootstrap-tools.yml
index 0aa1d9a35c1e..8a714788cce7 100644
--- a/.github/workflows/cross-bootstrap-tools.yml
+++ b/.github/workflows/cross-bootstrap-tools.yml
@@ -30,7 +30,7 @@ jobs:
pkgs: bmake libarchive-dev clang-14 lld-14
- os: macos-latest
compiler: clang-13
- cross-bindir: /usr/local/opt/llvm@13/bin
+ cross-bindir: /opt/homebrew/opt/llvm@13/bin
pkgs: bmake libarchive llvm@13
- target_arch: amd64
target: amd64
diff --git a/ObsoleteFiles.inc b/ObsoleteFiles.inc
index b5253c28d42c..b99bd4f890e5 100644
--- a/ObsoleteFiles.inc
+++ b/ObsoleteFiles.inc
@@ -51,6 +51,9 @@
# xargs -n1 | sort | uniq -d;
# done
+# 20240509: Remove remnants of portsnap(8)
+OLD_DIRS+=var/db/portsnap
+
# 20240419: new clang import which bumps version from 17 to 18
OLD_FILES+=usr/lib/clang/17/include/__clang_cuda_builtin_vars.h
OLD_FILES+=usr/lib/clang/17/include/__clang_cuda_cmath.h
diff --git a/bin/cat/cat.c b/bin/cat/cat.c
index 81ec5feec240..9d40a3f0fa35 100644
--- a/bin/cat/cat.c
+++ b/bin/cat/cat.c
@@ -139,7 +139,7 @@ init_casper_net(cap_channel_t *casper)
familylimit = AF_LOCAL;
cap_net_limit_name2addr_family(limit, &familylimit, 1);
- if (cap_net_limit(limit) < 0)
+ if (cap_net_limit(limit) != 0)
err(EXIT_FAILURE, "unable to apply limits");
}
#endif
@@ -212,7 +212,7 @@ main(int argc, char *argv[])
stdout_lock.l_start = 0;
stdout_lock.l_type = F_WRLCK;
stdout_lock.l_whence = SEEK_SET;
- if (fcntl(STDOUT_FILENO, F_SETLKW, &stdout_lock) == -1)
+ if (fcntl(STDOUT_FILENO, F_SETLKW, &stdout_lock) != 0)
err(EXIT_FAILURE, "stdout");
}
@@ -220,7 +220,7 @@ main(int argc, char *argv[])
caph_cache_catpages();
- if (caph_enter_casper() < 0)
+ if (caph_enter_casper() != 0)
err(EXIT_FAILURE, "capsicum");
if (bflag || eflag || nflag || sflag || tflag || vflag)
@@ -280,7 +280,7 @@ scanfiles(char *argv[], int cooked __unused)
#endif
} else {
#ifndef BOOTSTRAP_CAT
- if (in_kernel_copy(fd) == -1) {
+ if (in_kernel_copy(fd) != 0) {
if (errno == EINVAL || errno == EBADF ||
errno == EISDIR)
raw_cat(fd);
@@ -485,7 +485,7 @@ udom_open(const char *path, int flags)
errno = serrno;
return (-1);
}
- if (caph_rights_limit(fd, &rights) < 0) {
+ if (caph_rights_limit(fd, &rights) != 0) {
serrno = errno;
close(fd);
freeaddrinfo(res0);
@@ -514,12 +514,12 @@ udom_open(const char *path, int flags)
switch (flags & O_ACCMODE) {
case O_RDONLY:
cap_rights_clear(&rights, CAP_WRITE);
- if (shutdown(fd, SHUT_WR) == -1)
+ if (shutdown(fd, SHUT_WR) != 0)
warn(NULL);
break;
case O_WRONLY:
cap_rights_clear(&rights, CAP_READ);
- if (shutdown(fd, SHUT_RD) == -1)
+ if (shutdown(fd, SHUT_RD) != 0)
warn(NULL);
break;
default:
@@ -527,7 +527,7 @@ udom_open(const char *path, int flags)
}
cap_rights_clear(&rights, CAP_CONNECT, CAP_SHUTDOWN);
- if (caph_rights_limit(fd, &rights) < 0) {
+ if (caph_rights_limit(fd, &rights) != 0) {
serrno = errno;
close(fd);
errno = serrno;
diff --git a/cddl/usr.sbin/zfsd/case_file.cc b/cddl/usr.sbin/zfsd/case_file.cc
index 39f89fbbf7c8..f9fd84da7277 100644
--- a/cddl/usr.sbin/zfsd/case_file.cc
+++ b/cddl/usr.sbin/zfsd/case_file.cc
@@ -53,6 +53,7 @@
#include <syslog.h>
#include <unistd.h>
+#include <libzutil.h>
#include <libzfs.h>
#include <list>
@@ -91,7 +92,6 @@ using DevdCtl::ParseException;
CaseFileList CaseFile::s_activeCases;
const string CaseFile::s_caseFilePath = "/var/db/zfsd/cases";
-const timeval CaseFile::s_removeGracePeriod = { 60 /*sec*/, 0 /*usec*/};
//- CaseFile Static Public Methods ---------------------------------------------
CaseFile *
@@ -255,6 +255,7 @@ CaseFile::RefreshVdevState()
m_vdevState = vd.State();
m_vdevPhysPath = vd.PhysicalPath();
+ m_vdevName = vd.Name(casePool, false);
return (true);
}
@@ -610,15 +611,55 @@ CaseFile::ActivateSpare() {
return (Replace(vdev_type, devPath, /*isspare*/true));
}
+/* Does the argument event refer to a checksum error? */
+static bool
+IsChecksumEvent(const Event* const event)
+{
+ return ("ereport.fs.zfs.checksum" == event->Value("type"));
+}
+
+/* Does the argument event refer to an IO error? */
+static bool
+IsIOEvent(const Event* const event)
+{
+ return ("ereport.fs.zfs.io" == event->Value("type"));
+}
+
+/* Does the argument event refer to an IO delay? */
+static bool
+IsDelayEvent(const Event* const event)
+{
+ return ("ereport.fs.zfs.delay" == event->Value("type"));
+}
+
void
CaseFile::RegisterCallout(const Event &event)
{
timeval now, countdown, elapsed, timestamp, zero, remaining;
+ /**
+ * The time ZFSD waits before promoting a tentative event
+ * into a permanent event.
+ */
+ int sec = -1;
+ if (IsChecksumEvent(&event))
+ sec = CaseFile::GetVdevProp(VDEV_PROP_CHECKSUM_T);
+ else if (IsIOEvent(&event))
+ sec = CaseFile::GetVdevProp(VDEV_PROP_IO_T);
+ else if (IsDelayEvent(&event))
+ sec = CaseFile::GetVdevProp(VDEV_PROP_SLOW_IO_T);
+
+ if (sec == -1)
+ sec = 60; /* default */
+
+ timeval removeGracePeriod = {
+ sec, /*sec*/
+ 0 /*usec*/
+ };
gettimeofday(&now, 0);
timestamp = event.GetTimestamp();
timersub(&now, &timestamp, &elapsed);
- timersub(&s_removeGracePeriod, &elapsed, &countdown);
+ timersub(&removeGracePeriod, &elapsed, &countdown);
/*
* If countdown is <= zero, Reset the timer to the
* smallest positive time value instead
@@ -827,6 +868,10 @@ CaseFile::CaseFile(const Vdev &vdev)
guidString << m_poolGUID;
m_poolGUIDString = guidString.str();
+ ZpoolList zpl(ZpoolList::ZpoolByGUID, &m_poolGUID);
+ zpool_handle_t *zhp(zpl.empty() ? NULL : zpl.front());
+ m_vdevName = vdev.Name(zhp, false);
+
s_activeCases.push_back(this);
syslog(LOG_INFO, "Creating new CaseFile:\n");
@@ -1158,43 +1203,54 @@ CaseFile::Replace(const char* vdev_type, const char* path, bool isspare) {
return (retval);
}
-/* Does the argument event refer to a checksum error? */
-static bool
-IsChecksumEvent(const Event* const event)
+/* Lookup the vdev prop. Used for checksum, IO, or slow IO props */
+int
+CaseFile::GetVdevProp(vdev_prop_t vdev_prop) const
{
- return ("ereport.fs.zfs.checksum" == event->Value("type"));
-}
+ char val[ZFS_MAXPROPLEN];
+ zprop_source_t srctype;
+ DevdCtl::Guid poolGUID = PoolGUID();
+ ZpoolList zpl(ZpoolList::ZpoolByGUID, &poolGUID);
+ zpool_handle_t *zhp(zpl.empty() ? NULL : zpl.front());
-/* Does the argument event refer to an IO error? */
-static bool
-IsIOEvent(const Event* const event)
-{
- return ("ereport.fs.zfs.io" == event->Value("type"));
-}
+ char *prop_str = (char *) vdev_prop_to_name(vdev_prop);
+ if (zhp == NULL || zpool_get_vdev_prop(zhp, m_vdevName.c_str(),
+ vdev_prop, prop_str, val, sizeof (val), &srctype, B_FALSE) != 0)
+ return (-1);
-/* Does the argument event refer to an IO delay? */
-static bool
-IsDelayEvent(const Event* const event)
-{
- return ("ereport.fs.zfs.delay" == event->Value("type"));
+ /* we'll get "-" from libzfs for a prop that is not set */
+ if (zfs_isnumber(val) == B_FALSE)
+ return (-1);
+
+ return (atoi(val));
}
bool
CaseFile::ShouldDegrade() const
{
+ int checksum_n = GetVdevProp(VDEV_PROP_CHECKSUM_N);
+ if (checksum_n == -1)
+ checksum_n = DEFAULT_ZFS_DEGRADE_IO_COUNT;
return (std::count_if(m_events.begin(), m_events.end(),
- IsChecksumEvent) > ZFS_DEGRADE_IO_COUNT);
+ IsChecksumEvent) > checksum_n);
}
bool
CaseFile::ShouldFault() const
{
bool should_fault_for_io, should_fault_for_delay;
+ int io_n = GetVdevProp(VDEV_PROP_IO_N);
+ int slow_io_n = GetVdevProp(VDEV_PROP_SLOW_IO_N);
+
+ if (io_n == -1)
+ io_n = DEFAULT_ZFS_DEGRADE_IO_COUNT;
+ if (slow_io_n == -1)
+ slow_io_n = DEFAULT_ZFS_FAULT_SLOW_IO_COUNT;
should_fault_for_io = std::count_if(m_events.begin(), m_events.end(),
- IsIOEvent) > ZFS_DEGRADE_IO_COUNT;
+ IsIOEvent) > io_n;
should_fault_for_delay = std::count_if(m_events.begin(), m_events.end(),
- IsDelayEvent) > ZFS_FAULT_DELAY_COUNT;
+ IsDelayEvent) > slow_io_n;
return (should_fault_for_io || should_fault_for_delay);
}
diff --git a/cddl/usr.sbin/zfsd/case_file.h b/cddl/usr.sbin/zfsd/case_file.h
index 9566b1586ef5..199918c4fead 100644
--- a/cddl/usr.sbin/zfsd/case_file.h
+++ b/cddl/usr.sbin/zfsd/case_file.h
@@ -235,18 +235,27 @@ public:
*/
int IsSpare();
+ /**
+ * \brief Get case vdev's specified property
+ */
+ int GetVdevProp(vdev_prop_t) const;
+
protected:
enum {
+ /*
+ * Use these defaults if we can't get the corresponding vdev
+ * prop or if the prop is not set
+ */
/**
* The number of soft errors on a vdev required
* to transition a vdev from healthy to degraded
- * status.
+ * status
*/
- ZFS_DEGRADE_IO_COUNT = 50,
+ DEFAULT_ZFS_DEGRADE_IO_COUNT = 50,
/**
* The number of delay errors on a vdev required to fault it
*/
- ZFS_FAULT_DELAY_COUNT = 8,
+ DEFAULT_ZFS_FAULT_SLOW_IO_COUNT = 8,
};
static CalloutFunc_t OnGracePeriodEnded;
@@ -380,12 +389,6 @@ protected:
static const string s_caseFilePath;
/**
- * \brief The time ZFSD waits before promoting a tentative event
- * into a permanent event.
- */
- static const timeval s_removeGracePeriod;
-
- /**
* \brief A list of soft error events counted against the health of
* a vdev.
*/
@@ -404,6 +407,7 @@ protected:
string m_poolGUIDString;
string m_vdevGUIDString;
string m_vdevPhysPath;
+ string m_vdevName;
int m_is_spare;
/**
diff --git a/cddl/usr.sbin/zfsd/tests/zfsd_unittest.cc b/cddl/usr.sbin/zfsd/tests/zfsd_unittest.cc
index d76abb54c9ed..f1e925b0b4ef 100644
--- a/cddl/usr.sbin/zfsd/tests/zfsd_unittest.cc
+++ b/cddl/usr.sbin/zfsd/tests/zfsd_unittest.cc
@@ -134,6 +134,7 @@ public:
MOCK_CONST_METHOD0(PoolGUID, Guid());
MOCK_CONST_METHOD0(State, vdev_state());
MOCK_CONST_METHOD0(PhysicalPath, string());
+ MOCK_CONST_METHOD2(Name, string(zpool_handle_t * zhp, bool verbose));
};
MockVdev::MockVdev(nvlist_t *vdevConfig)
@@ -431,6 +432,8 @@ protected:
m_vdev = new MockVdev(m_vdevConfig);
ON_CALL(*m_vdev, GUID())
.WillByDefault(::testing::Return(Guid(123)));
+ ON_CALL(*m_vdev, Name(::testing::_, ::testing::_))
+ .WillByDefault(::testing::Return(string("/dev/da999")));
ON_CALL(*m_vdev, PoolGUID())
.WillByDefault(::testing::Return(Guid(456)));
ON_CALL(*m_vdev, State())
diff --git a/cddl/usr.sbin/zfsd/vdev.h b/cddl/usr.sbin/zfsd/vdev.h
index ace5d5a009fa..42278a3d7229 100644
--- a/cddl/usr.sbin/zfsd/vdev.h
+++ b/cddl/usr.sbin/zfsd/vdev.h
@@ -130,7 +130,7 @@ public:
nvlist_t *Config() const;
Vdev Parent();
Vdev RootVdev();
- std::string Name(zpool_handle_t *, bool verbose) const;
+ virtual std::string Name(zpool_handle_t *, bool verbose) const;
bool IsSpare();
bool IsAvailableSpare() const;
bool IsActiveSpare() const;
diff --git a/cddl/usr.sbin/zfsd/zfsd.8 b/cddl/usr.sbin/zfsd/zfsd.8
index 75a3333e6f9e..d6b0e1d4bd22 100644
--- a/cddl/usr.sbin/zfsd/zfsd.8
+++ b/cddl/usr.sbin/zfsd/zfsd.8
@@ -23,7 +23,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd April 18, 2020
+.Dd February 20, 2024
.Dt ZFSD 8
.Os
.Sh NAME
@@ -55,7 +55,7 @@ directly.
Instead, they control its behavior indirectly through zpool configuration.
There are two ways to influence
.Nm :
-assigning hotspares and setting pool properties.
+assigning hot spares and setting pool properties.
Currently, only the
.Em autoreplace
property has any effect.
@@ -69,7 +69,7 @@ will attempt to resolve the following types of fault:
.It device removal
When a leaf vdev disappears,
.Nm
-will activate any available hotspare.
+will activate any available hot spare.
.It device arrival
When a new GEOM device appears,
.Nm
@@ -77,40 +77,71 @@ will attempt to read its ZFS label, if any.
If it matches a previously removed vdev on an active pool,
.Nm
will online it.
-Once resilvering completes, any active hotspare will detach automatically.
+Once resilvering completes, any active hot spare will detach automatically.
.Pp
If the new device has no ZFS label but its physical path matches the
physical path of a previously removed vdev on an active pool, and that
pool has the autoreplace property set, then
.Nm
will replace the missing vdev with the newly arrived device.
-Once resilvering completes, any active hotspare will detach automatically.
+Once resilvering completes, any active hot spare will detach automatically.
.It vdev degrade or fault events
If a vdev becomes degraded or faulted,
.Nm
-will activate any available hotspare.
+will activate any available hot spare.
.It I/O errors
-If a leaf vdev generates more than 50 I/O errors in a 60 second period, then
+By default, if a leaf vdev generates more than 50 I/O errors in a 60 second
+period, then
+.Nm
+will mark that vdev as
+.Em FAULTED .
+ZFS will no longer issue any I/Os to it.
+.Nm
+will activate a hot spare if one is available. The defaults can be changed by
+setting the
+.Em io_n
+and/or
+.Em io_t
+vdev properties. See
+.Xr vdevprops 7
+for details.
+.It I/O delays
+By default, if a leaf vdev generates more than delayed 8 I/O events in a 60
+second period, then
.Nm
will mark that vdev as
.Em FAULTED .
ZFS will no longer issue any I/Os to it.
.Nm
-will activate a hotspare if one is available.
+will activate a hot spare if one is available. The defaults can be changed by
+setting the
+.Em slow_io_n
+and/or
+.Em slow_io_t
+vdev properties. See
+.Xr vdevprops 7
+for details.
.It Checksum errors
-If a leaf vdev generates more than 50 checksum errors in a 60 second
-period, then
+By default, if a leaf vdev generates more than 50 checksum errors in a 60
+second period, then
.Nm
will mark that vdev as
.Em DEGRADED .
-ZFS will still use it, but zfsd will activate a spare anyway.
+ZFS will still use it, but zfsd will also activate a hot spare if one is
+available. The defaults can be changed by setting the
+.Em checksum_n
+and/or
+.Em checksum_t
+vdev properties. See
+.Xr vdevprops 7
+for details.
.It Spare addition
-If the system administrator adds a hotspare to a pool that is already degraded,
+If the system administrator adds a hot spare to a pool that is already degraded,
.Nm
will activate the spare.
.It Resilver complete
.Nm
-will detach any hotspare once a permanent replacement finishes resilvering.
+will detach any hot spare once a permanent replacement finishes resilvering.
.It Physical path change
If the physical path of an existing disk changes,
.Nm
@@ -134,6 +165,7 @@ then reads them back in when next it starts up.
.El
.Sh SEE ALSO
.Xr devctl 4 ,
+.Xr vdevprops 7 ,
.Xr zpool 8
.Sh HISTORY
.Nm
diff --git a/contrib/llvm-project/clang/lib/CodeGen/CGBuiltin.cpp b/contrib/llvm-project/clang/lib/CodeGen/CGBuiltin.cpp
index a4f26a6f0eb1..44ddd2428b10 100644
--- a/contrib/llvm-project/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/contrib/llvm-project/clang/lib/CodeGen/CGBuiltin.cpp
@@ -823,29 +823,32 @@ const FieldDecl *CodeGenFunction::FindFlexibleArrayMemberField(
ASTContext &Ctx, const RecordDecl *RD, StringRef Name, uint64_t &Offset) {
const LangOptions::StrictFlexArraysLevelKind StrictFlexArraysLevel =
getLangOpts().getStrictFlexArraysLevel();
- unsigned FieldNo = 0;
- bool IsUnion = RD->isUnion();
+ uint32_t FieldNo = 0;
- for (const Decl *D : RD->decls()) {
- if (const auto *Field = dyn_cast<FieldDecl>(D);
- Field && (Name.empty() || Field->getNameAsString() == Name) &&
+ if (RD->isImplicit())
+ return nullptr;
+
+ for (const FieldDecl *FD : RD->fields()) {
+ if ((Name.empty() || FD->getNameAsString() == Name) &&
Decl::isFlexibleArrayMemberLike(
- Ctx, Field, Field->getType(), StrictFlexArraysLevel,
+ Ctx, FD, FD->getType(), StrictFlexArraysLevel,
/*IgnoreTemplateOrMacroSubstitution=*/true)) {
const ASTRecordLayout &Layout = Ctx.getASTRecordLayout(RD);
Offset += Layout.getFieldOffset(FieldNo);
- return Field;
+ return FD;
}
- if (const auto *Record = dyn_cast<RecordDecl>(D))
- if (const FieldDecl *Field =
- FindFlexibleArrayMemberField(Ctx, Record, Name, Offset)) {
+ QualType Ty = FD->getType();
+ if (Ty->isRecordType()) {
+ if (const FieldDecl *Field = FindFlexibleArrayMemberField(
+ Ctx, Ty->getAsRecordDecl(), Name, Offset)) {
const ASTRecordLayout &Layout = Ctx.getASTRecordLayout(RD);
Offset += Layout.getFieldOffset(FieldNo);
return Field;
}
+ }
- if (!IsUnion && isa<FieldDecl>(D))
+ if (!RD->isUnion())
++FieldNo;
}
diff --git a/contrib/llvm-project/clang/lib/CodeGen/CGCall.cpp b/contrib/llvm-project/clang/lib/CodeGen/CGCall.cpp
index 28c211aa631e..a6a2f3595fe7 100644
--- a/contrib/llvm-project/clang/lib/CodeGen/CGCall.cpp
+++ b/contrib/llvm-project/clang/lib/CodeGen/CGCall.cpp
@@ -1581,6 +1581,11 @@ bool CodeGenModule::ReturnTypeUsesSRet(const CGFunctionInfo &FI) {
return RI.isIndirect() || (RI.isInAlloca() && RI.getInAllocaSRet());
}
+bool CodeGenModule::ReturnTypeHasInReg(const CGFunctionInfo &FI) {
+ const auto &RI = FI.getReturnInfo();
+ return RI.getInReg();
+}
+
bool CodeGenModule::ReturnSlotInterferesWithArgs(const CGFunctionInfo &FI) {
return ReturnTypeUsesSRet(FI) &&
getTargetCodeGenInfo().doesReturnSlotInterfereWithArgs();
diff --git a/contrib/llvm-project/clang/lib/CodeGen/CGObjCGNU.cpp b/contrib/llvm-project/clang/lib/CodeGen/CGObjCGNU.cpp
index a36b0cdddaf0..05e3f8d4bfc2 100644
--- a/contrib/llvm-project/clang/lib/CodeGen/CGObjCGNU.cpp
+++ b/contrib/llvm-project/clang/lib/CodeGen/CGObjCGNU.cpp
@@ -2903,23 +2903,29 @@ CGObjCGNU::GenerateMessageSend(CodeGenFunction &CGF,
break;
case CodeGenOptions::Mixed:
case CodeGenOptions::NonLegacy:
+ StringRef name = "objc_msgSend";
if (CGM.ReturnTypeUsesFPRet(ResultType)) {
- imp =
- CGM.CreateRuntimeFunction(llvm::FunctionType::get(IdTy, IdTy, true),
- "objc_msgSend_fpret")
- .getCallee();
+ name = "objc_msgSend_fpret";
} else if (CGM.ReturnTypeUsesSRet(MSI.CallInfo)) {
- // The actual types here don't matter - we're going to bitcast the
- // function anyway
- imp =
- CGM.CreateRuntimeFunction(llvm::FunctionType::get(IdTy, IdTy, true),
- "objc_msgSend_stret")
- .getCallee();
- } else {
- imp = CGM.CreateRuntimeFunction(
- llvm::FunctionType::get(IdTy, IdTy, true), "objc_msgSend")
- .getCallee();
+ name = "objc_msgSend_stret";
+
+ // The address of the memory block is be passed in x8 for POD type,
+ // or in x0 for non-POD type (marked as inreg).
+ bool shouldCheckForInReg =
+ CGM.getContext()
+ .getTargetInfo()
+ .getTriple()
+ .isWindowsMSVCEnvironment() &&
+ CGM.getContext().getTargetInfo().getTriple().isAArch64();
+ if (shouldCheckForInReg && CGM.ReturnTypeHasInReg(MSI.CallInfo)) {
+ name = "objc_msgSend_stret2";
+ }
}
+ // The actual types here don't matter - we're going to bitcast the
+ // function anyway
+ imp = CGM.CreateRuntimeFunction(llvm::FunctionType::get(IdTy, IdTy, true),
+ name)
+ .getCallee();
}
// Reset the receiver in case the lookup modified it
diff --git a/contrib/llvm-project/clang/lib/CodeGen/CodeGenModule.h b/contrib/llvm-project/clang/lib/CodeGen/CodeGenModule.h
index ec34680fd3f7..d9ece4d98eec 100644
--- a/contrib/llvm-project/clang/lib/CodeGen/CodeGenModule.h
+++ b/contrib/llvm-project/clang/lib/CodeGen/CodeGenModule.h
@@ -1239,6 +1239,9 @@ public:
/// Return true iff the given type uses 'sret' when used as a return type.
bool ReturnTypeUsesSRet(const CGFunctionInfo &FI);
+ /// Return true iff the given type has `inreg` set.
+ bool ReturnTypeHasInReg(const CGFunctionInfo &FI);
+
/// Return true iff the given type uses an argument slot when 'sret' is used
/// as a return type.
bool ReturnSlotInterferesWithArgs(const CGFunctionInfo &FI);
diff --git a/contrib/llvm-project/clang/lib/CodeGen/CoverageMappingGen.cpp b/contrib/llvm-project/clang/lib/CodeGen/CoverageMappingGen.cpp
index 0c43317642bc..ae4e6d4c88c0 100644
--- a/contrib/llvm-project/clang/lib/CodeGen/CoverageMappingGen.cpp
+++ b/contrib/llvm-project/clang/lib/CodeGen/CoverageMappingGen.cpp
@@ -1207,6 +1207,12 @@ struct CounterCoverageMappingBuilder
/// Find a valid gap range between \p AfterLoc and \p BeforeLoc.
std::optional<SourceRange> findGapAreaBetween(SourceLocation AfterLoc,
SourceLocation BeforeLoc) {
+ // Some statements (like AttributedStmt and ImplicitValueInitExpr) don't
+ // have valid source locations. Do not emit a gap region if this is the case
+ // in either AfterLoc end or BeforeLoc end.
+ if (AfterLoc.isInvalid() || BeforeLoc.isInvalid())
+ return std::nullopt;
+
// If AfterLoc is in function-like macro, use the right parenthesis
// location.
if (AfterLoc.isMacroID()) {
@@ -1370,9 +1376,8 @@ struct CounterCoverageMappingBuilder
for (const Stmt *Child : S->children())
if (Child) {
// If last statement contains terminate statements, add a gap area
- // between the two statements. Skipping attributed statements, because
- // they don't have valid start location.
- if (LastStmt && HasTerminateStmt && !isa<AttributedStmt>(Child)) {
+ // between the two statements.
+ if (LastStmt && HasTerminateStmt) {
auto Gap = findGapAreaBetween(getEnd(LastStmt), getStart(Child));
if (Gap)
fillGapAreaWithCount(Gap->getBegin(), Gap->getEnd(),
diff --git a/contrib/llvm-project/clang/lib/CodeGen/MicrosoftCXXABI.cpp b/contrib/llvm-project/clang/lib/CodeGen/MicrosoftCXXABI.cpp
index 172c4c937b97..4d0f4c63f843 100644
--- a/contrib/llvm-project/clang/lib/CodeGen/MicrosoftCXXABI.cpp
+++ b/contrib/llvm-project/clang/lib/CodeGen/MicrosoftCXXABI.cpp
@@ -1135,9 +1135,15 @@ static bool isTrivialForMSVC(const CXXRecordDecl *RD, QualType Ty,
return false;
if (RD->hasNonTrivialCopyAssignment())
return false;
- for (const CXXConstructorDecl *Ctor : RD->ctors())
- if (Ctor->isUserProvided())
- return false;
+ for (const Decl *D : RD->decls()) {
+ if (auto *Ctor = dyn_cast<CXXConstructorDecl>(D)) {
+ if (Ctor->isUserProvided())
+ return false;
+ } else if (auto *Template = dyn_cast<FunctionTemplateDecl>(D)) {
+ if (isa<CXXConstructorDecl>(Template->getTemplatedDecl()))
+ return false;
+ }
+ }
if (RD->hasNonTrivialDestructor())
return false;
return true;
diff --git a/contrib/llvm-project/clang/lib/Format/ContinuationIndenter.cpp b/contrib/llvm-project/clang/lib/Format/ContinuationIndenter.cpp
index a3eb9138b218..53cd169b0590 100644
--- a/contrib/llvm-project/clang/lib/Format/ContinuationIndenter.cpp
+++ b/contrib/llvm-project/clang/lib/Format/ContinuationIndenter.cpp
@@ -674,7 +674,13 @@ void ContinuationIndenter::addTokenOnCurrentLine(LineState &State, bool DryRun,
// arguments to function calls. We do this by ensuring that either all
// arguments (including any lambdas) go on the same line as the function
// call, or we break before the first argument.
- auto PrevNonComment = Current.getPreviousNonComment();
+ const auto *Prev = Current.Previous;
+ if (!Prev)
+ return false;
+ // For example, `/*Newline=*/false`.
+ if (Prev->is(TT_BlockComment) && Current.SpacesRequiredBefore == 0)
+ return false;
+ const auto *PrevNonComment = Current.getPreviousNonComment();
if (!PrevNonComment || PrevNonComment->isNot(tok::l_paren))
return false;
if (Current.isOneOf(tok::comment, tok::l_paren, TT_LambdaLSquare))
diff --git a/contrib/llvm-project/clang/lib/Format/TokenAnnotator.cpp b/contrib/llvm-project/clang/lib/Format/TokenAnnotator.cpp
index 4d482e6543d6..c1f166248192 100644
--- a/contrib/llvm-project/clang/lib/Format/TokenAnnotator.cpp
+++ b/contrib/llvm-project/clang/lib/Format/TokenAnnotator.cpp
@@ -3532,6 +3532,8 @@ void TokenAnnotator::calculateFormattingInformation(AnnotatedLine &Line) const {
}
} else if (ClosingParen) {
for (auto *Tok = ClosingParen->Next; Tok; Tok = Tok->Next) {
+ if (Tok->is(TT_CtorInitializerColon))
+ break;
if (Tok->is(tok::arrow)) {
Tok->setType(TT_TrailingReturnArrow);
break;
@@ -5157,12 +5159,8 @@ bool TokenAnnotator::mustBreakBefore(const AnnotatedLine &Line,
return true;
if (Left.IsUnterminatedLiteral)
return true;
- // FIXME: Breaking after newlines seems useful in general. Turn this into an
- // option and recognize more cases like endl etc, and break independent of
- // what comes after operator lessless.
- if (Right.is(tok::lessless) && Right.Next &&
- Right.Next->is(tok::string_literal) && Left.is(tok::string_literal) &&
- Left.TokenText.ends_with("\\n\"")) {
+ if (Right.is(tok::lessless) && Right.Next && Left.is(tok::string_literal) &&
+ Right.Next->is(tok::string_literal)) {
return true;
}
if (Right.is(TT_RequiresClause)) {
diff --git a/contrib/llvm-project/clang/lib/Format/UnwrappedLineParser.cpp b/contrib/llvm-project/clang/lib/Format/UnwrappedLineParser.cpp
index 573919798870..a6eb18bb2b32 100644
--- a/contrib/llvm-project/clang/lib/Format/UnwrappedLineParser.cpp
+++ b/contrib/llvm-project/clang/lib/Format/UnwrappedLineParser.cpp
@@ -489,18 +489,23 @@ void UnwrappedLineParser::calculateBraceTypes(bool ExpectClassBody) {
};
SmallVector<StackEntry, 8> LBraceStack;
assert(Tok->is(tok::l_brace));
+
do {
- // Get next non-comment, non-preprocessor token.
FormatToken *NextTok;
do {
NextTok = Tokens->getNextToken();
} while (NextTok->is(tok::comment));
- while (NextTok->is(tok::hash) && !Line->InMacroBody) {
- NextTok = Tokens->getNextToken();
- do {
- NextTok = Tokens->getNextToken();
- } while (NextTok->is(tok::comment) ||
- (NextTok->NewlinesBefore == 0 && NextTok->isNot(tok::eof)));
+
+ if (!Line->InMacroBody) {
+ // Skip PPDirective lines and comments.
+ while (NextTok->is(tok::hash)) {
+ do {
+ NextTok = Tokens->getNextToken();
+ } while (NextTok->NewlinesBefore == 0 && NextTok->isNot(tok::eof));
+
+ while (NextTok->is(tok::comment))
+ NextTok = Tokens->getNextToken();
+ }
}
switch (Tok->Tok.getKind()) {
@@ -534,16 +539,6 @@ void UnwrappedLineParser::calculateBraceTypes(bool ExpectClassBody) {
if (Style.Language == FormatStyle::LK_Proto) {
ProbablyBracedList = NextTok->isOneOf(tok::comma, tok::r_square);
} else {
- // Skip NextTok over preprocessor lines, otherwise we may not
- // properly diagnose the block as a braced intializer
- // if the comma separator appears after the pp directive.
- while (NextTok->is(tok::hash)) {
- ScopedMacroState MacroState(*Line, Tokens, NextTok);
- do {
- NextTok = Tokens->getNextToken();
- } while (NextTok->isNot(tok::eof));
- }
-
// Using OriginalColumn to distinguish between ObjC methods and
// binary operators is a bit hacky.
bool NextIsObjCMethod = NextTok->isOneOf(tok::plus, tok::minus) &&
@@ -602,6 +597,16 @@ void UnwrappedLineParser::calculateBraceTypes(bool ExpectClassBody) {
NextTok = Tokens->getNextToken();
ProbablyBracedList = NextTok->isNot(tok::l_square);
}
+
+ // Cpp macro definition body that is a nonempty braced list or block:
+ if (Style.isCpp() && Line->InMacroBody && PrevTok != FormatTok &&
+ !FormatTok->Previous && NextTok->is(tok::eof) &&
+ // A statement can end with only `;` (simple statement), a block
+ // closing brace (compound statement), or `:` (label statement).
+ // If PrevTok is a block opening brace, Tok ends an empty block.
+ !PrevTok->isOneOf(tok::semi, BK_Block, tok::colon)) {
+ ProbablyBracedList = true;
+ }
}
if (ProbablyBracedList) {
Tok->setBlockKind(BK_BracedInit);
@@ -631,6 +636,7 @@ void UnwrappedLineParser::calculateBraceTypes(bool ExpectClassBody) {
default:
break;
}
+
PrevTok = Tok;
Tok = NextTok;
} while (Tok->isNot(tok::eof) && !LBraceStack.empty());
diff --git a/contrib/llvm-project/clang/lib/StaticAnalyzer/Checkers/Taint.cpp b/contrib/llvm-project/clang/lib/StaticAnalyzer/Checkers/Taint.cpp
index 4edb671753bf..6362c82b009d 100644
--- a/contrib/llvm-project/clang/lib/StaticAnalyzer/Checkers/Taint.cpp
+++ b/contrib/llvm-project/clang/lib/StaticAnalyzer/Checkers/Taint.cpp
@@ -216,21 +216,17 @@ std::vector<SymbolRef> taint::getTaintedSymbolsImpl(ProgramStateRef State,
std::vector<SymbolRef> TaintedSymbols;
if (!Reg)
return TaintedSymbols;
- // Element region (array element) is tainted if either the base or the offset
- // are tainted.
+
+ // Element region (array element) is tainted if the offset is tainted.
if (const ElementRegion *ER = dyn_cast<ElementRegion>(Reg)) {
std::vector<SymbolRef> TaintedIndex =
getTaintedSymbolsImpl(State, ER->getIndex(), K, returnFirstOnly);
llvm::append_range(TaintedSymbols, TaintedIndex);
if (returnFirstOnly && !TaintedSymbols.empty())
return TaintedSymbols; // return early if needed
- std::vector<SymbolRef> TaintedSuperRegion =
- getTaintedSymbolsImpl(State, ER->getSuperRegion(), K, returnFirstOnly);
- llvm::append_range(TaintedSymbols, TaintedSuperRegion);
- if (returnFirstOnly && !TaintedSymbols.empty())
- return TaintedSymbols; // return early if needed
}
+ // Symbolic region is tainted if the corresponding symbol is tainted.
if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(Reg)) {
std::vector<SymbolRef> TaintedRegions =
getTaintedSymbolsImpl(State, SR->getSymbol(), K, returnFirstOnly);
@@ -239,6 +235,8 @@ std::vector<SymbolRef> taint::getTaintedSymbolsImpl(ProgramStateRef State,
return TaintedSymbols; // return early if needed
}
+ // Any subregion (including Element and Symbolic regions) is tainted if its
+ // super-region is tainted.
if (const SubRegion *ER = dyn_cast<SubRegion>(Reg)) {
std::vector<SymbolRef> TaintedSubRegions =
getTaintedSymbolsImpl(State, ER->getSuperRegion(), K, returnFirstOnly);
@@ -318,4 +316,4 @@ std::vector<SymbolRef> taint::getTaintedSymbolsImpl(ProgramStateRef State,
}
}
return TaintedSymbols;
-} \ No newline at end of file
+}
diff --git a/contrib/llvm-project/clang/lib/StaticAnalyzer/Checkers/cert/InvalidPtrChecker.cpp b/contrib/llvm-project/clang/lib/StaticAnalyzer/Checkers/cert/InvalidPtrChecker.cpp
index e5dd907c660d..b2947f590c4e 100644
--- a/contrib/llvm-project/clang/lib/StaticAnalyzer/Checkers/cert/InvalidPtrChecker.cpp
+++ b/contrib/llvm-project/clang/lib/StaticAnalyzer/Checkers/cert/InvalidPtrChecker.cpp
@@ -205,8 +205,12 @@ void InvalidPtrChecker::postPreviousReturnInvalidatingCall(
CE, LCtx, CE->getType(), C.blockCount());
State = State->BindExpr(CE, LCtx, RetVal);
+ const auto *SymRegOfRetVal =
+ dyn_cast_or_null<SymbolicRegion>(RetVal.getAsRegion());
+ if (!SymRegOfRetVal)
+ return;
+
// Remember to this region.
- const auto *SymRegOfRetVal = cast<SymbolicRegion>(RetVal.getAsRegion());
const MemRegion *MR = SymRegOfRetVal->getBaseRegion();
State = State->set<PreviousCallResultMap>(FD, MR);
diff --git a/contrib/llvm-project/libcxx/modules/std.compat/cstdlib.inc b/contrib/llvm-project/libcxx/modules/std.compat/cstdlib.inc
index a45a0a1caf8b..4783cbf51623 100644
--- a/contrib/llvm-project/libcxx/modules/std.compat/cstdlib.inc
+++ b/contrib/llvm-project/libcxx/modules/std.compat/cstdlib.inc
@@ -25,7 +25,7 @@ export {
using ::system;
// [c.malloc], C library memory allocation
- using ::aligned_alloc;
+ using ::aligned_alloc _LIBCPP_USING_IF_EXISTS;
using ::calloc;
using ::free;
using ::malloc;
diff --git a/contrib/llvm-project/lld/ELF/Writer.cpp b/contrib/llvm-project/lld/ELF/Writer.cpp
index 8a08b0fcc90d..0c1bd27bb1fe 100644
--- a/contrib/llvm-project/lld/ELF/Writer.cpp
+++ b/contrib/llvm-project/lld/ELF/Writer.cpp
@@ -2148,9 +2148,13 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
addPhdrForSection(part, SHT_MIPS_OPTIONS, PT_MIPS_OPTIONS, PF_R);
addPhdrForSection(part, SHT_MIPS_ABIFLAGS, PT_MIPS_ABIFLAGS, PF_R);
}
+#if 0
+ // XXX: This stops elftoolchain strip adjusting .riscv.attributes,
+ // leaving large holes in binaries.
if (config->emachine == EM_RISCV)
addPhdrForSection(part, SHT_RISCV_ATTRIBUTES, PT_RISCV_ATTRIBUTES,
PF_R);
+#endif
}
Out::programHeaders->size = sizeof(Elf_Phdr) * mainPart->phdrs.size();
diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/LoadStoreOpt.h b/contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/LoadStoreOpt.h
index 0f20a33f3a75..7990997835d0 100644
--- a/contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/LoadStoreOpt.h
+++ b/contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/LoadStoreOpt.h
@@ -35,11 +35,23 @@ struct LegalityQuery;
class MachineRegisterInfo;
namespace GISelAddressing {
/// Helper struct to store a base, index and offset that forms an address
-struct BaseIndexOffset {
+class BaseIndexOffset {
+private:
Register BaseReg;
Register IndexReg;
- int64_t Offset = 0;
- bool IsIndexSignExt = false;
+ std::optional<int64_t> Offset;
+
+public:
+ BaseIndexOffset() = default;
+ Register getBase() { return BaseReg; }
+ Register getBase() const { return BaseReg; }
+ Register getIndex() { return IndexReg; }
+ Register getIndex() const { return IndexReg; }
+ void setBase(Register NewBase) { BaseReg = NewBase; }
+ void setIndex(Register NewIndex) { IndexReg = NewIndex; }
+ void setOffset(std::optional<int64_t> NewOff) { Offset = NewOff; }
+ bool hasValidOffset() const { return Offset.has_value(); }
+ int64_t getOffset() const { return *Offset; }
};
/// Returns a BaseIndexOffset which describes the pointer in \p Ptr.
@@ -89,7 +101,7 @@ private:
// order stores are writing to incremeneting consecutive addresses. So when
// we walk the block in reverse order, the next eligible store must write to
// an offset one store width lower than CurrentLowestOffset.
- uint64_t CurrentLowestOffset;
+ int64_t CurrentLowestOffset;
SmallVector<GStore *> Stores;
// A vector of MachineInstr/unsigned pairs to denote potential aliases that
// need to be checked before the candidate is considered safe to merge. The
diff --git a/contrib/llvm-project/llvm/lib/CodeGen/CodeGenPrepare.cpp b/contrib/llvm-project/llvm/lib/CodeGen/CodeGenPrepare.cpp
index 8ee1f19e083e..1cca56fc19cf 100644
--- a/contrib/llvm-project/llvm/lib/CodeGen/CodeGenPrepare.cpp
+++ b/contrib/llvm-project/llvm/lib/CodeGen/CodeGenPrepare.cpp
@@ -8154,6 +8154,7 @@ static bool optimizeBranch(BranchInst *Branch, const TargetLowering &TLI,
IRBuilder<> Builder(Branch);
if (UI->getParent() != Branch->getParent())
UI->moveBefore(Branch);
+ UI->dropPoisonGeneratingFlags();
Value *NewCmp = Builder.CreateCmp(ICmpInst::ICMP_EQ, UI,
ConstantInt::get(UI->getType(), 0));
LLVM_DEBUG(dbgs() << "Converting " << *Cmp << "\n");
@@ -8167,6 +8168,7 @@ static bool optimizeBranch(BranchInst *Branch, const TargetLowering &TLI,
IRBuilder<> Builder(Branch);
if (UI->getParent() != Branch->getParent())
UI->moveBefore(Branch);
+ UI->dropPoisonGeneratingFlags();
Value *NewCmp = Builder.CreateCmp(Cmp->getPredicate(), UI,
ConstantInt::get(UI->getType(), 0));
LLVM_DEBUG(dbgs() << "Converting " << *Cmp << "\n");
diff --git a/contrib/llvm-project/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp b/contrib/llvm-project/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
index 772229215e79..61ddc858ba44 100644
--- a/contrib/llvm-project/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
+++ b/contrib/llvm-project/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
@@ -591,8 +591,8 @@ bool CombinerHelper::matchCombineExtendingLoads(MachineInstr &MI,
UseMI.getOpcode() == TargetOpcode::G_ZEXT ||
(UseMI.getOpcode() == TargetOpcode::G_ANYEXT)) {
const auto &MMO = LoadMI->getMMO();
- // For atomics, only form anyextending loads.
- if (MMO.isAtomic() && UseMI.getOpcode() != TargetOpcode::G_ANYEXT)
+ // Don't do anything for atomics.
+ if (MMO.isAtomic())
continue;
// Check for legality.
if (!isPreLegalize()) {
diff --git a/contrib/llvm-project/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp b/contrib/llvm-project/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
index c0c22e36004f..47d045ac4817 100644
--- a/contrib/llvm-project/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
+++ b/contrib/llvm-project/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
@@ -4180,6 +4180,10 @@ LegalizerHelper::fewerElementsVectorPhi(GenericMachineInstr &MI,
}
}
+ // Set the insert point after the existing PHIs
+ MachineBasicBlock &MBB = *MI.getParent();
+ MIRBuilder.setInsertPt(MBB, MBB.getFirstNonPHI());
+
// Merge small outputs into MI's def.
if (NumLeftovers) {
mergeMixedSubvectors(MI.getReg(0), OutputRegs);
diff --git a/contrib/llvm-project/llvm/lib/CodeGen/GlobalISel/LoadStoreOpt.cpp b/contrib/llvm-project/llvm/lib/CodeGen/GlobalISel/LoadStoreOpt.cpp
index 246aa88b09ac..ee499c41c558 100644
--- a/contrib/llvm-project/llvm/lib/CodeGen/GlobalISel/LoadStoreOpt.cpp
+++ b/contrib/llvm-project/llvm/lib/CodeGen/GlobalISel/LoadStoreOpt.cpp
@@ -84,21 +84,20 @@ BaseIndexOffset GISelAddressing::getPointerInfo(Register Ptr,
MachineRegisterInfo &MRI) {
BaseIndexOffset Info;
Register PtrAddRHS;
- if (!mi_match(Ptr, MRI, m_GPtrAdd(m_Reg(Info.BaseReg), m_Reg(PtrAddRHS)))) {
- Info.BaseReg = Ptr;
- Info.IndexReg = Register();
- Info.IsIndexSignExt = false;
+ Register BaseReg;
+ if (!mi_match(Ptr, MRI, m_GPtrAdd(m_Reg(BaseReg), m_Reg(PtrAddRHS)))) {
+ Info.setBase(Ptr);
+ Info.setOffset(0);
return Info;
}
-
+ Info.setBase(BaseReg);
auto RHSCst = getIConstantVRegValWithLookThrough(PtrAddRHS, MRI);
if (RHSCst)
- Info.Offset = RHSCst->Value.getSExtValue();
+ Info.setOffset(RHSCst->Value.getSExtValue());
// Just recognize a simple case for now. In future we'll need to match
// indexing patterns for base + index + constant.
- Info.IndexReg = PtrAddRHS;
- Info.IsIndexSignExt = false;
+ Info.setIndex(PtrAddRHS);
return Info;
}
@@ -114,15 +113,16 @@ bool GISelAddressing::aliasIsKnownForLoadStore(const MachineInstr &MI1,
BaseIndexOffset BasePtr0 = getPointerInfo(LdSt1->getPointerReg(), MRI);
BaseIndexOffset BasePtr1 = getPointerInfo(LdSt2->getPointerReg(), MRI);
- if (!BasePtr0.BaseReg.isValid() || !BasePtr1.BaseReg.isValid())
+ if (!BasePtr0.getBase().isValid() || !BasePtr1.getBase().isValid())
return false;
int64_t Size1 = LdSt1->getMemSize();
int64_t Size2 = LdSt2->getMemSize();
int64_t PtrDiff;
- if (BasePtr0.BaseReg == BasePtr1.BaseReg) {
- PtrDiff = BasePtr1.Offset - BasePtr0.Offset;
+ if (BasePtr0.getBase() == BasePtr1.getBase() && BasePtr0.hasValidOffset() &&
+ BasePtr1.hasValidOffset()) {
+ PtrDiff = BasePtr1.getOffset() - BasePtr0.getOffset();
// If the size of memory access is unknown, do not use it to do analysis.
// One example of unknown size memory access is to load/store scalable
// vector objects on the stack.
@@ -151,8 +151,8 @@ bool GISelAddressing::aliasIsKnownForLoadStore(const MachineInstr &MI1,
// able to calculate their relative offset if at least one arises
// from an alloca. However, these allocas cannot overlap and we
// can infer there is no alias.
- auto *Base0Def = getDefIgnoringCopies(BasePtr0.BaseReg, MRI);
- auto *Base1Def = getDefIgnoringCopies(BasePtr1.BaseReg, MRI);
+ auto *Base0Def = getDefIgnoringCopies(BasePtr0.getBase(), MRI);
+ auto *Base1Def = getDefIgnoringCopies(BasePtr1.getBase(), MRI);
if (!Base0Def || !Base1Def)
return false; // Couldn't tell anything.
@@ -520,16 +520,20 @@ bool LoadStoreOpt::addStoreToCandidate(GStore &StoreMI,
Register StoreAddr = StoreMI.getPointerReg();
auto BIO = getPointerInfo(StoreAddr, *MRI);
- Register StoreBase = BIO.BaseReg;
- uint64_t StoreOffCst = BIO.Offset;
+ Register StoreBase = BIO.getBase();
if (C.Stores.empty()) {
+ C.BasePtr = StoreBase;
+ if (!BIO.hasValidOffset()) {
+ C.CurrentLowestOffset = 0;
+ } else {
+ C.CurrentLowestOffset = BIO.getOffset();
+ }
// This is the first store of the candidate.
// If the offset can't possibly allow for a lower addressed store with the
// same base, don't bother adding it.
- if (StoreOffCst < ValueTy.getSizeInBytes())
+ if (BIO.hasValidOffset() &&
+ BIO.getOffset() < static_cast<int64_t>(ValueTy.getSizeInBytes()))
return false;
- C.BasePtr = StoreBase;
- C.CurrentLowestOffset = StoreOffCst;
C.Stores.emplace_back(&StoreMI);
LLVM_DEBUG(dbgs() << "Starting a new merge candidate group with: "
<< StoreMI);
@@ -549,8 +553,12 @@ bool LoadStoreOpt::addStoreToCandidate(GStore &StoreMI,
// writes to the next lowest adjacent address.
if (C.BasePtr != StoreBase)
return false;
- if ((C.CurrentLowestOffset - ValueTy.getSizeInBytes()) !=
- static_cast<uint64_t>(StoreOffCst))
+ // If we don't have a valid offset, we can't guarantee to be an adjacent
+ // offset.
+ if (!BIO.hasValidOffset())
+ return false;
+ if ((C.CurrentLowestOffset -
+ static_cast<int64_t>(ValueTy.getSizeInBytes())) != BIO.getOffset())
return false;
// This writes to an adjacent address. Allow it.
diff --git a/contrib/llvm-project/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/contrib/llvm-project/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index e806e0f0731f..5038f8a1fc15 100644
--- a/contrib/llvm-project/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/contrib/llvm-project/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -9636,8 +9636,15 @@ static SDValue combineShiftOfShiftedLogic(SDNode *Shift, SelectionDAG &DAG) {
if (ShiftAmtVal->getBitWidth() != C1Val.getBitWidth())
return false;
+ // The fold is not valid if the sum of the shift values doesn't fit in the
+ // given shift amount type.
+ bool Overflow = false;
+ APInt NewShiftAmt = C1Val.uadd_ov(*ShiftAmtVal, Overflow);
+ if (Overflow)
+ return false;
+
// The fold is not valid if the sum of the shift values exceeds bitwidth.
- if ((*ShiftAmtVal + C1Val).uge(V.getScalarValueSizeInBits()))
+ if (NewShiftAmt.uge(V.getScalarValueSizeInBits()))
return false;
return true;
diff --git a/contrib/llvm-project/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/contrib/llvm-project/llvm/lib/Target/AArch64/AArch64InstrInfo.td
index 03baa7497615..ac61dd8745d4 100644
--- a/contrib/llvm-project/llvm/lib/Target/AArch64/AArch64InstrInfo.td
+++ b/contrib/llvm-project/llvm/lib/Target/AArch64/AArch64InstrInfo.td
@@ -4885,19 +4885,9 @@ defm UABDL : SIMDLongThreeVectorBHSabdl<1, 0b0111, "uabdl",
def : Pat<(abs (v8i16 (sub (zext (v8i8 V64:$opA)),
(zext (v8i8 V64:$opB))))),
(UABDLv8i8_v8i16 V64:$opA, V64:$opB)>;
-def : Pat<(xor (v8i16 (AArch64vashr v8i16:$src, (i32 15))),
- (v8i16 (add (sub (zext (v8i8 V64:$opA)),
- (zext (v8i8 V64:$opB))),
- (AArch64vashr v8i16:$src, (i32 15))))),
- (UABDLv8i8_v8i16 V64:$opA, V64:$opB)>;
def : Pat<(abs (v8i16 (sub (zext (extract_high_v16i8 (v16i8 V128:$opA))),
(zext (extract_high_v16i8 (v16i8 V128:$opB)))))),
(UABDLv16i8_v8i16 V128:$opA, V128:$opB)>;
-def : Pat<(xor (v8i16 (AArch64vashr v8i16:$src, (i32 15))),
- (v8i16 (add (sub (zext (extract_high_v16i8 (v16i8 V128:$opA))),
- (zext (extract_high_v16i8 (v16i8 V128:$opB)))),
- (AArch64vashr v8i16:$src, (i32 15))))),
- (UABDLv16i8_v8i16 V128:$opA, V128:$opB)>;
def : Pat<(abs (v4i32 (sub (zext (v4i16 V64:$opA)),
(zext (v4i16 V64:$opB))))),
(UABDLv4i16_v4i32 V64:$opA, V64:$opB)>;
diff --git a/contrib/llvm-project/llvm/lib/Target/AMDGPU/SIMemoryLegalizer.cpp b/contrib/llvm-project/llvm/lib/Target/AMDGPU/SIMemoryLegalizer.cpp
index 84b9330ef963..50d8bfa87508 100644
--- a/contrib/llvm-project/llvm/lib/Target/AMDGPU/SIMemoryLegalizer.cpp
+++ b/contrib/llvm-project/llvm/lib/Target/AMDGPU/SIMemoryLegalizer.cpp
@@ -2358,6 +2358,11 @@ bool SIGfx12CacheControl::enableVolatileAndOrNonTemporal(
bool Changed = false;
+ if (IsNonTemporal) {
+ // Set non-temporal hint for all cache levels.
+ Changed |= setTH(MI, AMDGPU::CPol::TH_NT);
+ }
+
if (IsVolatile) {
Changed |= setScope(MI, AMDGPU::CPol::SCOPE_SYS);
@@ -2370,11 +2375,6 @@ bool SIGfx12CacheControl::enableVolatileAndOrNonTemporal(
Position::AFTER);
}
- if (IsNonTemporal) {
- // Set non-temporal hint for all cache levels.
- Changed |= setTH(MI, AMDGPU::CPol::TH_NT);
- }
-
return Changed;
}
diff --git a/contrib/llvm-project/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/contrib/llvm-project/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index a0cec426002b..d46093b9e260 100644
--- a/contrib/llvm-project/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/contrib/llvm-project/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -14559,7 +14559,7 @@ static SDValue tryFoldSelectIntoOp(SDNode *N, SelectionDAG &DAG,
EVT VT = N->getValueType(0);
SDLoc DL(N);
SDValue OtherOp = TrueVal.getOperand(1 - OpToFold);
- EVT OtherOpVT = OtherOp->getValueType(0);
+ EVT OtherOpVT = OtherOp.getValueType();
SDValue IdentityOperand =
DAG.getNeutralElement(Opc, DL, OtherOpVT, N->getFlags());
if (!Commutative)
diff --git a/contrib/llvm-project/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp b/contrib/llvm-project/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp
index 833f058253d8..553d338b7790 100644
--- a/contrib/llvm-project/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp
+++ b/contrib/llvm-project/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp
@@ -2923,11 +2923,10 @@ bool X86DAGToDAGISel::selectAddr(SDNode *Parent, SDValue N, SDValue &Base,
}
bool X86DAGToDAGISel::selectMOV64Imm32(SDValue N, SDValue &Imm) {
- // Cannot use 32 bit constants to reference objects in kernel code model.
- // Cannot use 32 bit constants to reference objects in large PIC mode since
- // GOTOFF is 64 bits.
+ // Cannot use 32 bit constants to reference objects in kernel/large code
+ // model.
if (TM.getCodeModel() == CodeModel::Kernel ||
- (TM.getCodeModel() == CodeModel::Large && TM.isPositionIndependent()))
+ TM.getCodeModel() == CodeModel::Large)
return false;
// In static codegen with small code model, we can get the address of a label
diff --git a/contrib/llvm-project/llvm/lib/Target/X86/X86ISelLowering.cpp b/contrib/llvm-project/llvm/lib/Target/X86/X86ISelLowering.cpp
index 96bbd981ff24..201dd8382536 100644
--- a/contrib/llvm-project/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/contrib/llvm-project/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -47038,10 +47038,13 @@ static SDValue combineShiftRightArithmetic(SDNode *N, SelectionDAG &DAG,
if (SDValue V = combineShiftToPMULH(N, DAG, Subtarget))
return V;
- // fold (ashr (shl, a, [56,48,32,24,16]), SarConst)
- // into (shl, (sext (a), [56,48,32,24,16] - SarConst)) or
- // into (lshr, (sext (a), SarConst - [56,48,32,24,16]))
- // depending on sign of (SarConst - [56,48,32,24,16])
+ // fold (SRA (SHL X, ShlConst), SraConst)
+ // into (SHL (sext_in_reg X), ShlConst - SraConst)
+ // or (sext_in_reg X)
+ // or (SRA (sext_in_reg X), SraConst - ShlConst)
+ // depending on relation between SraConst and ShlConst.
+ // We only do this if (Size - ShlConst) is equal to 8, 16 or 32. That allows
+ // us to do the sext_in_reg from corresponding bit.
// sexts in X86 are MOVs. The MOVs have the same code size
// as above SHIFTs (only SHIFT on 1 has lower code size).
@@ -47057,29 +47060,29 @@ static SDValue combineShiftRightArithmetic(SDNode *N, SelectionDAG &DAG,
SDValue N00 = N0.getOperand(0);
SDValue N01 = N0.getOperand(1);
APInt ShlConst = N01->getAsAPIntVal();
- APInt SarConst = N1->getAsAPIntVal();
+ APInt SraConst = N1->getAsAPIntVal();
EVT CVT = N1.getValueType();
- if (SarConst.isNegative())
+ if (CVT != N01.getValueType())
+ return SDValue();
+ if (SraConst.isNegative())
return SDValue();
for (MVT SVT : { MVT::i8, MVT::i16, MVT::i32 }) {
unsigned ShiftSize = SVT.getSizeInBits();
- // skipping types without corresponding sext/zext and
- // ShlConst that is not one of [56,48,32,24,16]
+ // Only deal with (Size - ShlConst) being equal to 8, 16 or 32.
if (ShiftSize >= Size || ShlConst != Size - ShiftSize)
continue;
SDLoc DL(N);
SDValue NN =
DAG.getNode(ISD::SIGN_EXTEND_INREG, DL, VT, N00, DAG.getValueType(SVT));
- SarConst = SarConst - (Size - ShiftSize);
- if (SarConst == 0)
+ if (SraConst.eq(ShlConst))
return NN;
- if (SarConst.isNegative())
+ if (SraConst.ult(ShlConst))
return DAG.getNode(ISD::SHL, DL, VT, NN,
- DAG.getConstant(-SarConst, DL, CVT));
+ DAG.getConstant(ShlConst - SraConst, DL, CVT));
return DAG.getNode(ISD::SRA, DL, VT, NN,
- DAG.getConstant(SarConst, DL, CVT));
+ DAG.getConstant(SraConst - ShlConst, DL, CVT));
}
return SDValue();
}
diff --git a/contrib/llvm-project/llvm/lib/Target/X86/X86Subtarget.h b/contrib/llvm-project/llvm/lib/Target/X86/X86Subtarget.h
index a458b5f9ec8f..4d55a084b730 100644
--- a/contrib/llvm-project/llvm/lib/Target/X86/X86Subtarget.h
+++ b/contrib/llvm-project/llvm/lib/Target/X86/X86Subtarget.h
@@ -244,7 +244,8 @@ public:
// TODO: Currently we're always allowing widening on CPUs without VLX,
// because for many cases we don't have a better option.
bool canExtendTo512DQ() const {
- return hasAVX512() && (!hasVLX() || getPreferVectorWidth() >= 512);
+ return hasAVX512() && hasEVEX512() &&
+ (!hasVLX() || getPreferVectorWidth() >= 512);
}
bool canExtendTo512BW() const {
return hasBWI() && canExtendTo512DQ();
diff --git a/contrib/llvm-project/llvm/lib/TargetParser/Host.cpp b/contrib/llvm-project/llvm/lib/TargetParser/Host.cpp
index 4466d50458e1..1adef15771fa 100644
--- a/contrib/llvm-project/llvm/lib/TargetParser/Host.cpp
+++ b/contrib/llvm-project/llvm/lib/TargetParser/Host.cpp
@@ -1266,8 +1266,10 @@ static void getAvailableFeatures(unsigned ECX, unsigned EDX, unsigned MaxLeaf,
setFeature(X86::FEATURE_AVX2);
if (HasLeaf7 && ((EBX >> 8) & 1))
setFeature(X86::FEATURE_BMI2);
- if (HasLeaf7 && ((EBX >> 16) & 1) && HasAVX512Save)
+ if (HasLeaf7 && ((EBX >> 16) & 1) && HasAVX512Save) {
setFeature(X86::FEATURE_AVX512F);
+ setFeature(X86::FEATURE_EVEX512);
+ }
if (HasLeaf7 && ((EBX >> 17) & 1) && HasAVX512Save)
setFeature(X86::FEATURE_AVX512DQ);
if (HasLeaf7 && ((EBX >> 19) & 1))
@@ -1772,6 +1774,7 @@ bool sys::getHostCPUFeatures(StringMap<bool> &Features) {
Features["rtm"] = HasLeaf7 && ((EBX >> 11) & 1);
// AVX512 is only supported if the OS supports the context save for it.
Features["avx512f"] = HasLeaf7 && ((EBX >> 16) & 1) && HasAVX512Save;
+ Features["evex512"] = Features["avx512f"];
Features["avx512dq"] = HasLeaf7 && ((EBX >> 17) & 1) && HasAVX512Save;
Features["rdseed"] = HasLeaf7 && ((EBX >> 18) & 1);
Features["adx"] = HasLeaf7 && ((EBX >> 19) & 1);
diff --git a/contrib/llvm-project/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/contrib/llvm-project/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
index 9f220ec003ec..8cc7901cbac7 100644
--- a/contrib/llvm-project/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
+++ b/contrib/llvm-project/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
@@ -2606,7 +2606,7 @@ static Instruction *foldSelectWithSRem(SelectInst &SI, InstCombinerImpl &IC,
// %cnd = icmp slt i32 %rem, 0
// %add = add i32 %rem, %n
// %sel = select i1 %cnd, i32 %add, i32 %rem
- if (match(TrueVal, m_Add(m_Value(RemRes), m_Value(Remainder))) &&
+ if (match(TrueVal, m_Add(m_Specific(RemRes), m_Value(Remainder))) &&
match(RemRes, m_SRem(m_Value(Op), m_Specific(Remainder))) &&
IC.isKnownToBeAPowerOfTwo(Remainder, /*OrZero*/ true) &&
FalseVal == RemRes)
diff --git a/contrib/llvm-project/llvm/lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp b/contrib/llvm-project/llvm/lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp
index 9df28747570c..104e8ceb7967 100644
--- a/contrib/llvm-project/llvm/lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp
+++ b/contrib/llvm-project/llvm/lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp
@@ -279,6 +279,9 @@ bool InductiveRangeCheck::parseRangeCheckICmp(Loop *L, ICmpInst *ICI,
Value *LHS = ICI->getOperand(0);
Value *RHS = ICI->getOperand(1);
+ if (!LHS->getType()->isIntegerTy())
+ return false;
+
// Canonicalize to the `Index Pred Invariant` comparison
if (IsLoopInvariant(LHS)) {
std::swap(LHS, RHS);
diff --git a/contrib/llvm-project/openmp/runtime/src/kmp_settings.cpp b/contrib/llvm-project/openmp/runtime/src/kmp_settings.cpp
index ec86ee07472c..58f19ea5b8ab 100644
--- a/contrib/llvm-project/openmp/runtime/src/kmp_settings.cpp
+++ b/contrib/llvm-project/openmp/runtime/src/kmp_settings.cpp
@@ -6426,6 +6426,8 @@ void __kmp_env_initialize(char const *string) {
}
if ((__kmp_nested_proc_bind.bind_types[0] != proc_bind_intel) &&
(__kmp_nested_proc_bind.bind_types[0] != proc_bind_default)) {
+ if (__kmp_nested_proc_bind.bind_types[0] == proc_bind_false)
+ __kmp_affinity.type = affinity_none;
if (__kmp_affinity.type == affinity_default) {
__kmp_affinity.type = affinity_compact;
__kmp_affinity.flags.dups = FALSE;
diff --git a/contrib/llvm-project/openmp/runtime/src/z_Linux_util.cpp b/contrib/llvm-project/openmp/runtime/src/z_Linux_util.cpp
index b9ff96873702..97ddb8a608b7 100644
--- a/contrib/llvm-project/openmp/runtime/src/z_Linux_util.cpp
+++ b/contrib/llvm-project/openmp/runtime/src/z_Linux_util.cpp
@@ -2129,10 +2129,10 @@ int __kmp_is_address_mapped(void *addr) {
// We pass from number of vm entry's semantic
// to size of whole entry map list.
lstsz = lstsz * 4 / 3;
- buf = reinterpret_cast<char *>(kmpc_malloc(lstsz));
+ buf = reinterpret_cast<char *>(KMP_INTERNAL_MALLOC(lstsz));
rc = sysctl(mib, 4, buf, &lstsz, NULL, 0);
if (rc < 0) {
- kmpc_free(buf);
+ KMP_INTERNAL_FREE(buf);
return 0;
}
@@ -2156,7 +2156,7 @@ int __kmp_is_address_mapped(void *addr) {
}
lw += cursz;
}
- kmpc_free(buf);
+ KMP_INTERNAL_FREE(buf);
#elif KMP_OS_DARWIN
diff --git a/contrib/netbsd-tests/fs/tmpfs/t_times.sh b/contrib/netbsd-tests/fs/tmpfs/t_times.sh
index 2d8eb6f67aa0..7b3be8d98d03 100755
--- a/contrib/netbsd-tests/fs/tmpfs/t_times.sh
+++ b/contrib/netbsd-tests/fs/tmpfs/t_times.sh
@@ -70,8 +70,6 @@ holey_head() {
atf_set "require.user" "root"
}
holey_body() {
- atf_expect_fail "https://bugs.freebsd.org/274615"
-
test_mount
atf_check -s eq:0 -o empty -e empty truncate -s 8k a
diff --git a/etc/mtree/BSD.var.dist b/etc/mtree/BSD.var.dist
index 6f2327b59f0c..0845d8a59f65 100644
--- a/etc/mtree/BSD.var.dist
+++ b/etc/mtree/BSD.var.dist
@@ -53,8 +53,6 @@
..
ports
..
- portsnap
- ..
zfsd tags=package=zfs
cases
..
diff --git a/lib/clang/include/VCSVersion.inc b/lib/clang/include/VCSVersion.inc
index 687fb1656937..c4bb0df4e3a5 100644
--- a/lib/clang/include/VCSVersion.inc
+++ b/lib/clang/include/VCSVersion.inc
@@ -1,8 +1,8 @@
-#define LLVM_REVISION "llvmorg-18.1.4-0-ge6c3289804a6"
+#define LLVM_REVISION "llvmorg-18.1.5-0-g617a15a9eac9"
#define LLVM_REPOSITORY "https://github.com/llvm/llvm-project.git"
-#define CLANG_REVISION "llvmorg-18.1.4-0-ge6c3289804a6"
+#define CLANG_REVISION "llvmorg-18.1.5-0-g617a15a9eac9"
#define CLANG_REPOSITORY "https://github.com/llvm/llvm-project.git"
-#define LLDB_REVISION "llvmorg-18.1.4-0-ge6c3289804a6"
+#define LLDB_REVISION "llvmorg-18.1.5-0-g617a15a9eac9"
#define LLDB_REPOSITORY "https://github.com/llvm/llvm-project.git"
diff --git a/lib/clang/include/clang/Basic/Version.inc b/lib/clang/include/clang/Basic/Version.inc
index 536f72efec52..c243016c5f73 100644
--- a/lib/clang/include/clang/Basic/Version.inc
+++ b/lib/clang/include/clang/Basic/Version.inc
@@ -1,8 +1,8 @@
-#define CLANG_VERSION 18.1.4
-#define CLANG_VERSION_STRING "18.1.4"
+#define CLANG_VERSION 18.1.5
+#define CLANG_VERSION_STRING "18.1.5"
#define CLANG_VERSION_MAJOR 18
#define CLANG_VERSION_MAJOR_STRING "18"
#define CLANG_VERSION_MINOR 1
-#define CLANG_VERSION_PATCHLEVEL 4
+#define CLANG_VERSION_PATCHLEVEL 5
#define CLANG_VENDOR "FreeBSD "
diff --git a/lib/clang/include/lld/Common/Version.inc b/lib/clang/include/lld/Common/Version.inc
index 65838f76ba5d..4079a361ce8d 100644
--- a/lib/clang/include/lld/Common/Version.inc
+++ b/lib/clang/include/lld/Common/Version.inc
@@ -1,4 +1,4 @@
// Local identifier in __FreeBSD_version style
#define LLD_FREEBSD_VERSION 1400006
-#define LLD_VERSION_STRING "18.1.4 (FreeBSD llvmorg-18.1.4-0-ge6c3289804a6-" __XSTRING(LLD_FREEBSD_VERSION) ")"
+#define LLD_VERSION_STRING "18.1.5 (FreeBSD llvmorg-18.1.5-0-g617a15a9eac9-" __XSTRING(LLD_FREEBSD_VERSION) ")"
diff --git a/lib/clang/include/lldb/Version/Version.inc b/lib/clang/include/lldb/Version/Version.inc
index 1fc1a4d88b7b..0e86bd2e01ba 100644
--- a/lib/clang/include/lldb/Version/Version.inc
+++ b/lib/clang/include/lldb/Version/Version.inc
@@ -1,6 +1,6 @@
-#define LLDB_VERSION 18.1.4
-#define LLDB_VERSION_STRING "18.1.4"
+#define LLDB_VERSION 18.1.5
+#define LLDB_VERSION_STRING "18.1.5"
#define LLDB_VERSION_MAJOR 18
#define LLDB_VERSION_MINOR 1
-#define LLDB_VERSION_PATCH 4
+#define LLDB_VERSION_PATCH 5
/* #undef LLDB_FULL_VERSION_STRING */
diff --git a/lib/clang/include/llvm/Config/AsmParsers.def b/lib/clang/include/llvm/Config/AsmParsers.def
index afd86d898673..3dccab75a285 100644
--- a/lib/clang/include/llvm/Config/AsmParsers.def
+++ b/lib/clang/include/llvm/Config/AsmParsers.def
@@ -42,9 +42,6 @@ LLVM_ASM_PARSER(PowerPC)
#ifdef LLVM_TARGET_ENABLE_RISCV
LLVM_ASM_PARSER(RISCV)
#endif
-#ifdef LLVM_TARGET_ENABLE_SPARC
-LLVM_ASM_PARSER(Sparc)
-#endif
#ifdef LLVM_TARGET_ENABLE_X86
LLVM_ASM_PARSER(X86)
#endif
diff --git a/lib/clang/include/llvm/Config/AsmPrinters.def b/lib/clang/include/llvm/Config/AsmPrinters.def
index ffcca0730101..649b8353c926 100644
--- a/lib/clang/include/llvm/Config/AsmPrinters.def
+++ b/lib/clang/include/llvm/Config/AsmPrinters.def
@@ -42,9 +42,6 @@ LLVM_ASM_PRINTER(PowerPC)
#ifdef LLVM_TARGET_ENABLE_RISCV
LLVM_ASM_PRINTER(RISCV)
#endif
-#ifdef LLVM_TARGET_ENABLE_SPARC
-LLVM_ASM_PRINTER(Sparc)
-#endif
#ifdef LLVM_TARGET_ENABLE_X86
LLVM_ASM_PRINTER(X86)
#endif
diff --git a/lib/clang/include/llvm/Config/Disassemblers.def b/lib/clang/include/llvm/Config/Disassemblers.def
index 18e29e3a09ff..c44fa4e303e2 100644
--- a/lib/clang/include/llvm/Config/Disassemblers.def
+++ b/lib/clang/include/llvm/Config/Disassemblers.def
@@ -42,9 +42,6 @@ LLVM_DISASSEMBLER(PowerPC)
#ifdef LLVM_TARGET_ENABLE_RISCV
LLVM_DISASSEMBLER(RISCV)
#endif
-#ifdef LLVM_TARGET_ENABLE_SPARC
-LLVM_DISASSEMBLER(Sparc)
-#endif
#ifdef LLVM_TARGET_ENABLE_X86
LLVM_DISASSEMBLER(X86)
#endif
diff --git a/lib/clang/include/llvm/Config/Targets.def b/lib/clang/include/llvm/Config/Targets.def
index 604fd9337048..d3332a51a2cc 100644
--- a/lib/clang/include/llvm/Config/Targets.def
+++ b/lib/clang/include/llvm/Config/Targets.def
@@ -41,9 +41,6 @@ LLVM_TARGET(PowerPC)
#ifdef LLVM_TARGET_ENABLE_RISCV
LLVM_TARGET(RISCV)
#endif
-#ifdef LLVM_TARGET_ENABLE_SPARC
-LLVM_TARGET(Sparc)
-#endif
#ifdef LLVM_TARGET_ENABLE_X86
LLVM_TARGET(X86)
#endif
diff --git a/lib/clang/include/llvm/Config/config.h b/lib/clang/include/llvm/Config/config.h
index a017437dc568..0760c0b17a87 100644
--- a/lib/clang/include/llvm/Config/config.h
+++ b/lib/clang/include/llvm/Config/config.h
@@ -344,10 +344,10 @@
#define PACKAGE_NAME "LLVM"
/* Define to the full name and version of this package. */
-#define PACKAGE_STRING "LLVM 18.1.4"
+#define PACKAGE_STRING "LLVM 18.1.5"
/* Define to the version of this package. */
-#define PACKAGE_VERSION "18.1.4"
+#define PACKAGE_VERSION "18.1.5"
/* Define to the vendor of this package. */
/* #undef PACKAGE_VENDOR */
diff --git a/lib/clang/include/llvm/Config/llvm-config.h b/lib/clang/include/llvm/Config/llvm-config.h
index fb878ccdde4d..049529efdd7f 100644
--- a/lib/clang/include/llvm/Config/llvm-config.h
+++ b/lib/clang/include/llvm/Config/llvm-config.h
@@ -130,11 +130,7 @@
#endif
/* Define if the Sparc target is built in */
-#ifdef LLVM_TARGET_ENABLE_SPARC
-#define LLVM_HAS_SPARC_TARGET 1
-#else
#define LLVM_HAS_SPARC_TARGET 0
-#endif
/* Define if the SPIRV target is built in */
#define LLVM_HAS_SPIRV_TARGET 0
@@ -180,10 +176,10 @@
#define LLVM_VERSION_MINOR 1
/* Patch version of the LLVM API */
-#define LLVM_VERSION_PATCH 4
+#define LLVM_VERSION_PATCH 5
/* LLVM version string */
-#define LLVM_VERSION_STRING "18.1.4"
+#define LLVM_VERSION_STRING "18.1.5"
/* Whether LLVM records statistics for use with GetStatistics(),
* PrintStatistics() or PrintStatisticsJSON()
diff --git a/lib/clang/include/llvm/Support/VCSRevision.h b/lib/clang/include/llvm/Support/VCSRevision.h
index e324de0f9fc6..433b2b53b8fe 100644
--- a/lib/clang/include/llvm/Support/VCSRevision.h
+++ b/lib/clang/include/llvm/Support/VCSRevision.h
@@ -1,2 +1,2 @@
-#define LLVM_REVISION "llvmorg-18.1.4-0-ge6c3289804a6"
+#define LLVM_REVISION "llvmorg-18.1.5-0-g617a15a9eac9"
#define LLVM_REPOSITORY "https://github.com/llvm/llvm-project.git"
diff --git a/lib/geom/eli/geli.8 b/lib/geom/eli/geli.8
index c378c591290c..098ba4d0485e 100644
--- a/lib/geom/eli/geli.8
+++ b/lib/geom/eli/geli.8
@@ -22,7 +22,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd April 18, 2022
+.Dd April 24, 2024
.Dt GELI 8
.Os
.Sh NAME
@@ -851,6 +851,15 @@ This variable should be set in
Specifies how many times the Master Key is overwritten
with random values when it is destroyed.
After this operation it is filled with zeros.
+.It Va kern.geom.eli.use_uma_bytes
+.Nm
+must allocate a buffer for every write operation, used when performing
+encryption.
+This sysctl reports the maximum size in bytes for which geli will perform the
+allocation using
+.Xr UMA 9 ,
+as opposed to
+.Xr malloc 9 .
.It Va kern.geom.eli.visible_passphrase : No 0
If set to 1, the passphrase entered on boot will be visible.
This alternative should be used with caution as the entered
@@ -863,11 +872,14 @@ Specifies how many kernel threads should be used for doing software
cryptography.
Its purpose is to increase performance on SMP systems.
If set to 0, a CPU-pinned thread will be started for every active CPU.
+Note that this variable must be set prior to attaching
+.Nm
+to a disk.
.It Va kern.geom.eli.batch : No 0
When set to 1, can speed-up crypto operations by using batching.
Batching reduces the number of interrupts by responding to a group of
crypto requests with one interrupt.
-The crypto card and the driver has to support this feature.
+The crypto card and the driver have to support this feature.
.It Va kern.geom.eli.key_cache_limit : No 8192
Specifies how many Data Keys to cache.
The default limit
@@ -884,13 +896,41 @@ Reports how many times we were looking up a Data Key and it was not in cache.
This sysctl is not updated for providers that need fewer Data Keys than the limit
specified in
.Va kern.geom.eli.key_cache_limit .
-.Va kern.geom.eli.unmapped_io
+.It Va kern.geom.eli.unmapped_io
Enable support for unmapped I/O buffers, currently implemented only on 64-bit
platforms.
This is an optimization which reduces the overhead of I/O processing.
This variable is intended for debugging purposes and must be set in
.Pa /boot/loader.conf .
.El
+.Sh PERFORMANCE CONSIDERATIONS
+The default value of
+.Va kern.geom.eli.threads
+is usually good for a system with one SSD.
+However, it may need to be lowered on systems with many disks,
+so as to avoid creating too much thread-switching overhead.
+On systems with more disks than CPUs, it's best to set this variable
+to 1.
+.Pp
+.Nm
+internally uses
+.Xr malloc 9
+to allocate memory for operations larger than
+.Va kern.geom.eli.use_uma_bytes ,
+but malloc is slow for allocations larger than
+.Va vm.kmem_zmax .
+So it's best to avoid writing more than
+.Ms MAX(kern.geom.eli.use_uma_bytes, vm.kmem_zmax)
+in a single write operation.
+On systems that format
+.Xr zfs 4
+on top of
+.Nm ,
+the maximum write size can be controlled by
+.Va vfs.zfs.vdev.aggregation_limit
+and
+.Va vfs.zfs.vdev.aggregation_limit_non_rotating
+for HDDs and SSDs, respectively.
.Sh EXIT STATUS
Exit status is 0 on success, and 1 if the command fails.
.Sh EXAMPLES
diff --git a/lib/libc/gen/dlopen.3 b/lib/libc/gen/dlopen.3
index 09f37ff2fa93..340545114114 100644
--- a/lib/libc/gen/dlopen.3
+++ b/lib/libc/gen/dlopen.3
@@ -29,9 +29,7 @@
.\"
.\" Copyright (c) 1991 Sun Microsystems, Inc.
.\"
-.\" @(#) dlopen.3 1.6 90/01/31 SMI
-.\"
-.Dd May 14, 2020
+.Dd May 7, 2024
.Dt DLOPEN 3
.Os
.Sh NAME
@@ -201,6 +199,10 @@ The
function can be used by the code that needs to perform
additional checks on the loaded objects, to prevent races with
symlinking or renames.
+Applications sandboxed using
+.Xr capsicum 4
+can also make beneficial use of
+.Fn fdlopen .
.Pp
The
.Fn dlsym
diff --git a/lib/libc/stdlib/cxa_thread_atexit_impl.c b/lib/libc/stdlib/cxa_thread_atexit_impl.c
index f95384b30347..3123bd12dca8 100644
--- a/lib/libc/stdlib/cxa_thread_atexit_impl.c
+++ b/lib/libc/stdlib/cxa_thread_atexit_impl.c
@@ -102,7 +102,7 @@ walk_cb_call(struct cxa_thread_dtor *dtor)
{
struct dl_phdr_info phdr_info;
- if (_rtld_addr_phdr(dtor->dso, &phdr_info) &&
+ if (_rtld_addr_phdr(dtor->func, &phdr_info) &&
__elf_phdr_match_addr(&phdr_info, dtor->func))
dtor->func(dtor->obj);
else
diff --git a/lib/libc/sys/clock_gettime.2 b/lib/libc/sys/clock_gettime.2
index ed469153a40e..c8bef4c5424f 100644
--- a/lib/libc/sys/clock_gettime.2
+++ b/lib/libc/sys/clock_gettime.2
@@ -94,29 +94,29 @@ Returns the execution time of the calling thread.
.El
.Pp
The clock IDs
-.Fa CLOCK_REALTIME ,
-.Fa CLOCK_MONOTONIC ,
+.Dv CLOCK_REALTIME ,
+.Dv CLOCK_MONOTONIC ,
and
-.Fa CLOCK_UPTIME
+.Dv CLOCK_UPTIME
perform a full time counter query.
The clock IDs with the _FAST suffix, i.e.,
-.Fa CLOCK_REALTIME_FAST ,
-.Fa CLOCK_MONOTONIC_FAST ,
+.Dv CLOCK_REALTIME_FAST ,
+.Dv CLOCK_MONOTONIC_FAST ,
and
-.Fa CLOCK_UPTIME_FAST ,
+.Dv CLOCK_UPTIME_FAST ,
do not perform
a full time counter query, so their accuracy is one timer tick.
Similarly,
-.Fa CLOCK_REALTIME_PRECISE ,
-.Fa CLOCK_MONOTONIC_PRECISE ,
+.Dv CLOCK_REALTIME_PRECISE ,
+.Dv CLOCK_MONOTONIC_PRECISE ,
and
-.Fa CLOCK_UPTIME_PRECISE
+.Dv CLOCK_UPTIME_PRECISE
are used to get the most exact value as possible, at the expense of
execution time.
The clock IDs
-.Fa CLOCK_REALTIME_COARSE
+.Dv CLOCK_REALTIME_COARSE
and
-.Fa CLOCK_MONOTONIC_COARSE
+.Dv CLOCK_MONOTONIC_COARSE
are aliases of corresponding IDs with _FAST suffix for compatibility with other
systems.
Finally,
@@ -138,7 +138,7 @@ struct timespec {
.Ed
.Pp
Only the super-user may set the time of day, using only
-.Fa CLOCK_REALTIME .
+.Dv CLOCK_REALTIME .
If the system
.Xr securelevel 7
is greater than 1 (see
@@ -186,14 +186,14 @@ and
system calls conform to
.St -p1003.1b-93 .
The clock IDs
-.Fa CLOCK_REALTIME_FAST ,
-.Fa CLOCK_REALTIME_PRECISE ,
-.Fa CLOCK_MONOTONIC_FAST ,
-.Fa CLOCK_MONOTONIC_PRECISE ,
-.Fa CLOCK_UPTIME ,
-.Fa CLOCK_UPTIME_FAST ,
-.Fa CLOCK_UPTIME_PRECISE ,
-.Fa CLOCK_SECOND
+.Dv CLOCK_REALTIME_FAST ,
+.Dv CLOCK_REALTIME_PRECISE ,
+.Dv CLOCK_MONOTONIC_FAST ,
+.Dv CLOCK_MONOTONIC_PRECISE ,
+.Dv CLOCK_UPTIME ,
+.Dv CLOCK_UPTIME_FAST ,
+.Dv CLOCK_UPTIME_PRECISE ,
+.Dv CLOCK_SECOND
are
.Fx
extensions to the POSIX interface.
diff --git a/lib/libpfctl/libpfctl.c b/lib/libpfctl/libpfctl.c
index f43fb78d9a0f..7dc375717acc 100644
--- a/lib/libpfctl/libpfctl.c
+++ b/lib/libpfctl/libpfctl.c
@@ -250,7 +250,7 @@ pfctl_get_status(int dev)
_pfctl_get_status_counters(nvlist_get_nvlist(nvl, "scounters"),
&status->scounters);
- pf_nvuint_64_array(nvl, "pcounters", 2 * 2 * 3,
+ pf_nvuint_64_array(nvl, "pcounters", 2 * 2 * 2,
(uint64_t *)status->pcounters, NULL);
pf_nvuint_64_array(nvl, "bcounters", 2 * 2,
(uint64_t *)status->bcounters, NULL);
diff --git a/lib/libpfctl/libpfctl.h b/lib/libpfctl/libpfctl.h
index edaffdd12118..a2991cc05b04 100644
--- a/lib/libpfctl/libpfctl.h
+++ b/lib/libpfctl/libpfctl.h
@@ -62,7 +62,7 @@ struct pfctl_status {
struct pfctl_status_counters lcounters;
struct pfctl_status_counters fcounters;
struct pfctl_status_counters scounters;
- uint64_t pcounters[2][2][3];
+ uint64_t pcounters[2][2][2];
uint64_t bcounters[2][2];
};
diff --git a/libexec/phttpget/phttpget.8 b/libexec/phttpget/phttpget.8
index b82c788c53c6..16e0be65cd4c 100644
--- a/libexec/phttpget/phttpget.8
+++ b/libexec/phttpget/phttpget.8
@@ -49,9 +49,7 @@ small files need to be downloaded.
.Pp
The
.Xr freebsd-update 8
-and
-.Xr portsnap 8
-tools use
+tool uses
.Nm
to download binary patch files.
.Sh ENVIRONMENT
@@ -69,17 +67,16 @@ Timeout for HTTP request in seconds.
.El
.Sh SEE ALSO
.Xr fetch 1 ,
-.Xr freebsd-update 8 ,
-.Xr portsnap 8
+.Xr freebsd-update 8
.Sh AUTHORS
.An -nosplit
The
.Nm
utility was written by
.An Colin Percival Aq Mt cperciva@FreeBSD.org
-for use with
+initially for use with
.Xr portsnap 8
-and later with
+(now removed) and has been used by
.Xr freebsd-update 8 .
This manual page was written by
.An Xin LI Aq Mt delphij@FreeBSD.org .
diff --git a/libexec/rc/rc.d/devmatch b/libexec/rc/rc.d/devmatch
index 78050cfa4541..67bb14761614 100755
--- a/libexec/rc/rc.d/devmatch
+++ b/libexec/rc/rc.d/devmatch
@@ -46,6 +46,7 @@ devmatch_start()
if [ -n "$one_nomatch" ]; then
list=$(devmatch -p "${one_nomatch}" | sort -u)
else
+ sysctl hw.bus.devctl_nomatch_enabled=1
list=$(devmatch | sort -u)
fi
diff --git a/libexec/rtld-elf/rtld.1 b/libexec/rtld-elf/rtld.1
index a152dd444bd7..4cc5b639c89a 100644
--- a/libexec/rtld-elf/rtld.1
+++ b/libexec/rtld-elf/rtld.1
@@ -26,7 +26,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 29, 2023
+.Dd April 28, 2024
.Dt RTLD 1
.Os
.Sh NAME
@@ -352,6 +352,7 @@ The syntax of the direct invocation is
.Op Fl b Ar exe
.Op Fl d
.Op Fl f Ar fd
+.Op Fl o Ar OPT=NAME
.Op Fl p
.Op Fl u
.Op Fl v
@@ -387,6 +388,23 @@ If this option is specified,
is only used to provide the
.Va argv[0]
value to the program.
+.It Fl o Ar OPT=VALUE
+Set the
+.Ar OPT
+configuration variable to the value
+.Ar VALUE .
+The possible variable names are listed above as
+.Ev LD_
+prefixed environment variables, but here are referenced without the
+.Ev LD_
+prefix.
+A configuration variable set this way does not leak into
+the activated image's environment.
+.Pp
+The option can be repeated as many times as needed to set
+all configuration parameters.
+The parameters set using this option have priority over
+the same parameters assigned via environment.
.It Fl p
If the
.Pa image_path
@@ -400,7 +418,9 @@ to find the binary to execute.
.It Fl u
Ignore all
.Ev LD_
-environment variables that otherwise affect the dynamic
+environment variables and previous command line
+.Fl o
+options that otherwise affect the dynamic
linker behavior.
.It Fl v
Display information about this run-time linker binary, then exit.
diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c
index d5e702652058..96042f7b5af3 100644
--- a/libexec/rtld-elf/rtld.c
+++ b/libexec/rtld-elf/rtld.c
@@ -6155,10 +6155,42 @@ parse_args(char* argv[], int argc, bool *use_pathp, int *fdp,
*fdp = fd;
seen_f = true;
break;
+ } else if (opt == 'o') {
+ struct ld_env_var_desc *l;
+ char *n, *v;
+ u_int ll;
+
+ if (j != arglen - 1) {
+ _rtld_error("Invalid options: %s", arg);
+ rtld_die();
+ }
+ i++;
+ n = argv[i];
+ v = strchr(n, '=');
+ if (v == NULL) {
+ _rtld_error("No '=' in -o parameter");
+ rtld_die();
+ }
+ for (ll = 0; ll < nitems(ld_env_vars); ll++) {
+ l = &ld_env_vars[ll];
+ if (v - n == (ptrdiff_t)strlen(l->n) &&
+ strncmp(n, l->n, v - n) == 0) {
+ l->val = v + 1;
+ break;
+ }
+ }
+ if (ll == nitems(ld_env_vars)) {
+ _rtld_error("Unknown LD_ option %s",
+ n);
+ rtld_die();
+ }
} else if (opt == 'p') {
*use_pathp = true;
} else if (opt == 'u') {
- trust = false;
+ u_int ll;
+
+ for (ll = 0; ll < nitems(ld_env_vars); ll++)
+ ld_env_vars[ll].val = NULL;
} else if (opt == 'v') {
machine[0] = '\0';
mib[0] = CTL_HW;
@@ -6238,6 +6270,7 @@ print_usage(const char *argv0)
" -b <exe> Execute <exe> instead of <binary>, arg0 is <binary>\n"
" -d Ignore lack of exec permissions for the binary\n"
" -f <FD> Execute <FD> instead of searching for <binary>\n"
+ " -o <OPT>=<VAL> Set LD_<OPT> to <VAL>, without polluting env\n"
" -p Search in PATH for named binary\n"
" -u Ignore LD_ environment variables\n"
" -v Display identification information\n"
diff --git a/libexec/tftpd/tests/functional.c b/libexec/tftpd/tests/functional.c
index f31d2a893da1..32e5f85cf421 100644
--- a/libexec/tftpd/tests/functional.c
+++ b/libexec/tftpd/tests/functional.c
@@ -29,6 +29,7 @@
#include <sys/param.h>
#include <sys/socket.h>
#include <sys/stat.h>
+#include <sys/time.h>
#include <sys/wait.h>
#include <netinet/in.h>
diff --git a/libexec/tftpd/tftp-file.h b/libexec/tftpd/tftp-file.h
index 0fb7f6c1decc..c424e5cbc75b 100644
--- a/libexec/tftpd/tftp-file.h
+++ b/libexec/tftpd/tftp-file.h
@@ -25,7 +25,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
int write_init(int fd, FILE *f, const char *mode);
size_t write_file(char *buffer, int count);
int write_close(void);
diff --git a/libexec/tftpd/tftp-io.c b/libexec/tftpd/tftp-io.c
index b5f39423fd60..aaacc9dd7f45 100644
--- a/libexec/tftpd/tftp-io.c
+++ b/libexec/tftpd/tftp-io.c
@@ -72,13 +72,13 @@ static struct errmsg {
#define DROPPACKET(s) \
if (packetdroppercentage != 0 && \
- random()%100 < packetdroppercentage) { \
+ arc4random()%100 < packetdroppercentage) { \
tftp_log(LOG_DEBUG, "Artificial packet drop in %s", s); \
return; \
}
#define DROPPACKETn(s,n) \
if (packetdroppercentage != 0 && \
- random()%100 < packetdroppercentage) { \
+ arc4random()%100 < packetdroppercentage) { \
tftp_log(LOG_DEBUG, "Artificial packet drop in %s", s); \
return (n); \
}
@@ -157,10 +157,8 @@ send_error(int peer, int error)
pe->e_msg = strerror(error - 100);
tp->th_code = EUNDEF; /* set 'undef' errorcode */
}
- strcpy(tp->th_msg, pe->e_msg);
- length = strlen(pe->e_msg);
- tp->th_msg[length] = '\0';
- length += 5;
+ snprintf(tp->th_msg, MAXPKTSIZE - 4, "%s%n", pe->e_msg, &length);
+ length += 5; /* header and terminator */
if (debug & DEBUG_PACKETS)
tftp_log(LOG_DEBUG, "Sending ERROR %d: %s", error, tp->th_msg);
@@ -331,7 +329,6 @@ send_ack(int fp, uint16_t block)
DROPPACKETn("send_ack", 0);
tp = (struct tftphdr *)buf;
- size = sizeof(buf) - 2;
tp->th_opcode = htons((u_short)ACK);
tp->th_block = htons((u_short)block);
size = 4;
diff --git a/libexec/tftpd/tftp-io.h b/libexec/tftpd/tftp-io.h
index 85934e824a1a..1d6bc2bd8b5e 100644
--- a/libexec/tftpd/tftp-io.h
+++ b/libexec/tftpd/tftp-io.h
@@ -25,7 +25,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
#define RP_NONE 0
#define RP_RECVFROM -1
#define RP_TOOSMALL -2
diff --git a/libexec/tftpd/tftp-options.h b/libexec/tftpd/tftp-options.h
index c68db53de4e2..f1b0a5cfaf32 100644
--- a/libexec/tftpd/tftp-options.h
+++ b/libexec/tftpd/tftp-options.h
@@ -25,7 +25,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
/*
* Options
*/
diff --git a/libexec/tftpd/tftp-transfer.h b/libexec/tftpd/tftp-transfer.h
index 48431ebbc863..449f29c246e0 100644
--- a/libexec/tftpd/tftp-transfer.h
+++ b/libexec/tftpd/tftp-transfer.h
@@ -25,7 +25,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
int tftp_send(int peer, uint16_t *block, struct tftp_stats *tp);
int tftp_receive(int peer, uint16_t *block, struct tftp_stats *tp,
struct tftphdr *firstblock, size_t fb_size);
diff --git a/libexec/tftpd/tftp-utils.c b/libexec/tftpd/tftp-utils.c
index b309a94f7653..8ce7c09c9992 100644
--- a/libexec/tftpd/tftp-utils.c
+++ b/libexec/tftpd/tftp-utils.c
@@ -204,7 +204,7 @@ struct debugs debugs[] = {
{ DEBUG_ACCESS, "access", "TCPd access debugging" },
{ DEBUG_NONE, NULL, "No debugging" },
};
-int packetdroppercentage = 0;
+unsigned int packetdroppercentage = 0;
int
debug_find(char *s)
diff --git a/libexec/tftpd/tftp-utils.h b/libexec/tftpd/tftp-utils.h
index 763b3b493c7e..276dedcf74cd 100644
--- a/libexec/tftpd/tftp-utils.h
+++ b/libexec/tftpd/tftp-utils.h
@@ -25,7 +25,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
/*
*/
#define TIMEOUT 5
@@ -100,7 +99,7 @@ struct debugs {
};
extern int debug;
extern struct debugs debugs[];
-extern int packetdroppercentage;
+extern unsigned int packetdroppercentage;
int debug_find(char *s);
int debug_finds(char *s);
const char *debug_show(int d);
diff --git a/libexec/tftpd/tftpd.8 b/libexec/tftpd/tftpd.8
index 3de042197618..24a743a92e14 100644
--- a/libexec/tftpd/tftpd.8
+++ b/libexec/tftpd/tftpd.8
@@ -27,7 +27,7 @@
.\"
.\" @(#)tftpd.8 8.1 (Berkeley) 6/4/93
.\"
-.Dd July 20, 2023
+.Dd May 8, 2024
.Dt TFTPD 8
.Os
.Sh NAME
@@ -35,11 +35,11 @@
.Nd Internet Trivial File Transfer Protocol server
.Sh SYNOPSIS
.Nm tftpd
-.Op Fl cdClnow
+.Op Fl CcdlnoSw
.Op Fl F Ar strftime-format
.Op Fl s Ar directory
-.Op Fl u Ar user
.Op Fl U Ar umask
+.Op Fl u Ar user
.Op Ar directory ...
.Sh DESCRIPTION
The
diff --git a/libexec/tftpd/tftpd.c b/libexec/tftpd/tftpd.c
index 78348a8c6aaf..00c1257ce548 100644
--- a/libexec/tftpd/tftpd.c
+++ b/libexec/tftpd/tftpd.c
@@ -172,7 +172,7 @@ main(int argc, char *argv[])
options_extra_enabled = 0;
break;
case 'p':
- packetdroppercentage = atoi(optarg);
+ packetdroppercentage = (unsigned int)atoi(optarg);
tftp_log(LOG_INFO,
"Randomly dropping %d out of 100 packets",
packetdroppercentage);
@@ -463,9 +463,9 @@ static char *
parse_header(int peer, char *recvbuffer, size_t size,
char **filename, char **mode)
{
- char *cp;
- int i;
struct formats *pf;
+ char *cp;
+ size_t i;
*mode = NULL;
cp = recvbuffer;
@@ -482,12 +482,11 @@ parse_header(int peer, char *recvbuffer, size_t size,
i = get_field(peer, cp, size);
*mode = cp;
- cp += i;
/* Find the file transfer mode */
- for (cp = *mode; *cp; cp++)
- if (isupper(*cp))
- *cp = tolower(*cp);
+ for (; *cp; cp++)
+ if (isupper((unsigned char)*cp))
+ *cp = tolower((unsigned char)*cp);
for (pf = formats; pf->f_mode; pf++)
if (strcmp(pf->f_mode, *mode) == 0)
break;
@@ -624,12 +623,20 @@ tftp_rrq(int peer, char *recvbuffer, size_t size)
static int
find_next_name(char *filename, int *fd)
{
- int i;
+ /*
+ * GCC "knows" that we might write all of yyyymmdd plus the static
+ * elemenents in the format into into newname and thus complains
+ * unless we reduce the size. This array is still too big, but since
+ * the format is user supplied, it's not clear what a better limit
+ * value would be and this is sufficent to silence the warnings.
+ */
+ static const int suffix_len = strlen("..00");
+ char yyyymmdd[MAXPATHLEN - suffix_len];
+ char newname[MAXPATHLEN];
+ int i, ret;
time_t tval;
- size_t len;
+ size_t len, namelen;
struct tm lt;
- char yyyymmdd[MAXPATHLEN];
- char newname[MAXPATHLEN];
/* Create the YYYYMMDD part of the filename */
time(&tval);
@@ -637,26 +644,33 @@ find_next_name(char *filename, int *fd)
len = strftime(yyyymmdd, sizeof(yyyymmdd), newfile_format, &lt);
if (len == 0) {
syslog(LOG_WARNING,
- "Filename suffix too long (%d characters maximum)",
- MAXPATHLEN);
+ "Filename suffix too long (%zu characters maximum)",
+ sizeof(yyyymmdd) - 1);
return (EACCESS);
}
/* Make sure the new filename is not too long */
- if (strlen(filename) > MAXPATHLEN - len - 5) {
+ namelen = strlen(filename);
+ if (namelen >= sizeof(newname) - len - suffix_len) {
syslog(LOG_WARNING,
- "Filename too long (%zd characters, %zd maximum)",
- strlen(filename), MAXPATHLEN - len - 5);
+ "Filename too long (%zu characters, %zu maximum)",
+ namelen,
+ sizeof(newname) - len - suffix_len - 1);
return (EACCESS);
}
/* Find the first file which doesn't exist */
for (i = 0; i < 100; i++) {
- sprintf(newname, "%s.%s.%02d", filename, yyyymmdd, i);
- *fd = open(newname,
- O_WRONLY | O_CREAT | O_EXCL,
- S_IRUSR | S_IWUSR | S_IRGRP |
- S_IWGRP | S_IROTH | S_IWOTH);
+ ret = snprintf(newname, sizeof(newname), "%s.%s.%02d",
+ filename, yyyymmdd, i);
+ /*
+ * Size checked above so this can't happen, we'd use a
+ * (void) cast, but gcc intentionally ignores that if
+ * snprintf has __attribute__((warn_unused_result)).
+ */
+ if (ret < 0 || (size_t)ret >= sizeof(newname))
+ __unreachable();
+ *fd = open(newname, O_WRONLY | O_CREAT | O_EXCL, 0666);
if (*fd > 0)
return 0;
}
diff --git a/release/Makefile.mirrors b/release/Makefile.mirrors
index cbc5cd768e28..591fd85b29ea 100644
--- a/release/Makefile.mirrors
+++ b/release/Makefile.mirrors
@@ -193,6 +193,16 @@ vm-images-stage:
cd ${VM_DIR}/Latest && \
ln -s ../${BUILDDATE}/${OSRELEASE}-${SNAP_SUFFIX}.${VMFORMAT}.xz \
${OSRELEASE}.${VMFORMAT}.xz
+. for FS in ${VMFSLIST}
+ cd ${RELEASEDIR}/vmimages && \
+ mv ${OSRELEASE}-${FS}.${VMFORMAT}.xz \
+ ${OSRELEASE}-${FS}-${SNAP_SUFFIX}.${VMFORMAT}.xz
+ cp -p ${RELEASEDIR}/vmimages/${OSRELEASE}-${FS}-${SNAP_SUFFIX}.${VMFORMAT}.xz \
+ ${VM_DIR}/${BUILDDATE}/${OSRELEASE}-${FS}-${SNAP_SUFFIX}.${VMFORMAT}.xz
+ cd ${VM_DIR}/Latest && \
+ ln -s ../${BUILDDATE}/${OSRELEASE}-${FS}-${SNAP_SUFFIX}.${VMFORMAT}.xz \
+ ${OSRELEASE}-${FS}.${VMFORMAT}.xz
+. endfor
. endfor
cd ${RELEASEDIR}/vmimages && rm -f CHECKSUM.*
. for CHECKSUM in ${CHECKSUM_FILES}
@@ -212,6 +222,10 @@ vm-images-stage:
. for VMFORMAT in ${VMFORMATS}
cp -p ${RELEASEDIR}/vmimages/${OSRELEASE}.${VMFORMAT}.xz \
${VM_DIR}/Latest/${OSRELEASE}.${VMFORMAT}.xz
+. for FS in ${VMFSLIST}
+ cp -p ${RELEASEDIR}/vmimages/${OSRELEASE}-${FS}.${VMFORMAT}.xz \
+ ${VM_DIR}/Latest/${OSRELEASE}-${FS}.${VMFORMAT}.xz
+. endfor
. endfor
. for CHECKSUM in ${CHECKSUM_FILES}
cp -p ${RELEASEDIR}/vmimages/CHECKSUM.${CHECKSUM} \
diff --git a/release/Makefile.vm b/release/Makefile.vm
index 0eb549ec7bc2..95d48490c353 100644
--- a/release/Makefile.vm
+++ b/release/Makefile.vm
@@ -157,12 +157,13 @@ CLEANFILES+= ${VMBASE}.${FS}.${FORMAT}
vm-base: vm-image
-vm-image:
+vm-image: ${QEMUTGT}
.if defined(WITH_VMIMAGES) && !empty(WITH_VMIMAGES)
. for FORMAT in ${VMFORMATS}
. for FS in ${VMFSLIST}
mkdir -p ${.OBJDIR}/${.TARGET}-${FORMAT}-${FS}
env TARGET=${TARGET} TARGET_ARCH=${TARGET_ARCH} SWAPSIZE=${SWAPSIZE} \
+ QEMUSTATIC=${QEMUSTATIC} \
${.CURDIR}/scripts/mk-vmimage.sh \
-C ${.CURDIR}/tools/vmimage.subr \
-d ${.OBJDIR}/${.TARGET}-${FORMAT}-${FS} -F ${FS} \
@@ -222,14 +223,16 @@ vm-install:
${DESTDIR}/vmimages/CHECKSUM.SHA256
.endif
-vm-release:
.if defined(WITH_VMIMAGES) && !empty(WITH_VMIMAGES)
- ${MAKE} -C ${.CURDIR} ${.MAKEFLAGS} ${VMTARGETS}
+vm-release: ${VMTARGETS}
+.else
+vm-release:
.endif
-cloudware-release:
.if defined(WITH_CLOUDWARE) && !empty(WITH_CLOUDWARE) && !empty(CLOUDWARE)
- ${MAKE} -C ${.CURDIR} ${.MAKEFLAGS} ${CLOUDTARGETS}
+cloudware-release: ${CLOUDTARGETS}
+.else
+cloudware-release:
.endif
.include "${.CURDIR}/Makefile.azure"
diff --git a/release/scripts/mk-vmimage.sh b/release/scripts/mk-vmimage.sh
index ca6a359affbd..dfd91f43140d 100755
--- a/release/scripts/mk-vmimage.sh
+++ b/release/scripts/mk-vmimage.sh
@@ -97,13 +97,14 @@ main() {
vm_create_base
vm_install_base
+ vm_emulation_setup
vm_extra_install_base
vm_extra_install_packages
vm_extra_install_ports
vm_extra_enable_services
vm_extra_pre_umount
vm_extra_pkg_rmcache
- cleanup
+ vm_emulation_cleanup
vm_copy_base
vm_create_disk || return 0
vm_extra_create_disk
diff --git a/release/tools/azure.conf b/release/tools/azure.conf
index b6526f21e474..9da2b19de694 100644
--- a/release/tools/azure.conf
+++ b/release/tools/azure.conf
@@ -53,7 +53,5 @@ EOF
touch ${DESTDIR}/firstboot
- rm -f ${DESTDIR}/etc/resolv.conf
-
return 0
}
diff --git a/release/tools/ec2.conf b/release/tools/ec2.conf
index a233bf5981c1..ce09ab0d2367 100644
--- a/release/tools/ec2.conf
+++ b/release/tools/ec2.conf
@@ -102,10 +102,5 @@ EOF
# The first time the AMI boots, run "first boot" scripts.
touch ${DESTDIR}/firstboot
- if ! [ -z "${QEMUSTATIC}" ]; then
- rm -f ${DESTDIR}/${EMULATOR}
- fi
- rm -f ${DESTDIR}/etc/resolv.conf
-
return 0
}
diff --git a/release/tools/gce.conf b/release/tools/gce.conf
index aad4a74d2e39..5ad83bcded53 100644
--- a/release/tools/gce.conf
+++ b/release/tools/gce.conf
@@ -118,7 +118,15 @@ EOF
touch ${DESTDIR}/firstboot
- rm -f ${DESTDIR}/etc/resolv.conf
+ return 0
+}
+# Do everything except deleting resolv.conf since we construct our own
+# Googlized resolv.conf file in vm_extra_install_base.
+vm_emulation_cleanup() {
+ if ! [ -z "${QEMUSTATIC}" ]; then
+ rm -f ${DESTDIR}/${EMULATOR}
+ fi
+ umount_loop ${DESTDIR}/dev
return 0
}
diff --git a/release/tools/oci.conf b/release/tools/oci.conf
index c57a7683a500..a4fe54ad3031 100644
--- a/release/tools/oci.conf
+++ b/release/tools/oci.conf
@@ -90,10 +90,5 @@ EOF
touch ${DESTDIR}/firstboot
- if ! [ -z "${QEMUSTATIC}" ]; then
- rm -f ${DESTDIR}/${EMULATOR}
- fi
- rm -f ${DESTDIR}/etc/resolv.conf
-
return 0
}
diff --git a/release/tools/openstack.conf b/release/tools/openstack.conf
index 4c905fbae4ba..05d2d13bbb39 100644
--- a/release/tools/openstack.conf
+++ b/release/tools/openstack.conf
@@ -35,8 +35,6 @@ vm_extra_pre_umount() {
echo 'ALL ALL=(ALL) NOPASSWD:ALL' >> \
${DESTDIR}/usr/local/etc/sudoers.d/cloud-init
- rm -f ${DESTDIR}/etc/resolv.conf
-
# The console is not interactive, so we might as well boot quickly.
echo 'autoboot_delay="-1"' >> ${DESTDIR}/boot/loader.conf
echo 'beastie_disable="YES"' >> ${DESTDIR}/boot/loader.conf
diff --git a/release/tools/vagrant-virtualbox.conf b/release/tools/vagrant-virtualbox.conf
index 4dd7ca8953ad..9e0e430bbc88 100644
--- a/release/tools/vagrant-virtualbox.conf
+++ b/release/tools/vagrant-virtualbox.conf
@@ -14,5 +14,4 @@ vm_extra_pre_umount () {
# Setup the Vagrant common items
vagrant_common
- rm -f ${DESTDIR}/etc/resolv.conf
}
diff --git a/release/tools/vagrant-vmware.conf b/release/tools/vagrant-vmware.conf
index 52ff7f1aac1a..fff929829222 100644
--- a/release/tools/vagrant-vmware.conf
+++ b/release/tools/vagrant-vmware.conf
@@ -18,5 +18,4 @@ vm_extra_pre_umount () {
# Setup the Vagrant common items
vagrant_common
- rm -f ${DESTDIR}/etc/resolv.conf
}
diff --git a/release/tools/vmimage.subr b/release/tools/vmimage.subr
index eda22e061c6d..72540dad14a8 100644
--- a/release/tools/vmimage.subr
+++ b/release/tools/vmimage.subr
@@ -83,8 +83,14 @@ vm_install_base() {
echo "zfs_enable=\"YES\"" >> ${DESTDIR}/etc/rc.conf
echo "zpool_reguid=\"zroot\"" >> ${DESTDIR}/etc/rc.conf
echo "zpool_upgrade=\"zroot\"" >> ${DESTDIR}/etc/rc.conf
+ echo "kern.geom.label.disk_ident.enable=0" >> ${DESTDIR}/boot/loader.conf
+ echo "zfs_load=YES" >> ${DESTDIR}/boot/loader.conf
fi
+ return 0
+}
+
+vm_emulation_setup() {
if ! [ -z "${QEMUSTATIC}" ]; then
export EMULATOR=/qemu
cp ${QEMUSTATIC} ${DESTDIR}/${EMULATOR}
@@ -94,15 +100,8 @@ vm_install_base() {
mount -t devfs devfs ${DESTDIR}/dev
chroot ${DESTDIR} ${EMULATOR} /usr/bin/newaliases
chroot ${DESTDIR} ${EMULATOR} /bin/sh /etc/rc.d/ldconfig forcestart
- umount_loop ${DESTDIR}/dev
-
cp /etc/resolv.conf ${DESTDIR}/etc/resolv.conf
- if [ "${VMFS}" = zfs ]; then
- echo "kern.geom.label.disk_ident.enable=0" >> ${DESTDIR}/boot/loader.conf
- echo "zfs_load=YES" >> ${DESTDIR}/boot/loader.conf
- fi
-
return 0
}
@@ -136,15 +135,12 @@ vm_extra_install_packages() {
if [ -z "${VM_EXTRA_PACKAGES}" ]; then
return 0
fi
- mkdir -p ${DESTDIR}/dev
- mount -t devfs devfs ${DESTDIR}/dev
chroot ${DESTDIR} ${EMULATOR} env ASSUME_ALWAYS_YES=yes \
/usr/sbin/pkg bootstrap -y
for p in ${VM_EXTRA_PACKAGES}; do
chroot ${DESTDIR} ${EMULATOR} env ASSUME_ALWAYS_YES=yes \
/usr/sbin/pkg install -y ${p}
done
- umount_loop ${DESTDIR}/dev
return 0
}
@@ -159,13 +155,16 @@ vm_extra_install_ports() {
vm_extra_pre_umount() {
# Prototype. When overridden, performs additional tasks within the
# virtual machine environment prior to unmounting the filesystem.
- # Note: When overriding this function, removing resolv.conf in the
- # disk image must be included.
+ return 0
+}
+
+vm_emulation_cleanup() {
if ! [ -z "${QEMUSTATIC}" ]; then
rm -f ${DESTDIR}/${EMULATOR}
fi
rm -f ${DESTDIR}/etc/resolv.conf
+ umount_loop ${DESTDIR}/dev
return 0
}
diff --git a/sbin/newfs/newfs.8 b/sbin/newfs/newfs.8
index e1496af814ca..0dc93cb8b78d 100644
--- a/sbin/newfs/newfs.8
+++ b/sbin/newfs/newfs.8
@@ -27,7 +27,7 @@
.\"
.\" @(#)newfs.8 8.6 (Berkeley) 5/3/95
.\"
-.Dd October 21, 2022
+.Dd May 18, 2024
.Dt NEWFS 8
.Os
.Sh NAME
@@ -100,6 +100,10 @@ The default format is UFS2.
For backward compatibility.
.It Fl U
Enable soft updates on the new file system.
+Soft updates are enabled by default for UFS2 format file systems.
+Use
+.Xr tunefs 8
+to disable soft updates if they are not wanted.
.It Fl a Ar maxcontig
Specify the maximum number of contiguous blocks that will be
laid out before forcing a rotational delay.
diff --git a/sbin/newfs/newfs.c b/sbin/newfs/newfs.c
index afb71f9f25b4..c96e414b85dd 100644
--- a/sbin/newfs/newfs.c
+++ b/sbin/newfs/newfs.c
@@ -395,6 +395,9 @@ main(int argc, char *argv[])
fprintf(stderr, "because minfree is less than %d%%\n", MINFREE);
opt = FS_OPTSPACE;
}
+ /* Use soft updates by default for UFS2 and above */
+ if (Oflag > 1)
+ Uflag = 1;
realsectorsize = sectorsize;
if (sectorsize != DEV_BSIZE) { /* XXX */
int secperblk = sectorsize / DEV_BSIZE;
diff --git a/share/man/man4/Makefile b/share/man/man4/Makefile
index a2d544034005..222422526180 100644
--- a/share/man/man4/Makefile
+++ b/share/man/man4/Makefile
@@ -342,6 +342,7 @@ MAN= aac.4 \
netlink.4 \
netmap.4 \
${_nfe.4} \
+ nfslockd.4 \
${_nfsmb.4} \
ng_async.4 \
ng_bpf.4 \
diff --git a/share/man/man4/nfslockd.4 b/share/man/man4/nfslockd.4
new file mode 100644
index 000000000000..770d9b8736b0
--- /dev/null
+++ b/share/man/man4/nfslockd.4
@@ -0,0 +1,45 @@
+.\"-
+.\" Copyright (c) 2024 Dag-Erling Smørgrav
+.\"
+.\" SPDX-License-Identifier: BSD-2-Clause
+.\"
+.Dd May 8, 2024
+.Dt NFSLOCKD 4
+.Os
+.Sh NAME
+.Nm nfslockd
+.Nd NFS advisory locking
+.Sh SYNOPSIS
+To compile this driver into the kernel, place the following lines in
+your kernel configuration file:
+.Bd -ragged -offset indent
+.Cd "options NFSLOCKD"
+.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
+nfslockd_load="YES"
+.Ed
+.Sh DESCRIPTION
+The
+.Nm
+driver provides kernel support for NFSv3 advisory locking.
+It works in tandem with
+.Xr rpc.lockd 8 ,
+which will normally load it on startup if it is not already loaded or
+compiled-in.
+.Sh SEE ALSO
+.Xr rpc.lockd 8
+.Sh HISTORY
+The
+.Nm
+driver first appeared in
+.Fx 6.4 .
+.Sh AUTHORS
+.An -nosplit
+The
+.Nm
+driver was written by
+.An Doug Rabson Aq Mt dfr@FreeBSD.org .
diff --git a/share/man/man4/smsc.4 b/share/man/man4/smsc.4
index 56c1556e5f83..61b12c7d230c 100644
--- a/share/man/man4/smsc.4
+++ b/share/man/man4/smsc.4
@@ -25,12 +25,12 @@
.\" ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd November 24, 2015
+.Dd May 7, 2024
.Dt SMSC 4
.Os
.Sh NAME
.Nm smsc
-.Nd "USB SMSC LAN9xxx Fast Ethernet driver"
+.Nd "USB Microchip LAN9xxx Fast Ethernet driver"
.Sh SYNOPSIS
To load the driver as a module at boot time, place the
following line in
@@ -53,7 +53,7 @@ following lines in your kernel configuration file:
The
.Nm
device driver provides support for USB Fast Ethernet adapters based
-on the SMSC LAN9xxx chipsets.
+on the Microchip (formerly SMSC) LAN9xxx chipsets.
.Pp
For more information on configuring this device, see
.Xr ifconfig 8 .
@@ -64,11 +64,11 @@ driver:
.Pp
.Bl -bullet -compact
.It
-SMSC LAN9500, LAN9500A, LAN9505 and LAN9505A based Ethernet adapters
+LAN9500, LAN9500A, LAN9505 and LAN9505A based Ethernet adapters
.It
-SMSC LAN89530, LAN9530 and LAN9730 based Ethernet adapters
+LAN89530, LAN9530 and LAN9730 based Ethernet adapters
.It
-SMSC LAN951x Ethernet adapters with integrated USB hub
+LAN951x Ethernet adapters with integrated USB hub
.El
.Sh SEE ALSO
.Xr arp 4 ,
diff --git a/share/man/man4/vmm.4 b/share/man/man4/vmm.4
index cb3276a7d8f1..dfd7ad26fb98 100644
--- a/share/man/man4/vmm.4
+++ b/share/man/man4/vmm.4
@@ -22,7 +22,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd October 12, 2023
+.Dd March 6, 2024
.Dt VMM 4
.Os
.Sh NAME
@@ -70,6 +70,19 @@ See the
.Sx EXAMPLES
section below for sample usage.
.Pp
+Note that
+.Nm vmm
+must be given first the right of refusal to all
+.Xr pci 4
+devices it may need to claim.
+As a result, the
+.Nm vmm
+kernel module almost certainly needs to be loaded from
+.Xr loader.conf 5
+rather than by adding it to
+.Va kld_list in
+.Xr rc.conf 5 .
+.Pp
A large number of PCI device entries may require a string longer than the
128-character limit of
.Xr loader.conf 5
diff --git a/share/man/man9/Makefile b/share/man/man9/Makefile
index 8effacbc0cee..55427c5b0eca 100644
--- a/share/man/man9/Makefile
+++ b/share/man/man9/Makefile
@@ -633,6 +633,8 @@ MLINKS+=bitset.9 BITSET_DEFINE.9 \
bitset.9 BIT_CMP.9 \
bitset.9 BIT_OR.9 \
bitset.9 BIT_OR2.9 \
+ bitset.9 BIT_ORNOT.9 \
+ bitset.9 BIT_ORNOT2.9 \
bitset.9 BIT_AND.9 \
bitset.9 BIT_AND2.9 \
bitset.9 BIT_ANDNOT.9 \
@@ -922,6 +924,7 @@ MLINKS+=cpuset.9 CPUSET_T_INITIALIZER.9 \
cpuset.9 CPU_OVERLAP.9 \
cpuset.9 CPU_CMP.9 \
cpuset.9 CPU_OR.9 \
+ cpuset.9 CPU_ORNOT.9 \
cpuset.9 CPU_AND.9 \
cpuset.9 CPU_ANDNOT.9 \
cpuset.9 CPU_CLR_ATOMIC.9 \
diff --git a/share/man/man9/bitset.9 b/share/man/man9/bitset.9
index 1bdfdeb7484c..a4e360a678d7 100644
--- a/share/man/man9/bitset.9
+++ b/share/man/man9/bitset.9
@@ -51,6 +51,8 @@
.Nm BIT_CMP ,
.Nm BIT_OR ,
.Nm BIT_OR2 ,
+.Nm BIT_ORNOT ,
+.Nm BIT_ORNOT2 ,
.Nm BIT_AND ,
.Nm BIT_AND2 ,
.Nm BIT_ANDNOT ,
@@ -123,6 +125,13 @@
.Fa "struct STRUCTNAME *src1"
.Fa "struct STRUCTNAME *src2"
.Fc
+.Fn BIT_ORNOT "const SETSIZE" "struct STRUCTNAME *dst" "struct STRUCTNAME *src"
+.Fo BIT_ORNOT2
+.Fa "const SETSIZE"
+.Fa "struct STRUCTNAME *dst"
+.Fa "struct STRUCTNAME *src1"
+.Fa "struct STRUCTNAME *src2"
+.Fc
.Fn BIT_AND "const SETSIZE" "struct STRUCTNAME *dst" "struct STRUCTNAME *src"
.Fo BIT_AND2
.Fa "const SETSIZE"
@@ -459,6 +468,36 @@ equivalent of the scalar:
.Fa src2 . )
.Pp
The
+.Fn BIT_ORNOT
+macro sets bits not in
+.Fa src
+in
+.Fa dst .
+(It is the
+.Nm
+equivalent of the scalar:
+.Fa dst
+|=
+.Fa ~ src . )
+.Pp
+The
+.Fn BIT_ORNOT2
+macro computes
+.Fa src1
+bitwise or not
+.Fa src2
+and assigns the result to
+.Fa dst .
+(It is the
+.Nm
+equivalent of the scalar:
+.Fa dst
+=
+.Fa src1
+| ~
+.Fa src2 . )
+.Pp
+The
.Fn BIT_AND
macro clears bits absent from
.Fa src
diff --git a/share/man/man9/cpuset.9 b/share/man/man9/cpuset.9
index 974dc55b2c65..20485059a4c8 100644
--- a/share/man/man9/cpuset.9
+++ b/share/man/man9/cpuset.9
@@ -45,6 +45,7 @@
.Nm CPU_OVERLAP ,
.Nm CPU_CMP ,
.Nm CPU_OR ,
+.Nm CPU_ORNOT ,
.Nm CPU_AND ,
.Nm CPU_ANDNOT ,
.Nm CPU_XOR ,
@@ -86,6 +87,7 @@
.Ft bool
.Fn CPU_CMP "cpuset_t *cpuset1" "cpuset_t *cpuset2"
.Fn CPU_OR "cpuset_t *dst" "cpuset_t *src1" "cpuset_t *src2"
+.Fn CPU_ORNOT "cpuset_t *dst" "cpuset_t *src1" "cpuset_t *src2"
.Fn CPU_AND "cpuset_t *dst" "cpuset_t *src1" "cpuset_t *src2"
.Fn CPU_ANDNOT "cpuset_t *dst" "cpuset_t *src1" "cpuset_t *src2"
.Fn CPU_XOR "cpuset_t *dst" "cpuset_t *src1" "cpuset_t *src2"
@@ -296,6 +298,19 @@ is composed of multiple machine words,
performs multiple individually atomic operations.)
.Pp
The
+.Fn CPU_ORNOT
+macro add CPUs not in
+.Fa src
+to
+.Fa dst .
+(It is the
+.Nm
+equivalent of the scalar:
+.Fa dst
+|=
+.Fa ~ src . )
+.Pp
+The
.Fn CPU_AND
macro removes CPUs absent from
.Fa src
diff --git a/share/misc/bsd-family-tree b/share/misc/bsd-family-tree
index d81c8829f4e8..ed18b96cb39a 100644
--- a/share/misc/bsd-family-tree
+++ b/share/misc/bsd-family-tree
@@ -446,11 +446,20 @@ FreeBSD 5.2 | | | |
| | | | OpenBSD 7.3 |
| FreeBSD | | | |
| 13.2 | | | |
- | macOS | | |
- | 14 | | |
- | | | OpenBSD 7.4 |
- *--FreeBSD | | | |
- | 14.0 | | | |
+ | | | | | |
+ | `------. | | | |
+ | | macOS | | |
+ | | 14 | | |
+ | | | | OpenBSD 7.4 |
+ *--FreeBSD | | | | |
+ | 14.0 | | | | |
+ | | | | | |
+ | FreeBSD | | | |
+ | 13.3 | | | |
+ | | *--NetBSD | |
+ | | | 10.0 | |
+ | | | | |
+ | | | OpenBSD 7.5 |
| | | | |
FreeBSD 15 -current | NetBSD -current OpenBSD -current DragonFly -current
| | | | |
@@ -479,7 +488,8 @@ was the announcement in Usenet or if it was available as tape.
Distribution UNIX Version 2.9, July, 1983.
[NBD] NetBSD Project, The.
[OBD] OpenBSD Project, The.
-[QCU] Salus, Peter H. A quarter century of UNIX.
+[QCU] Salus, Peter H. A quarter century of UNIX. ISBN 0201547775,
+ EAN 9780201547771
[SMS] Steven M. Schultz. 2.11BSD, UNIX for the PDP-11.
[TUHS] The Unix Historical Society. https://minnie.tuhs.org/Unix_History/.
[USE] Usenet announcement.
@@ -880,6 +890,9 @@ FreeBSD 13.2 2023-04-11 [FBD]
macOS 14 2023-09-26 [APL]
OpenBSD 7.4 2023-10-16 [OBD]
FreeBSD 14.0 2023-11-20 [FBD]
+FreeBSD 13.3 2024-03-05 [FBD]
+NetBSD 10.0 2024-03-28 [NBD]
+OpenBSD 7.5 2024-04-05 [OBD]
Bibliography
------------------------
diff --git a/sys/amd64/amd64/sys_machdep.c b/sys/amd64/amd64/sys_machdep.c
index 6f8d6feaf60b..6c8b038bdb09 100644
--- a/sys/amd64/amd64/sys_machdep.c
+++ b/sys/amd64/amd64/sys_machdep.c
@@ -189,35 +189,33 @@ sysarch(struct thread *td, struct sysarch_args *uap)
* explicitly indicate whether or not the operation is safe to
* perform in capability mode.
*/
- if (IN_CAPABILITY_MODE(td)) {
- switch (uap->op) {
- case I386_GET_LDT:
- case I386_SET_LDT:
- case I386_GET_IOPERM:
- case I386_GET_FSBASE:
- case I386_SET_FSBASE:
- case I386_GET_GSBASE:
- case I386_SET_GSBASE:
- case I386_GET_XFPUSTATE:
- case I386_SET_PKRU:
- case I386_CLEAR_PKRU:
- case AMD64_GET_FSBASE:
- case AMD64_SET_FSBASE:
- case AMD64_GET_GSBASE:
- case AMD64_SET_GSBASE:
- case AMD64_GET_XFPUSTATE:
- case AMD64_SET_PKRU:
- case AMD64_CLEAR_PKRU:
- break;
+ switch (uap->op) {
+ case I386_GET_LDT:
+ case I386_SET_LDT:
+ case I386_GET_IOPERM:
+ case I386_GET_FSBASE:
+ case I386_SET_FSBASE:
+ case I386_GET_GSBASE:
+ case I386_SET_GSBASE:
+ case I386_GET_XFPUSTATE:
+ case I386_SET_PKRU:
+ case I386_CLEAR_PKRU:
+ case AMD64_GET_FSBASE:
+ case AMD64_SET_FSBASE:
+ case AMD64_GET_GSBASE:
+ case AMD64_SET_GSBASE:
+ case AMD64_GET_XFPUSTATE:
+ case AMD64_SET_PKRU:
+ case AMD64_CLEAR_PKRU:
+ break;
- case I386_SET_IOPERM:
- default:
-#ifdef KTRACE
- if (KTRPOINT(td, KTR_CAPFAIL))
- ktrcapfail(CAPFAIL_SYSCALL, NULL, NULL);
-#endif
+ case I386_SET_IOPERM:
+ default:
+ if (CAP_TRACING(td))
+ ktrcapfail(CAPFAIL_SYSCALL, &uap->op);
+ if (IN_CAPABILITY_MODE(td))
return (ECAPMODE);
- }
+ break;
}
#endif
diff --git a/sys/arm/allwinner/a10_codec.c b/sys/arm/allwinner/a10_codec.c
index 05fb25d9b02d..036de684b788 100644
--- a/sys/arm/allwinner/a10_codec.c
+++ b/sys/arm/allwinner/a10_codec.c
@@ -41,7 +41,6 @@
#include <machine/bus.h>
#include <dev/sound/pcm/sound.h>
-#include <dev/sound/chip.h>
#include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_bus_subr.h>
diff --git a/sys/arm/arm/sys_machdep.c b/sys/arm/arm/sys_machdep.c
index 208026db85ba..d167c757952b 100644
--- a/sys/arm/arm/sys_machdep.c
+++ b/sys/arm/arm/sys_machdep.c
@@ -177,22 +177,19 @@ sysarch(struct thread *td, struct sysarch_args *uap)
* explicitly indicate whether or not the operation is safe to
* perform in capability mode.
*/
- if (IN_CAPABILITY_MODE(td)) {
- switch (uap->op) {
- case ARM_SYNC_ICACHE:
- case ARM_DRAIN_WRITEBUF:
- case ARM_SET_TP:
- case ARM_GET_TP:
- case ARM_GET_VFPSTATE:
- break;
-
- default:
-#ifdef KTRACE
- if (KTRPOINT(td, KTR_CAPFAIL))
- ktrcapfail(CAPFAIL_SYSCALL, NULL, NULL);
-#endif
+ switch (uap->op) {
+ case ARM_SYNC_ICACHE:
+ case ARM_DRAIN_WRITEBUF:
+ case ARM_SET_TP:
+ case ARM_GET_TP:
+ case ARM_GET_VFPSTATE:
+ break;
+
+ default:
+ if (CAP_TRACING(td))
+ ktrcapfail(CAPFAIL_SYSCALL, &uap->op);
+ if (IN_CAPABILITY_MODE(td))
return (ECAPMODE);
- }
}
#endif
diff --git a/sys/arm/broadcom/bcm2835/bcm2835_audio.c b/sys/arm/broadcom/bcm2835/bcm2835_audio.c
index e0f525fa9520..75a0c81f29a1 100644
--- a/sys/arm/broadcom/bcm2835/bcm2835_audio.c
+++ b/sys/arm/broadcom/bcm2835/bcm2835_audio.c
@@ -28,7 +28,6 @@
#endif
#include <dev/sound/pcm/sound.h>
-#include <dev/sound/chip.h>
#include "mixer_if.h"
diff --git a/sys/arm/freescale/imx/imx6_ssi.c b/sys/arm/freescale/imx/imx6_ssi.c
index 931a2b677eae..6b23334a4e97 100644
--- a/sys/arm/freescale/imx/imx6_ssi.c
+++ b/sys/arm/freescale/imx/imx6_ssi.c
@@ -43,7 +43,6 @@
#include <sys/timetc.h>
#include <dev/sound/pcm/sound.h>
-#include <dev/sound/chip.h>
#include <mixer_if.h>
#include <dev/ofw/openfirm.h>
diff --git a/sys/arm/freescale/vybrid/vf_sai.c b/sys/arm/freescale/vybrid/vf_sai.c
index 5336dfc6dd57..3b3a120df4e1 100644
--- a/sys/arm/freescale/vybrid/vf_sai.c
+++ b/sys/arm/freescale/vybrid/vf_sai.c
@@ -44,7 +44,6 @@
#include <sys/watchdog.h>
#include <dev/sound/pcm/sound.h>
-#include <dev/sound/chip.h>
#include <mixer_if.h>
#include <dev/ofw/openfirm.h>
diff --git a/sys/arm/include/armreg.h b/sys/arm/include/armreg.h
index 8beef9b31022..819355111909 100644
--- a/sys/arm/include/armreg.h
+++ b/sys/arm/include/armreg.h
@@ -41,8 +41,6 @@
#ifndef MACHINE_ARMREG_H
#define MACHINE_ARMREG_H
-#define INSN_SIZE 4
-#define INSN_COND_MASK 0xf0000000 /* Condition mask */
#define PSR_MODE 0x0000001f /* mode mask */
#define PSR_USR32_MODE 0x00000010
#define PSR_FIQ32_MODE 0x00000011
diff --git a/sys/compat/linuxkpi/common/include/asm/set_memory.h b/sys/compat/linuxkpi/common/include/asm/set_memory.h
index 69f659001c60..1019aaf264a0 100644
--- a/sys/compat/linuxkpi/common/include/asm/set_memory.h
+++ b/sys/compat/linuxkpi/common/include/asm/set_memory.h
@@ -34,26 +34,20 @@
static inline int
set_memory_uc(unsigned long addr, int numpages)
{
- vm_offset_t va;
vm_size_t len;
- va = PHYS_TO_DMAP(addr);
- len = numpages << PAGE_SHIFT;
-
- return (-pmap_change_attr(va, len, VM_MEMATTR_UNCACHEABLE));
+ len = (vm_size_t)numpages << PAGE_SHIFT;
+ return (-pmap_change_attr(addr, len, VM_MEMATTR_UNCACHEABLE));
}
static inline int
set_memory_wc(unsigned long addr, int numpages)
{
#ifdef VM_MEMATTR_WRITE_COMBINING
- vm_offset_t va;
vm_size_t len;
- va = PHYS_TO_DMAP(addr);
- len = numpages << PAGE_SHIFT;
-
- return (-pmap_change_attr(va, len, VM_MEMATTR_WRITE_COMBINING));
+ len = (vm_size_t)numpages << PAGE_SHIFT;
+ return (-pmap_change_attr(addr, len, VM_MEMATTR_WRITE_COMBINING));
#else
return (set_memory_uc(addr, numpages));
#endif
@@ -62,13 +56,10 @@ set_memory_wc(unsigned long addr, int numpages)
static inline int
set_memory_wb(unsigned long addr, int numpages)
{
- vm_offset_t va;
vm_size_t len;
- va = PHYS_TO_DMAP(addr);
- len = numpages << PAGE_SHIFT;
-
- return (-pmap_change_attr(va, len, VM_MEMATTR_WRITE_BACK));
+ len = (vm_size_t)numpages << PAGE_SHIFT;
+ return (-pmap_change_attr(addr, len, VM_MEMATTR_WRITE_BACK));
}
static inline int
diff --git a/sys/compat/linuxkpi/common/include/linux/io.h b/sys/compat/linuxkpi/common/include/linux/io.h
index bce70ed0cb8d..164347dbc4e7 100644
--- a/sys/compat/linuxkpi/common/include/linux/io.h
+++ b/sys/compat/linuxkpi/common/include/linux/io.h
@@ -541,30 +541,29 @@ void lkpi_arch_phys_wc_del(int);
#define arch_phys_wc_index(x) \
(((x) < __MTRR_ID_BASE) ? -1 : ((x) - __MTRR_ID_BASE))
-#if defined(__amd64__) || defined(__i386__) || defined(__aarch64__) || defined(__powerpc__) || defined(__riscv)
static inline int
arch_io_reserve_memtype_wc(resource_size_t start, resource_size_t size)
{
+#if defined(__amd64__)
vm_offset_t va;
va = PHYS_TO_DMAP(start);
-
-#ifdef VM_MEMATTR_WRITE_COMBINING
return (-pmap_change_attr(va, size, VM_MEMATTR_WRITE_COMBINING));
#else
- return (-pmap_change_attr(va, size, VM_MEMATTR_UNCACHEABLE));
+ return (0);
#endif
}
static inline void
arch_io_free_memtype_wc(resource_size_t start, resource_size_t size)
{
+#if defined(__amd64__)
vm_offset_t va;
va = PHYS_TO_DMAP(start);
pmap_change_attr(va, size, VM_MEMATTR_WRITE_BACK);
-}
#endif
+}
#endif /* _LINUXKPI_LINUX_IO_H_ */
diff --git a/sys/conf/files b/sys/conf/files
index c4e9f0698c4f..7d3c44893e09 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -3060,7 +3060,6 @@ dev/smc/if_smc.c optional smc
dev/smc/if_smc_acpi.c optional smc acpi
dev/smc/if_smc_fdt.c optional smc fdt
dev/snp/snp.c optional snp
-dev/sound/unit.c optional sound
dev/sound/pci/als4000.c optional snd_als4000 pci
dev/sound/pci/atiixp.c optional snd_atiixp pci
dev/sound/pci/cmi.c optional snd_cmi pci
diff --git a/sys/dev/etherswitch/ip17x/ip17x.c b/sys/dev/etherswitch/ip17x/ip17x.c
index 218c0c293662..65e548ba293b 100644
--- a/sys/dev/etherswitch/ip17x/ip17x.c
+++ b/sys/dev/etherswitch/ip17x/ip17x.c
@@ -556,7 +556,7 @@ ip17x_ifmedia_sts(if_t ifp, struct ifmediareq *ifmr)
static int
ip17x_readreg(device_t dev, int addr)
{
- struct ip17x_softc *sc;
+ struct ip17x_softc *sc __diagused;
sc = device_get_softc(dev);
IP17X_LOCK_ASSERT(sc, MA_OWNED);
@@ -568,7 +568,7 @@ ip17x_readreg(device_t dev, int addr)
static int
ip17x_writereg(device_t dev, int addr, int value)
{
- struct ip17x_softc *sc;
+ struct ip17x_softc *sc __diagused;
sc = device_get_softc(dev);
IP17X_LOCK_ASSERT(sc, MA_OWNED);
diff --git a/sys/dev/etherswitch/ukswitch/ukswitch.c b/sys/dev/etherswitch/ukswitch/ukswitch.c
index 6eff37bb118e..88726422bd01 100644
--- a/sys/dev/etherswitch/ukswitch/ukswitch.c
+++ b/sys/dev/etherswitch/ukswitch/ukswitch.c
@@ -514,7 +514,7 @@ ukswitch_writephy(device_t dev, int phy, int reg, int data)
static int
ukswitch_readreg(device_t dev, int addr)
{
- struct ukswitch_softc *sc;
+ struct ukswitch_softc *sc __diagused;
sc = device_get_softc(dev);
UKSWITCH_LOCK_ASSERT(sc, MA_OWNED);
@@ -526,7 +526,7 @@ ukswitch_readreg(device_t dev, int addr)
static int
ukswitch_writereg(device_t dev, int addr, int value)
{
- struct ukswitch_softc *sc;
+ struct ukswitch_softc *sc __diagused;
sc = device_get_softc(dev);
UKSWITCH_LOCK_ASSERT(sc, MA_OWNED);
diff --git a/sys/dev/iicbus/if_ic.c b/sys/dev/iicbus/if_ic.c
index 4ca8f3960298..52ab5afb9c4e 100644
--- a/sys/dev/iicbus/if_ic.c
+++ b/sys/dev/iicbus/if_ic.c
@@ -363,8 +363,8 @@ icoutput(if_t ifp, struct mbuf *m, const struct sockaddr *dst,
u_char *cp;
u_int32_t hdr;
- /* BPF writes need to be handled specially. */
- if (dst->sa_family == AF_UNSPEC)
+ /* BPF writes need to be handled specially. */
+ if (dst->sa_family == AF_UNSPEC || dst->sa_family == pseudo_AF_HDRCMPLT)
bcopy(dst->sa_data, &hdr, sizeof(hdr));
else
hdr = RO_GET_FAMILY(ro, dst);
diff --git a/sys/dev/mlx5/mlx5_en/mlx5_en_main.c b/sys/dev/mlx5/mlx5_en/mlx5_en_main.c
index e1dbd02fcf3a..962705e6d258 100644
--- a/sys/dev/mlx5/mlx5_en/mlx5_en_main.c
+++ b/sys/dev/mlx5/mlx5_en/mlx5_en_main.c
@@ -3674,6 +3674,9 @@ out:
/* Check if module is present before doing an access */
module_status = mlx5_query_module_status(priv->mdev, module_num);
if (module_status != MLX5_MODULE_STATUS_PLUGGED_ENABLED) {
+ mlx5_en_err(ifp,
+ "Query module %d status: not plugged (%d), eeprom reading is not supported\n",
+ module_num, module_status);
error = EINVAL;
goto err_i2c;
}
diff --git a/sys/dev/sound/chip.h b/sys/dev/sound/chip.h
deleted file mode 100644
index bb40d2809a00..000000000000
--- a/sys/dev/sound/chip.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause
- *
- * Copyright (c) 1999 Seigo Tanimura
- * 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.
- */
-
-/*
- * These are the function codes assigned to the children of
- * sound cards.
- */
-enum {
- SCF_PCM,
- SCF_MIDI,
- SCF_SYNTH,
-};
-
-/*
- * This is the device information struct, used by
- * a bridge device to pass the device function code
- * to the children.
- */
-struct sndcard_func {
- int func; /* The function code. */
- void *varinfo; /* Bridge-specific information. */
-};
diff --git a/sys/dev/sound/pci/atiixp.c b/sys/dev/sound/pci/atiixp.c
index dcbf041f9605..eeb28bb08276 100644
--- a/sys/dev/sound/pci/atiixp.c
+++ b/sys/dev/sound/pci/atiixp.c
@@ -1168,12 +1168,12 @@ atiixp_release_resource(struct atiixp_info *sc)
static int
atiixp_pci_probe(device_t dev)
{
- int i;
+ size_t i;
uint16_t devid, vendor;
vendor = pci_get_vendor(dev);
devid = pci_get_device(dev);
- for (i = 0; i < sizeof(atiixp_hw) / sizeof(atiixp_hw[0]); i++) {
+ for (i = 0; i < nitems(atiixp_hw); i++) {
if (vendor == atiixp_hw[i].vendor &&
devid == atiixp_hw[i].devid) {
device_set_desc(dev, atiixp_hw[i].desc);
diff --git a/sys/dev/sound/pci/csa.c b/sys/dev/sound/pci/csa.c
index 7bb7967b74e7..662f0de80188 100644
--- a/sys/dev/sound/pci/csa.c
+++ b/sys/dev/sound/pci/csa.c
@@ -45,7 +45,6 @@
#endif
#include <dev/sound/pcm/sound.h>
-#include <dev/sound/chip.h>
#include <dev/sound/pci/csareg.h>
#include <dev/sound/pci/csavar.h>
diff --git a/sys/dev/sound/pci/csamidi.c b/sys/dev/sound/pci/csamidi.c
index df1699092990..29d5548b0954 100644
--- a/sys/dev/sound/pci/csamidi.c
+++ b/sys/dev/sound/pci/csamidi.c
@@ -43,7 +43,6 @@
#include <dev/pci/pcireg.h>
#include <dev/pci/pcivar.h>
-#include <dev/sound/chip.h>
#include <dev/sound/pcm/sound.h>
#include <dev/sound/midi/midi.h>
diff --git a/sys/dev/sound/pci/csapcm.c b/sys/dev/sound/pci/csapcm.c
index 71b9a0253cdb..c8424dd3e433 100644
--- a/sys/dev/sound/pci/csapcm.c
+++ b/sys/dev/sound/pci/csapcm.c
@@ -36,7 +36,6 @@
#include <dev/sound/pcm/sound.h>
#include <dev/sound/pcm/ac97.h>
-#include <dev/sound/chip.h>
#include <dev/sound/pci/csareg.h>
#include <dev/sound/pci/csavar.h>
diff --git a/sys/dev/sound/pci/emu10kx-midi.c b/sys/dev/sound/pci/emu10kx-midi.c
index 4ed8e6c1dd9c..2a98562f8f39 100644
--- a/sys/dev/sound/pci/emu10kx-midi.c
+++ b/sys/dev/sound/pci/emu10kx-midi.c
@@ -43,7 +43,6 @@
#include "opt_snd.h"
#endif
-#include <dev/sound/chip.h>
#include <dev/sound/pcm/sound.h>
#include <dev/sound/midi/midi.h>
diff --git a/sys/dev/sound/pci/emu10kx-pcm.c b/sys/dev/sound/pci/emu10kx-pcm.c
index 825a39fc4e63..bef6b596646e 100644
--- a/sys/dev/sound/pci/emu10kx-pcm.c
+++ b/sys/dev/sound/pci/emu10kx-pcm.c
@@ -43,7 +43,6 @@
#include "opt_snd.h"
#endif
-#include <dev/sound/chip.h>
#include <dev/sound/pcm/sound.h>
#include <dev/sound/pcm/ac97.h>
diff --git a/sys/dev/sound/pci/emu10kx.c b/sys/dev/sound/pci/emu10kx.c
index 6bbbfcc1df0e..0f938597e06c 100644
--- a/sys/dev/sound/pci/emu10kx.c
+++ b/sys/dev/sound/pci/emu10kx.c
@@ -49,7 +49,6 @@
#include "opt_snd.h"
#endif
-#include <dev/sound/chip.h>
#include <dev/sound/pcm/sound.h>
#include <dev/sound/pcm/ac97.h>
@@ -2313,7 +2312,7 @@ emu10kx_dev_init(struct emu_sc_info *sc)
mtx_init(&sc->emu10kx_lock, device_get_nameunit(sc->dev), "kxdevlock", 0);
unit = device_get_unit(sc->dev);
- sc->cdev = make_dev(&emu10kx_cdevsw, PCMMINOR(unit), UID_ROOT, GID_WHEEL, 0640, "emu10kx%d", unit);
+ sc->cdev = make_dev(&emu10kx_cdevsw, unit, UID_ROOT, GID_WHEEL, 0640, "emu10kx%d", unit);
if (sc->cdev != NULL) {
sc->cdev->si_drv1 = sc;
return (0);
diff --git a/sys/dev/sound/pci/hda/hdaa.c b/sys/dev/sound/pci/hda/hdaa.c
index dcd10cb36510..e8d9ee12fffc 100644
--- a/sys/dev/sound/pci/hda/hdaa.c
+++ b/sys/dev/sound/pci/hda/hdaa.c
@@ -267,7 +267,8 @@ hdaa_channels_handler(struct hdaa_audio_as *as)
struct hdaa_chan *ch = &devinfo->chans[as->chans[0]];
struct hdaa_widget *w;
uint8_t *eld;
- int i, total, sub, assume, channels;
+ int total, sub, assume, channels;
+ size_t i;
uint16_t cpins, upins, tpins;
cpins = upins = 0;
@@ -347,7 +348,7 @@ hdaa_channels_handler(struct hdaa_audio_as *as)
printf("\n");
);
/* Look for maximal fitting matrix. */
- for (i = 0; i < sizeof(matrixes) / sizeof(struct matrix); i++) {
+ for (i = 0; i < nitems(matrixes); i++) {
if (as->pinset != 0 && matrixes[i].analog == 0)
continue;
if ((matrixes[i].m.mask & ~channels) == 0) {
@@ -1252,7 +1253,8 @@ hdaa_sysctl_config(SYSCTL_HANDLER_ARGS)
static void
hdaa_config_fetch(const char *str, uint32_t *on, uint32_t *off)
{
- int i = 0, j, k, len, inv;
+ size_t k;
+ int i = 0, j, len, inv;
for (;;) {
while (str[i] != '\0' &&
@@ -1292,7 +1294,8 @@ static int
hdaa_sysctl_quirks(SYSCTL_HANDLER_ARGS)
{
char buf[256];
- int error, n = 0, i;
+ int error, n = 0;
+ size_t i;
uint32_t quirks, quirks_off;
quirks = *(uint32_t *)oidp->oid_arg1;
diff --git a/sys/dev/sound/pci/hda/hdaa_patches.c b/sys/dev/sound/pci/hda/hdaa_patches.c
index 3a7dfc63637a..9f3532562252 100644
--- a/sys/dev/sound/pci/hda/hdaa_patches.c
+++ b/sys/dev/sound/pci/hda/hdaa_patches.c
@@ -318,7 +318,8 @@ hdac_pin_patch(struct hdaa_widget *w)
}
} else if (id == HDA_CODEC_ALC257 &&
(subid == LENOVO_L5AMD_SUBVENDOR ||
- subid == LENOVO_L5INTEL_SUBVENDOR)) {
+ subid == LENOVO_L5INTEL_SUBVENDOR ||
+ subid == LENOVO_IDEAPAD3_SUBVENDOR)) {
switch (nid) {
case 20:
patch_str = "as=1 seq=0";
@@ -339,7 +340,7 @@ hdac_pin_patch(struct hdaa_widget *w)
break;
}
} else if (id == HDA_CODEC_ALC230 &&
- subid == LENOVO_I330_SUBVENDOR) {
+ subid == LENOVO_IDEAPAD330_SUBVENDOR) {
switch (nid) {
case 20:
patch_str = "as=1 seq=0 device=Speaker";
diff --git a/sys/dev/sound/pci/hda/hdac.h b/sys/dev/sound/pci/hda/hdac.h
index 4dd589ed2a09..6a3314280a22 100644
--- a/sys/dev/sound/pci/hda/hdac.h
+++ b/sys/dev/sound/pci/hda/hdac.h
@@ -382,7 +382,8 @@
#define LENOVO_L5AMD_SUBVENDOR HDA_MODEL_CONSTRUCT(LENOVO, 0x381b)
#define LENOVO_L5INTEL_SUBVENDOR HDA_MODEL_CONSTRUCT(LENOVO, 0x380f)
#define LENOVO_3000_SUBVENDOR HDA_MODEL_CONSTRUCT(LENOVO, 0x384e)
-#define LENOVO_I330_SUBVENDOR HDA_MODEL_CONSTRUCT(LENOVO, 0x3808)
+#define LENOVO_IDEAPAD330_SUBVENDOR HDA_MODEL_CONSTRUCT(LENOVO, 0x3808)
+#define LENOVO_IDEAPAD3_SUBVENDOR HDA_MODEL_CONSTRUCT(LENOVO, 0x3881)
#define LENOVO_ALL_SUBVENDOR HDA_MODEL_CONSTRUCT(LENOVO, 0xffff)
/* Samsung */
diff --git a/sys/dev/sound/pci/hdspe-pcm.c b/sys/dev/sound/pci/hdspe-pcm.c
index db39b867879f..4bea6c65e087 100644
--- a/sys/dev/sound/pci/hdspe-pcm.c
+++ b/sys/dev/sound/pci/hdspe-pcm.c
@@ -34,7 +34,6 @@
#include <dev/sound/pcm/sound.h>
#include <dev/sound/pci/hdspe.h>
-#include <dev/sound/chip.h>
#include <dev/pci/pcireg.h>
#include <dev/pci/pcivar.h>
diff --git a/sys/dev/sound/pci/hdspe.c b/sys/dev/sound/pci/hdspe.c
index e0197d1e981a..91d1f3ee1bf6 100644
--- a/sys/dev/sound/pci/hdspe.c
+++ b/sys/dev/sound/pci/hdspe.c
@@ -37,7 +37,6 @@
#include <dev/sound/pcm/sound.h>
#include <dev/sound/pci/hdspe.h>
-#include <dev/sound/chip.h>
#include <dev/pci/pcireg.h>
#include <dev/pci/pcivar.h>
diff --git a/sys/dev/sound/pci/ich.c b/sys/dev/sound/pci/ich.c
index fbde0accfd28..910a371c6653 100644
--- a/sys/dev/sound/pci/ich.c
+++ b/sys/dev/sound/pci/ich.c
@@ -860,12 +860,12 @@ ich_init(struct sc_info *sc)
static int
ich_pci_probe(device_t dev)
{
- int i;
+ size_t i;
uint16_t devid, vendor;
vendor = pci_get_vendor(dev);
devid = pci_get_device(dev);
- for (i = 0; i < sizeof(ich_devs)/sizeof(ich_devs[0]); i++) {
+ for (i = 0; i < nitems(ich_devs); i++) {
if (vendor == ich_devs[i].vendor &&
devid == ich_devs[i].devid) {
device_set_desc(dev, ich_devs[i].name);
diff --git a/sys/dev/sound/pci/maestro3.c b/sys/dev/sound/pci/maestro3.c
index 6dd54a66f683..4d6dca310eea 100644
--- a/sys/dev/sound/pci/maestro3.c
+++ b/sys/dev/sound/pci/maestro3.c
@@ -488,7 +488,7 @@ m3_pchan_init(kobj_t kobj, void *devinfo, struct snd_dbuf *b, struct pcm_channel
DMAC_BLOCKF_SELECTOR);
/* set an armload of static initializers */
- for(i = 0 ; i < (sizeof(pv) / sizeof(pv[0])) ; i++) {
+ for(i = 0 ; i < nitems(pv); i++) {
m3_wr_assp_data(sc, ch->dac_data + pv[i].addr, pv[i].val);
}
@@ -862,7 +862,7 @@ m3_rchan_init(kobj_t kobj, void *devinfo, struct snd_dbuf *b, struct pcm_channel
DMAC_PAGE3_SELECTOR + DMAC_BLOCKF_SELECTOR);
/* set an armload of static initializers */
- for(i = 0 ; i < (sizeof(rv) / sizeof(rv[0])) ; i++) {
+ for(i = 0 ; i < nitems(rv); i++) {
m3_wr_assp_data(sc, ch->adc_data + rv[i].addr, rv[i].val);
}
diff --git a/sys/dev/sound/pci/solo.c b/sys/dev/sound/pci/solo.c
index bee79e723696..82eabf3a4884 100644
--- a/sys/dev/sound/pci/solo.c
+++ b/sys/dev/sound/pci/solo.c
@@ -35,7 +35,6 @@
#include <dev/pci/pcivar.h>
#include <dev/sound/isa/sb.h>
-#include <dev/sound/chip.h>
#include "mixer_if.h"
diff --git a/sys/dev/sound/pcm/channel.c b/sys/dev/sound/pcm/channel.c
index 1527d5ea3d2c..846885b9d729 100644
--- a/sys/dev/sound/pcm/channel.c
+++ b/sys/dev/sound/pcm/channel.c
@@ -1157,17 +1157,105 @@ chn_reset(struct pcm_channel *c, uint32_t fmt, uint32_t spd)
return r;
}
-int
-chn_init(struct pcm_channel *c, void *devinfo, int dir, int direction)
+struct pcm_channel *
+chn_init(struct snddev_info *d, struct pcm_channel *parent, kobj_class_t cls,
+ int dir, void *devinfo)
{
+ struct pcm_channel *c;
struct feeder_class *fc;
struct snd_dbuf *b, *bs;
- int i, ret;
+ char *dirs, *devname, buf[CHN_NAMELEN];
+ int i, ret, direction, rpnum, *pnum, max, type, unit;
- if (chn_timeout < CHN_TIMEOUT_MIN || chn_timeout > CHN_TIMEOUT_MAX)
- chn_timeout = CHN_TIMEOUT;
+ PCM_BUSYASSERT(d);
+ PCM_LOCKASSERT(d);
+ switch (dir) {
+ case PCMDIR_PLAY:
+ dirs = "play";
+ direction = PCMDIR_PLAY;
+ pnum = &d->playcount;
+ type = SND_DEV_DSPHW_PLAY;
+ max = SND_MAXHWCHAN;
+ break;
+ case PCMDIR_PLAY_VIRTUAL:
+ dirs = "virtual_play";
+ direction = PCMDIR_PLAY;
+ pnum = &d->pvchancount;
+ type = SND_DEV_DSPHW_VPLAY;
+ max = SND_MAXVCHANS;
+ break;
+ case PCMDIR_REC:
+ dirs = "record";
+ direction = PCMDIR_REC;
+ pnum = &d->reccount;
+ type = SND_DEV_DSPHW_REC;
+ max = SND_MAXHWCHAN;
+ break;
+ case PCMDIR_REC_VIRTUAL:
+ dirs = "virtual_record";
+ direction = PCMDIR_REC;
+ pnum = &d->rvchancount;
+ type = SND_DEV_DSPHW_VREC;
+ max = SND_MAXVCHANS;
+ break;
+ default:
+ device_printf(d->dev,
+ "%s(): invalid channel direction: %d\n",
+ __func__, dir);
+ goto out1;
+ }
+
+ unit = 0;
+
+ if (*pnum >= max || unit >= max) {
+ device_printf(d->dev, "%s(): unit=%d or pnum=%d >= than "
+ "max=%d\n", __func__, unit, *pnum, max);
+ goto out1;
+ }
+
+ rpnum = 0;
+
+ CHN_FOREACH(c, d, channels.pcm) {
+ if (c->type != type)
+ continue;
+ unit++;
+ if (unit >= max) {
+ device_printf(d->dev,
+ "%s(): chan=%d >= max=%d\n", __func__, unit, max);
+ goto out1;
+ }
+ rpnum++;
+ }
+
+ if (*pnum != rpnum) {
+ device_printf(d->dev,
+ "%s(): pnum screwed: dirs=%s pnum=%d rpnum=%d\n",
+ __func__, dirs, *pnum, rpnum);
+ goto out1;
+ }
+
+ PCM_UNLOCK(d);
+ c = malloc(sizeof(*c), M_DEVBUF, M_WAITOK | M_ZERO);
+ c->methods = kobj_create(cls, M_DEVBUF, M_WAITOK | M_ZERO);
+ c->type = type;
+ c->unit = unit;
+ c->pid = -1;
+ strlcpy(c->comm, CHN_COMM_UNUSED, sizeof(c->comm));
+ c->parentsnddev = d;
+ c->parentchannel = parent;
+ c->dev = d->dev;
+ c->trigger = PCMTRIG_STOP;
chn_lockinit(c, dir);
+ devname = dsp_unit2name(buf, sizeof(buf), c);
+ if (devname == NULL) {
+ ret = EINVAL;
+ device_printf(d->dev, "%s(): failed to create channel name",
+ __func__);
+ goto out2;
+ }
+ snprintf(c->name, sizeof(c->name), "%s:%s:%s",
+ device_get_nameunit(c->dev), dirs, devname);
b = NULL;
bs = NULL;
@@ -1180,20 +1268,31 @@ chn_init(struct pcm_channel *c, void *devinfo, int dir, int direction)
ret = ENOMEM;
b = sndbuf_create(c->dev, c->name, "primary", c);
- if (b == NULL)
- goto out;
+ if (b == NULL) {
+ device_printf(d->dev, "%s(): failed to create hardware buffer\n",
+ __func__);
+ goto out2;
+ }
bs = sndbuf_create(c->dev, c->name, "secondary", c);
- if (bs == NULL)
- goto out;
+ if (bs == NULL) {
+ device_printf(d->dev, "%s(): failed to create software buffer\n",
+ __func__);
+ goto out2;
+ }
CHN_LOCK(c);
ret = EINVAL;
fc = feeder_getclass(NULL);
- if (fc == NULL)
- goto out;
- if (chn_addfeeder(c, fc, NULL))
- goto out;
+ if (fc == NULL) {
+ device_printf(d->dev, "%s(): failed to get feeder class\n",
+ __func__);
+ goto out2;
+ }
+ if (chn_addfeeder(c, fc, NULL)) {
+ device_printf(d->dev, "%s(): failed to add feeder\n", __func__);
+ goto out2;
+ }
/*
* XXX - sndbuf_setup() & sndbuf_resize() expect to be called
@@ -1229,12 +1328,17 @@ chn_init(struct pcm_channel *c, void *devinfo, int dir, int direction)
CHN_UNLOCK(c); /* XXX - Unlock for CHANNEL_INIT() malloc() call */
c->devinfo = CHANNEL_INIT(c->methods, devinfo, b, c, direction);
CHN_LOCK(c);
- if (c->devinfo == NULL)
- goto out;
+ if (c->devinfo == NULL) {
+ device_printf(d->dev, "%s(): NULL devinfo\n", __func__);
+ goto out2;
+ }
ret = ENOMEM;
- if ((sndbuf_getsize(b) == 0) && ((c->flags & CHN_F_VIRTUAL) == 0))
- goto out;
+ if ((sndbuf_getsize(b) == 0) && ((c->flags & CHN_F_VIRTUAL) == 0)) {
+ device_printf(d->dev, "%s(): hardware buffer's size is 0\n",
+ __func__);
+ goto out2;
+ }
ret = 0;
c->direction = direction;
@@ -1254,12 +1358,14 @@ chn_init(struct pcm_channel *c, void *devinfo, int dir, int direction)
bs->shadbuf = malloc(bs->sl, M_DEVBUF, M_NOWAIT);
if (bs->shadbuf == NULL) {
ret = ENOMEM;
- goto out;
+ device_printf(d->dev, "%s(): failed to create shadow "
+ "buffer\n", __func__);
+ goto out2;
}
}
-
-out:
- CHN_UNLOCK(c);
+out2:
+ if (CHN_LOCKOWNED(c))
+ CHN_UNLOCK(c);
if (ret) {
if (c->devinfo) {
if (CHANNEL_FREE(c->methods, c->devinfo))
@@ -1273,17 +1379,28 @@ out:
c->flags |= CHN_F_DEAD;
chn_lockdestroy(c);
- return ret;
+ PCM_LOCK(d);
+
+ kobj_delete(c->methods, M_DEVBUF);
+ free(c, M_DEVBUF);
+
+ return (NULL);
}
- return 0;
+ PCM_LOCK(d);
+
+ return (c);
+out1:
+ return (NULL);
}
-int
+void
chn_kill(struct pcm_channel *c)
{
- struct snd_dbuf *b = c->bufhard;
- struct snd_dbuf *bs = c->bufsoft;
+ struct snd_dbuf *b = c->bufhard;
+ struct snd_dbuf *bs = c->bufsoft;
+
+ PCM_BUSYASSERT(c->parentsnddev);
if (CHN_STARTED(c)) {
CHN_LOCK(c);
@@ -1299,8 +1416,8 @@ chn_kill(struct pcm_channel *c)
CHN_LOCK(c);
c->flags |= CHN_F_DEAD;
chn_lockdestroy(c);
-
- return (0);
+ kobj_delete(c->methods, M_DEVBUF);
+ free(c, M_DEVBUF);
}
void
@@ -1312,6 +1429,34 @@ chn_shutdown(struct pcm_channel *c)
c->flags |= CHN_F_DEAD;
}
+/* release a locked channel and unlock it */
+int
+chn_release(struct pcm_channel *c)
+{
+ PCM_BUSYASSERT(c->parentsnddev);
+ CHN_LOCKASSERT(c);
+
+ c->flags &= ~CHN_F_BUSY;
+ c->pid = -1;
+ strlcpy(c->comm, CHN_COMM_UNUSED, sizeof(c->comm));
+ CHN_UNLOCK(c);
+
+ return (0);
+}
+
+int
+chn_ref(struct pcm_channel *c, int ref)
+{
+ PCM_BUSYASSERT(c->parentsnddev);
+ CHN_LOCKASSERT(c);
+ KASSERT((c->refcount + ref) >= 0,
+ ("%s(): new refcount will be negative", __func__));
+
+ c->refcount += ref;
+
+ return (c->refcount);
+}
+
int
chn_setvolume_multi(struct pcm_channel *c, int vc, int left, int right,
int center)
diff --git a/sys/dev/sound/pcm/channel.h b/sys/dev/sound/pcm/channel.h
index c8d33c583188..445882a62f0a 100644
--- a/sys/dev/sound/pcm/channel.h
+++ b/sys/dev/sound/pcm/channel.h
@@ -104,6 +104,7 @@ struct pcm_channel {
void *devinfo;
device_t dev;
int unit;
+ int type;
char name[CHN_NAMELEN];
char comm[MAXCOMLEN + 1];
struct mtx *lock;
@@ -224,7 +225,7 @@ struct pcm_channel {
#define CHN_INSERT_SORT(w, x, y, z) do { \
struct pcm_channel *t, *a = NULL; \
CHN_FOREACH(t, x, z) { \
- if ((y)->unit w t->unit) \
+ if ((y)->type w t->type) \
a = t; \
else \
break; \
@@ -235,13 +236,9 @@ struct pcm_channel {
CHN_INSERT_HEAD(x, y, z); \
} while (0)
-#define CHN_INSERT_SORT_ASCEND(x, y, z) CHN_INSERT_SORT(>, x, y, z)
+#define CHN_INSERT_SORT_ASCEND(x, y, z) CHN_INSERT_SORT(>=, x, y, z)
#define CHN_INSERT_SORT_DESCEND(x, y, z) CHN_INSERT_SORT(<, x, y, z)
-#define CHN_UNIT(x) (snd_unit2u((x)->unit))
-#define CHN_DEV(x) (snd_unit2d((x)->unit))
-#define CHN_CHAN(x) (snd_unit2c((x)->unit))
-
#define CHN_BUF_PARENT(x, y) \
(((x) != NULL && (x)->parentchannel != NULL && \
(x)->parentchannel->bufhard != NULL) ? \
@@ -262,9 +259,12 @@ int chn_sync(struct pcm_channel *c, int threshold);
int chn_flush(struct pcm_channel *c);
int chn_poll(struct pcm_channel *c, int ev, struct thread *td);
-int chn_init(struct pcm_channel *c, void *devinfo, int dir, int direction);
-int chn_kill(struct pcm_channel *c);
+struct pcm_channel *chn_init(struct snddev_info *d, struct pcm_channel *parent,
+ kobj_class_t cls, int dir, void *devinfo);
+void chn_kill(struct pcm_channel *c);
void chn_shutdown(struct pcm_channel *c);
+int chn_release(struct pcm_channel *c);
+int chn_ref(struct pcm_channel *c, int ref);
int chn_reset(struct pcm_channel *c, u_int32_t fmt, u_int32_t spd);
int chn_setvolume_multi(struct pcm_channel *c, int vc, int left, int right,
int center);
diff --git a/sys/dev/sound/pcm/dsp.c b/sys/dev/sound/pcm/dsp.c
index aa6c21f36601..6e5fad048d40 100644
--- a/sys/dev/sound/pcm/dsp.c
+++ b/sys/dev/sound/pcm/dsp.c
@@ -181,8 +181,8 @@ getchns(struct dsp_cdevpriv *priv, uint32_t prio)
pcm_setflags(d->dev, flags);
if (ch != NULL) {
CHN_LOCK(ch);
- pcm_chnref(ch, -1);
- pcm_chnrelease(ch);
+ chn_ref(ch, -1);
+ chn_release(ch);
}
PCM_RELEASE(d);
PCM_UNLOCK(d);
@@ -203,13 +203,6 @@ relchns(struct dsp_cdevpriv *priv, uint32_t prio)
CHN_UNLOCK(priv->wrch);
}
-/* duplex / simplex cdev type */
-enum {
- DSP_CDEV_TYPE_RDONLY, /* simplex read-only (record) */
- DSP_CDEV_TYPE_WRONLY, /* simplex write-only (play) */
- DSP_CDEV_TYPE_RDWR /* duplex read, write, or both */
-};
-
#define DSP_F_VALID(x) ((x) & (FREAD | FWRITE))
#define DSP_F_DUPLEX(x) (((x) & (FREAD | FWRITE)) == (FREAD | FWRITE))
#define DSP_F_SIMPLEX(x) (!DSP_F_DUPLEX(x))
@@ -221,48 +214,18 @@ static const struct {
char *name;
char *sep;
char *alias;
- int use_sep;
- int hw;
- int max;
- int volctl;
- uint32_t fmt, spd;
- int query;
} dsp_cdevs[] = {
- { SND_DEV_DSP, "dsp", ".", NULL, 0, 0, 0, 0,
- SND_FORMAT(AFMT_U8, 1, 0), DSP_DEFAULT_SPEED,
- DSP_CDEV_TYPE_RDWR },
- { SND_DEV_AUDIO, "audio", ".", NULL, 0, 0, 0, 0,
- SND_FORMAT(AFMT_MU_LAW, 1, 0), DSP_DEFAULT_SPEED,
- DSP_CDEV_TYPE_RDWR },
- { SND_DEV_DSP16, "dspW", ".", NULL, 0, 0, 0, 0,
- SND_FORMAT(AFMT_S16_LE, 1, 0), DSP_DEFAULT_SPEED,
- DSP_CDEV_TYPE_RDWR },
- { SND_DEV_DSPHW_PLAY, "dsp", ".p", NULL, 1, 1, SND_MAXHWCHAN, 1,
- SND_FORMAT(AFMT_S16_LE, 2, 0), 48000, DSP_CDEV_TYPE_WRONLY },
- { SND_DEV_DSPHW_VPLAY, "dsp", ".vp", NULL, 1, 1, SND_MAXVCHANS, 1,
- SND_FORMAT(AFMT_S16_LE, 2, 0), 48000, DSP_CDEV_TYPE_WRONLY },
- { SND_DEV_DSPHW_REC, "dsp", ".r", NULL, 1, 1, SND_MAXHWCHAN, 1,
- SND_FORMAT(AFMT_S16_LE, 2, 0), 48000, DSP_CDEV_TYPE_RDONLY },
- { SND_DEV_DSPHW_VREC, "dsp", ".vr", NULL, 1, 1, SND_MAXVCHANS, 1,
- SND_FORMAT(AFMT_S16_LE, 2, 0), 48000, DSP_CDEV_TYPE_RDONLY },
- { SND_DEV_DSPHW_CD, "dspcd", ".", NULL, 0, 0, 0, 0,
- SND_FORMAT(AFMT_S16_LE, 2, 0), 44100, DSP_CDEV_TYPE_RDWR },
+ { SND_DEV_DSP, "dsp", ".", NULL },
+ { SND_DEV_DSPHW_PLAY, "dsp", ".p", NULL },
+ { SND_DEV_DSPHW_VPLAY, "dsp", ".vp", NULL },
+ { SND_DEV_DSPHW_REC, "dsp", ".r", NULL },
+ { SND_DEV_DSPHW_VREC, "dsp", ".vr", NULL },
/* Low priority, OSSv4 aliases. */
- { SND_DEV_DSP, "dsp_ac3", ".", "dsp", 0, 0, 0, 0,
- SND_FORMAT(AFMT_U8, 1, 0), DSP_DEFAULT_SPEED,
- DSP_CDEV_TYPE_RDWR },
- { SND_DEV_DSP, "dsp_mmap", ".", "dsp", 0, 0, 0, 0,
- SND_FORMAT(AFMT_U8, 1, 0), DSP_DEFAULT_SPEED,
- DSP_CDEV_TYPE_RDWR },
- { SND_DEV_DSP, "dsp_multich", ".", "dsp", 0, 0, 0, 0,
- SND_FORMAT(AFMT_U8, 1, 0), DSP_DEFAULT_SPEED,
- DSP_CDEV_TYPE_RDWR },
- { SND_DEV_DSP, "dsp_spdifout", ".", "dsp", 0, 0, 0, 0,
- SND_FORMAT(AFMT_U8, 1, 0), DSP_DEFAULT_SPEED,
- DSP_CDEV_TYPE_RDWR },
- { SND_DEV_DSP, "dsp_spdifin", ".", "dsp", 0, 0, 0, 0,
- SND_FORMAT(AFMT_U8, 1, 0), DSP_DEFAULT_SPEED,
- DSP_CDEV_TYPE_RDWR },
+ { SND_DEV_DSP, "dsp_ac3", ".", "dsp" },
+ { SND_DEV_DSP, "dsp_mmap", ".", "dsp" },
+ { SND_DEV_DSP, "dsp_multich", ".", "dsp" },
+ { SND_DEV_DSP, "dsp_spdifout", ".", "dsp" },
+ { SND_DEV_DSP, "dsp_spdifin", ".", "dsp" },
};
static void
@@ -301,7 +264,7 @@ dsp_close(void *data)
wdref--;
else {
CHN_LOCK(volch);
- pcm_chnref(volch, -1);
+ chn_ref(volch, -1);
CHN_UNLOCK(volch);
}
}
@@ -332,12 +295,12 @@ dsp_close(void *data)
free_unr(pcmsg_unrhdr, sg_ids);
CHN_LOCK(rdch);
- pcm_chnref(rdch, rdref);
+ chn_ref(rdch, rdref);
chn_abort(rdch); /* won't sleep */
rdch->flags &= ~(CHN_F_RUNNING | CHN_F_MMAP |
CHN_F_DEAD | CHN_F_EXCLUSIVE);
chn_reset(rdch, 0, 0);
- pcm_chnrelease(rdch);
+ chn_release(rdch);
}
if (wrch != NULL) {
/*
@@ -350,12 +313,12 @@ dsp_close(void *data)
free_unr(pcmsg_unrhdr, sg_ids);
CHN_LOCK(wrch);
- pcm_chnref(wrch, wdref);
+ chn_ref(wrch, wdref);
chn_flush(wrch); /* may sleep */
wrch->flags &= ~(CHN_F_RUNNING | CHN_F_MMAP |
CHN_F_DEAD | CHN_F_EXCLUSIVE);
chn_reset(wrch, 0, 0);
- pcm_chnrelease(wrch);
+ chn_release(wrch);
}
PCM_LOCK(d);
}
@@ -444,14 +407,14 @@ dsp_open(struct cdev *i_dev, int flags, int mode, struct thread *td)
if (DSP_F_READ(flags)) {
/* open for read */
rderror = pcm_chnalloc(d, &rdch, PCMDIR_REC,
- td->td_proc->p_pid, td->td_proc->p_comm, -1);
+ td->td_proc->p_pid, td->td_proc->p_comm);
if (rderror == 0 && chn_reset(rdch, fmt, spd) != 0)
rderror = ENXIO;
if (rderror != 0) {
if (rdch != NULL)
- pcm_chnrelease(rdch);
+ chn_release(rdch);
if (!DSP_F_DUPLEX(flags)) {
PCM_RELEASE_QUICK(d);
PCM_GIANT_EXIT(d);
@@ -463,7 +426,7 @@ dsp_open(struct cdev *i_dev, int flags, int mode, struct thread *td)
rdch->flags |= CHN_F_NBIO;
if (flags & O_EXCL)
rdch->flags |= CHN_F_EXCLUSIVE;
- pcm_chnref(rdch, 1);
+ chn_ref(rdch, 1);
chn_vpc_reset(rdch, SND_VOL_C_PCM, 0);
CHN_UNLOCK(rdch);
}
@@ -472,14 +435,14 @@ dsp_open(struct cdev *i_dev, int flags, int mode, struct thread *td)
if (DSP_F_WRITE(flags)) {
/* open for write */
wrerror = pcm_chnalloc(d, &wrch, PCMDIR_PLAY,
- td->td_proc->p_pid, td->td_proc->p_comm, -1);
+ td->td_proc->p_pid, td->td_proc->p_comm);
if (wrerror == 0 && chn_reset(wrch, fmt, spd) != 0)
wrerror = ENXIO;
if (wrerror != 0) {
if (wrch != NULL)
- pcm_chnrelease(wrch);
+ chn_release(wrch);
if (!DSP_F_DUPLEX(flags)) {
if (rdch != NULL) {
/*
@@ -487,8 +450,8 @@ dsp_open(struct cdev *i_dev, int flags, int mode, struct thread *td)
* created record channel
*/
CHN_LOCK(rdch);
- pcm_chnref(rdch, -1);
- pcm_chnrelease(rdch);
+ chn_ref(rdch, -1);
+ chn_release(rdch);
}
PCM_RELEASE_QUICK(d);
PCM_GIANT_EXIT(d);
@@ -500,7 +463,7 @@ dsp_open(struct cdev *i_dev, int flags, int mode, struct thread *td)
wrch->flags |= CHN_F_NBIO;
if (flags & O_EXCL)
wrch->flags |= CHN_F_EXCLUSIVE;
- pcm_chnref(wrch, 1);
+ chn_ref(wrch, 1);
chn_vpc_reset(wrch, SND_VOL_C_PCM, 0);
CHN_UNLOCK(wrch);
}
@@ -630,68 +593,12 @@ dsp_write(struct cdev *i_dev, struct uio *buf, int flag)
}
static int
-dsp_get_volume_channel(struct dsp_cdevpriv *priv, struct pcm_channel **volch)
-{
- struct snddev_info *d;
- struct pcm_channel *c;
- int unit;
-
- KASSERT(volch != NULL,
- ("%s(): NULL query priv=%p volch=%p", __func__, priv, volch));
-
- d = priv->sc;
- if (!PCM_REGISTERED(d)) {
- *volch = NULL;
- return (EINVAL);
- }
-
- PCM_UNLOCKASSERT(d);
-
- *volch = NULL;
-
- c = priv->volch;
- if (c != NULL) {
- if (!(c->feederflags & (1 << FEEDER_VOLUME)))
- return (-1);
- *volch = c;
- return (0);
- }
-
- PCM_LOCK(d);
- PCM_WAIT(d);
- PCM_ACQUIRE(d);
-
- unit = dev2unit(d->dsp_dev);
-
- CHN_FOREACH(c, d, channels.pcm) {
- CHN_LOCK(c);
- if (c->unit != unit) {
- CHN_UNLOCK(c);
- continue;
- }
- *volch = c;
- pcm_chnref(c, 1);
- priv->volch = c;
- CHN_UNLOCK(c);
- PCM_RELEASE(d);
- PCM_UNLOCK(d);
- return ((c->feederflags & (1 << FEEDER_VOLUME)) ? 0 : -1);
- }
-
- PCM_RELEASE(d);
- PCM_UNLOCK(d);
-
- return (EINVAL);
-}
-
-static int
dsp_ioctl_channel(struct dsp_cdevpriv *priv, struct pcm_channel *volch,
u_long cmd, caddr_t arg)
{
struct snddev_info *d;
struct pcm_channel *rdch, *wrch;
- int j, devtype, ret;
- int left, right, center, mute;
+ int j, left, right, center, mute;
d = priv->sc;
if (!PCM_REGISTERED(d) || !(pcm_getflags(d->dev) & SD_F_VPC))
@@ -716,19 +623,6 @@ dsp_ioctl_channel(struct dsp_cdevpriv *priv, struct pcm_channel *volch,
volch = wrch;
}
- devtype = PCMDEV(d->dsp_dev);
-
- /* Look super harder */
- if (volch == NULL &&
- (devtype == SND_DEV_DSPHW_PLAY || devtype == SND_DEV_DSPHW_VPLAY ||
- devtype == SND_DEV_DSPHW_REC || devtype == SND_DEV_DSPHW_VREC)) {
- ret = dsp_get_volume_channel(priv, &volch);
- if (ret != 0)
- return (ret);
- if (volch == NULL)
- return (EINVAL);
- }
-
/* Final validation */
if (volch == NULL)
return (EINVAL);
@@ -2072,7 +1966,7 @@ dsp_clone(void *arg, struct ucred *cred, char *name, int namelen,
struct cdev **dev)
{
struct snddev_info *d;
- int i;
+ size_t i;
if (*dev != NULL)
return;
@@ -2105,8 +1999,6 @@ dsp_sysinit(void *p)
{
if (dsp_ehtag != NULL)
return;
- /* initialize unit numbering */
- snd_unit_init();
dsp_ehtag = EVENTHANDLER_REGISTER(dev_clone, dsp_clone, 0, 1000);
}
@@ -2123,20 +2015,19 @@ SYSINIT(dsp_sysinit, SI_SUB_DRIVERS, SI_ORDER_MIDDLE, dsp_sysinit, NULL);
SYSUNINIT(dsp_sysuninit, SI_SUB_DRIVERS, SI_ORDER_MIDDLE, dsp_sysuninit, NULL);
char *
-dsp_unit2name(char *buf, size_t len, int unit)
+dsp_unit2name(char *buf, size_t len, struct pcm_channel *ch)
{
- int i, dtype;
+ size_t i;
KASSERT(buf != NULL && len != 0,
("bogus buf=%p len=%ju", buf, (uintmax_t)len));
- dtype = snd_unit2d(unit);
-
for (i = 0; i < nitems(dsp_cdevs); i++) {
- if (dtype != dsp_cdevs[i].type || dsp_cdevs[i].alias != NULL)
+ if (ch->type != dsp_cdevs[i].type || dsp_cdevs[i].alias != NULL)
continue;
- snprintf(buf, len, "%s%d%s%d", dsp_cdevs[i].name,
- snd_unit2u(unit), dsp_cdevs[i].sep, snd_unit2c(unit));
+ snprintf(buf, len, "%s%d%s%d",
+ dsp_cdevs[i].name, device_get_unit(ch->dev),
+ dsp_cdevs[i].sep, ch->unit);
return (buf);
}
@@ -2185,7 +2076,7 @@ dsp_oss_audioinfo(struct cdev *i_dev, oss_audioinfo *ai)
struct pcm_channel *ch;
struct snddev_info *d;
uint32_t fmts;
- int i, nchan, *rates, minch, maxch;
+ int i, nchan, *rates, minch, maxch, unit;
char *devname, buf[CHN_NAMELEN];
/*
@@ -2205,9 +2096,9 @@ dsp_oss_audioinfo(struct cdev *i_dev, oss_audioinfo *ai)
* Search for the requested audio device (channel). Start by
* iterating over pcm devices.
*/
- for (i = 0; pcm_devclass != NULL &&
- i < devclass_get_maxunit(pcm_devclass); i++) {
- d = devclass_get_softc(pcm_devclass, i);
+ for (unit = 0; pcm_devclass != NULL &&
+ unit < devclass_get_maxunit(pcm_devclass); unit++) {
+ d = devclass_get_softc(pcm_devclass, unit);
if (!PCM_REGISTERED(d))
continue;
@@ -2224,12 +2115,10 @@ dsp_oss_audioinfo(struct cdev *i_dev, oss_audioinfo *ai)
if (devfs_foreach_cdevpriv(i_dev,
dsp_oss_audioinfo_cb, ch) != 0) {
devname = dsp_unit2name(buf,
- sizeof(buf), ch->unit);
+ sizeof(buf), ch);
}
- } else if (ai->dev == nchan) {
- devname = dsp_unit2name(buf, sizeof(buf),
- ch->unit);
- }
+ } else if (ai->dev == nchan)
+ devname = dsp_unit2name(buf, sizeof(buf), ch);
if (devname != NULL)
break;
CHN_UNLOCK(ch);
@@ -2332,14 +2221,13 @@ dsp_oss_audioinfo(struct cdev *i_dev, oss_audioinfo *ai)
* @todo @c port_number - routing information?
*/
ai->port_number = -1;
- ai->mixer_dev = (d->mixer_dev != NULL) ? PCMUNIT(d->mixer_dev) : -1;
+ ai->mixer_dev = (d->mixer_dev != NULL) ? unit : -1;
/**
* @note
- * @c real_device - OSSv4 docs: "Obsolete."
+ * @c legacy_device - OSSv4 docs: "Obsolete."
*/
- ai->real_device = -1;
- snprintf(ai->devnode, sizeof(ai->devnode),
- "/dev/dsp%d", device_get_unit(d->dev));
+ ai->legacy_device = -1;
+ snprintf(ai->devnode, sizeof(ai->devnode), "/dev/dsp%d", unit);
ai->enabled = device_is_attached(d->dev) ? 1 : 0;
/**
* @note
diff --git a/sys/dev/sound/pcm/dsp.h b/sys/dev/sound/pcm/dsp.h
index 6098c0641eb5..b81e60dc19b5 100644
--- a/sys/dev/sound/pcm/dsp.h
+++ b/sys/dev/sound/pcm/dsp.h
@@ -35,7 +35,7 @@ extern struct cdevsw dsp_cdevsw;
int dsp_make_dev(device_t);
void dsp_destroy_dev(device_t);
-char *dsp_unit2name(char *, size_t, int);
+char *dsp_unit2name(char *, size_t, struct pcm_channel *);
int dsp_oss_audioinfo(struct cdev *, oss_audioinfo *);
#endif /* !_PCMDSP_H_ */
diff --git a/sys/dev/sound/pcm/feeder.c b/sys/dev/sound/pcm/feeder.c
index 8278a85948a8..0113299bd0d4 100644
--- a/sys/dev/sound/pcm/feeder.c
+++ b/sys/dev/sound/pcm/feeder.c
@@ -32,6 +32,7 @@
#endif
#include <dev/sound/pcm/sound.h>
+#include <dev/sound/pcm/vchan.h>
#include "feeder_if.h"
@@ -82,9 +83,7 @@ feeder_register(void *p)
if (snd_verbose < 0 || snd_verbose > 4)
snd_verbose = 1;
- /* initialize unit numbering */
- snd_unit_init();
- if (snd_unit < 0 || snd_unit > PCMMAXUNIT)
+ if (snd_unit < 0)
snd_unit = -1;
if (snd_maxautovchans < 0 ||
diff --git a/sys/dev/sound/pcm/feeder_format.c b/sys/dev/sound/pcm/feeder_format.c
index 1e18e3e07450..3bdd808df0ee 100644
--- a/sys/dev/sound/pcm/feeder_format.c
+++ b/sys/dev/sound/pcm/feeder_format.c
@@ -115,16 +115,13 @@ static const struct {
}
};
-#define FEEDFORMAT_TAB_SIZE \
- ((int32_t)(sizeof(feed_format_ops) / sizeof(feed_format_ops[0])))
-
static int
feed_format_init(struct pcm_feeder *f)
{
struct feed_format_info *info;
intpcm_read_t *rd_op;
intpcm_write_t *wr_op;
- int i;
+ size_t i;
if (f->desc->in == f->desc->out ||
AFMT_CHANNEL(f->desc->in) != AFMT_CHANNEL(f->desc->out))
@@ -133,7 +130,7 @@ feed_format_init(struct pcm_feeder *f)
rd_op = NULL;
wr_op = NULL;
- for (i = 0; i < FEEDFORMAT_TAB_SIZE &&
+ for (i = 0; i < nitems(feed_format_ops) &&
(rd_op == NULL || wr_op == NULL); i++) {
if (rd_op == NULL &&
AFMT_ENCODING(f->desc->in) == feed_format_ops[i].format)
@@ -276,9 +273,9 @@ FEEDER_DECLARE(feeder_format, NULL);
intpcm_read_t *
feeder_format_read_op(uint32_t format)
{
- int i;
+ size_t i;
- for (i = 0; i < FEEDFORMAT_TAB_SIZE; i++) {
+ for (i = 0; i < nitems(feed_format_ops); i++) {
if (AFMT_ENCODING(format) == feed_format_ops[i].format)
return (feed_format_ops[i].read);
}
@@ -289,9 +286,9 @@ feeder_format_read_op(uint32_t format)
intpcm_write_t *
feeder_format_write_op(uint32_t format)
{
- int i;
+ size_t i;
- for (i = 0; i < FEEDFORMAT_TAB_SIZE; i++) {
+ for (i = 0; i < nitems(feed_format_ops); i++) {
if (AFMT_ENCODING(format) == feed_format_ops[i].format)
return (feed_format_ops[i].write);
}
diff --git a/sys/dev/sound/pcm/feeder_matrix.c b/sys/dev/sound/pcm/feeder_matrix.c
index f5f02e2bf4f5..97cf86585636 100644
--- a/sys/dev/sound/pcm/feeder_matrix.c
+++ b/sys/dev/sound/pcm/feeder_matrix.c
@@ -230,7 +230,7 @@ feed_matrix_reset(struct feed_matrix_info *info)
{
uint32_t i, j;
- for (i = 0; i < (sizeof(info->matrix) / sizeof(info->matrix[0])); i++) {
+ for (i = 0; i < nitems(info->matrix); i++) {
for (j = 0;
j < (sizeof(info->matrix[i].chn) /
sizeof(info->matrix[i].chn[0])); j++) {
@@ -679,7 +679,7 @@ feeder_matrix_compare(struct pcmchan_matrix *m_in, struct pcmchan_matrix *m_out)
m_in->mask != m_out->mask)
return (1);
- for (i = 0; i < (sizeof(m_in->map) / sizeof(m_in->map[0])); i++) {
+ for (i = 0; i < nitems(m_in->map); i++) {
if (m_in->map[i].type != m_out->map[i].type)
return (1);
if (m_in->map[i].type == SND_CHN_T_MAX)
diff --git a/sys/dev/sound/pcm/feeder_volume.c b/sys/dev/sound/pcm/feeder_volume.c
index 452d8788a5a5..7e600c131afe 100644
--- a/sys/dev/sound/pcm/feeder_volume.c
+++ b/sys/dev/sound/pcm/feeder_volume.c
@@ -337,7 +337,7 @@ feeder_volume_apply_matrix(struct pcm_feeder *f, struct pcmchan_matrix *m)
info = f->data;
- for (i = 0; i < (sizeof(info->matrix) / sizeof(info->matrix[0])); i++) {
+ for (i = 0; i < nitems(info->matrix); i++) {
if (i < m->channels)
info->matrix[i] = m->map[i].type;
else
diff --git a/sys/dev/sound/pcm/mixer.c b/sys/dev/sound/pcm/mixer.c
index 0645089ac503..9811496853c8 100644
--- a/sys/dev/sound/pcm/mixer.c
+++ b/sys/dev/sound/pcm/mixer.c
@@ -650,7 +650,7 @@ mixer_obj_create(device_t dev, kobj_class_t cls, void *devinfo,
int type, const char *desc)
{
struct snd_mixer *m;
- int i;
+ size_t i;
KASSERT(dev != NULL && cls != NULL && devinfo != NULL,
("%s(): NULL data dev=%p cls=%p devinfo=%p",
@@ -671,7 +671,7 @@ mixer_obj_create(device_t dev, kobj_class_t cls, void *devinfo,
m->devinfo = devinfo;
m->busy = 0;
m->dev = dev;
- for (i = 0; i < (sizeof(m->parent) / sizeof(m->parent[0])); i++) {
+ for (i = 0; i < nitems(m->parent); i++) {
m->parent[i] = SOUND_MIXER_NONE;
m->child[i] = 0;
m->realdev[i] = i;
@@ -726,14 +726,17 @@ mixer_init(device_t dev, kobj_class_t cls, void *devinfo)
struct snd_mixer *m;
u_int16_t v;
struct cdev *pdev;
- int i, unit, devunit, val;
+ const char *name;
+ int i, unit, val;
snddev = device_get_softc(dev);
if (snddev == NULL)
return (-1);
- if (resource_int_value(device_get_name(dev),
- device_get_unit(dev), "eq", &val) == 0 && val != 0) {
+ name = device_get_name(dev);
+ unit = device_get_unit(dev);
+ if (resource_int_value(name, unit, "eq", &val) == 0 &&
+ val != 0) {
snddev->flags |= SD_F_EQ;
if ((val & SD_F_EQ_MASK) == val)
snddev->flags |= val;
@@ -749,8 +752,8 @@ mixer_init(device_t dev, kobj_class_t cls, void *devinfo)
for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) {
v = snd_mixerdefaults[i];
- if (resource_int_value(device_get_name(dev),
- device_get_unit(dev), snd_mixernames[i], &val) == 0) {
+ if (resource_int_value(name, unit, snd_mixernames[i],
+ &val) == 0) {
if (val >= 0 && val <= 100) {
v = (u_int16_t) val;
}
@@ -761,10 +764,8 @@ mixer_init(device_t dev, kobj_class_t cls, void *devinfo)
mixer_setrecsrc(m, 0); /* Set default input. */
- unit = device_get_unit(dev);
- devunit = snd_mkunit(unit, SND_DEV_CTL, 0);
- pdev = make_dev(&mixer_cdevsw, PCMMINOR(devunit),
- UID_ROOT, GID_WHEEL, 0666, "mixer%d", unit);
+ pdev = make_dev(&mixer_cdevsw, SND_DEV_CTL, UID_ROOT, GID_WHEEL, 0666,
+ "mixer%d", unit);
pdev->si_drv1 = m;
snddev->mixer_dev = pdev;
@@ -1430,7 +1431,7 @@ mixer_oss_mixerinfo(struct cdev *i_dev, oss_mixerinfo *mi)
{
struct snddev_info *d;
struct snd_mixer *m;
- int nmix, i;
+ int i;
/*
* If probing the device handling the ioctl, make sure it's a mixer
@@ -1441,7 +1442,6 @@ mixer_oss_mixerinfo(struct cdev *i_dev, oss_mixerinfo *mi)
d = NULL;
m = NULL;
- nmix = 0;
/*
* There's a 1:1 relationship between mixers and PCM devices, so
@@ -1461,7 +1461,7 @@ mixer_oss_mixerinfo(struct cdev *i_dev, oss_mixerinfo *mi)
if (d->mixer_dev != NULL && d->mixer_dev->si_drv1 != NULL &&
((mi->dev == -1 && d->mixer_dev == i_dev) ||
- mi->dev == nmix)) {
+ mi->dev == i)) {
m = d->mixer_dev->si_drv1;
mtx_lock(m->lock);
@@ -1473,7 +1473,7 @@ mixer_oss_mixerinfo(struct cdev *i_dev, oss_mixerinfo *mi)
* sure to unlock when existing.
*/
bzero((void *)mi, sizeof(*mi));
- mi->dev = nmix;
+ mi->dev = i;
snprintf(mi->id, sizeof(mi->id), "mixer%d", i);
strlcpy(mi->name, m->name, sizeof(mi->name));
mi->modify_counter = m->modify_counter;
@@ -1516,6 +1516,7 @@ mixer_oss_mixerinfo(struct cdev *i_dev, oss_mixerinfo *mi)
* Mixer extensions currently aren't supported, so
* leave @sa oss_mixerinfo::nrext blank for now.
*/
+
/**
* @todo Fill in @sa oss_mixerinfo::priority (requires
* touching drivers?)
@@ -1529,16 +1530,13 @@ mixer_oss_mixerinfo(struct cdev *i_dev, oss_mixerinfo *mi)
* default mixer. Other devices use values 1 to 9
* depending on the estimated probability of being the
* default device.
- *
- * XXX Described by Hannu@4Front, but not found in
- * soundcard.h.
- strlcpy(mi->devnode, devtoname(d->mixer_dev),
- sizeof(mi->devnode));
- mi->legacy_device = i;
*/
+
+ snprintf(mi->devnode, sizeof(mi->devnode), "/dev/mixer%d", i);
+ mi->legacy_device = i;
+
mtx_unlock(m->lock);
- } else
- ++nmix;
+ }
PCM_UNLOCK(d);
diff --git a/sys/dev/sound/pcm/sndstat.c b/sys/dev/sound/pcm/sndstat.c
index ef006a580d40..edb33e92ade9 100644
--- a/sys/dev/sound/pcm/sndstat.c
+++ b/sys/dev/sound/pcm/sndstat.c
@@ -51,7 +51,6 @@
#include <dev/sound/pcm/sound.h>
#include <dev/sound/pcm/pcm.h>
-#include <dev/sound/version.h>
#include "feeder_if.h"
@@ -1271,11 +1270,8 @@ sndstat_prepare(struct sndstat_file *pf_self)
/* make sure buffer is reset */
sbuf_clear(s);
- if (snd_verbose > 0) {
- sbuf_printf(s, "FreeBSD Audio Driver (%ubit %d/%s)\n",
- (u_int)sizeof(intpcm32_t) << 3, SND_DRV_VERSION,
- MACHINE_ARCH);
- }
+ if (snd_verbose > 0)
+ sbuf_printf(s, "FreeBSD Audio Driver\n");
/* generate list of installed devices */
k = 0;
diff --git a/sys/dev/sound/pcm/sound.c b/sys/dev/sound/pcm/sound.c
index 2057c7572ad6..e66462af2a71 100644
--- a/sys/dev/sound/pcm/sound.c
+++ b/sys/dev/sound/pcm/sound.c
@@ -41,7 +41,6 @@
#include <dev/sound/pcm/ac97.h>
#include <dev/sound/pcm/vchan.h>
#include <dev/sound/pcm/dsp.h>
-#include <dev/sound/version.h>
#include <sys/limits.h>
#include <sys/sysctl.h>
@@ -57,22 +56,11 @@ static int snd_unit_auto = -1;
SYSCTL_INT(_hw_snd, OID_AUTO, default_auto, CTLFLAG_RWTUN,
&snd_unit_auto, 0, "assign default unit to a newly attached device");
-int snd_maxautovchans = 16;
-
SYSCTL_NODE(_hw, OID_AUTO, snd, CTLFLAG_RD | CTLFLAG_MPSAFE, 0,
"Sound driver");
static void pcm_sysinit(device_t);
-/*
- * XXX I've had enough with people not telling proper version/arch
- * while reporting problems, not after 387397913213th questions/requests.
- */
-static char snd_driver_version[] =
- __XSTRING(SND_DRV_VERSION)"/"MACHINE_ARCH;
-SYSCTL_STRING(_hw_snd, OID_AUTO, version, CTLFLAG_RD, &snd_driver_version,
- 0, "driver version/arch");
-
/**
* @brief Unit number allocator for syncgroup IDs
*/
@@ -121,271 +109,71 @@ snd_setup_intr(device_t dev, struct resource *res, int flags, driver_intr_t hand
return bus_setup_intr(dev, res, flags, NULL, hand, param, cookiep);
}
-int
-pcm_setvchans(struct snddev_info *d, int direction, int newcnt, int num)
-{
- struct pcm_channel *c, *ch, *nch;
- struct pcmchan_caps *caps;
- int i, err, vcnt;
-
- PCM_BUSYASSERT(d);
-
- if ((direction == PCMDIR_PLAY && d->playcount < 1) ||
- (direction == PCMDIR_REC && d->reccount < 1))
- return (ENODEV);
-
- if (!(d->flags & SD_F_AUTOVCHAN))
- return (EINVAL);
-
- if (newcnt < 0 || newcnt > SND_MAXVCHANS)
- return (E2BIG);
-
- if (direction == PCMDIR_PLAY)
- vcnt = d->pvchancount;
- else if (direction == PCMDIR_REC)
- vcnt = d->rvchancount;
- else
- return (EINVAL);
-
- if (newcnt > vcnt) {
- KASSERT(num == -1 ||
- (num >= 0 && num < SND_MAXVCHANS && (newcnt - 1) == vcnt),
- ("bogus vchan_create() request num=%d newcnt=%d vcnt=%d",
- num, newcnt, vcnt));
- /* add new vchans - find a parent channel first */
- ch = NULL;
- CHN_FOREACH(c, d, channels.pcm) {
- CHN_LOCK(c);
- if (c->direction == direction &&
- ((c->flags & CHN_F_HAS_VCHAN) || (vcnt == 0 &&
- c->refcount < 1 &&
- !(c->flags & (CHN_F_BUSY | CHN_F_VIRTUAL))))) {
- /*
- * Reuse hw channel with vchans already
- * created.
- */
- if (c->flags & CHN_F_HAS_VCHAN) {
- ch = c;
- break;
- }
- /*
- * No vchans ever created, look for
- * channels with supported formats.
- */
- caps = chn_getcaps(c);
- if (caps == NULL) {
- CHN_UNLOCK(c);
- continue;
- }
- for (i = 0; caps->fmtlist[i] != 0; i++) {
- if (caps->fmtlist[i] & AFMT_CONVERTIBLE)
- break;
- }
- if (caps->fmtlist[i] != 0) {
- ch = c;
- break;
- }
- }
- CHN_UNLOCK(c);
- }
- if (ch == NULL)
- return (EBUSY);
- ch->flags |= CHN_F_BUSY;
- err = 0;
- while (err == 0 && newcnt > vcnt) {
- err = vchan_create(ch, num);
- if (err == 0)
- vcnt++;
- else if (err == E2BIG && newcnt > vcnt)
- device_printf(d->dev,
- "%s: err=%d Maximum channel reached.\n",
- __func__, err);
- }
- if (vcnt == 0)
- ch->flags &= ~CHN_F_BUSY;
- CHN_UNLOCK(ch);
- if (err != 0)
- return (err);
- } else if (newcnt < vcnt) {
- KASSERT(num == -1,
- ("bogus vchan_destroy() request num=%d", num));
- CHN_FOREACH(c, d, channels.pcm) {
- CHN_LOCK(c);
- if (c->direction != direction ||
- CHN_EMPTY(c, children) ||
- !(c->flags & CHN_F_HAS_VCHAN)) {
- CHN_UNLOCK(c);
- continue;
- }
- CHN_FOREACH_SAFE(ch, c, nch, children) {
- CHN_LOCK(ch);
- if (vcnt == 1 && c->refcount > 0) {
- CHN_UNLOCK(ch);
- break;
- }
- if (!(ch->flags & CHN_F_BUSY) &&
- ch->refcount < 1) {
- err = vchan_destroy(ch);
- if (err == 0)
- vcnt--;
- } else
- CHN_UNLOCK(ch);
- if (vcnt == newcnt)
- break;
- }
- CHN_UNLOCK(c);
- break;
- }
- }
-
- return (0);
-}
-
/* return error status and a locked channel */
int
pcm_chnalloc(struct snddev_info *d, struct pcm_channel **ch, int direction,
- pid_t pid, char *comm, int devunit)
+ pid_t pid, char *comm)
{
struct pcm_channel *c;
int err, vchancount, vchan_num;
+ bool retry;
- KASSERT(d != NULL && ch != NULL && (devunit == -1 ||
- !(devunit & ~(SND_U_MASK | SND_D_MASK | SND_C_MASK))) &&
+ KASSERT(d != NULL && ch != NULL &&
(direction == PCMDIR_PLAY || direction == PCMDIR_REC),
- ("%s(): invalid d=%p ch=%p direction=%d pid=%d devunit=%d",
- __func__, d, ch, direction, pid, devunit));
+ ("%s(): invalid d=%p ch=%p direction=%d pid=%d",
+ __func__, d, ch, direction, pid));
PCM_BUSYASSERT(d);
- /* Double check again. */
- if (devunit != -1) {
- switch (snd_unit2d(devunit)) {
- case SND_DEV_DSPHW_PLAY:
- case SND_DEV_DSPHW_VPLAY:
- if (direction != PCMDIR_PLAY)
- return (ENOTSUP);
- break;
- case SND_DEV_DSPHW_REC:
- case SND_DEV_DSPHW_VREC:
- if (direction != PCMDIR_REC)
- return (ENOTSUP);
- break;
- default:
- if (!(direction == PCMDIR_PLAY ||
- direction == PCMDIR_REC))
- return (ENOTSUP);
- break;
- }
- }
-
*ch = NULL;
vchan_num = 0;
vchancount = (direction == PCMDIR_PLAY) ? d->pvchancount :
d->rvchancount;
+ retry = false;
retry_chnalloc:
err = ENOTSUP;
/* scan for a free channel */
CHN_FOREACH(c, d, channels.pcm) {
CHN_LOCK(c);
- if (devunit == -1 && c->direction == direction &&
- (c->flags & CHN_F_VIRTUAL)) {
+ if (c->direction == direction && (c->flags & CHN_F_VIRTUAL)) {
if (vchancount < snd_maxautovchans &&
- vchan_num < CHN_CHAN(c)) {
+ vchan_num < c->unit) {
CHN_UNLOCK(c);
goto vchan_alloc;
}
vchan_num++;
}
- if (c->direction == direction && !(c->flags & CHN_F_BUSY) &&
- (devunit == -1 || devunit == -2 || c->unit == devunit)) {
+ if (c->direction == direction && !(c->flags & CHN_F_BUSY)) {
c->flags |= CHN_F_BUSY;
c->pid = pid;
strlcpy(c->comm, (comm != NULL) ? comm :
CHN_COMM_UNKNOWN, sizeof(c->comm));
*ch = c;
return (0);
- } else if (c->unit == devunit) {
- if (c->direction != direction)
- err = ENOTSUP;
- else if (c->flags & CHN_F_BUSY)
- err = EBUSY;
- else
- err = EINVAL;
- CHN_UNLOCK(c);
- return (err);
- } else if ((devunit == -1 || devunit == -2) &&
- c->direction == direction && (c->flags & CHN_F_BUSY))
+ } else if (c->direction == direction && (c->flags & CHN_F_BUSY))
err = EBUSY;
CHN_UNLOCK(c);
}
- if (devunit == -2)
+ /*
+ * We came from retry_chnalloc and still didn't find a free channel.
+ */
+ if (retry)
return (err);
vchan_alloc:
/* no channel available */
- if (devunit == -1 || snd_unit2d(devunit) == SND_DEV_DSPHW_VPLAY ||
- snd_unit2d(devunit) == SND_DEV_DSPHW_VREC) {
- if (!(vchancount > 0 && vchancount < snd_maxautovchans) &&
- (devunit == -1 || snd_unit2c(devunit) < snd_maxautovchans))
- return (err);
- err = pcm_setvchans(d, direction, vchancount + 1,
- (devunit == -1) ? -1 : snd_unit2c(devunit));
- if (err == 0) {
- if (devunit == -1)
- devunit = -2;
- goto retry_chnalloc;
- }
+ if (!(vchancount > 0 && vchancount < snd_maxautovchans))
+ return (err);
+ err = vchan_setnew(d, direction, vchancount + 1);
+ if (err == 0) {
+ retry = true;
+ goto retry_chnalloc;
}
return (err);
}
-/* release a locked channel and unlock it */
-int
-pcm_chnrelease(struct pcm_channel *c)
-{
- PCM_BUSYASSERT(c->parentsnddev);
- CHN_LOCKASSERT(c);
-
- c->flags &= ~CHN_F_BUSY;
- c->pid = -1;
- strlcpy(c->comm, CHN_COMM_UNUSED, sizeof(c->comm));
- CHN_UNLOCK(c);
-
- return (0);
-}
-
-int
-pcm_chnref(struct pcm_channel *c, int ref)
-{
- PCM_BUSYASSERT(c->parentsnddev);
- CHN_LOCKASSERT(c);
-
- c->refcount += ref;
-
- return (c->refcount);
-}
-
-static void
-pcm_setmaxautovchans(struct snddev_info *d, int num)
-{
- PCM_BUSYASSERT(d);
-
- if (num < 0)
- return;
-
- if (num >= 0 && d->pvchancount > num)
- (void)pcm_setvchans(d, PCMDIR_PLAY, num, -1);
- else if (num > 0 && d->pvchancount == 0)
- (void)pcm_setvchans(d, PCMDIR_PLAY, 1, -1);
-
- if (num >= 0 && d->rvchancount > num)
- (void)pcm_setvchans(d, PCMDIR_REC, num, -1);
- else if (num > 0 && d->rvchancount == 0)
- (void)pcm_setvchans(d, PCMDIR_REC, 1, -1);
-}
-
static int
sysctl_hw_snd_default_unit(SYSCTL_HANDLER_ARGS)
{
@@ -409,173 +197,7 @@ SYSCTL_PROC(_hw_snd, OID_AUTO, default_unit,
sizeof(int), sysctl_hw_snd_default_unit, "I",
"default sound device");
-static int
-sysctl_hw_snd_maxautovchans(SYSCTL_HANDLER_ARGS)
-{
- struct snddev_info *d;
- int i, v, error;
-
- v = snd_maxautovchans;
- error = sysctl_handle_int(oidp, &v, 0, req);
- if (error == 0 && req->newptr != NULL) {
- if (v < 0)
- v = 0;
- if (v > SND_MAXVCHANS)
- v = SND_MAXVCHANS;
- snd_maxautovchans = v;
- for (i = 0; pcm_devclass != NULL &&
- i < devclass_get_maxunit(pcm_devclass); i++) {
- d = devclass_get_softc(pcm_devclass, i);
- if (!PCM_REGISTERED(d))
- continue;
- PCM_ACQUIRE_QUICK(d);
- pcm_setmaxautovchans(d, v);
- PCM_RELEASE_QUICK(d);
- }
- }
- return (error);
-}
-SYSCTL_PROC(_hw_snd, OID_AUTO, maxautovchans,
- CTLTYPE_INT | CTLFLAG_RWTUN | CTLFLAG_NEEDGIANT, 0, sizeof(int),
- sysctl_hw_snd_maxautovchans, "I",
- "maximum virtual channel");
-
-struct pcm_channel *
-pcm_chn_create(struct snddev_info *d, struct pcm_channel *parent, kobj_class_t cls, int dir, int num, void *devinfo)
-{
- struct pcm_channel *ch;
- int direction, err, rpnum, *pnum, max;
- int udc, device, chan;
- char *dirs, *devname, buf[CHN_NAMELEN];
-
- PCM_BUSYASSERT(d);
- PCM_LOCKASSERT(d);
- KASSERT(num >= -1, ("invalid num=%d", num));
-
- switch (dir) {
- case PCMDIR_PLAY:
- dirs = "play";
- direction = PCMDIR_PLAY;
- pnum = &d->playcount;
- device = SND_DEV_DSPHW_PLAY;
- max = SND_MAXHWCHAN;
- break;
- case PCMDIR_PLAY_VIRTUAL:
- dirs = "virtual";
- direction = PCMDIR_PLAY;
- pnum = &d->pvchancount;
- device = SND_DEV_DSPHW_VPLAY;
- max = SND_MAXVCHANS;
- break;
- case PCMDIR_REC:
- dirs = "record";
- direction = PCMDIR_REC;
- pnum = &d->reccount;
- device = SND_DEV_DSPHW_REC;
- max = SND_MAXHWCHAN;
- break;
- case PCMDIR_REC_VIRTUAL:
- dirs = "virtual";
- direction = PCMDIR_REC;
- pnum = &d->rvchancount;
- device = SND_DEV_DSPHW_VREC;
- max = SND_MAXVCHANS;
- break;
- default:
- return (NULL);
- }
-
- chan = (num == -1) ? 0 : num;
-
- if (*pnum >= max || chan >= max)
- return (NULL);
-
- rpnum = 0;
-
- CHN_FOREACH(ch, d, channels.pcm) {
- if (CHN_DEV(ch) != device)
- continue;
- if (chan == CHN_CHAN(ch)) {
- if (num != -1) {
- device_printf(d->dev,
- "channel num=%d allocated!\n", chan);
- return (NULL);
- }
- chan++;
- if (chan >= max) {
- device_printf(d->dev,
- "chan=%d > %d\n", chan, max);
- return (NULL);
- }
- }
- rpnum++;
- }
-
- if (*pnum != rpnum) {
- device_printf(d->dev,
- "%s(): WARNING: pnum screwed : dirs=%s pnum=%d rpnum=%d\n",
- __func__, dirs, *pnum, rpnum);
- return (NULL);
- }
-
- udc = snd_mkunit(device_get_unit(d->dev), device, chan);
- devname = dsp_unit2name(buf, sizeof(buf), udc);
-
- if (devname == NULL) {
- device_printf(d->dev,
- "Failed to query device name udc=0x%08x\n", udc);
- return (NULL);
- }
-
- PCM_UNLOCK(d);
- ch = malloc(sizeof(*ch), M_DEVBUF, M_WAITOK | M_ZERO);
- ch->methods = kobj_create(cls, M_DEVBUF, M_WAITOK | M_ZERO);
- ch->unit = udc;
- ch->pid = -1;
- strlcpy(ch->comm, CHN_COMM_UNUSED, sizeof(ch->comm));
- ch->parentsnddev = d;
- ch->parentchannel = parent;
- ch->dev = d->dev;
- ch->trigger = PCMTRIG_STOP;
- snprintf(ch->name, sizeof(ch->name), "%s:%s:%s",
- device_get_nameunit(ch->dev), dirs, devname);
-
- err = chn_init(ch, devinfo, dir, direction);
- PCM_LOCK(d);
- if (err) {
- device_printf(d->dev, "chn_init(%s) failed: err = %d\n",
- ch->name, err);
- kobj_delete(ch->methods, M_DEVBUF);
- free(ch, M_DEVBUF);
- return (NULL);
- }
-
- return (ch);
-}
-
-int
-pcm_chn_destroy(struct pcm_channel *ch)
-{
- struct snddev_info *d __diagused;
- int err;
-
- d = ch->parentsnddev;
- PCM_BUSYASSERT(d);
-
- err = chn_kill(ch);
- if (err) {
- device_printf(ch->dev, "chn_kill(%s) failed, err = %d\n",
- ch->name, err);
- return (err);
- }
-
- kobj_delete(ch->methods, M_DEVBUF);
- free(ch, M_DEVBUF);
-
- return (0);
-}
-
-int
+void
pcm_chn_add(struct snddev_info *d, struct pcm_channel *ch)
{
PCM_BUSYASSERT(d);
@@ -585,7 +207,7 @@ pcm_chn_add(struct snddev_info *d, struct pcm_channel *ch)
CHN_INSERT_SORT_ASCEND(d, ch, channels.pcm);
- switch (CHN_DEV(ch)) {
+ switch (ch->type) {
case SND_DEV_DSPHW_PLAY:
d->playcount++;
break;
@@ -599,12 +221,8 @@ pcm_chn_add(struct snddev_info *d, struct pcm_channel *ch)
d->rvchancount++;
break;
default:
- break;
+ __assert_unreachable();
}
-
- d->devcount++;
-
- return (0);
}
int
@@ -627,7 +245,7 @@ pcm_chn_remove(struct snddev_info *d, struct pcm_channel *ch)
CHN_REMOVE(d, ch, channels.pcm);
- switch (CHN_DEV(ch)) {
+ switch (ch->type) {
case SND_DEV_DSPHW_PLAY:
d->playcount--;
break;
@@ -641,11 +259,9 @@ pcm_chn_remove(struct snddev_info *d, struct pcm_channel *ch)
d->rvchancount--;
break;
default:
- break;
+ __assert_unreachable();
}
- d->devcount--;
-
return (0);
}
@@ -654,28 +270,22 @@ pcm_addchan(device_t dev, int dir, kobj_class_t cls, void *devinfo)
{
struct snddev_info *d = device_get_softc(dev);
struct pcm_channel *ch;
- int err;
PCM_BUSYASSERT(d);
PCM_LOCK(d);
- ch = pcm_chn_create(d, NULL, cls, dir, -1, devinfo);
+ ch = chn_init(d, NULL, cls, dir, devinfo);
if (!ch) {
- device_printf(d->dev, "pcm_chn_create(%s, %d, %p) failed\n",
+ device_printf(d->dev, "chn_init(%s, %d, %p) failed\n",
cls->name, dir, devinfo);
PCM_UNLOCK(d);
return (ENODEV);
}
- err = pcm_chn_add(d, ch);
+ pcm_chn_add(d, ch);
PCM_UNLOCK(d);
- if (err) {
- device_printf(d->dev, "pcm_chn_add(%s) failed, err=%d\n",
- ch->name, err);
- pcm_chn_destroy(ch);
- }
- return (err);
+ return (0);
}
static void
@@ -720,7 +330,7 @@ pcm_killchans(struct snddev_info *d)
error = pcm_chn_remove(d, ch);
PCM_UNLOCK(d);
if (error == 0)
- pcm_chn_destroy(ch);
+ chn_kill(ch);
} while (!CHN_EMPTY(d, channels.pcm));
}
@@ -767,7 +377,7 @@ pcm_setstatus(device_t dev, char *str)
if (d->playcount > 0 || d->reccount > 0)
d->flags |= SD_F_AUTOVCHAN;
- pcm_setmaxautovchans(d, snd_maxautovchans);
+ vchan_setmaxauto(d, snd_maxautovchans);
strlcpy(d->status, str, SND_STATUSLEN);
@@ -943,14 +553,6 @@ pcm_register(device_t dev, void *devinfo, int numplay, int numrec)
return EINVAL;
}
- if (device_get_unit(dev) > PCMMAXUNIT) {
- device_printf(dev, "PCMMAXUNIT reached : unit=%d > %d\n",
- device_get_unit(dev), PCMMAXUNIT);
- device_printf(dev,
- "Use 'hw.snd.maxunit' tunable to raise the limit.\n");
- return ENODEV;
- }
-
d = device_get_softc(dev);
d->dev = dev;
d->lock = snd_mtxcreate(device_get_nameunit(dev), "sound cdev");
@@ -974,7 +576,6 @@ pcm_register(device_t dev, void *devinfo, int numplay, int numrec)
d->flags |= SD_F_BITPERFECT;
d->devinfo = devinfo;
- d->devcount = 0;
d->reccount = 0;
d->playcount = 0;
d->pvchancount = 0;
@@ -1107,9 +708,8 @@ sound_oss_sysinfo(oss_sysinfo *si)
struct snddev_info *d;
struct pcm_channel *c;
- int i, j, ncards;
-
- ncards = 0;
+ int j;
+ size_t i;
strlcpy(si->product, si_product, sizeof(si->product));
strlcpy(si->version, si_version, sizeof(si->version));
@@ -1118,7 +718,7 @@ sound_oss_sysinfo(oss_sysinfo *si)
/*
* Iterate over PCM devices and their channels, gathering up data
- * for the numaudios, ncards, and openedaudio fields.
+ * for the numaudios and openedaudio fields.
*/
si->numaudios = 0;
bzero((void *)&si->openedaudio, sizeof(si->openedaudio));
@@ -1137,8 +737,7 @@ sound_oss_sysinfo(oss_sysinfo *si)
PCM_UNLOCKASSERT(d);
PCM_LOCK(d);
- si->numaudios += d->devcount;
- ++ncards;
+ si->numaudios += PCM_CHANCOUNT(d);
CHN_FOREACH(c, d, channels.pcm) {
CHN_UNLOCKASSERT(c);
@@ -1169,7 +768,7 @@ sound_oss_sysinfo(oss_sysinfo *si)
si->nummidis = 0;
si->numtimers = 0;
si->nummixers = mixer_count;
- si->numcards = ncards;
+ si->numcards = devclass_get_maxunit(pcm_devclass);
/* OSSv4 docs: Intended only for test apps; API doesn't
really have much of a concept of cards. Shouldn't be
used by applications. */
@@ -1185,7 +784,7 @@ sound_oss_sysinfo(oss_sysinfo *si)
* Si->filler is a reserved array, but according to docs each
* element should be set to -1.
*/
- for (i = 0; i < sizeof(si->filler)/sizeof(si->filler[0]); i++)
+ for (i = 0; i < nitems(si->filler); i++)
si->filler[i] = -1;
}
@@ -1193,9 +792,7 @@ int
sound_oss_card_info(oss_card_info *si)
{
struct snddev_info *d;
- int i, ncards;
-
- ncards = 0;
+ int i;
for (i = 0; pcm_devclass != NULL &&
i < devclass_get_maxunit(pcm_devclass); i++) {
@@ -1203,7 +800,7 @@ sound_oss_card_info(oss_card_info *si)
if (!PCM_REGISTERED(d))
continue;
- if (ncards++ != si->card)
+ if (i != si->card)
continue;
PCM_UNLOCKASSERT(d);
diff --git a/sys/dev/sound/pcm/sound.h b/sys/dev/sound/pcm/sound.h
index b48aed7c2d6e..e4a3ba41ee7f 100644
--- a/sys/dev/sound/pcm/sound.h
+++ b/sys/dev/sound/pcm/sound.h
@@ -88,7 +88,6 @@ struct snd_mixer;
#include <dev/sound/pcm/feeder.h>
#include <dev/sound/pcm/mixer.h>
#include <dev/sound/pcm/dsp.h>
-#include <dev/sound/unit.h>
#define PCM_SOFTC_SIZE (sizeof(struct snddev_info))
@@ -101,24 +100,6 @@ struct snd_mixer;
#define SOUND_MAXVER SOUND_MODVER
/*
- * We're abusing the fact that MAXMINOR still have enough room
- * for our bit twiddling and nobody ever need 512 unique soundcards,
- * 32 unique device types and 1024 unique cloneable devices for the
- * next 100 years...
- */
-
-#define PCMMAXUNIT (snd_max_u())
-#define PCMMAXDEV (snd_max_d())
-#define PCMMAXCHAN (snd_max_c())
-
-#define PCMUNIT(x) (snd_unit2u(dev2unit(x)))
-#define PCMDEV(x) (snd_unit2d(dev2unit(x)))
-#define PCMCHAN(x) (snd_unit2c(dev2unit(x)))
-
-/* XXX unit2minor compat */
-#define PCMMINOR(x) (x)
-
-/*
* By design, limit possible channels for each direction.
*/
#define SND_MAXHWCHAN 256
@@ -175,6 +156,9 @@ struct snd_mixer;
#define PCM_DETACHING(x) ((x)->flags & SD_F_DETACHING)
+#define PCM_CHANCOUNT(d) \
+ (d->playcount + d->pvchancount + d->reccount + d->rvchancount)
+
/* many variables should be reduced to a range. Here define a macro */
#define RANGE(var, low, high) (var) = \
(((var)<(low))? (low) : ((var)>(high))? (high) : (var))
@@ -244,45 +228,17 @@ struct snd_mixer;
#define AFMT_NE (AFMT_SIGNED_NE | AFMT_U8_NE | AFMT_U16_NE | \
AFMT_U24_NE | AFMT_U32_NE)
-/*
- * Minor numbers for the sound driver.
- *
- * Unfortunately Creative called the codec chip of SB as a DSP. For this
- * reason the /dev/dsp is reserved for digitized audio use. There is a
- * device for true DSP processors but it will be called something else.
- * In v3.0 it's /dev/sndproc but this could be a temporary solution.
- */
-
-#define SND_DEV_CTL 0 /* Control port /dev/mixer */
-#define SND_DEV_SEQ 1 /* Sequencer /dev/sequencer */
-#define SND_DEV_MIDIN 2 /* Raw midi access */
-#define SND_DEV_DSP 3 /* Digitized voice /dev/dsp */
-#define SND_DEV_AUDIO 4 /* Sparc compatible /dev/audio */
-#define SND_DEV_DSP16 5 /* Like /dev/dsp but 16 bits/sample */
-#define SND_DEV_STATUS 6 /* /dev/sndstat */
- /* #7 not in use now. */
-#define SND_DEV_SEQ2 8 /* /dev/sequencer, level 2 interface */
-#define SND_DEV_SNDPROC 9 /* /dev/sndproc for programmable devices */
-#define SND_DEV_PSS SND_DEV_SNDPROC /* ? */
-#define SND_DEV_NORESET 10
-
-#define SND_DEV_DSPHW_PLAY 11 /* specific playback channel */
-#define SND_DEV_DSPHW_VPLAY 12 /* specific virtual playback channel */
-#define SND_DEV_DSPHW_REC 13 /* specific record channel */
-#define SND_DEV_DSPHW_VREC 14 /* specific virtual record channel */
-
-#define SND_DEV_DSPHW_CD 15 /* s16le/stereo 44100Hz CD */
-
-/*
- * OSSv4 compatible device. For now, it serve no purpose and
- * the cloning itself will forward the request to ordinary /dev/dsp
- * instead.
- */
-#define SND_DEV_DSP_MMAP 16 /* /dev/dsp_mmap */
-#define SND_DEV_DSP_AC3 17 /* /dev/dsp_ac3 */
-#define SND_DEV_DSP_MULTICH 18 /* /dev/dsp_multich */
-#define SND_DEV_DSP_SPDIFOUT 19 /* /dev/dsp_spdifout */
-#define SND_DEV_DSP_SPDIFIN 20 /* /dev/dsp_spdifin */
+enum {
+ SND_DEV_CTL = 0, /* Control port /dev/mixer */
+ SND_DEV_SEQ, /* Sequencer /dev/sequencer */
+ SND_DEV_MIDIN, /* Raw midi access */
+ SND_DEV_DSP, /* Digitized voice /dev/dsp */
+ SND_DEV_STATUS, /* /dev/sndstat */
+ SND_DEV_DSPHW_PLAY, /* specific playback channel */
+ SND_DEV_DSPHW_VPLAY, /* specific virtual playback channel */
+ SND_DEV_DSPHW_REC, /* specific record channel */
+ SND_DEV_DSPHW_VREC, /* specific virtual record channel */
+};
#define DSP_DEFAULT_SPEED 8000
@@ -291,7 +247,6 @@ struct snd_mixer;
extern int pcm_veto_load;
extern int snd_unit;
-extern int snd_maxautovchans;
extern int snd_verbose;
extern devclass_t pcm_devclass;
extern struct unrhdr *pcmsg_unrhdr;
@@ -309,15 +264,10 @@ extern struct unrhdr *pcmsg_unrhdr;
SYSCTL_DECL(_hw_snd);
-int pcm_setvchans(struct snddev_info *d, int direction, int newcnt, int num);
int pcm_chnalloc(struct snddev_info *d, struct pcm_channel **ch, int direction,
- pid_t pid, char *comm, int devunit);
-int pcm_chnrelease(struct pcm_channel *c);
-int pcm_chnref(struct pcm_channel *c, int ref);
+ pid_t pid, char *comm);
-struct pcm_channel *pcm_chn_create(struct snddev_info *d, struct pcm_channel *parent, kobj_class_t cls, int dir, int num, void *devinfo);
-int pcm_chn_destroy(struct pcm_channel *ch);
-int pcm_chn_add(struct snddev_info *d, struct pcm_channel *ch);
+void pcm_chn_add(struct snddev_info *d, struct pcm_channel *ch);
int pcm_chn_remove(struct snddev_info *d, struct pcm_channel *ch);
int pcm_addchan(device_t dev, int dir, kobj_class_t cls, void *devinfo);
@@ -341,13 +291,21 @@ void snd_mtxassert(void *m);
int sndstat_register(device_t dev, char *str);
int sndstat_unregister(device_t dev);
-/* usage of flags in device config entry (config file) */
-#define DV_F_DRQ_MASK 0x00000007 /* mask for secondary drq */
-#define DV_F_DUAL_DMA 0x00000010 /* set to use secondary dma channel */
+/* These are the function codes assigned to the children of sound cards. */
+enum {
+ SCF_PCM,
+ SCF_MIDI,
+ SCF_SYNTH,
+};
-/* ought to be made obsolete but still used by mss */
-#define DV_F_DEV_MASK 0x0000ff00 /* force device type/class */
-#define DV_F_DEV_SHIFT 8 /* force device type/class */
+/*
+ * This is the device information struct, used by a bridge device to pass the
+ * device function code to the children.
+ */
+struct sndcard_func {
+ int func; /* The function code. */
+ void *varinfo; /* Bridge-specific information. */
+};
/*
* this is rather kludgey- we need to duplicate these struct def'ns from sound.c
@@ -367,7 +325,7 @@ struct snddev_info {
} opened;
} pcm;
} channels;
- unsigned devcount, playcount, reccount, pvchancount, rvchancount ;
+ unsigned playcount, reccount, pvchancount, rvchancount;
unsigned flags;
unsigned int bufsz;
void *devinfo;
diff --git a/sys/dev/sound/pcm/vchan.c b/sys/dev/sound/pcm/vchan.c
index d10c3ff4aabb..528c6fa62621 100644
--- a/sys/dev/sound/pcm/vchan.c
+++ b/sys/dev/sound/pcm/vchan.c
@@ -4,6 +4,10 @@
* Copyright (c) 2006-2009 Ariff Abdullah <ariff@FreeBSD.org>
* Copyright (c) 2001 Cameron Grant <cg@FreeBSD.org>
* All rights reserved.
+ * Copyright (c) 2024 The FreeBSD Foundation
+ *
+ * Portions of this software were developed by Christos Margiolis
+ * <christos@FreeBSD.org> 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
@@ -57,6 +61,8 @@ struct vchan_info {
int trigger;
};
+int snd_maxautovchans = 16;
+
static void *
vchan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b,
struct pcm_channel *c, int dir)
@@ -249,7 +255,7 @@ static kobj_method_t vchan_methods[] = {
CHANNEL_DECLARE(vchan);
static void
-pcm_getparentchannel(struct snddev_info *d,
+vchan_getparentchannel(struct snddev_info *d,
struct pcm_channel **wrch, struct pcm_channel **rdch)
{
struct pcm_channel **ch, *wch, *rch, *c;
@@ -337,7 +343,7 @@ sysctl_dev_pcm_vchans(SYSCTL_HANDLER_ARGS)
cnt = 0;
if (cnt > SND_MAXVCHANS)
cnt = SND_MAXVCHANS;
- err = pcm_setvchans(d, direction, cnt, -1);
+ err = vchan_setnew(d, direction, cnt);
}
PCM_RELEASE_QUICK(d);
@@ -378,9 +384,9 @@ sysctl_dev_pcm_vchanmode(SYSCTL_HANDLER_ARGS)
PCM_UNLOCK(d);
if (direction == PCMDIR_PLAY)
- pcm_getparentchannel(d, &c, NULL);
+ vchan_getparentchannel(d, &c, NULL);
else
- pcm_getparentchannel(d, NULL, &c);
+ vchan_getparentchannel(d, NULL, &c);
if (c == NULL) {
PCM_RELEASE_QUICK(d);
@@ -480,9 +486,9 @@ sysctl_dev_pcm_vchanrate(SYSCTL_HANDLER_ARGS)
PCM_UNLOCK(d);
if (direction == PCMDIR_PLAY)
- pcm_getparentchannel(d, &c, NULL);
+ vchan_getparentchannel(d, &c, NULL);
else
- pcm_getparentchannel(d, NULL, &c);
+ vchan_getparentchannel(d, NULL, &c);
if (c == NULL) {
PCM_RELEASE_QUICK(d);
@@ -589,9 +595,9 @@ sysctl_dev_pcm_vchanformat(SYSCTL_HANDLER_ARGS)
PCM_UNLOCK(d);
if (direction == PCMDIR_PLAY)
- pcm_getparentchannel(d, &c, NULL);
+ vchan_getparentchannel(d, &c, NULL);
else
- pcm_getparentchannel(d, NULL, &c);
+ vchan_getparentchannel(d, NULL, &c);
if (c == NULL) {
PCM_RELEASE_QUICK(d);
@@ -662,7 +668,7 @@ sysctl_dev_pcm_vchanformat(SYSCTL_HANDLER_ARGS)
"play.vchanrate" : "rec.vchanrate"
int
-vchan_create(struct pcm_channel *parent, int num)
+vchan_create(struct pcm_channel *parent)
{
struct snddev_info *d;
struct pcm_channel *ch;
@@ -698,7 +704,7 @@ vchan_create(struct pcm_channel *parent, int num)
}
/* create a new playback channel */
- ch = pcm_chn_create(d, parent, &vchan_class, direction, num, parent);
+ ch = chn_init(d, parent, &vchan_class, direction, parent);
if (ch == NULL) {
PCM_UNLOCK(d);
CHN_LOCK(parent);
@@ -706,13 +712,8 @@ vchan_create(struct pcm_channel *parent, int num)
}
/* add us to our grandparent's channel list */
- ret = pcm_chn_add(d, ch);
+ pcm_chn_add(d, ch);
PCM_UNLOCK(d);
- if (ret != 0) {
- pcm_chn_destroy(ch);
- CHN_LOCK(parent);
- return (ret);
- }
CHN_LOCK(parent);
/*
@@ -727,6 +728,7 @@ vchan_create(struct pcm_channel *parent, int num)
parent->flags |= CHN_F_HAS_VCHAN;
+ ret = 0;
parent_caps = chn_getcaps(parent);
if (parent_caps == NULL)
ret = EINVAL;
@@ -837,7 +839,7 @@ vchan_create(struct pcm_channel *parent, int num)
PCM_LOCK(d);
if (pcm_chn_remove(d, ch) == 0) {
PCM_UNLOCK(d);
- pcm_chn_destroy(ch);
+ chn_kill(ch);
} else
PCM_UNLOCK(d);
CHN_LOCK(parent);
@@ -890,7 +892,7 @@ vchan_destroy(struct pcm_channel *c)
/* destroy ourselves */
if (ret == 0)
- ret = pcm_chn_destroy(c);
+ chn_kill(c);
CHN_LOCK(parent);
@@ -923,7 +925,7 @@ vchan_sync(struct pcm_channel *c)
if (snd_passthrough_verbose != 0) {
char *devname, buf[CHN_NAMELEN];
- devname = dsp_unit2name(buf, sizeof(buf), c->unit);
+ devname = dsp_unit2name(buf, sizeof(buf), c);
device_printf(c->dev,
"%s(%s/%s) %s() -> re-sync err=%d\n",
__func__, (devname != NULL) ? devname : "dspX", c->comm,
@@ -934,6 +936,172 @@ vchan_sync(struct pcm_channel *c)
return (ret);
}
+int
+vchan_setnew(struct snddev_info *d, int direction, int newcnt)
+{
+ struct pcm_channel *c, *ch, *nch;
+ struct pcmchan_caps *caps;
+ int i, err, vcnt;
+
+ PCM_BUSYASSERT(d);
+
+ if ((direction == PCMDIR_PLAY && d->playcount < 1) ||
+ (direction == PCMDIR_REC && d->reccount < 1))
+ return (ENODEV);
+
+ if (!(d->flags & SD_F_AUTOVCHAN))
+ return (EINVAL);
+
+ if (newcnt < 0 || newcnt > SND_MAXVCHANS)
+ return (E2BIG);
+
+ if (direction == PCMDIR_PLAY)
+ vcnt = d->pvchancount;
+ else if (direction == PCMDIR_REC)
+ vcnt = d->rvchancount;
+ else
+ return (EINVAL);
+
+ if (newcnt > vcnt) {
+ KASSERT((newcnt - 1) == vcnt,
+ ("bogus vchan_create() request newcnt=%d vcnt=%d",
+ newcnt, vcnt));
+ /* add new vchans - find a parent channel first */
+ ch = NULL;
+ CHN_FOREACH(c, d, channels.pcm) {
+ CHN_LOCK(c);
+ if (c->direction == direction &&
+ ((c->flags & CHN_F_HAS_VCHAN) || (vcnt == 0 &&
+ c->refcount < 1 &&
+ !(c->flags & (CHN_F_BUSY | CHN_F_VIRTUAL))))) {
+ /*
+ * Reuse hw channel with vchans already
+ * created.
+ */
+ if (c->flags & CHN_F_HAS_VCHAN) {
+ ch = c;
+ break;
+ }
+ /*
+ * No vchans ever created, look for
+ * channels with supported formats.
+ */
+ caps = chn_getcaps(c);
+ if (caps == NULL) {
+ CHN_UNLOCK(c);
+ continue;
+ }
+ for (i = 0; caps->fmtlist[i] != 0; i++) {
+ if (caps->fmtlist[i] & AFMT_CONVERTIBLE)
+ break;
+ }
+ if (caps->fmtlist[i] != 0) {
+ ch = c;
+ break;
+ }
+ }
+ CHN_UNLOCK(c);
+ }
+ if (ch == NULL)
+ return (EBUSY);
+ ch->flags |= CHN_F_BUSY;
+ err = 0;
+ while (err == 0 && newcnt > vcnt) {
+ err = vchan_create(ch);
+ if (err == 0)
+ vcnt++;
+ else if (err == E2BIG && newcnt > vcnt)
+ device_printf(d->dev,
+ "%s: err=%d Maximum channel reached.\n",
+ __func__, err);
+ }
+ if (vcnt == 0)
+ ch->flags &= ~CHN_F_BUSY;
+ CHN_UNLOCK(ch);
+ if (err != 0)
+ return (err);
+ } else if (newcnt < vcnt) {
+ CHN_FOREACH(c, d, channels.pcm) {
+ CHN_LOCK(c);
+ if (c->direction != direction ||
+ CHN_EMPTY(c, children) ||
+ !(c->flags & CHN_F_HAS_VCHAN)) {
+ CHN_UNLOCK(c);
+ continue;
+ }
+ CHN_FOREACH_SAFE(ch, c, nch, children) {
+ CHN_LOCK(ch);
+ if (vcnt == 1 && c->refcount > 0) {
+ CHN_UNLOCK(ch);
+ break;
+ }
+ if (!(ch->flags & CHN_F_BUSY) &&
+ ch->refcount < 1) {
+ err = vchan_destroy(ch);
+ if (err == 0)
+ vcnt--;
+ } else
+ CHN_UNLOCK(ch);
+ if (vcnt == newcnt)
+ break;
+ }
+ CHN_UNLOCK(c);
+ break;
+ }
+ }
+
+ return (0);
+}
+
+void
+vchan_setmaxauto(struct snddev_info *d, int num)
+{
+ PCM_BUSYASSERT(d);
+
+ if (num < 0)
+ return;
+
+ if (num >= 0 && d->pvchancount > num)
+ (void)vchan_setnew(d, PCMDIR_PLAY, num);
+ else if (num > 0 && d->pvchancount == 0)
+ (void)vchan_setnew(d, PCMDIR_PLAY, 1);
+
+ if (num >= 0 && d->rvchancount > num)
+ (void)vchan_setnew(d, PCMDIR_REC, num);
+ else if (num > 0 && d->rvchancount == 0)
+ (void)vchan_setnew(d, PCMDIR_REC, 1);
+}
+
+static int
+sysctl_hw_snd_maxautovchans(SYSCTL_HANDLER_ARGS)
+{
+ struct snddev_info *d;
+ int i, v, error;
+
+ v = snd_maxautovchans;
+ error = sysctl_handle_int(oidp, &v, 0, req);
+ if (error == 0 && req->newptr != NULL) {
+ if (v < 0)
+ v = 0;
+ if (v > SND_MAXVCHANS)
+ v = SND_MAXVCHANS;
+ snd_maxautovchans = v;
+ for (i = 0; pcm_devclass != NULL &&
+ i < devclass_get_maxunit(pcm_devclass); i++) {
+ d = devclass_get_softc(pcm_devclass, i);
+ if (!PCM_REGISTERED(d))
+ continue;
+ PCM_ACQUIRE_QUICK(d);
+ vchan_setmaxauto(d, v);
+ PCM_RELEASE_QUICK(d);
+ }
+ }
+ return (error);
+}
+SYSCTL_PROC(_hw_snd, OID_AUTO, maxautovchans,
+ CTLTYPE_INT | CTLFLAG_RWTUN | CTLFLAG_NEEDGIANT, 0, sizeof(int),
+ sysctl_hw_snd_maxautovchans, "I", "maximum virtual channel");
+
void
vchan_initsys(device_t dev)
{
diff --git a/sys/dev/sound/pcm/vchan.h b/sys/dev/sound/pcm/vchan.h
index e2dcc9761261..1f0fa058cf71 100644
--- a/sys/dev/sound/pcm/vchan.h
+++ b/sys/dev/sound/pcm/vchan.h
@@ -30,7 +30,9 @@
#ifndef _SND_VCHAN_H_
#define _SND_VCHAN_H_
-int vchan_create(struct pcm_channel *, int);
+extern int snd_maxautovchans;
+
+int vchan_create(struct pcm_channel *);
int vchan_destroy(struct pcm_channel *);
#ifdef SND_DEBUG
@@ -45,6 +47,9 @@ int vchan_sync(struct pcm_channel *);
sndbuf_getfmt((c)->bufhard) != (c)->parentchannel->format || \
sndbuf_getspd((c)->bufhard) != (c)->parentchannel->speed))
+int vchan_setnew(struct snddev_info *, int, int);
+void vchan_setmaxauto(struct snddev_info *, int);
+
void vchan_initsys(device_t);
/*
diff --git a/sys/dev/sound/unit.c b/sys/dev/sound/unit.c
deleted file mode 100644
index 28ffbde1f7ec..000000000000
--- a/sys/dev/sound/unit.c
+++ /dev/null
@@ -1,188 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause
- *
- * Copyright (c) 2007 Ariff Abdullah <ariff@FreeBSD.org>
- * 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/param.h>
-#include <sys/systm.h>
-
-#ifdef HAVE_KERNEL_OPTION_HEADERS
-#include "opt_snd.h"
-#endif
-
-#include <dev/sound/unit.h>
-
-/*
- * Unit magic allocator for sound driver.
- *
- * 'u' = Unit of attached soundcards
- * 'd' = Device type
- * 'c' = Channel number
- *
- * eg: dsp0.p1 - u=0, d=p, c=1
- * dsp1.vp0 - u=1, d=vp, c=0
- *
- * Maximum unit of soundcards can be tuned through "hw.snd.maxunit", which is
- * between SND_UNIT_UMIN (16) and SND_UNIT_UMAX (2048). By design, the maximum
- * allowable allocated channel is 256.
- */
-
-/* Default width */
-static int snd_u_shift = 9; /* 0 - 0x1ff : 512 distinct soundcards */
-static int snd_d_shift = 5; /* 0 - 0x1f : 32 distinct device types */
-static int snd_c_shift = 10; /* 0 - 0x3ff : 1024 distinct channels
- (256 limit "by design") */
-
-static int snd_unit_initialized = 0;
-
-#ifdef SND_DIAGNOSTIC
-#define SND_UNIT_ASSERT() do { \
- if (snd_unit_initialized == 0) \
- panic("%s(): Uninitialized sound unit!", __func__); \
-} while (0)
-#else
-#define SND_UNIT_ASSERT() KASSERT(snd_unit_initialized != 0, \
- ("%s(): Uninitialized sound unit!", \
- __func__))
-#endif
-
-#define MKMASK(x) ((1 << snd_##x##_shift) - 1)
-
-int
-snd_max_u(void)
-{
- SND_UNIT_ASSERT();
-
- return (MKMASK(u));
-}
-
-int
-snd_max_d(void)
-{
- SND_UNIT_ASSERT();
-
- return (MKMASK(d));
-}
-
-int
-snd_max_c(void)
-{
- SND_UNIT_ASSERT();
-
- return (MKMASK(c));
-}
-
-int
-snd_unit2u(int unit)
-{
- SND_UNIT_ASSERT();
-
- return ((unit >> (snd_c_shift + snd_d_shift)) & MKMASK(u));
-}
-
-int
-snd_unit2d(int unit)
-{
- SND_UNIT_ASSERT();
-
- return ((unit >> snd_c_shift) & MKMASK(d));
-}
-
-int
-snd_unit2c(int unit)
-{
- SND_UNIT_ASSERT();
-
- return (unit & MKMASK(c));
-}
-
-int
-snd_u2unit(int u)
-{
- SND_UNIT_ASSERT();
-
- return ((u & MKMASK(u)) << (snd_c_shift + snd_d_shift));
-}
-
-int
-snd_d2unit(int d)
-{
- SND_UNIT_ASSERT();
-
- return ((d & MKMASK(d)) << snd_c_shift);
-}
-
-int
-snd_c2unit(int c)
-{
- SND_UNIT_ASSERT();
-
- return (c & MKMASK(c));
-}
-
-int
-snd_mkunit(int u, int d, int c)
-{
- SND_UNIT_ASSERT();
-
- return ((c & MKMASK(c)) | ((d & MKMASK(d)) << snd_c_shift) |
- ((u & MKMASK(u)) << (snd_c_shift + snd_d_shift)));
-}
-
-/*
- * This *must* be called first before any of the functions above!!!
- */
-void
-snd_unit_init(void)
-{
- int i;
-
- if (snd_unit_initialized != 0)
- return;
-
- snd_unit_initialized = 1;
-
- if (getenv_int("hw.snd.maxunit", &i) != 0) {
- if (i < SND_UNIT_UMIN)
- i = SND_UNIT_UMIN;
- else if (i > SND_UNIT_UMAX)
- i = SND_UNIT_UMAX;
- else
- i = roundup2(i, 2);
-
- for (snd_u_shift = 0; (i >> (snd_u_shift + 1)) != 0;
- snd_u_shift++)
- ;
-
- /* Make room for channels to fit within 24bit MAXMINOR limit. */
- snd_c_shift = 24 - snd_u_shift - snd_d_shift;
- }
-
- if (bootverbose != 0)
- printf("%s() u=0x%08x [%d] d=0x%08x [%d] c=0x%08x [%d]\n",
- __func__, SND_U_MASK, snd_max_u() + 1,
- SND_D_MASK, snd_max_d() + 1, SND_C_MASK, snd_max_c() + 1);
-}
diff --git a/sys/dev/sound/unit.h b/sys/dev/sound/unit.h
deleted file mode 100644
index 9ddd68a2fe04..000000000000
--- a/sys/dev/sound/unit.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause
- *
- * Copyright (c) 2007 Ariff Abdullah <ariff@FreeBSD.org>
- * 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.
- */
-
-#ifndef _SND_UNIT_H_
-#define _SND_UNIT_H_
-
-#define SND_UNIT_UMIN 16
-#define SND_UNIT_UMAX 2048
-
-int snd_max_u(void);
-int snd_max_d(void);
-int snd_max_c(void);
-int snd_unit2u(int);
-int snd_unit2d(int);
-int snd_unit2c(int);
-int snd_u2unit(int);
-int snd_d2unit(int);
-int snd_c2unit(int);
-int snd_mkunit(int, int, int);
-
-void snd_unit_init(void);
-
-#define SND_U_MASK (snd_u2unit(snd_max_u()))
-#define SND_D_MASK (snd_d2unit(snd_max_d()))
-#define SND_C_MASK (snd_c2unit(snd_max_c()))
-
-#endif /* !_SND_UNIT_H_ */
diff --git a/sys/dev/sound/usb/uaudio.c b/sys/dev/sound/usb/uaudio.c
index 2351c2522021..d47eb86ed271 100644
--- a/sys/dev/sound/usb/uaudio.c
+++ b/sys/dev/sound/usb/uaudio.c
@@ -90,7 +90,6 @@
#include <dev/sound/pcm/sound.h>
#include <dev/sound/usb/uaudioreg.h>
#include <dev/sound/usb/uaudio.h>
-#include <dev/sound/chip.h>
#include "feeder_if.h"
static int uaudio_default_rate = 0; /* use rate list */
diff --git a/sys/dev/sound/usb/uaudio_pcm.c b/sys/dev/sound/usb/uaudio_pcm.c
index 9b17cb232907..0b3da9b20440 100644
--- a/sys/dev/sound/usb/uaudio_pcm.c
+++ b/sys/dev/sound/usb/uaudio_pcm.c
@@ -32,7 +32,6 @@
#endif
#include <dev/sound/pcm/sound.h>
-#include <dev/sound/chip.h>
#include <dev/sound/usb/uaudio.h>
#include "mixer_if.h"
diff --git a/sys/dev/sound/version.h b/sys/dev/sound/version.h
deleted file mode 100644
index b816bbf964e8..000000000000
--- a/sys/dev/sound/version.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause
- *
- * Copyright (c) 2007 Ariff Abdullah <ariff@FreeBSD.org>
- * 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.
- */
-
-#ifndef _SND_VERSION_H_
-#define _SND_VERSION_H_
-
-/*
- * FreeBSD sound driver internal versioning, nothing to do
- * with OSS whatsoever. Dear future maintainer, please revisit
- * this _before_ Jan 1 2148
- *
- * Last 2 decimal places reserved for daily versioning, starting
- * with 0.
- */
-#define SND_DRV_VERSION 2009061500
-
-#endif /* !_SND_VERSION_H_ */
diff --git a/sys/dev/usb/net/if_smsc.c b/sys/dev/usb/net/if_smsc.c
index a59501b6bbff..58809de4ad3a 100644
--- a/sys/dev/usb/net/if_smsc.c
+++ b/sys/dev/usb/net/if_smsc.c
@@ -28,7 +28,7 @@
#include <sys/cdefs.h>
/*
- * SMSC LAN9xxx devices (http://www.smsc.com/)
+ * Microchip LAN9xxx devices (https://www.microchip.com/en-us/product/lan9500a)
*
* The LAN9500 & LAN9500A devices are stand-alone USB to Ethernet chips that
* support USB 2.0 and 10/100 Mbps Ethernet.
@@ -38,7 +38,7 @@
* supports the hub part.
*
* This driver is closely modelled on the Linux driver written and copyrighted
- * by SMSC.
+ * by SMSC (later acquired by Microchip).
*
*
*
diff --git a/sys/dev/wg/if_wg.c b/sys/dev/wg/if_wg.c
index 2c867956912a..30429c3725cd 100644
--- a/sys/dev/wg/if_wg.c
+++ b/sys/dev/wg/if_wg.c
@@ -2194,7 +2194,8 @@ wg_output(if_t ifp, struct mbuf *m, const struct sockaddr *dst, struct route *ro
int ret;
struct mbuf *defragged;
- if (dst->sa_family == AF_UNSPEC)
+ /* BPF writes need to be handled specially. */
+ if (dst->sa_family == AF_UNSPEC || dst->sa_family == pseudo_AF_HDRCMPLT)
memcpy(&af, dst->sa_data, sizeof(af));
else
af = dst->sa_family;
diff --git a/sys/fs/nfs/nfs_var.h b/sys/fs/nfs/nfs_var.h
index 578fb3ce1340..950e0c097457 100644
--- a/sys/fs/nfs/nfs_var.h
+++ b/sys/fs/nfs/nfs_var.h
@@ -713,7 +713,7 @@ int nfsvno_rmdirsub(struct nameidata *, int, struct ucred *, NFSPROC_T *,
struct nfsexstuff *);
int nfsvno_rename(struct nameidata *, struct nameidata *, u_int32_t,
u_int32_t, struct ucred *, NFSPROC_T *);
-int nfsvno_link(struct nameidata *, vnode_t, struct ucred *,
+int nfsvno_link(struct nameidata *, vnode_t, nfsquad_t, struct ucred *,
NFSPROC_T *, struct nfsexstuff *);
int nfsvno_fsync(vnode_t, u_int64_t, int, struct ucred *, NFSPROC_T *);
int nfsvno_statfs(vnode_t, struct statfs *);
diff --git a/sys/fs/nfsserver/nfs_nfsdport.c b/sys/fs/nfsserver/nfs_nfsdport.c
index f8c2ddfd2a59..f4679309657b 100644
--- a/sys/fs/nfsserver/nfs_nfsdport.c
+++ b/sys/fs/nfsserver/nfs_nfsdport.c
@@ -1656,8 +1656,8 @@ out1:
* Link vnode op.
*/
int
-nfsvno_link(struct nameidata *ndp, struct vnode *vp, struct ucred *cred,
- struct thread *p, struct nfsexstuff *exp)
+nfsvno_link(struct nameidata *ndp, struct vnode *vp, nfsquad_t clientid,
+ struct ucred *cred, struct thread *p, struct nfsexstuff *exp)
{
struct vnode *xp;
int error = 0;
@@ -1672,9 +1672,11 @@ nfsvno_link(struct nameidata *ndp, struct vnode *vp, struct ucred *cred,
}
if (!error) {
NFSVOPLOCK(vp, LK_EXCLUSIVE | LK_RETRY);
- if (!VN_IS_DOOMED(vp))
- error = VOP_LINK(ndp->ni_dvp, vp, &ndp->ni_cnd);
- else
+ if (!VN_IS_DOOMED(vp)) {
+ error = nfsrv_checkremove(vp, 0, NULL, clientid, p);
+ if (error == 0)
+ error = VOP_LINK(ndp->ni_dvp, vp, &ndp->ni_cnd);
+ } else
error = EPERM;
if (ndp->ni_dvp == vp) {
vrele(ndp->ni_dvp);
diff --git a/sys/fs/nfsserver/nfs_nfsdserv.c b/sys/fs/nfsserver/nfs_nfsdserv.c
index 8141ee6cbdb6..0c8bda6dc6a6 100644
--- a/sys/fs/nfsserver/nfs_nfsdserv.c
+++ b/sys/fs/nfsserver/nfs_nfsdserv.c
@@ -1797,6 +1797,7 @@ nfsrvd_link(struct nfsrv_descript *nd, int isdgram,
char *bufp;
u_long *hashp;
struct thread *p = curthread;
+ nfsquad_t clientid;
if (nd->nd_repstat) {
nfsrv_postopattr(nd, getret, &at);
@@ -1858,8 +1859,14 @@ nfsrvd_link(struct nfsrv_descript *nd, int isdgram,
NULL);
}
}
- if (!nd->nd_repstat)
- nd->nd_repstat = nfsvno_link(&named, vp, nd->nd_cred, p, exp);
+ if (!nd->nd_repstat) {
+ clientid.qval = 0;
+ if ((nd->nd_flag & (ND_IMPLIEDCLID | ND_NFSV41)) ==
+ (ND_IMPLIEDCLID | ND_NFSV41))
+ clientid.qval = nd->nd_clientid.qval;
+ nd->nd_repstat = nfsvno_link(&named, vp, clientid, nd->nd_cred,
+ p, exp);
+ }
if (nd->nd_flag & ND_NFSV3)
getret = nfsvno_getattr(vp, &at, nd, p, 0, NULL);
if (dirp) {
diff --git a/sys/geom/eli/g_eli.c b/sys/geom/eli/g_eli.c
index 16b38e628e35..400734c10596 100644
--- a/sys/geom/eli/g_eli.c
+++ b/sys/geom/eli/g_eli.c
@@ -101,11 +101,13 @@ SYSCTL_BOOL(_kern_geom_eli, OID_AUTO, blocking_malloc, CTLFLAG_RWTUN,
static bool g_eli_unmapped_io = true;
SYSCTL_BOOL(_kern_geom_eli, OID_AUTO, unmapped_io, CTLFLAG_RDTUN,
&g_eli_unmapped_io, 0, "Enable support for unmapped I/O");
+static int g_eli_alloc_sz;
+SYSCTL_UINT(_kern_geom_eli, OID_AUTO, use_uma_bytes, CTLFLAG_RD,
+ &g_eli_alloc_sz, 0, "Use uma(9) for allocations of this size or smaller.");
static struct sx g_eli_umalock; /* Controls changes to UMA zone. */
SX_SYSINIT(g_eli_umalock, &g_eli_umalock, "GELI UMA");
static uma_zone_t g_eli_uma = NULL;
-static int g_eli_alloc_sz;
static volatile int g_eli_umaoutstanding;
static volatile int g_eli_devs;
diff --git a/sys/i386/i386/sys_machdep.c b/sys/i386/i386/sys_machdep.c
index 1634041daf2a..3a7b7c2f6c71 100644
--- a/sys/i386/i386/sys_machdep.c
+++ b/sys/i386/i386/sys_machdep.c
@@ -154,26 +154,24 @@ sysarch(struct thread *td, struct sysarch_args *uap)
* explicitly indicate whether or not the operation is safe to
* perform in capability mode.
*/
- if (IN_CAPABILITY_MODE(td)) {
- switch (uap->op) {
- case I386_GET_LDT:
- case I386_SET_LDT:
- case I386_GET_IOPERM:
- case I386_GET_FSBASE:
- case I386_SET_FSBASE:
- case I386_GET_GSBASE:
- case I386_SET_GSBASE:
- case I386_GET_XFPUSTATE:
- break;
+ switch (uap->op) {
+ case I386_GET_LDT:
+ case I386_SET_LDT:
+ case I386_GET_IOPERM:
+ case I386_GET_FSBASE:
+ case I386_SET_FSBASE:
+ case I386_GET_GSBASE:
+ case I386_SET_GSBASE:
+ case I386_GET_XFPUSTATE:
+ break;
- case I386_SET_IOPERM:
- default:
-#ifdef KTRACE
- if (KTRPOINT(td, KTR_CAPFAIL))
- ktrcapfail(CAPFAIL_SYSCALL, NULL, NULL);
-#endif
+ case I386_SET_IOPERM:
+ default:
+ if (CAP_TRACING(td))
+ ktrcapfail(CAPFAIL_SYSCALL, &uap->op);
+ if (IN_CAPABILITY_MODE(td))
return (ECAPMODE);
- }
+ break;
}
#endif
diff --git a/sys/kern/kern_boottrace.c b/sys/kern/kern_boottrace.c
index 86fee4f47fbe..1b097e7378ad 100644
--- a/sys/kern/kern_boottrace.c
+++ b/sys/kern/kern_boottrace.c
@@ -613,4 +613,4 @@ boottrace_init(void)
st.table = malloc(st.size * sizeof(struct bt_event), M_BOOTTRACE,
M_WAITOK | M_ZERO);
}
-SYSINIT(boottrace, SI_SUB_CPU, SI_ORDER_ANY, boottrace_init, 0);
+SYSINIT(boottrace, SI_SUB_CPU, SI_ORDER_ANY, boottrace_init, NULL);
diff --git a/sys/kern/kern_cpuset.c b/sys/kern/kern_cpuset.c
index 17176afa6ad3..5d9e2f2f326b 100644
--- a/sys/kern/kern_cpuset.c
+++ b/sys/kern/kern_cpuset.c
@@ -1762,22 +1762,38 @@ cpuset_setproc_update_set(struct proc *p, struct cpuset *set)
* In Capability mode, the only accesses that are permitted are to the current
* thread and process' CPU and domain sets.
*/
+static bool
+cpuset_capmode_allowed(struct thread *td, cpulevel_t level, cpuwhich_t which,
+ id_t id)
+{
+ if (level != CPU_LEVEL_WHICH)
+ return (false);
+ if (which != CPU_WHICH_TID && which != CPU_WHICH_PID &&
+ which != CPU_WHICH_TIDPID)
+ return (false);
+ if (id != -1 && which == CPU_WHICH_TIDPID &&
+ id != td->td_tid && id != td->td_proc->p_pid)
+ return (false);
+ if (id != -1 &&
+ !(which == CPU_WHICH_TID && id == td->td_tid) &&
+ !(which == CPU_WHICH_PID && id == td->td_proc->p_pid))
+ return (false);
+ return (true);
+}
+
+/*
+ * Check for capability violations and record them if ktrace(2) is active.
+ */
static int
cpuset_check_capabilities(struct thread *td, cpulevel_t level, cpuwhich_t which,
id_t id)
{
- if (IN_CAPABILITY_MODE(td)) {
- if (level != CPU_LEVEL_WHICH)
- return (ECAPMODE);
- if (which != CPU_WHICH_TID && which != CPU_WHICH_PID &&
- which != CPU_WHICH_TIDPID)
- return (ECAPMODE);
- if (id != -1 && which == CPU_WHICH_TIDPID &&
- id != td->td_tid && id != td->td_proc->p_pid)
- return (ECAPMODE);
- if (id != -1 &&
- !(which == CPU_WHICH_TID && id == td->td_tid) &&
- !(which == CPU_WHICH_PID && id == td->td_proc->p_pid))
+ if (IN_CAPABILITY_MODE(td) || CAP_TRACING(td)) {
+ if (cpuset_capmode_allowed(td, level, which, id))
+ return (0);
+ if (CAP_TRACING(td))
+ ktrcapfail(CAPFAIL_CPUSET, NULL);
+ if (IN_CAPABILITY_MODE(td))
return (ECAPMODE);
}
return (0);
diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c
index 30d82f74d725..35e9afea4625 100644
--- a/sys/kern/kern_descrip.c
+++ b/sys/kern/kern_descrip.c
@@ -877,6 +877,8 @@ revert_f_setfl:
case F_KINFO:
#ifdef CAPABILITY_MODE
+ if (CAP_TRACING(td))
+ ktrcapfail(CAPFAIL_SYSCALL, &cmd);
if (IN_CAPABILITY_MODE(td)) {
error = ECAPMODE;
break;
@@ -3054,7 +3056,7 @@ fgetvp_lookup_smr(struct nameidata *ndp, struct vnode **vpp, bool *fsearch)
ndp->ni_filecaps.fc_fcntls != CAP_FCNTL_ALL ||
ndp->ni_filecaps.fc_nioctls != -1) {
#ifdef notyet
- ndp->ni_lcf |= NI_LCF_STRICTRELATIVE;
+ ndp->ni_lcf |= NI_LCF_STRICTREL;
#else
return (EAGAIN);
#endif
@@ -3146,7 +3148,7 @@ fgetvp_lookup(struct nameidata *ndp, struct vnode **vpp)
if (!cap_rights_contains(&ndp->ni_filecaps.fc_rights, &rights) ||
ndp->ni_filecaps.fc_fcntls != CAP_FCNTL_ALL ||
ndp->ni_filecaps.fc_nioctls != -1) {
- ndp->ni_lcf |= NI_LCF_STRICTRELATIVE;
+ ndp->ni_lcf |= NI_LCF_STRICTREL;
ndp->ni_resflags |= NIRES_STRICTREL;
}
#endif
diff --git a/sys/kern/kern_devctl.c b/sys/kern/kern_devctl.c
index 12d4f9ebfc4d..0dd05a49c9ad 100644
--- a/sys/kern/kern_devctl.c
+++ b/sys/kern/kern_devctl.c
@@ -89,6 +89,9 @@ static int sysctl_devctl_queue(SYSCTL_HANDLER_ARGS);
static int devctl_queue_length = DEVCTL_DEFAULT_QUEUE_LEN;
SYSCTL_PROC(_hw_bus, OID_AUTO, devctl_queue, CTLTYPE_INT | CTLFLAG_RWTUN |
CTLFLAG_MPSAFE, NULL, 0, sysctl_devctl_queue, "I", "devctl queue length");
+static bool nomatch_enabled = false;
+SYSCTL_BOOL(_hw_bus, OID_AUTO, devctl_nomatch_enabled, CTLFLAG_RWTUN,
+ &nomatch_enabled, 0, "enable nomatch events");
static void devctl_attach_handler(void *arg __unused, device_t dev);
static void devctl_detach_handler(void *arg __unused, device_t dev,
@@ -208,7 +211,8 @@ devctl_detach_handler(void *arg __unused, device_t dev, enum evhdev_detach state
static void
devctl_nomatch_handler(void *arg __unused, device_t dev)
{
- devaddq("?", "", dev);
+ if (nomatch_enabled)
+ devaddq("?", "", dev);
}
static int
diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c
index ae2b624c2659..6727872b5b10 100644
--- a/sys/kern/kern_exec.c
+++ b/sys/kern/kern_exec.c
@@ -454,6 +454,8 @@ do_execve(struct thread *td, struct image_args *args, struct mac *mac_p,
interpret:
if (args->fname != NULL) {
#ifdef CAPABILITY_MODE
+ if (CAP_TRACING(td))
+ ktrcapfail(CAPFAIL_NAMEI, args->fname);
/*
* While capability mode can't reach this point via direct
* path arguments to execve(), we also don't allow
diff --git a/sys/kern/kern_ktrace.c b/sys/kern/kern_ktrace.c
index 4c1936edc301..555762185411 100644
--- a/sys/kern/kern_ktrace.c
+++ b/sys/kern/kern_ktrace.c
@@ -925,14 +925,17 @@ ktrstructarray(const char *name, enum uio_seg seg, const void *data,
}
void
-ktrcapfail(enum ktr_cap_fail_type type, const cap_rights_t *needed,
- const cap_rights_t *held)
+ktrcapfail(enum ktr_cap_violation type, const void *data)
{
struct thread *td = curthread;
struct ktr_request *req;
struct ktr_cap_fail *kcf;
+ union ktr_cap_data *kcd;
- if (__predict_false(curthread->td_pflags & TDP_INKTRACE))
+ if (__predict_false(td->td_pflags & TDP_INKTRACE))
+ return;
+ if (type != CAPFAIL_SYSCALL &&
+ (td->td_sa.callp->sy_flags & SYF_CAPENABLED) == 0)
return;
req = ktr_getrequest(KTR_CAPFAIL);
@@ -940,14 +943,32 @@ ktrcapfail(enum ktr_cap_fail_type type, const cap_rights_t *needed,
return;
kcf = &req->ktr_data.ktr_cap_fail;
kcf->cap_type = type;
- if (needed != NULL)
- kcf->cap_needed = *needed;
- else
- cap_rights_init(&kcf->cap_needed);
- if (held != NULL)
- kcf->cap_held = *held;
- else
- cap_rights_init(&kcf->cap_held);
+ kcf->cap_code = td->td_sa.code;
+ kcf->cap_svflags = td->td_proc->p_sysent->sv_flags;
+ if (data != NULL) {
+ kcd = &kcf->cap_data;
+ switch (type) {
+ case CAPFAIL_NOTCAPABLE:
+ case CAPFAIL_INCREASE:
+ kcd->cap_needed = *(const cap_rights_t *)data;
+ kcd->cap_held = *((const cap_rights_t *)data + 1);
+ break;
+ case CAPFAIL_SYSCALL:
+ case CAPFAIL_SIGNAL:
+ case CAPFAIL_PROTO:
+ kcd->cap_int = *(const int *)data;
+ break;
+ case CAPFAIL_SOCKADDR:
+ kcd->cap_sockaddr = *(const struct sockaddr *)data;
+ break;
+ case CAPFAIL_NAMEI:
+ strlcpy(kcd->cap_path, data, MAXPATHLEN);
+ break;
+ case CAPFAIL_CPUSET:
+ default:
+ break;
+ }
+ }
ktr_enqueuerequest(td, req);
ktrace_exit(td);
}
diff --git a/sys/kern/kern_procctl.c b/sys/kern/kern_procctl.c
index 9e860e7c80a5..23b3403fec4f 100644
--- a/sys/kern/kern_procctl.c
+++ b/sys/kern/kern_procctl.c
@@ -28,6 +28,8 @@
*/
#include <sys/cdefs.h>
+#include "opt_ktrace.h"
+
#include <sys/param.h>
#include <sys/_unrhdr.h>
#include <sys/systm.h>
@@ -543,6 +545,8 @@ reap_kill(struct thread *td, struct proc *p, void *data)
rk = data;
sx_assert(&proctree_lock, SX_LOCKED);
+ if (CAP_TRACING(td))
+ ktrcapfail(CAPFAIL_SIGNAL, &rk->rk_sig);
if (IN_CAPABILITY_MODE(td))
return (ECAPMODE);
if (rk->rk_sig <= 0 || rk->rk_sig > _SIG_MAXSIG ||
diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c
index 2f2ec7edfb12..802231767762 100644
--- a/sys/kern/kern_sig.c
+++ b/sys/kern/kern_sig.c
@@ -1907,8 +1907,12 @@ kern_kill(struct thread *td, pid_t pid, int signum)
* The main rationale behind this is that abort(3) is implemented as
* kill(getpid(), SIGABRT).
*/
- if (IN_CAPABILITY_MODE(td) && pid != td->td_proc->p_pid)
- return (ECAPMODE);
+ if (pid != td->td_proc->p_pid) {
+ if (CAP_TRACING(td))
+ ktrcapfail(CAPFAIL_SIGNAL, &signum);
+ if (IN_CAPABILITY_MODE(td))
+ return (ECAPMODE);
+ }
AUDIT_ARG_SIGNUM(signum);
AUDIT_ARG_PID(pid);
@@ -2690,10 +2694,16 @@ ptrace_syscallreq(struct thread *td, struct proc *p,
&td->td_proc->p_cowgen)))
thread_cow_update(td);
+ td->td_sa = tsr->ts_sa;
+
#ifdef CAPABILITY_MODE
- if (IN_CAPABILITY_MODE(td) && (se->sy_flags & SYF_CAPENABLED) == 0) {
- tsr->ts_ret.sr_error = ECAPMODE;
- return;
+ if ((se->sy_flags & SYF_CAPENABLED) == 0) {
+ if (CAP_TRACING(td))
+ ktrcapfail(CAPFAIL_SYSCALL, NULL);
+ if (IN_CAPABILITY_MODE(td)) {
+ tsr->ts_ret.sr_error = ECAPMODE;
+ return;
+ }
}
#endif
diff --git a/sys/kern/kern_sysctl.c b/sys/kern/kern_sysctl.c
index 814579a80f5a..53b61c08713f 100644
--- a/sys/kern/kern_sysctl.c
+++ b/sys/kern/kern_sysctl.c
@@ -634,17 +634,15 @@ sysctl_ctx_free(struct sysctl_ctx_list *clist)
return(EBUSY);
}
/* Now really delete the entries */
- e = TAILQ_FIRST(clist);
- while (e != NULL) {
- e1 = TAILQ_NEXT(e, link);
+ TAILQ_FOREACH_SAFE(e, clist, link, e1) {
error = sysctl_remove_oid_locked(e->entry, 1, 0);
if (error)
panic("sysctl_remove_oid: corrupt tree, entry: %s",
e->entry->oid_name);
free(e, M_SYSCTLOID);
- e = e1;
}
SYSCTL_WUNLOCK();
+ TAILQ_INIT(clist);
return (error);
}
diff --git a/sys/kern/kern_umtx.c b/sys/kern/kern_umtx.c
index 57ff74f5421e..092fcade9d19 100644
--- a/sys/kern/kern_umtx.c
+++ b/sys/kern/kern_umtx.c
@@ -2520,7 +2520,8 @@ do_lock_pp(struct thread *td, struct umutex *m, uint32_t flags,
struct umtx_pi *pi;
uint32_t ceiling;
uint32_t owner, id;
- int error, pri, old_inherited_pri, su, rv;
+ int error, pri, old_inherited_pri, new_pri, rv;
+ bool su;
id = td->td_tid;
uq = td->td_umtxq;
@@ -2549,21 +2550,23 @@ do_lock_pp(struct thread *td, struct umutex *m, uint32_t flags,
error = EINVAL;
goto out;
}
+ new_pri = PRI_MIN_REALTIME + ceiling;
- mtx_lock(&umtx_lock);
- if (UPRI(td) < PRI_MIN_REALTIME + ceiling) {
- mtx_unlock(&umtx_lock);
+ if (td->td_base_user_pri < new_pri) {
error = EINVAL;
goto out;
}
- if (su && PRI_MIN_REALTIME + ceiling < uq->uq_inherited_pri) {
- uq->uq_inherited_pri = PRI_MIN_REALTIME + ceiling;
- thread_lock(td);
- if (uq->uq_inherited_pri < UPRI(td))
- sched_lend_user_prio(td, uq->uq_inherited_pri);
- thread_unlock(td);
+ if (su) {
+ mtx_lock(&umtx_lock);
+ if (new_pri < uq->uq_inherited_pri) {
+ uq->uq_inherited_pri = new_pri;
+ thread_lock(td);
+ if (new_pri < UPRI(td))
+ sched_lend_user_prio(td, new_pri);
+ thread_unlock(td);
+ }
+ mtx_unlock(&umtx_lock);
}
- mtx_unlock(&umtx_lock);
rv = casueword32(&m->m_owner, UMUTEX_CONTESTED, &owner,
id | UMUTEX_CONTESTED);
@@ -2684,7 +2687,8 @@ do_unlock_pp(struct thread *td, struct umutex *m, uint32_t flags, bool rb)
struct umtx_q *uq, *uq2;
struct umtx_pi *pi;
uint32_t id, owner, rceiling;
- int error, pri, new_inherited_pri, su;
+ int error, pri, new_inherited_pri;
+ bool su;
id = td->td_tid;
uq = td->td_umtxq;
@@ -2739,7 +2743,7 @@ do_unlock_pp(struct thread *td, struct umutex *m, uint32_t flags, bool rb)
error = EFAULT;
else {
mtx_lock(&umtx_lock);
- if (su != 0)
+ if (su || new_inherited_pri == PRI_MAX)
uq->uq_inherited_pri = new_inherited_pri;
pri = PRI_MAX;
TAILQ_FOREACH(pi, &uq->uq_pi_contested, pi_link) {
diff --git a/sys/kern/sched_4bsd.c b/sys/kern/sched_4bsd.c
index f0fffeb08e2d..ff1e57746404 100644
--- a/sys/kern/sched_4bsd.c
+++ b/sys/kern/sched_4bsd.c
@@ -981,15 +981,9 @@ void
sched_lend_user_prio_cond(struct thread *td, u_char prio)
{
- if (td->td_lend_user_pri != prio)
- goto lend;
- if (td->td_user_pri != min(prio, td->td_base_user_pri))
- goto lend;
- if (td->td_priority != td->td_user_pri)
- goto lend;
- return;
-
-lend:
+ if (td->td_lend_user_pri == prio)
+ return;
+
thread_lock(td);
sched_lend_user_prio(td, prio);
thread_unlock(td);
diff --git a/sys/kern/sched_ule.c b/sys/kern/sched_ule.c
index ee1e0ab0b955..4b99f1c486bf 100644
--- a/sys/kern/sched_ule.c
+++ b/sys/kern/sched_ule.c
@@ -2007,15 +2007,9 @@ void
sched_lend_user_prio_cond(struct thread *td, u_char prio)
{
- if (td->td_lend_user_pri != prio)
- goto lend;
- if (td->td_user_pri != min(prio, td->td_base_user_pri))
- goto lend;
- if (td->td_priority != td->td_user_pri)
- goto lend;
- return;
+ if (td->td_lend_user_pri == prio)
+ return;
-lend:
thread_lock(td);
sched_lend_user_prio(td, prio);
thread_unlock(td);
diff --git a/sys/kern/subr_intr.c b/sys/kern/subr_intr.c
index 49fe20cdc890..6535c42f2404 100644
--- a/sys/kern/subr_intr.c
+++ b/sys/kern/subr_intr.c
@@ -175,11 +175,11 @@ intr_irq_init(void *dummy __unused)
/*
* - 2 counters for each I/O interrupt.
- * - mp_maxid + 1 counters for each IPI counters for SMP.
+ * - MAXCPU counters for each IPI counters for SMP.
*/
nintrcnt = intr_nirq * 2;
#ifdef SMP
- nintrcnt += INTR_IPI_COUNT * (mp_maxid + 1);
+ nintrcnt += INTR_IPI_COUNT * MAXCPU;
#endif
intrcnt = mallocarray(nintrcnt, sizeof(u_long), M_INTRNG,
@@ -312,18 +312,18 @@ intr_ipi_setup_counters(const char *name)
mtx_lock(&isrc_table_lock);
/*
- * We should never have a problem finding mp_maxid + 1 contiguous
- * counters, in practice. Interrupts will be allocated sequentially
- * during boot, so the array should fill from low to high index. Once
- * reserved, the IPI counters will never be released. Similarly, we
- * will not need to allocate more IPIs once the system is running.
+ * We should never have a problem finding MAXCPU contiguous counters,
+ * in practice. Interrupts will be allocated sequentially during boot,
+ * so the array should fill from low to high index. Once reserved, the
+ * IPI counters will never be released. Similarly, we will not need to
+ * allocate more IPIs once the system is running.
*/
- bit_ffc_area(intrcnt_bitmap, nintrcnt, mp_maxid + 1, &index);
+ bit_ffc_area(intrcnt_bitmap, nintrcnt, MAXCPU, &index);
if (index == -1)
panic("Failed to allocate %d counters. Array exhausted?",
- mp_maxid + 1);
- bit_nset(intrcnt_bitmap, index, index + mp_maxid);
- for (i = 0; i < mp_maxid + 1; i++) {
+ MAXCPU);
+ bit_nset(intrcnt_bitmap, index, index + MAXCPU - 1);
+ for (i = 0; i < MAXCPU; i++) {
snprintf(str, INTRNAME_LEN, "cpu%d:%s", i, name);
intrcnt_setname(str, index + i);
}
diff --git a/sys/kern/subr_syscall.c b/sys/kern/subr_syscall.c
index ff13672501b2..725467e1215f 100644
--- a/sys/kern/subr_syscall.c
+++ b/sys/kern/subr_syscall.c
@@ -120,10 +120,13 @@ syscallenter(struct thread *td)
* In capability mode, we only allow access to system calls
* flagged with SYF_CAPENABLED.
*/
- if (__predict_false(IN_CAPABILITY_MODE(td) &&
- (se->sy_flags & SYF_CAPENABLED) == 0)) {
- td->td_errno = error = ECAPMODE;
- goto retval;
+ if ((se->sy_flags & SYF_CAPENABLED) == 0) {
+ if (CAP_TRACING(td))
+ ktrcapfail(CAPFAIL_SYSCALL, NULL);
+ if (IN_CAPABILITY_MODE(td)) {
+ td->td_errno = error = ECAPMODE;
+ goto retval;
+ }
}
#endif
diff --git a/sys/kern/sys_capability.c b/sys/kern/sys_capability.c
index fac264a78531..d59ad37f35ec 100644
--- a/sys/kern/sys_capability.c
+++ b/sys/kern/sys_capability.c
@@ -154,14 +154,13 @@ MALLOC_DECLARE(M_FILECAPS);
static inline int
_cap_check(const cap_rights_t *havep, const cap_rights_t *needp,
- enum ktr_cap_fail_type type)
+ enum ktr_cap_violation type)
{
+ const cap_rights_t rights[] = { *needp, *havep };
if (!cap_rights_contains(havep, needp)) {
-#ifdef KTRACE
- if (KTRPOINT(curthread, KTR_CAPFAIL))
- ktrcapfail(type, needp, havep);
-#endif
+ if (CAP_TRACING(curthread))
+ ktrcapfail(type, rights);
return (ENOTCAPABLE);
}
return (0);
@@ -180,11 +179,10 @@ cap_check(const cap_rights_t *havep, const cap_rights_t *needp)
int
cap_check_failed_notcapable(const cap_rights_t *havep, const cap_rights_t *needp)
{
+ const cap_rights_t rights[] = { *needp, *havep };
-#ifdef KTRACE
- if (KTRPOINT(curthread, KTR_CAPFAIL))
- ktrcapfail(CAPFAIL_NOTCAPABLE, needp, havep);
-#endif
+ if (CAP_TRACING(curthread))
+ ktrcapfail(CAPFAIL_NOTCAPABLE, rights);
return (ENOTCAPABLE);
}
diff --git a/sys/kern/uipc_shm.c b/sys/kern/uipc_shm.c
index 1b9434aa438c..0bfbc636e405 100644
--- a/sys/kern/uipc_shm.c
+++ b/sys/kern/uipc_shm.c
@@ -1172,14 +1172,6 @@ kern_shm_open2(struct thread *td, const char *userpath, int flags, mode_t mode,
if ((shmflags & SHM_ALLOW_SEALING) != 0)
initial_seals &= ~F_SEAL_SEAL;
-#ifdef CAPABILITY_MODE
- /*
- * shm_open(2) is only allowed for anonymous objects.
- */
- if (IN_CAPABILITY_MODE(td) && (userpath != SHM_ANON))
- return (ECAPMODE);
-#endif
-
AUDIT_ARG_FFLAGS(flags);
AUDIT_ARG_MODE(mode);
@@ -1204,6 +1196,28 @@ kern_shm_open2(struct thread *td, const char *userpath, int flags, mode_t mode,
if ((initial_seals & ~F_SEAL_SEAL) != 0)
return (EINVAL);
+ if (userpath != SHM_ANON) {
+ error = shm_copyin_path(td, userpath, &path);
+ if (error != 0)
+ return (error);
+
+#ifdef CAPABILITY_MODE
+ /*
+ * shm_open(2) is only allowed for anonymous objects.
+ */
+ if (CAP_TRACING(td))
+ ktrcapfail(CAPFAIL_NAMEI, path);
+ if (IN_CAPABILITY_MODE(td)) {
+ free(path, M_SHMFD);
+ return (ECAPMODE);
+ }
+#endif
+
+ AUDIT_ARG_UPATH1_CANON(path);
+ } else {
+ path = NULL;
+ }
+
pdp = td->td_proc->p_pd;
cmode = (mode & ~pdp->pd_cmask) & ACCESSPERMS;
@@ -1215,8 +1229,10 @@ kern_shm_open2(struct thread *td, const char *userpath, int flags, mode_t mode,
* in sys_shm_open() to keep this implementation compliant.
*/
error = falloc_caps(td, &fp, &fd, flags & O_CLOEXEC, fcaps);
- if (error)
+ if (error) {
+ free(path, M_SHMFD);
return (error);
+ }
/* A SHM_ANON path pointer creates an anonymous object. */
if (userpath == SHM_ANON) {
@@ -1230,14 +1246,6 @@ kern_shm_open2(struct thread *td, const char *userpath, int flags, mode_t mode,
shmfd->shm_seals = initial_seals;
shmfd->shm_flags = shmflags;
} else {
- error = shm_copyin_path(td, userpath, &path);
- if (error != 0) {
- fdclose(td, fp, fd);
- fdrop(fp, td);
- return (error);
- }
-
- AUDIT_ARG_UPATH1_CANON(path);
fnv = fnv_32_str(path, FNV1_32_INIT);
sx_xlock(&shm_dict_lock);
shmfd = shm_lookup(path, fnv);
diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c
index 5faf018dca11..32a6ff14bb43 100644
--- a/sys/kern/uipc_socket.c
+++ b/sys/kern/uipc_socket.c
@@ -106,6 +106,7 @@
#include "opt_inet.h"
#include "opt_inet6.h"
#include "opt_kern_tls.h"
+#include "opt_ktrace.h"
#include "opt_sctp.h"
#include <sys/param.h>
@@ -524,8 +525,12 @@ socreate(int dom, struct socket **aso, int type, int proto,
MPASS(prp->pr_attach);
- if (IN_CAPABILITY_MODE(td) && (prp->pr_flags & PR_CAPATTACH) == 0)
- return (ECAPMODE);
+ if ((prp->pr_flags & PR_CAPATTACH) == 0) {
+ if (CAP_TRACING(td))
+ ktrcapfail(CAPFAIL_PROTO, &proto);
+ if (IN_CAPABILITY_MODE(td))
+ return (ECAPMODE);
+ }
if (prison_check_af(cred, prp->pr_domain->dom_family) != 0)
return (EPROTONOSUPPORT);
diff --git a/sys/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c
index 85b2214eaeb9..6c13740d8094 100644
--- a/sys/kern/uipc_syscalls.c
+++ b/sys/kern/uipc_syscalls.c
@@ -201,8 +201,12 @@ kern_bindat(struct thread *td, int dirfd, int fd, struct sockaddr *sa)
int error;
#ifdef CAPABILITY_MODE
- if (IN_CAPABILITY_MODE(td) && (dirfd == AT_FDCWD))
- return (ECAPMODE);
+ if (dirfd == AT_FDCWD) {
+ if (CAP_TRACING(td))
+ ktrcapfail(CAPFAIL_NAMEI, "AT_FDCWD");
+ if (IN_CAPABILITY_MODE(td))
+ return (ECAPMODE);
+ }
#endif
AUDIT_ARG_FD(fd);
@@ -487,8 +491,12 @@ kern_connectat(struct thread *td, int dirfd, int fd, struct sockaddr *sa)
int error;
#ifdef CAPABILITY_MODE
- if (IN_CAPABILITY_MODE(td) && (dirfd == AT_FDCWD))
- return (ECAPMODE);
+ if (dirfd == AT_FDCWD) {
+ if (CAP_TRACING(td))
+ ktrcapfail(CAPFAIL_NAMEI, "AT_FDCWD");
+ if (IN_CAPABILITY_MODE(td))
+ return (ECAPMODE);
+ }
#endif
AUDIT_ARG_FD(fd);
@@ -665,11 +673,6 @@ sendit(struct thread *td, int s, struct msghdr *mp, int flags)
struct sockaddr *to;
int error;
-#ifdef CAPABILITY_MODE
- if (IN_CAPABILITY_MODE(td) && (mp->msg_name != NULL))
- return (ECAPMODE);
-#endif
-
if (mp->msg_name != NULL) {
error = getsockaddr(&to, mp->msg_name, mp->msg_namelen);
if (error != 0) {
@@ -677,6 +680,14 @@ sendit(struct thread *td, int s, struct msghdr *mp, int flags)
goto bad;
}
mp->msg_name = to;
+#ifdef CAPABILITY_MODE
+ if (CAP_TRACING(td))
+ ktrcapfail(CAPFAIL_SOCKADDR, mp->msg_name);
+ if (IN_CAPABILITY_MODE(td)) {
+ error = ECAPMODE;
+ goto bad;
+ }
+#endif
} else {
to = NULL;
}
diff --git a/sys/kern/vfs_cache.c b/sys/kern/vfs_cache.c
index e3ab80f94482..70c4dbc01c98 100644
--- a/sys/kern/vfs_cache.c
+++ b/sys/kern/vfs_cache.c
@@ -4396,7 +4396,7 @@ cache_can_fplookup(struct cache_fpl *fpl)
cache_fpl_aborted_early(fpl);
return (false);
}
- if (IN_CAPABILITY_MODE(td)) {
+ if (IN_CAPABILITY_MODE(td) || CAP_TRACING(td)) {
cache_fpl_aborted_early(fpl);
return (false);
}
diff --git a/sys/kern/vfs_lookup.c b/sys/kern/vfs_lookup.c
index 6c83746eaf8b..b7f751a364ce 100644
--- a/sys/kern/vfs_lookup.c
+++ b/sys/kern/vfs_lookup.c
@@ -88,6 +88,17 @@ static void NDVALIDATE_impl(struct nameidata *, int);
ndp->ni_cnd.cn_flags |= ISRESTARTED; \
} while (0)
+#ifdef KTRACE
+#define NIKTRCAPFAIL(path) ktrcapfail(CAPFAIL_NAMEI, (path))
+#else
+#define NIKTRCAPFAIL(path)
+#endif
+
+#define NI_CAP_VIOLATION(ndp, path) do { \
+ NIKTRCAPFAIL(path); \
+ (ndp)->ni_lcf &= ~NI_LCF_KTR_FLAGS; \
+} while (0)
+
SDT_PROVIDER_DEFINE(vfs);
SDT_PROBE_DEFINE4(vfs, namei, lookup, entry, "struct vnode *", "char *",
"unsigned long", "bool");
@@ -238,14 +249,17 @@ nameicap_check_dotdot(struct nameidata *ndp, struct vnode *dp)
struct mount *mp;
if (dp == NULL || dp->v_type != VDIR || (ndp->ni_lcf &
- NI_LCF_STRICTRELATIVE) == 0)
+ NI_LCF_STRICTREL) == 0)
return (0);
+ if (__predict_false((ndp->ni_lcf & (NI_LCF_STRICTREL_KTR |
+ NI_LCF_CAP_DOTDOT_KTR)) == NI_LCF_STRICTREL_KTR))
+ NI_CAP_VIOLATION(ndp, ndp->ni_cnd.cn_pnbuf);
if ((ndp->ni_lcf & NI_LCF_CAP_DOTDOT) == 0)
return (ENOTCAPABLE);
mp = dp->v_mount;
if (lookup_cap_dotdot_nonlocal == 0 && mp != NULL &&
(mp->mnt_flag & MNT_LOCAL) == 0)
- return (ENOTCAPABLE);
+ goto capfail;
TAILQ_FOREACH_REVERSE(nt, &ndp->ni_cap_tracker, nameicap_tracker_head,
nm_link) {
if (dp == nt->dp) {
@@ -255,6 +269,10 @@ nameicap_check_dotdot(struct nameidata *ndp, struct vnode *dp)
return (0);
}
}
+
+capfail:
+ if (__predict_false((ndp->ni_lcf & NI_LCF_STRICTREL_KTR) != 0))
+ NI_CAP_VIOLATION(ndp, ndp->ni_cnd.cn_pnbuf);
return (ENOTCAPABLE);
}
@@ -273,12 +291,12 @@ namei_handle_root(struct nameidata *ndp, struct vnode **dpp)
struct componentname *cnp;
cnp = &ndp->ni_cnd;
- if ((ndp->ni_lcf & NI_LCF_STRICTRELATIVE) != 0) {
-#ifdef KTRACE
- if (KTRPOINT(curthread, KTR_CAPFAIL))
- ktrcapfail(CAPFAIL_LOOKUP, NULL, NULL);
-#endif
- return (ENOTCAPABLE);
+ if (__predict_false((ndp->ni_lcf & (NI_LCF_STRICTREL |
+ NI_LCF_STRICTREL_KTR)) != 0)) {
+ if ((ndp->ni_lcf & NI_LCF_STRICTREL_KTR) != 0)
+ NI_CAP_VIOLATION(ndp, cnp->cn_pnbuf);
+ if ((ndp->ni_lcf & NI_LCF_STRICTREL) != 0)
+ return (ENOTCAPABLE);
}
while (*(cnp->cn_nameptr) == '/') {
cnp->cn_nameptr++;
@@ -319,15 +337,17 @@ namei_setup(struct nameidata *ndp, struct vnode **dpp, struct pwd **pwdp)
* previously walked by us, which prevents an escape from
* the relative root.
*/
- if (IN_CAPABILITY_MODE(td) && (cnp->cn_flags & NOCAPCHECK) == 0) {
- ndp->ni_lcf |= NI_LCF_STRICTRELATIVE;
- ndp->ni_resflags |= NIRES_STRICTREL;
- if (ndp->ni_dirfd == AT_FDCWD) {
-#ifdef KTRACE
- if (KTRPOINT(td, KTR_CAPFAIL))
- ktrcapfail(CAPFAIL_LOOKUP, NULL, NULL);
-#endif
- return (ECAPMODE);
+ if ((cnp->cn_flags & NOCAPCHECK) == 0) {
+ if (CAP_TRACING(td)) {
+ ndp->ni_lcf |= NI_LCF_STRICTREL_KTR;
+ if (ndp->ni_dirfd == AT_FDCWD)
+ NI_CAP_VIOLATION(ndp, "AT_FDCWD");
+ }
+ if (IN_CAPABILITY_MODE(td)) {
+ ndp->ni_lcf |= NI_LCF_STRICTREL;
+ ndp->ni_resflags |= NIRES_STRICTREL;
+ if (ndp->ni_dirfd == AT_FDCWD)
+ return (ECAPMODE);
}
}
#endif
@@ -370,8 +390,8 @@ namei_setup(struct nameidata *ndp, struct vnode **dpp, struct pwd **pwdp)
if (error == 0 && (cnp->cn_flags & RBENEATH) != 0) {
if (cnp->cn_pnbuf[0] == '/') {
error = ENOTCAPABLE;
- } else if ((ndp->ni_lcf & NI_LCF_STRICTRELATIVE) == 0) {
- ndp->ni_lcf |= NI_LCF_STRICTRELATIVE |
+ } else if ((ndp->ni_lcf & NI_LCF_STRICTREL) == 0) {
+ ndp->ni_lcf |= NI_LCF_STRICTREL |
NI_LCF_CAP_DOTDOT;
}
}
@@ -393,9 +413,12 @@ namei_setup(struct nameidata *ndp, struct vnode **dpp, struct pwd **pwdp)
pwd_drop(pwd);
return (error);
}
- if ((ndp->ni_lcf & NI_LCF_STRICTRELATIVE) != 0 &&
- lookup_cap_dotdot != 0)
- ndp->ni_lcf |= NI_LCF_CAP_DOTDOT;
+ if (lookup_cap_dotdot != 0) {
+ if ((ndp->ni_lcf & NI_LCF_STRICTREL_KTR) != 0)
+ ndp->ni_lcf |= NI_LCF_CAP_DOTDOT_KTR;
+ if ((ndp->ni_lcf & NI_LCF_STRICTREL) != 0)
+ ndp->ni_lcf |= NI_LCF_CAP_DOTDOT;
+ }
SDT_PROBE4(vfs, namei, lookup, entry, *dpp, cnp->cn_pnbuf,
cnp->cn_flags, false);
*pwdp = pwd;
@@ -1170,12 +1193,11 @@ dirloop:
* result of dotdot lookup.
*/
if (cnp->cn_flags & ISDOTDOT) {
- if ((ndp->ni_lcf & (NI_LCF_STRICTRELATIVE | NI_LCF_CAP_DOTDOT))
- == NI_LCF_STRICTRELATIVE) {
-#ifdef KTRACE
- if (KTRPOINT(curthread, KTR_CAPFAIL))
- ktrcapfail(CAPFAIL_LOOKUP, NULL, NULL);
-#endif
+ if (__predict_false((ndp->ni_lcf & (NI_LCF_STRICTREL_KTR |
+ NI_LCF_CAP_DOTDOT_KTR)) == NI_LCF_STRICTREL_KTR))
+ NI_CAP_VIOLATION(ndp, cnp->cn_pnbuf);
+ if (__predict_false((ndp->ni_lcf & (NI_LCF_STRICTREL |
+ NI_LCF_CAP_DOTDOT)) == NI_LCF_STRICTREL)) {
error = ENOTCAPABLE;
goto bad;
}
@@ -1192,10 +1214,14 @@ dirloop:
bool isroot = dp == ndp->ni_rootdir ||
dp == ndp->ni_topdir || dp == rootvnode ||
pr != NULL;
- if (isroot && (ndp->ni_lcf &
- NI_LCF_STRICTRELATIVE) != 0) {
- error = ENOTCAPABLE;
- goto capdotdot;
+ if (__predict_false(isroot && (ndp->ni_lcf &
+ (NI_LCF_STRICTREL | NI_LCF_STRICTREL_KTR)) != 0)) {
+ if ((ndp->ni_lcf & NI_LCF_STRICTREL_KTR) != 0)
+ NI_CAP_VIOLATION(ndp, cnp->cn_pnbuf);
+ if ((ndp->ni_lcf & NI_LCF_STRICTREL) != 0) {
+ error = ENOTCAPABLE;
+ goto capdotdot;
+ }
}
if (isroot || ((dp->v_vflag & VV_ROOT) != 0 &&
(cnp->cn_flags & NOCROSSMOUNT) != 0)) {
@@ -1220,10 +1246,6 @@ dirloop:
error = nameicap_check_dotdot(ndp, dp);
if (error != 0) {
capdotdot:
-#ifdef KTRACE
- if (KTRPOINT(curthread, KTR_CAPFAIL))
- ktrcapfail(CAPFAIL_LOOKUP, NULL, NULL);
-#endif
goto bad;
}
}
@@ -1376,13 +1398,8 @@ nextname:
}
if (cnp->cn_flags & ISDOTDOT) {
error = nameicap_check_dotdot(ndp, ndp->ni_vp);
- if (error != 0) {
-#ifdef KTRACE
- if (KTRPOINT(curthread, KTR_CAPFAIL))
- ktrcapfail(CAPFAIL_LOOKUP, NULL, NULL);
-#endif
+ if (error != 0)
goto bad2;
- }
}
if (*ndp->ni_next == '/') {
cnp->cn_nameptr = ndp->ni_next;
diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c
index 51386d0e9581..1171b72a3a96 100644
--- a/sys/kern/vfs_vnops.c
+++ b/sys/kern/vfs_vnops.c
@@ -3341,7 +3341,7 @@ vn_generic_copy_file_range(struct vnode *invp, off_t *inoffp,
off_t startoff, endoff, xfer, xfer2;
u_long blksize;
int error, interrupted;
- bool cantseek, readzeros, eof, lastblock, holetoeof, sparse;
+ bool cantseek, readzeros, eof, first, lastblock, holetoeof, sparse;
ssize_t aresid, r = 0;
size_t copylen, len, savlen;
off_t outsize;
@@ -3482,6 +3482,7 @@ vn_generic_copy_file_range(struct vnode *invp, off_t *inoffp,
endts.tv_sec++;
} else
timespecclear(&endts);
+ first = true;
holetoeof = eof = false;
while (len > 0 && error == 0 && !eof && interrupted == 0) {
endoff = 0; /* To shut up compilers. */
@@ -3583,10 +3584,17 @@ vn_generic_copy_file_range(struct vnode *invp, off_t *inoffp,
*/
xfer -= (*inoffp % blksize);
}
- /* Loop copying the data block. */
- while (copylen > 0 && error == 0 && !eof && interrupted == 0) {
+
+ /*
+ * Loop copying the data block. If this was our first attempt
+ * to copy anything, allow a zero-length block so that the VOPs
+ * get a chance to update metadata, specifically the atime.
+ */
+ while (error == 0 && ((copylen > 0 && !eof) || first) &&
+ interrupted == 0) {
if (copylen < xfer)
xfer = copylen;
+ first = false;
error = vn_lock(invp, LK_SHARED);
if (error != 0)
goto out;
@@ -3596,7 +3604,7 @@ vn_generic_copy_file_range(struct vnode *invp, off_t *inoffp,
curthread);
VOP_UNLOCK(invp);
lastblock = false;
- if (error == 0 && aresid > 0) {
+ if (error == 0 && (xfer == 0 || aresid > 0)) {
/* Stop the copy at EOF on the input file. */
xfer -= aresid;
eof = true;
diff --git a/sys/modules/sound/sound/Makefile b/sys/modules/sound/sound/Makefile
index 833330ef9b26..1c3685715503 100644
--- a/sys/modules/sound/sound/Makefile
+++ b/sys/modules/sound/sound/Makefile
@@ -17,7 +17,7 @@ SRCS+= feeder_eq_gen.h feeder_rate_gen.h snd_fxdiv_gen.h
SRCS+= mpu_if.h mpufoi_if.h synth_if.h
SRCS+= mpu_if.c mpufoi_if.c synth_if.c
SRCS+= ac97.c ac97_patch.c buffer.c channel.c dsp.c
-SRCS+= mixer.c sndstat.c sound.c unit.c vchan.c
+SRCS+= mixer.c sndstat.c sound.c vchan.c
SRCS+= midi.c mpu401.c sequencer.c
feeder_eq_gen.h: ${SYSDIR}/tools/sound/feeder_eq_mkfilter.awk
diff --git a/sys/net/if.c b/sys/net/if.c
index 0128fb8039ee..1ca0893eb724 100644
--- a/sys/net/if.c
+++ b/sys/net/if.c
@@ -4873,6 +4873,9 @@ if_resolvemulti(if_t ifp, struct sockaddr **srcs, struct sockaddr *dst)
int
if_ioctl(if_t ifp, u_long cmd, void *data)
{
+ if (ifp->if_ioctl == NULL)
+ return (EOPNOTSUPP);
+
return (ifp->if_ioctl(ifp, cmd, data));
}
diff --git a/sys/net/if_bridge.c b/sys/net/if_bridge.c
index 1b4ac92b62a3..1e6f9b578ee3 100644
--- a/sys/net/if_bridge.c
+++ b/sys/net/if_bridge.c
@@ -403,12 +403,14 @@ static int bridge_ioctl_sproto(struct bridge_softc *, void *);
static int bridge_ioctl_stxhc(struct bridge_softc *, void *);
static int bridge_pfil(struct mbuf **, struct ifnet *, struct ifnet *,
int);
+#ifdef INET
static int bridge_ip_checkbasic(struct mbuf **mp);
+static int bridge_fragment(struct ifnet *, struct mbuf **mp,
+ struct ether_header *, int, struct llc *);
+#endif /* INET */
#ifdef INET6
static int bridge_ip6_checkbasic(struct mbuf **mp);
#endif /* INET6 */
-static int bridge_fragment(struct ifnet *, struct mbuf **mp,
- struct ether_header *, int, struct llc *);
static void bridge_linkstate(struct ifnet *ifp);
static void bridge_linkcheck(struct bridge_softc *sc);
@@ -3390,12 +3392,15 @@ bridge_state_change(struct ifnet *ifp, int state)
static int
bridge_pfil(struct mbuf **mp, struct ifnet *bifp, struct ifnet *ifp, int dir)
{
- int snap, error, i, hlen;
+ int snap, error, i;
struct ether_header *eh1, eh2;
- struct ip *ip;
struct llc llc1;
u_int16_t ether_type;
pfil_return_t rv;
+#ifdef INET
+ struct ip *ip = NULL;
+ int hlen = 0;
+#endif
snap = 0;
error = -1; /* Default error if not error == 0 */
@@ -3436,31 +3441,36 @@ bridge_pfil(struct mbuf **mp, struct ifnet *bifp, struct ifnet *ifp, int dir)
}
/*
- * If we're trying to filter bridge traffic, don't look at anything
- * other than IP and ARP traffic. If the filter doesn't understand
- * IPv6, don't allow IPv6 through the bridge either. This is lame
- * since if we really wanted, say, an AppleTalk filter, we are hosed,
- * but of course we don't have an AppleTalk filter to begin with.
- * (Note that since pfil doesn't understand ARP it will pass *ALL*
- * ARP traffic.)
+ * If we're trying to filter bridge traffic, only look at traffic for
+ * protocols available in the kernel (IPv4 and/or IPv6) to avoid
+ * passing traffic for an unsupported protocol to the filter. This is
+ * lame since if we really wanted, say, an AppleTalk filter, we are
+ * hosed, but of course we don't have an AppleTalk filter to begin
+ * with. (Note that since pfil doesn't understand ARP it will pass
+ * *ALL* ARP traffic.)
*/
switch (ether_type) {
+#ifdef INET
case ETHERTYPE_ARP:
case ETHERTYPE_REVARP:
if (V_pfil_ipfw_arp == 0)
return (0); /* Automatically pass */
- break;
+ /* FALLTHROUGH */
case ETHERTYPE_IP:
+#endif
#ifdef INET6
case ETHERTYPE_IPV6:
#endif /* INET6 */
break;
+
default:
/*
- * Check to see if the user wants to pass non-ip
- * packets, these will not be checked by pfil(9) and
- * passed unconditionally so the default is to drop.
+ * We get here if the packet isn't from a supported
+ * protocol. Check to see if the user wants to pass
+ * non-IP packets, these will not be checked by pfil(9)
+ * and passed unconditionally so the default is to
+ * drop.
*/
if (V_pfil_onlyip)
goto bad;
@@ -3492,9 +3502,11 @@ bridge_pfil(struct mbuf **mp, struct ifnet *bifp, struct ifnet *ifp, int dir)
*/
if (dir == PFIL_IN) {
switch (ether_type) {
+#ifdef INET
case ETHERTYPE_IP:
error = bridge_ip_checkbasic(mp);
break;
+#endif
#ifdef INET6
case ETHERTYPE_IPV6:
error = bridge_ip6_checkbasic(mp);
@@ -3514,6 +3526,7 @@ bridge_pfil(struct mbuf **mp, struct ifnet *bifp, struct ifnet *ifp, int dir)
*/
rv = PFIL_PASS;
switch (ether_type) {
+#ifdef INET
case ETHERTYPE_IP:
/*
* Run pfil on the member interface and the bridge, both can
@@ -3571,6 +3584,7 @@ bridge_pfil(struct mbuf **mp, struct ifnet *bifp, struct ifnet *ifp, int dir)
ip->ip_sum = in_cksum(*mp, hlen);
break;
+#endif /* INET */
#ifdef INET6
case ETHERTYPE_IPV6:
if (V_pfil_bridge && dir == PFIL_OUT && bifp != NULL && (rv =
@@ -3628,6 +3642,7 @@ bad:
return (error);
}
+#ifdef INET
/*
* Perform basic checks on header size since
* pfil assumes ip_input has already processed
@@ -3728,6 +3743,7 @@ bad:
*mp = m;
return (-1);
}
+#endif /* INET */
#ifdef INET6
/*
@@ -3783,6 +3799,7 @@ bad:
}
#endif /* INET6 */
+#ifdef INET
/*
* bridge_fragment:
*
@@ -3859,6 +3876,7 @@ dropit:
}
return (error);
}
+#endif /* INET */
static void
bridge_linkstate(struct ifnet *ifp)
diff --git a/sys/net/if_disc.c b/sys/net/if_disc.c
index 02f3bbbfdaf1..193bb31d138f 100644
--- a/sys/net/if_disc.c
+++ b/sys/net/if_disc.c
@@ -182,7 +182,7 @@ discoutput(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst,
M_ASSERTPKTHDR(m);
/* BPF writes need to be handled specially. */
- if (dst->sa_family == AF_UNSPEC)
+ if (dst->sa_family == AF_UNSPEC || dst->sa_family == pseudo_AF_HDRCMPLT)
bcopy(dst->sa_data, &af, sizeof(af));
else
af = RO_GET_FAMILY(ro, dst);
diff --git a/sys/net/if_gif.c b/sys/net/if_gif.c
index e5065889d732..ef64c15074ed 100644
--- a/sys/net/if_gif.c
+++ b/sys/net/if_gif.c
@@ -408,7 +408,8 @@ gif_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst,
KASSERT(ifp->if_bridge == NULL,
("%s: unexpectedly called with bridge attached", __func__));
- if (dst->sa_family == AF_UNSPEC)
+ /* BPF writes need to be handled specially. */
+ if (dst->sa_family == AF_UNSPEC || dst->sa_family == pseudo_AF_HDRCMPLT)
memcpy(&af, dst->sa_data, sizeof(af));
else
af = RO_GET_FAMILY(ro, dst);
diff --git a/sys/net/if_gre.c b/sys/net/if_gre.c
index 55163416f807..ca9c4835daf6 100644
--- a/sys/net/if_gre.c
+++ b/sys/net/if_gre.c
@@ -609,7 +609,8 @@ gre_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst,
{
uint32_t af;
- if (dst->sa_family == AF_UNSPEC)
+ /* BPF writes need to be handled specially. */
+ if (dst->sa_family == AF_UNSPEC || dst->sa_family == pseudo_AF_HDRCMPLT)
bcopy(dst->sa_data, &af, sizeof(af));
else
af = RO_GET_FAMILY(ro, dst);
diff --git a/sys/net/if_me.c b/sys/net/if_me.c
index e9bcd345b5c5..80c2816b808a 100644
--- a/sys/net/if_me.c
+++ b/sys/net/if_me.c
@@ -539,7 +539,8 @@ me_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst,
{
uint32_t af;
- if (dst->sa_family == AF_UNSPEC)
+ /* BPF writes need to be handled specially. */
+ if (dst->sa_family == AF_UNSPEC || dst->sa_family == pseudo_AF_HDRCMPLT)
bcopy(dst->sa_data, &af, sizeof(af));
else
af = RO_GET_FAMILY(ro, dst);
diff --git a/sys/net/if_tuntap.c b/sys/net/if_tuntap.c
index 4cb219dc92b6..5d37879e87b9 100644
--- a/sys/net/if_tuntap.c
+++ b/sys/net/if_tuntap.c
@@ -1442,7 +1442,7 @@ tunoutput(struct ifnet *ifp, struct mbuf *m0, const struct sockaddr *dst,
}
/* BPF writes need to be handled specially. */
- if (dst->sa_family == AF_UNSPEC)
+ if (dst->sa_family == AF_UNSPEC || dst->sa_family == pseudo_AF_HDRCMPLT)
bcopy(dst->sa_data, &af, sizeof(af));
else
af = RO_GET_FAMILY(ro, dst);
diff --git a/sys/netgraph/ng_iface.c b/sys/netgraph/ng_iface.c
index 8ae4707b7abd..e9f97ff0fdec 100644
--- a/sys/netgraph/ng_iface.c
+++ b/sys/netgraph/ng_iface.c
@@ -367,7 +367,7 @@ ng_iface_output(struct ifnet *ifp, struct mbuf *m,
}
/* BPF writes need to be handled specially. */
- if (dst->sa_family == AF_UNSPEC)
+ if (dst->sa_family == AF_UNSPEC || dst->sa_family == pseudo_AF_HDRCMPLT)
bcopy(dst->sa_data, &af, sizeof(af));
else
af = RO_GET_FAMILY(ro, dst);
diff --git a/sys/netgraph/ng_pipe.c b/sys/netgraph/ng_pipe.c
index a2966c9a0349..42a5991e8dc7 100644
--- a/sys/netgraph/ng_pipe.c
+++ b/sys/netgraph/ng_pipe.c
@@ -34,7 +34,7 @@
* This node permits simple traffic shaping by emulating bandwidth
* and delay, as well as random packet losses.
* The node has two hooks, upper and lower. Traffic flowing from upper to
- * lower hook is referenced as downstream, and vice versa. Parameters for
+ * lower hook is referenced as downstream, and vice versa. Parameters for
* both directions can be set separately, except for delay.
*/
@@ -44,6 +44,7 @@
#include <sys/kernel.h>
#include <sys/malloc.h>
#include <sys/mbuf.h>
+#include <sys/prng.h>
#include <sys/time.h>
#include <vm/uma.h>
@@ -195,8 +196,8 @@ static const struct ng_cmdlist ngp_cmds[] = {
{
.cookie = NGM_PIPE_COOKIE,
.cmd = NGM_PIPE_GET_STATS,
- .name = "getstats",
- .respType = &ng_pipe_stats_type
+ .name = "getstats",
+ .respType = &ng_pipe_stats_type
},
{
.cookie = NGM_PIPE_COOKIE,
@@ -494,7 +495,7 @@ parse_cfg(struct ng_pipe_hookcfg *current, struct ng_pipe_hookcfg *new,
if (new->qin_size_limit == -1)
current->qin_size_limit = 0;
- else if (new->qin_size_limit >= 5)
+ else if (new->qin_size_limit >= 5)
current->qin_size_limit = new->qin_size_limit;
if (new->qout_size_limit == -1)
@@ -547,7 +548,7 @@ parse_cfg(struct ng_pipe_hookcfg *current, struct ng_pipe_hookcfg *new,
} else if (new->bandwidth >= 100 && new->bandwidth <= 1000000000)
current->bandwidth = new->bandwidth;
- if (current->bandwidth | priv->delay |
+ if (current->bandwidth | priv->delay |
current->duplicate | current->ber)
hinfo->noqueue = 0;
else
@@ -640,12 +641,14 @@ ngp_rcvdata(hook_p hook, item_p item)
}
/* Populate the packet header */
- ngp_h = uma_zalloc(ngp_zone, M_NOWAIT);
- KASSERT((ngp_h != NULL), ("ngp_h zalloc failed (1)"));
NGI_GET_M(item, m);
- KASSERT(m != NULL, ("NGI_GET_M failed"));
- ngp_h->m = m;
NG_FREE_ITEM(item);
+ ngp_h = uma_zalloc(ngp_zone, M_NOWAIT);
+ if (ngp_h == NULL) {
+ NG_FREE_M(m);
+ return (ENOMEM);
+ }
+ ngp_h->m = m;
if (hinfo->cfg.fifo)
hash = 0; /* all packets go into a single FIFO queue */
@@ -658,7 +661,11 @@ ngp_rcvdata(hook_p hook, item_p item)
break;
if (ngp_f == NULL) {
ngp_f = uma_zalloc(ngp_zone, M_NOWAIT);
- KASSERT(ngp_h != NULL, ("ngp_h zalloc failed (2)"));
+ if (ngp_f == NULL) {
+ NG_FREE_M(ngp_h->m);
+ uma_zfree(ngp_zone, ngp_h);
+ return (ENOMEM);
+ }
TAILQ_INIT(&ngp_f->packet_head);
ngp_f->hash = hash;
ngp_f->packets = 1;
@@ -686,9 +693,9 @@ ngp_rcvdata(hook_p hook, item_p item)
}
/* Drop a frame from the queue head/tail, depending on cfg */
- if (hinfo->cfg.drophead)
+ if (hinfo->cfg.drophead)
ngp_h = TAILQ_FIRST(&ngp_f->packet_head);
- else
+ else
ngp_h = TAILQ_LAST(&ngp_f->packet_head, p_head);
TAILQ_REMOVE(&ngp_f->packet_head, ngp_h, ngp_link);
m1 = ngp_h->m;
@@ -732,7 +739,7 @@ pipe_dequeue(struct hookinfo *hinfo, struct timeval *now) {
const priv_p priv = NG_NODE_PRIVATE(node);
struct hookinfo *dest;
struct ngp_fifo *ngp_f, *ngp_f1;
- struct ngp_hdr *ngp_h;
+ struct ngp_hdr *ngp_h, *ngp_dup;
struct timeval *when;
struct mbuf *m;
int plen, error = 0;
@@ -767,23 +774,34 @@ pipe_dequeue(struct hookinfo *hinfo, struct timeval *now) {
}
/*
- * Either create a duplicate and pass it on, or dequeue
- * the original packet...
+ * Either create a duplicate and pass it on, or
+ * dequeue the original packet. When any of the
+ * memory allocations for the duplicate package fail,
+ * simply do not duplicate it at all.
*/
+ ngp_dup = NULL;
if (hinfo->cfg.duplicate &&
- random() % 100 <= hinfo->cfg.duplicate) {
- ngp_h = uma_zalloc(ngp_zone, M_NOWAIT);
- KASSERT(ngp_h != NULL, ("ngp_h zalloc failed (3)"));
- m = m_dup(m, M_NOWAIT);
- KASSERT(m != NULL, ("m_dup failed"));
- ngp_h->m = m;
+ prng32_bounded(100) <= hinfo->cfg.duplicate) {
+ ngp_dup = uma_zalloc(ngp_zone, M_NOWAIT);
+ if (ngp_dup != NULL) {
+ ngp_dup->m = m_dup(m, M_NOWAIT);
+ if (ngp_dup->m == NULL) {
+ uma_zfree(ngp_zone, ngp_dup);
+ ngp_dup = NULL;
+ }
+ }
+ }
+
+ if (ngp_dup != NULL) {
+ ngp_h = ngp_dup;
+ m = ngp_h->m;
} else {
TAILQ_REMOVE(&ngp_f->packet_head, ngp_h, ngp_link);
hinfo->run.qin_frames--;
hinfo->run.qin_octets -= m->m_pkthdr.len;
ngp_f->packets--;
}
-
+
/* Calculate the serialization delay */
if (hinfo->cfg.bandwidth) {
hinfo->qin_utime.tv_usec +=
@@ -814,7 +832,7 @@ pipe_dequeue(struct hookinfo *hinfo, struct timeval *now) {
/* Randomly discard the frame, according to BER setting */
if (hinfo->cfg.ber) {
oldrand = rand;
- rand = random();
+ rand = prng32_bounded(1U << 31);
if (((oldrand ^ rand) << 17) >=
hinfo->ber_p[priv->overhead + m->m_pkthdr.len]) {
hinfo->stats.out_disc_frames++;
@@ -936,6 +954,7 @@ ngp_disconnect(hook_p hook)
struct hookinfo *const hinfo = NG_HOOK_PRIVATE(hook);
struct ngp_fifo *ngp_f;
struct ngp_hdr *ngp_h;
+ priv_p priv;
KASSERT(hinfo != NULL, ("%s: null info", __FUNCTION__));
hinfo->hook = NULL;
@@ -962,6 +981,12 @@ ngp_disconnect(hook_p hook)
if (hinfo->ber_p)
free(hinfo->ber_p, M_NG_PIPE);
+ /* Destroy the node if all hooks are disconnected */
+ priv = NG_NODE_PRIVATE(NG_HOOK_NODE(hook));
+
+ if (priv->upper.hook == NULL && priv->lower.hook == NULL)
+ ng_rmnode_self(NG_HOOK_NODE(hook));
+
return (0);
}
@@ -975,8 +1000,6 @@ ngp_modevent(module_t mod, int type, void *unused)
ngp_zone = uma_zcreate("ng_pipe", max(sizeof(struct ngp_hdr),
sizeof (struct ngp_fifo)), NULL, NULL, NULL, NULL,
UMA_ALIGN_PTR, 0);
- if (ngp_zone == NULL)
- panic("ng_pipe: couldn't allocate descriptor zone");
break;
case MOD_UNLOAD:
uma_zdestroy(ngp_zone);
diff --git a/sys/netinet/in_fib_dxr.c b/sys/netinet/in_fib_dxr.c
index e7eede53ea51..82245ecf6e66 100644
--- a/sys/netinet/in_fib_dxr.c
+++ b/sys/netinet/in_fib_dxr.c
@@ -474,8 +474,7 @@ chunk_ref(struct dxr_aux *da, uint32_t chunk)
cdp->cd_max_size = size;
cdp->cd_base = fdesc->base;
LIST_INSERT_HEAD(&da->all_chunks, cdp, cd_all_le);
- KASSERT(cdp->cd_base + cdp->cd_max_size == da->rtbl_top,
- ("dxr: %s %d", __FUNCTION__, __LINE__));
+ MPASS(cdp->cd_base + cdp->cd_max_size == da->rtbl_top);
}
cdp->cd_hash = hash;
@@ -497,8 +496,11 @@ chunk_ref(struct dxr_aux *da, uint32_t chunk)
da->range_tbl = realloc(da->range_tbl,
sizeof(*da->range_tbl) * da->rtbl_size + FRAGS_PREF_SHORT,
M_DXRAUX, M_NOWAIT);
- if (da->range_tbl == NULL)
+ if (da->range_tbl == NULL) {
+ FIB_PRINTF(LOG_NOTICE, da->fd,
+ "Unable to allocate DXR range table");
return (1);
+ }
}
return (0);
@@ -522,7 +524,7 @@ chunk_unref(struct dxr_aux *da, uint32_t chunk)
sizeof(struct range_entry_long) * size) == 0)
break;
- KASSERT(cdp != NULL, ("dxr: dangling chunk"));
+ MPASS(cdp != NULL);
if (--cdp->cd_refcnt > 0)
return;
@@ -533,8 +535,7 @@ chunk_unref(struct dxr_aux *da, uint32_t chunk)
/* Attempt to merge with the preceding chunk, if empty */
cdp2 = LIST_NEXT(cdp, cd_all_le);
if (cdp2 != NULL && cdp2->cd_cur_size == 0) {
- KASSERT(cdp2->cd_base + cdp2->cd_max_size == cdp->cd_base,
- ("dxr: %s %d", __FUNCTION__, __LINE__));
+ MPASS(cdp2->cd_base + cdp2->cd_max_size == cdp->cd_base);
LIST_REMOVE(cdp, cd_all_le);
LIST_REMOVE(cdp2, cd_hash_le);
cdp2->cd_max_size += cdp->cd_max_size;
@@ -545,8 +546,7 @@ chunk_unref(struct dxr_aux *da, uint32_t chunk)
/* Attempt to merge with the subsequent chunk, if empty */
cdp2 = LIST_PREV(cdp, &da->all_chunks, chunk_desc, cd_all_le);
if (cdp2 != NULL && cdp2->cd_cur_size == 0) {
- KASSERT(cdp->cd_base + cdp->cd_max_size == cdp2->cd_base,
- ("dxr: %s %d", __FUNCTION__, __LINE__));
+ MPASS(cdp->cd_base + cdp->cd_max_size == cdp2->cd_base);
LIST_REMOVE(cdp, cd_all_le);
LIST_REMOVE(cdp2, cd_hash_le);
cdp2->cd_max_size += cdp->cd_max_size;
@@ -557,8 +557,7 @@ chunk_unref(struct dxr_aux *da, uint32_t chunk)
if (cdp->cd_base + cdp->cd_max_size == da->rtbl_top) {
/* Free the chunk on the top of the range heap, trim the heap */
- KASSERT(cdp == LIST_FIRST(&da->all_chunks),
- ("dxr: %s %d", __FUNCTION__, __LINE__));
+ MPASS(cdp == LIST_FIRST(&da->all_chunks));
da->rtbl_top -= cdp->cd_max_size;
da->unused_chunks_size -= cdp->cd_max_size;
LIST_REMOVE(cdp, cd_all_le);
@@ -632,8 +631,11 @@ trie_ref(struct dxr_aux *da, uint32_t index)
da->xtbl_size += XTBL_SIZE_INCR;
da->x_tbl = realloc(da->x_tbl,
sizeof(*da->x_tbl) * da->xtbl_size, M_DXRAUX, M_NOWAIT);
- if (da->x_tbl == NULL)
+ if (da->x_tbl == NULL) {
+ FIB_PRINTF(LOG_NOTICE, da->fd,
+ "Unable to allocate DXR extension table");
return (-1);
+ }
}
return(tp->td_index);
}
@@ -869,14 +871,18 @@ dxr_build(struct dxr *dxr)
uint32_t trie_frag;
#endif
- KASSERT(dxr->d == NULL, ("dxr: d not free"));
+ MPASS(dxr->d == NULL);
if (da == NULL) {
da = malloc(sizeof(*dxr->aux), M_DXRAUX, M_NOWAIT);
- if (da == NULL)
+ if (da == NULL) {
+ FIB_PRINTF(LOG_NOTICE, dxr->fd,
+ "Unable to allocate DXR aux struct");
return;
+ }
dxr->aux = da;
da->fibnum = dxr->fibnum;
+ da->fd = dxr->fd;
da->refcnt = 1;
LIST_INIT(&da->all_chunks);
LIST_INIT(&da->all_trie);
@@ -894,20 +900,25 @@ dxr_build(struct dxr *dxr)
if (da->range_tbl == NULL) {
da->range_tbl = malloc(sizeof(*da->range_tbl) * da->rtbl_size
+ FRAGS_PREF_SHORT, M_DXRAUX, M_NOWAIT);
- if (da->range_tbl == NULL)
+ if (da->range_tbl == NULL) {
+ FIB_PRINTF(LOG_NOTICE, da->fd,
+ "Unable to allocate DXR range table");
return;
+ }
range_rebuild = 1;
}
#ifdef DXR2
if (da->x_tbl == NULL) {
da->x_tbl = malloc(sizeof(*da->x_tbl) * da->xtbl_size,
M_DXRAUX, M_NOWAIT);
- if (da->x_tbl == NULL)
+ if (da->x_tbl == NULL) {
+ FIB_PRINTF(LOG_NOTICE, da->fd,
+ "Unable to allocate DXR extension table");
return;
+ }
trie_rebuild = 1;
}
#endif
- da->fd = dxr->fd;
microuptime(&t0);
@@ -1039,8 +1050,11 @@ dxr2_try_squeeze:
#endif
dxr->d = malloc(dxr_tot_size, M_DXRLPM, M_NOWAIT);
- if (dxr->d == NULL)
+ if (dxr->d == NULL) {
+ FIB_PRINTF(LOG_NOTICE, da->fd,
+ "Unable to allocate DXR lookup table");
return;
+ }
#ifdef DXR2
memcpy(dxr->d, da->d_tbl, d_size);
dxr->x = ((char *) dxr->d) + d_size;
@@ -1098,7 +1112,7 @@ dxr2_try_squeeze:
}
/*
- * Glue functions for attaching to FreeBSD 13 fib_algo infrastructure.
+ * Glue functions for attaching to the FIB_ALGO infrastructure.
*/
static struct nhop_object *
@@ -1118,8 +1132,11 @@ dxr_init(uint32_t fibnum, struct fib_data *fd, void *old_data, void **data)
struct dxr *dxr;
dxr = malloc(sizeof(*dxr), M_DXRAUX, M_NOWAIT);
- if (dxr == NULL)
+ if (dxr == NULL) {
+ FIB_PRINTF(LOG_NOTICE, fd,
+ "Unable to allocate DXR container struct");
return (FLM_REBUILD);
+ }
/* Check whether we may reuse the old auxiliary structures */
if (old_dxr != NULL && old_dxr->aux != NULL) {
@@ -1140,14 +1157,11 @@ static void
dxr_destroy(void *data)
{
struct dxr *dxr = data;
- struct dxr_aux *da;
+ struct dxr_aux *da = dxr->aux;
struct chunk_desc *cdp;
struct trie_desc *tp;
- if (dxr->d != NULL)
- free(dxr->d, M_DXRLPM);
-
- da = dxr->aux;
+ free(dxr->d, M_DXRLPM);
free(dxr, M_DXRAUX);
if (da == NULL || atomic_fetchadd_int(&da->refcnt, -1) > 1)
@@ -1213,17 +1227,12 @@ dxr_dump_end(void *data, struct fib_dp *dp)
dxr_build(dxr);
da = dxr->aux;
- if (da == NULL)
+ if (da == NULL || dxr->d == NULL)
return (FLM_REBUILD);
- /* Structural limit exceeded, hard error */
if (da->rtbl_top >= BASE_MAX)
return (FLM_ERROR);
- /* A malloc(,, M_NOWAIT) failed somewhere, retry later */
- if (dxr->d == NULL)
- return (FLM_REBUILD);
-
dp->f = choose_lookup_fn(da);
dp->arg = dxr;
@@ -1260,13 +1269,14 @@ dxr_change_rib_batch(struct rib_head *rnh, struct fib_change_queue *q,
int update_delta = 0;
#endif
- KASSERT(data != NULL, ("%s: NULL data", __FUNCTION__));
- KASSERT(q != NULL, ("%s: NULL q", __FUNCTION__));
- KASSERT(q->count < q->size, ("%s: q->count %d q->size %d",
- __FUNCTION__, q->count, q->size));
+ MPASS(data != NULL);
+ MPASS(q != NULL);
+ MPASS(q->count < q->size);
da = dxr->aux;
- KASSERT(da != NULL, ("%s: NULL dxr->aux", __FUNCTION__));
+ MPASS(da != NULL);
+ MPASS(da->fd != NULL);
+ MPASS(da->refcnt > 0);
FIB_PRINTF(LOG_INFO, da->fd, "processing %d update(s)", q->count);
for (ui = 0; ui < q->count; ui++) {
@@ -1299,8 +1309,7 @@ dxr_change_rib_batch(struct rib_head *rnh, struct fib_change_queue *q,
#ifdef INVARIANTS
fib_get_rtable_info(fib_get_rh(da->fd), &rinfo);
- KASSERT(da->prefixes + update_delta == rinfo.num_prefixes,
- ("%s: update count mismatch", __FUNCTION__));
+ MPASS(da->prefixes + update_delta == rinfo.num_prefixes);
#endif
res = dxr_init(0, dxr->fd, data, (void **) &new_dxr);
@@ -1310,12 +1319,9 @@ dxr_change_rib_batch(struct rib_head *rnh, struct fib_change_queue *q,
dxr_build(new_dxr);
/* Structural limit exceeded, hard error */
- if (da->rtbl_top >= BASE_MAX) {
- dxr_destroy(new_dxr);
+ if (da->rtbl_top >= BASE_MAX)
return (FLM_ERROR);
- }
- /* A malloc(,, M_NOWAIT) failed somewhere, retry later */
if (new_dxr->d == NULL) {
dxr_destroy(new_dxr);
return (FLM_REBUILD);
@@ -1329,6 +1335,7 @@ dxr_change_rib_batch(struct rib_head *rnh, struct fib_change_queue *q,
return (FLM_SUCCESS);
}
+ FIB_PRINTF(LOG_NOTICE, dxr->fd, "fib_set_datapath_ptr() failed");
dxr_destroy(new_dxr);
return (FLM_REBUILD);
}
diff --git a/sys/netinet/in_pcb.c b/sys/netinet/in_pcb.c
index 95e162e60f53..0fffd285fb17 100644
--- a/sys/netinet/in_pcb.c
+++ b/sys/netinet/in_pcb.c
@@ -657,6 +657,10 @@ in_pcballoc(struct socket *so, struct inpcbinfo *pcbinfo)
#if defined(IPSEC) || defined(IPSEC_SUPPORT) || defined(MAC)
out:
+ crfree(inp->inp_cred);
+#ifdef INVARIANTS
+ inp->inp_cred = NULL;
+#endif
uma_zfree_smr(pcbinfo->ipi_zone, inp);
return (error);
#endif
diff --git a/sys/netinet/ip_fw.h b/sys/netinet/ip_fw.h
index 2b59e46b5bcc..937dc8fbbbc2 100644
--- a/sys/netinet/ip_fw.h
+++ b/sys/netinet/ip_fw.h
@@ -979,7 +979,7 @@ typedef struct _ipfw_range_tlv {
#define IPFW_RCFLAG_USER (IPFW_RCFLAG_RANGE | IPFW_RCFLAG_ALL | \
IPFW_RCFLAG_SET | IPFW_RCFLAG_DYNAMIC)
/* Internally used flags */
-#define IPFW_RCFLAG_DEFAULT 0x0100 /* Do not skip defaul rule */
+#define IPFW_RCFLAG_DEFAULT 0x0100 /* Do not skip default rule */
typedef struct _ipfw_ta_tinfo {
uint32_t flags; /* Format flags */
diff --git a/sys/netinet6/in6.h b/sys/netinet6/in6.h
index 78c9cd56ed60..ce3bbea6b8e6 100644
--- a/sys/netinet6/in6.h
+++ b/sys/netinet6/in6.h
@@ -102,7 +102,13 @@ struct in6_addr {
};
#define s6_addr __u6_addr.__u6_addr8
-#if defined(_KERNEL) || defined(_STANDALONE) /* XXX nonstandard */
+#if __BSD_VISIBLE
+/*
+ * s6_addr is the only in6_addr element specified in RFCs 2553 and 3493,
+ * also in POSIX 1003.1-2017. The following three definitions were not
+ * exposed to user programs in FreeBSD before 14.1, or in other BSDs,
+ * and are thus less portable than s6_addr.
+ */
#define s6_addr8 __u6_addr.__u6_addr8
#define s6_addr16 __u6_addr.__u6_addr16
#define s6_addr32 __u6_addr.__u6_addr32
diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c
index 5fc234c5aca9..6874dd59c1f7 100644
--- a/sys/netpfil/pf/pf.c
+++ b/sys/netpfil/pf/pf.c
@@ -1325,6 +1325,7 @@ keyattach:
sk : NULL);
printf("\n");
}
+ s->timeout = PFTM_UNLINKED;
PF_HASHROW_UNLOCK(ih);
KEYS_UNLOCK();
uma_zfree(V_pf_state_key_z, sk);
@@ -1392,6 +1393,8 @@ pf_detach_state(struct pf_kstate *s)
struct pf_state_key *sks = s->key[PF_SK_STACK];
struct pf_keyhash *kh;
+ MPASS(s->timeout >= PFTM_MAX);
+
pf_sctp_multihome_detach_addr(s);
if (sks != NULL) {
@@ -1517,6 +1520,7 @@ pf_state_insert(struct pfi_kkif *kif, struct pfi_kkif *orig_kif,
break;
if (cur != NULL) {
+ s->timeout = PFTM_UNLINKED;
PF_HASHROW_UNLOCK(ih);
if (V_pf_status.debug >= PF_DEBUG_MISC) {
printf("pf: state ID collision: "
diff --git a/sys/sys/bitset.h b/sys/sys/bitset.h
index 5ff2bb76a4ab..4afac9b172e8 100644
--- a/sys/sys/bitset.h
+++ b/sys/sys/bitset.h
@@ -135,6 +135,18 @@
(d)->__bits[__i] = (s1)->__bits[__i] | (s2)->__bits[__i];\
} while (0)
+#define __BIT_ORNOT(_s, d, s) do { \
+ __size_t __i; \
+ for (__i = 0; __i < __bitset_words((_s)); __i++) \
+ (d)->__bits[__i] |= ~(s)->__bits[__i]; \
+} while (0)
+
+#define __BIT_ORNOT2(_s, d, s1, s2) do { \
+ __size_t __i; \
+ for (__i = 0; __i < __bitset_words((_s)); __i++) \
+ (d)->__bits[__i] = (s1)->__bits[__i] | ~(s2)->__bits[__i];\
+} while (0)
+
#define __BIT_AND(_s, d, s) do { \
__size_t __i; \
for (__i = 0; __i < __bitset_words((_s)); __i++) \
@@ -330,6 +342,8 @@
#define BIT_ISSET(_s, n, p) __BIT_ISSET(_s, n, p)
#define BIT_OR(_s, d, s) __BIT_OR(_s, d, s)
#define BIT_OR2(_s, d, s1, s2) __BIT_OR2(_s, d, s1, s2)
+#define BIT_ORNOT(_s, d, s) __BIT_ORNOT(_s, d, s)
+#define BIT_ORNOT2(_s, d, s1, s2) __BIT_ORNOT2(_s, d, s1, s2)
#define BIT_OR_ATOMIC(_s, d, s) __BIT_OR_ATOMIC(_s, d, s)
#define BIT_OVERLAP(_s, p, c) __BIT_OVERLAP(_s, p, c)
#define BIT_SET(_s, n, p) __BIT_SET(_s, n, p)
diff --git a/sys/sys/capsicum.h b/sys/sys/capsicum.h
index 93c5f0c9c390..e2f305462f0d 100644
--- a/sys/sys/capsicum.h
+++ b/sys/sys/capsicum.h
@@ -417,6 +417,13 @@ __END_DECLS
#ifdef _KERNEL
#include <sys/systm.h>
+#include <sys/ktrace.h>
+
+#ifdef KTRACE
+#define CAP_TRACING(td) KTRPOINT((td), KTR_CAPFAIL)
+#else
+#define CAP_TRACING(td) 0
+#endif
#define IN_CAPABILITY_MODE(td) (((td)->td_ucred->cr_flags & CRED_FLAG_CAPMODE) != 0)
diff --git a/sys/sys/cpuset.h b/sys/sys/cpuset.h
index 219e190f0b37..b036b45da283 100644
--- a/sys/sys/cpuset.h
+++ b/sys/sys/cpuset.h
@@ -56,6 +56,7 @@
#define CPU_OVERLAP(p, c) __BIT_OVERLAP(CPU_SETSIZE, p, c)
#define CPU_CMP(p, c) __BIT_CMP(CPU_SETSIZE, p, c)
#define CPU_OR(d, s1, s2) __BIT_OR2(CPU_SETSIZE, d, s1, s2)
+#define CPU_ORNOT(d, s1, s2) __BIT_ORNOT2(CPU_SETSIZE, d, s1, s2)
#define CPU_AND(d, s1, s2) __BIT_AND2(CPU_SETSIZE, d, s1, s2)
#define CPU_ANDNOT(d, s1, s2) __BIT_ANDNOT2(CPU_SETSIZE, d, s1, s2)
#define CPU_XOR(d, s1, s2) __BIT_XOR2(CPU_SETSIZE, d, s1, s2)
diff --git a/sys/sys/domainset.h b/sys/sys/domainset.h
index 42891263b81b..f98b175e9bc8 100644
--- a/sys/sys/domainset.h
+++ b/sys/sys/domainset.h
@@ -54,6 +54,7 @@
#define DOMAINSET_OVERLAP(p, c) __BIT_OVERLAP(DOMAINSET_SETSIZE, p, c)
#define DOMAINSET_CMP(p, c) __BIT_CMP(DOMAINSET_SETSIZE, p, c)
#define DOMAINSET_OR(d, s) __BIT_OR(DOMAINSET_SETSIZE, d, s)
+#define DOMAINSET_ORNOT(d, s) __BIT_ORNOT(DOMAINSET_SETSIZE, d, s)
#define DOMAINSET_AND(d, s) __BIT_AND(DOMAINSET_SETSIZE, d, s)
#define DOMAINSET_ANDNOT(d, s) __BIT_ANDNOT(DOMAINSET_SETSIZE, d, s)
#define DOMAINSET_CLR_ATOMIC(n, p) __BIT_CLR_ATOMIC(DOMAINSET_SETSIZE, n, p)
diff --git a/sys/sys/ktrace.h b/sys/sys/ktrace.h
index 594f912b02ef..6d8280c415a6 100644
--- a/sys/sys/ktrace.h
+++ b/sys/sys/ktrace.h
@@ -34,8 +34,10 @@
#ifndef _SYS_KTRACE_H_
#define _SYS_KTRACE_H_
+#include <sys/param.h>
#include <sys/caprights.h>
#include <sys/signal.h>
+#include <sys/socket.h>
#include <sys/_uio.h>
/*
@@ -207,16 +209,31 @@ struct ktr_proc_ctor {
* KTR_CAPFAIL - trace capability check failures
*/
#define KTR_CAPFAIL 12
-enum ktr_cap_fail_type {
+enum ktr_cap_violation {
CAPFAIL_NOTCAPABLE, /* insufficient capabilities in cap_check() */
- CAPFAIL_INCREASE, /* attempt to increase capabilities */
+ CAPFAIL_INCREASE, /* attempt to increase rights on a capability */
CAPFAIL_SYSCALL, /* disallowed system call */
- CAPFAIL_LOOKUP, /* disallowed VFS lookup */
+ CAPFAIL_SIGNAL, /* sent signal to process other than self */
+ CAPFAIL_PROTO, /* disallowed protocol */
+ CAPFAIL_SOCKADDR, /* restricted address lookup */
+ CAPFAIL_NAMEI, /* restricted namei lookup */
+ CAPFAIL_CPUSET, /* restricted CPU set modification */
};
+
+union ktr_cap_data {
+ cap_rights_t cap_rights[2];
+#define cap_needed cap_rights[0]
+#define cap_held cap_rights[1]
+ int cap_int;
+ struct sockaddr cap_sockaddr;
+ char cap_path[MAXPATHLEN];
+};
+
struct ktr_cap_fail {
- enum ktr_cap_fail_type cap_type;
- cap_rights_t cap_needed;
- cap_rights_t cap_held;
+ enum ktr_cap_violation cap_type;
+ short cap_code;
+ u_int cap_svflags;
+ union ktr_cap_data cap_data;
};
/*
@@ -319,8 +336,7 @@ void ktruserret(struct thread *);
void ktrstruct(const char *, const void *, size_t);
void ktrstruct_error(const char *, const void *, size_t, int);
void ktrstructarray(const char *, enum uio_seg, const void *, int, size_t);
-void ktrcapfail(enum ktr_cap_fail_type, const cap_rights_t *,
- const cap_rights_t *);
+void ktrcapfail(enum ktr_cap_violation, const void *);
#define ktrcaprights(s) \
ktrstruct("caprights", (s), sizeof(cap_rights_t))
#define ktritimerval(s) \
diff --git a/sys/sys/namei.h b/sys/sys/namei.h
index 8ffa87aa3d7e..f6279700e735 100644
--- a/sys/sys/namei.h
+++ b/sys/sys/namei.h
@@ -198,8 +198,12 @@ int cache_fplookup(struct nameidata *ndp, enum cache_fpl_status *status,
/*
* Flags in ni_lcf, valid for the duration of the namei call.
*/
-#define NI_LCF_STRICTRELATIVE 0x0001 /* relative lookup only */
+#define NI_LCF_STRICTREL 0x0001 /* relative lookup only */
#define NI_LCF_CAP_DOTDOT 0x0002 /* ".." in strictrelative case */
+/* Track capability restrictions seperately for violation ktracing. */
+#define NI_LCF_STRICTREL_KTR 0x0004 /* trace relative lookups */
+#define NI_LCF_CAP_DOTDOT_KTR 0x0008 /* ".." in strictrelative case */
+#define NI_LCF_KTR_FLAGS (NI_LCF_STRICTREL_KTR | NI_LCF_CAP_DOTDOT_KTR)
/*
* Initialization of a nameidata structure.
diff --git a/sys/sys/sdt.h b/sys/sys/sdt.h
index ba3dcfa15762..20be685ad081 100644
--- a/sys/sys/sdt.h
+++ b/sys/sys/sdt.h
@@ -147,36 +147,41 @@ SET_DECLARE(sdt_providers_set, struct sdt_provider);
SET_DECLARE(sdt_probes_set, struct sdt_probe);
SET_DECLARE(sdt_argtypes_set, struct sdt_argtype);
+#define _SDT_PROBE_NAME(prov, mod, func, name) \
+ sdt_##prov##_##mod##_##func##_##name
+#define _SDT_PROVIDER_NAME(prov) \
+ sdt_provider_##prov
+
#define SDT_PROVIDER_DEFINE(_prov) \
- struct sdt_provider sdt_provider_##_prov[1] = { \
+ struct sdt_provider _SDT_PROVIDER_NAME(_prov)[1] = { \
[0] = { .name = #_prov }, \
}; \
- DATA_SET(sdt_providers_set, sdt_provider_##_prov);
+ DATA_SET(sdt_providers_set, _SDT_PROVIDER_NAME(_prov))
-#define SDT_PROVIDER_DECLARE(prov) \
- extern struct sdt_provider sdt_provider_##prov[1]
+#define SDT_PROVIDER_DECLARE(prov) \
+ extern struct sdt_provider _SDT_PROVIDER_NAME(prov)[1]
#define SDT_PROBE_DEFINE(_prov, _mod, _func, _name) \
- struct sdt_probe sdt_##_prov##_##_mod##_##_func##_##_name[1] = {\
+ struct sdt_probe _SDT_PROBE_NAME(_prov, _mod, _func, _name)[1] = { \
[0] = { \
.version = sizeof(struct sdt_probe), \
- .prov = sdt_provider_##_prov, \
+ .prov = _SDT_PROVIDER_NAME(_prov), \
.mod = #_mod, \
.func = #_func, \
.name = #_name, \
}, \
}; \
- DATA_SET(sdt_probes_set, sdt_##_prov##_##_mod##_##_func##_##_name)
+ DATA_SET(sdt_probes_set, _SDT_PROBE_NAME(_prov, _mod, _func, _name))
-#define SDT_PROBE_DECLARE(prov, mod, func, name) \
- extern struct sdt_probe sdt_##prov##_##mod##_##func##_##name[1]
+#define SDT_PROBE_DECLARE(prov, mod, func, name) \
+ extern struct sdt_probe _SDT_PROBE_NAME(prov, mod, func, name)[1]
#define SDT_PROBES_ENABLED() __predict_false(sdt_probes_enabled)
#define SDT_PROBE(prov, mod, func, name, arg0, arg1, arg2, arg3, arg4) do { \
if (SDT_PROBES_ENABLED()) { \
- if (__predict_false(sdt_##prov##_##mod##_##func##_##name->id)) \
- (*sdt_probe_func)(sdt_##prov##_##mod##_##func##_##name->id, \
+ if (__predict_false(_SDT_PROBE_NAME(prov, mod, func, name)->id)) \
+ (*sdt_probe_func)(_SDT_PROBE_NAME(prov, mod, func, name)->id, \
(uintptr_t) arg0, (uintptr_t) arg1, (uintptr_t) arg2, \
(uintptr_t) arg3, (uintptr_t) arg4); \
} \
@@ -189,7 +194,7 @@ SET_DECLARE(sdt_argtypes_set, struct sdt_argtype);
.ndx = _num, \
.type = _type, \
.xtype = _xtype, \
- .probe = sdt_##_prov##_##_mod##_##_func##_##_name, \
+ .probe = _SDT_PROBE_NAME(_prov, _mod, _func, _name), \
}, \
}; \
DATA_SET(sdt_argtypes_set, \
@@ -322,21 +327,21 @@ SET_DECLARE(sdt_argtypes_set, struct sdt_argtype);
SDT_PROBE(prov, mod, func, name, arg0, arg1, arg2, arg3, arg4)
#define SDT_PROBE6(prov, mod, func, name, arg0, arg1, arg2, arg3, arg4, arg5) \
do { \
- if (sdt_##prov##_##mod##_##func##_##name->id) \
+ if (_SDT_PROBE_NAME(prov, mod, func, name)->id) \
(*(void (*)(uint32_t, uintptr_t, uintptr_t, uintptr_t, \
uintptr_t, uintptr_t, uintptr_t))sdt_probe_func)( \
- sdt_##prov##_##mod##_##func##_##name->id, \
+ _SDT_PROBE_NAME(prov, mod, func, name)->id, \
(uintptr_t)arg0, (uintptr_t)arg1, (uintptr_t)arg2, \
(uintptr_t)arg3, (uintptr_t)arg4, (uintptr_t)arg5);\
} while (0)
#define SDT_PROBE7(prov, mod, func, name, arg0, arg1, arg2, arg3, arg4, arg5, \
arg6) \
do { \
- if (sdt_##prov##_##mod##_##func##_##name->id) \
+ if (_SDT_PROBE_NAME(prov, mod, func, name)->id) \
(*(void (*)(uint32_t, uintptr_t, uintptr_t, uintptr_t, \
uintptr_t, uintptr_t, uintptr_t, uintptr_t)) \
sdt_probe_func)( \
- sdt_##prov##_##mod##_##func##_##name->id, \
+ _SDT_PROBE_NAME(prov, mod, func, name)->id, \
(uintptr_t)arg0, (uintptr_t)arg1, (uintptr_t)arg2, \
(uintptr_t)arg3, (uintptr_t)arg4, (uintptr_t)arg5, \
(uintptr_t)arg6); \
diff --git a/sys/sys/soundcard.h b/sys/sys/soundcard.h
index ddd8a51d29a5..b5434b930215 100644
--- a/sys/sys/soundcard.h
+++ b/sys/sys/soundcard.h
@@ -1878,7 +1878,7 @@ typedef struct oss_audioinfo
int card_number;
int port_number;
int mixer_dev;
- int real_device; /* Obsolete field. Replaced by devnode */
+ int legacy_device; /* Obsolete field. Replaced by devnode */
int enabled; /* 1=enabled, 0=device not ready at this
moment */
int flags; /* For internal use only - no practical
@@ -1925,7 +1925,9 @@ typedef struct oss_mixerinfo
* as the default mixer.
*/
int priority;
- int filler[254]; /* Reserved */
+ oss_devnode_t devnode;
+ int legacy_device;
+ int filler[245]; /* Reserved */
} oss_mixerinfo;
typedef struct oss_midi_info
diff --git a/sys/x86/include/apicvar.h b/sys/x86/include/apicvar.h
index 10016e291b9b..ac6a82659e34 100644
--- a/sys/x86/include/apicvar.h
+++ b/sys/x86/include/apicvar.h
@@ -78,7 +78,12 @@
#define MAX_APIC_ID 0x800
#define APIC_ID_ALL 0xffffffff
-#define IOAPIC_MAX_ID xAPIC_MAX_APIC_ID
+/*
+ * The 0xff ID is used for broadcast IPIs for local APICs when not using
+ * x2APIC. IPIs are not sent to I/O APICs so it's acceptable for an I/O APIC
+ * to use that ID.
+ */
+#define IOAPIC_MAX_ID 0xff
/* I/O Interrupts are used for external devices such as ISA, PCI, etc. */
#define APIC_IO_INTS (IDT_IO_INTS + 16)
diff --git a/tests/sys/kern/Makefile b/tests/sys/kern/Makefile
index b95be12d9665..d78c761feaac 100644
--- a/tests/sys/kern/Makefile
+++ b/tests/sys/kern/Makefile
@@ -21,6 +21,7 @@ ATF_TESTS_C+= kill_zombie
.if ${MK_OPENSSL} != "no"
ATF_TESTS_C+= ktls_test
.endif
+ATF_TESTS_C+= ktrace_test
ATF_TESTS_C+= module_test
ATF_TESTS_C+= ptrace_test
TEST_METADATA.ptrace_test+= timeout="15"
@@ -79,6 +80,7 @@ LIBADD.socket_msg_waitall+= pthread
LIBADD.sendfile_helper+= pthread
LIBADD.fdgrowtable_test+= util pthread kvm procstat
LIBADD.sigwait+= rt
+LIBADD.ktrace_test+= sysdecode
NETBSD_ATF_TESTS_C+= lockf_test
NETBSD_ATF_TESTS_C+= mqueue_test
diff --git a/tests/sys/kern/ktrace_test.c b/tests/sys/kern/ktrace_test.c
new file mode 100644
index 000000000000..21868441c687
--- /dev/null
+++ b/tests/sys/kern/ktrace_test.c
@@ -0,0 +1,522 @@
+/*-
+ * Copyright (c) 2015 John Baldwin <jhb@FreeBSD.org>
+ * Copyright (c) 2023 The FreeBSD Foundation
+ *
+ * This software was developed by Jake Freeland <jfree@FreeBSD.org>
+ * 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 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/param.h>
+#include <sys/capsicum.h>
+#include <sys/cpuset.h>
+#include <sys/ktrace.h>
+#include <sys/mman.h>
+#include <sys/socket.h>
+#include <sys/sysent.h>
+#include <sys/time.h>
+#include <sys/uio.h>
+#include <sys/user.h>
+#include <sys/wait.h>
+
+#include <machine/sysarch.h>
+#include <netinet/in.h>
+
+#include <atf-c.h>
+#include <capsicum_helpers.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <netdb.h>
+#include <signal.h>
+#include <sysdecode.h>
+
+/*
+ * A variant of ATF_REQUIRE that is suitable for use in child
+ * processes. This only works if the parent process is tripped up by
+ * the early exit and fails some requirement itself.
+ */
+#define CHILD_REQUIRE(exp) do { \
+ if (!(exp)) \
+ child_fail_require(__FILE__, __LINE__, \
+ #exp " not met\n"); \
+} while (0)
+#define CHILD_REQUIRE_EQ(actual, expected) do { \
+ __typeof__(expected) _e = expected; \
+ __typeof__(actual) _a = actual; \
+ if (_e != _a) \
+ child_fail_require(__FILE__, __LINE__, #actual \
+ " (%jd) == " #expected " (%jd) not met\n", \
+ (intmax_t)_a, (intmax_t)_e); \
+} while (0)
+
+static __dead2 void
+child_fail_require(const char *file, int line, const char *fmt, ...)
+{
+ va_list ap;
+ char buf[1024];
+
+ /* Use write() not fprintf() to avoid possible duplicate output. */
+ snprintf(buf, sizeof(buf), "%s:%d: ", file, line);
+ write(STDERR_FILENO, buf, strlen(buf));
+ va_start(ap, fmt);
+ vsnprintf(buf, sizeof(buf), fmt, ap);
+ write(STDERR_FILENO, buf, strlen(buf));
+ va_end(ap);
+
+ _exit(32);
+}
+
+/*
+ * Determine sysdecode ABI based on proc's ABI in sv_flags.
+ */
+static enum sysdecode_abi
+syscallabi(u_int sv_flags)
+{
+ switch (sv_flags & SV_ABI_MASK) {
+ case SV_ABI_FREEBSD:
+ return (SYSDECODE_ABI_FREEBSD);
+ case SV_ABI_LINUX:
+#ifdef __LP64__
+ if ((sv_flags & SV_ILP32) != 0)
+ return (SYSDECODE_ABI_LINUX32);
+#endif
+ return (SYSDECODE_ABI_LINUX);
+ }
+ return (SYSDECODE_ABI_UNKNOWN);
+}
+
+/*
+ * Start tracing capability violations and notify child that it can execute.
+ * Return @numv capability violations from child in @v.
+ */
+static void
+cap_trace_child(int cpid, struct ktr_cap_fail *v, int numv)
+{
+ struct ktr_header header;
+ int error, fd, i;
+
+ ATF_REQUIRE((fd = open("ktrace.out",
+ O_RDONLY | O_CREAT | O_TRUNC)) != -1);
+ ATF_REQUIRE(ktrace("ktrace.out", KTROP_SET,
+ KTRFAC_CAPFAIL, cpid) != -1);
+ /* Notify child that we've starting tracing. */
+ ATF_REQUIRE(kill(cpid, SIGUSR1) != -1);
+ /* Wait for child to raise violation and exit. */
+ ATF_REQUIRE(waitpid(cpid, &error, 0) != -1);
+ ATF_REQUIRE(WIFEXITED(error));
+ ATF_REQUIRE_EQ(WEXITSTATUS(error), 0);
+ /* Read ktrace header and ensure violation occurred. */
+ for (i = 0; i < numv; ++i) {
+ ATF_REQUIRE((error = read(fd, &header, sizeof(header))) != -1);
+ ATF_REQUIRE_EQ(error, sizeof(header));
+ ATF_REQUIRE_EQ(header.ktr_len, sizeof(*v));
+ ATF_REQUIRE_EQ(header.ktr_pid, cpid);
+ /* Read the capability violation. */
+ ATF_REQUIRE((error = read(fd, v + i,
+ sizeof(*v))) != -1);
+ ATF_REQUIRE_EQ(error, sizeof(*v));
+ }
+ ATF_REQUIRE(close(fd) != -1);
+}
+
+/*
+ * Test if ktrace will record an operation that is done with
+ * insufficient rights.
+ */
+ATF_TC_WITHOUT_HEAD(ktrace__cap_not_capable);
+ATF_TC_BODY(ktrace__cap_not_capable, tc)
+{
+ struct ktr_cap_fail violation;
+ cap_rights_t rights;
+ sigset_t set = { };
+ pid_t pid;
+ int error;
+
+ /* Block SIGUSR1 so child does not terminate. */
+ ATF_REQUIRE(sigaddset(&set, SIGUSR1) != -1);
+ ATF_REQUIRE(sigprocmask(SIG_BLOCK, &set, NULL) != -1);
+
+ ATF_REQUIRE((pid = fork()) != -1);
+ if (pid == 0) {
+ /* Limit fd rights to CAP_READ. */
+ cap_rights_init(&rights, CAP_READ);
+ CHILD_REQUIRE(caph_rights_limit(STDIN_FILENO, &rights) != -1);
+ CHILD_REQUIRE(caph_enter() != -1);
+ /* Wait until ktrace has started. */
+ CHILD_REQUIRE(sigwait(&set, &error) != -1);
+ CHILD_REQUIRE_EQ(error, SIGUSR1);
+ /* Write without CAP_WRITE. */
+ CHILD_REQUIRE(write(STDIN_FILENO, &pid, sizeof(pid)) == -1);
+ CHILD_REQUIRE_EQ(errno, ENOTCAPABLE);
+ exit(0);
+ }
+
+ cap_trace_child(pid, &violation, 1);
+ ATF_REQUIRE_EQ(violation.cap_type, CAPFAIL_NOTCAPABLE);
+ ATF_REQUIRE(cap_rights_is_set(&violation.cap_data.cap_needed,
+ CAP_WRITE));
+}
+
+/*
+ * Test if ktrace will record an attempt to increase rights.
+ */
+ATF_TC_WITHOUT_HEAD(ktrace__cap_increase_rights);
+ATF_TC_BODY(ktrace__cap_increase_rights, tc)
+{
+ struct ktr_cap_fail violation;
+ cap_rights_t rights;
+ sigset_t set = { };
+ pid_t pid;
+ int error;
+
+ /* Block SIGUSR1 so child does not terminate. */
+ ATF_REQUIRE(sigaddset(&set, SIGUSR1) != -1);
+ ATF_REQUIRE(sigprocmask(SIG_BLOCK, &set, NULL) != -1);
+
+ ATF_REQUIRE((pid = fork()) != -1);
+ if (pid == 0) {
+ /* Limit fd rights to CAP_READ. */
+ cap_rights_init(&rights, CAP_READ);
+ CHILD_REQUIRE(caph_rights_limit(STDIN_FILENO, &rights) != -1);
+ CHILD_REQUIRE(caph_enter() != -1);
+ /* Wait until ktrace has started. */
+ CHILD_REQUIRE(sigwait(&set, &error) != -1);
+ CHILD_REQUIRE_EQ(error, SIGUSR1);
+ /* Increase fd rights to include CAP_WRITE. */
+ cap_rights_set(&rights, CAP_WRITE);
+ CHILD_REQUIRE(caph_rights_limit(STDIN_FILENO, &rights) == -1);
+ CHILD_REQUIRE_EQ(errno, ENOTCAPABLE);
+ exit(0);
+ }
+
+ cap_trace_child(pid, &violation, 1);
+ ATF_REQUIRE_EQ(violation.cap_type, CAPFAIL_INCREASE);
+ ATF_REQUIRE(cap_rights_is_set(&violation.cap_data.cap_needed,
+ CAP_WRITE));
+}
+
+/*
+ * Test if disallowed syscalls are reported as capability violations.
+ */
+ATF_TC_WITHOUT_HEAD(ktrace__cap_syscall);
+ATF_TC_BODY(ktrace__cap_syscall, tc)
+{
+ struct kinfo_file kinf;
+ struct ktr_cap_fail violation[2];
+ sigset_t set = { };
+ pid_t pid;
+ int error;
+
+ /* Block SIGUSR1 so child does not terminate. */
+ ATF_REQUIRE(sigaddset(&set, SIGUSR1) != -1);
+ ATF_REQUIRE(sigprocmask(SIG_BLOCK, &set, NULL) != -1);
+
+ ATF_REQUIRE((pid = fork()) != -1);
+ if (pid == 0) {
+ /* Wait until ktrace has started. */
+ CHILD_REQUIRE(sigwait(&set, &error) != -1);
+ CHILD_REQUIRE_EQ(error, SIGUSR1);
+ /* chdir() is not permitted in capability mode. */
+ CHILD_REQUIRE(chdir(".") != -1);
+ kinf.kf_structsize = sizeof(struct kinfo_file);
+ /*
+ * fcntl() is permitted in capability mode,
+ * but the F_KINFO cmd is not.
+ */
+ CHILD_REQUIRE(fcntl(STDIN_FILENO, F_KINFO, &kinf) != -1);
+ exit(0);
+ }
+
+ cap_trace_child(pid, violation, 2);
+ ATF_REQUIRE_EQ(violation[0].cap_type, CAPFAIL_SYSCALL);
+ error = syscallabi(violation[0].cap_svflags);
+ ATF_REQUIRE_STREQ(sysdecode_syscallname(error, violation[0].cap_code),
+ "chdir");
+
+ ATF_REQUIRE_EQ(violation[1].cap_type, CAPFAIL_SYSCALL);
+ error = syscallabi(violation[1].cap_svflags);
+ ATF_REQUIRE_STREQ(sysdecode_syscallname(error, violation[1].cap_code),
+ "fcntl");
+ ATF_REQUIRE_EQ(violation[1].cap_data.cap_int, F_KINFO);
+}
+
+/*
+ * Test if sending a signal to another process is reported as
+ * a signal violation.
+ */
+ATF_TC_WITHOUT_HEAD(ktrace__cap_signal);
+ATF_TC_BODY(ktrace__cap_signal, tc)
+{
+ struct ktr_cap_fail violation;
+ sigset_t set = { };
+ pid_t pid;
+ int error;
+
+ /* Block SIGUSR1 so child does not terminate. */
+ ATF_REQUIRE(sigaddset(&set, SIGUSR1) != -1);
+ ATF_REQUIRE(sigprocmask(SIG_BLOCK, &set, NULL) != -1);
+
+ ATF_REQUIRE((pid = fork()) != -1);
+ if (pid == 0) {
+ /* Wait until ktrace has started. */
+ CHILD_REQUIRE(sigwait(&set, &error) != -1);
+ CHILD_REQUIRE_EQ(error, SIGUSR1);
+ /*
+ * Signals may only be sent to ourself. Sending signals
+ * to other processes is not allowed in capability mode.
+ */
+ CHILD_REQUIRE(kill(getppid(), SIGCONT) != -1);
+ exit(0);
+ }
+
+ cap_trace_child(pid, &violation, 1);
+ ATF_REQUIRE_EQ(violation.cap_type, CAPFAIL_SIGNAL);
+ error = syscallabi(violation.cap_svflags);
+ ATF_REQUIRE_STREQ(sysdecode_syscallname(error, violation.cap_code),
+ "kill");
+ ATF_REQUIRE_EQ(violation.cap_data.cap_int, SIGCONT);
+}
+
+/*
+ * Test if opening a socket with a restricted protocol is reported
+ * as a protocol violation.
+ */
+ATF_TC_WITHOUT_HEAD(ktrace__cap_proto);
+ATF_TC_BODY(ktrace__cap_proto, tc)
+{
+ struct ktr_cap_fail violation;
+ sigset_t set = { };
+ pid_t pid;
+ int error;
+
+ /* Block SIGUSR1 so child does not terminate. */
+ ATF_REQUIRE(sigaddset(&set, SIGUSR1) != -1);
+ ATF_REQUIRE(sigprocmask(SIG_BLOCK, &set, NULL) != -1);
+
+ ATF_REQUIRE((pid = fork()) != -1);
+ if (pid == 0) {
+ /* Wait until ktrace has started. */
+ CHILD_REQUIRE(sigwait(&set, &error) != -1);
+ CHILD_REQUIRE_EQ(error, SIGUSR1);
+ /*
+ * Certain protocols may not be used in capability mode.
+ * ICMP's raw-protocol interface is not allowed.
+ */
+ CHILD_REQUIRE(close(socket(AF_INET, SOCK_RAW,
+ IPPROTO_ICMP)) != -1);
+ exit(0);
+ }
+
+ cap_trace_child(pid, &violation, 1);
+ ATF_REQUIRE_EQ(violation.cap_type, CAPFAIL_PROTO);
+ error = syscallabi(violation.cap_svflags);
+ ATF_REQUIRE_STREQ(sysdecode_syscallname(error, violation.cap_code),
+ "socket");
+ ATF_REQUIRE_EQ(violation.cap_data.cap_int, IPPROTO_ICMP);
+}
+
+/*
+ * Test if sending data to an address using a socket is
+ * reported as a sockaddr violation.
+ */
+ATF_TC_WITHOUT_HEAD(ktrace__cap_sockaddr);
+ATF_TC_BODY(ktrace__cap_sockaddr, tc)
+{
+ struct sockaddr_in addr = { }, *saddr;
+ struct ktr_cap_fail violation;
+ sigset_t set = { };
+ pid_t pid;
+ int error, sfd;
+
+ /* Block SIGUSR1 so child does not terminate. */
+ ATF_REQUIRE(sigaddset(&set, SIGUSR1) != -1);
+ ATF_REQUIRE(sigprocmask(SIG_BLOCK, &set, NULL) != -1);
+
+ CHILD_REQUIRE((sfd = socket(AF_INET, SOCK_DGRAM,
+ IPPROTO_UDP)) != -1);
+ addr.sin_family = AF_INET;
+ addr.sin_port = htons(5000);
+ addr.sin_addr.s_addr = INADDR_ANY;
+ CHILD_REQUIRE(bind(sfd, (const struct sockaddr *)&addr,
+ sizeof(addr)) != -1);
+
+ ATF_REQUIRE((pid = fork()) != -1);
+ if (pid == 0) {
+ /* Wait until ktrace has started. */
+ CHILD_REQUIRE(sigwait(&set, &error) != -1);
+ CHILD_REQUIRE_EQ(error, SIGUSR1);
+ /*
+ * Sending data to an address is not permitted.
+ * In this case, sending data to @addr causes a
+ * violation.
+ */
+ CHILD_REQUIRE(sendto(sfd, NULL, 0, 0,
+ (const struct sockaddr *)&addr, sizeof(addr)) != -1);
+ exit(0);
+ }
+
+ cap_trace_child(pid, &violation, 1);
+ ATF_REQUIRE_EQ(violation.cap_type, CAPFAIL_SOCKADDR);
+ error = syscallabi(violation.cap_svflags);
+ ATF_REQUIRE_STREQ(sysdecode_syscallname(error, violation.cap_code),
+ "sendto");
+ saddr = (struct sockaddr_in *)&violation.cap_data.cap_sockaddr;
+ ATF_REQUIRE_EQ(saddr->sin_family, AF_INET);
+ ATF_REQUIRE_EQ(saddr->sin_port, htons(5000));
+ ATF_REQUIRE_EQ(saddr->sin_addr.s_addr, INADDR_ANY);
+ close(sfd);
+}
+
+/*
+ * Test if openat() with AT_FDCWD and absolute path are reported
+ * as namei violations.
+ */
+ATF_TC_WITHOUT_HEAD(ktrace__cap_namei);
+ATF_TC_BODY(ktrace__cap_namei, tc)
+{
+ struct ktr_cap_fail violation[2];
+ sigset_t set = { };
+ pid_t pid;
+ int error;
+
+ /* Block SIGUSR1 so child does not terminate. */
+ ATF_REQUIRE(sigaddset(&set, SIGUSR1) != -1);
+ ATF_REQUIRE(sigprocmask(SIG_BLOCK, &set, NULL) != -1);
+
+ ATF_REQUIRE((pid = fork()) != -1);
+ if (pid == 0) {
+ /* Wait until ktrace has started. */
+ CHILD_REQUIRE(sigwait(&set, &error) != -1);
+ CHILD_REQUIRE_EQ(error, SIGUSR1);
+ /*
+ * The AT_FDCWD file descriptor has not been opened
+ * and will be inaccessible in capability mode.
+ */
+ CHILD_REQUIRE(close(openat(AT_FDCWD, "ktrace.out",
+ O_RDONLY | O_CREAT)) != -1);
+ /*
+ * Absolute paths are inaccessible in capability mode.
+ */
+ CHILD_REQUIRE(close(openat(-1, "/", O_RDONLY)) != -1);
+ exit(0);
+ }
+
+ cap_trace_child(pid, violation, 2);
+ ATF_REQUIRE_EQ(violation[0].cap_type, CAPFAIL_NAMEI);
+ error = syscallabi(violation[0].cap_svflags);
+ ATF_REQUIRE_STREQ(sysdecode_syscallname(error, violation[0].cap_code),
+ "openat");
+ ATF_REQUIRE_STREQ(violation[0].cap_data.cap_path, "AT_FDCWD");
+
+ ATF_REQUIRE_EQ(violation[1].cap_type, CAPFAIL_NAMEI);
+ error = syscallabi(violation[1].cap_svflags);
+ ATF_REQUIRE_STREQ(sysdecode_syscallname(error, violation[1].cap_code),
+ "openat");
+ ATF_REQUIRE_STREQ(violation[1].cap_data.cap_path, "/");
+}
+
+/*
+ * Test if changing another process's cpu set is recorded as
+ * a cpuset violation.
+ */
+ATF_TC_WITHOUT_HEAD(ktrace__cap_cpuset);
+ATF_TC_BODY(ktrace__cap_cpuset, tc)
+{
+ struct ktr_cap_fail violation;
+ cpuset_t cpuset_mask = { };
+ sigset_t set = { };
+ pid_t pid;
+ int error;
+
+ /* Block SIGUSR1 so child does not terminate. */
+ ATF_REQUIRE(sigaddset(&set, SIGUSR1) != -1);
+ ATF_REQUIRE(sigprocmask(SIG_BLOCK, &set, NULL) != -1);
+
+ ATF_REQUIRE((pid = fork()) != -1);
+ if (pid == 0) {
+ /* Wait until ktrace has started. */
+ CHILD_REQUIRE(sigwait(&set, &error) != -1);
+ CHILD_REQUIRE_EQ(error, SIGUSR1);
+ /*
+ * Set cpu 0 affinity for parent process.
+ * Other process's cpu sets are restricted in capability
+ * mode, so this will raise a violation.
+ */
+ CPU_SET(0, &cpuset_mask);
+ CHILD_REQUIRE(cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID,
+ getppid(), sizeof(cpuset_mask), &cpuset_mask) != -1);
+ exit(0);
+ }
+
+ cap_trace_child(pid, &violation, 1);
+ ATF_REQUIRE_EQ(violation.cap_type, CAPFAIL_CPUSET);
+ error = syscallabi(violation.cap_svflags);
+ ATF_REQUIRE_STREQ(sysdecode_syscallname(error, violation.cap_code),
+ "cpuset_setaffinity");
+}
+
+ATF_TC_WITHOUT_HEAD(ktrace__cap_shm_open);
+ATF_TC_BODY(ktrace__cap_shm_open, tc)
+{
+ struct ktr_cap_fail violation;
+ sigset_t set = { };
+ pid_t pid;
+ int error;
+
+ /* Block SIGUSR1 so child does not terminate. */
+ ATF_REQUIRE(sigaddset(&set, SIGUSR1) != -1);
+ ATF_REQUIRE(sigprocmask(SIG_BLOCK, &set, NULL) != -1);
+
+ ATF_REQUIRE((pid = fork()) != -1);
+ if (pid == 0) {
+ /* Wait until ktrace has started. */
+ CHILD_REQUIRE(sigwait(&set, &error) != -1);
+ CHILD_REQUIRE_EQ(error, SIGUSR1);
+
+ CHILD_REQUIRE(shm_open("/ktrace_shm", O_RDWR | O_CREAT,
+ 0600) != -1);
+ CHILD_REQUIRE(shm_unlink("/ktrace_shm") != -1);
+ exit(0);
+ }
+
+ cap_trace_child(pid, &violation, 1);
+ ATF_REQUIRE_EQ(violation.cap_type, CAPFAIL_NAMEI);
+ error = syscallabi(violation.cap_svflags);
+ ATF_REQUIRE_STREQ(sysdecode_syscallname(error, violation.cap_code),
+ "shm_open2");
+ ATF_REQUIRE_STREQ(violation.cap_data.cap_path, "/ktrace_shm");
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, ktrace__cap_not_capable);
+ ATF_TP_ADD_TC(tp, ktrace__cap_increase_rights);
+ ATF_TP_ADD_TC(tp, ktrace__cap_syscall);
+ ATF_TP_ADD_TC(tp, ktrace__cap_signal);
+ ATF_TP_ADD_TC(tp, ktrace__cap_proto);
+ ATF_TP_ADD_TC(tp, ktrace__cap_sockaddr);
+ ATF_TP_ADD_TC(tp, ktrace__cap_namei);
+ ATF_TP_ADD_TC(tp, ktrace__cap_cpuset);
+ ATF_TP_ADD_TC(tp, ktrace__cap_shm_open);
+ return (atf_no_error());
+}
diff --git a/tools/regression/iscsi/initiator-instructions.txt b/tools/regression/iscsi/initiator-instructions.txt
index 11c3311cddb2..e99ff87fe379 100644
--- a/tools/regression/iscsi/initiator-instructions.txt
+++ b/tools/regression/iscsi/initiator-instructions.txt
@@ -3,9 +3,9 @@ How to prepare initiator virtual machines for iSCSI target testing
1. Install operating systems.
- - FreeBSD: Use default settings for everything. Don't install
- ports from the system installer, use "portsnap fetch extract"
- after installation instead.
+ - FreeBSD: Use default settings for everything. Don't install ports
+ from the system installer, fetch a new ports tree after
+ installation instead.
- Fedora: Change the environment to "Minimal install".
diff --git a/usr.bin/ctags/C.c b/usr.bin/ctags/C.c
index 25c5db5d405b..725336d33e01 100644
--- a/usr.bin/ctags/C.c
+++ b/usr.bin/ctags/C.c
@@ -43,10 +43,10 @@ static char sccsid[] = "@(#)C.c 8.4 (Berkeley) 4/2/94";
#include "ctags.h"
-static int func_entry(void);
+static bool func_entry(void);
static void hash_entry(void);
static void skip_string(int);
-static int str_entry(int);
+static bool str_entry(int);
/*
* c_entries --
@@ -58,13 +58,13 @@ c_entries(void)
int c; /* current character */
int level; /* brace level */
int token; /* if reading a token */
- int t_def; /* if reading a typedef */
+ bool t_def; /* if reading a typedef */
int t_level; /* typedef's brace level */
char *sp; /* buffer pointer */
char tok[MAXTOKEN]; /* token buffer */
lineftell = ftell(inf);
- sp = tok; token = t_def = NO; t_level = -1; level = 0; lineno = 1;
+ sp = tok; token = t_def = false; t_level = -1; level = 0; lineno = 1;
while (GETC(!=, EOF)) {
switch (c) {
/*
@@ -98,11 +98,11 @@ c_entries(void)
*/
endtok: if (sp > tok) {
*sp = EOS;
- token = YES;
+ token = true;
sp = tok;
}
else
- token = NO;
+ token = false;
continue;
/*
@@ -180,7 +180,7 @@ c_entries(void)
*/
case ';':
if (t_def && level == t_level) {
- t_def = NO;
+ t_def = false;
get_line();
if (sp != tok)
*sp = EOS;
@@ -213,7 +213,7 @@ c_entries(void)
/* no typedefs inside typedefs */
if (!t_def &&
!memcmp(tok, "typedef",8)) {
- t_def = YES;
+ t_def = true;
t_level = level;
break;
}
@@ -239,15 +239,15 @@ c_entries(void)
if (sp == tok + sizeof tok - 1)
/* Too long -- truncate it */
*sp = EOS;
- else
+ else
*sp++ = c;
- token = YES;
+ token = true;
}
continue;
}
sp = tok;
- token = NO;
+ token = false;
}
}
@@ -255,7 +255,7 @@ c_entries(void)
* func_entry --
* handle a function reference
*/
-static int
+static bool
func_entry(void)
{
int c; /* current character */
@@ -293,7 +293,7 @@ func_entry(void)
SETLINE;
}
}
- return (NO);
+ return (false);
fnd:
/*
* we assume that the character after a function's right paren
@@ -305,7 +305,7 @@ fnd:
if (c == '\n')
SETLINE;
if (c == EOF)
- return NO;
+ return false;
/*
* Recognize the gnu __attribute__ extension, which would
* otherwise make the heuristic test DTWT
@@ -317,7 +317,7 @@ fnd:
}
} else {
if (intoken(c)) {
- if (anext - maybe_attribute
+ if (anext - maybe_attribute
< (ptrdiff_t)(sizeof attribute - 1))
*anext++ = c;
else break;
@@ -326,7 +326,7 @@ fnd:
*anext++ = '\0';
if (strcmp(maybe_attribute, attribute) == 0) {
(void)ungetc(c, inf);
- return NO;
+ return false;
}
break;
}
@@ -337,12 +337,12 @@ fnd:
skip_comment(c);
else { /* don't ever "read" '/' */
(void)ungetc(c, inf);
- return (NO);
+ return (false);
}
}
if (c != '{')
(void)skip_key('{');
- return (YES);
+ return (true);
}
/*
@@ -371,7 +371,7 @@ hash_entry(void)
if (sp == tok + sizeof tok - 1)
/* Too long -- truncate it */
*sp = EOS;
- else
+ else
*sp++ = c;
}
*sp = EOS;
@@ -387,7 +387,7 @@ hash_entry(void)
if (sp == tok + sizeof tok - 1)
/* Too long -- truncate it */
*sp = EOS;
- else
+ else
*sp++ = c;
if (GETC(==, EOF))
return;
@@ -415,7 +415,7 @@ skip: if (c == '\n') { /* get rid of rest of define */
* str_entry --
* handle a struct, union or enum entry
*/
-static int
+static bool
str_entry(int c) /* c is current character */
{
int curline; /* line started on */
@@ -425,17 +425,17 @@ str_entry(int c) /* c is current character */
curline = lineno;
while (iswhite(c))
if (GETC(==, EOF))
- return (NO);
+ return (false);
if (c == '{') /* it was "struct {" */
- return (YES);
+ return (true);
for (sp = tok;;) { /* get next token */
if (sp == tok + sizeof tok - 1)
/* Too long -- truncate it */
*sp = EOS;
- else
+ else
*sp++ = c;
if (GETC(==, EOF))
- return (NO);
+ return (false);
if (!intoken(c))
break;
}
@@ -452,12 +452,12 @@ str_entry(int c) /* c is current character */
break;
if (c != '{') {
(void)ungetc(c, inf);
- return (NO);
+ return (false);
}
}
*sp = EOS;
pfnote(tok, curline);
- return (YES);
+ return (true);
}
/*
@@ -474,7 +474,7 @@ skip_comment(int t) /* t is comment character */
switch(c) {
/* comments don't nest, nor can they be escaped. */
case '*':
- star = YES;
+ star = true;
break;
case '/':
if (star && t == '*')
@@ -486,7 +486,7 @@ skip_comment(int t) /* t is comment character */
return;
/*FALLTHROUGH*/
default:
- star = NO;
+ star = false;
break;
}
}
@@ -501,7 +501,7 @@ skip_string(int key)
int c,
skip;
- for (skip = NO; GETC(!=, EOF); )
+ for (skip = false; GETC(!=, EOF); )
switch (c) {
case '\\': /* a backslash escapes anything */
skip = !skip; /* we toggle in case it's "\\" */
@@ -512,7 +512,7 @@ skip_string(int key)
default:
if (c == key && !skip)
return;
- skip = NO;
+ skip = false;
}
}
@@ -520,21 +520,21 @@ skip_string(int key)
* skip_key --
* skip to next char "key"
*/
-int
+bool
skip_key(int key)
{
- int c,
- skip,
- retval;
+ int c;
+ bool skip;
+ bool retval;
- for (skip = retval = NO; GETC(!=, EOF);)
+ for (skip = retval = false; GETC(!=, EOF);)
switch(c) {
case '\\': /* a backslash escapes anything */
skip = !skip; /* we toggle in case it's "\\" */
break;
case ';': /* special case for yacc; if one */
case '|': /* of these chars occurs, we may */
- retval = YES; /* have moved out of the rule */
+ retval = true; /* have moved out of the rule */
break; /* not used by C */
case '\'':
case '"':
@@ -557,7 +557,7 @@ skip_key(int key)
norm:
if (c == key && !skip)
return (retval);
- skip = NO;
+ skip = false;
}
return (retval);
}
diff --git a/usr.bin/ctags/ctags.c b/usr.bin/ctags/ctags.c
index 6053a52f32da..686acd0f9cdf 100644
--- a/usr.bin/ctags/ctags.c
+++ b/usr.bin/ctags/ctags.c
@@ -99,8 +99,8 @@ main(int argc, char **argv)
setlocale(LC_ALL, "");
- aflag = uflag = NO;
- tflag = YES;
+ aflag = uflag = false;
+ tflag = true;
while ((ch = getopt(argc, argv, "BFTadf:tuwvx")) != -1)
switch(ch) {
case 'B':
@@ -110,7 +110,7 @@ main(int argc, char **argv)
searchar = '/';
break;
case 'T':
- tflag = NO;
+ tflag = false;
break;
case 'a':
aflag++;
@@ -122,7 +122,7 @@ main(int argc, char **argv)
outfile = optarg;
break;
case 't':
- tflag = YES;
+ tflag = true;
break;
case 'u':
uflag++;
@@ -264,24 +264,24 @@ init(void)
const unsigned char *sp;
for (i = 0; i < 256; i++) {
- _wht[i] = _etk[i] = _itk[i] = _btk[i] = NO;
- _gd[i] = YES;
+ _wht[i] = _etk[i] = _itk[i] = _btk[i] = false;
+ _gd[i] = true;
}
#define CWHITE " \f\t\n"
for (sp = CWHITE; *sp; sp++) /* white space chars */
- _wht[*sp] = YES;
+ _wht[*sp] = true;
#define CTOKEN " \t\n\"'#()[]{}=-+%*/&|^~!<>;,.:?"
for (sp = CTOKEN; *sp; sp++) /* token ending chars */
- _etk[*sp] = YES;
+ _etk[*sp] = true;
#define CINTOK "ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz0123456789"
for (sp = CINTOK; *sp; sp++) /* valid in-token chars */
- _itk[*sp] = YES;
+ _itk[*sp] = true;
#define CBEGIN "ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz"
for (sp = CBEGIN; *sp; sp++) /* token starting chars */
- _btk[*sp] = YES;
+ _btk[*sp] = true;
#define CNOTGD ",;"
for (sp = CNOTGD; *sp; sp++) /* invalid after-function chars */
- _gd[*sp] = NO;
+ _gd[*sp] = false;
}
/*
diff --git a/usr.bin/ctags/ctags.h b/usr.bin/ctags/ctags.h
index 8892733d650f..5079353a8136 100644
--- a/usr.bin/ctags/ctags.h
+++ b/usr.bin/ctags/ctags.h
@@ -32,10 +32,9 @@
*
*/
-#define bool char
+/* This header requires bool for some externed symbols. */
+#include <stdbool.h>
-#define YES 1
-#define NO 0
#define EOS '\0'
#define ENDLINE 50 /* max length of pattern */
@@ -83,14 +82,14 @@ extern char lbuf[LINE_MAX];
extern char *lbp;
extern char searchar; /* ex search character */
-extern int cicmp(const char *);
+extern bool cicmp(const char *);
extern void get_line(void);
extern void pfnote(const char *, int);
-extern int skip_key(int);
+extern bool skip_key(int);
extern void put_entries(NODE *);
extern void toss_yysec(void);
extern void l_entries(void);
extern void y_entries(void);
-extern int PF_funcs(void);
+extern bool PF_funcs(void);
extern void c_entries(void);
extern void skip_comment(int);
diff --git a/usr.bin/ctags/fortran.c b/usr.bin/ctags/fortran.c
index 7fa6ec3823d9..56ae3b66458b 100644
--- a/usr.bin/ctags/fortran.c
+++ b/usr.bin/ctags/fortran.c
@@ -47,14 +47,14 @@ static void takeprec(void);
char *lbp; /* line buffer pointer */
-int
+bool
PF_funcs(void)
{
bool pfcnt; /* pascal/fortran functions found */
char *cp;
char tok[MAXTOKEN];
- for (pfcnt = NO;;) {
+ for (pfcnt = false;;) {
lineftell = ftell(inf);
if (!fgets(lbuf, sizeof(lbuf), inf))
return (pfcnt);
@@ -126,7 +126,7 @@ PF_funcs(void)
(void)strlcpy(tok, lbp, sizeof(tok)); /* possible trunc */
get_line(); /* process line for ex(1) */
pfnote(tok, lineno);
- pfcnt = YES;
+ pfcnt = true;
}
/*NOTREACHED*/
}
@@ -135,7 +135,7 @@ PF_funcs(void)
* cicmp --
* do case-independent strcmp
*/
-int
+bool
cicmp(const char *cp)
{
int len;
@@ -146,9 +146,9 @@ cicmp(const char *cp)
continue;
if (!*cp) {
lbp += len;
- return (YES);
+ return (true);
}
- return (NO);
+ return (false);
}
static void
diff --git a/usr.bin/ctags/lisp.c b/usr.bin/ctags/lisp.c
index d167c82e7c69..bd6100709299 100644
--- a/usr.bin/ctags/lisp.c
+++ b/usr.bin/ctags/lisp.c
@@ -50,7 +50,7 @@ static char sccsid[] = "@(#)lisp.c 8.3 (Berkeley) 4/2/94";
void
l_entries(void)
{
- int special;
+ bool special;
char *cp;
char savedc;
char tok[MAXTOKEN];
@@ -63,15 +63,15 @@ l_entries(void)
lbp = lbuf;
if (!cicmp("(def"))
continue;
- special = NO;
+ special = false;
switch(*lbp | ' ') {
case 'm':
if (cicmp("method"))
- special = YES;
+ special = true;
break;
case 'w':
if (cicmp("wrapper") || cicmp("whopper"))
- special = YES;
+ special = true;
}
for (; !isspace(*lbp); ++lbp)
continue;
diff --git a/usr.bin/ctags/tree.c b/usr.bin/ctags/tree.c
index 15291f4a5e80..c3cfabc6e25f 100644
--- a/usr.bin/ctags/tree.c
+++ b/usr.bin/ctags/tree.c
@@ -106,7 +106,7 @@ add_node(NODE *node, NODE *cur_node)
if (!cur_node->been_warned)
if (!wflag)
fprintf(stderr, "Duplicate entry in files %s and %s: %s (Warning only)\n", node->file, cur_node->file, node->entry);
- cur_node->been_warned = YES;
+ cur_node->been_warned = true;
}
else if (dif < 0)
if (cur_node->left)
diff --git a/usr.bin/ctags/yacc.c b/usr.bin/ctags/yacc.c
index 0fd8537fb74f..e30ea0eacad0 100644
--- a/usr.bin/ctags/yacc.c
+++ b/usr.bin/ctags/yacc.c
@@ -54,7 +54,7 @@ y_entries(void)
bool in_rule;
char tok[MAXTOKEN];
- in_rule = NO;
+ in_rule = false;
while (GETC(!=, EOF))
switch (c) {
@@ -68,12 +68,12 @@ y_entries(void)
break;
case '{':
if (skip_key('}'))
- in_rule = NO;
+ in_rule = false;
break;
case '\'':
case '"':
if (skip_key(c))
- in_rule = NO;
+ in_rule = false;
break;
case '%':
if (GETC(==, '%'))
@@ -88,7 +88,7 @@ y_entries(void)
break;
case '|':
case ';':
- in_rule = NO;
+ in_rule = false;
break;
default:
if (in_rule || (!isalpha(c) && c != '.' && c != '_'))
@@ -107,7 +107,7 @@ y_entries(void)
}
if (c == ':') {
pfnote(tok, lineno);
- in_rule = YES;
+ in_rule = true;
}
else
(void)ungetc(c, inf);
diff --git a/usr.bin/expand/expand.1 b/usr.bin/expand/expand.1
index 9a49deb1a948..c1e19891b1ab 100644
--- a/usr.bin/expand/expand.1
+++ b/usr.bin/expand/expand.1
@@ -80,9 +80,15 @@ If the
.Fl a
option is given, then tabs are inserted whenever they would compress the
resultant file by replacing two or more characters.
-.It Fl t \&Sm Ar tab1 , tab2 , ... , tabn \&Sm
+.It Fl t Xo
+.Sm off
+.Ar tab1 , tab2 , ... , tabn
+.Sm on
+.Xc
Set tab stops at column positions
+.Sm off
.Ar tab1 , tab2 , ... , tabn .
+.Sm on
If only a single number is given, tab stops are set that number of
column positions apart instead of the default number of 8.
.El
diff --git a/usr.bin/kdump/kdump.c b/usr.bin/kdump/kdump.c
index d69c019bd6be..abbe57b0b75e 100644
--- a/usr.bin/kdump/kdump.c
+++ b/usr.bin/kdump/kdump.c
@@ -2137,35 +2137,74 @@ invalid:
void
ktrcapfail(struct ktr_cap_fail *ktr)
{
+ union ktr_cap_data *kcd = &ktr->cap_data;
+
switch (ktr->cap_type) {
case CAPFAIL_NOTCAPABLE:
/* operation on fd with insufficient capabilities */
printf("operation requires ");
- sysdecode_cap_rights(stdout, &ktr->cap_needed);
+ sysdecode_cap_rights(stdout, &kcd->cap_needed);
printf(", descriptor holds ");
- sysdecode_cap_rights(stdout, &ktr->cap_held);
+ sysdecode_cap_rights(stdout, &kcd->cap_held);
break;
case CAPFAIL_INCREASE:
/* requested more capabilities than fd already has */
printf("attempt to increase capabilities from ");
- sysdecode_cap_rights(stdout, &ktr->cap_held);
+ sysdecode_cap_rights(stdout, &kcd->cap_held);
printf(" to ");
- sysdecode_cap_rights(stdout, &ktr->cap_needed);
+ sysdecode_cap_rights(stdout, &kcd->cap_needed);
break;
case CAPFAIL_SYSCALL:
/* called restricted syscall */
- printf("disallowed system call");
+ printf("system call not allowed: ");
+ syscallname(ktr->cap_code, ktr->cap_svflags);
+ if (syscallabi(ktr->cap_svflags) == SYSDECODE_ABI_FREEBSD) {
+ switch (ktr->cap_code) {
+ case SYS_sysarch:
+ printf(", op: ");
+ print_integer_arg(sysdecode_sysarch_number,
+ kcd->cap_int);
+ break;
+ case SYS_fcntl:
+ printf(", cmd: ");
+ print_integer_arg(sysdecode_fcntl_cmd,
+ kcd->cap_int);
+ break;
+ }
+ }
break;
- case CAPFAIL_LOOKUP:
- /* absolute or AT_FDCWD path, ".." path, etc. */
- printf("restricted VFS lookup");
+ case CAPFAIL_SIGNAL:
+ /* sent signal to proc other than self */
+ syscallname(ktr->cap_code, ktr->cap_svflags);
+ printf(": signal delivery not allowed: ");
+ print_integer_arg(sysdecode_signal, kcd->cap_int);
break;
- default:
- printf("unknown capability failure: ");
- sysdecode_cap_rights(stdout, &ktr->cap_needed);
- printf(" ");
- sysdecode_cap_rights(stdout, &ktr->cap_held);
+ case CAPFAIL_PROTO:
+ /* created socket with restricted protocol */
+ syscallname(ktr->cap_code, ktr->cap_svflags);
+ printf(": protocol not allowed: ");
+ print_integer_arg(sysdecode_ipproto, kcd->cap_int);
break;
+ case CAPFAIL_SOCKADDR:
+ /* unable to look up address */
+ syscallname(ktr->cap_code, ktr->cap_svflags);
+ printf(": restricted address lookup: ");
+ ktrsockaddr(&kcd->cap_sockaddr);
+ return;
+ case CAPFAIL_NAMEI:
+ /* absolute or AT_FDCWD path, ".." path, etc. */
+ syscallname(ktr->cap_code, ktr->cap_svflags);
+ printf(": restricted VFS lookup: %s\n", kcd->cap_path);
+ return;
+ case CAPFAIL_CPUSET:
+ /* modification of an external cpuset */
+ syscallname(ktr->cap_code, ktr->cap_svflags);
+ printf(": restricted cpuset operation\n");
+ return;
+ default:
+ syscallname(ktr->cap_code, ktr->cap_svflags);
+ printf(": unknown capability failure\n");
+ return;
}
printf("\n");
}
diff --git a/usr.bin/ktrace/ktrace.1 b/usr.bin/ktrace/ktrace.1
index a6a07bb93caf..1b287af7a611 100644
--- a/usr.bin/ktrace/ktrace.1
+++ b/usr.bin/ktrace/ktrace.1
@@ -27,7 +27,7 @@
.\"
.\" @(#)ktrace.1 8.1 (Berkeley) 6/6/93
.\"
-.Dd August 26, 2019
+.Dd April 20, 2024
.Dt KTRACE 1
.Os
.Sh NAME
@@ -139,7 +139,7 @@ trace
requests
.It Cm +
trace the default set of trace points -
-.Cm c , i , n , p , s , t , u , y
+.Cm c , i , n , s , t , u , y
.El
.It Ar command
Execute
@@ -153,6 +153,21 @@ The
and
.Ar command
options are mutually exclusive.
+.Sh CAPABILITY VIOLATION TRACING
+When the
+.Cm p
+trace point is specified,
+.Nm
+will record
+.Xr capsicum 4
+capability mode violations made by the traced process.
+Violations will be logged regardless of whether the process has actually
+entered capability mode.
+.Pp
+For developers that are interested in Capsicumizing their programs, the
+.Cm c , n , p
+trace points can help quickly identify any system calls and path lookups that
+are triggering violations.
.Sh EXAMPLES
Run "make", then trace it and any child processes:
.Dl $ ktrace -i make
@@ -185,7 +200,8 @@ Disable tracing of all user-owned processes:
.Xr kdump 1 ,
.Xr truss 1 ,
.Xr ktrace 2 ,
-.Xr utrace 2
+.Xr utrace 2 ,
+.Xr capsicum 4
.Sh HISTORY
The
.Nm
diff --git a/usr.bin/ktrace/ktrace.h b/usr.bin/ktrace/ktrace.h
index cecd0adc7321..1d96c6faa2b7 100644
--- a/usr.bin/ktrace/ktrace.h
+++ b/usr.bin/ktrace/ktrace.h
@@ -33,13 +33,12 @@
#define DEF_POINTS (KTRFAC_SYSCALL | KTRFAC_SYSRET | KTRFAC_NAMEI | \
KTRFAC_GENIO | KTRFAC_PSIG | KTRFAC_USER | \
- KTRFAC_STRUCT | KTRFAC_SYSCTL | KTRFAC_CAPFAIL | \
- KTRFAC_STRUCT_ARRAY)
+ KTRFAC_STRUCT | KTRFAC_SYSCTL | KTRFAC_STRUCT_ARRAY)
#define PROC_ABI_POINTS (KTRFAC_PROCCTOR | KTRFAC_PROCDTOR)
-#define ALL_POINTS (DEF_POINTS | KTRFAC_CSW | PROC_ABI_POINTS | \
- KTRFAC_FAULT | KTRFAC_FAULTEND)
+#define ALL_POINTS (DEF_POINTS | KTRFAC_CAPFAIL | KTRFAC_CSW | \
+ PROC_ABI_POINTS | KTRFAC_FAULT | KTRFAC_FAULTEND)
#define DEF_TRACEFILE "ktrace.out"
diff --git a/usr.bin/locate/locate/locate.rc b/usr.bin/locate/locate/locate.rc
index 404af4cc4a64..f004dea19508 100644
--- a/usr.bin/locate/locate/locate.rc
+++ b/usr.bin/locate/locate/locate.rc
@@ -15,7 +15,7 @@
#SEARCHPATHS="/"
# paths unwanted in output
-#PRUNEPATHS="/tmp /usr/tmp /var/tmp /var/db/portsnap /var/db/freebsd-update"
+#PRUNEPATHS="/tmp /usr/tmp /var/tmp /var/db/freebsd-update"
# directories unwanted in output
#PRUNEDIRS=".zfs"
diff --git a/usr.bin/locate/locate/updatedb.sh b/usr.bin/locate/locate/updatedb.sh
index e874700afdb8..ff7ec7f6c18e 100644
--- a/usr.bin/locate/locate/updatedb.sh
+++ b/usr.bin/locate/locate/updatedb.sh
@@ -52,7 +52,7 @@ PATH=$LIBEXECDIR:/bin:/usr/bin:$PATH; export PATH
: ${mklocatedb:=locate.mklocatedb} # make locate database program
: ${FCODES:=/var/db/locate.database} # the database
: ${SEARCHPATHS="/"} # directories to be put in the database
-: ${PRUNEPATHS="/tmp /usr/tmp /var/tmp /var/db/portsnap /var/db/freebsd-update"} # unwanted directories
+: ${PRUNEPATHS="/tmp /usr/tmp /var/tmp /var/db/freebsd-update"} # unwanted directories
: ${PRUNEDIRS=".zfs"} # unwanted directories, in any parent
: ${FILESYSTEMS="$(lsvfs | tail -n +3 | \
egrep -vw "loopback|network|synthetic|read-only|0" | \
diff --git a/usr.bin/split/split.c b/usr.bin/split/split.c
index e246a0d4adfc..52374c93efca 100644
--- a/usr.bin/split/split.c
+++ b/usr.bin/split/split.c
@@ -401,6 +401,10 @@ newfile(void)
*/
if (!dflag && autosfx && (fpnt[0] == 'y') &&
strspn(fpnt+1, "z") == strlen(fpnt+1)) {
+ /* Ensure the generated filenames will fit into the buffer. */
+ if (strlen(fname) + 2 >= sizeof(fname))
+ errx(EX_USAGE, "combined filenames would be too long");
+
fpnt = fname + strlen(fname) - sufflen;
fpnt[sufflen + 2] = '\0';
fpnt[0] = end;
diff --git a/usr.sbin/adduser/adduser.sh b/usr.sbin/adduser/adduser.sh
index e9027b6b7876..7c3fdb418179 100644
--- a/usr.sbin/adduser/adduser.sh
+++ b/usr.sbin/adduser/adduser.sh
@@ -53,7 +53,7 @@ info() {
# by pw(8).
#
get_nextuid () {
- local _uid=$1 _nextuid
+ local _uid=$1 _nextuid=
if [ -z "$_uid" ]; then
_nextuid="$(${PWCMD} usernext | cut -f1 -d:)"
@@ -101,7 +101,7 @@ show_usage() {
# basename of the shell is output.
#
valid_shells() {
- local _prefix
+ local _prefix=
${GREPCMD} '^[^#]' ${ETCSHELLS} |
while read _path _junk ; do
@@ -119,7 +119,7 @@ valid_shells() {
# full path to the shell from the /etc/shells file.
#
fullpath_from_shell() {
- local _shell=$1 _fullpath
+ local _shell=$1 _fullpath=
if [ -z "$_shell" ]; then
return
@@ -154,7 +154,7 @@ fullpath_from_shell() {
# will emit an informational message saying so.
#
shell_exists() {
- local _sh="$1"
+ local _sh=$1
if [ -z "$(fullpath_from_shell "$_sh")" ] ; then
err "Invalid shell ($_sh) for user $username."
@@ -193,8 +193,9 @@ save_config() {
# message or lock the account, do so.
#
add_user() {
- local _uid _name _comment _gecos _home _group _grouplist _shell _class
- local _dotdir _expire _pwexpire _passwd _upasswd _passwdmethod
+ local _uid= _name= _comment= _gecos= _home= _group= _grouplist=
+ local _shell= _class= _dotdir= _expire= _pwexpire= _passwd= _upasswd=
+ local _passwdmethod= _pwcmd=
# Is this a configuration run? If so, don't modify user database.
#
@@ -299,7 +300,7 @@ add_user() {
fi
fi
- local _line _owner _perms _file _dir
+ local _line= _owner= _perms= _file= _dir=
if [ -n "$msgflag" ]; then
if [ -r "$msgfile" ]; then
# We're evaluating the contents of an external file.
@@ -331,7 +332,7 @@ add_user() {
# a file it will output an error message and return to the caller.
#
get_user() {
- local _input
+ local _input=
# No need to take down user names if this is a configuration saving run.
[ -n "$configflag" ] && return
@@ -366,7 +367,7 @@ get_user() {
# and batch (from file) mode.
#
get_gecos() {
- local _input
+ local _input=
# No need to take down additional user information for a configuration run.
[ -n "$configflag" ] && return
@@ -386,7 +387,7 @@ get_gecos() {
# If an invalid shell is entered it will simply use the default shell.
#
get_shell() {
- local _input _fullpath
+ local _input= _fullpath=
ushell="$defaultshell"
# Make sure the current value of the shell is a valid one
@@ -424,7 +425,7 @@ get_shell() {
# and batch input.
#
get_homedir() {
- _input=
+ local _input=
if [ -z "$fflag" ]; then
echo -n "Home directory [${homeprefix}/${username}]: "
read _input
@@ -450,7 +451,7 @@ get_homedir() {
# Reads the account's home directory permissions.
#
get_homeperm() {
- local _input _prompt
+ local _input= _prompt=
uhomeperm=$defaultHomePerm
if [ -n "$uhomeperm" ]; then
@@ -473,7 +474,7 @@ get_homeperm() {
# so, enable ZFS home dataset creation.
#
get_zfs_home() {
- local _prefix
+ local _prefix=
# check if zfs kernel module is loaded before attempting to run zfs to
# prevent loading the kernel module on systems that don't use ZFS
@@ -494,7 +495,7 @@ get_zfs_home() {
# allocates one if it is not specified.
#
get_uid() {
- local _input _prompt
+ local _input= _prompt=
uuid=${uidstart}
if [ -n "$uuid" ]; then
@@ -519,7 +520,7 @@ get_uid() {
# Reads login class of account. Can be used in interactive or batch mode.
#
get_class() {
- local _input _uclass
+ local _input= _class=
uclass="$defaultclass"
_class=${uclass:-"default"}
@@ -541,7 +542,7 @@ get_class() {
# will then provide a login group with the same name as the username.
#
get_logingroup() {
- local _input
+ local _input=
ulogingroup="$defaultLgroup"
if [ -z "$fflag" ]; then
@@ -560,7 +561,7 @@ get_logingroup() {
# and batch modes.
#
get_groups() {
- local _input _group
+ local _input= _group=
ugroups="$defaultgroups"
_group=${ulogingroup:-"${username}"}
@@ -626,7 +627,7 @@ get_password() {
# Ask user if they want to enable encryption on their ZFS home dataset.
#
get_zfs_encryption() {
- local _input _prompt
+ local _input= _prompt=
_prompt="Enable ZFS encryption? (yes/no) [${Zencrypt}]: "
while : ; do
echo -n "$_prompt"
@@ -702,7 +703,7 @@ set_zfs_perms() {
# adds it to the user database.
#
input_from_file() {
- local _field
+ local _field=
while read -r fileline ; do
case "$fileline" in
@@ -733,14 +734,13 @@ input_from_file() {
# the user database.
#
input_interactive() {
- local _disable _pass _passconfirm _input
+ local _disable= _pass= _passconfirm= _input=
local _random="no"
local _emptypass="no"
local _usepass="yes"
local _logingroup_ok="no"
local _groups_ok="no"
local _all_ok="yes"
- local _another_user="no"
case $passwdtype in
none)
_emptypass="yes"
@@ -1129,6 +1129,7 @@ if [ -n "$fflag" ]; then
else
input_interactive
while : ; do
+ _another_user="no"
if [ -z "$configflag" ]; then
echo -n "Add another user? (yes/no) [$_another_user]: "
else
diff --git a/usr.sbin/bhyve/gdb.c b/usr.sbin/bhyve/gdb.c
index 2a075cd10ca6..0319aaf0a9cd 100644
--- a/usr.sbin/bhyve/gdb.c
+++ b/usr.sbin/bhyve/gdb.c
@@ -193,7 +193,6 @@ static const struct gdb_reg {
{ .id = VM_REG_GUEST_EFER, .size = 8 },
};
-#define GDB_LOG
#ifdef GDB_LOG
#include <stdarg.h>
#include <stdio.h>
diff --git a/usr.sbin/freebsd-update/freebsd-update.sh b/usr.sbin/freebsd-update/freebsd-update.sh
index 4a6a8d78330b..77b12a3756c2 100644
--- a/usr.sbin/freebsd-update/freebsd-update.sh
+++ b/usr.sbin/freebsd-update/freebsd-update.sh
@@ -1052,10 +1052,10 @@ IDS_check_params () {
# a useful answer, use the server name specified by the user.
# Put another way... look up _http._tcp.${SERVERNAME} and pick a server
# from that; or if no servers are returned, use ${SERVERNAME}.
-# This allows a user to specify "portsnap.freebsd.org" (in which case
-# portsnap will select one of the mirrors) or "portsnap5.tld.freebsd.org"
-# (in which case portsnap will use that particular server, since there
-# won't be an SRV entry for that name).
+# This allows a user to specify "update.FreeBSD.org" (in which case
+# freebsd-update will select one of the mirrors) or "update1.freebsd.org"
+# (in which case freebsd-update will use that particular server, since
+# there won't be an SRV entry for that name).
#
# We ignore the Port field, since we are always going to use port 80.
diff --git a/usr.sbin/pw/pw.c b/usr.sbin/pw/pw.c
index 063553dd084f..fc17f6dba022 100644
--- a/usr.sbin/pw/pw.c
+++ b/usr.sbin/pw/pw.c
@@ -101,13 +101,16 @@ static int (*cmdfunc[W_NUM][M_NUM])(int argc, char **argv, char *_name) = {
struct pwconf conf;
+static int mode = -1;
+static int which = -1;
+
static int getindex(const char *words[], const char *word);
static void cmdhelp(int mode, int which);
int
main(int argc, char *argv[])
{
- int mode = -1, which = -1, tmp;
+ int tmp;
struct stat st;
char arg, *arg1;
bool relocated, nis;
@@ -375,5 +378,11 @@ cmdhelp(int mode, int which)
fprintf(stderr, "%s", help[which][mode]);
}
- exit(EXIT_FAILURE);
+ exit(EX_USAGE);
+}
+
+void
+usage(void)
+{
+ cmdhelp(mode, which);
}
diff --git a/usr.sbin/pw/pw.h b/usr.sbin/pw/pw.h
index 5de333ce5e71..c3725693f91d 100644
--- a/usr.sbin/pw/pw.h
+++ b/usr.sbin/pw/pw.h
@@ -36,14 +36,14 @@
enum _mode
{
- M_ADD,
- M_DELETE,
- M_UPDATE,
- M_PRINT,
+ M_ADD,
+ M_DELETE,
+ M_MODIFY,
+ M_SHOW,
M_NEXT,
M_LOCK,
M_UNLOCK,
- M_NUM
+ M_NUM
};
enum _passmode
@@ -56,13 +56,13 @@ enum _passmode
enum _which
{
- W_USER,
- W_GROUP,
- W_NUM
+ W_USER,
+ W_GROUP,
+ W_NUM
};
-#define _DEF_DIRMODE (S_IRWXU | S_IRWXG | S_IRWXO)
-#define _PW_CONF "pw.conf"
+#define _DEF_DIRMODE (S_IRWXU | S_IRWXG | S_IRWXO)
+#define _PW_CONF "pw.conf"
#define _UC_MAXLINE 1024
#define _UC_MAXSHELLS 32
@@ -114,3 +114,5 @@ uintmax_t strtounum(const char * __restrict, uintmax_t, uintmax_t,
const char ** __restrict);
bool grp_has_member(struct group *grp, const char *name);
+
+void usage(void);
diff --git a/usr.sbin/pw/pw_group.c b/usr.sbin/pw/pw_group.c
index 32dec769fb1a..1941c03aa2c5 100644
--- a/usr.sbin/pw/pw_group.c
+++ b/usr.sbin/pw/pw_group.c
@@ -273,9 +273,13 @@ pw_group_next(int argc, char **argv, char *arg1 __unused)
quiet = true;
break;
default:
- exit(EX_USAGE);
+ usage();
}
}
+ argc -= optind;
+ argv += optind;
+ if (argc > 0)
+ usage();
if (quiet)
freopen(_PATH_DEVNULL, "w", stderr);
@@ -332,9 +336,13 @@ pw_group_show(int argc, char **argv, char *arg1)
all = true;
break;
default:
- exit(EX_USAGE);
+ usage();
}
}
+ argc -= optind;
+ argv += optind;
+ if (argc > 0)
+ usage();
if (quiet)
freopen(_PATH_DEVNULL, "w", stderr);
@@ -391,9 +399,13 @@ pw_group_del(int argc, char **argv, char *arg1)
nis = true;
break;
default:
- exit(EX_USAGE);
+ usage();
}
}
+ argc -= optind;
+ argv += optind;
+ if (argc > 0)
+ usage();
if (quiet)
freopen(_PATH_DEVNULL, "w", stderr);
@@ -551,9 +563,13 @@ pw_group_add(int argc, char **argv, char *arg1)
nis = true;
break;
default:
- exit(EX_USAGE);
+ usage();
}
}
+ argc -= optind;
+ argv += optind;
+ if (argc > 0)
+ usage();
if (quiet)
freopen(_PATH_DEVNULL, "w", stderr);
@@ -645,9 +661,14 @@ pw_group_mod(int argc, char **argv, char *arg1)
nis = true;
break;
default:
- exit(EX_USAGE);
+ usage();
}
}
+ argc -= optind;
+ argv += optind;
+ if (argc > 0)
+ usage();
+
if (quiet)
freopen(_PATH_DEVNULL, "w", stderr);
cnf = get_userconfig(cfg);
@@ -697,11 +718,11 @@ pw_group_mod(int argc, char **argv, char *arg1)
if ((grp = GETGRNAM(name)) == NULL)
errx(EX_SOFTWARE, "group disappeared during update");
- pw_log(cnf, M_UPDATE, W_GROUP, "%s(%ju)", grp->gr_name,
+ pw_log(cnf, M_MODIFY, W_GROUP, "%s(%ju)", grp->gr_name,
(uintmax_t)grp->gr_gid);
if (nis && nis_update() == 0)
- pw_log(cnf, M_UPDATE, W_GROUP, "NIS maps updated");
+ pw_log(cnf, M_MODIFY, W_GROUP, "NIS maps updated");
return (EXIT_SUCCESS);
}
diff --git a/usr.sbin/pw/pw_user.c b/usr.sbin/pw/pw_user.c
index 6875d931a1d2..89354b249935 100644
--- a/usr.sbin/pw/pw_user.c
+++ b/usr.sbin/pw/pw_user.c
@@ -146,7 +146,7 @@ create_and_populate_homedir(struct userconf *cnf, struct passwd *pwd,
copymkdir(conf.rootfd, pwd->pw_dir, skelfd, homemode, pwd->pw_uid,
pwd->pw_gid, 0);
- pw_log(cnf, update ? M_UPDATE : M_ADD, W_USER, "%s(%ju) home %s made",
+ pw_log(cnf, update ? M_MODIFY : M_ADD, W_USER, "%s(%ju) home %s made",
pwd->pw_name, (uintmax_t)pwd->pw_uid, pwd->pw_dir);
}
@@ -708,9 +708,13 @@ pw_user_next(int argc, char **argv, char *name __unused)
quiet = true;
break;
default:
- exit(EX_USAGE);
+ usage();
}
}
+ argc -= optind;
+ argv += optind;
+ if (argc > 0)
+ usage();
if (quiet)
freopen(_PATH_DEVNULL, "w", stderr);
@@ -772,9 +776,13 @@ pw_user_show(int argc, char **argv, char *arg1)
v7 = true;
break;
default:
- exit(EX_USAGE);
+ usage();
}
}
+ argc -= optind;
+ argv += optind;
+ if (argc > 0)
+ usage();
if (quiet)
freopen(_PATH_DEVNULL, "w", stderr);
@@ -855,9 +863,13 @@ pw_user_del(int argc, char **argv, char *arg1)
nis = true;
break;
default:
- exit(EX_USAGE);
+ usage();
}
}
+ argc -= optind;
+ argv += optind;
+ if (argc > 0)
+ usage();
if (quiet)
freopen(_PATH_DEVNULL, "w", stderr);
@@ -1003,9 +1015,13 @@ pw_user_lock(int argc, char **argv, char *arg1)
/* compatibility */
break;
default:
- exit(EX_USAGE);
+ usage();
}
}
+ argc -= optind;
+ argv += optind;
+ if (argc > 0)
+ usage();
return (pw_userlock(arg1, M_LOCK));
}
@@ -1022,9 +1038,13 @@ pw_user_unlock(int argc, char **argv, char *arg1)
/* compatibility */
break;
default:
- exit(EX_USAGE);
+ usage();
}
}
+ argc -= optind;
+ argv += optind;
+ if (argc > 0)
+ usage();
return (pw_userlock(arg1, M_UNLOCK));
}
@@ -1291,9 +1311,13 @@ pw_user_add(int argc, char **argv, char *arg1)
nis = true;
break;
default:
- exit(EX_USAGE);
+ usage();
}
}
+ argc -= optind;
+ argv += optind;
+ if (argc > 0)
+ usage();
if (geteuid() != 0 && ! dryrun)
errx(EX_NOPERM, "you must be root");
@@ -1604,9 +1628,13 @@ pw_user_mod(int argc, char **argv, char *arg1)
nis = true;
break;
default:
- exit(EX_USAGE);
+ usage();
}
}
+ argc -= optind;
+ argv += optind;
+ if (argc > 0)
+ usage();
if (geteuid() != 0 && ! dryrun)
errx(EX_NOPERM, "you must be root");
@@ -1787,7 +1815,7 @@ pw_user_mod(int argc, char **argv, char *arg1)
if (pwd == NULL)
errx(EX_NOUSER, "user '%s' disappeared during update", name);
grp = GETGRGID(pwd->pw_gid);
- pw_log(cnf, M_UPDATE, W_USER, "%s(%ju):%s(%ju):%s:%s:%s",
+ pw_log(cnf, M_MODIFY, W_USER, "%s(%ju):%s(%ju):%s:%s:%s",
pwd->pw_name, (uintmax_t)pwd->pw_uid,
grp ? grp->gr_name : "unknown",
(uintmax_t)(grp ? grp->gr_gid : (uid_t)-1),
@@ -1808,7 +1836,7 @@ pw_user_mod(int argc, char **argv, char *arg1)
}
if (nis && nis_update() == 0)
- pw_log(cnf, M_UPDATE, W_USER, "NIS maps updated");
+ pw_log(cnf, M_MODIFY, W_USER, "NIS maps updated");
return (EXIT_SUCCESS);
}
diff --git a/usr.sbin/pw/tests/pw_useradd_test.sh b/usr.sbin/pw/tests/pw_useradd_test.sh
index 3b495482eb05..b4efa42bada7 100755
--- a/usr.sbin/pw/tests/pw_useradd_test.sh
+++ b/usr.sbin/pw/tests/pw_useradd_test.sh
@@ -313,6 +313,22 @@ user_add_R_intermed_body() {
test -d ${HOME}/a/b/c/foo || atf_fail "user directory not created"
}
+atf_test_case user_add_dir
+user_add_dir_body() {
+ populate_root_etc_skel
+
+ atf_check -s exit:0 ${RPW} useradd foo -M 0705 -m
+ atf_check grep -q '^foo:' $HOME/etc/master.passwd
+ atf_check test -d ${HOME}/home/foo
+ atf_check -o save:ugid \
+ awk -F: '$1 == "foo" { print $3, $4 }' \
+ $HOME/etc/master.passwd
+ atf_check -o file:ugid \
+ stat -f '%u %g' ${HOME}/home/foo
+ atf_check -o inline:"40705\n" \
+ stat -f '%p' ${HOME}/home/foo
+}
+
atf_test_case user_add_skel
user_add_skel_body() {
populate_root_etc_skel
@@ -511,6 +527,7 @@ atf_init_test_cases() {
atf_add_test_case user_add_R
atf_add_test_case user_add_R_no_symlink
atf_add_test_case user_add_R_intermed
+ atf_add_test_case user_add_dir
atf_add_test_case user_add_skel
atf_add_test_case user_add_uid0
atf_add_test_case user_add_uid_too_large
diff --git a/usr.sbin/rpc.lockd/lockd.c b/usr.sbin/rpc.lockd/lockd.c
index 7e0652d26533..0ac7ddfeea5c 100644
--- a/usr.sbin/rpc.lockd/lockd.c
+++ b/usr.sbin/rpc.lockd/lockd.c
@@ -188,7 +188,8 @@ main(int argc, char **argv)
kernel_lockd_client = FALSE;
if (modfind("nfslockd") < 0) {
if (kldload("nfslockd") < 0) {
- fprintf(stderr, "Can't find or load kernel support for rpc.lockd - using non-kernel implementation\n");
+ fprintf(stderr, "Unable to load nfslockd(4), "
+ "using userland implementation\n");
} else {
kernel_lockd = TRUE;
}
diff --git a/usr.sbin/rpc.lockd/rpc.lockd.8 b/usr.sbin/rpc.lockd/rpc.lockd.8
index 89f55087901d..89592a1cceaf 100644
--- a/usr.sbin/rpc.lockd/rpc.lockd.8
+++ b/usr.sbin/rpc.lockd/rpc.lockd.8
@@ -27,7 +27,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd November 21, 2019
+.Dd May 8, 2024
.Dt RPC.LOCKD 8
.Os
.Sh NAME
@@ -44,7 +44,7 @@
The
.Nm
utility provides monitored and unmonitored file and record locking services
-in an NFS environment.
+in an NFSv3 environment.
To monitor the status of hosts requesting locks,
the locking daemon typically operates in conjunction
with
@@ -137,6 +137,7 @@ RPC protocol specification for the network lock manager protocol.
.El
.Sh SEE ALSO
.Xr syslog 3 ,
+.Xr nfslockd 4 ,
.Xr rc.conf 5 ,
.Xr rpc.statd 8
.Sh STANDARDS