diff options
53 files changed, 1283 insertions, 544 deletions
diff --git a/Makefile.inc1 b/Makefile.inc1 index d899f994a40d..c6cbc411be80 100644 --- a/Makefile.inc1 +++ b/Makefile.inc1 @@ -3712,7 +3712,7 @@ check-old-libs: .PHONY list-old-dirs: .PHONY @cd ${.CURDIR}; \ ${MAKE} -f ${.CURDIR}/Makefile.inc1 ${.MAKEFLAGS} ${.TARGET} \ - -V OLD_DIRS | sed -E 's/[[:space:]]+/\n/g' | sort -r + -V "OLD_DIRS:ts\n" | sort -r delete-old-dirs: .PHONY @echo ">>> Removing old directories" @@ -10,6 +10,18 @@ newline. Entries should be separated by a newline. Changes to this file should not be MFCed. +2b74ff5fceb6: + Introduced support for watchdog timer in Intel 6300ESB I/O controller + hub via the i6300esbwd driver, now included in ichwd.ko. + This driver is intended primarily for QEMU users, where it serves as + the default and only watchdog timer for x86 virtual machines. + +3068d706eabe: + Lua updated to 5.4.8, which is minor bug fixes from 5.4.7. + +b45a181a74c8: + Awk updates to August 04, 2025 version, with minor bug fixes. + dc5ba6b8b4f0: The WITHOUT_GSSAPI src.conf(5) option has been removed. The GSSAPI libraries are now always built unless WITHOUT_KERBEROS is set. @@ -74,10 +74,16 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 15.x IS SLOW: require libmilter, you can now remove it. 20250815: + The [gs]etgroups(2)syscalls have changed. To maintain backwards + compatibility with existing programs, you need COMPAT_FREEBSD14 in + your kernel config until all applications which use this are + rebuild/reinstalled. + +20250815: jemalloc 5.3.0 has been committed to the tree. 20250815: - The removal of Secure RPC DES authentication notced in 20250810 + The removal of Secure RPC DES authentication noted in 20250810 has been reverted. (However, it is still non-functional.) 20250813: diff --git a/contrib/mandoc/roff_term.c b/contrib/mandoc/roff_term.c index 8f95aa920790..85d2caeb2749 100644 --- a/contrib/mandoc/roff_term.c +++ b/contrib/mandoc/roff_term.c @@ -165,6 +165,7 @@ roff_term_pre_po(ROFF_TERM_ARGS) static int polast; /* Previously requested. */ static int po; /* Currently requested. */ static int pouse; /* Currently used. */ + int pomin; /* Minimum to be used. */ int pomax; /* Maximum to be used. */ int ponew; /* Newly requested. */ @@ -186,9 +187,9 @@ roff_term_pre_po(ROFF_TERM_ARGS) po = ponew; /* Truncate to the range [-offset, 60], remember, and apply it. */ + pomin = -p->tcol->offset; pomax = term_len(p, 60); - pouse = po >= pomax ? pomax : - po < -(int)p->tcol->offset ? -p->tcol->offset : po; + pouse = po > pomax ? pomax : po < pomin ? pomin : po; p->tcol->offset += pouse; } diff --git a/etc/mail/Makefile b/etc/mail/Makefile index 784023d6f9c0..9b03047102ea 100644 --- a/etc/mail/Makefile +++ b/etc/mail/Makefile @@ -241,5 +241,7 @@ restart restart-mta restart-mspq: .include "Makefile.local" .endif -# For the definition of $SHAREMODE +# For the definition of $SHAREMODE. Define _WITHOUT_SRCCONF to prevent this +# including <bsd.compiler.mk>, which requires clang. +_WITHOUT_SRCCONF=yes .include <bsd.own.mk> diff --git a/kerberos5/lib/libroken/fbsd_ossl_provider_load.c b/kerberos5/lib/libroken/fbsd_ossl_provider_load.c index 2328041bc166..b8812f207af8 100644 --- a/kerberos5/lib/libroken/fbsd_ossl_provider_load.c +++ b/kerberos5/lib/libroken/fbsd_ossl_provider_load.c @@ -5,10 +5,9 @@ #include <openssl/provider.h> #if defined(OPENSSL_VERSION_MAJOR) && (OPENSSL_VERSION_MAJOR >= 3) -#define CRYPTO_LIBRARY "/lib/libcrypto.so.30" +#define CRYPTO_LIBRARY "/lib/libcrypto.so.35" static void fbsd_ossl_provider_unload(void); static void print_dlerror(char *); -static OSSL_PROVIDER *legacy; static OSSL_PROVIDER *deflt; static int providers_loaded = 0; static OSSL_PROVIDER * (*ossl_provider_load)(OSSL_LIB_CTX *, const char*) = NULL; @@ -25,7 +24,6 @@ fbsd_ossl_provider_unload(void) } } if (providers_loaded == 1) { - (*ossl_provider_unload)(legacy); (*ossl_provider_unload)(deflt); providers_loaded = 0; } @@ -61,10 +59,7 @@ fbsd_ossl_provider_load(void) } if (providers_loaded == 0) { - if ((legacy = (*ossl_provider_load)(NULL, "legacy")) == NULL) - return (EINVAL); if ((deflt = (*ossl_provider_load)(NULL, "default")) == NULL) { - (*ossl_provider_unload)(legacy); return (EINVAL); } if (atexit(fbsd_ossl_provider_unload)) { diff --git a/lib/libc/tests/stdtime/Makefile b/lib/libc/tests/stdtime/Makefile index adb883cc5b9a..6b9068e1641b 100644 --- a/lib/libc/tests/stdtime/Makefile +++ b/lib/libc/tests/stdtime/Makefile @@ -1,8 +1,10 @@ .include <src.opts.mk> ATF_TESTS_C+= strptime_test -.if ${MK_DETECT_TZ_CHANGES} != "no" ATF_TESTS_C+= detect_tz_changes_test + +.if ${MK_DETECT_TZ_CHANGES} != "no" +CFLAGS.detect_tz_changes_test+= -DDETECT_TZ_CHANGES .endif TESTSDIR:= ${TESTSBASE}/${RELDIR:C/libc\/tests/libc/} diff --git a/lib/libc/tests/stdtime/detect_tz_changes_test.c b/lib/libc/tests/stdtime/detect_tz_changes_test.c index 75f55bdede04..e3fdcc0baef7 100644 --- a/lib/libc/tests/stdtime/detect_tz_changes_test.c +++ b/lib/libc/tests/stdtime/detect_tz_changes_test.c @@ -4,6 +4,8 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include <sys/param.h> +#include <sys/conf.h> #include <sys/stat.h> #include <sys/wait.h> @@ -41,6 +43,8 @@ static const struct tzcase { }; static const time_t then = 1751328000; /* 2025-07-01 00:00:00 UTC */ + +#ifdef DETECT_TZ_CHANGES static const char *tz_change_interval_sym = "__tz_change_interval"; static int *tz_change_interval_p; static const int tz_change_interval = 3; @@ -272,6 +276,21 @@ ATF_TC_BODY(detect_tz_changes, tc) ATF_REQUIRE(WIFEXITED(status)); ATF_REQUIRE_EQ(0, WEXITSTATUS(status)); } +#endif /* DETECT_TZ_CHANGES */ + +static void +test_tz_env(const char *tzval, const char *expect) +{ + char buf[128]; + struct tm *tm; + size_t len; + + setenv("TZ", tzval, 1); + ATF_REQUIRE((tm = localtime(&then)) != NULL); + len = strftime(buf, sizeof(buf), "%z (%Z)", tm); + ATF_REQUIRE(len > 0); + ATF_CHECK_STREQ(expect, buf); +} ATF_TC(tz_env); ATF_TC_HEAD(tz_env, tc) @@ -280,25 +299,37 @@ ATF_TC_HEAD(tz_env, tc) } ATF_TC_BODY(tz_env, tc) { - char buf[128]; - const struct tzcase *tzcase = NULL; - struct tm *tm; - size_t len; + const struct tzcase *tzcase; - for (tzcase = tzcases; tzcase->tzfn != NULL; tzcase++) { - setenv("TZ", tzcase->tzfn, 1); - ATF_REQUIRE((tm = localtime(&then)) != NULL); - len = strftime(buf, sizeof(buf), "%z (%Z)", tm); - ATF_REQUIRE(len > 0); - ATF_REQUIRE_STREQ(tzcase->expect, buf); - } + for (tzcase = tzcases; tzcase->tzfn != NULL; tzcase++) + test_tz_env(tzcase->tzfn, tzcase->expect); +} + +ATF_TC(tz_env_setugid); +ATF_TC_HEAD(tz_env_setugid, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test TZ environment variable " + "in setugid process"); + atf_tc_set_md_var(tc, "require.user", "root"); +} +ATF_TC_BODY(tz_env_setugid, tc) +{ + const struct tzcase *tzcase; + + ATF_REQUIRE_EQ(0, seteuid(UID_NOBODY)); + ATF_REQUIRE(issetugid()); + for (tzcase = tzcases; tzcase->tzfn != NULL; tzcase++) + test_tz_env(tzcase->tzfn, tzcase->expect); } ATF_TP_ADD_TCS(tp) { +#ifdef DETECT_TZ_CHANGES debugging = !getenv("__RUNNING_INSIDE_ATF_RUN") && isatty(STDERR_FILENO); ATF_TP_ADD_TC(tp, detect_tz_changes); +#endif /* DETECT_TZ_CHANGES */ ATF_TP_ADD_TC(tp, tz_env); + ATF_TP_ADD_TC(tp, tz_env_setugid); return (atf_no_error()); } diff --git a/lib/libsysdecode/Makefile b/lib/libsysdecode/Makefile index ca020552a6e9..11f45355b8e2 100644 --- a/lib/libsysdecode/Makefile +++ b/lib/libsysdecode/Makefile @@ -27,7 +27,7 @@ MAN= sysdecode.3 \ sysdecode_sigcode.3 \ sysdecode_sockopt_name.3 \ sysdecode_socket_protocol.3 \ - sysdecode_syscallnames.3 \ + sysdecode_syscallname.3 \ sysdecode_utrace.3 MLINKS= sysdecode_abi_to_freebsd_errno.3 sysdecode_freebsd_to_abi_errno.3 MLINKS+=sysdecode_enum.3 sysdecode_acltype.3 \ diff --git a/lib/libsysdecode/sysdecode.3 b/lib/libsysdecode/sysdecode.3 index 0aa4155c004b..32f7fad4e6c5 100644 --- a/lib/libsysdecode/sysdecode.3 +++ b/lib/libsysdecode/sysdecode.3 @@ -73,7 +73,7 @@ A placeholder for use when the ABI is not known. .Xr sysdecode_sigcode 3 , .Xr sysdecode_socket_protocol 3 , .Xr sysdecode_sockopt_name 3 , -.Xr sysdecode_syscallnames 3 , +.Xr sysdecode_syscallname 3 , .Xr sysdecode_utrace 3 .Sh HISTORY The diff --git a/lib/libsysdecode/sysdecode_abi_to_freebsd_errno.3 b/lib/libsysdecode/sysdecode_abi_to_freebsd_errno.3 index 8f710d1e3756..51955f062393 100644 --- a/lib/libsysdecode/sysdecode_abi_to_freebsd_errno.3 +++ b/lib/libsysdecode/sysdecode_abi_to_freebsd_errno.3 @@ -89,4 +89,4 @@ see .Xr sysdecode 3 . .Sh SEE ALSO .Xr sysdecode 3 , -.Xr sysdecode_syscallnames 3 +.Xr sysdecode_syscallname 3 diff --git a/lib/libsysdecode/sysdecode_syscallnames.3 b/lib/libsysdecode/sysdecode_syscallname.3 index 610cbc9b2115..8ba88fd3c43e 100644 --- a/lib/libsysdecode/sysdecode_syscallnames.3 +++ b/lib/libsysdecode/sysdecode_syscallname.3 @@ -23,17 +23,17 @@ .\" SUCH DAMAGE. .\" .Dd October 17, 2016 -.Dt sysdecode_syscallnames 3 +.Dt sysdecode_syscallname 3 .Os .Sh NAME -.Nm sysdecode_syscallnames +.Nm sysdecode_syscallname .Nd lookup name of system calls .Sh LIBRARY .Lb libsysdecode .Sh SYNOPSIS .In sysdecode.h .Ft const char * -.Fn sysdecode_syscallnames "enum sysdecode_abi abi" "unsigned int code" +.Fn sysdecode_syscallname "enum sysdecode_abi abi" "unsigned int code" .Sh DESCRIPTION This function returns a pointer to the name of a system call identified by .Fa code diff --git a/sbin/ipfw/Makefile b/sbin/ipfw/Makefile index bfbe70130de7..418c0f613741 100644 --- a/sbin/ipfw/Makefile +++ b/sbin/ipfw/Makefile @@ -17,6 +17,9 @@ CFLAGS+=-DPF LIBADD= jail util MAN= ipfw.8 +HAS_TESTS= +SUBDIR.${MK_TESTS}= tests + .include <bsd.prog.mk> CWARNFLAGS+= -Wno-cast-align diff --git a/sbin/ipfw/nptv6.c b/sbin/ipfw/nptv6.c index 83bf4c768fd9..eee6109a3d9e 100644 --- a/sbin/ipfw/nptv6.c +++ b/sbin/ipfw/nptv6.c @@ -153,10 +153,10 @@ static struct _s_x nptv6newcmds[] = { { NULL, 0 } }; - static void nptv6_parse_prefix(const char *arg, struct in6_addr *prefix, int *len) { + long plen; char *p, *l; p = strdup(arg); @@ -167,13 +167,15 @@ nptv6_parse_prefix(const char *arg, struct in6_addr *prefix, int *len) if (inet_pton(AF_INET6, p, prefix) != 1) errx(EX_USAGE, "Bad prefix: %s", p); if (l != NULL) { - *len = (int)strtol(l, &l, 10); - if (*l != '\0' || *len <= 0 || *len > 64) + plen = strtol(l, &l, 10); + if (*l != '\0' || plen < 8 || plen > 64) errx(EX_USAGE, "Bad prefix length: %s", arg); + *len = plen; } else *len = 0; free(p); } + /* * Creates new nptv6 instance * ipfw nptv6 <NAME> create int_prefix <prefix> ext_prefix <prefix> @@ -189,10 +191,10 @@ nptv6_create(const char *name, uint8_t set, int ac, char *av[]) struct in6_addr mask; ipfw_nptv6_cfg *cfg; ipfw_obj_lheader *olh; - int tcmd, flags, plen; + int tcmd, flags, iplen, eplen, pplen; char *p; - plen = 0; + iplen = eplen = pplen = 0; memset(buf, 0, sizeof(buf)); olh = (ipfw_obj_lheader *)buf; cfg = (ipfw_nptv6_cfg *)(olh + 1); @@ -205,10 +207,8 @@ nptv6_create(const char *name, uint8_t set, int ac, char *av[]) switch (tcmd) { case TOK_INTPREFIX: NEED1("IPv6 prefix required"); - nptv6_parse_prefix(*av, &cfg->internal, &plen); + nptv6_parse_prefix(*av, &cfg->internal, &iplen); flags |= NPTV6_HAS_INTPREFIX; - if (plen > 0) - goto check_prefix; ac--; av++; break; case TOK_EXTPREFIX: @@ -216,10 +216,8 @@ nptv6_create(const char *name, uint8_t set, int ac, char *av[]) errx(EX_USAGE, "Only one ext_prefix or ext_if allowed"); NEED1("IPv6 prefix required"); - nptv6_parse_prefix(*av, &cfg->external, &plen); + nptv6_parse_prefix(*av, &cfg->external, &eplen); flags |= NPTV6_HAS_EXTPREFIX; - if (plen > 0) - goto check_prefix; ac--; av++; break; case TOK_EXTIF: @@ -236,24 +234,29 @@ nptv6_create(const char *name, uint8_t set, int ac, char *av[]) break; case TOK_PREFIXLEN: NEED1("IPv6 prefix length required"); - plen = strtol(*av, &p, 10); -check_prefix: - if (*p != '\0' || plen < 8 || plen > 64) + pplen = strtol(*av, &p, 10); + if (*p != '\0' || pplen < 8 || pplen > 64) errx(EX_USAGE, "wrong prefix length: %s", *av); - /* RFC 6296 Sec. 3.1 */ - if (cfg->plen > 0 && cfg->plen != plen) { - warnx("Prefix length mismatch (%d vs %d). " - "It was extended up to %d", - cfg->plen, plen, MAX(plen, cfg->plen)); - plen = MAX(plen, cfg->plen); - } - cfg->plen = plen; - flags |= NPTV6_HAS_PREFIXLEN; ac--; av++; break; } } + /* RFC 6296 Sec. 3.1 */ + if (pplen != 0) { + if ((eplen != 0 && eplen != pplen) || + (iplen != 0 && iplen != pplen)) + errx(EX_USAGE, "prefix length mismatch"); + cfg->plen = pplen; + flags |= NPTV6_HAS_PREFIXLEN; + } else if (eplen != 0 || iplen != 0) { + if (eplen != 0 && iplen != 0 && eplen != iplen) + errx(EX_USAGE, "prefix length mismatch"); + warnx("use prefixlen instead"); + cfg->plen = eplen ? eplen : iplen; + flags |= NPTV6_HAS_PREFIXLEN; + } + /* Check validness */ if ((flags & NPTV6_HAS_INTPREFIX) != NPTV6_HAS_INTPREFIX) errx(EX_USAGE, "int_prefix required"); diff --git a/sbin/ipfw/tests/Makefile b/sbin/ipfw/tests/Makefile index 987410f5d710..e2d4dab2729a 100644 --- a/sbin/ipfw/tests/Makefile +++ b/sbin/ipfw/tests/Makefile @@ -1,5 +1,6 @@ PACKAGE= tests ATF_TESTS_PYTEST+= test_add_rule.py +ATF_TESTS_SH+= ipfw_test .include <bsd.test.mk> diff --git a/sbin/ipfw/tests/ipfw_test.sh b/sbin/ipfw/tests/ipfw_test.sh new file mode 100644 index 000000000000..c7993c430a3d --- /dev/null +++ b/sbin/ipfw/tests/ipfw_test.sh @@ -0,0 +1,107 @@ +# +# Copyright (c) 2025 Dag-Erling Smørgrav <des@FreeBSD.org> +# +# SPDX-License-Identifier: BSD-2-Clause +# + +. $(atf_get_srcdir)/../../sys/common/vnet.subr + +atf_test_case nptv6 cleanup +nptv6_head() +{ + atf_set "descr" "Test creation of NPTv6 rules" + atf_set "require.user" "root" + atf_set "require.kmods" "ipfw_nptv6" +} +nptv6_body() +{ + vnet_init + local jail=ipfw_$(atf_get ident) + local epair=$(vnet_mkepair) + vnet_mkjail ${jail} ${epair}a + + local rule="xyzzy" + local int="2001:db8:1::" + local ext="2001:db8:2::" + + atf_check jexec ${jail} \ + ifconfig "${epair}"a inet6 ${ext}1/64 up + + # This is how it's supposed to be used + atf_check jexec ${jail} ipfw nptv6 ${rule} create \ + int_prefix ${int} ext_prefix ${ext} prefixlen 64 + atf_check -o inline:\ +"nptv6 $rule int_prefix $int ext_prefix $ext prefixlen 64\n" \ + jexec ${jail} ipfw nptv6 all list + atf_check jexec ${jail} ipfw nptv6 all destroy + + # Specify external interface rather than network + atf_check jexec ${jail} ipfw nptv6 ${rule} create \ + int_prefix ${int} ext_if ${epair}a prefixlen 64 + atf_check -o inline:\ +"nptv6 $rule int_prefix $int ext_if ${epair}a prefixlen 64\n" \ + jexec ${jail} ipfw nptv6 all list + atf_check jexec ${jail} ipfw nptv6 all destroy + + # This should also work + atf_check jexec ${jail} ipfw nptv6 ${rule} create \ + int_prefix ${int}/64 ext_prefix ${ext}/64 prefixlen 64 + atf_check -o inline:\ +"nptv6 $rule int_prefix $int ext_prefix $ext prefixlen 64\n" \ + jexec ${jail} ipfw nptv6 all list + atf_check jexec ${jail} ipfw nptv6 all destroy + + # This should also work, although it's not encouraged + atf_check -e match:"use prefixlen instead" \ + jexec ${jail} ipfw nptv6 ${rule} create \ + int_prefix ${int}/64 ext_prefix ${ext}/64 + atf_check -o inline:\ +"nptv6 $rule int_prefix $int ext_prefix $ext prefixlen 64\n" \ + jexec ${jail} ipfw nptv6 all list + atf_check jexec ${jail} ipfw nptv6 all destroy + + # These should all fail + atf_check -s not-exit:0 -e match:"one ext_prefix or ext_if" \ + jexec ${jail} ipfw nptv6 ${rule} create \ + int_prefix ${int} ext_prefix ${ext} ext_if ${epair}a + atf_check -o empty jexec ${jail} ipfw nptv6 all list + + atf_check -s not-exit:0 -e match:"one ext_prefix or ext_if" \ + jexec ${jail} ipfw nptv6 ${rule} create \ + int_prefix ${int} ext_if ${epair}a ext_prefix ${ext} + atf_check -o empty jexec ${jail} ipfw nptv6 all list + + atf_check -s not-exit:0 -e match:"prefix length mismatch" \ + jexec ${jail} ipfw nptv6 ${rule} create \ + int_prefix ${int}/48 ext_prefix ${ext}/64 + atf_check -o empty jexec ${jail} ipfw nptv6 all list + + atf_check -s not-exit:0 -e match:"prefix length mismatch" \ + jexec ${jail} ipfw nptv6 ${rule} create \ + int_prefix ${int}/64 ext_prefix ${ext}/64 prefixlen 48 + atf_check -o empty jexec ${jail} ipfw nptv6 all list + + atf_check -s not-exit:0 -e match:"prefix length mismatch" \ + jexec ${jail} ipfw nptv6 ${rule} create \ + int_prefix ${int}/64 ext_prefix ${ext} prefixlen 48 + atf_check -o empty jexec ${jail} ipfw nptv6 all list + + atf_check -s not-exit:0 -e match:"prefix length mismatch" \ + jexec ${jail} ipfw nptv6 ${rule} create \ + int_prefix ${int} ext_prefix ${ext}/64 prefixlen 48 + atf_check -o empty jexec ${jail} ipfw nptv6 all list + + atf_check -s not-exit:0 -e match:"prefix length mismatch" \ + jexec ${jail} ipfw nptv6 ${rule} create \ + int_prefix ${int}/64 ext_if ${epair}a prefixlen 48 + atf_check -o empty jexec ${jail} ipfw nptv6 all list +} +nptv6_cleanup() +{ + vnet_cleanup +} + +atf_init_test_cases() +{ + atf_add_test_case nptv6 +} diff --git a/secure/caroot/MAca-bundle.pl b/secure/caroot/MAca-bundle.pl deleted file mode 100755 index 58cfe1cbf6fa..000000000000 --- a/secure/caroot/MAca-bundle.pl +++ /dev/null @@ -1,305 +0,0 @@ -#!/usr/bin/env perl -## -## MAca-bundle.pl -- Regenerate ca-root-nss.crt from the Mozilla certdata.txt -## -## Rewritten in September 2011 by Matthias Andree to heed untrust -## - -## Copyright (c) 2011, 2013 Matthias Andree <mandree@FreeBSD.org> -## All rights reserved. -## Copyright (c) 2018, Allan Jude <allanjude@FreeBSD.org> -## -## Redistribution and use in source and binary forms, with or without -## modification, are permitted provided that the following conditions are -## met: -## -## * Redistributions of source code must retain the above copyright -## notice, this list of conditions and the following disclaimer. -## -## * 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 COPYRIGHT HOLDERS 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 -## COPYRIGHT HOLDER 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. - -use strict; -use Carp; -use MIME::Base64; -use Getopt::Long; -use Time::Local qw( timegm_posix ); -use POSIX qw( strftime ); - -my $generated = '@' . 'generated'; -my $inputfh = *STDIN; -my $debug = 0; -my $infile; -my $outputdir; -my %labels; -my %certs; -my %trusts; - -$debug++ - if defined $ENV{'WITH_DEBUG'} - and $ENV{'WITH_DEBUG'} !~ m/(?i)^(no|0|false|)$/; - -GetOptions ( - "debug+" => \$debug, - "infile:s" => \$infile, - "outputdir:s" => \$outputdir) - or die("Error in command line arguments\n$0 [-d] [-i input-file] [-o output-dir]\n"); - -if ($infile) { - open($inputfh, "<", $infile) or die "Failed to open $infile"; -} - -sub print_header($$) -{ - my $dstfile = shift; - my $label = shift; - - if ($outputdir) { - print $dstfile <<EOFH; -## -## $label -## -## This is a single X.509 certificate for a public Certificate -## Authority (CA). It was automatically extracted from Mozilla's -## root CA list (the file `certdata.txt' in security/nss). -## -## It contains a certificate trusted for server authentication. -## -## Extracted from nss -## -## $generated -## -EOFH - } else { - print $dstfile <<EOH; -## -## ca-root-nss.crt -- Bundle of CA Root Certificates -## -## This is a bundle of X.509 certificates of public Certificate -## Authorities (CA). These were automatically extracted from Mozilla's -## root CA list (the file `certdata.txt'). -## -## It contains certificates trusted for server authentication. -## -## Extracted from nss -## -## $generated -## -EOH - } -} - -sub printcert($$$) -{ - my ($fh, $label, $certdata) = @_; - return unless $certdata; - open(OUT, "|openssl x509 -text -inform DER -fingerprint") - or die "could not pipe to openssl x509"; - print OUT $certdata; - close(OUT) or die "openssl x509 failed with exit code $?"; -} - -# converts a datastream that is to be \177-style octal constants -# from <> to a (binary) string and returns it -sub graboct($) -{ - my $ifh = shift; - my $data; - - while (<$ifh>) { - last if /^END/; - my (undef,@oct) = split /\\/; - my @bin = map(chr(oct), @oct); - $data .= join('', @bin); - } - - return $data; -} - -sub grabcert($) -{ - my $ifh = shift; - my $certdata; - my $cka_label = ''; - my $serial = 0; - my $distrust = 0; - - while (<$ifh>) { - chomp; - last if ($_ eq ''); - - if (/^CKA_LABEL UTF8 "([^"]+)"/) { - $cka_label = $1; - } - - if (/^CKA_VALUE MULTILINE_OCTAL/) { - $certdata = graboct($ifh); - } - - if (/^CKA_SERIAL_NUMBER MULTILINE_OCTAL/) { - $serial = graboct($ifh); - } - - if (/^CKA_NSS_SERVER_DISTRUST_AFTER MULTILINE_OCTAL/) - { - my $distrust_after = graboct($ifh); - my ($year, $mon, $mday, $hour, $min, $sec) = unpack "A2A2A2A2A2A2", $distrust_after; - $distrust_after = timegm_posix( $sec, $min, $hour, $mday, $mon - 1, $year + 100); - my $time_now = time; - # When a CA is distrusted before its NotAfter date, issued certificates - # are valid for a maximum of 398 days after that date. - if ($time_now >= $distrust_after + 398 * 24 * 60 * 60) { $distrust = 1; } - if ($debug) { - printf STDERR "line $.: $cka_label ser #%d: distrust 398 days after %s, now: %s -> distrust $distrust\n", $serial, - strftime("%FT%TZ", gmtime($distrust_after)), strftime("%FT%TZ", gmtime($time_now)); - } - if ($distrust) { - return undef; - } - } - } - return ($serial, $cka_label, $certdata); -} - -sub grabtrust($) { - my $ifh = shift; - my $cka_label; - my $serial; - my $maytrust = 0; - my $distrust = 0; - - while (<$ifh>) { - chomp; - last if ($_ eq ''); - - if (/^CKA_LABEL UTF8 "([^"]+)"/) { - $cka_label = $1; - } - - if (/^CKA_SERIAL_NUMBER MULTILINE_OCTAL/) { - $serial = graboct($ifh); - } - - if (/^CKA_TRUST_SERVER_AUTH CK_TRUST (\S+)$/) - { - if ($1 eq 'CKT_NSS_NOT_TRUSTED') { - $distrust = 1; - } elsif ($1 eq 'CKT_NSS_TRUSTED_DELEGATOR') { - $maytrust = 1; - } elsif ($1 ne 'CKT_NSS_MUST_VERIFY_TRUST') { - confess "Unknown trust setting on line $.:\n" - . "$_\n" - . "Script must be updated:"; - } - } - } - - if (!$maytrust && !$distrust && $debug) { - print STDERR "line $.: no explicit trust/distrust found for $cka_label\n"; - } - - my $trust = ($maytrust and not $distrust); - return ($serial, $cka_label, $trust); -} - -if (!$outputdir) { - print_header(*STDOUT, ""); -} - -my $untrusted = 0; - -while (<$inputfh>) { - if (/^CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE/) { - my ($serial, $label, $certdata) = grabcert($inputfh); - if (defined $certs{$label."\0".$serial}) { - warn "Certificate $label duplicated!\n"; - } - if (defined $certdata) { - $certs{$label."\0".$serial} = $certdata; - # We store the label in a separate hash because truncating the key - # with \0 was causing garbage data after the end of the text. - $labels{$label."\0".$serial} = $label; - } else { # $certdata undefined? distrust_after in effect - $untrusted ++; - } - } elsif (/^CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST/) { - my ($serial, $label, $trust) = grabtrust($inputfh); - if (defined $trusts{$label."\0".$serial}) { - warn "Trust for $label duplicated!\n"; - } - $trusts{$label."\0".$serial} = $trust; - $labels{$label."\0".$serial} = $label; - } elsif (/^CVS_ID.*Revision: ([^ ]*).*/) { - print "## Source: \"certdata.txt\" CVS revision $1\n##\n\n"; - } -} - -sub label_to_filename(@) { - my @res = @_; - map { s/\0.*//; s/[^[:alnum:]\-]/_/g; $_ = "$_.pem"; } @res; - return wantarray ? @res : $res[0]; -} - -# weed out untrusted certificates -foreach my $it (keys %trusts) { - if (!$trusts{$it}) { - if (!exists($certs{$it})) { - warn "Found trust for nonexistent certificate $labels{$it}\n" if $debug; - } else { - delete $certs{$it}; - warn "Skipping untrusted $labels{$it}\n" if $debug; - $untrusted++; - } - } -} - -if (!$outputdir) { - print "## Untrusted certificates omitted from this bundle: $untrusted\n\n"; -} -print STDERR "## Untrusted certificates omitted from this bundle: $untrusted\n"; - -my $certcount = 0; -foreach my $it (sort {uc($a) cmp uc($b)} keys %certs) { - my $fh = *STDOUT; - my $filename; - if (!exists($trusts{$it})) { - die "Found certificate without trust block,\naborting"; - } - if ($outputdir) { - $filename = label_to_filename($labels{$it}); - open($fh, ">", "$outputdir/$filename") or die "Failed to open certificate $filename"; - print_header($fh, $labels{$it}); - } - printcert($fh, $labels{$it}, $certs{$it}); - if ($outputdir) { - close($fh) or die "Unable to close: $filename"; - } else { - print $fh "\n\n\n"; - } - $certcount++; - print STDERR "Trusting $certcount: $labels{$it}\n" if $debug; -} - -if ($certcount < 25) { - die "Certificate count of $certcount is implausibly low.\nAbort"; -} - -if (!$outputdir) { - print "## Number of certificates: $certcount\n"; - print "## End of file.\n"; -} -print STDERR "## Number of certificates: $certcount\n"; diff --git a/secure/caroot/Makefile b/secure/caroot/Makefile index ace802a906a3..e0ef4623b498 100644 --- a/secure/caroot/Makefile +++ b/secure/caroot/Makefile @@ -13,4 +13,5 @@ cleancerts: .PHONY @${MAKE} -C ${.CURDIR}/trusted ${.TARGET} updatecerts: .PHONY cleancerts fetchcerts - perl ${.CURDIR}/MAca-bundle.pl -i certdata.txt -o ${.CURDIR}/trusted + perl ${.CURDIR}/ca-extract.pl -i certdata.txt \ + -t ${.CURDIR}/trusted -u ${.CURDIR}/untrusted diff --git a/secure/caroot/ca-extract.pl b/secure/caroot/ca-extract.pl new file mode 100755 index 000000000000..75f8352e384e --- /dev/null +++ b/secure/caroot/ca-extract.pl @@ -0,0 +1,253 @@ +#!/usr/bin/env perl +#- +# SPDX-License-Identifier: BSD-2-Clause +# +# Copyright (c) 2011, 2013 Matthias Andree <mandree@FreeBSD.org> +# Copyright (c) 2018 Allan Jude <allanjude@FreeBSD.org> +# Copyright (c) 2025 Dag-Erling Smørgrav <des@FreeBSD.org> +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# +# ca-extract.pl -- Extract trusted and untrusted certificates from +# Mozilla's certdata.txt. +# +# Rewritten in September 2011 by Matthias Andree to heed untrust +# + +use strict; +use warnings; +use Carp; +use MIME::Base64; +use Getopt::Long; +use Time::Local qw( timegm_posix ); +use POSIX qw( strftime ); + +my $generated = '@' . 'generated'; +my $inputfh = *STDIN; +my $debug = 0; +my $infile; +my $trustdir = "trusted"; +my $untrustdir = "untrusted"; +my %labels; +my %certs; +my %trusts; +my %expires; + +$debug++ + if defined $ENV{'WITH_DEBUG'} + and $ENV{'WITH_DEBUG'} !~ m/(?i)^(no|0|false|)$/; + +GetOptions ( + "debug+" => \$debug, + "infile:s" => \$infile, + "trustdir:s" => \$trustdir, + "untrustdir:s" => \$untrustdir) + or die("Error in command line arguments\n$0 [-d] [-i input-file] [-t trust-dir] [-u untrust-dir]\n"); + +if ($infile) { + open($inputfh, "<", $infile) or die "Failed to open $infile"; +} + +sub print_header($$) +{ + my $dstfile = shift; + my $label = shift; + + print $dstfile <<EOFH; +## +## $label +## +## This is a single X.509 certificate for a public Certificate +## Authority (CA). It was automatically extracted from Mozilla's +## root CA list (the file `certdata.txt' in security/nss). +## +## $generated +## +EOFH +} + +sub printcert($$$) +{ + my ($fh, $label, $certdata) = @_; + return unless $certdata; + open(OUT, "|-", qw(openssl x509 -text -inform DER -fingerprint)) + or die "could not pipe to openssl x509"; + print OUT $certdata; + close(OUT) or die "openssl x509 failed with exit code $?"; +} + +# converts a datastream that is to be \177-style octal constants +# from <> to a (binary) string and returns it +sub graboct($) +{ + my $ifh = shift; + my $data = ""; + + while (<$ifh>) { + last if /^END/; + $data .= join('', map { chr(oct($_)) } m/\\([0-7]{3})/g); + } + + return $data; +} + +sub grabcert($) +{ + my $ifh = shift; + my $certdata; + my $cka_label = ''; + my $serial = 0; + my $distrust = 0; + + while (<$ifh>) { + chomp; + last if ($_ eq ''); + + if (/^CKA_LABEL UTF8 "([^"]+)"/) { + $cka_label = $1; + } + + if (/^CKA_VALUE MULTILINE_OCTAL/) { + $certdata = graboct($ifh); + } + + if (/^CKA_SERIAL_NUMBER MULTILINE_OCTAL/) { + $serial = graboct($ifh); + } + + if (/^CKA_NSS_SERVER_DISTRUST_AFTER MULTILINE_OCTAL/) + { + my $distrust_after = graboct($ifh); + my ($year, $mon, $mday, $hour, $min, $sec) = unpack "A2A2A2A2A2A2", $distrust_after; + $distrust_after = timegm_posix($sec, $min, $hour, $mday, $mon - 1, $year + 100); + $expires{$cka_label."\0".$serial} = $distrust_after; + } + } + return ($serial, $cka_label, $certdata); +} + +sub grabtrust($) { + my $ifh = shift; + my $cka_label; + my $serial; + my $maytrust = 0; + my $distrust = 0; + + while (<$ifh>) { + chomp; + last if ($_ eq ''); + + if (/^CKA_LABEL UTF8 "([^"]+)"/) { + $cka_label = $1; + } + + if (/^CKA_SERIAL_NUMBER MULTILINE_OCTAL/) { + $serial = graboct($ifh); + } + + if (/^CKA_TRUST_SERVER_AUTH CK_TRUST (\S+)$/) { + if ($1 eq 'CKT_NSS_NOT_TRUSTED') { + $distrust = 1; + } elsif ($1 eq 'CKT_NSS_TRUSTED_DELEGATOR') { + $maytrust = 1; + } elsif ($1 ne 'CKT_NSS_MUST_VERIFY_TRUST') { + confess "Unknown trust setting on line $.:\n" + . "$_\n" + . "Script must be updated:"; + } + } + } + + if (!$maytrust && !$distrust && $debug) { + print STDERR "line $.: no explicit trust/distrust found for $cka_label\n"; + } + + my $trust = ($maytrust and not $distrust); + return ($serial, $cka_label, $trust); +} + +while (<$inputfh>) { + if (/^CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE/) { + my ($serial, $label, $certdata) = grabcert($inputfh); + if (defined $certs{$label."\0".$serial}) { + warn "Certificate $label duplicated!\n"; + } + if (defined $certdata) { + $certs{$label."\0".$serial} = $certdata; + # We store the label in a separate hash because truncating the key + # with \0 was causing garbage data after the end of the text. + $labels{$label."\0".$serial} = $label; + } + } elsif (/^CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST/) { + my ($serial, $label, $trust) = grabtrust($inputfh); + if (defined $trusts{$label."\0".$serial}) { + warn "Trust for $label duplicated!\n"; + } + $trusts{$label."\0".$serial} = $trust; + $labels{$label."\0".$serial} = $label; + } elsif (/^CVS_ID.*Revision: ([^ ]*).*/) { + print "## Source: \"certdata.txt\" CVS revision $1\n##\n\n"; + } +} + +sub label_to_filename(@) { + my @res = @_; + map { s/\0.*//; s/[^[:alnum:]\-]/_/g; $_ = "$_.pem"; } @res; + return wantarray ? @res : $res[0]; +} + +my $untrusted = 0; +my $trusted = 0; +my $now = time; + +foreach my $it (sort {uc($a) cmp uc($b)} keys %certs) { + my $fh = *STDOUT; + my $outputdir; + my $filename; + if (exists($expires{$it}) && + $now >= $expires{$it} + 398 * 24 * 60 * 60) { + print(STDERR "## Expired: $labels{$it}\n"); + $outputdir = $untrustdir; + $untrusted++; + } elsif (!$trusts{$it}) { + print(STDERR "## Untrusted: $labels{$it}\n"); + $outputdir = $untrustdir; + $untrusted++; + } else { + print(STDERR "## Trusted: $labels{$it}\n"); + $outputdir = $trustdir; + $trusted++; + } + $filename = label_to_filename($labels{$it}); + open($fh, ">", "$outputdir/$filename") or die "Failed to open certificate $outputdir/$filename"; + print_header($fh, $labels{$it}); + printcert($fh, $labels{$it}, $certs{$it}); + if ($outputdir) { + close($fh) or die "Unable to close: $filename"; + } else { + print $fh "\n\n\n"; + } +} + +printf STDERR "## Trusted certificates: %4d\n", $trusted; +printf STDERR "## Untrusted certificates: %4d\n", $untrusted; diff --git a/secure/caroot/trusted/Makefile b/secure/caroot/trusted/Makefile index b2fe43fcb802..a47e781262b8 100644 --- a/secure/caroot/trusted/Makefile +++ b/secure/caroot/trusted/Makefile @@ -1,10 +1,10 @@ BINDIR= /usr/share/certs/trusted -TRUSTED_CERTS!= echo ${.CURDIR}/*.pem 2> /dev/null || true +TRUSTED_CERTS!= (cd ${.CURDIR} && echo *.pem) FILES+= ${TRUSTED_CERTS} -cleancerts: - @[ -z "${TRUSTED_CERTS}" ] || rm ${TRUSTED_CERTS} +cleancerts: .PHONY + @(cd ${.CURDIR} && rm -f ${TRUSTED_CERTS}) .include <bsd.prog.mk> diff --git a/secure/caroot/untrusted/Makefile b/secure/caroot/untrusted/Makefile index 19d7359ddcb9..45df0a55ebd9 100644 --- a/secure/caroot/untrusted/Makefile +++ b/secure/caroot/untrusted/Makefile @@ -1,7 +1,10 @@ BINDIR= /usr/share/certs/untrusted -UNTRUSTED_CERTS!= echo ${.CURDIR}/*.pem 2> /dev/null || true +UNTRUSTED_CERTS!= (cd ${.CURDIR} && echo *.pem) FILES+= ${UNTRUSTED_CERTS} +cleancerts: .PHONY + @(cd ${.CURDIR} && rm -f ${UNTRUSTED_CERTS}) + .include <bsd.prog.mk> diff --git a/share/man/man4/puc.4 b/share/man/man4/puc.4 index a29376d3f2d5..624c215027af 100644 --- a/share/man/man4/puc.4 +++ b/share/man/man4/puc.4 @@ -257,6 +257,8 @@ Sunix SER5xxxx 8/4/2 port serial .It Syba Tech Ltd PCI-4S2P-550-ECP .It +Systembase SB16C1054/8 4/8 port serial +.It Titan PCI-800H/PCI-200H .It VScom: diff --git a/share/man/man7/simd.7 b/share/man/man7/simd.7 index 2c3ed3de411e..d5092348d9b3 100644 --- a/share/man/man7/simd.7 +++ b/share/man/man7/simd.7 @@ -24,7 +24,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE . -.Dd July 29, 2025 +.Dd November 18, 2024 .Dt SIMD 7 .Os .Sh NAME @@ -50,43 +50,48 @@ can be used to override this mechanism. .Pp Enhanced functions are present for the following architectures: .Bl -column FUNCTION_________ aarch64_ arm_ amd64_ i386_ ppc64_ -offset indent -.It Em FUNCTION Ta Em AARCH64 Ta Em ARM Ta Em AMD64 Ta Em PPC64 -.It bcmp Ta A Ta Ta S1 -.It bcopy Ta A Ta S Ta S Ta SV -.It bzero Ta A Ta S Ta S -.It div Ta Ta Ta S +.It Em FUNCTION Ta Em AARCH64 Ta Em ARM Ta Em AMD64 Ta Em I386 Ta Em PPC64 +.It bcmp Ta A Ta Ta S1 Ta S +.It bcopy Ta A Ta S Ta S Ta S Ta SV +.It bzero Ta A Ta S Ta S Ta S +.It div Ta Ta Ta S Ta S .It index Ta A Ta Ta S1 -.It ldiv Ta Ta Ta S +.It ldiv Ta Ta Ta S Ta S .It lldiv Ta Ta Ta S .It memchr Ta A Ta Ta S1 -.It memcmp Ta A Ta S Ta S1 +.It memcmp Ta A Ta S Ta S1 Ta S .It memccpy Ta A Ta Ta S1 -.It memcpy Ta A Ta S Ta S Ta SV -.It memmove Ta A Ta S Ta S Ta SV +.It memcpy Ta A Ta S Ta S Ta S Ta SV +.It memmove Ta A Ta S Ta S Ta S Ta SV .It memrchr Ta A Ta Ta S1 -.It memset Ta A Ta S Ta S -.It rindex Ta A Ta Ta S1 +.It memset Ta A Ta S Ta S Ta S +.It rindex Ta A Ta Ta S1 Ta S .It stpcpy Ta A Ta Ta S1 .It stpncpy Ta Ta Ta S1 -.It strcat Ta A Ta Ta S1 -.It strchr Ta A Ta Ta S1 +.It strcat Ta A Ta Ta S1 Ta S +.It strchr Ta A Ta Ta S1 Ta S .It strchrnul Ta A Ta Ta S1 -.It strcmp Ta A Ta S Ta S1 -.It strcpy Ta A Ta Ta S1 Ta S2 +.It strcmp Ta A Ta S Ta S1 Ta S +.It strcpy Ta A Ta Ta S1 Ta S Ta S2 .It strcspn Ta S Ta Ta S2 .It strlcat Ta A Ta Ta S1 .It strlcpy Ta A Ta Ta S1 .It strlen Ta A Ta S Ta S1 .It strncat Ta A Ta Ta S1 -.It strncmp Ta A Ta S Ta S1 -.It strncpy Ta Ta Ta S1 Ta S2 +.It strncmp Ta A Ta S Ta S1 Ta S +.It strncpy Ta Ta Ta S1 Ta Ta S2 .It strnlen Ta A Ta Ta S1 -.It strrchr Ta A Ta Ta S1 +.It strrchr Ta A Ta Ta S1 Ta S .It strpbrk Ta S Ta Ta S2 .It strsep Ta S Ta Ta S2 .It strspn Ta S Ta Ta S2 +.It swab Ta Ta Ta Ta S .It timingsafe_bcmp Ta A Ta Ta S1 .It timingsafe_memcmp Ta S Ta Ta S +.It wcschr Ta Ta Ta Ta S +.It wcscmp Ta Ta Ta Ta S +.It wcslen Ta Ta Ta Ta S +.It wmemchr Ta Ta Ta Ta S .El .Pp .Sy S Ns :\ scalar (non-SIMD), diff --git a/sys/compat/linuxkpi/common/include/acpi/acpi.h b/sys/compat/linuxkpi/common/include/acpi/acpi.h index 1e398d05ba20..016c7ede0f6e 100644 --- a/sys/compat/linuxkpi/common/include/acpi/acpi.h +++ b/sys/compat/linuxkpi/common/include/acpi/acpi.h @@ -37,7 +37,7 @@ /* * LINUXKPI_WANT_LINUX_ACPI is a temporary workaround to allow drm-kmod * to update all needed branches without breaking builds. - * Once that happened and checks are implemented based on __FreeBSD_verison + * Once that happened and checks are implemented based on __FreeBSD_version * we will remove these conditions again. */ diff --git a/sys/compat/linuxkpi/common/include/linux/netdevice.h b/sys/compat/linuxkpi/common/include/linux/netdevice.h index cd7d23077a62..3b808a4a1749 100644 --- a/sys/compat/linuxkpi/common/include/linux/netdevice.h +++ b/sys/compat/linuxkpi/common/include/linux/netdevice.h @@ -4,7 +4,7 @@ * Copyright (c) 2010 Panasas, Inc. * Copyright (c) 2013-2019 Mellanox Technologies, Ltd. * All rights reserved. - * Copyright (c) 2020-2021 The FreeBSD Foundation + * Copyright (c) 2020-2025 The FreeBSD Foundation * Copyright (c) 2020-2022 Bjoern A. Zeeb * * Portions of this software were developed by Björn Zeeb @@ -302,6 +302,13 @@ netdev_rss_key_fill(uint32_t *buf, size_t len) get_random_bytes(buf, len); } +static inline void +__hw_addr_init(struct netdev_hw_addr_list *list) +{ + list->count = 0; + INIT_LIST_HEAD(&list->addr_list); +} + static inline int netdev_hw_addr_list_count(struct netdev_hw_addr_list *list) { diff --git a/sys/compat/linuxkpi/common/include/net/mac80211.h b/sys/compat/linuxkpi/common/include/net/mac80211.h index 19f7bcff29dc..0106e6648bd4 100644 --- a/sys/compat/linuxkpi/common/include/net/mac80211.h +++ b/sys/compat/linuxkpi/common/include/net/mac80211.h @@ -87,6 +87,9 @@ enum mcast_filter_flags { FIF_PSPOLL = BIT(5), FIF_CONTROL = BIT(6), FIF_MCAST_ACTION = BIT(7), + + /* Must stay last. */ + FIF_FLAGS_MASK = BIT(8)-1, }; enum ieee80211_bss_changed { diff --git a/sys/compat/linuxkpi/common/src/linux_80211.c b/sys/compat/linuxkpi/common/src/linux_80211.c index 500c1c1d52eb..e248588dd275 100644 --- a/sys/compat/linuxkpi/common/src/linux_80211.c +++ b/sys/compat/linuxkpi/common/src/linux_80211.c @@ -1179,7 +1179,7 @@ lkpi_find_lkpi80211_chan(struct lkpi_hw *lhw, channels = hw->wiphy->bands[band]->channels; for (i = 0; i < nchans; i++) { - if (channels[i].hw_value == c->ic_ieee) + if (channels[i].center_freq == c->ic_freq) return (&channels[i]); } @@ -1717,6 +1717,24 @@ lkpi_iv_key_update_end(struct ieee80211vap *vap) } #endif +static void +lkpi_cleanup_mcast_list_locked(struct lkpi_hw *lhw) +{ + struct list_head *le, *next; + struct netdev_hw_addr *addr; + + if (lhw->mc_list.count != 0) { + list_for_each_safe(le, next, &lhw->mc_list.addr_list) { + addr = list_entry(le, struct netdev_hw_addr, addr_list); + list_del(le); + lhw->mc_list.count--; + free(addr, M_LKPI80211); + } + } + KASSERT(lhw->mc_list.count == 0, ("%s: mc_list %p count %d != 0\n", + __func__, &lhw->mc_list, lhw->mc_list.count)); +} + static u_int lkpi_ic_update_mcast_copy(void *arg, struct sockaddr_dl *sdl, u_int cnt) { @@ -1753,16 +1771,13 @@ lkpi_ic_update_mcast_copy(void *arg, struct sockaddr_dl *sdl, u_int cnt) } static void -lkpi_update_mcast_filter(struct ieee80211com *ic, bool force) +lkpi_update_mcast_filter(struct ieee80211com *ic) { struct lkpi_hw *lhw; struct ieee80211_hw *hw; - struct netdev_hw_addr_list mc_list; - struct list_head *le, *next; - struct netdev_hw_addr *addr; - struct ieee80211vap *vap; u64 mc; - unsigned int changed_flags, total_flags; + unsigned int changed_flags, flags; + bool scanning; lhw = ic->ic_softc; @@ -1770,44 +1785,32 @@ lkpi_update_mcast_filter(struct ieee80211com *ic, bool force) lhw->ops->configure_filter == NULL) return; - if (!lhw->update_mc && !force) - return; + LKPI_80211_LHW_SCAN_LOCK(lhw); + scanning = (lhw->scan_flags & LKPI_LHW_SCAN_RUNNING) != 0; + LKPI_80211_LHW_SCAN_UNLOCK(lhw); - changed_flags = total_flags = 0; - mc_list.count = 0; - INIT_LIST_HEAD(&mc_list.addr_list); - if (ic->ic_allmulti == 0) { - TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) - if_foreach_llmaddr(vap->iv_ifp, - lkpi_ic_update_mcast_copy, &mc_list); - } else { - changed_flags |= FIF_ALLMULTI; - } + LKPI_80211_LHW_MC_LOCK(lhw); + + flags = 0; + if (scanning) + flags |= FIF_BCN_PRBRESP_PROMISC; + if (lhw->mc_all_multi) + flags |= FIF_ALLMULTI; hw = LHW_TO_HW(lhw); - mc = lkpi_80211_mo_prepare_multicast(hw, &mc_list); - /* - * XXX-BZ make sure to get this sorted what is a change, - * what gets all set; what was already set? - */ - total_flags = changed_flags; - lkpi_80211_mo_configure_filter(hw, changed_flags, &total_flags, mc); + mc = lkpi_80211_mo_prepare_multicast(hw, &lhw->mc_list); + + changed_flags = (lhw->mc_flags ^ flags) & FIF_FLAGS_MASK; + lkpi_80211_mo_configure_filter(hw, changed_flags, &flags, mc); + lhw->mc_flags = flags; #ifdef LINUXKPI_DEBUG_80211 if (linuxkpi_debug_80211 & D80211_TRACE) - printf("%s: changed_flags %#06x count %d total_flags %#010x\n", - __func__, changed_flags, mc_list.count, total_flags); + printf("%s: changed_flags %#06x count %d mc_flags %#010x\n", + __func__, changed_flags, lhw->mc_list.count, lhw->mc_flags); #endif - if (mc_list.count != 0) { - list_for_each_safe(le, next, &mc_list.addr_list) { - addr = list_entry(le, struct netdev_hw_addr, addr_list); - free(addr, M_LKPI80211); - mc_list.count--; - } - } - KASSERT(mc_list.count == 0, ("%s: mc_list %p count %d != 0\n", - __func__, &mc_list, mc_list.count)); + LKPI_80211_LHW_MC_UNLOCK(lhw); } static enum ieee80211_bss_changed @@ -1926,19 +1929,19 @@ lkpi_disassoc(struct ieee80211_sta *sta, struct ieee80211_vif *vif, struct lkpi_hw *lhw) { enum ieee80211_bss_changed changed; + struct lkpi_vif *lvif; changed = 0; sta->aid = 0; if (vif->cfg.assoc) { - lhw->update_mc = true; - lkpi_update_mcast_filter(lhw->ic, true); - vif->cfg.assoc = false; vif->cfg.aid = 0; changed |= BSS_CHANGED_ASSOC; IMPROVE(); + lkpi_update_mcast_filter(lhw->ic); + /* * Executing the bss_info_changed(BSS_CHANGED_ASSOC) with * assoc = false right away here will remove the sta from @@ -1949,6 +1952,9 @@ lkpi_disassoc(struct ieee80211_sta *sta, struct ieee80211_vif *vif, * bss_info_changed() update. * See lkpi_sta_run_to_init() for more detailed comment. */ + + lvif = VIF_TO_LVIF(vif); + lvif->beacons = 0; } return (changed); @@ -2219,6 +2225,7 @@ lkpi_sta_scan_to_auth(struct ieee80211vap *vap, enum ieee80211_state nstate, int /* vif->bss_conf.basic_rates ? Where exactly? */ + lvif->beacons = 0; /* Should almost assert it is this. */ vif->cfg.assoc = false; vif->cfg.aid = 0; @@ -2408,6 +2415,7 @@ lkpi_sta_auth_to_scan(struct ieee80211vap *vap, enum ieee80211_state nstate, int struct lkpi_sta *lsta; struct ieee80211_sta *sta; struct ieee80211_prep_tx_info prep_tx_info; + enum ieee80211_bss_changed bss_changed; int error; lhw = vap->iv_ic->ic_softc; @@ -2479,6 +2487,11 @@ lkpi_sta_auth_to_scan(struct ieee80211vap *vap, enum ieee80211_state nstate, int lsta->added_to_drv = false; /* mo manages. */ #endif + bss_changed = 0; + vif->bss_conf.dtim_period = 0; /* go back to 0. */ + bss_changed |= BSS_CHANGED_BEACON_INFO; + lkpi_80211_mo_bss_info_changed(hw, vif, &vif->bss_conf, bss_changed); + lkpi_lsta_dump(lsta, ni, __func__, __LINE__); LKPI_80211_LVIF_LOCK(lvif); @@ -2807,6 +2820,8 @@ _lkpi_sta_assoc_to_down(struct ieee80211vap *vap, enum ieee80211_state nstate, i vif->cfg.ssid_len = 0; memset(vif->cfg.ssid, '\0', sizeof(vif->cfg.ssid)); bss_changed |= BSS_CHANGED_BSSID; + vif->bss_conf.dtim_period = 0; /* go back to 0. */ + bss_changed |= BSS_CHANGED_BEACON_INFO; lkpi_80211_mo_bss_info_changed(hw, vif, &vif->bss_conf, bss_changed); LKPI_80211_LVIF_LOCK(lvif); @@ -2939,6 +2954,7 @@ lkpi_sta_assoc_to_run(struct ieee80211vap *vap, enum ieee80211_state nstate, int bss_changed |= lkpi_wme_update(lhw, vap, true); #endif if (!vif->cfg.assoc || vif->cfg.aid != IEEE80211_NODE_AID(ni)) { + lvif->beacons = 0; vif->cfg.assoc = true; vif->cfg.aid = IEEE80211_NODE_AID(ni); bss_changed |= BSS_CHANGED_ASSOC; @@ -2987,9 +3003,6 @@ lkpi_sta_assoc_to_run(struct ieee80211vap *vap, enum ieee80211_state nstate, int * - set_key (?) * - ipv6_addr_change (?) */ - /* Prepare_multicast && configure_filter. */ - lhw->update_mc = true; - lkpi_update_mcast_filter(vap->iv_ic, true); if (!ieee80211_node_is_authorized(ni)) { IMPROVE("net80211 does not consider node authorized"); @@ -3028,6 +3041,9 @@ lkpi_sta_assoc_to_run(struct ieee80211vap *vap, enum ieee80211_state nstate, int bss_changed |= lkpi_update_dtim_tsf(vif, ni, vap, __func__, __LINE__); lkpi_80211_mo_bss_info_changed(hw, vif, &vif->bss_conf, bss_changed); + /* Prepare_multicast && configure_filter. */ + lkpi_update_mcast_filter(vap->iv_ic); + out: wiphy_unlock(hw->wiphy); IEEE80211_LOCK(vap->iv_ic); @@ -3408,6 +3424,8 @@ lkpi_sta_run_to_init(struct ieee80211vap *vap, enum ieee80211_state nstate, int vif->bss_conf.use_short_preamble = false; vif->bss_conf.qos = false; /* XXX BSS_CHANGED_???? */ + vif->bss_conf.dtim_period = 0; /* go back to 0. */ + bss_changed |= BSS_CHANGED_BEACON_INFO; lkpi_80211_mo_bss_info_changed(hw, vif, &vif->bss_conf, bss_changed); LKPI_80211_LVIF_LOCK(lvif); @@ -3710,6 +3728,42 @@ lkpi_ic_wme_update(struct ieee80211com *ic) return (0); /* unused */ } +static void +lkpi_iv_sta_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0, + int subtype, const struct ieee80211_rx_stats *rxs, int rssi, int nf) +{ + struct lkpi_hw *lhw; + struct ieee80211_hw *hw; + struct lkpi_vif *lvif; + struct ieee80211_vif *vif; + enum ieee80211_bss_changed bss_changed; + + lvif = VAP_TO_LVIF(ni->ni_vap); + + lvif->iv_recv_mgmt(ni, m0, subtype, rxs, rssi, nf); + + switch (subtype) { + case IEEE80211_FC0_SUBTYPE_PROBE_RESP: + break; + case IEEE80211_FC0_SUBTYPE_BEACON: + lvif->beacons++; + break; + default: + return; + } + + vif = LVIF_TO_VIF(lvif); + lhw = ni->ni_ic->ic_softc; + hw = LHW_TO_HW(lhw); + + /* + * If this direct call to mo_bss_info_changed will not work due to + * locking, see if queue_work() is fast enough. + */ + bss_changed = lkpi_update_dtim_tsf(vif, ni, ni->ni_vap, __func__, __LINE__); + lkpi_80211_mo_bss_info_changed(hw, vif, &vif->bss_conf, bss_changed); +} + /* * Change link-layer address on the vif (if the vap is not started/"UP"). * This can happen if a user changes 'ether' using ifconfig. @@ -3892,7 +3946,7 @@ lkpi_ic_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], lkpi_80211_mo_bss_info_changed(hw, vif, &vif->bss_conf, changed); /* Force MC init. */ - lkpi_update_mcast_filter(ic, true); + lkpi_update_mcast_filter(ic); ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid); @@ -3905,6 +3959,8 @@ lkpi_ic_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], vap->iv_newstate = lkpi_iv_newstate; lvif->iv_update_bss = vap->iv_update_bss; vap->iv_update_bss = lkpi_iv_update_bss; + lvif->iv_recv_mgmt = vap->iv_recv_mgmt; + vap->iv_recv_mgmt = lkpi_iv_sta_recv_mgmt; #ifdef LKPI_80211_HW_CRYPTO /* Key management. */ @@ -4027,8 +4083,30 @@ lkpi_ic_vap_delete(struct ieee80211vap *vap) static void lkpi_ic_update_mcast(struct ieee80211com *ic) { + struct ieee80211vap *vap; + struct lkpi_hw *lhw; + + lhw = ic->ic_softc; + if (lhw->ops->prepare_multicast == NULL || + lhw->ops->configure_filter == NULL) + return; + + LKPI_80211_LHW_MC_LOCK(lhw); + /* Cleanup anything on the current list. */ + lkpi_cleanup_mcast_list_locked(lhw); - lkpi_update_mcast_filter(ic, false); + /* Build up the new list (or allmulti). */ + if (ic->ic_allmulti == 0) { + TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) + if_foreach_llmaddr(vap->iv_ifp, + lkpi_ic_update_mcast_copy, &lhw->mc_list); + lhw->mc_all_multi = false; + } else { + lhw->mc_all_multi = true; + } + LKPI_80211_LHW_MC_UNLOCK(lhw); + + lkpi_update_mcast_filter(ic); TRACEOK(); } @@ -4264,6 +4342,8 @@ sw_scan: if (vap->iv_state == IEEE80211_S_SCAN) lkpi_hw_conf_idle(hw, false); + lkpi_update_mcast_filter(ic); + lkpi_80211_mo_sw_scan_start(hw, vif, vif->addr); /* net80211::scan_start() handled PS for us. */ IMPROVE(); @@ -4371,7 +4451,6 @@ sw_scan: struct ieee80211_channel *c; c = ss->ss_chans[ss->ss_next + i]; - lc->hw_value = c->ic_ieee; lc->center_freq = c->ic_freq; /* XXX */ /* lc->flags */ lc->band = lkpi_net80211_chan_to_nl80211_band(c); @@ -4400,7 +4479,6 @@ sw_scan: } } #endif - hw_req->req.n_ssids = ssid_count; if (hw_req->req.n_ssids > 0) { ssids = (struct cfg80211_ssid *)lc; @@ -4447,6 +4525,8 @@ sw_scan: return; } + lkpi_update_mcast_filter(ic); + error = lkpi_80211_mo_hw_scan(hw, vif, hw_req); if (error != 0) { ieee80211_cancel_scan(vap); @@ -4472,6 +4552,7 @@ sw_scan: lhw->scan_flags &= ~LKPI_LHW_SCAN_RUNNING; } LKPI_80211_LHW_SCAN_UNLOCK(lhw); + lkpi_update_mcast_filter(ic); /* * XXX-SIGH magic number. @@ -5839,8 +5920,9 @@ lkpi_ic_getradiocaps(struct ieee80211com *ic, int maxchan, cflags &= ~NET80211_CBW_FLAG_HT40; error = ieee80211_add_channel_cbw(c, maxchan, n, - channels[i].hw_value, channels[i].center_freq, - channels[i].max_power, + ieee80211_mhz2ieee(channels[i].center_freq, + lkpi_nl80211_band_to_net80211_band(channels[i].band)), + channels[i].center_freq, channels[i].max_power, nflags, bands, cflags); /* net80211::ENOBUFS: *n >= maxchans */ if (error != 0 && error != ENOBUFS) @@ -5911,8 +5993,9 @@ lkpi_ic_getradiocaps(struct ieee80211com *ic, int maxchan, cflags &= ~NET80211_CBW_FLAG_HT40; error = ieee80211_add_channel_cbw(c, maxchan, n, - channels[i].hw_value, channels[i].center_freq, - channels[i].max_power, + ieee80211_mhz2ieee(channels[i].center_freq, + lkpi_nl80211_band_to_net80211_band(channels[i].band)), + channels[i].center_freq, channels[i].max_power, nflags, bands, cflags); /* net80211::ENOBUFS: *n >= maxchans */ if (error != 0 && error != ENOBUFS) @@ -5960,7 +6043,9 @@ linuxkpi_ieee80211_alloc_hw(size_t priv_len, const struct ieee80211_ops *ops) LKPI_80211_LHW_SCAN_LOCK_INIT(lhw); LKPI_80211_LHW_TXQ_LOCK_INIT(lhw); sx_init_flags(&lhw->lvif_sx, "lhw-lvif", SX_RECURSE | SX_DUPOK); + LKPI_80211_LHW_MC_LOCK_INIT(lhw); TAILQ_INIT(&lhw->lvif_head); + __hw_addr_init(&lhw->mc_list); for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { lhw->txq_generation[ac] = 1; TAILQ_INIT(&lhw->scheduled_txqs[ac]); @@ -6057,10 +6142,15 @@ linuxkpi_ieee80211_iffree(struct ieee80211_hw *hw) } } + LKPI_80211_LHW_MC_LOCK(lhw); + lkpi_cleanup_mcast_list_locked(lhw); + LKPI_80211_LHW_MC_UNLOCK(lhw); + /* Cleanup more of lhw here or in wiphy_free()? */ LKPI_80211_LHW_TXQ_LOCK_DESTROY(lhw); LKPI_80211_LHW_SCAN_LOCK_DESTROY(lhw); sx_destroy(&lhw->lvif_sx); + LKPI_80211_LHW_MC_LOCK_DESTROY(lhw) IMPROVE(); } @@ -7865,8 +7955,11 @@ linuxkpi_ieee80211_connection_loss(struct ieee80211_vif *vif) nstate = IEEE80211_S_INIT; arg = 0; /* Not a valid reason. */ - ic_printf(vap->iv_ic, "%s: vif %p vap %p state %s\n", __func__, - vif, vap, ieee80211_state_name[vap->iv_state]); + ic_printf(vap->iv_ic, "%s: vif %p vap %p state %s (synched %d, assoc %d " + "beacons %d dtim_period %d)\n", __func__, vif, vap, + ieee80211_state_name[vap->iv_state], + lvif->lvif_bss_synched, vif->cfg.assoc, lvif->beacons, + vif->bss_conf.dtim_period); ieee80211_new_state(vap, nstate, arg); } @@ -7879,8 +7972,11 @@ linuxkpi_ieee80211_beacon_loss(struct ieee80211_vif *vif) lvif = VIF_TO_LVIF(vif); vap = LVIF_TO_VAP(lvif); - ic_printf(vap->iv_ic, "%s: vif %p vap %p state %s\n", __func__, - vif, vap, ieee80211_state_name[vap->iv_state]); + ic_printf(vap->iv_ic, "%s: vif %p vap %p state %s (synched %d, assoc %d " + "beacons %d dtim_period %d)\n", __func__, vif, vap, + ieee80211_state_name[vap->iv_state], + lvif->lvif_bss_synched, vif->cfg.assoc, lvif->beacons, + vif->bss_conf.dtim_period); ieee80211_beacon_miss(vap->iv_ic); } diff --git a/sys/compat/linuxkpi/common/src/linux_80211.h b/sys/compat/linuxkpi/common/src/linux_80211.h index 89afec1235bd..eaf6d804af4c 100644 --- a/sys/compat/linuxkpi/common/src/linux_80211.h +++ b/sys/compat/linuxkpi/common/src/linux_80211.h @@ -187,6 +187,11 @@ struct lkpi_vif { enum ieee80211_state, int); struct ieee80211_node * (*iv_update_bss)(struct ieee80211vap *, struct ieee80211_node *); + void (*iv_recv_mgmt)(struct ieee80211_node *, + struct mbuf *, int, + const struct ieee80211_rx_stats *, + int, int); + struct list_head lsta_list; struct lkpi_sta *lvif_bss; @@ -194,6 +199,7 @@ struct lkpi_vif { struct ieee80211_node *key_update_iv_bss; int ic_unlocked; /* Count of ic unlocks pending (*mo_set_key) */ int nt_unlocked; /* Count of nt unlocks pending (*mo_set_key) */ + int beacons; /* # of beacons since assoc */ bool lvif_bss_synched; bool added_to_drv; /* Driver knows; i.e. we called add_interface(). */ @@ -223,6 +229,9 @@ struct lkpi_hw { /* name it mac80211_sc? */ struct sx lvif_sx; struct list_head lchanctx_list; + struct netdev_hw_addr_list mc_list; + unsigned int mc_flags; + struct sx mc_sx; struct mtx txq_mtx; uint32_t txq_generation[IEEE80211_NUM_ACS]; @@ -279,7 +288,7 @@ struct lkpi_hw { /* name it mac80211_sc? */ int max_rates; /* Maximum number of bitrates supported in any channel. */ int scan_ie_len; /* Length of common per-band scan IEs. */ - bool update_mc; + bool mc_all_multi; bool update_wme; bool rxq_stopped; @@ -369,6 +378,13 @@ struct lkpi_wiphy { #define LKPI_80211_LHW_LVIF_LOCK(_lhw) sx_xlock(&(_lhw)->lvif_sx) #define LKPI_80211_LHW_LVIF_UNLOCK(_lhw) sx_xunlock(&(_lhw)->lvif_sx) +#define LKPI_80211_LHW_MC_LOCK_INIT(_lhw) \ + sx_init_flags(&lhw->mc_sx, "lhw-mc", 0); +#define LKPI_80211_LHW_MC_LOCK_DESTROY(_lhw) \ + sx_destroy(&lhw->mc_sx); +#define LKPI_80211_LHW_MC_LOCK(_lhw) sx_xlock(&(_lhw)->mc_sx) +#define LKPI_80211_LHW_MC_UNLOCK(_lhw) sx_xunlock(&(_lhw)->mc_sx) + #define LKPI_80211_LVIF_LOCK(_lvif) mtx_lock(&(_lvif)->mtx) #define LKPI_80211_LVIF_UNLOCK(_lvif) mtx_unlock(&(_lvif)->mtx) diff --git a/sys/conf/files.x86 b/sys/conf/files.x86 index 9976e9cfec5d..953da7dd1284 100644 --- a/sys/conf/files.x86 +++ b/sys/conf/files.x86 @@ -146,6 +146,7 @@ dev/hyperv/vmbus/vmbus_et.c optional hyperv dev/hyperv/vmbus/vmbus_if.m optional hyperv dev/hyperv/vmbus/vmbus_res.c optional hyperv dev/hyperv/vmbus/vmbus_xact.c optional hyperv +dev/ichwd/i6300esbwd.c optional ichwd dev/ichwd/ichwd.c optional ichwd dev/imcsmb/imcsmb.c optional imcsmb dev/imcsmb/imcsmb_pci.c optional imcsmb pci diff --git a/sys/contrib/vchiq/interface/vchiq_arm/vchiq_2835_arm.c b/sys/contrib/vchiq/interface/vchiq_arm/vchiq_2835_arm.c index ab8981e25cb2..0150ce72f0a4 100644 --- a/sys/contrib/vchiq/interface/vchiq_arm/vchiq_2835_arm.c +++ b/sys/contrib/vchiq/interface/vchiq_arm/vchiq_2835_arm.c @@ -464,7 +464,8 @@ create_pagelist(char __user *buf, size_t count, unsigned short type, (type == PAGELIST_READ ? VM_PROT_WRITE : 0 ) | VM_PROT_READ, pages, num_pages); if (actual_pages != num_pages) { - vm_page_unhold_pages(pages, actual_pages); + if (actual_pages > 0) + vm_page_unhold_pages(pages, actual_pages); free(pagelist, M_VCPAGELIST); return (-ENOMEM); } diff --git a/sys/dev/amdgpio/amdgpio.c b/sys/dev/amdgpio/amdgpio.c index 2bd455c612b8..20589ff71b0b 100644 --- a/sys/dev/amdgpio/amdgpio.c +++ b/sys/dev/amdgpio/amdgpio.c @@ -3,6 +3,10 @@ * * Copyright (c) 2018 Advanced Micro Devices * All rights reserved. + * Copyright (c) 2025 The FreeBSD Foundation + * + * Portions of this software were developed by Aymeric Wibo + * <obiwac@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 @@ -51,11 +55,11 @@ #include <dev/acpica/acpivar.h> #include <dev/gpio/gpiobusvar.h> -#include "gpio_if.h" #include "amdgpio.h" static struct resource_spec amdgpio_spec[] = { - { SYS_RES_MEMORY, 0, RF_ACTIVE }, + { SYS_RES_MEMORY, 0, RF_ACTIVE }, + { SYS_RES_IRQ, 0, RF_ACTIVE | RF_SHAREABLE }, { -1, 0, 0 } }; @@ -196,7 +200,7 @@ static int amdgpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags) { struct amdgpio_softc *sc; - uint32_t reg, val, allowed; + uint32_t reg, val; sc = device_get_softc(dev); @@ -204,18 +208,19 @@ amdgpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags) if (!amdgpio_valid_pin(sc, pin)) return (EINVAL); - allowed = GPIO_PIN_INPUT | GPIO_PIN_OUTPUT; + if ((flags & ~AMDGPIO_DEFAULT_CAPS) != 0) { + device_printf(dev, "disallowed flags (0x%x) trying to be set " + "(allowed is 0x%x)\n", flags, AMDGPIO_DEFAULT_CAPS); + return (EINVAL); + } - /* - * Only directtion flag allowed - */ - if (flags & ~allowed) + /* Either input or output must be selected. */ + if ((flags & (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT)) == 0) return (EINVAL); - /* - * Not both directions simultaneously - */ - if ((flags & allowed) == allowed) + /* Not both directions simultaneously. */ + if ((flags & (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT)) == + (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT)) return (EINVAL); /* Set the GPIO mode and state */ @@ -224,16 +229,21 @@ amdgpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags) reg = AMDGPIO_PIN_REGISTER(pin); val = amdgpio_read_4(sc, reg); - if (flags & GPIO_PIN_INPUT) { + if ((flags & GPIO_PIN_INPUT) != 0) val &= ~BIT(OUTPUT_ENABLE_OFF); - sc->sc_gpio_pins[pin].gp_flags = GPIO_PIN_INPUT; - } else { + else val |= BIT(OUTPUT_ENABLE_OFF); - sc->sc_gpio_pins[pin].gp_flags = GPIO_PIN_OUTPUT; - } + + val &= ~(BIT(PULL_DOWN_ENABLE_OFF) | BIT(PULL_UP_ENABLE_OFF)); + + if ((flags & GPIO_PIN_PULLDOWN) != 0) + val |= BIT(PULL_DOWN_ENABLE_OFF); + if ((flags & GPIO_PIN_PULLUP) != 0) + val |= BIT(PULL_UP_ENABLE_OFF); amdgpio_write_4(sc, reg, val); + sc->sc_gpio_pins[pin].gp_flags = flags; dprintf("pin %d flags 0x%x val 0x%x gp_flags 0x%x\n", pin, flags, val, sc->sc_gpio_pins[pin].gp_flags); @@ -359,11 +369,73 @@ amdgpio_probe(device_t dev) return (rv); } +static void +amdgpio_eoi_locked(struct amdgpio_softc *sc) +{ + uint32_t master_reg = amdgpio_read_4(sc, WAKE_INT_MASTER_REG); + + AMDGPIO_ASSERT_LOCKED(sc); + master_reg |= EOI_MASK; + amdgpio_write_4(sc, WAKE_INT_MASTER_REG, master_reg); +} + +static void +amdgpio_eoi(struct amdgpio_softc *sc) +{ + AMDGPIO_LOCK(sc); + amdgpio_eoi_locked(sc); + AMDGPIO_UNLOCK(sc); +} + +static int +amdgpio_intr_filter(void *arg) +{ + struct amdgpio_softc *sc = arg; + int off, rv = FILTER_STRAY; + uint32_t reg; + + /* We can lock in the filter routine as it is MTX_SPIN. */ + AMDGPIO_LOCK(sc); + + /* + * TODO Instead of just reading the registers of all pins, we should + * read WAKE_INT_STATUS_REG0/1. A bit set in here denotes a group of + * 4 pins where at least one has an interrupt for us. Then we can just + * iterate over those 4 pins. + * + * See GPIO_Interrupt_Status_Index_0 in BKDG. + */ + for (size_t pin = 0; pin < AMD_GPIO_PINS_EXPOSED; pin++) { + off = AMDGPIO_PIN_REGISTER(pin); + reg = amdgpio_read_4(sc, off); + if ((reg & UNSERVICED_INTERRUPT_MASK) == 0) + continue; + /* + * Must write 1's to wake/interrupt status bits to clear them. + * We can do this simply by writing back to the register. + */ + amdgpio_write_4(sc, off, reg); + } + + amdgpio_eoi_locked(sc); + AMDGPIO_UNLOCK(sc); + + rv = FILTER_HANDLED; + return (rv); +} + +static void +amdgpio_intr_handler(void *arg) +{ + /* TODO */ +} + static int amdgpio_attach(device_t dev) { struct amdgpio_softc *sc; - int i, pin, bank; + int i, pin, bank, reg; + uint32_t flags; sc = device_get_softc(dev); sc->sc_dev = dev; @@ -386,6 +458,14 @@ amdgpio_attach(device_t dev) sc->sc_bst = rman_get_bustag(sc->sc_res[0]); sc->sc_bsh = rman_get_bushandle(sc->sc_res[0]); + /* Set up interrupt handler. */ + if (bus_setup_intr(dev, sc->sc_res[1], INTR_TYPE_MISC | INTR_MPSAFE, + amdgpio_intr_filter, amdgpio_intr_handler, sc, &sc->sc_intr_handle) + != 0) { + device_printf(dev, "couldn't set up interrupt\n"); + goto err_intr; + } + /* Initialize all possible pins to be Invalid */ for (i = 0; i < AMD_GPIO_PINS_MAX ; i++) { snprintf(sc->sc_gpio_pins[i].gp_name, GPIOMAXNAME, @@ -395,7 +475,12 @@ amdgpio_attach(device_t dev) sc->sc_gpio_pins[i].gp_flags = 0; } - /* Initialize only driver exposed pins with appropriate capabilities */ + /* + * Initialize only driver exposed pins with appropriate capabilities. + * + * XXX Also mask and disable interrupts on all pins, since we don't + * support them at the moment. + */ for (i = 0; i < AMD_GPIO_PINS_EXPOSED ; i++) { pin = kernzp_pins[i].pin_num; bank = pin/AMD_GPIO_PINS_PER_BANK; @@ -406,7 +491,14 @@ amdgpio_attach(device_t dev) sc->sc_gpio_pins[pin].gp_flags = amdgpio_is_pin_output(sc, pin) ? GPIO_PIN_OUTPUT : GPIO_PIN_INPUT; + + reg = AMDGPIO_PIN_REGISTER(pin); + flags = amdgpio_read_4(sc, reg); + flags &= ~(1 << INTERRUPT_ENABLE_OFF); + flags &= ~(1 << INTERRUPT_MASK_OFF); + amdgpio_write_4(sc, reg, flags); } + amdgpio_eoi(sc); sc->sc_busdev = gpiobus_add_bus(dev); if (sc->sc_busdev == NULL) { @@ -418,8 +510,9 @@ amdgpio_attach(device_t dev) return (0); err_bus: + bus_teardown_intr(dev, sc->sc_res[1], sc->sc_intr_handle); +err_intr: bus_release_resources(dev, amdgpio_spec, sc->sc_res); - err_rsrc: AMDGPIO_LOCK_DESTROY(sc); @@ -434,7 +527,8 @@ amdgpio_detach(device_t dev) if (sc->sc_busdev) gpiobus_detach_bus(dev); - + if (sc->sc_intr_handle) + bus_teardown_intr(dev, sc->sc_res[1], sc->sc_intr_handle); bus_release_resources(dev, amdgpio_spec, sc->sc_res); AMDGPIO_LOCK_DESTROY(sc); diff --git a/sys/dev/amdgpio/amdgpio.h b/sys/dev/amdgpio/amdgpio.h index aca3039bfc98..3743eba23e17 100644 --- a/sys/dev/amdgpio/amdgpio.h +++ b/sys/dev/amdgpio/amdgpio.h @@ -50,7 +50,8 @@ AMD_GPIO_PINS_BANK1 + \ AMD_GPIO_PINS_BANK2 + \ AMD_GPIO_PINS_BANK3) -#define AMDGPIO_DEFAULT_CAPS (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT) +#define AMDGPIO_DEFAULT_CAPS (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT | \ + GPIO_PIN_PULLDOWN | GPIO_PIN_PULLUP) /* Register related macros */ #define AMDGPIO_PIN_REGISTER(pin) (pin * 4) @@ -84,6 +85,9 @@ #define INTERRUPT_STS_OFF 28 #define WAKE_STS_OFF 29 +#define UNSERVICED_INTERRUPT_MASK \ + ((1 << INTERRUPT_STS_OFF) | (1 << WAKE_STS_OFF)) + #define DB_TMR_OUT_MASK 0xFUL #define DB_CNTRL_MASK 0x3UL #define ACTIVE_LEVEL_MASK 0x3UL @@ -316,12 +320,13 @@ struct amdgpio_softc { int sc_npins; int sc_ngroups; struct mtx sc_mtx; - struct resource *sc_res[AMD_GPIO_NUM_PIN_BANK + 1]; + struct resource *sc_res[2]; bus_space_tag_t sc_bst; bus_space_handle_t sc_bsh; struct gpio_pin sc_gpio_pins[AMD_GPIO_PINS_MAX]; const struct pin_info *sc_pin_info; const struct amd_pingroup *sc_groups; + void *sc_intr_handle; }; struct amdgpio_sysctl { diff --git a/sys/dev/hpt27xx/hptintf.h b/sys/dev/hpt27xx/hptintf.h index 558b479ec2ee..eb8105ec5666 100644 --- a/sys/dev/hpt27xx/hptintf.h +++ b/sys/dev/hpt27xx/hptintf.h @@ -155,8 +155,8 @@ typedef HPT_U32 DEVICEID; #define ARRAY_FLAG_NEED_AUTOREBUILD 0x00000080 /* auto-rebuild should start */ #define ARRAY_FLAG_VERIFYING 0x00000100 /* is being verified */ #define ARRAY_FLAG_INITIALIZING 0x00000200 /* is being initialized */ -#define ARRAY_FLAG_TRANSFORMING 0x00000400 /* tranform in progress */ -#define ARRAY_FLAG_NEEDTRANSFORM 0x00000800 /* array need tranform */ +#define ARRAY_FLAG_TRANSFORMING 0x00000400 /* transform in progress */ +#define ARRAY_FLAG_NEEDTRANSFORM 0x00000800 /* array need transform */ #define ARRAY_FLAG_NEEDINITIALIZING 0x00001000 /* the array's initialization hasn't finished*/ #define ARRAY_FLAG_BROKEN_REDUNDANT 0x00002000 /* broken but redundant (raid6) */ #define ARRAY_FLAG_RAID15PLUS 0x80000000 /* display this RAID 1 as RAID 1.5 */ @@ -2018,7 +2018,7 @@ DEVICEID hpt_create_transform_v2(DEVICEID idArray, PCREATE_ARRAY_PARAMS_V3 destI #endif /* hpt_step_transform - * move a block in a tranform progress. + * move a block in a transform progress. * This function is called by mid-layer, not GUI (which uses set_array_state instead). * Version compatibility: v2.0.0.0 or later * Parameters: diff --git a/sys/dev/ichwd/i6300esbwd.c b/sys/dev/ichwd/i6300esbwd.c new file mode 100644 index 000000000000..d95aeb53c3f5 --- /dev/null +++ b/sys/dev/ichwd/i6300esbwd.c @@ -0,0 +1,245 @@ +/* + * Copyright (c) 2025 The FreeBSD Foundation + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +/* + * Reference: Intel 6300ESB Controller Hub Datasheet Section 16 + */ + +#include <sys/param.h> +#include <sys/eventhandler.h> +#include <sys/kernel.h> +#include <sys/module.h> +#include <sys/sysctl.h> +#include <sys/errno.h> +#include <sys/systm.h> +#include <sys/bus.h> +#include <machine/bus.h> +#include <sys/rman.h> +#include <machine/resource.h> +#include <sys/watchdog.h> + +#include <dev/pci/pcireg.h> + +#include <dev/ichwd/ichwd.h> +#include <dev/ichwd/i6300esbwd.h> + +#include <x86/pci_cfgreg.h> +#include <dev/pci/pcivar.h> +#include <dev/pci/pci_private.h> + +struct i6300esbwd_softc { + device_t dev; + int res_id; + struct resource *res; + eventhandler_tag ev_tag; + bool locked; +}; + +static const struct i6300esbwd_pci_id { + uint16_t id; + const char *name; +} i6300esbwd_pci_devices[] = { + { DEVICEID_6300ESB_2, "6300ESB Watchdog Timer" }, +}; + +static uint16_t +i6300esbwd_cfg_read(struct i6300esbwd_softc *sc) +{ + return (pci_read_config(sc->dev, WDT_CONFIG_REG, 2)); +} + +static void +i6300esbwd_cfg_write(struct i6300esbwd_softc *sc, uint16_t val) +{ + pci_write_config(sc->dev, WDT_CONFIG_REG, val, 2); +} + +static uint8_t +i6300esbwd_lock_read(struct i6300esbwd_softc *sc) +{ + return (pci_read_config(sc->dev, WDT_LOCK_REG, 1)); +} + +static void +i6300esbwd_lock_write(struct i6300esbwd_softc *sc, uint8_t val) +{ + pci_write_config(sc->dev, WDT_LOCK_REG, val, 1); +} + +/* + * According to Intel 6300ESB I/O Controller Hub Datasheet 16.5.2, + * the resource should be unlocked before modifing any registers. + * The way to unlock is by write 0x80, 0x86 to the reload register. + */ +static void +i6300esbwd_unlock_res(struct i6300esbwd_softc *sc) +{ + bus_write_2(sc->res, WDT_RELOAD_REG, WDT_UNLOCK_SEQ_1_VAL); + bus_write_2(sc->res, WDT_RELOAD_REG, WDT_UNLOCK_SEQ_2_VAL); +} + +static int +i6300esbwd_sysctl_locked(SYSCTL_HANDLER_ARGS) +{ + struct i6300esbwd_softc *sc = (struct i6300esbwd_softc *)arg1; + int error; + int result; + + result = sc->locked; + error = sysctl_handle_int(oidp, &result, 0, req); + + if (error || !req->newptr) + return (error); + + if (result == 1 && !sc->locked) { + i6300esbwd_lock_write(sc, i6300esbwd_lock_read(sc) | WDT_LOCK); + sc->locked = true; + } + + return (0); +} + +static void +i6300esbwd_event(void *arg, unsigned int cmd, int *error) +{ + struct i6300esbwd_softc *sc = arg; + uint32_t timeout; + uint16_t regval; + + cmd &= WD_INTERVAL; + if (cmd != 0 && + (cmd < WD_TO_1MS || (cmd - WD_TO_1MS) >= WDT_PRELOAD_BIT)) { + *error = EINVAL; + return; + } + timeout = 1 << (cmd - WD_TO_1MS); + + /* reset the timer to prevent timeout a timeout is about to occur */ + i6300esbwd_unlock_res(sc); + bus_write_2(sc->res, WDT_RELOAD_REG, WDT_RELOAD); + + if (!cmd) { + /* + * when the lock is enabled, we are unable to overwrite LOCK + * register + */ + if (sc->locked) + *error = EPERM; + else + i6300esbwd_lock_write(sc, + i6300esbwd_lock_read(sc) & ~WDT_ENABLE); + return; + } + + i6300esbwd_unlock_res(sc); + bus_write_4(sc->res, WDT_PRELOAD_1_REG, timeout); + + i6300esbwd_unlock_res(sc); + bus_write_4(sc->res, WDT_PRELOAD_2_REG, timeout); + + i6300esbwd_unlock_res(sc); + bus_write_2(sc->res, WDT_RELOAD_REG, WDT_RELOAD); + + if (!sc->locked) { + i6300esbwd_lock_write(sc, WDT_ENABLE); + regval = i6300esbwd_lock_read(sc); + sc->locked = regval & WDT_LOCK; + } +} + +static int +i6300esbwd_probe(device_t dev) +{ + const struct i6300esbwd_pci_id *pci_id; + uint16_t pci_dev_id; + int err = ENXIO; + + if (pci_get_vendor(dev) != VENDORID_INTEL) + goto end; + + pci_dev_id = pci_get_device(dev); + for (pci_id = i6300esbwd_pci_devices; + pci_id < i6300esbwd_pci_devices + nitems(i6300esbwd_pci_devices); + ++pci_id) { + if (pci_id->id == pci_dev_id) { + device_set_desc(dev, pci_id->name); + err = BUS_PROBE_DEFAULT; + break; + } + } + +end: + return (err); +} + +static int +i6300esbwd_attach(device_t dev) +{ + struct i6300esbwd_softc *sc = device_get_softc(dev); + uint16_t regval; + + sc->dev = dev; + sc->res_id = PCIR_BAR(0); + sc->res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->res_id, + RF_ACTIVE); + if (sc->res == NULL) { + device_printf(dev, "unable to map memory region\n"); + return (ENXIO); + } + + i6300esbwd_cfg_write(sc, WDT_INT_TYPE_DISABLED_VAL); + regval = i6300esbwd_lock_read(sc); + if (regval & WDT_LOCK) + sc->locked = true; + else { + sc->locked = false; + i6300esbwd_lock_write(sc, WDT_TOUT_CNF_WT_MODE); + } + + i6300esbwd_unlock_res(sc); + bus_write_2(sc->res, WDT_RELOAD_REG, WDT_RELOAD | WDT_TIMEOUT); + + sc->ev_tag = EVENTHANDLER_REGISTER(watchdog_list, i6300esbwd_event, sc, + 0); + + SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), + SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "locked", + CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT, sc, 0, + i6300esbwd_sysctl_locked, "I", + "Lock the timer so that we cannot disable it"); + + return (0); +} + +static int +i6300esbwd_detach(device_t dev) +{ + struct i6300esbwd_softc *sc = device_get_softc(dev); + + if (sc->ev_tag) + EVENTHANDLER_DEREGISTER(watchdog_list, sc->ev_tag); + + if (sc->res) + bus_release_resource(dev, SYS_RES_MEMORY, sc->res_id, sc->res); + + return (0); +} + +static device_method_t i6300esbwd_methods[] = { + DEVMETHOD(device_probe, i6300esbwd_probe), + DEVMETHOD(device_attach, i6300esbwd_attach), + DEVMETHOD(device_detach, i6300esbwd_detach), + DEVMETHOD(device_shutdown, i6300esbwd_detach), + DEVMETHOD_END +}; + +static driver_t i6300esbwd_driver = { + "i6300esbwd", + i6300esbwd_methods, + sizeof(struct i6300esbwd_softc), +}; + +DRIVER_MODULE(i6300esbwd, pci, i6300esbwd_driver, NULL, NULL); diff --git a/sys/dev/ichwd/i6300esbwd.h b/sys/dev/ichwd/i6300esbwd.h new file mode 100644 index 000000000000..39ed5d5a84f6 --- /dev/null +++ b/sys/dev/ichwd/i6300esbwd.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2025 The FreeBSD Foundation + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#ifndef _I6300ESBWD_H_ +#define _I6300ESBWD_H_ + +#define WDT_CONFIG_REG 0x60 +#define WDT_LOCK_REG 0x68 + +#define WDT_PRELOAD_1_REG 0x00 +#define WDT_PRELOAD_2_REG 0x04 +#define WDT_INTR_REG 0x08 +#define WDT_RELOAD_REG 0x0C + +/* For config register */ +#define WDT_OUTPUT_EN (0x1 << 5) +#define WDT_PRE_SEL (0x1 << 2) +#define WDT_INT_TYPE_BITS (0x3) +#define WDT_INT_TYPE_IRQ_VAL (0x0) +#define WDT_INT_TYPE_RES_VAL (0x1) +#define WDT_INT_TYPE_SMI_VAL (0x2) +#define WDT_INT_TYPE_DISABLED_VAL (0x3) + +/* For lock register */ +#define WDT_TOUT_CNF_WT_MODE (0x0 << 2) +#define WDT_TOUT_CNF_FR_MODE (0x1 << 2) +#define WDT_ENABLE (0x02) +#define WDT_LOCK (0x01) + +/* For preload 1/2 registers */ +#define WDT_PRELOAD_BIT 20 +#define WDT_PRELOAD_BITS ((0x1 << WDT_PRELOAD_BIT) - 1) + +/* For interrupt register */ +#define WDT_INTR_ACT (0x01 << 0) + +/* For reload register */ +#define WDT_TIMEOUT (0x01 << 9) +#define WDT_RELOAD (0x01 << 8) +#define WDT_UNLOCK_SEQ_1_VAL 0x80 +#define WDT_UNLOCK_SEQ_2_VAL 0x86 + +#endif /* _I6300ESBWD_H_ */ diff --git a/sys/dev/ichwd/ichwd.c b/sys/dev/ichwd/ichwd.c index cade2cc4fb45..5481553cc175 100644 --- a/sys/dev/ichwd/ichwd.c +++ b/sys/dev/ichwd/ichwd.c @@ -90,7 +90,7 @@ static struct ichwd_device ichwd_devices[] = { { DEVICEID_82801E, "Intel 82801E watchdog timer", 5, 1 }, { DEVICEID_82801EB, "Intel 82801EB watchdog timer", 5, 1 }, { DEVICEID_82801EBR, "Intel 82801EB/ER watchdog timer", 5, 1 }, - { DEVICEID_6300ESB, "Intel 6300ESB watchdog timer", 5, 1 }, + { DEVICEID_6300ESB_1, "Intel 6300ESB watchdog timer", 5, 1 }, { DEVICEID_82801FBR, "Intel 82801FB/FR watchdog timer", 6, 2 }, { DEVICEID_ICH6M, "Intel ICH6M watchdog timer", 6, 2 }, { DEVICEID_ICH6W, "Intel ICH6W watchdog timer", 6, 2 }, diff --git a/sys/dev/ichwd/ichwd.h b/sys/dev/ichwd/ichwd.h index 90fda08b74c1..72d0ca1cd6aa 100644 --- a/sys/dev/ichwd/ichwd.h +++ b/sys/dev/ichwd/ichwd.h @@ -151,7 +151,8 @@ struct ichwd_softc { #define DEVICEID_82801E 0x2450 #define DEVICEID_82801EB 0x24dc #define DEVICEID_82801EBR 0x24d0 -#define DEVICEID_6300ESB 0x25a1 +#define DEVICEID_6300ESB_1 0x25a1 +#define DEVICEID_6300ESB_2 0x25ab #define DEVICEID_82801FBR 0x2640 #define DEVICEID_ICH6M 0x2641 #define DEVICEID_ICH6W 0x2642 diff --git a/sys/dev/puc/pucdata.c b/sys/dev/puc/pucdata.c index e911a407cca9..436af76001da 100644 --- a/sys/dev/puc/pucdata.c +++ b/sys/dev/puc/pucdata.c @@ -64,6 +64,7 @@ static puc_config_f puc_config_quatech; static puc_config_f puc_config_syba; static puc_config_f puc_config_siig; static puc_config_f puc_config_sunix; +static puc_config_f puc_config_systembase; static puc_config_f puc_config_timedia; static puc_config_f puc_config_titan; @@ -1705,6 +1706,23 @@ const struct puc_cfg puc_pci_devices[] = { PUC_PORT_4S, 0x10, 0, 8, .config_function = puc_config_icbook }, + + /* + * Systembase cards using SB16C1050 UARTs: + */ + { 0x14a1, 0x0008, 0x14a1, 0x0008, + "Systembase SB16C1058", + DEFAULT_RCLK * 8, + PUC_PORT_8S, 0x10, 0, 8, + .config_function = puc_config_systembase, + }, + { 0x14a1, 0x0004, 0x14a1, 0x0004, + "Systembase SB16C1054", + DEFAULT_RCLK * 8, + PUC_PORT_4S, 0x10, 0, 8, + .config_function = puc_config_systembase, + }, + { 0xffff, 0, 0xffff, 0, NULL, 0 } }; @@ -2294,3 +2312,28 @@ puc_config_titan(struct puc_softc *sc __unused, enum puc_cfg_cmd cmd, } return (ENXIO); } + +static int +puc_config_systembase(struct puc_softc *sc __unused, + enum puc_cfg_cmd cmd, int port, intptr_t *res) +{ + struct puc_bar *bar; + + switch (cmd) { + case PUC_CFG_SETUP: + bar = puc_get_bar(sc, 0x14); + if (bar == NULL) + return (ENXIO); + + /* + * The Systembase SB16C1058 (and probably other devices + * based on the SB16C1050 UART core) require poking a + * register in the *other* RID to turn on interrupts. + */ + bus_write_1(bar->b_res, /* OPT_IMRREG0 */ 0xc, 0xff); + return (0); + default: + break; + } + return (ENXIO); +} diff --git a/sys/dev/uart/uart_bus_pci.c b/sys/dev/uart/uart_bus_pci.c index 14ac213066b8..22af8ee8663c 100644 --- a/sys/dev/uart/uart_bus_pci.c +++ b/sys/dev/uart/uart_bus_pci.c @@ -141,6 +141,8 @@ static const struct pci_id pci_ns8250_ids[] = { 0x10, 16384000 }, { 0x1415, 0xc120, 0xffff, 0, "Oxford Semiconductor OXPCIe952 PCIe 16950 UART", 0x10 }, +{ 0x14a1, 0x0008, 0x14a1, 0x0008, "Systembase SB16C1058", + 0x10, 8 * DEFAULT_RCLK, }, { 0x14e4, 0x160a, 0xffff, 0, "Broadcom TruManage UART", 0x10, 128 * DEFAULT_RCLK, 2}, { 0x14e4, 0x4344, 0xffff, 0, "Sony Ericsson GC89 PC Card", 0x10}, diff --git a/sys/modules/ichwd/Makefile b/sys/modules/ichwd/Makefile index 3c3bbc37eff5..27b4c38437ff 100644 --- a/sys/modules/ichwd/Makefile +++ b/sys/modules/ichwd/Makefile @@ -1,6 +1,6 @@ .PATH: ${SRCTOP}/sys/dev/ichwd KMOD= ichwd -SRCS= ichwd.c device_if.h bus_if.h pci_if.h isa_if.h +SRCS= i6300esbwd.c ichwd.c device_if.h bus_if.h pci_if.h isa_if.h .include <bsd.kmod.mk> diff --git a/sys/net/if.c b/sys/net/if.c index 79c883fd4a0a..202be4794f6e 100644 --- a/sys/net/if.c +++ b/sys/net/if.c @@ -2589,16 +2589,7 @@ ifhwioctl(u_long cmd, struct ifnet *ifp, caddr_t data, struct thread *td) * flip. They require special handling because in-kernel * consumers may indepdently toggle them. */ - if ((ifp->if_flags ^ new_flags) & IFF_PPROMISC) { - if (new_flags & IFF_PPROMISC) - ifp->if_flags |= IFF_PROMISC; - else if (ifp->if_pcount == 0) - ifp->if_flags &= ~IFF_PROMISC; - if (log_promisc_mode_change) - if_printf(ifp, "permanently promiscuous mode %s\n", - ((new_flags & IFF_PPROMISC) ? - "enabled" : "disabled")); - } + if_setppromisc(ifp, new_flags & IFF_PPROMISC); if ((ifp->if_flags ^ new_flags) & IFF_PALLMULTI) { if (new_flags & IFF_PALLMULTI) ifp->if_flags |= IFF_ALLMULTI; @@ -4456,6 +4447,32 @@ if_getmtu_family(const if_t ifp, int family) return (ifp->if_mtu); } +void +if_setppromisc(if_t ifp, bool ppromisc) +{ + int new_flags; + + if (ppromisc) + new_flags = ifp->if_flags | IFF_PPROMISC; + else + new_flags = ifp->if_flags & ~IFF_PPROMISC; + if ((ifp->if_flags ^ new_flags) & IFF_PPROMISC) { + if (new_flags & IFF_PPROMISC) + new_flags |= IFF_PROMISC; + /* + * Only unset IFF_PROMISC if there are no more consumers of + * promiscuity, i.e. the ifp->if_pcount refcount is 0. + */ + else if (ifp->if_pcount == 0) + new_flags &= ~IFF_PROMISC; + if (log_promisc_mode_change) + if_printf(ifp, "permanently promiscuous mode %s\n", + ((new_flags & IFF_PPROMISC) ? + "enabled" : "disabled")); + } + ifp->if_flags = new_flags; +} + /* * Methods for drivers to access interface unicast and multicast * link level addresses. Driver shall not know 'struct ifaddr' neither diff --git a/sys/net/if_var.h b/sys/net/if_var.h index 08435e7bd5f6..f2df612b19c1 100644 --- a/sys/net/if_var.h +++ b/sys/net/if_var.h @@ -622,6 +622,7 @@ int if_setmtu(if_t ifp, int mtu); int if_getmtu(const if_t ifp); int if_getmtu_family(const if_t ifp, int family); void if_notifymtu(if_t ifp); +void if_setppromisc(const if_t ifp, bool ppromisc); int if_setflagbits(if_t ifp, int set, int clear); int if_setflags(if_t ifp, int flags); int if_getflags(const if_t ifp); diff --git a/sys/netgraph/ng_nat.c b/sys/netgraph/ng_nat.c index defbe817becd..8b82d777caeb 100644 --- a/sys/netgraph/ng_nat.c +++ b/sys/netgraph/ng_nat.c @@ -818,7 +818,8 @@ ng_nat_rcvdata(hook_p hook, item_p item ) if (ip->ip_v != IPVERSION) goto send; /* other IP version, let it pass */ - if (m->m_pkthdr.len < ipofs + ntohs(ip->ip_len)) + uint16_t ip_len = ntohs(ip->ip_len); + if (m->m_pkthdr.len < (ipofs + ip_len)) goto send; /* packet too short (i.e. fragmented or broken) */ /* @@ -852,50 +853,68 @@ ng_nat_rcvdata(hook_p hook, item_p item ) if (rval == PKT_ALIAS_RESPOND) m->m_flags |= M_SKIP_FIREWALL; - m->m_pkthdr.len = m->m_len = ntohs(ip->ip_len) + ipofs; - if ((ip->ip_off & htons(IP_OFFMASK)) == 0 && - ip->ip_p == IPPROTO_TCP) { - struct tcphdr *th = (struct tcphdr *)((caddr_t)ip + - (ip->ip_hl << 2)); + /* Re-read just in case it has been updated */ + ip_len = ntohs(ip->ip_len); + int new_m_len = ip_len + ipofs; + if (new_m_len > (m->m_len + M_TRAILINGSPACE(m))) { /* - * Here is our terrible HACK. - * - * Sometimes LibAlias edits contents of TCP packet. - * In this case it needs to recompute full TCP - * checksum. However, the problem is that LibAlias - * doesn't have any idea about checksum offloading - * in kernel. To workaround this, we do not do - * checksumming in LibAlias, but only mark the - * packets with TH_RES1 in the th_x2 field. If we - * receive a marked packet, we calculate correct - * checksum for it aware of offloading. - * - * Why do I do such a terrible hack instead of - * recalculating checksum for each packet? - * Because the previous checksum was not checked! - * Recalculating checksums for EVERY packet will - * hide ALL transmission errors. Yes, marked packets - * still suffer from this problem. But, sigh, natd(8) - * has this problem, too. + * This is just a safety railguard to make sure LibAlias has not + * screwed the IP packet up somehow, should probably be KASSERT() + * at some point. Calling in_delayed_cksum() will parse IP packet + * again and reliably panic if there is less data than the IP + * header declares, there might be some other places too. */ + log(LOG_ERR, "ng_nat_rcvdata: outgoing packet corrupted, " + "not enough data: expected %d, available (%d - %d)\n", + ip_len, m->m_len + (int)M_TRAILINGSPACE(m), ipofs); + NG_FREE_ITEM(item); + return (ENXIO); + } + + m->m_pkthdr.len = m->m_len = new_m_len; - if (tcp_get_flags(th) & TH_RES1) { - uint16_t ip_len = ntohs(ip->ip_len); + if ((ip->ip_off & htons(IP_OFFMASK)) != 0 || ip->ip_p != IPPROTO_TCP) + goto send; - tcp_set_flags(th, tcp_get_flags(th) & ~TH_RES1); - th->th_sum = in_pseudo(ip->ip_src.s_addr, - ip->ip_dst.s_addr, htons(IPPROTO_TCP + - ip_len - (ip->ip_hl << 2))); + uint16_t pl_offset = ip->ip_hl << 2; + struct tcphdr *th = (struct tcphdr *)((caddr_t)ip + pl_offset); - if ((m->m_pkthdr.csum_flags & CSUM_TCP) == 0) { - m->m_pkthdr.csum_data = offsetof(struct tcphdr, - th_sum); - in_delayed_cksum(m); - } - } - } + /* + * Here is our terrible HACK. + * + * Sometimes LibAlias edits contents of TCP packet. + * In this case it needs to recompute full TCP + * checksum. However, the problem is that LibAlias + * doesn't have any idea about checksum offloading + * in kernel. To workaround this, we do not do + * checksumming in LibAlias, but only mark the + * packets with TH_RES1 in the th_x2 field. If we + * receive a marked packet, we calculate correct + * checksum for it aware of offloading. + * + * Why do I do such a terrible hack instead of + * recalculating checksum for each packet? + * Because the previous checksum was not checked! + * Recalculating checksums for EVERY packet will + * hide ALL transmission errors. Yes, marked packets + * still suffer from this problem. But, sigh, natd(8) + * has this problem, too. + */ + + if (!(tcp_get_flags(th) & TH_RES1)) + goto send; + + tcp_set_flags(th, tcp_get_flags(th) & ~TH_RES1); + th->th_sum = in_pseudo(ip->ip_src.s_addr, ip->ip_dst.s_addr, + htons(IPPROTO_TCP + ip_len - pl_offset)); + + if ((m->m_pkthdr.csum_flags & CSUM_TCP) != 0) + goto send; + + m->m_pkthdr.csum_data = offsetof(struct tcphdr, th_sum); + in_delayed_cksum_o(m, ipofs); send: if (hook == priv->in) diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c index ec6ba8d92015..ef08b9cfd3d6 100644 --- a/sys/netinet/ip_output.c +++ b/sys/netinet/ip_output.c @@ -1044,14 +1044,14 @@ done: } void -in_delayed_cksum(struct mbuf *m) +in_delayed_cksum_o(struct mbuf *m, uint16_t iph_offset) { struct ip *ip; struct udphdr *uh; uint16_t cklen, csum, offset; - ip = mtod(m, struct ip *); - offset = ip->ip_hl << 2 ; + ip = (struct ip *)mtodo(m, iph_offset); + offset = iph_offset + (ip->ip_hl << 2); if (m->m_pkthdr.csum_flags & CSUM_UDP) { /* if udp header is not in the first mbuf copy udplen */ @@ -1078,6 +1078,13 @@ in_delayed_cksum(struct mbuf *m) *(u_short *)mtodo(m, offset) = csum; } +void +in_delayed_cksum(struct mbuf *m) +{ + + in_delayed_cksum_o(m, 0); +} + /* * IP socket option processing. */ diff --git a/sys/netinet/ip_var.h b/sys/netinet/ip_var.h index f782ebc53eb0..c113484079a3 100644 --- a/sys/netinet/ip_var.h +++ b/sys/netinet/ip_var.h @@ -271,6 +271,7 @@ VNET_DECLARE(struct pfil_head *, inet_local_pfil_head); #define PFIL_INET_LOCAL_NAME "inet-local" void in_delayed_cksum(struct mbuf *m); +void in_delayed_cksum_o(struct mbuf *m, uint16_t o); /* Hooks for ipfw, dummynet, divert etc. Most are declared in raw_ip.c */ /* diff --git a/sys/netinet/tcp_hpts.c b/sys/netinet/tcp_hpts.c index b77ebc928809..63bbe4bba11b 100644 --- a/sys/netinet/tcp_hpts.c +++ b/sys/netinet/tcp_hpts.c @@ -137,8 +137,6 @@ #include <netinet/in_kdtrace.h> #include <netinet/in_pcb.h> #include <netinet/ip.h> -#include <netinet/ip_icmp.h> /* required for icmp_var.h */ -#include <netinet/icmp_var.h> /* for ICMP_BANDLIM */ #include <netinet/ip_var.h> #include <netinet/ip6.h> #include <netinet6/in6_pcb.h> diff --git a/sys/netinet/tcp_stacks/bbr.c b/sys/netinet/tcp_stacks/bbr.c index fed259f4d8e1..f2d7867df9b4 100644 --- a/sys/netinet/tcp_stacks/bbr.c +++ b/sys/netinet/tcp_stacks/bbr.c @@ -78,8 +78,6 @@ #include <netinet/in_kdtrace.h> #include <netinet/in_pcb.h> #include <netinet/ip.h> -#include <netinet/ip_icmp.h> /* required for icmp_var.h */ -#include <netinet/icmp_var.h> /* for ICMP_BANDLIM */ #include <netinet/ip_var.h> #include <netinet/ip6.h> #include <netinet6/in6_pcb.h> diff --git a/sys/netinet/tcp_stacks/rack.c b/sys/netinet/tcp_stacks/rack.c index 71dd4de6baf9..11ef5ba706c5 100644 --- a/sys/netinet/tcp_stacks/rack.c +++ b/sys/netinet/tcp_stacks/rack.c @@ -77,8 +77,6 @@ #include <netinet/in_kdtrace.h> #include <netinet/in_pcb.h> #include <netinet/ip.h> -#include <netinet/ip_icmp.h> /* required for icmp_var.h */ -#include <netinet/icmp_var.h> /* for ICMP_BANDLIM */ #include <netinet/ip_var.h> #include <netinet/ip6.h> #include <netinet6/in6_pcb.h> diff --git a/sys/netinet/tcp_stacks/rack_bbr_common.c b/sys/netinet/tcp_stacks/rack_bbr_common.c index fc12672a45f7..4a0a5fc118f6 100644 --- a/sys/netinet/tcp_stacks/rack_bbr_common.c +++ b/sys/netinet/tcp_stacks/rack_bbr_common.c @@ -76,8 +76,6 @@ #include <netinet/in_kdtrace.h> #include <netinet/in_pcb.h> #include <netinet/ip.h> -#include <netinet/ip_icmp.h> /* required for icmp_var.h */ -#include <netinet/icmp_var.h> /* for ICMP_BANDLIM */ #include <netinet/ip_var.h> #include <netinet/ip6.h> #include <netinet6/in6_pcb.h> diff --git a/sys/netinet/tcp_stacks/rack_pcm.c b/sys/netinet/tcp_stacks/rack_pcm.c index 759bfda98357..1a51097f627c 100644 --- a/sys/netinet/tcp_stacks/rack_pcm.c +++ b/sys/netinet/tcp_stacks/rack_pcm.c @@ -78,8 +78,6 @@ #include <netinet/in_kdtrace.h> #include <netinet/in_pcb.h> #include <netinet/ip.h> -#include <netinet/ip_icmp.h> /* required for icmp_var.h */ -#include <netinet/icmp_var.h> /* for ICMP_BANDLIM */ #include <netinet/ip_var.h> #include <netinet/ip6.h> #include <netinet6/in6_pcb.h> diff --git a/sys/netinet/tcp_stacks/tailq_hash.c b/sys/netinet/tcp_stacks/tailq_hash.c index 5ba3e7cd36c0..ff01640524b6 100644 --- a/sys/netinet/tcp_stacks/tailq_hash.c +++ b/sys/netinet/tcp_stacks/tailq_hash.c @@ -51,8 +51,6 @@ #include <netinet/in_kdtrace.h> #include <netinet/in_pcb.h> #include <netinet/ip.h> -#include <netinet/ip_icmp.h> /* required for icmp_var.h */ -#include <netinet/icmp_var.h> /* for ICMP_BANDLIM */ #include <netinet/ip_var.h> #include <netinet/ip6.h> #include <netinet6/in6_pcb.h> diff --git a/sys/netlink/route/iface_drivers.c b/sys/netlink/route/iface_drivers.c index 21db3017df18..4f1540740ead 100644 --- a/sys/netlink/route/iface_drivers.c +++ b/sys/netlink/route/iface_drivers.c @@ -82,28 +82,39 @@ _nl_modify_ifp_generic(struct ifnet *ifp, struct nl_parsed_link *lattrs, } } - if ((lattrs->ifi_change & IFF_UP) && (lattrs->ifi_flags & IFF_UP) == 0) { - /* Request to down the interface */ - if_down(ifp); + if ((lattrs->ifi_change & IFF_UP) != 0 || lattrs->ifi_change == 0) { + /* Request to up or down the interface */ + if (lattrs->ifi_flags & IFF_UP) + if_up(ifp); + else + if_down(ifp); } if (lattrs->ifla_mtu > 0) { if (nlp_has_priv(npt->nlp, PRIV_NET_SETIFMTU)) { struct ifreq ifr = { .ifr_mtu = lattrs->ifla_mtu }; - error = ifhwioctl(SIOCSIFMTU, ifp, (char *)&ifr, curthread); + error = ifhwioctl(SIOCSIFMTU, ifp, (char *)&ifr, + curthread); + if (error != 0) { + nlmsg_report_err_msg(npt, "Failed to set mtu"); + return (error); + } } else { nlmsg_report_err_msg(npt, "Not enough privileges to set mtu"); return (EPERM); } } - if (lattrs->ifi_change & IFF_PROMISC) { - error = ifpromisc(ifp, lattrs->ifi_flags & IFF_PROMISC); - if (error != 0) { - nlmsg_report_err_msg(npt, "unable to set promisc"); - return (error); - } - } + if ((lattrs->ifi_change & IFF_PROMISC) != 0 || + lattrs->ifi_change == 0) + /* + * When asking for IFF_PROMISC, set permanent flag instead + * (IFF_PPROMISC) as we have no way of doing promiscuity + * reference counting through ifpromisc(). Every call to this + * function either sets or unsets IFF_PROMISC, and ifi_change + * is usually set to 0xFFFFFFFF. + */ + if_setppromisc(ifp, (lattrs->ifi_flags & IFF_PROMISC) != 0); if (lattrs->ifla_address != NULL) { if (nlp_has_priv(npt->nlp, PRIV_NET_SETIFMAC)) { diff --git a/usr.sbin/mountd/exports.5 b/usr.sbin/mountd/exports.5 index a90d81c4db99..786411fbf6d8 100644 --- a/usr.sbin/mountd/exports.5 +++ b/usr.sbin/mountd/exports.5 @@ -25,7 +25,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd December 16, 2024 +.Dd August 24, 2025 .Dt EXPORTS 5 .Os .Sh NAME @@ -148,6 +148,19 @@ characters. Mount points for a file system may appear on multiple lines each with different sets of hosts and export options. .Pp +Note that, for NFSv4 exporting, there must be both one or more ``V4:'' line(s) +and one or more line(s) exporting the file systems that are to be +exported to NFSv4 clients. +If there are multiple ``V4:'' lines, these lines must all specify the +same root directory path, but with different options for different +clients. +These line(s) do not export any file system, but simply define the +location of the ``root'' of the NFSv4 export subtree. +The line(s) exporting the file systems should always +specify the pathname of the root of a server file system +and must include at least one line exporting the file system +which is specified as the ``root'' by the ``V4:'' line(s). +.Pp The second component of a line specifies how the file system is to be exported to the host set. The option flags specify whether the file system |