mirror of
https://github.com/freebsd/freebsd-src.git
synced 2024-11-26 20:12:44 +00:00
Compare commits
47 Commits
b26a26f4c6
...
dc98c1a84d
Author | SHA1 | Date | |
---|---|---|---|
|
dc98c1a84d | ||
|
f2233ac33a | ||
|
9206c79961 | ||
|
6d77827b96 | ||
|
5317480967 | ||
|
6d4c59e261 | ||
|
2839ad58dd | ||
|
5ac39263d8 | ||
|
5bd08172b4 | ||
|
56b7685ae3 | ||
|
4cc5d081d8 | ||
|
cca0dc49e0 | ||
|
3abef90c32 | ||
|
c0a5ee953f | ||
|
ccb973da1f | ||
|
cab31f5633 | ||
|
5035db222e | ||
|
501c4801ed | ||
|
3a212cc66a | ||
|
73465bb47b | ||
|
37cef00192 | ||
|
e9fa399180 | ||
|
c7fa232e9b | ||
|
ccbe9a9f73 | ||
|
dfe57951f0 | ||
|
4ab2a84e09 | ||
|
bf06074106 | ||
|
370ad2d367 | ||
|
bde575b273 | ||
|
67218bcea8 | ||
|
31784ee1e3 | ||
|
af1ef35a00 | ||
|
b2f7c53430 | ||
|
67f9307907 | ||
|
8585680682 | ||
|
fb4cdd5160 | ||
|
c1e304c60c | ||
|
c94d6389e4 | ||
|
4d58cf6ff9 | ||
|
bef05a7537 | ||
|
aa308b49e3 | ||
|
73b42eff25 | ||
|
6ec4ff7088 | ||
|
2d6923790b | ||
|
aebac84982 | ||
|
ff4c19bb54 | ||
|
4142468ff4 |
5
RELNOTES
5
RELNOTES
@ -10,6 +10,11 @@ newline. Entries should be separated by a newline.
|
||||
|
||||
Changes to this file should not be MFCed.
|
||||
|
||||
b2f7c53430c3:
|
||||
Kernel TLS is now enabled by default in kernels including KTLS
|
||||
support. KTLS is included in GENERIC kernels for aarch64,
|
||||
amd64, powerpc64, and powerpc64le.
|
||||
|
||||
f57efe95cc25:
|
||||
New mididump(1) utility which dumps MIDI 1.0 events in real time.
|
||||
|
||||
|
@ -505,6 +505,8 @@
|
||||
..
|
||||
route
|
||||
..
|
||||
savecore
|
||||
..
|
||||
sysctl
|
||||
..
|
||||
..
|
||||
@ -1089,8 +1091,6 @@
|
||||
..
|
||||
cut
|
||||
..
|
||||
dc
|
||||
..
|
||||
diff
|
||||
..
|
||||
diff3
|
||||
|
@ -60,7 +60,7 @@ code in the global variable
|
||||
.Va errno .
|
||||
.Sh ERRORS
|
||||
The
|
||||
.Fn readlink
|
||||
.Fn fhreadlink
|
||||
system call
|
||||
will fail if:
|
||||
.Bl -tag -width Er
|
||||
@ -87,7 +87,8 @@ is no longer valid
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr fhlink 2 ,
|
||||
.Xr fhstat 2
|
||||
.Xr fhstat 2 ,
|
||||
.Xr readlink 2
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Fn fhreadlink
|
||||
|
@ -25,7 +25,7 @@
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd July 8, 2024
|
||||
.Dd November 25, 2024
|
||||
.Dt GETSOCKOPT 2
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -568,9 +568,14 @@ struct so_splice {
|
||||
.Pp
|
||||
Data received on
|
||||
.Fa s
|
||||
will automatically be transmitted from the socket specified in
|
||||
will automatically be transmitted via the socket specified in
|
||||
.Fa sp_fd
|
||||
without any intervention by userspace.
|
||||
That is, the data will be transmitted via
|
||||
.Fa sp_fd
|
||||
as if userspace had called
|
||||
.Xr send 2
|
||||
directly.
|
||||
Splicing is a one-way operation; a given pair of sockets may be
|
||||
spliced in one or both directions.
|
||||
Currently only connected
|
||||
|
@ -138,6 +138,7 @@ is neither
|
||||
nor a file descriptor associated with a directory.
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr fhreadlink 2 ,
|
||||
.Xr lstat 2 ,
|
||||
.Xr stat 2 ,
|
||||
.Xr symlink 2 ,
|
||||
|
@ -263,8 +263,8 @@ icmp_log_redirect="NO" # Set to YES to log ICMP REDIRECT packets
|
||||
network_interfaces="auto" # List of network interfaces (or "auto").
|
||||
cloned_interfaces="" # List of cloned network interfaces to create.
|
||||
#cloned_interfaces="gif0 gif1 gif2 gif3" # Pre-cloning GENERIC config.
|
||||
#ifconfig_lo0="inet 127.0.0.1" # default loopback device configuration.
|
||||
#ifconfig_lo0_alias0="inet 127.0.0.254 netmask 0xffffffff" # Sample alias entry.
|
||||
#ifconfig_lo0="inet 127.0.0.1/8" # default loopback device configuration.
|
||||
#ifconfig_lo0_alias0="inet 127.0.0.254/32" # Sample alias entry.
|
||||
#ifconfig_em0_ipv6="inet6 2001:db8:1::1 prefixlen 64" # Sample IPv6 addr entry
|
||||
#ifconfig_em0_alias0="inet6 2001:db8:2::1 prefixlen 64" # Sample IPv6 alias
|
||||
#ifconfig_em0_name="net0" # Change interface name from em0 to net0.
|
||||
|
@ -27,7 +27,7 @@ _var_run_load() {
|
||||
|
||||
_var_run_save() {
|
||||
if [ ! -d $(dirname ${var_run_mtree}) ]; then
|
||||
mkdir -p ${var_run_mtree}
|
||||
mkdir -p $(dirname ${var_run_mtree})
|
||||
fi
|
||||
mtree -dcbj -p /var/run > ${var_run_mtree}
|
||||
}
|
||||
|
@ -36,7 +36,7 @@
|
||||
.\"
|
||||
.\" $TSHeader: src/sbin/ffsinfo/ffsinfo.8,v 1.3 2000/12/12 19:30:55 tomsoft Exp $
|
||||
.\"
|
||||
.Dd September 8, 2000
|
||||
.Dd November 19, 2024
|
||||
.Dt FFSINFO 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -120,6 +120,7 @@ to
|
||||
.Pa /var/tmp/ffsinfo
|
||||
with all available information.
|
||||
.Sh SEE ALSO
|
||||
.Xr ffs 4 ,
|
||||
.Xr dumpfs 8 ,
|
||||
.Xr fsck 8 ,
|
||||
.Xr gpart 8 ,
|
||||
|
@ -25,7 +25,7 @@
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd January 24, 2024
|
||||
.Dd November 19, 2024
|
||||
.Dt MOUNT 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -568,6 +568,7 @@ support for a particular file system might be provided either on a static
|
||||
.Xr cd9660 4 ,
|
||||
.Xr devfs 4 ,
|
||||
.Xr ext2fs 4 ,
|
||||
.Xr ffs 4 ,
|
||||
.Xr mac 4 ,
|
||||
.Xr procfs 4 ,
|
||||
.Xr tarfs 4 ,
|
||||
|
@ -25,7 +25,7 @@
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd May 18, 2024
|
||||
.Dd November 19, 2024
|
||||
.Dt NEWFS 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -350,6 +350,7 @@ than the historical defaults
|
||||
This large fragment size may lead to much wasted space
|
||||
on file systems that contain many small files.
|
||||
.Sh SEE ALSO
|
||||
.Xr ffs 4 ,
|
||||
.Xr geom 4 ,
|
||||
.Xr disktab 5 ,
|
||||
.Xr fs 5 ,
|
||||
|
@ -18,4 +18,7 @@ CFLAGS+= -DWITH_CASPER
|
||||
LIBADD+= casper cap_fileargs cap_syslog
|
||||
.endif
|
||||
|
||||
HAS_TESTS=
|
||||
SUBDIR.${MK_TESTS}+= tests
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
3
sbin/savecore/tests/Makefile
Normal file
3
sbin/savecore/tests/Makefile
Normal file
@ -0,0 +1,3 @@
|
||||
ATF_TESTS_SH= livedump_test
|
||||
|
||||
.include <bsd.test.mk>
|
54
sbin/savecore/tests/livedump_test.sh
Normal file
54
sbin/savecore/tests/livedump_test.sh
Normal file
@ -0,0 +1,54 @@
|
||||
#
|
||||
# SPDX-License-Identifier: BSD-2-Clause
|
||||
#
|
||||
# Copyright (c) 2024 Mark Johnston <markj@FreeBSD.org>
|
||||
#
|
||||
|
||||
atf_test_case livedump_kldstat
|
||||
livedump_kldstat_head()
|
||||
{
|
||||
atf_set "descr" "Test livedump integrity"
|
||||
atf_set "require.progs" kgdb
|
||||
atf_set "require.user" root
|
||||
}
|
||||
livedump_kldstat_body()
|
||||
{
|
||||
atf_check savecore -L .
|
||||
|
||||
kernel=$(sysctl -n kern.bootfile)
|
||||
|
||||
if ! [ -f /usr/lib/debug/${kernel}.debug ]; then
|
||||
atf_skip "No debug symbols for the running kernel"
|
||||
fi
|
||||
|
||||
# Implement kldstat using gdb script.
|
||||
cat >./kldstat.gdb <<'__EOF__'
|
||||
printf "Id Refs Address Size Name\n"
|
||||
set $_lf = linker_files.tqh_first
|
||||
while ($_lf)
|
||||
printf "%2d %4d %p %8x %s\n", $_lf->id, $_lf->refs, $_lf->address, $_lf->size, $_lf->filename
|
||||
set $_lf = $_lf->link.tqe_next
|
||||
end
|
||||
__EOF__
|
||||
|
||||
# Ignore stderr since kgdb prints some warnings about inaccessible
|
||||
# source files.
|
||||
#
|
||||
# Use a script to source the main gdb script, otherwise kgdb prints
|
||||
# a bunch of line noise that is annoying to filter out.
|
||||
echo "source ./kldstat.gdb" > ./script.gdb
|
||||
atf_check -o save:out -e ignore \
|
||||
kgdb -q ${kernel} ./livecore.0 < ./script.gdb
|
||||
|
||||
# Get rid of gunk printed by kgdb.
|
||||
sed -i '' -n -e 's/^(kgdb) //' -e '/^Id Refs /,$p' out
|
||||
|
||||
# The output of kgdb should match the output of kldstat.
|
||||
atf_check -o save:kldstat kldstat
|
||||
atf_check diff kldstat out
|
||||
}
|
||||
|
||||
atf_init_test_cases()
|
||||
{
|
||||
atf_add_test_case livedump_kldstat
|
||||
}
|
@ -22,7 +22,7 @@
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd June 3, 2019
|
||||
.Dd November 25, 2024
|
||||
.Dt CCR 4
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -52,7 +52,10 @@ The driver accelerates AES-CBC, AES-CCM, AES-CTR, AES-GCM, AES-XTS,
|
||||
SHA1, SHA2-224, SHA2-256, SHA2-384, SHA2-512,
|
||||
SHA1-HMAC, SHA2-224-HMAC, SHA2-256-HMAC, SHA2-384-HMAC, and SHA2-512-HMAC
|
||||
operations for
|
||||
.Xr crypto 4
|
||||
.Xr crypto 9
|
||||
consumers such as
|
||||
.Xr ktls 4 ,
|
||||
.Xr geli 4 ,
|
||||
and
|
||||
.Xr ipsec 4 .
|
||||
The driver also supports chaining one of AES-CBC, AES-CTR, or AES-XTS with
|
||||
@ -97,7 +100,11 @@ email all the specific information related to the issue to
|
||||
.Sh SEE ALSO
|
||||
.Xr crypto 4 ,
|
||||
.Xr cxgbe 4 ,
|
||||
.Xr ipsec 4
|
||||
.Xr geli 4 ,
|
||||
.Xr ipsec 4 ,
|
||||
.Xr ktls 4 ,
|
||||
.Xr crypto 7 ,
|
||||
.Xr crypto 9
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
|
@ -4082,7 +4082,19 @@ pmap_qremove(vm_offset_t sva, int count)
|
||||
|
||||
va = sva;
|
||||
while (count-- > 0) {
|
||||
/*
|
||||
* pmap_enter() calls within the kernel virtual
|
||||
* address space happen on virtual addresses from
|
||||
* subarenas that import superpage-sized and -aligned
|
||||
* address ranges. So, the virtual address that we
|
||||
* allocate to use with pmap_qenter() can't be close
|
||||
* enough to one of those pmap_enter() calls for it to
|
||||
* be caught up in a promotion.
|
||||
*/
|
||||
KASSERT(va >= VM_MIN_KERNEL_ADDRESS, ("usermode va %lx", va));
|
||||
KASSERT((*vtopde(va) & X86_PG_PS) == 0,
|
||||
("pmap_qremove on promoted va %#lx", va));
|
||||
|
||||
pmap_kremove(va);
|
||||
va += PAGE_SIZE;
|
||||
}
|
||||
@ -10506,8 +10518,7 @@ pmap_map_io_transient(vm_page_t page[], vm_offset_t vaddr[], int count,
|
||||
{
|
||||
vm_paddr_t paddr;
|
||||
bool needs_mapping;
|
||||
pt_entry_t *pte;
|
||||
int cache_bits, error __unused, i;
|
||||
int error __unused, i;
|
||||
|
||||
/*
|
||||
* Allocate any KVA space that we need, this is done in a separate
|
||||
@ -10552,11 +10563,8 @@ pmap_map_io_transient(vm_page_t page[], vm_offset_t vaddr[], int count,
|
||||
*/
|
||||
pmap_qenter(vaddr[i], &page[i], 1);
|
||||
} else {
|
||||
pte = vtopte(vaddr[i]);
|
||||
cache_bits = pmap_cache_bits(kernel_pmap,
|
||||
page[i]->md.pat_mode, false);
|
||||
pte_store(pte, paddr | X86_PG_RW | X86_PG_V |
|
||||
cache_bits);
|
||||
pmap_kenter_attr(vaddr[i], paddr,
|
||||
page[i]->md.pat_mode);
|
||||
pmap_invlpg(kernel_pmap, vaddr[i]);
|
||||
}
|
||||
}
|
||||
|
@ -101,14 +101,19 @@ get_vfpcontext(struct thread *td, mcontext_vfp_t *vfp)
|
||||
P_SHOULDSTOP(td->td_proc));
|
||||
|
||||
pcb = td->td_pcb;
|
||||
if ((pcb->pcb_fpflags & PCB_FP_STARTED) != 0 && td == curthread) {
|
||||
if (td == curthread) {
|
||||
critical_enter();
|
||||
vfp_store(&pcb->pcb_vfpstate, false);
|
||||
critical_exit();
|
||||
}
|
||||
KASSERT(pcb->pcb_vfpsaved == &pcb->pcb_vfpstate,
|
||||
("Called get_vfpcontext while the kernel is using the VFP"));
|
||||
memcpy(vfp, &pcb->pcb_vfpstate, sizeof(*vfp));
|
||||
|
||||
memset(vfp, 0, sizeof(*vfp));
|
||||
memcpy(vfp->mcv_reg, pcb->pcb_vfpstate.reg,
|
||||
sizeof(vfp->mcv_reg));
|
||||
vfp->mcv_fpscr = pcb->pcb_vfpstate.fpscr;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
@ -127,7 +132,10 @@ set_vfpcontext(struct thread *td, mcontext_vfp_t *vfp)
|
||||
}
|
||||
KASSERT(pcb->pcb_vfpsaved == &pcb->pcb_vfpstate,
|
||||
("Called set_vfpcontext while the kernel is using the VFP"));
|
||||
memcpy(&pcb->pcb_vfpstate, vfp, sizeof(*vfp));
|
||||
memcpy(pcb->pcb_vfpstate.reg, vfp->mcv_reg,
|
||||
sizeof(pcb->pcb_vfpstate.reg));
|
||||
pcb->pcb_vfpstate.fpscr = vfp->mcv_fpscr;
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -163,8 +171,6 @@ get_mcontext(struct thread *td, mcontext_t *mcp, int clear_ret)
|
||||
{
|
||||
struct trapframe *tf = td->td_frame;
|
||||
__greg_t *gr = mcp->__gregs;
|
||||
mcontext_vfp_t mcontext_vfp;
|
||||
int rv;
|
||||
|
||||
if (clear_ret & GET_MC_CLEAR_RET) {
|
||||
gr[_REG_R0] = 0;
|
||||
@ -189,19 +195,9 @@ get_mcontext(struct thread *td, mcontext_t *mcp, int clear_ret)
|
||||
gr[_REG_LR] = tf->tf_usr_lr;
|
||||
gr[_REG_PC] = tf->tf_pc;
|
||||
|
||||
#ifdef VFP
|
||||
if (mcp->mc_vfp_size != sizeof(mcontext_vfp_t))
|
||||
return (EINVAL);
|
||||
get_vfpcontext(td, &mcontext_vfp);
|
||||
#else
|
||||
bzero(&mcontext_vfp, sizeof(mcontext_vfp));
|
||||
#endif
|
||||
|
||||
if (mcp->mc_vfp_ptr != NULL) {
|
||||
rv = copyout(&mcontext_vfp, mcp->mc_vfp_ptr, sizeof(mcontext_vfp));
|
||||
if (rv != 0)
|
||||
return (rv);
|
||||
}
|
||||
mcp->mc_vfp_size = 0;
|
||||
mcp->mc_vfp_ptr = NULL;
|
||||
memset(&mcp->mc_spare, 0, sizeof(mcp->mc_spare));
|
||||
|
||||
return (0);
|
||||
}
|
||||
@ -315,6 +311,16 @@ sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
|
||||
/* Populate the siginfo frame. */
|
||||
bzero(&frame, sizeof(frame));
|
||||
get_mcontext(td, &frame.sf_uc.uc_mcontext, 0);
|
||||
|
||||
#ifdef VFP
|
||||
get_vfpcontext(td, &frame.sf_vfp);
|
||||
frame.sf_uc.uc_mcontext.mc_vfp_size = sizeof(fp->sf_vfp);
|
||||
frame.sf_uc.uc_mcontext.mc_vfp_ptr = &fp->sf_vfp;
|
||||
#else
|
||||
frame.sf_uc.uc_mcontext.mc_vfp_size = 0;
|
||||
frame.sf_uc.uc_mcontext.mc_vfp_ptr = NULL;
|
||||
#endif
|
||||
|
||||
frame.sf_si = ksi->ksi_info;
|
||||
frame.sf_uc.uc_sigmask = *mask;
|
||||
frame.sf_uc.uc_stack = td->td_sigstk;
|
||||
|
@ -98,7 +98,7 @@ error_to_xattrerror(int attrnamespace, int error)
|
||||
}
|
||||
|
||||
static int
|
||||
xatrr_to_extattr(const char *uattrname, int *attrnamespace, char *attrname)
|
||||
xattr_to_extattr(const char *uattrname, int *attrnamespace, char *attrname)
|
||||
{
|
||||
char uname[LINUX_XATTR_NAME_MAX + 1], *dot;
|
||||
size_t len, cplen;
|
||||
@ -255,7 +255,7 @@ removexattr(struct thread *td, struct removexattr_args *args)
|
||||
char attrname[LINUX_XATTR_NAME_MAX + 1];
|
||||
int attrnamespace, error;
|
||||
|
||||
error = xatrr_to_extattr(args->name, &attrnamespace, attrname);
|
||||
error = xattr_to_extattr(args->name, &attrnamespace, attrname);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
if (args->path != NULL)
|
||||
@ -312,7 +312,7 @@ getxattr(struct thread *td, struct getxattr_args *args)
|
||||
char attrname[LINUX_XATTR_NAME_MAX + 1];
|
||||
int attrnamespace, error;
|
||||
|
||||
error = xatrr_to_extattr(args->name, &attrnamespace, attrname);
|
||||
error = xattr_to_extattr(args->name, &attrnamespace, attrname);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
if (args->path != NULL)
|
||||
@ -378,7 +378,7 @@ setxattr(struct thread *td, struct setxattr_args *args)
|
||||
if ((args->flags & ~(LINUX_XATTR_FLAGS)) != 0 ||
|
||||
args->flags == (LINUX_XATTR_FLAGS))
|
||||
return (EINVAL);
|
||||
error = xatrr_to_extattr(args->name, &attrnamespace, attrname);
|
||||
error = xattr_to_extattr(args->name, &attrnamespace, attrname);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
|
||||
|
@ -36,6 +36,7 @@ riscv/riscv/bus_machdep.c standard
|
||||
riscv/riscv/bus_space_asm.S standard
|
||||
riscv/riscv/busdma_bounce.c standard
|
||||
riscv/riscv/busdma_machdep.c standard
|
||||
riscv/riscv/cache.c standard
|
||||
riscv/riscv/clock.c standard
|
||||
riscv/riscv/copyinout.S standard
|
||||
riscv/riscv/cpufunc_asm.S standard
|
||||
@ -83,5 +84,7 @@ riscv/vmm/vmm_riscv.c optional vmm
|
||||
riscv/vmm/vmm_sbi.c optional vmm
|
||||
riscv/vmm/vmm_switch.S optional vmm
|
||||
|
||||
riscv/thead/thead.c standard
|
||||
|
||||
# Zstd
|
||||
contrib/zstd/lib/freebsd/zstd_kfreebsd.c optional zstdio compile-with ${ZSTD_C}
|
||||
|
@ -158,7 +158,7 @@ SYSCTL_INT(_hw_ena, OID_AUTO, enable_9k_mbufs, CTLFLAG_RDTUN,
|
||||
int ena_force_large_llq_header = ENA_LLQ_HEADER_SIZE_POLICY_DEFAULT;
|
||||
SYSCTL_INT(_hw_ena, OID_AUTO, force_large_llq_header, CTLFLAG_RDTUN,
|
||||
&ena_force_large_llq_header, 0,
|
||||
"Change default LLQ entry size received from the device\n");
|
||||
"Change default LLQ entry size received from the device");
|
||||
|
||||
int ena_rss_table_size = ENA_RX_RSS_TABLE_SIZE;
|
||||
|
||||
|
@ -122,6 +122,7 @@ struct hms_softc {
|
||||
hid_size_t isize;
|
||||
uint32_t drift_cnt;
|
||||
uint32_t drift_thresh;
|
||||
struct hid_location wheel_loc;
|
||||
#endif
|
||||
};
|
||||
|
||||
@ -131,6 +132,7 @@ hms_intr(void *context, void *buf, hid_size_t len)
|
||||
{
|
||||
struct hidmap *hm = context;
|
||||
struct hms_softc *sc = device_get_softc(hm->dev);
|
||||
int32_t wheel;
|
||||
|
||||
if (len > sc->isize)
|
||||
len = sc->isize;
|
||||
@ -140,8 +142,18 @@ hms_intr(void *context, void *buf, hid_size_t len)
|
||||
* to return last report data in sampling mode even after touch has
|
||||
* been ended. That results in cursor drift. Filter out such a
|
||||
* reports through comparing with previous one.
|
||||
*
|
||||
* Except this results in dropping consecutive mouse wheel events,
|
||||
* because differently from cursor movement they always move by the
|
||||
* same amount. So, don't do it when there's mouse wheel movement.
|
||||
*/
|
||||
if (len == sc->last_irsize && memcmp(buf, sc->last_ir, len) == 0) {
|
||||
if (sc->wheel_loc.size != 0)
|
||||
wheel = hid_get_data(buf, len, &sc->wheel_loc);
|
||||
else
|
||||
wheel = 0;
|
||||
|
||||
if (len == sc->last_irsize && memcmp(buf, sc->last_ir, len) == 0 &&
|
||||
wheel == 0) {
|
||||
sc->drift_cnt++;
|
||||
if (sc->drift_thresh != 0 && sc->drift_cnt >= sc->drift_thresh)
|
||||
return;
|
||||
@ -285,9 +297,25 @@ hms_attach(device_t dev)
|
||||
/* Count number of input usages of variable type mapped to buttons */
|
||||
for (hi = sc->hm.hid_items;
|
||||
hi < sc->hm.hid_items + sc->hm.nhid_items;
|
||||
hi++)
|
||||
hi++) {
|
||||
if (hi->type == HIDMAP_TYPE_VARIABLE && hi->evtype == EV_KEY)
|
||||
nbuttons++;
|
||||
#ifdef IICHID_SAMPLING
|
||||
/*
|
||||
* Make note of which part of the report descriptor is the wheel.
|
||||
*/
|
||||
if (hi->type == HIDMAP_TYPE_VARIABLE &&
|
||||
hi->evtype == EV_REL && hi->code == REL_WHEEL) {
|
||||
sc->wheel_loc = hi->loc;
|
||||
/*
|
||||
* Account for the leading Report ID byte
|
||||
* if it is a multi-report device.
|
||||
*/
|
||||
if (hi->id != 0)
|
||||
sc->wheel_loc.pos += 8;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* announce information about the mouse */
|
||||
device_printf(dev, "%d buttons and [%s%s%s%s%s] coordinates ID=%u\n",
|
||||
|
@ -409,7 +409,7 @@ mlx5e_tls_snd_tag_alloc(if_t ifp, union if_snd_tag_alloc_params *params,
|
||||
if (priv->gone != 0 || priv->tls.init == 0)
|
||||
return (EOPNOTSUPP);
|
||||
|
||||
ptag = uma_zalloc(priv->tls.zone, M_WAITOK);
|
||||
ptag = uma_zalloc(priv->tls.zone, M_NOWAIT);
|
||||
if (ptag == NULL)
|
||||
return (ENOMEM);
|
||||
|
||||
|
@ -3404,6 +3404,51 @@ mlx5e_set_rx_mode(if_t ifp)
|
||||
queue_work(priv->wq, &priv->set_rx_mode_work);
|
||||
}
|
||||
|
||||
static bool
|
||||
mlx5e_is_ipsec_capable(struct mlx5_core_dev *mdev)
|
||||
{
|
||||
#ifdef IPSEC_OFFLOAD
|
||||
if ((mlx5_ipsec_device_caps(mdev) & MLX5_IPSEC_CAP_PACKET_OFFLOAD) != 0)
|
||||
return (true);
|
||||
#endif
|
||||
return (false);
|
||||
}
|
||||
|
||||
static bool
|
||||
mlx5e_is_ratelimit_capable(struct mlx5_core_dev *mdev)
|
||||
{
|
||||
#ifdef RATELIMIT
|
||||
if (MLX5_CAP_GEN(mdev, qos) &&
|
||||
MLX5_CAP_QOS(mdev, packet_pacing))
|
||||
return (true);
|
||||
#endif
|
||||
return (false);
|
||||
}
|
||||
|
||||
static bool
|
||||
mlx5e_is_tlstx_capable(struct mlx5_core_dev *mdev)
|
||||
{
|
||||
#ifdef KERN_TLS
|
||||
if (MLX5_CAP_GEN(mdev, tls_tx) != 0 &&
|
||||
MLX5_CAP_GEN(mdev, log_max_dek) != 0)
|
||||
return (true);
|
||||
#endif
|
||||
return (false);
|
||||
}
|
||||
|
||||
static bool
|
||||
mlx5e_is_tlsrx_capable(struct mlx5_core_dev *mdev)
|
||||
{
|
||||
#ifdef KERN_TLS
|
||||
if (MLX5_CAP_GEN(mdev, tls_rx) != 0 &&
|
||||
MLX5_CAP_GEN(mdev, log_max_dek) != 0 &&
|
||||
MLX5_CAP_FLOWTABLE_NIC_RX(mdev,
|
||||
ft_field_support.outer_ip_version) != 0)
|
||||
return (true);
|
||||
#endif
|
||||
return (false);
|
||||
}
|
||||
|
||||
static int
|
||||
mlx5e_ioctl(if_t ifp, u_long command, caddr_t data)
|
||||
{
|
||||
@ -3507,6 +3552,24 @@ mlx5e_ioctl(if_t ifp, u_long command, caddr_t data)
|
||||
drv_ioctl_data = (struct siocsifcapnv_driver_data *)data;
|
||||
PRIV_LOCK(priv);
|
||||
siocsifcap_driver:
|
||||
if (!mlx5e_is_tlstx_capable(priv->mdev)) {
|
||||
drv_ioctl_data->reqcap &= ~(IFCAP_TXTLS4 |
|
||||
IFCAP_TXTLS6);
|
||||
}
|
||||
if (!mlx5e_is_tlsrx_capable(priv->mdev)) {
|
||||
drv_ioctl_data->reqcap &= ~(
|
||||
IFCAP2_BIT(IFCAP2_RXTLS4) |
|
||||
IFCAP2_BIT(IFCAP2_RXTLS6));
|
||||
}
|
||||
if (!mlx5e_is_ipsec_capable(priv->mdev)) {
|
||||
drv_ioctl_data->reqcap &=
|
||||
~IFCAP2_BIT(IFCAP2_IPSEC_OFFLOAD);
|
||||
}
|
||||
if (!mlx5e_is_ratelimit_capable(priv->mdev)) {
|
||||
drv_ioctl_data->reqcap &= ~(IFCAP_TXTLS_RTLMT |
|
||||
IFCAP_TXRTLMT);
|
||||
}
|
||||
|
||||
mask = drv_ioctl_data->reqcap ^ if_getcapenable(ifp);
|
||||
|
||||
if (mask & IFCAP_TXCSUM) {
|
||||
@ -4535,29 +4598,20 @@ mlx5e_create_ifp(struct mlx5_core_dev *mdev)
|
||||
if_setcapabilitiesbit(ifp, IFCAP_TSO | IFCAP_VLAN_HWTSO, 0);
|
||||
if_setcapabilitiesbit(ifp, IFCAP_HWSTATS | IFCAP_HWRXTSTMP, 0);
|
||||
if_setcapabilitiesbit(ifp, IFCAP_MEXTPG, 0);
|
||||
#ifdef KERN_TLS
|
||||
if (MLX5_CAP_GEN(mdev, tls_tx) != 0 &&
|
||||
MLX5_CAP_GEN(mdev, log_max_dek) != 0)
|
||||
if (mlx5e_is_tlstx_capable(mdev))
|
||||
if_setcapabilitiesbit(ifp, IFCAP_TXTLS4 | IFCAP_TXTLS6, 0);
|
||||
if (MLX5_CAP_GEN(mdev, tls_rx) != 0 &&
|
||||
MLX5_CAP_GEN(mdev, log_max_dek) != 0 &&
|
||||
MLX5_CAP_FLOWTABLE_NIC_RX(mdev,
|
||||
ft_field_support.outer_ip_version) != 0)
|
||||
if (mlx5e_is_tlsrx_capable(mdev))
|
||||
if_setcapabilities2bit(ifp, IFCAP2_BIT(IFCAP2_RXTLS4) |
|
||||
IFCAP2_BIT(IFCAP2_RXTLS6), 0);
|
||||
#endif
|
||||
#ifdef RATELIMIT
|
||||
if (MLX5_CAP_GEN(mdev, qos) &&
|
||||
MLX5_CAP_QOS(mdev, packet_pacing))
|
||||
if_setcapabilitiesbit(ifp, IFCAP_TXRTLMT | IFCAP_TXTLS_RTLMT,
|
||||
0);
|
||||
#endif
|
||||
if (mlx5e_is_ratelimit_capable(mdev)) {
|
||||
if_setcapabilitiesbit(ifp, IFCAP_TXRTLMT, 0);
|
||||
if (mlx5e_is_tlstx_capable(mdev))
|
||||
if_setcapabilitiesbit(ifp, IFCAP_TXTLS_RTLMT, 0);
|
||||
}
|
||||
if_setcapabilitiesbit(ifp, IFCAP_VXLAN_HWCSUM | IFCAP_VXLAN_HWTSO, 0);
|
||||
#ifdef IPSEC_OFFLOAD
|
||||
if (mlx5_ipsec_device_caps(mdev) & MLX5_IPSEC_CAP_PACKET_OFFLOAD)
|
||||
if (mlx5e_is_ipsec_capable(mdev))
|
||||
if_setcapabilities2bit(ifp, IFCAP2_BIT(IFCAP2_IPSEC_OFFLOAD),
|
||||
0);
|
||||
#endif
|
||||
|
||||
if_setsndtagallocfn(ifp, mlx5e_snd_tag_alloc);
|
||||
#ifdef RATELIMIT
|
||||
|
@ -67,6 +67,24 @@ struct dummy_softc {
|
||||
struct mtx *lock;
|
||||
};
|
||||
|
||||
static bool
|
||||
dummy_active(struct dummy_softc *sc)
|
||||
{
|
||||
struct dummy_chan *ch;
|
||||
int i;
|
||||
|
||||
snd_mtxassert(sc->lock);
|
||||
|
||||
for (i = 0; i < sc->chnum; i++) {
|
||||
ch = &sc->chans[i];
|
||||
if (ch->run)
|
||||
return (true);
|
||||
}
|
||||
|
||||
/* No channel is running at the moment. */
|
||||
return (false);
|
||||
}
|
||||
|
||||
static void
|
||||
dummy_chan_io(void *arg)
|
||||
{
|
||||
@ -74,7 +92,9 @@ dummy_chan_io(void *arg)
|
||||
struct dummy_chan *ch;
|
||||
int i = 0;
|
||||
|
||||
snd_mtxlock(sc->lock);
|
||||
/* Do not reschedule if no channel is running. */
|
||||
if (!dummy_active(sc))
|
||||
return;
|
||||
|
||||
for (i = 0; i < sc->chnum; i++) {
|
||||
ch = &sc->chans[i];
|
||||
@ -89,8 +109,6 @@ dummy_chan_io(void *arg)
|
||||
snd_mtxlock(sc->lock);
|
||||
}
|
||||
callout_schedule(&sc->callout, 1);
|
||||
|
||||
snd_mtxunlock(sc->lock);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -179,15 +197,15 @@ dummy_chan_trigger(kobj_t obj, void *data, int go)
|
||||
|
||||
switch (go) {
|
||||
case PCMTRIG_START:
|
||||
if (!callout_active(&sc->callout))
|
||||
callout_reset(&sc->callout, 1, dummy_chan_io, sc);
|
||||
ch->ptr = 0;
|
||||
ch->run = 1;
|
||||
callout_reset(&sc->callout, 1, dummy_chan_io, sc);
|
||||
break;
|
||||
case PCMTRIG_STOP:
|
||||
case PCMTRIG_ABORT:
|
||||
ch->run = 0;
|
||||
if (callout_active(&sc->callout))
|
||||
/* If all channels are stopped, stop the callout as well. */
|
||||
if (!dummy_active(sc))
|
||||
callout_stop(&sc->callout);
|
||||
default:
|
||||
break;
|
||||
@ -292,6 +310,7 @@ dummy_attach(device_t dev)
|
||||
sc = device_get_softc(dev);
|
||||
sc->dev = dev;
|
||||
sc->lock = snd_mtxcreate(device_get_nameunit(dev), "snd_dummy softc");
|
||||
callout_init_mtx(&sc->callout, sc->lock, 0);
|
||||
|
||||
sc->cap_fmts[0] = SND_FORMAT(AFMT_S32_LE, 2, 0);
|
||||
sc->cap_fmts[1] = SND_FORMAT(AFMT_S24_LE, 2, 0);
|
||||
@ -316,7 +335,6 @@ dummy_attach(device_t dev)
|
||||
if (pcm_register(dev, status))
|
||||
return (ENXIO);
|
||||
mixer_init(dev, &dummy_mixer_class, sc);
|
||||
callout_init(&sc->callout, 1);
|
||||
|
||||
return (0);
|
||||
}
|
||||
@ -327,8 +345,8 @@ dummy_detach(device_t dev)
|
||||
struct dummy_softc *sc = device_get_softc(dev);
|
||||
int err;
|
||||
|
||||
callout_drain(&sc->callout);
|
||||
err = pcm_unregister(dev);
|
||||
callout_drain(&sc->callout);
|
||||
snd_mtxfree(sc->lock);
|
||||
|
||||
return (err);
|
||||
|
@ -309,14 +309,7 @@ chn_wakeup(struct pcm_channel *c)
|
||||
if (CHN_EMPTY(c, children.busy)) {
|
||||
if (SEL_WAITING(sndbuf_getsel(bs)) && chn_polltrigger(c))
|
||||
selwakeuppri(sndbuf_getsel(bs), PRIBIO);
|
||||
if (c->flags & CHN_F_SLEEPING) {
|
||||
/*
|
||||
* Ok, I can just panic it right here since it is
|
||||
* quite obvious that we never allow multiple waiters
|
||||
* from userland. I'm too generous...
|
||||
*/
|
||||
CHN_BROADCAST(&c->intr_cv);
|
||||
}
|
||||
CHN_BROADCAST(&c->intr_cv);
|
||||
} else {
|
||||
CHN_FOREACH(ch, c, children.busy) {
|
||||
CHN_LOCK(ch);
|
||||
@ -332,15 +325,11 @@ chn_sleep(struct pcm_channel *c, int timeout)
|
||||
int ret;
|
||||
|
||||
CHN_LOCKASSERT(c);
|
||||
KASSERT((c->flags & CHN_F_SLEEPING) == 0,
|
||||
("%s(): entered with CHN_F_SLEEPING", __func__));
|
||||
|
||||
if (c->flags & CHN_F_DEAD)
|
||||
return (EINVAL);
|
||||
|
||||
c->flags |= CHN_F_SLEEPING;
|
||||
ret = cv_timedwait_sig(&c->intr_cv, c->lock, timeout);
|
||||
c->flags &= ~CHN_F_SLEEPING;
|
||||
|
||||
return ((c->flags & CHN_F_DEAD) ? EINVAL : ret);
|
||||
}
|
||||
@ -2318,44 +2307,46 @@ chn_trigger(struct pcm_channel *c, int go)
|
||||
if (go == c->trigger)
|
||||
return (0);
|
||||
|
||||
if (snd_verbose > 3) {
|
||||
device_printf(c->dev, "%s() %s: calling go=0x%08x , "
|
||||
"prev=0x%08x\n", __func__, c->name, go, c->trigger);
|
||||
}
|
||||
|
||||
c->trigger = go;
|
||||
ret = CHANNEL_TRIGGER(c->methods, c->devinfo, go);
|
||||
if (ret != 0)
|
||||
return (ret);
|
||||
|
||||
CHN_UNLOCK(c);
|
||||
PCM_LOCK(d);
|
||||
CHN_LOCK(c);
|
||||
|
||||
/*
|
||||
* Do nothing if another thread set a different trigger while we had
|
||||
* dropped the mutex.
|
||||
*/
|
||||
if (go != c->trigger) {
|
||||
PCM_UNLOCK(d);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Use the SAFE variants to prevent inserting/removing an already
|
||||
* existing/missing element.
|
||||
*/
|
||||
switch (go) {
|
||||
case PCMTRIG_START:
|
||||
if (snd_verbose > 3)
|
||||
device_printf(c->dev,
|
||||
"%s() %s: calling go=0x%08x , "
|
||||
"prev=0x%08x\n", __func__, c->name, go,
|
||||
c->trigger);
|
||||
if (c->trigger != PCMTRIG_START) {
|
||||
c->trigger = go;
|
||||
CHN_UNLOCK(c);
|
||||
PCM_LOCK(d);
|
||||
CHN_INSERT_HEAD(d, c, channels.pcm.busy);
|
||||
PCM_UNLOCK(d);
|
||||
CHN_LOCK(c);
|
||||
chn_syncstate(c);
|
||||
}
|
||||
CHN_INSERT_HEAD_SAFE(d, c, channels.pcm.busy);
|
||||
PCM_UNLOCK(d);
|
||||
chn_syncstate(c);
|
||||
break;
|
||||
case PCMTRIG_STOP:
|
||||
case PCMTRIG_ABORT:
|
||||
if (snd_verbose > 3)
|
||||
device_printf(c->dev,
|
||||
"%s() %s: calling go=0x%08x , "
|
||||
"prev=0x%08x\n", __func__, c->name, go,
|
||||
c->trigger);
|
||||
if (c->trigger == PCMTRIG_START) {
|
||||
c->trigger = go;
|
||||
CHN_UNLOCK(c);
|
||||
PCM_LOCK(d);
|
||||
CHN_REMOVE(d, c, channels.pcm.busy);
|
||||
PCM_UNLOCK(d);
|
||||
CHN_LOCK(c);
|
||||
}
|
||||
CHN_REMOVE_SAFE(d, c, channels.pcm.busy);
|
||||
PCM_UNLOCK(d);
|
||||
break;
|
||||
default:
|
||||
PCM_UNLOCK(d);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -354,7 +354,7 @@ enum {
|
||||
#define CHN_F_RUNNING 0x00000004 /* dma is running */
|
||||
#define CHN_F_TRIGGERED 0x00000008
|
||||
#define CHN_F_NOTRIGGER 0x00000010
|
||||
#define CHN_F_SLEEPING 0x00000020
|
||||
/* unused 0x00000020 */
|
||||
|
||||
#define CHN_F_NBIO 0x00000040 /* do non-blocking i/o */
|
||||
#define CHN_F_MMAP 0x00000080 /* has been mmap()ed */
|
||||
@ -362,7 +362,7 @@ enum {
|
||||
#define CHN_F_BUSY 0x00000100 /* has been opened */
|
||||
#define CHN_F_DIRTY 0x00000200 /* need re-config */
|
||||
#define CHN_F_DEAD 0x00000400 /* too many errors, dead, mdk */
|
||||
#define CHN_F_SILENCE 0x00000800 /* silence, nil, null, yada */
|
||||
/* unused 0x00000800 */
|
||||
|
||||
#define CHN_F_HAS_SIZE 0x00001000 /* user set block size */
|
||||
#define CHN_F_HAS_VCHAN 0x00002000 /* vchan master */
|
||||
@ -381,14 +381,14 @@ enum {
|
||||
"\002ABORTING" \
|
||||
"\003RUNNING" \
|
||||
"\004TRIGGERED" \
|
||||
/* \006 */ \
|
||||
"\005NOTRIGGER" \
|
||||
"\006SLEEPING" \
|
||||
"\007NBIO" \
|
||||
"\010MMAP" \
|
||||
"\011BUSY" \
|
||||
"\012DIRTY" \
|
||||
"\013DEAD" \
|
||||
"\014SILENCE" \
|
||||
/* \014 */ \
|
||||
"\015HAS_SIZE" \
|
||||
"\016HAS_VCHAN" \
|
||||
"\017VCHAN_PASSTHROUGH" \
|
||||
|
@ -137,7 +137,7 @@ dsp_destroy_dev(device_t dev)
|
||||
struct snddev_info *d;
|
||||
|
||||
d = device_get_softc(dev);
|
||||
destroy_dev_sched(d->dsp_dev);
|
||||
destroy_dev(d->dsp_dev);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -177,7 +177,7 @@ dsp_close(void *data)
|
||||
|
||||
d = priv->sc;
|
||||
/* At this point pcm_unregister() will destroy all channels anyway. */
|
||||
if (!DSP_REGISTERED(d) || PCM_DETACHING(d))
|
||||
if (!DSP_REGISTERED(d))
|
||||
goto skip;
|
||||
|
||||
PCM_GIANT_ENTER(d);
|
||||
@ -264,7 +264,7 @@ dsp_open(struct cdev *i_dev, int flags, int mode, struct thread *td)
|
||||
return (ENODEV);
|
||||
|
||||
d = i_dev->si_drv1;
|
||||
if (!DSP_REGISTERED(d) || PCM_DETACHING(d))
|
||||
if (!DSP_REGISTERED(d))
|
||||
return (EBADF);
|
||||
|
||||
priv = malloc(sizeof(*priv), M_DEVBUF, M_WAITOK | M_ZERO);
|
||||
@ -445,7 +445,7 @@ dsp_io_ops(struct dsp_cdevpriv *priv, struct uio *buf)
|
||||
("%s(): io train wreck!", __func__));
|
||||
|
||||
d = priv->sc;
|
||||
if (!DSP_REGISTERED(d) || PCM_DETACHING(d))
|
||||
if (!DSP_REGISTERED(d))
|
||||
return (EBADF);
|
||||
|
||||
PCM_GIANT_ENTER(d);
|
||||
@ -664,7 +664,7 @@ dsp_ioctl(struct cdev *i_dev, u_long cmd, caddr_t arg, int mode,
|
||||
return (err);
|
||||
|
||||
d = priv->sc;
|
||||
if (!DSP_REGISTERED(d) || PCM_DETACHING(d))
|
||||
if (!DSP_REGISTERED(d))
|
||||
return (EBADF);
|
||||
|
||||
PCM_GIANT_ENTER(d);
|
||||
@ -1783,7 +1783,7 @@ dsp_poll(struct cdev *i_dev, int events, struct thread *td)
|
||||
if ((err = devfs_get_cdevpriv((void **)&priv)) != 0)
|
||||
return (err);
|
||||
d = priv->sc;
|
||||
if (!DSP_REGISTERED(d) || PCM_DETACHING(d)) {
|
||||
if (!DSP_REGISTERED(d)) {
|
||||
/* XXX many clients don't understand POLLNVAL */
|
||||
return (events & (POLLHUP | POLLPRI | POLLIN |
|
||||
POLLRDNORM | POLLOUT | POLLWRNORM));
|
||||
@ -1865,7 +1865,7 @@ dsp_mmap_single(struct cdev *i_dev, vm_ooffset_t *offset,
|
||||
if ((err = devfs_get_cdevpriv((void **)&priv)) != 0)
|
||||
return (err);
|
||||
d = priv->sc;
|
||||
if (!DSP_REGISTERED(d) || PCM_DETACHING(d))
|
||||
if (!DSP_REGISTERED(d))
|
||||
return (EINVAL);
|
||||
|
||||
PCM_GIANT_ENTER(d);
|
||||
|
@ -146,7 +146,7 @@ mixer_set_softpcmvol(struct snd_mixer *m, struct snddev_info *d,
|
||||
struct pcm_channel *c;
|
||||
int dropmtx, acquiremtx;
|
||||
|
||||
if (!PCM_REGISTERED(d) || PCM_DETACHING(d))
|
||||
if (!PCM_REGISTERED(d))
|
||||
return (EINVAL);
|
||||
|
||||
if (mtx_owned(m->lock))
|
||||
@ -199,7 +199,7 @@ mixer_set_eq(struct snd_mixer *m, struct snddev_info *d,
|
||||
else
|
||||
return (EINVAL);
|
||||
|
||||
if (!PCM_REGISTERED(d) || PCM_DETACHING(d))
|
||||
if (!PCM_REGISTERED(d))
|
||||
return (EINVAL);
|
||||
|
||||
if (mtx_owned(m->lock))
|
||||
@ -1053,7 +1053,7 @@ mixer_open(struct cdev *i_dev, int flags, int mode, struct thread *td)
|
||||
|
||||
m = i_dev->si_drv1;
|
||||
d = device_get_softc(m->dev);
|
||||
if (!PCM_REGISTERED(d) || PCM_DETACHING(d))
|
||||
if (!PCM_REGISTERED(d))
|
||||
return (EBADF);
|
||||
|
||||
/* XXX Need Giant magic entry ??? */
|
||||
@ -1209,7 +1209,7 @@ mixer_ioctl(struct cdev *i_dev, u_long cmd, caddr_t arg, int mode,
|
||||
return (EBADF);
|
||||
|
||||
d = device_get_softc(((struct snd_mixer *)i_dev->si_drv1)->dev);
|
||||
if (!PCM_REGISTERED(d) || PCM_DETACHING(d))
|
||||
if (!PCM_REGISTERED(d))
|
||||
return (EBADF);
|
||||
|
||||
PCM_GIANT_ENTER(d);
|
||||
@ -1447,7 +1447,7 @@ mixer_oss_mixerinfo(struct cdev *i_dev, oss_mixerinfo *mi)
|
||||
for (i = 0; pcm_devclass != NULL &&
|
||||
i < devclass_get_maxunit(pcm_devclass); i++) {
|
||||
d = devclass_get_softc(pcm_devclass, i);
|
||||
if (!PCM_REGISTERED(d) || PCM_DETACHING(d)) {
|
||||
if (!PCM_REGISTERED(d)) {
|
||||
if ((mi->dev == -1 && i == snd_unit) || mi->dev == i) {
|
||||
mixer_oss_mixerinfo_unavail(mi, i);
|
||||
return (0);
|
||||
|
@ -211,40 +211,53 @@ static void
|
||||
pcm_killchans(struct snddev_info *d)
|
||||
{
|
||||
struct pcm_channel *ch;
|
||||
bool found;
|
||||
bool again;
|
||||
|
||||
PCM_BUSYASSERT(d);
|
||||
do {
|
||||
found = false;
|
||||
KASSERT(!PCM_REGISTERED(d), ("%s(): still registered\n", __func__));
|
||||
|
||||
for (;;) {
|
||||
again = false;
|
||||
/* Make sure all channels are stopped. */
|
||||
CHN_FOREACH(ch, d, channels.pcm) {
|
||||
CHN_LOCK(ch);
|
||||
/*
|
||||
* Make sure no channel has went to sleep in the
|
||||
* meantime.
|
||||
*/
|
||||
chn_shutdown(ch);
|
||||
/*
|
||||
* We have to give a thread sleeping in chn_sleep() a
|
||||
* chance to observe that the channel is dead.
|
||||
*/
|
||||
if ((ch->flags & CHN_F_SLEEPING) == 0) {
|
||||
found = true;
|
||||
if (ch->intr_cv.cv_waiters == 0 && CHN_STOPPED(ch) &&
|
||||
ch->inprog == 0) {
|
||||
CHN_UNLOCK(ch);
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
chn_shutdown(ch);
|
||||
if (ch->direction == PCMDIR_PLAY)
|
||||
chn_flush(ch);
|
||||
else
|
||||
chn_abort(ch);
|
||||
CHN_UNLOCK(ch);
|
||||
again = true;
|
||||
}
|
||||
|
||||
/*
|
||||
* All channels are still sleeping. Sleep for a bit and try
|
||||
* again to see if any of them is awake now.
|
||||
* Some channels are still active. Sleep for a bit and try
|
||||
* again.
|
||||
*/
|
||||
if (!found) {
|
||||
pause_sbt("pcmkillchans", SBT_1MS * 5, 0, 0);
|
||||
continue;
|
||||
}
|
||||
if (again)
|
||||
pause_sbt("pcmkillchans", mstosbt(5), 0, 0);
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
/* All channels are finally dead. */
|
||||
while (!CHN_EMPTY(d, channels.pcm)) {
|
||||
ch = CHN_FIRST(d, channels.pcm);
|
||||
chn_kill(ch);
|
||||
} while (!CHN_EMPTY(d, channels.pcm));
|
||||
}
|
||||
|
||||
if (d->p_unr != NULL)
|
||||
delete_unrhdr(d->p_unr);
|
||||
if (d->vp_unr != NULL)
|
||||
delete_unrhdr(d->vp_unr);
|
||||
if (d->r_unr != NULL)
|
||||
delete_unrhdr(d->r_unr);
|
||||
if (d->vr_unr != NULL)
|
||||
delete_unrhdr(d->vr_unr);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -512,7 +525,6 @@ int
|
||||
pcm_unregister(device_t dev)
|
||||
{
|
||||
struct snddev_info *d;
|
||||
struct pcm_channel *ch;
|
||||
|
||||
d = device_get_softc(dev);
|
||||
|
||||
@ -524,29 +536,14 @@ pcm_unregister(device_t dev)
|
||||
PCM_LOCK(d);
|
||||
PCM_WAIT(d);
|
||||
|
||||
d->flags |= SD_F_DETACHING;
|
||||
d->flags &= ~SD_F_REGISTERED;
|
||||
|
||||
PCM_ACQUIRE(d);
|
||||
PCM_UNLOCK(d);
|
||||
|
||||
CHN_FOREACH(ch, d, channels.pcm) {
|
||||
CHN_LOCK(ch);
|
||||
/*
|
||||
* Do not wait for the timeout in chn_read()/chn_write(). Wake
|
||||
* up the sleeping thread and kill the channel.
|
||||
*/
|
||||
chn_shutdown(ch);
|
||||
chn_abort(ch);
|
||||
CHN_UNLOCK(ch);
|
||||
}
|
||||
pcm_killchans(d);
|
||||
|
||||
/* remove /dev/sndstat entry first */
|
||||
sndstat_unregister(dev);
|
||||
|
||||
PCM_LOCK(d);
|
||||
d->flags |= SD_F_DYING;
|
||||
d->flags &= ~SD_F_REGISTERED;
|
||||
PCM_UNLOCK(d);
|
||||
PCM_RELEASE_QUICK(d);
|
||||
|
||||
if (d->play_sysctl_tree != NULL) {
|
||||
sysctl_ctx_free(&d->play_sysctl_ctx);
|
||||
@ -557,24 +554,12 @@ pcm_unregister(device_t dev)
|
||||
d->rec_sysctl_tree = NULL;
|
||||
}
|
||||
|
||||
sndstat_unregister(dev);
|
||||
mixer_uninit(dev);
|
||||
dsp_destroy_dev(dev);
|
||||
(void)mixer_uninit(dev);
|
||||
|
||||
pcm_killchans(d);
|
||||
|
||||
PCM_LOCK(d);
|
||||
PCM_RELEASE(d);
|
||||
cv_destroy(&d->cv);
|
||||
PCM_UNLOCK(d);
|
||||
snd_mtxfree(d->lock);
|
||||
if (d->p_unr != NULL)
|
||||
delete_unrhdr(d->p_unr);
|
||||
if (d->vp_unr != NULL)
|
||||
delete_unrhdr(d->vp_unr);
|
||||
if (d->r_unr != NULL)
|
||||
delete_unrhdr(d->r_unr);
|
||||
if (d->vr_unr != NULL)
|
||||
delete_unrhdr(d->vr_unr);
|
||||
|
||||
if (snd_unit == device_get_unit(dev)) {
|
||||
snd_unit = pcm_best_unit(-1);
|
||||
|
@ -104,17 +104,15 @@ struct snd_mixer;
|
||||
#define SD_F_SIMPLEX 0x00000001
|
||||
#define SD_F_AUTOVCHAN 0x00000002
|
||||
#define SD_F_SOFTPCMVOL 0x00000004
|
||||
#define SD_F_DYING 0x00000008
|
||||
#define SD_F_DETACHING 0x00000010
|
||||
#define SD_F_BUSY 0x00000020
|
||||
#define SD_F_MPSAFE 0x00000040
|
||||
#define SD_F_REGISTERED 0x00000080
|
||||
#define SD_F_BITPERFECT 0x00000100
|
||||
#define SD_F_VPC 0x00000200 /* volume-per-channel */
|
||||
#define SD_F_EQ 0x00000400 /* EQ */
|
||||
#define SD_F_EQ_ENABLED 0x00000800 /* EQ enabled */
|
||||
#define SD_F_EQ_BYPASSED 0x00001000 /* EQ bypassed */
|
||||
#define SD_F_EQ_PC 0x00002000 /* EQ per-channel */
|
||||
#define SD_F_BUSY 0x00000008
|
||||
#define SD_F_MPSAFE 0x00000010
|
||||
#define SD_F_REGISTERED 0x00000020
|
||||
#define SD_F_BITPERFECT 0x00000040
|
||||
#define SD_F_VPC 0x00000080 /* volume-per-channel */
|
||||
#define SD_F_EQ 0x00000100 /* EQ */
|
||||
#define SD_F_EQ_ENABLED 0x00000200 /* EQ enabled */
|
||||
#define SD_F_EQ_BYPASSED 0x00000400 /* EQ bypassed */
|
||||
#define SD_F_EQ_PC 0x00000800 /* EQ per-channel */
|
||||
|
||||
#define SD_F_EQ_DEFAULT (SD_F_EQ | SD_F_EQ_ENABLED)
|
||||
#define SD_F_EQ_MASK (SD_F_EQ | SD_F_EQ_ENABLED | \
|
||||
@ -127,26 +125,20 @@ struct snd_mixer;
|
||||
"\001SIMPLEX" \
|
||||
"\002AUTOVCHAN" \
|
||||
"\003SOFTPCMVOL" \
|
||||
"\004DYING" \
|
||||
"\005DETACHING" \
|
||||
"\006BUSY" \
|
||||
"\007MPSAFE" \
|
||||
"\010REGISTERED" \
|
||||
"\011BITPERFECT" \
|
||||
"\012VPC" \
|
||||
"\013EQ" \
|
||||
"\014EQ_ENABLED" \
|
||||
"\015EQ_BYPASSED" \
|
||||
"\016EQ_PC" \
|
||||
"\004BUSY" \
|
||||
"\005MPSAFE" \
|
||||
"\006REGISTERED" \
|
||||
"\007BITPERFECT" \
|
||||
"\010VPC" \
|
||||
"\011EQ" \
|
||||
"\012EQ_ENABLED" \
|
||||
"\013EQ_BYPASSED" \
|
||||
"\014EQ_PC" \
|
||||
"\035PRIO_RD" \
|
||||
"\036PRIO_WR"
|
||||
|
||||
#define PCM_ALIVE(x) ((x) != NULL && (x)->lock != NULL && \
|
||||
!((x)->flags & SD_F_DYING))
|
||||
#define PCM_REGISTERED(x) (PCM_ALIVE(x) && \
|
||||
((x)->flags & SD_F_REGISTERED))
|
||||
|
||||
#define PCM_DETACHING(x) ((x)->flags & SD_F_DETACHING)
|
||||
#define PCM_ALIVE(x) ((x) != NULL && (x)->lock != NULL)
|
||||
#define PCM_REGISTERED(x) (PCM_ALIVE(x) && ((x)->flags & SD_F_REGISTERED))
|
||||
|
||||
#define PCM_CHANCOUNT(d) \
|
||||
(d->playcount + d->pvchancount + d->reccount + d->rvchancount)
|
||||
|
@ -146,20 +146,19 @@ vchan_trigger(kobj_t obj, void *data, int go)
|
||||
int ret, otrigger;
|
||||
|
||||
info = data;
|
||||
c = info->channel;
|
||||
p = c->parentchannel;
|
||||
|
||||
CHN_LOCKASSERT(c);
|
||||
if (!PCMTRIG_COMMON(go) || go == info->trigger)
|
||||
return (0);
|
||||
|
||||
c = info->channel;
|
||||
p = c->parentchannel;
|
||||
otrigger = info->trigger;
|
||||
info->trigger = go;
|
||||
|
||||
CHN_LOCKASSERT(c);
|
||||
|
||||
CHN_UNLOCK(c);
|
||||
CHN_LOCK(p);
|
||||
|
||||
otrigger = info->trigger;
|
||||
info->trigger = go;
|
||||
|
||||
switch (go) {
|
||||
case PCMTRIG_START:
|
||||
if (otrigger != PCMTRIG_START)
|
||||
|
@ -365,6 +365,16 @@ sigqueue_start(void)
|
||||
SIGFILLSET(fastblock_mask);
|
||||
SIG_CANTMASK(fastblock_mask);
|
||||
ast_register(TDA_SIG, ASTR_UNCOND, 0, ast_sig);
|
||||
|
||||
/*
|
||||
* TDA_PSELECT is for the case where the signal mask should be restored
|
||||
* before delivering any signals so that we do not deliver any that are
|
||||
* blocked by the normal thread mask. It is mutually exclusive with
|
||||
* TDA_SIGSUSPEND, which should be used if we *do* want to deliver
|
||||
* signals that are normally blocked, e.g., if it interrupted our sleep.
|
||||
*/
|
||||
ast_register(TDA_PSELECT, ASTR_ASTF_REQUIRED | ASTR_TDP,
|
||||
TDP_OLDMASK, ast_sigsuspend);
|
||||
ast_register(TDA_SIGSUSPEND, ASTR_ASTF_REQUIRED | ASTR_TDP,
|
||||
TDP_OLDMASK, ast_sigsuspend);
|
||||
}
|
||||
|
@ -133,8 +133,10 @@ livedump_start_vnode(struct vnode *vp, int flags, uint8_t compression)
|
||||
if (error != 0)
|
||||
goto out;
|
||||
|
||||
curthread->td_pflags2 |= TDP2_SAN_QUIET;
|
||||
dump_savectx();
|
||||
error = minidumpsys(livedi, true);
|
||||
curthread->td_pflags2 &= ~TDP2_SAN_QUIET;
|
||||
|
||||
EVENTHANDLER_INVOKE(livedumper_finish);
|
||||
out:
|
||||
|
@ -405,6 +405,9 @@ kasan_shadow_check(unsigned long addr, size_t size, bool write,
|
||||
|
||||
if (__predict_false(!kasan_enabled))
|
||||
return;
|
||||
if (__predict_false(curthread != NULL &&
|
||||
(curthread->td_pflags2 & TDP2_SAN_QUIET) != 0))
|
||||
return;
|
||||
if (__predict_false(size == 0))
|
||||
return;
|
||||
if (__predict_false(kasan_md_unsupported(addr)))
|
||||
|
@ -179,6 +179,9 @@ kmsan_report_hook(const void *addr, msan_orig_t *orig, size_t size, size_t off,
|
||||
|
||||
if (__predict_false(KERNEL_PANICKED() || kdb_active || kmsan_reporting))
|
||||
return;
|
||||
if (__predict_false(curthread != NULL &&
|
||||
(curthread->td_pflags2 & TDP2_SAN_QUIET) != 0))
|
||||
return;
|
||||
|
||||
kmsan_reporting = true;
|
||||
__compiler_membar();
|
||||
@ -232,6 +235,9 @@ kmsan_report_inline(msan_orig_t orig, unsigned long pc)
|
||||
|
||||
if (__predict_false(KERNEL_PANICKED() || kdb_active || kmsan_reporting))
|
||||
return;
|
||||
if (__predict_false(curthread != NULL &&
|
||||
(curthread->td_pflags2 & TDP2_SAN_QUIET) != 0))
|
||||
return;
|
||||
|
||||
kmsan_reporting = true;
|
||||
__compiler_membar();
|
||||
|
@ -1049,14 +1049,26 @@ kern_pselect(struct thread *td, int nd, fd_set *in, fd_set *ou, fd_set *ex,
|
||||
if (error != 0)
|
||||
return (error);
|
||||
td->td_pflags |= TDP_OLDMASK;
|
||||
}
|
||||
error = kern_select(td, nd, in, ou, ex, tvp, abi_nfdbits);
|
||||
if (uset != NULL) {
|
||||
/*
|
||||
* Make sure that ast() is called on return to
|
||||
* usermode and TDP_OLDMASK is cleared, restoring old
|
||||
* sigmask.
|
||||
* sigmask. If we didn't get interrupted, then the caller is
|
||||
* likely not expecting a signal to hit that should normally be
|
||||
* blocked by its signal mask, so we restore the mask before
|
||||
* any signals could be delivered.
|
||||
*/
|
||||
ast_sched(td, TDA_SIGSUSPEND);
|
||||
if (error == EINTR) {
|
||||
ast_sched(td, TDA_SIGSUSPEND);
|
||||
} else {
|
||||
/* *select(2) should never restart. */
|
||||
MPASS(error != ERESTART);
|
||||
ast_sched(td, TDA_PSELECT);
|
||||
}
|
||||
}
|
||||
error = kern_select(td, nd, in, ou, ex, tvp, abi_nfdbits);
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
@ -1528,12 +1540,6 @@ kern_poll_kfds(struct thread *td, struct pollfd *kfds, u_int nfds,
|
||||
if (error)
|
||||
return (error);
|
||||
td->td_pflags |= TDP_OLDMASK;
|
||||
/*
|
||||
* Make sure that ast() is called on return to
|
||||
* usermode and TDP_OLDMASK is cleared, restoring old
|
||||
* sigmask.
|
||||
*/
|
||||
ast_sched(td, TDA_SIGSUSPEND);
|
||||
}
|
||||
|
||||
seltdinit(td);
|
||||
@ -1556,6 +1562,22 @@ kern_poll_kfds(struct thread *td, struct pollfd *kfds, u_int nfds,
|
||||
error = EINTR;
|
||||
if (error == EWOULDBLOCK)
|
||||
error = 0;
|
||||
|
||||
if (uset != NULL) {
|
||||
/*
|
||||
* Make sure that ast() is called on return to
|
||||
* usermode and TDP_OLDMASK is cleared, restoring old
|
||||
* sigmask. If we didn't get interrupted, then the caller is
|
||||
* likely not expecting a signal to hit that should normally be
|
||||
* blocked by its signal mask, so we restore the mask before
|
||||
* any signals could be delivered.
|
||||
*/
|
||||
if (error == EINTR)
|
||||
ast_sched(td, TDA_SIGSUSPEND);
|
||||
else
|
||||
ast_sched(td, TDA_PSELECT);
|
||||
}
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
|
@ -136,7 +136,7 @@ SYSCTL_UINT(_kern_ipc_tls, OID_AUTO, ifnet_max_rexmit_pct, CTLFLAG_RWTUN,
|
||||
&ktls_ifnet_max_rexmit_pct, 2,
|
||||
"Max percent bytes retransmitted before ifnet TLS is disabled");
|
||||
|
||||
static bool ktls_offload_enable;
|
||||
static bool ktls_offload_enable = true;
|
||||
SYSCTL_BOOL(_kern_ipc_tls, OID_AUTO, enable, CTLFLAG_RWTUN,
|
||||
&ktls_offload_enable, 0,
|
||||
"Enable support for kernel TLS offload");
|
||||
@ -273,7 +273,7 @@ SYSCTL_COUNTER_U64(_kern_ipc_tls_ifnet, OID_AUTO, reset_failed, CTLFLAG_RD,
|
||||
&ktls_ifnet_reset_failed,
|
||||
"TLS sessions that failed to allocate a new ifnet send tag");
|
||||
|
||||
static int ktls_ifnet_permitted;
|
||||
static int ktls_ifnet_permitted = 1;
|
||||
SYSCTL_UINT(_kern_ipc_tls_ifnet, OID_AUTO, permitted, CTLFLAG_RWTUN,
|
||||
&ktls_ifnet_permitted, 1,
|
||||
"Whether to permit hardware (ifnet) TLS sessions");
|
||||
|
@ -3265,6 +3265,8 @@ kern___realpathat(struct thread *td, int fd, const char *path, char *buf,
|
||||
|
||||
if (nd.ni_vp->v_type == VREG && nd.ni_dvp->v_type != VDIR &&
|
||||
(nd.ni_vp->v_vflag & VV_ROOT) != 0) {
|
||||
struct vnode *covered_vp;
|
||||
|
||||
/*
|
||||
* This happens if vp is a file mount. The call to
|
||||
* vn_fullpath_hardlink can panic if path resolution can't be
|
||||
@ -3274,7 +3276,6 @@ kern___realpathat(struct thread *td, int fd, const char *path, char *buf,
|
||||
* this should have a unique global path since we disallow
|
||||
* mounting on linked files.
|
||||
*/
|
||||
struct vnode *covered_vp;
|
||||
error = vn_lock(nd.ni_vp, LK_SHARED);
|
||||
if (error != 0)
|
||||
goto out;
|
||||
@ -3284,11 +3285,20 @@ kern___realpathat(struct thread *td, int fd, const char *path, char *buf,
|
||||
error = vn_fullpath(covered_vp, &retbuf, &freebuf);
|
||||
vrele(covered_vp);
|
||||
} else {
|
||||
error = vn_fullpath_hardlink(nd.ni_vp, nd.ni_dvp, nd.ni_cnd.cn_nameptr,
|
||||
nd.ni_cnd.cn_namelen, &retbuf, &freebuf, &size);
|
||||
error = vn_fullpath_hardlink(nd.ni_vp, nd.ni_dvp,
|
||||
nd.ni_cnd.cn_nameptr, nd.ni_cnd.cn_namelen, &retbuf,
|
||||
&freebuf, &size);
|
||||
}
|
||||
if (error == 0) {
|
||||
error = copyout(retbuf, buf, size);
|
||||
size_t len;
|
||||
|
||||
len = strlen(retbuf) + 1;
|
||||
if (size < len)
|
||||
error = ENAMETOOLONG;
|
||||
else if (pathseg == UIO_USERSPACE)
|
||||
error = copyout(retbuf, buf, len);
|
||||
else
|
||||
memcpy(buf, retbuf, len);
|
||||
free(freebuf, M_TEMP);
|
||||
}
|
||||
out:
|
||||
|
@ -70,6 +70,8 @@
|
||||
|
||||
#ifdef _KERNEL
|
||||
|
||||
#define PF_PFIL_NOREFRAGMENT 0x80000000
|
||||
|
||||
#if defined(__arm__)
|
||||
#define PF_WANT_32_TO_64_COUNTER
|
||||
#endif
|
||||
@ -2372,7 +2374,8 @@ void pf_poolmask(struct pf_addr *, struct pf_addr*,
|
||||
struct pf_addr *, struct pf_addr *, sa_family_t);
|
||||
void pf_addr_inc(struct pf_addr *, sa_family_t);
|
||||
int pf_max_frag_size(struct mbuf *);
|
||||
int pf_refragment6(struct ifnet *, struct mbuf **, struct m_tag *, bool);
|
||||
int pf_refragment6(struct ifnet *, struct mbuf **, struct m_tag *,
|
||||
struct ifnet *, bool);
|
||||
#endif /* INET6 */
|
||||
|
||||
int pf_multihome_scan_init(int, int, struct pf_pdesc *);
|
||||
|
@ -1112,7 +1112,7 @@ ipsec_encap(struct mbuf **mp, struct secasindex *saidx)
|
||||
#endif
|
||||
struct ip *ip;
|
||||
#ifdef INET
|
||||
int setdf;
|
||||
int setdf = V_ip4_ipsec_dfbit == 1 ? 1: 0;
|
||||
#endif
|
||||
uint8_t itos, proto;
|
||||
|
||||
@ -1122,17 +1122,11 @@ ipsec_encap(struct mbuf **mp, struct secasindex *saidx)
|
||||
case IPVERSION:
|
||||
proto = IPPROTO_IPIP;
|
||||
/*
|
||||
* Collect IP_DF state from the inner header
|
||||
* and honor system-wide control of how to handle it.
|
||||
* Copy IP_DF flag from the inner header if
|
||||
* system-wide control variable is greater than 1.
|
||||
*/
|
||||
switch (V_ip4_ipsec_dfbit) {
|
||||
case 0: /* clear in outer header */
|
||||
case 1: /* set in outer header */
|
||||
setdf = V_ip4_ipsec_dfbit;
|
||||
break;
|
||||
default:/* propagate to outer header */
|
||||
if (V_ip4_ipsec_dfbit > 1)
|
||||
setdf = (ip->ip_off & htons(IP_DF)) != 0;
|
||||
}
|
||||
itos = ip->ip_tos;
|
||||
break;
|
||||
#endif
|
||||
|
@ -7927,6 +7927,7 @@ pf_route6(struct mbuf **m, struct pf_krule *r, struct ifnet *oifp,
|
||||
struct pf_kstate *s, struct pf_pdesc *pd, struct inpcb *inp)
|
||||
{
|
||||
struct mbuf *m0, *md;
|
||||
struct m_tag *mtag;
|
||||
struct sockaddr_in6 dst;
|
||||
struct ip6_hdr *ip6;
|
||||
struct pfi_kkif *nkif = NULL;
|
||||
@ -8053,8 +8054,8 @@ pf_route6(struct mbuf **m, struct pf_krule *r, struct ifnet *oifp,
|
||||
}
|
||||
|
||||
if (pd->dir == PF_IN) {
|
||||
if (pf_test(AF_INET6, PF_OUT, PFIL_FWD, ifp, &m0, inp,
|
||||
&pd->act) != PF_PASS) {
|
||||
if (pf_test(AF_INET6, PF_OUT, PFIL_FWD | PF_PFIL_NOREFRAGMENT,
|
||||
ifp, &m0, inp, &pd->act) != PF_PASS) {
|
||||
SDT_PROBE1(pf, ip6, route_to, drop, __LINE__);
|
||||
goto bad;
|
||||
} else if (m0 == NULL) {
|
||||
@ -8087,6 +8088,14 @@ pf_route6(struct mbuf **m, struct pf_krule *r, struct ifnet *oifp,
|
||||
*/
|
||||
if (IN6_IS_SCOPE_EMBED(&dst.sin6_addr))
|
||||
dst.sin6_addr.s6_addr16[1] = htons(ifp->if_index);
|
||||
mtag = m_tag_find(m0, PACKET_TAG_PF_REASSEMBLED, NULL);
|
||||
if (mtag != NULL) {
|
||||
int ret;
|
||||
ret = pf_refragment6(ifp, &m0, mtag, ifp, true);
|
||||
SDT_PROBE2(pf, ip6, route_to, output, ifp, ret);
|
||||
goto done;
|
||||
}
|
||||
|
||||
if ((u_long)m0->m_pkthdr.len <= ifp->if_mtu) {
|
||||
md = m0;
|
||||
pf_dummynet_route(pd, s, r, ifp, sintosa(&dst), &md);
|
||||
@ -9474,14 +9483,15 @@ eat_pkt:
|
||||
if (s)
|
||||
PF_STATE_UNLOCK(s);
|
||||
|
||||
out:
|
||||
#ifdef INET6
|
||||
/* If reassembled packet passed, create new fragments. */
|
||||
if (af == AF_INET6 && action == PF_PASS && *m0 && dir == PF_OUT &&
|
||||
(! (pflags & PF_PFIL_NOREFRAGMENT)) &&
|
||||
(mtag = m_tag_find(pd.m, PACKET_TAG_PF_REASSEMBLED, NULL)) != NULL)
|
||||
action = pf_refragment6(ifp, m0, mtag, pflags & PFIL_FWD);
|
||||
action = pf_refragment6(ifp, m0, mtag, NULL, pflags & PFIL_FWD);
|
||||
#endif
|
||||
|
||||
out:
|
||||
pf_sctp_multihome_delayed(&pd, kif, s, action);
|
||||
|
||||
return (action);
|
||||
|
@ -42,6 +42,7 @@
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/if_var.h>
|
||||
#include <net/vnet.h>
|
||||
#include <net/pfvar.h>
|
||||
#include <net/if_pflog.h>
|
||||
@ -49,6 +50,8 @@
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <netinet/ip_var.h>
|
||||
#include <netinet6/in6_var.h>
|
||||
#include <netinet6/nd6.h>
|
||||
#include <netinet6/ip6_var.h>
|
||||
#include <netinet6/scope6_var.h>
|
||||
#include <netinet/tcp.h>
|
||||
@ -958,7 +961,7 @@ pf_max_frag_size(struct mbuf *m)
|
||||
|
||||
int
|
||||
pf_refragment6(struct ifnet *ifp, struct mbuf **m0, struct m_tag *mtag,
|
||||
bool forward)
|
||||
struct ifnet *rt, bool forward)
|
||||
{
|
||||
struct mbuf *m = *m0, *t;
|
||||
struct ip6_hdr *hdr;
|
||||
@ -1029,16 +1032,27 @@ pf_refragment6(struct ifnet *ifp, struct mbuf **m0, struct m_tag *mtag,
|
||||
m->m_flags |= M_SKIP_FIREWALL;
|
||||
memset(&pd, 0, sizeof(pd));
|
||||
pd.pf_mtag = pf_find_mtag(m);
|
||||
if (error == 0)
|
||||
if (forward) {
|
||||
MPASS(m->m_pkthdr.rcvif != NULL);
|
||||
ip6_forward(m, 0);
|
||||
} else {
|
||||
(void)ip6_output(m, NULL, NULL, 0, NULL, NULL,
|
||||
NULL);
|
||||
}
|
||||
else
|
||||
if (error != 0) {
|
||||
m_freem(m);
|
||||
continue;
|
||||
}
|
||||
if (rt != NULL) {
|
||||
struct sockaddr_in6 dst;
|
||||
hdr = mtod(m, struct ip6_hdr *);
|
||||
|
||||
bzero(&dst, sizeof(dst));
|
||||
dst.sin6_family = AF_INET6;
|
||||
dst.sin6_len = sizeof(dst);
|
||||
dst.sin6_addr = hdr->ip6_dst;
|
||||
|
||||
nd6_output_ifp(rt, rt, m, &dst, NULL);
|
||||
} else if (forward) {
|
||||
MPASS(m->m_pkthdr.rcvif != NULL);
|
||||
ip6_forward(m, 0);
|
||||
} else {
|
||||
(void)ip6_output(m, NULL, NULL, 0, NULL, NULL,
|
||||
NULL);
|
||||
}
|
||||
}
|
||||
|
||||
return (action);
|
||||
|
@ -69,4 +69,9 @@
|
||||
li tmp, SSTATUS_SUM; \
|
||||
csrc sstatus, tmp
|
||||
|
||||
#define SBI_CALL(ext, func) \
|
||||
li a7, ext; \
|
||||
li a6, func; \
|
||||
ecall
|
||||
|
||||
#endif /* _MACHINE_ASM_H_ */
|
||||
|
@ -35,9 +35,11 @@
|
||||
#ifndef _MACHINE_CPU_H_
|
||||
#define _MACHINE_CPU_H_
|
||||
|
||||
#ifndef LOCORE
|
||||
#include <machine/atomic.h>
|
||||
#include <machine/cpufunc.h>
|
||||
#include <machine/frame.h>
|
||||
#endif
|
||||
|
||||
#define TRAPF_PC(tfp) ((tfp)->tf_sepc)
|
||||
#define TRAPF_USERMODE(tfp) (((tfp)->tf_sstatus & SSTATUS_SPP) == 0)
|
||||
@ -88,6 +90,7 @@
|
||||
#define MMU_SV57 0x4 /* 5-level paging */
|
||||
|
||||
#ifdef _KERNEL
|
||||
#ifndef LOCORE
|
||||
|
||||
extern char btext[];
|
||||
extern char etext[];
|
||||
@ -105,6 +108,7 @@ get_cyclecount(void)
|
||||
return (rdcycle());
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif /* !LOCORE */
|
||||
#endif /* _KERNEL */
|
||||
|
||||
#endif /* !_MACHINE_CPU_H_ */
|
||||
|
@ -44,6 +44,8 @@ breakpoint(void)
|
||||
|
||||
#ifdef _KERNEL
|
||||
|
||||
#include <sys/_null.h>
|
||||
|
||||
#include <machine/riscvreg.h>
|
||||
|
||||
static __inline register_t
|
||||
@ -107,16 +109,42 @@ sfence_vma_page(uintptr_t addr)
|
||||
#define rdinstret() csr_read64(instret)
|
||||
#define rdhpmcounter(n) csr_read64(hpmcounter##n)
|
||||
|
||||
/* Cache hooks. */
|
||||
|
||||
extern int64_t dcache_line_size;
|
||||
extern int64_t icache_line_size;
|
||||
|
||||
#define cpu_dcache_wbinv_range(a, s)
|
||||
#define cpu_dcache_inv_range(a, s)
|
||||
#define cpu_dcache_wb_range(a, s)
|
||||
typedef void (*cache_op_t)(vm_offset_t start, vm_size_t size);
|
||||
|
||||
#define cpu_idcache_wbinv_range(a, s)
|
||||
#define cpu_icache_sync_range(a, s)
|
||||
#define cpu_icache_sync_range_checked(a, s)
|
||||
struct riscv_cache_ops {
|
||||
cache_op_t dcache_wbinv_range;
|
||||
cache_op_t dcache_inv_range;
|
||||
cache_op_t dcache_wb_range;
|
||||
};
|
||||
|
||||
extern struct riscv_cache_ops cache_ops;
|
||||
|
||||
static __inline void
|
||||
cpu_dcache_wbinv_range(vm_offset_t addr, vm_size_t size)
|
||||
{
|
||||
if (cache_ops.dcache_wbinv_range != NULL)
|
||||
cache_ops.dcache_wbinv_range(addr, size);
|
||||
}
|
||||
|
||||
static __inline void
|
||||
cpu_dcache_inv_range(vm_offset_t addr, vm_size_t size)
|
||||
{
|
||||
if (cache_ops.dcache_inv_range != NULL)
|
||||
cache_ops.dcache_inv_range(addr, size);
|
||||
}
|
||||
|
||||
static __inline void
|
||||
cpu_dcache_wb_range(vm_offset_t addr, vm_size_t size)
|
||||
{
|
||||
if (cache_ops.dcache_wb_range != NULL)
|
||||
cache_ops.dcache_wb_range(addr, size);
|
||||
}
|
||||
|
||||
void riscv_cache_install_hooks(struct riscv_cache_ops *, u_int);
|
||||
|
||||
#define cpufunc_nullop() riscv_nullop()
|
||||
|
||||
|
@ -102,6 +102,32 @@ typedef uint64_t pn_t; /* page number */
|
||||
#define PTE_MA_NC (1ul << PTE_MA_SHIFT)
|
||||
#define PTE_MA_IO (2ul << PTE_MA_SHIFT)
|
||||
|
||||
/*
|
||||
* T-HEAD Custom Memory Attribute (MA) bits [63:59].
|
||||
*
|
||||
* bit 59: Trustable (relating to TEE)
|
||||
* bit 60: Shareable (among CPUs, not configurable)
|
||||
* bit 61: Bufferable (writes to device memory)
|
||||
* bit 62: Cacheable
|
||||
* bit 63: Memory Ordering (1 = strongly ordered (device), 0 = default)
|
||||
*
|
||||
* +------+-------+------------------------------------------------------------+
|
||||
* | Mode | Value | Requested Memory Attributes |
|
||||
* +------+-------+------------------------------------------------------------+
|
||||
* | NC | 00110 | Weakly-ordered, non-cacheable, bufferable, shareable, |
|
||||
* | | | non-trustable |
|
||||
* | PMA | 01110 | Weakly-ordered, cacheable, bufferable, shareable, |
|
||||
* | | | non-trustable |
|
||||
* | IO | 10010 | Strongly-ordered, non-cacheable, non-bufferable, |
|
||||
* | | | shareable, non-trustable |
|
||||
* +------+-------+------------------------------------------------------------+
|
||||
*/
|
||||
#define PTE_THEAD_MA_SHIFT 59
|
||||
#define PTE_THEAD_MA_MASK (0x1ful << PTE_THEAD_MA_SHIFT)
|
||||
#define PTE_THEAD_MA_NC (0x6ul << PTE_THEAD_MA_SHIFT)
|
||||
#define PTE_THEAD_MA_NONE (0xeul << PTE_THEAD_MA_SHIFT)
|
||||
#define PTE_THEAD_MA_IO (0x12ul << PTE_THEAD_MA_SHIFT)
|
||||
|
||||
/* Bits 63 - 54 are reserved for future use. */
|
||||
#define PTE_HI_MASK 0xFFC0000000000000ULL
|
||||
|
||||
|
@ -123,6 +123,8 @@
|
||||
#define SBI_REMOTE_SFENCE_VMA_ASID 7
|
||||
#define SBI_SHUTDOWN 8
|
||||
|
||||
#ifndef LOCORE
|
||||
|
||||
#define SBI_CALL0(e, f) SBI_CALL5(e, f, 0, 0, 0, 0, 0)
|
||||
#define SBI_CALL1(e, f, p1) SBI_CALL5(e, f, p1, 0, 0, 0, 0)
|
||||
#define SBI_CALL2(e, f, p1, p2) SBI_CALL5(e, f, p1, p2, 0, 0, 0)
|
||||
@ -242,4 +244,5 @@ sbi_console_getchar(void)
|
||||
void sbi_print_version(void);
|
||||
void sbi_init(void);
|
||||
|
||||
#endif /* !LOCORE */
|
||||
#endif /* !_MACHINE_SBI_H_ */
|
||||
|
37
sys/riscv/include/thead.h
Normal file
37
sys/riscv/include/thead.h
Normal file
@ -0,0 +1,37 @@
|
||||
/*-
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*
|
||||
* Copyright (c) 2024 The FreeBSD Foundation
|
||||
*
|
||||
* This software was developed by Mitchell Horne <mhorne@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.
|
||||
*/
|
||||
#ifndef _RISCV_THEAD_H_
|
||||
#define _RISCV_THEAD_H_
|
||||
|
||||
extern bool has_errata_thead_pbmt;
|
||||
|
||||
void thead_setup_cache(void);
|
||||
|
||||
#endif /* _RISCV_THEAD_H_ */
|
53
sys/riscv/riscv/cache.c
Normal file
53
sys/riscv/riscv/cache.c
Normal file
@ -0,0 +1,53 @@
|
||||
/*-
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*
|
||||
* Copyright (c) 2024 The FreeBSD Foundation
|
||||
*
|
||||
* This software was developed by Mitchell Horne <mhorne@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/systm.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <machine/cpufunc.h>
|
||||
|
||||
struct riscv_cache_ops __read_frequently cache_ops;
|
||||
|
||||
int64_t __read_frequently dcache_line_size; /* The minimum D cache line size */
|
||||
|
||||
static bool cache_initialized;
|
||||
|
||||
void
|
||||
riscv_cache_install_hooks(struct riscv_cache_ops *newops, u_int line_size)
|
||||
{
|
||||
if (cache_initialized)
|
||||
panic("cache hooks already installed!");
|
||||
|
||||
bcopy(newops, &cache_ops, sizeof(cache_ops));
|
||||
dcache_line_size = line_size;
|
||||
|
||||
cache_initialized = true;
|
||||
}
|
@ -52,6 +52,7 @@
|
||||
#include <machine/cpufunc.h>
|
||||
#include <machine/elf.h>
|
||||
#include <machine/md_var.h>
|
||||
#include <machine/thead.h>
|
||||
|
||||
#ifdef FDT
|
||||
#include <dev/fdt/fdt_common.h>
|
||||
@ -463,6 +464,38 @@ identify_cpu_ids(struct cpu_desc *desc)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
handle_thead_quirks(u_int cpu, struct cpu_desc *desc)
|
||||
{
|
||||
if (cpu != 0)
|
||||
return;
|
||||
|
||||
/*
|
||||
* For now, it is assumed that T-HEAD CPUs have both marchid and mimpid
|
||||
* values of zero (although we leave this unchecked). It is true in
|
||||
* practice for the early generations of this hardware (C906, C910,
|
||||
* C920). In the future, the identity checks may need to become more
|
||||
* granular, but until then all known T-HEAD quirks are applied
|
||||
* indiscriminantly.
|
||||
*
|
||||
* Note: any changes in this function relating to has_errata_thead_pbmt
|
||||
* may need to be applied to get_pte_fixup_bits (in locore.S) as well.
|
||||
*/
|
||||
|
||||
has_errata_thead_pbmt = true;
|
||||
thead_setup_cache();
|
||||
}
|
||||
|
||||
static void
|
||||
handle_cpu_quirks(u_int cpu, struct cpu_desc *desc)
|
||||
{
|
||||
switch (mvendorid) {
|
||||
case MVENDORID_THEAD:
|
||||
handle_thead_quirks(cpu, desc);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
identify_cpu(u_int cpu)
|
||||
{
|
||||
@ -472,6 +505,7 @@ identify_cpu(u_int cpu)
|
||||
identify_cpu_features(cpu, desc);
|
||||
|
||||
update_global_capabilities(cpu, desc);
|
||||
handle_cpu_quirks(cpu, desc);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -42,9 +42,11 @@
|
||||
#include "assym.inc"
|
||||
|
||||
#include <machine/asm.h>
|
||||
#include <machine/cpu.h>
|
||||
#include <machine/param.h>
|
||||
#include <machine/riscvreg.h>
|
||||
#include <machine/pte.h>
|
||||
#include <machine/riscvreg.h>
|
||||
#include <machine/sbi.h>
|
||||
|
||||
.globl kernbase
|
||||
.set kernbase, KERNBASE
|
||||
@ -83,8 +85,12 @@ _alt_start:
|
||||
lla t0, boot_hart
|
||||
sw a0, 0(t0)
|
||||
|
||||
/* Load zero as modulep */
|
||||
mv a0, zero
|
||||
/*
|
||||
* Stash the DTB pointer in the callee-saved register s4, and zero s3
|
||||
* to indicate that we have no loader metadata.
|
||||
*/
|
||||
mv s4, a1
|
||||
mv s3, zero
|
||||
j pagetables
|
||||
|
||||
/*
|
||||
@ -104,10 +110,12 @@ _start:
|
||||
.option pop
|
||||
|
||||
/*
|
||||
* Zero a1 to indicate that we have no DTB pointer. It is already
|
||||
* included in the loader(8) metadata.
|
||||
* Stash modulep in the callee-saved register s3, and zero s4 to
|
||||
* indicate that we have no DTB pointer. It is already included in the
|
||||
* loader(8) metadata.
|
||||
*/
|
||||
mv a1, zero
|
||||
mv s3, a0
|
||||
mv s4, zero
|
||||
|
||||
/*
|
||||
* Set up page tables: Our goal is to enable virtual memory, doing the
|
||||
@ -128,19 +136,23 @@ _start:
|
||||
* here and will conditionally enable Sv48 (or higher) later.
|
||||
*
|
||||
* We arrive here with:
|
||||
* a0 - modulep or zero
|
||||
* a1 - zero or dtbp
|
||||
* s3 - modulep or zero
|
||||
* s4 - zero or dtbp
|
||||
*/
|
||||
pagetables:
|
||||
/* Get the kernel's load address (kernstart) in s9 */
|
||||
jal get_physmem
|
||||
|
||||
/* Get PTE attribute bits in s8 */
|
||||
jal get_pte_fixup_bits
|
||||
|
||||
/* Construct 1GB Identity Map (1:1 PA->VA) */
|
||||
lla s1, bootstrap_pt_l1
|
||||
|
||||
srli s2, s9, L1_SHIFT /* kernstart >> L1_SHIFT */
|
||||
andi a5, s2, Ln_ADDR_MASK /* & Ln_ADDR_MASK */
|
||||
li t4, (PTE_KERN)
|
||||
or t4, t4, s8 /* t4 |= pte bits */
|
||||
slli s2, s2, PTE_PPN2_S /* (s2 << PTE_PPN2_S) */
|
||||
or t6, t4, s2
|
||||
|
||||
@ -176,6 +188,7 @@ pagetables:
|
||||
li t2, Ln_ENTRIES /* Build 512 entries */
|
||||
add t3, t4, t2
|
||||
li t0, (PTE_KERN | PTE_X)
|
||||
or t0, t0, s8 /* t0 |= pte bits */
|
||||
1:
|
||||
slli t2, t4, PTE_PPN1_S /* << PTE_PPN1_S */
|
||||
or t5, t0, t2
|
||||
@ -244,8 +257,8 @@ va:
|
||||
|
||||
la t0, initstack
|
||||
sd t0, RISCV_BOOTPARAMS_KERN_STACK(sp)
|
||||
sd a1, RISCV_BOOTPARAMS_DTBP_PHYS(sp)
|
||||
sd a0, RISCV_BOOTPARAMS_MODULEP(sp)
|
||||
sd s4, RISCV_BOOTPARAMS_DTBP_PHYS(sp)
|
||||
sd s3, RISCV_BOOTPARAMS_MODULEP(sp)
|
||||
|
||||
mv a0, sp
|
||||
call _C_LABEL(initriscv) /* Off we go */
|
||||
@ -267,6 +280,28 @@ get_physmem:
|
||||
sub s9, t2, t1 /* s9 = physmem base */
|
||||
ret
|
||||
|
||||
/*
|
||||
* T-HEAD CPUs implement an alternate scheme for PTE attributes that is
|
||||
* incompatible with the RISC-V PTE specification (see the definitions in
|
||||
* pte.h). Worse, it defines a non-zero value for "main" memory, and this must
|
||||
* be set in order to proceed with our new page tables.
|
||||
*
|
||||
* Therefore, we are forced to check the CPU identity here, which is both
|
||||
* inconvenient and fragile.
|
||||
*
|
||||
* Return the required attribute bits in s8. For sane implementations this is
|
||||
* zero.
|
||||
*/
|
||||
get_pte_fixup_bits:
|
||||
mv s8, zero
|
||||
SBI_CALL(SBI_EXT_ID_BASE, SBI_BASE_GET_MVENDORID)
|
||||
li t0, MVENDORID_THEAD
|
||||
xor t0, t0, a1
|
||||
bnez t0, 1f /* branch if a1 != t0 */
|
||||
li s8, PTE_THEAD_MA_NONE
|
||||
1:
|
||||
ret
|
||||
|
||||
.align 4
|
||||
initstack:
|
||||
.space (PAGE_SIZE * KSTACK_PAGES)
|
||||
|
@ -113,10 +113,6 @@ int cold = 1;
|
||||
|
||||
struct kva_md_info kmi;
|
||||
|
||||
int64_t dcache_line_size; /* The minimum D cache line size */
|
||||
int64_t icache_line_size; /* The minimum I cache line size */
|
||||
int64_t idcache_line_size; /* The minimum cache line size */
|
||||
|
||||
#define BOOT_HART_INVALID 0xffffffff
|
||||
uint32_t boot_hart = BOOT_HART_INVALID; /* The hart we booted on. */
|
||||
|
||||
@ -329,17 +325,6 @@ try_load_dtb(caddr_t kmdp)
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
cache_setup(void)
|
||||
{
|
||||
|
||||
/* TODO */
|
||||
|
||||
dcache_line_size = 0;
|
||||
icache_line_size = 0;
|
||||
idcache_line_size = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Fake up a boot descriptor table.
|
||||
*/
|
||||
@ -550,8 +535,6 @@ initriscv(struct riscv_bootparams *rvbp)
|
||||
/* Do basic tuning, hz etc */
|
||||
init_param1();
|
||||
|
||||
cache_setup();
|
||||
|
||||
#ifdef FDT
|
||||
/*
|
||||
* XXX: Unconditionally exclude the lowest 2MB of physical memory, as
|
||||
|
@ -156,6 +156,7 @@
|
||||
#include <machine/md_var.h>
|
||||
#include <machine/pcb.h>
|
||||
#include <machine/sbi.h>
|
||||
#include <machine/thead.h>
|
||||
|
||||
/*
|
||||
* Boundary values for the page table page index space:
|
||||
@ -867,6 +868,11 @@ pmap_bootstrap(vm_paddr_t kernstart, vm_size_t kernlen)
|
||||
memattr_bits[VM_MEMATTR_UNCACHEABLE] = PTE_MA_NC;
|
||||
memattr_bits[VM_MEMATTR_DEVICE] = PTE_MA_IO;
|
||||
memattr_mask = PTE_MA_MASK;
|
||||
} else if (has_errata_thead_pbmt) {
|
||||
memattr_bits[VM_MEMATTR_PMA] = PTE_THEAD_MA_NONE;
|
||||
memattr_bits[VM_MEMATTR_UNCACHEABLE] = PTE_THEAD_MA_NC;
|
||||
memattr_bits[VM_MEMATTR_DEVICE] = PTE_THEAD_MA_IO;
|
||||
memattr_mask = PTE_THEAD_MA_MASK;
|
||||
}
|
||||
|
||||
/* Create a new set of pagetables to run the kernel in. */
|
||||
@ -5013,7 +5019,7 @@ pmap_change_attr_locked(vm_offset_t va, vm_size_t size, int mode)
|
||||
if (anychanged) {
|
||||
pmap_invalidate_range(kernel_pmap, base, tmpva);
|
||||
if (mode == VM_MEMATTR_UNCACHEABLE)
|
||||
cpu_dcache_wbinv_range((void *)base, size);
|
||||
cpu_dcache_wbinv_range(base, size);
|
||||
}
|
||||
|
||||
return (error);
|
||||
|
101
sys/riscv/thead/thead.c
Normal file
101
sys/riscv/thead/thead.c
Normal file
@ -0,0 +1,101 @@
|
||||
/*-
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*
|
||||
* Copyright (c) 2024 The FreeBSD Foundation
|
||||
*
|
||||
* This software was developed by Mitchell Horne <mhorne@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/systm.h>
|
||||
|
||||
#include <machine/thead.h>
|
||||
|
||||
bool has_errata_thead_pbmt = false;
|
||||
|
||||
/* ----------------- dcache ops --------------------- */
|
||||
|
||||
|
||||
/* th.dcache.civa: clean & invalidate at VA stored in t0. */
|
||||
#define THEAD_DCACHE_CIVA ".long 0x0272800b\n"
|
||||
|
||||
/* th.dcache.iva: invalidate at VA stored in t0. */
|
||||
#define THEAD_DCACHE_IVA ".long 0x0262800b\n"
|
||||
|
||||
/* th.dcache.cva: clean at VA stored in t0. */
|
||||
#define THEAD_DCACHE_CVA ".long 0x0252800b\n"
|
||||
|
||||
/* th.sync.s: two-way instruction barrier */
|
||||
#define THEAD_SYNC_S ".long 0x0190000b\n"
|
||||
|
||||
/* MHTODO: we could parse this information from the device tree. */
|
||||
#define THEAD_DCACHE_SIZE 64
|
||||
|
||||
static void
|
||||
thead_cpu_dcache_wbinv_range(vm_offset_t va, vm_size_t len)
|
||||
{
|
||||
register vm_offset_t t0 __asm("t0") = rounddown(va, dcache_line_size);
|
||||
|
||||
for (; t0 < va + len; t0 += dcache_line_size) {
|
||||
__asm __volatile(THEAD_DCACHE_CIVA
|
||||
:: "r" (t0) : "memory");
|
||||
}
|
||||
__asm __volatile(THEAD_SYNC_S ::: "memory");
|
||||
}
|
||||
|
||||
static void
|
||||
thead_cpu_dcache_inv_range(vm_offset_t va, vm_size_t len)
|
||||
{
|
||||
register vm_offset_t t0 __asm("t0") = rounddown(va, dcache_line_size);
|
||||
|
||||
for (; t0 < va + len; t0 += dcache_line_size) {
|
||||
__asm __volatile(THEAD_DCACHE_IVA
|
||||
:: "r" (t0) : "memory");
|
||||
}
|
||||
__asm __volatile(THEAD_SYNC_S ::: "memory");
|
||||
}
|
||||
|
||||
static void
|
||||
thead_cpu_dcache_wb_range(vm_offset_t va, vm_size_t len)
|
||||
{
|
||||
register vm_offset_t t0 __asm("t0") = rounddown(va, dcache_line_size);
|
||||
|
||||
for (; t0 < va + len; t0 += dcache_line_size) {
|
||||
__asm __volatile(THEAD_DCACHE_CVA
|
||||
:: "r" (t0) : "memory");
|
||||
}
|
||||
__asm __volatile(THEAD_SYNC_S ::: "memory");
|
||||
}
|
||||
|
||||
void
|
||||
thead_setup_cache(void)
|
||||
{
|
||||
struct riscv_cache_ops thead_ops;
|
||||
|
||||
thead_ops.dcache_wbinv_range = thead_cpu_dcache_wbinv_range;
|
||||
thead_ops.dcache_inv_range = thead_cpu_dcache_inv_range;
|
||||
thead_ops.dcache_wb_range = thead_cpu_dcache_wb_range;
|
||||
|
||||
riscv_cache_install_hooks(&thead_ops, THEAD_DCACHE_SIZE);
|
||||
}
|
@ -73,7 +73,7 @@
|
||||
* cannot include sys/param.h and should only be updated here.
|
||||
*/
|
||||
#undef __FreeBSD_version
|
||||
#define __FreeBSD_version 1500027
|
||||
#define __FreeBSD_version 1500028
|
||||
|
||||
/*
|
||||
* __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD,
|
||||
|
@ -494,6 +494,7 @@ enum {
|
||||
TDA_RACCT,
|
||||
TDA_MOD1, /* For third party use, before signals are */
|
||||
TAD_MOD2, /* processed .. */
|
||||
TDA_PSELECT, /* For discarding temporary signal mask */
|
||||
TDA_SIG,
|
||||
TDA_KTRACE,
|
||||
TDA_SUSPEND,
|
||||
@ -567,6 +568,7 @@ enum {
|
||||
#define TDP2_SBPAGES 0x00000001 /* Owns sbusy on some pages */
|
||||
#define TDP2_COMPAT32RB 0x00000002 /* compat32 ABI for robust lists */
|
||||
#define TDP2_ACCT 0x00000004 /* Doing accounting */
|
||||
#define TDP2_SAN_QUIET 0x00000008 /* Disable warnings from K(A|M)SAN */
|
||||
|
||||
/*
|
||||
* Reasons that the current thread can not be run yet.
|
||||
|
@ -660,7 +660,7 @@ _kmem_unback(vm_object_t object, vm_offset_t addr, vm_size_t size)
|
||||
m = vm_page_iter_lookup(&pages, atop(offset))) {
|
||||
vm_page_xbusy_claim(m);
|
||||
vm_page_unwire_noq(m);
|
||||
vm_page_iter_free(&pages);
|
||||
vm_page_iter_free(&pages, m);
|
||||
}
|
||||
VM_OBJECT_WUNLOCK(object);
|
||||
|
||||
|
@ -2060,7 +2060,7 @@ wired:
|
||||
if ((options & OBJPR_NOTMAPPED) == 0 &&
|
||||
object->ref_count != 0 && !vm_page_try_remove_all(p))
|
||||
goto wired;
|
||||
vm_page_iter_free(&pages);
|
||||
vm_page_iter_free(&pages, p);
|
||||
}
|
||||
vm_object_pip_wakeup(object);
|
||||
|
||||
|
@ -1713,14 +1713,12 @@ vm_page_free_object_prep(vm_page_t m)
|
||||
/*
|
||||
* vm_page_iter_free:
|
||||
*
|
||||
* Free the current page, as identified by iterator.
|
||||
* Free the given page, and use the iterator to remove it from the radix
|
||||
* tree.
|
||||
*/
|
||||
void
|
||||
vm_page_iter_free(struct pctrie_iter *pages)
|
||||
vm_page_iter_free(struct pctrie_iter *pages, vm_page_t m)
|
||||
{
|
||||
vm_page_t m;
|
||||
|
||||
m = vm_radix_iter_page(pages);
|
||||
vm_radix_iter_remove(pages);
|
||||
vm_page_free_object_prep(m);
|
||||
vm_page_xunbusy(m);
|
||||
|
@ -602,7 +602,6 @@ bool vm_page_busy_sleep(vm_page_t m, const char *msg, int allocflags);
|
||||
void vm_page_busy_sleep_unlocked(vm_object_t obj, vm_page_t m,
|
||||
vm_pindex_t pindex, const char *wmesg, int allocflags);
|
||||
void vm_page_free(vm_page_t m);
|
||||
void vm_page_iter_free(struct pctrie_iter *);
|
||||
void vm_page_free_zero(vm_page_t m);
|
||||
|
||||
void vm_page_activate (vm_page_t);
|
||||
@ -651,11 +650,13 @@ void vm_page_init_marker(vm_page_t marker, int queue, uint16_t aflags);
|
||||
void vm_page_init_page(vm_page_t m, vm_paddr_t pa, int segind, int pool);
|
||||
int vm_page_insert (vm_page_t, vm_object_t, vm_pindex_t);
|
||||
void vm_page_invalid(vm_page_t m);
|
||||
void vm_page_launder(vm_page_t m);
|
||||
vm_page_t vm_page_lookup(vm_object_t, vm_pindex_t);
|
||||
void vm_page_iter_free(struct pctrie_iter *pages, vm_page_t m);
|
||||
void vm_page_iter_init(struct pctrie_iter *, vm_object_t);
|
||||
void vm_page_iter_limit_init(struct pctrie_iter *, vm_object_t, vm_pindex_t);
|
||||
vm_page_t vm_page_iter_lookup(struct pctrie_iter *, vm_pindex_t);
|
||||
bool vm_page_iter_remove(struct pctrie_iter *pages);
|
||||
void vm_page_launder(vm_page_t m);
|
||||
vm_page_t vm_page_lookup(vm_object_t, vm_pindex_t);
|
||||
vm_page_t vm_page_lookup_unlocked(vm_object_t, vm_pindex_t);
|
||||
vm_page_t vm_page_next(vm_page_t m);
|
||||
void vm_page_pqbatch_drain(void);
|
||||
@ -680,7 +681,6 @@ void vm_page_release(vm_page_t m, int flags);
|
||||
void vm_page_release_locked(vm_page_t m, int flags);
|
||||
vm_page_t vm_page_relookup(vm_object_t, vm_pindex_t);
|
||||
bool vm_page_remove(vm_page_t);
|
||||
bool vm_page_iter_remove(struct pctrie_iter *);
|
||||
bool vm_page_remove_xbusy(vm_page_t);
|
||||
int vm_page_rename(struct pctrie_iter *, vm_object_t, vm_pindex_t);
|
||||
void vm_page_replace(vm_page_t mnew, vm_object_t object,
|
||||
|
@ -277,7 +277,7 @@ amdiommu_create_dev_tbl(struct amdiommu_unit *sc)
|
||||
pmap_qenter(seg_vaddr, &m, 1);
|
||||
}
|
||||
reg = i == 0 ? AMDIOMMU_DEVTAB_BASE : AMDIOMMU_DEVTAB_S1_BASE +
|
||||
i - 1;
|
||||
((i - 1) << 3);
|
||||
amdiommu_write8(sc, reg, rval);
|
||||
}
|
||||
|
||||
|
@ -155,6 +155,75 @@ v6_cleanup()
|
||||
pft_cleanup
|
||||
}
|
||||
|
||||
atf_test_case "v6_route_to" "cleanup"
|
||||
v6_route_to_head()
|
||||
{
|
||||
atf_set descr 'Test IPv6 reassembly combined with route-to'
|
||||
atf_set require.user root
|
||||
}
|
||||
|
||||
v6_route_to_body()
|
||||
{
|
||||
pft_init
|
||||
}
|
||||
|
||||
v6_route_to_cleanup()
|
||||
{
|
||||
pft_cleanup
|
||||
|
||||
epair_send=$(vnet_mkepair)
|
||||
epair_link=$(vnet_mkepair)
|
||||
|
||||
vnet_mkjail alcatraz ${epair_send}b ${epair_link}a
|
||||
vnet_mkjail singsing ${epair_link}b
|
||||
|
||||
ifconfig ${epair_send}a inet6 2001:db8:42::1/64 no_dad up
|
||||
|
||||
jexec alcatraz ifconfig ${epair_send}b inet6 2001:db8:42::2/64 no_dad up
|
||||
jexec alcatraz ifconfig ${epair_link}a inet6 2001:db8:43::2/64 no_dad up
|
||||
jexec alcatraz sysctl net.inet6.ip6.forwarding=1
|
||||
|
||||
jexec singsing ifconfig ${epair_link}b inet6 2001:db8:43::3/64 no_dad up
|
||||
jexec singsing route add -6 2001:db8:42::/64 2001:db8:43::2
|
||||
route add -6 2001:db8:43::/64 2001:db8:42::2
|
||||
|
||||
jexec alcatraz ifconfig ${epair_send}b inet6 -ifdisabled
|
||||
jexec alcatraz ifconfig ${epair_link}a inet6 -ifdisabled
|
||||
jexec singsing ifconfig ${epair_link}b inet6 -ifdisabled
|
||||
ifconfig ${epair_send}a inet6 -ifdisabled
|
||||
|
||||
jexec alcatraz pfctl -e
|
||||
pft_set_rules alcatraz \
|
||||
"set reassemble yes" \
|
||||
"pass" \
|
||||
"pass in route-to (${epair_link}a 2001:db8:43::3) inet6 proto icmp6 from any to 2001:db8:43::3 keep state"
|
||||
|
||||
# Forwarding test
|
||||
atf_check -s exit:0 -o ignore \
|
||||
ping -6 -c 1 2001:db8:43::3
|
||||
|
||||
atf_check -s exit:0 -o ignore \
|
||||
ping -6 -c 1 -s 4500 2001:db8:43::3
|
||||
|
||||
atf_check -s exit:0 -o ignore\
|
||||
ping -6 -c 1 -b 70000 -s 65000 2001:db8:43::3
|
||||
|
||||
# Now test this without fragmentation
|
||||
pft_set_rules alcatraz \
|
||||
"set reassemble no" \
|
||||
"pass" \
|
||||
"pass in route-to (${epair_link}a 2001:db8:43::3) inet6 proto icmp6 from any to 2001:db8:43::3 keep state"
|
||||
|
||||
atf_check -s exit:0 -o ignore \
|
||||
ping -6 -c 1 2001:db8:43::3
|
||||
|
||||
atf_check -s exit:0 -o ignore \
|
||||
ping -6 -c 1 -s 4500 2001:db8:43::3
|
||||
|
||||
atf_check -s exit:0 -o ignore\
|
||||
ping -6 -c 1 -b 70000 -s 65000 2001:db8:43::3
|
||||
}
|
||||
|
||||
atf_test_case "mtu_diff" "cleanup"
|
||||
mtu_diff_head()
|
||||
{
|
||||
@ -544,6 +613,7 @@ atf_init_test_cases()
|
||||
{
|
||||
atf_add_test_case "too_many_fragments"
|
||||
atf_add_test_case "v6"
|
||||
atf_add_test_case "v6_route_to"
|
||||
atf_add_test_case "mtu_diff"
|
||||
atf_add_test_case "overreplace"
|
||||
atf_add_test_case "overindex"
|
||||
|
@ -578,7 +578,7 @@ netname4(in_addr_t in, in_addr_t mask)
|
||||
struct netent *np = 0;
|
||||
in_addr_t i;
|
||||
|
||||
if (in == INADDR_ANY && mask == 0) {
|
||||
if (!numeric_addr && in == INADDR_ANY && mask == 0) {
|
||||
strlcpy(line, "default", sizeof(line));
|
||||
return (line);
|
||||
}
|
||||
@ -673,7 +673,8 @@ netname6(struct sockaddr_in6 *sa6, struct sockaddr_in6 *mask)
|
||||
else
|
||||
masklen = 128;
|
||||
|
||||
if (masklen == 0 && IN6_IS_ADDR_UNSPECIFIED(&sa6->sin6_addr))
|
||||
if (!numeric_addr && masklen == 0 &&
|
||||
IN6_IS_ADDR_UNSPECIFIED(&sa6->sin6_addr))
|
||||
return("default");
|
||||
|
||||
getnameinfo((struct sockaddr *)sa6, sa6->sin6_len, nline, sizeof(nline),
|
||||
|
@ -160,7 +160,7 @@ setup_and_wait(struct trussinfo *info, char *command[])
|
||||
|
||||
/* Only in the parent here */
|
||||
if (waitpid(pid, NULL, 0) < 0)
|
||||
err(1, "unexpect stop in waitpid");
|
||||
err(1, "unexpected stop in waitpid");
|
||||
|
||||
new_proc(info, pid, 0);
|
||||
}
|
||||
@ -179,10 +179,10 @@ start_tracing(struct trussinfo *info, pid_t pid)
|
||||
usleep(200);
|
||||
} while (ret && retry-- > 0);
|
||||
if (ret)
|
||||
err(1, "can not attach to target process");
|
||||
err(1, "Cannot attach to target process");
|
||||
|
||||
if (waitpid(pid, NULL, 0) < 0)
|
||||
err(1, "Unexpect stop in waitpid");
|
||||
err(1, "Unexpected stop in waitpid");
|
||||
|
||||
new_proc(info, pid, 0);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user