From 86dd740dd73aa88477ff450b2359abda1ad68534 Mon Sep 17 00:00:00 2001 From: Gordon Tetlow Date: Sun, 4 Aug 2024 14:10:46 -0700 Subject: [PATCH 001/213] openssl: Remove fips module from base system. To comply with FIPS 140 guidance, you must be using a specifically validated and approved version of the fips module. Currently, only OpenSSL 3.0.8 and 3.0.9 have been approved by NIST for FIPS 140 validation. As such, we need to stop shipping later versions of the module in the base system. MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D46223 --- ObsoleteFiles.inc | 3 + secure/lib/libcrypto/modules/Makefile | 2 +- secure/lib/libcrypto/modules/fips/Makefile | 340 --------------------- 3 files changed, 4 insertions(+), 341 deletions(-) delete mode 100644 secure/lib/libcrypto/modules/fips/Makefile diff --git a/ObsoleteFiles.inc b/ObsoleteFiles.inc index 5ce960fdca82..fe1eb89f1c9c 100644 --- a/ObsoleteFiles.inc +++ b/ObsoleteFiles.inc @@ -51,6 +51,9 @@ # xargs -n1 | sort | uniq -d; # done +# 20240827: retire fips.so +OLD_LIBS+=usr/lib/ossl-modules/fips.so + # 20240824: sound examples: midi.c moved out of oss/ OLD_FILES+=share/examples/sound/oss/midi.c diff --git a/secure/lib/libcrypto/modules/Makefile b/secure/lib/libcrypto/modules/Makefile index 0e01eb3b8ef2..69a8470ff20b 100644 --- a/secure/lib/libcrypto/modules/Makefile +++ b/secure/lib/libcrypto/modules/Makefile @@ -1,4 +1,4 @@ -SUBDIR= fips legacy +SUBDIR= legacy SUBDIR_PARALLEL= .include diff --git a/secure/lib/libcrypto/modules/fips/Makefile b/secure/lib/libcrypto/modules/fips/Makefile deleted file mode 100644 index 0f4889f3ff81..000000000000 --- a/secure/lib/libcrypto/modules/fips/Makefile +++ /dev/null @@ -1,340 +0,0 @@ -SHLIB_NAME?= fips.so - -CFLAGS+= -DFIPS_MODULE - -SRCS+= fips_entry.c fipsprov.c self_test.c self_test_kats.c - -.include "../../Makefile.common" - -# crypto -SRCS+= provider_core.c provider_predefined.c \ - core_fetch.c core_algorithm.c core_namemap.c self_test_core.c - -SRCS+= cpuid.c ctype.c -.if defined(ASM_aarch64) -SRCS+= arm64cpuid.S armcap.c -ACFLAGS.arm64cpuid.S= -march=armv8-a+crypto -.elif defined(ASM_amd64) -SRCS+= x86_64cpuid.S -.elif defined(ASM_arm) -SRCS+= armv4cpuid.S armcap.c -.elif defined(ASM_i386) -SRCS+= x86cpuid.S -.elif defined(ASM_powerpc) -SRCS+= ppccpuid.S ppccap.c -.elif defined(ASM_powerpc64) -SRCS+= ppccpuid.S ppccap.c -.elif defined(ASM_powerpc64le) -SRCS+= ppccpuid.S ppccap.c -.else -SRCS+= mem_clr.c -.endif - -# crypto/aes -SRCS+= aes_cfb.c aes_ecb.c aes_ige.c aes_misc.c aes_ofb.c aes_wrap.c -.if defined(ASM_aarch64) -SRCS+= aes_cbc.c aes_core.c aesv8-armx.S vpaes-armv8.S -ACFLAGS.aesv8-armx.S= -march=armv8-a+crypto -.elif defined(ASM_amd64) -SRCS+= aes-x86_64.S aesni-mb-x86_64.S aesni-sha1-x86_64.S -SRCS+= aesni-sha256-x86_64.S aesni-x86_64.S bsaes-x86_64.S vpaes-x86_64.S -.elif defined(ASM_arm) -SRCS+= aes_cbc.c aes-armv4.S aesv8-armx.S bsaes-armv7.S -.elif defined(ASM_i386) -SRCS+= aes-586.S aesni-x86.S vpaes-x86.S -.elif defined(ASM_powerpc) -SRCS+= aes_cbc.c aes_core.c aes-ppc.S vpaes-ppc.S aesp8-ppc.S -.elif defined(ASM_powerpc64) -SRCS+= aes_cbc.c aes_core.c aes-ppc.S vpaes-ppc.S aesp8-ppc.S -.elif defined(ASM_powerpc64le) -SRCS+= aes_cbc.c aes_core.c aes-ppc.S vpaes-ppc.S aesp8-ppc.S -.else -SRCS+= aes_cbc.c aes_core.c -.endif - -# crypto/bn -SRCS+= bn_add.c bn_div.c bn_exp.c bn_lib.c bn_ctx.c bn_mul.c \ - bn_mod.c bn_conv.c bn_rand.c bn_shift.c bn_word.c bn_blind.c \ - bn_kron.c bn_sqrt.c bn_gcd.c bn_prime.c bn_sqr.c \ - bn_recp.c bn_mont.c bn_mpi.c bn_exp2.c bn_gf2m.c bn_nist.c \ - bn_intern.c bn_dh.c bn_rsa_fips186_4.c bn_const.c -.if defined(ASM_aarch64) -SRCS+= armv8-mont.S bn_asm.c -.elif defined(ASM_amd64) -SRCS+= rsaz-avx2.S rsaz-avx512.S rsaz-x86_64.S rsaz_exp.c rsaz_exp_x2.c -SRCS+= x86_64-gcc.c x86_64-gf2m.S x86_64-mont.S x86_64-mont5.S -.elif defined(ASM_arm) -SRCS+= armv4-gf2m.S armv4-mont.S bn_asm.c -.elif defined(ASM_i386) -SRCS+= bn-586.S co-586.S x86-gf2m.S x86-mont.S -.elif defined(ASM_powerpc) -SRCS+= bn_ppc.c bn-ppc.S ppc-mont.S -.elif defined(ASM_powerpc64) -SRCS+= bn_ppc.c bn-ppc.S ppc-mont.S -.elif defined(ASM_powerpc64le) -SRCS+= bn_ppc.c bn-ppc.S ppc-mont.S -.else -SRCS+= bn_asm.c -.endif - -# crypto/buffer -SRCS+= buffer.c - -# crypto/cmac -SRCS+= cmac.c - -# crypto/des -SRCS+= set_key.c ecb3_enc.c -.if defined(ASM_i386) -SRCS+= crypt586.S des-586.S -.else -SRCS+= des_enc.c fcrypt_b.c -.endif - -# crypto/dh -SRCS+= dh_lib.c dh_key.c dh_group_params.c dh_check.c dh_backend.c dh_gen.c \ - dh_kdf.c - -# crypto/dsa -SRCS+= dsa_sign.c dsa_vrf.c dsa_lib.c dsa_ossl.c dsa_check.c \ - dsa_key.c dsa_backend.c dsa_gen.c - -# crypto/ec -SRCS+= ec_lib.c ecp_smpl.c ecp_mont.c ecp_nist.c ec_cvt.c ec_mult.c \ - ec_curve.c ec_check.c ec_key.c ec_kmeth.c ecx_key.c ec_asn1.c \ - ec2_smpl.c \ - ecp_oct.c ec2_oct.c ec_oct.c ecdh_ossl.c \ - ecdsa_ossl.c ecdsa_sign.c ecdsa_vrf.c curve25519.c \ - curve448/f_generic.c curve448/scalar.c \ - curve448/curve448_tables.c curve448/eddsa.c curve448/curve448.c \ - ec_backend.c ecx_backend.c ecdh_kdf.c curve448/arch_64/f_impl64.c \ - curve448/arch_32/f_impl32.c -SRCS+= cryptlib.c params.c params_from_text.c bsearch.c ex_data.c o_str.c \ - threads_pthread.c threads_none.c initthread.c \ - context.c sparse_array.c asn1_dsa.c packet.c param_build.c \ - param_build_set.c der_writer.c threads_lib.c params_dup.c - -.include -.if ${MACHINE_ABI:Mlittle-endian} && ${MACHINE_ABI:Mlong64} -SRCS+= ecp_nistp224.c ecp_nistp256.c ecp_nistp521.c ecp_nistputil.c -.endif -.if defined(ASM_aarch64) -SRCS+= ecp_nistz256-armv8.S ecp_nistz256.c -.elif defined(ASM_amd64) -SRCS+= ecp_nistz256-x86_64.S ecp_nistz256.c x25519-x86_64.S -.elif defined(ASM_arm) -SRCS+= ecp_nistz256-armv4.S ecp_nistz256.c -.elif defined(ASM_i386) -SRCS+= ecp_nistz256-x86.S ecp_nistz256.c -.elif defined(ASM_powerpc64) -SRCS+= ecp_nistp521-ppc64.S ecp_nistz256-ppc64.S ecp_nistz256.c ecp_ppc.c x25519-ppc64.S -.elif defined(ASM_powerpc64le) -SRCS+= ecp_nistp521-ppc64.S ecp_nistz256-ppc64.S ecp_nistz256.c ecp_ppc.c x25519-ppc64.S -.endif - -# crypto/evp -SRCS+= digest.c evp_enc.c evp_lib.c evp_fetch.c evp_utils.c \ - mac_lib.c mac_meth.c keymgmt_meth.c keymgmt_lib.c kdf_lib.c kdf_meth.c \ - m_sigver.c pmeth_lib.c signature.c p_lib.c pmeth_gn.c exchange.c \ - evp_rand.c asymcipher.c kem.c dh_support.c ec_support.c pmeth_check.c - -# crypto/ffc -SRCS+= ffc_params.c ffc_params_generate.c ffc_key_generate.c \ - ffc_params_validate.c ffc_key_validate.c ffc_backend.c \ - ffc_dh.c - -# crypto/hmac -SRCS+= hmac.c - -# crypto/lhash -SRCS+= lhash.c - -# crypto/modes -SRCS+= cbc128.c ctr128.c cfb128.c ofb128.c gcm128.c ccm128.c xts128.c -SRCS+= wrap128.c -.if defined(ASM_aarch64) -SRCS+= ghashv8-armx.S aes-gcm-armv8_64.S -ACFLAGS.ghashv8-armx.S= -march=armv8-a+crypto -.elif defined(ASM_amd64) -SRCS+= aesni-gcm-x86_64.S ghash-x86_64.S -.elif defined(ASM_arm) -SRCS+= ghash-armv4.S ghashv8-armx.S -.elif defined(ASM_i386) -SRCS+= ghash-x86.S -.elif defined(ASM_powerpc) -SRCS+= ghashp8-ppc.S -.elif defined(ASM_powerpc64) -SRCS+= ghashp8-ppc.S -.elif defined(ASM_powerpc64le) -SRCS+= ghashp8-ppc.S -.endif - -# crypto/property -SRCS+= property_string.c property_parse.c property_query.c property.c defn_cache.c - -# crypto/rand -SRCS+= rand_lib.c - -# crypto/rsa -SRCS+= rsa_ossl.c rsa_gen.c rsa_lib.c rsa_sign.c rsa_pk1.c \ - rsa_none.c rsa_oaep.c rsa_chk.c rsa_pss.c rsa_x931.c rsa_crpt.c \ - rsa_sp800_56b_gen.c rsa_sp800_56b_check.c rsa_backend.c \ - rsa_mp_names.c rsa_schemes.c -SRCS+= rsa_acvp_test_params.c - -# crypto/sha -SRCS+= sha1dgst.c sha256.c sha512.c sha3.c -.if defined(ASM_aarch64) -SRCS+= keccak1600-armv8.S sha1-armv8.S sha256-armv8.S sha512-armv8.S -.elif defined(ASM_amd64) -SRCS+= keccak1600-x86_64.S sha1-mb-x86_64.S sha1-x86_64.S -SRCS+= sha256-mb-x86_64.S sha256-x86_64.S sha512-x86_64.S -.elif defined(ASM_arm) -SRCS+= keccak1600-armv4.S sha1-armv4-large.S sha256-armv4.S sha512-armv4.S -.elif defined(ASM_i386) -SRCS+= keccak1600.c sha1-586.S sha256-586.S sha512-586.S -.elif defined(ASM_powerpc) -SRCS+= keccak1600.c sha_ppc.c sha1-ppc.S sha256-ppc.S sha512-ppc.S sha256p8-ppc.S sha512p8-ppc.S -.elif defined(ASM_powerpc64) -SRCS+= keccak1600-ppc64.S sha_ppc.c sha1-ppc.S sha256-ppc.S sha512-ppc.S sha256p8-ppc.S sha512p8-ppc.S -.elif defined(ASM_powerpc64le) -SRCS+= keccak1600-ppc64.S sha_ppc.c sha1-ppc.S sha256-ppc.S sha512-ppc.S sha256p8-ppc.S sha512p8-ppc.S -.else -SRCS+= keccak1600.c -.endif - -# crypto/stack -SRCS+= stack.c - -# common -SRCS+= capabilities.c bio_prov.c digest_to_nid.c \ - securitycheck.c provider_seeding.c -SRCS+= securitycheck_fips.c - -# common/der -SRCS+= der_rsa_gen.c der_rsa_key.c -SRCS+= der_rsa_sig.c - -SRCS+= der_dsa_gen.c der_dsa_key.c -SRCS+= der_dsa_sig.c - -SRCS+= der_ec_gen.c der_ec_key.c -SRCS+= der_ec_sig.c - -SRCS+= der_ecx_gen.c der_ecx_key.c - -SRCS+= der_wrap_gen.c - -# asymciphers -SRCS+= rsa_enc.c - -# ciphers -SRCS+= ciphercommon.c ciphercommon_hw.c ciphercommon_block.c \ - ciphercommon_gcm.c ciphercommon_gcm_hw.c \ - ciphercommon_ccm.c ciphercommon_ccm_hw.c -SRCS+= cipher_aes.c cipher_aes_hw.c \ - cipher_aes_xts.c cipher_aes_xts_hw.c \ - cipher_aes_gcm.c cipher_aes_gcm_hw.c \ - cipher_aes_ccm.c cipher_aes_ccm_hw.c \ - cipher_aes_wrp.c \ - cipher_aes_cbc_hmac_sha.c \ - cipher_aes_cbc_hmac_sha256_hw.c cipher_aes_cbc_hmac_sha1_hw.c \ - cipher_cts.c -SRCS+= cipher_aes_xts_fips.c -SRCS+= cipher_tdes.c cipher_tdes_common.c cipher_tdes_hw.c - -# digests -SRCS+= digestcommon.c -SRCS+= sha2_prov.c -SRCS+= sha3_prov.c - -# exchange -SRCS+= dh_exch.c -SRCS+= ecx_exch.c -SRCS+= ecdh_exch.c -SRCS+= kdf_exch.c - -# kdfs -SRCS+= tls1_prf.c -SRCS+= hkdf.c -SRCS+= kbkdf.c -SRCS+= pbkdf2.c -SRCS+= pbkdf2_fips.c -SRCS+= sskdf.c -SRCS+= sshkdf.c -SRCS+= x942kdf.c - -# kem -SRCS+= rsa_kem.c - -# keymgmt -SRCS+= dh_kmgmt.c -SRCS+= dsa_kmgmt.c -SRCS+= ec_kmgmt.c -SRCS+= ecx_kmgmt.c -SRCS+= kdf_legacy_kmgmt.c -SRCS+= mac_legacy_kmgmt.c -SRCS+= rsa_kmgmt.c - -# macs -SRCS+= gmac_prov.c -SRCS+= hmac_prov.c -SRCS+= kmac_prov.c -SRCS+= cmac_prov.c - -# rands -SRCS+= drbg.c test_rng.c drbg_ctr.c drbg_hash.c drbg_hmac.c crngt.c - -# signature -SRCS+= dsa_sig.c -SRCS+= eddsa_sig.c ecdsa_sig.c -SRCS+= mac_legacy_sig.c -SRCS+= rsa_sig.c - -# ssl -SRCS+= record/tls_pad.c s3_cbc.c - -.include - -.if defined(ASM_${MACHINE_CPUARCH}) -.PATH: ${SRCTOP}/sys/crypto/openssl/${MACHINE_CPUARCH} -.if defined(ASM_amd64) -.PATH: ${LCRYPTO_SRC}/crypto/bn/asm -.endif -.elif defined(ASM_${MACHINE_ARCH}) -.PATH: ${SRCTOP}/sys/crypto/openssl/${MACHINE_ARCH} -.endif - -.PATH: ${LCRYPTO_SRC}/crypto \ - ${LCRYPTO_SRC}/crypto/aes \ - ${LCRYPTO_SRC}/crypto/bio \ - ${LCRYPTO_SRC}/crypto/bn \ - ${LCRYPTO_SRC}/crypto/buffer \ - ${LCRYPTO_SRC}/crypto/cmac \ - ${LCRYPTO_SRC}/crypto/des \ - ${LCRYPTO_SRC}/crypto/dh \ - ${LCRYPTO_SRC}/crypto/dsa \ - ${LCRYPTO_SRC}/crypto/ec \ - ${LCRYPTO_SRC}/crypto/evp \ - ${LCRYPTO_SRC}/crypto/ffc \ - ${LCRYPTO_SRC}/crypto/hmac \ - ${LCRYPTO_SRC}/crypto/lhash \ - ${LCRYPTO_SRC}/crypto/modes \ - ${LCRYPTO_SRC}/crypto/property \ - ${LCRYPTO_SRC}/crypto/rand \ - ${LCRYPTO_SRC}/crypto/rsa \ - ${LCRYPTO_SRC}/crypto/sha \ - ${LCRYPTO_SRC}/crypto/stack \ - ${LCRYPTO_SRC}/providers/fips \ - ${LCRYPTO_SRC}/providers/common/der \ - ${LCRYPTO_SRC}/providers/implementations/asymciphers \ - ${LCRYPTO_SRC}/providers/implementations/ciphers \ - ${LCRYPTO_SRC}/providers/implementations/digests \ - ${LCRYPTO_SRC}/providers/implementations/exchange \ - ${LCRYPTO_SRC}/providers/implementations/kdfs \ - ${LCRYPTO_SRC}/providers/implementations/kem \ - ${LCRYPTO_SRC}/providers/implementations/keymgmt \ - ${LCRYPTO_SRC}/providers/implementations/macs \ - ${LCRYPTO_SRC}/providers/implementations/rands \ - ${LCRYPTO_SRC}/providers/implementations/signature \ - ${LCRYPTO_SRC}/ssl From e9a30c90d31ea86e30d06abcd91fdbd8065cf7f6 Mon Sep 17 00:00:00 2001 From: Christos Margiolis Date: Sat, 31 Aug 2024 19:35:07 +0300 Subject: [PATCH 002/213] ObsoleteFiles.inc: Fix examples path Fixes: c3516c6533a1 ("ObsoleteFiles.inc: Update after sound changes") Sponsored by: The FreeBSD Foundation --- ObsoleteFiles.inc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ObsoleteFiles.inc b/ObsoleteFiles.inc index fe1eb89f1c9c..29cfdc05a3d3 100644 --- a/ObsoleteFiles.inc +++ b/ObsoleteFiles.inc @@ -55,14 +55,14 @@ OLD_LIBS+=usr/lib/ossl-modules/fips.so # 20240824: sound examples: midi.c moved out of oss/ -OLD_FILES+=share/examples/sound/oss/midi.c +OLD_FILES+=usr/share/examples/sound/oss/midi.c # 20240824: sound examples: Remove ossinit.h and rename basic.c to audio.c -OLD_FILES+=share/examples/sound/oss/ossinit.h -OLD_FILES+=share/examples/sound/oss/basic.c +OLD_FILES+=usr/share/examples/sound/oss/ossinit.h +OLD_FILES+=usr/share/examples/sound/oss/basic.c # 20240824: sound examples: Remove ossmidi.h -OLD_FILES+=share/examples/sound/oss/ossmidi.h +OLD_FILES+=usr/share/examples/sound/oss/ossmidi.h # 20240729: rename quick_exit_test to libc_exit_test OLD_FILES+=usr/tests/lib/libc/stdlib/quick_exit_test From d7c87526b1c3d32d3ac3fee8c59d92405b7621b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Fran=C3=A7ois=20Hren?= Date: Sat, 31 Aug 2024 10:53:02 -0700 Subject: [PATCH 003/213] tpm: Register TPM as entropy source MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit TPM is defined as an entropy and is called every 10 seconds. However it was not registered and calls were discarded. Signed-off-by: Jean-François Hren MFC after: 1 week Pull Request: https://github.com/freebsd/freebsd-src/pull/1398 --- sys/dev/tpm/tpm20.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sys/dev/tpm/tpm20.c b/sys/dev/tpm/tpm20.c index 80f7d9e105a6..876dd0bcc40d 100644 --- a/sys/dev/tpm/tpm20.c +++ b/sys/dev/tpm/tpm20.c @@ -206,6 +206,7 @@ tpm20_init(struct tpm_sc *sc) tpm20_release(sc); #ifdef TPM_HARVEST + random_harvest_register_source(RANDOM_PURE_TPM); TIMEOUT_TASK_INIT(taskqueue_thread, &sc->harvest_task, 0, tpm20_harvest, sc); taskqueue_enqueue_timeout(taskqueue_thread, &sc->harvest_task, 0); @@ -222,6 +223,7 @@ tpm20_release(struct tpm_sc *sc) #ifdef TPM_HARVEST if (device_is_attached(sc->dev)) taskqueue_drain_timeout(taskqueue_thread, &sc->harvest_task); + random_harvest_deregister_source(RANDOM_PURE_TPM); #endif if (sc->buf != NULL) From f29e915bc0d216a87f222a208caeb2172c93e4ea Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Tue, 27 Aug 2024 21:20:09 +0000 Subject: [PATCH 004/213] LinuxKPI: add get_random_u8() Add a get_random_u8() implementation following the u36 and u64 versions. We'll likely want to macro-ify them in the future and add all the types which makes sense just to be done. Sponsored by: The FreeBSD Foundation MFC after: 3 days Reviewed by: emaste Differential Revision: https://reviews.freebsd.org/D46464 --- sys/compat/linuxkpi/common/include/linux/random.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/sys/compat/linuxkpi/common/include/linux/random.h b/sys/compat/linuxkpi/common/include/linux/random.h index 808c5bc55974..893ee2b7b728 100644 --- a/sys/compat/linuxkpi/common/include/linux/random.h +++ b/sys/compat/linuxkpi/common/include/linux/random.h @@ -54,6 +54,15 @@ get_random_int(void) return (val); } +static inline uint8_t +get_random_u8(void) +{ + uint8_t val; + + get_random_bytes(&val, sizeof(val)); + return (val); +} + #define get_random_u32() get_random_int() /* From 8adb745dc9716e769ef0f7e993cea8a07735d5d8 Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Tue, 27 Aug 2024 21:05:09 +0000 Subject: [PATCH 005/213] LinuxKPI: add ENAVAIL error code Used by an updated wireless driver. Sponsored by: The FreeBSD Foundation MFC after: 3 days Reviewed by: emaste Differential Revision: https://reviews.freebsd.org/D46461 --- sys/compat/linuxkpi/common/include/linux/errno.h | 1 + 1 file changed, 1 insertion(+) diff --git a/sys/compat/linuxkpi/common/include/linux/errno.h b/sys/compat/linuxkpi/common/include/linux/errno.h index ea258587c6f7..d634675d43d0 100644 --- a/sys/compat/linuxkpi/common/include/linux/errno.h +++ b/sys/compat/linuxkpi/common/include/linux/errno.h @@ -68,5 +68,6 @@ #define ENOMEDIUM 532 #define ENOSR 533 #define ELNRNG 534 +#define ENAVAIL 535 #endif /* _LINUXKPI_LINUX_ERRNO_H_ */ From 273cf7d36336eeed5fc2ad42e5e12a36e36650a0 Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Tue, 27 Aug 2024 21:07:52 +0000 Subject: [PATCH 006/213] LinuxKPI: add eth_hdr() Add an implementation of eth_hdr() needed by a wireless driver. Sponsored by: The FreeBSD Foundation MFC after: 3 days Reviewed by: emaste Differential Revision: https://reviews.freebsd.org/D46462 --- sys/compat/linuxkpi/common/include/linux/if_ether.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/sys/compat/linuxkpi/common/include/linux/if_ether.h b/sys/compat/linuxkpi/common/include/linux/if_ether.h index 3735ad2f5527..6676e8fc142f 100644 --- a/sys/compat/linuxkpi/common/include/linux/if_ether.h +++ b/sys/compat/linuxkpi/common/include/linux/if_ether.h @@ -34,6 +34,7 @@ #define _LINUXKPI_LINUX_IF_ETHER_H_ #include +#include #include @@ -69,4 +70,13 @@ struct ethhdr { uint16_t h_proto; } __packed; +static inline struct ethhdr * +eth_hdr(const struct sk_buff *skb) +{ + struct ethhdr *hdr; + + hdr = (struct ethhdr *)skb_mac_header(skb); + return (hdr); +} + #endif /* _LINUXKPI_LINUX_IF_ETHER_H_ */ From 1847e63d63f440cfcb2f4ee2c2ee8990f0272d88 Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Tue, 27 Aug 2024 21:12:08 +0000 Subject: [PATCH 007/213] LinuxKPI: add no_printk Add a version of no_printk(), which seems to be there to have format string checking while never calling the printk. It seems a very weird thing and it needs a return code and for some reason my initial while (0) { } version hadn't worked while porting over new code but could have been further downstream format string problems. if (0) seems to do the job though I would have expected that to more likely simply get optimised out without any futher format checking. Sponsored by: The FreeBSD Foundation MFC after: 3 days Reviewed by: emaste Differential Revision: https://reviews.freebsd.org/D46463 --- sys/compat/linuxkpi/common/include/linux/printk.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/sys/compat/linuxkpi/common/include/linux/printk.h b/sys/compat/linuxkpi/common/include/linux/printk.h index 933d5aa6f94a..3840a6e5fb8a 100644 --- a/sys/compat/linuxkpi/common/include/linux/printk.h +++ b/sys/compat/linuxkpi/common/include/linux/printk.h @@ -125,4 +125,11 @@ print_hex_dump_bytes(const char *prefix_str, const int prefix_type, #define pr_info_ratelimited(fmt, ...) \ printk_ratelimited(KERN_INFO pr_fmt(fmt), ##__VA_ARGS__) +#define no_printk(fmt, ...) \ +({ \ + if (0) \ + printk(pr_fmt(fmt), ##__VA_ARGS__); \ + 0; \ +}) + #endif /* _LINUXKPI_LINUX_PRINTK_H_ */ From b4ef1b1be753952a4aafa505817164624f712c37 Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Tue, 27 Aug 2024 18:41:17 +0000 Subject: [PATCH 008/213] tools/sdiodevs2h.awk: introduce palias Some of the defined names are not the direct 1:1 mapping with vendor and device names used by Linux device drivers. Introduce a p(roduct)alias so we can map the one device entry I came across without much extra hassle and generate a name device drivers know about: palias BROADCOM_CYPRESS_43439 CYPRESS_43439 Sponsored by: The FreeBSD Foundation MFC after: 3 days Reviewed by: emaste Differential Revision: https://reviews.freebsd.org/D46455 --- sys/tools/sdiodevs2h.awk | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/sys/tools/sdiodevs2h.awk b/sys/tools/sdiodevs2h.awk index 596d09531ab1..99735dc09a62 100644 --- a/sys/tools/sdiodevs2h.awk +++ b/sys/tools/sdiodevs2h.awk @@ -149,6 +149,18 @@ function product(hfile) printf("\n") > hfile } +function palias(hfile) +{ + nproducts++ + + products[nproducts, 1] = $2; # vendor name + products[nproducts, 2] = $3; # product id + products[nproducts, 3] = $4; # id + if (hfile) + printf("#define\tSDIO_DEVICE_ID_%s\tSDIO_DEVICE_ID_%s\n", \ + $2, $3) > hfile +} + function dump_dfile(dfile) { printf("\n") > dfile @@ -243,6 +255,10 @@ while ((getline < srcfile) > 0) { product(hfile) continue } + if ($1 == "palias") { + palias(hfile) + continue + } if ($0 == "") blanklines++ if (hfile) From a800b5bcd1b6638530d3a0759b17cd8d93b7e7ca Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Tue, 27 Aug 2024 20:12:20 +0000 Subject: [PATCH 009/213] sdiodevs: add more vendors and devices Add IDs for Realtek, Atheros (QCA), and Mediatek. While I am not sure we'll ever support the ath10k and possibly mt76 SDIO devices, rtw88 ones can be found with SoCs (e.g. r2s-plus) and are actively being worked on. Update Broadcom/Cypress entries. Sponsored by: The FreeBSD Foundation MFC after: 3 days Reviewed by: emaste Differential Revision: https://reviews.freebsd.org/D46460 --- sys/dev/sdio/sdiodevs | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/sys/dev/sdio/sdiodevs b/sys/dev/sdio/sdiodevs index 194ef8e5d901..8c341e77d9f9 100644 --- a/sys/dev/sdio/sdiodevs +++ b/sys/dev/sdio/sdiodevs @@ -42,8 +42,11 @@ * List of TPLMID_MANF "vendor ID"s. * Please sort by vendor ID ascending. */ +vendor REALTEK 0x024c Realtek +vendor ATHEROS 0x0271 Atheros vendor BROADCOM 0x02d0 Broadcom vendor CYPRESS 0x02d0 Cypress/Broadcom +vendor MEDIATEK 0x037a MediaTek /* * -------------------------------------------------------------------------- @@ -51,6 +54,21 @@ vendor CYPRESS 0x02d0 Cypress/Broadcom * Please group by vendor in same order as above. */ +/* Realtek products */ +/* PR 251063 */ +product REALTEK RTW8723BS 0xb723 802.11bgn SDIO WLAN with Bluetooth 4.0 Single-Chip Controller +/* rtw88 */ +product REALTEK RTW8821BS 0xb821 +product REALTEK RTW8822BS 0xb822 802.11ac/abgn SDIO WLAN with Bluetooth 4.1 Single-Chip Controller +product REALTEK RTW8821CS 0xc821 802.11ac/abgn SDIO WLAN with Bluetooth 4.2 Single-Chip Controller +product REALTEK RTW8822CS 0xc822 802.11ac/abgn SDIO WLAN with Bluetooth x.x Single-Chip Controller +product REALTEK RTW8723DS_1ANT 0xd724 802.11bgn SDIO WLAN with Bluetooth 4.2 Single-Chip Controller +product REALTEK RTW8723DS_2ANT 0xd723 802.11bgn SDIO WLAN with Bluetooth 4.2 Single-Chip Controller + +/* Atheros/QCA products */ +product ATHEROS AR6005 0x050a Qualcomm Atheros 802.11ac WLAN SDIO +product ATHEROS QCA9377 0x0701 Qualcomm Atheros 802.11ac WLAN SDIO + /* Broadcom products */ product BROADCOM 43241 0x4324 BCM43241 fullmac SDIO WiFi product BROADCOM 4329 0x4329 BCM4329 fullmac SDIO WiFi @@ -61,13 +79,25 @@ product BROADCOM 4339 0x4339 BCM4339 fullmac SDIO WiFi product BROADCOM 4345 0x4345 BCM4345 fullmac SDIO WiFi product BROADCOM 4354 0x4354 BCM4354 fullmac SDIO WiFi product BROADCOM 4356 0x4356 BCM4356 fullmac SDIO WiFi +product BROADCOM 4359 0x4359 BCM4359 fullmac SDIO WiFi product BROADCOM 43143 0xa887 BCM43143 fullmac SDIO WiFi product BROADCOM 43340 0xa94c BCM43340 fullmac SDIO WiFi product BROADCOM 43341 0xa94d BCM43341 fullmac SDIO WiFi product BROADCOM 43362 0xa962 BCM43362 fullmac SDIO WiFi product BROADCOM 43364 0xa9a4 BCM43364 fullmac SDIO WiFi product BROADCOM 43430 0xa9a6 BCM43430 fullmac SDIO WiFi +product BROADCOM 43439 0xa9af BCM43439 fullmac SDIO WiFi product BROADCOM 43455 0xa9bf BCM43455 fullmac SDIO WiFi -product CYPRESS 4373 0x4373 CY4373 fullmac SDIO WiFi +product BROADCOM CYPRESS_4373 0x4373 BCMCY4373 fullmac SDIO WiFi +product BROADCOM CYPRESS_43012 0xa804 BCMCY43012 fullmac SDIO WiFi +product BROADCOM CYPRESS_43752 0xaae8 BCMCY43752 fullmac SDIO WiFi +product BROADCOM CYPRESS_89359 0x4355 BCMCY89359 fullmac SDIO WiFi + +product CYPRESS 43439 0xbd3d CY43439 fullmac SDIO WiFi +palias BROADCOM_CYPRESS_43439 CYPRESS_43439 + +/* MediaTek products */ +product MEDIATEK MT7663S 0x7603 MediaTek MT7663S SDIO WiFi +product MEDIATEK MT7921S 0x7901 MediaTek MT7921S SDIO WiFi /* end */ From 780675e1bed9fa8e328327e3b6416642a16b2a98 Mon Sep 17 00:00:00 2001 From: Mark Johnston Date: Sun, 1 Sep 2024 14:00:20 +0000 Subject: [PATCH 010/213] arm64: Fix the VM_MAX_NAMELEN definition The maximum VM name length has changed since the arm64 vmm code was forked. For now, just sync with the amd64 definitions, since they permit longer VM names. As arm64/vmm is implemented only in main, I won't bother dealing with backward compat. Reviewed by: jhb Differential Revision: https://reviews.freebsd.org/D46484 --- sys/arm64/include/vmm.h | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/sys/arm64/include/vmm.h b/sys/arm64/include/vmm.h index 05b013557c06..acbd8f5cbcb9 100644 --- a/sys/arm64/include/vmm.h +++ b/sys/arm64/include/vmm.h @@ -102,14 +102,30 @@ enum vm_reg_name { #define VM_INTINFO_HWEXCEPTION (3 << 8) #define VM_INTINFO_SWINTR (4 << 8) -#define VM_MAX_SUFFIXLEN 15 - #define VM_GUEST_BASE_IPA 0x80000000UL /* Guest kernel start ipa */ -#ifdef _KERNEL - -#define VM_MAX_NAMELEN 32 +/* + * The VM name has to fit into the pathname length constraints of devfs, + * governed primarily by SPECNAMELEN. The length is the total number of + * characters in the full path, relative to the mount point and not + * including any leading '/' characters. + * A prefix and a suffix are added to the name specified by the user. + * The prefix is usually "vmm/" or "vmm.io/", but can be a few characters + * longer for future use. + * The suffix is a string that identifies a bootrom image or some similar + * image that is attached to the VM. A separator character gets added to + * the suffix automatically when generating the full path, so it must be + * accounted for, reducing the effective length by 1. + * The effective length of a VM name is 229 bytes for FreeBSD 13 and 37 + * bytes for FreeBSD 12. A minimum length is set for safety and supports + * a SPECNAMELEN as small as 32 on old systems. + */ +#define VM_MAX_PREFIXLEN 10 +#define VM_MAX_SUFFIXLEN 15 +#define VM_MAX_NAMELEN \ + (SPECNAMELEN - VM_MAX_PREFIXLEN - VM_MAX_SUFFIXLEN - 1) +#ifdef _KERNEL struct vm; struct vm_exception; struct vm_exit; From 133a513ddc9aedf83489373f4af9971347bc6201 Mon Sep 17 00:00:00 2001 From: Mark Johnston Date: Sun, 1 Sep 2024 14:00:26 +0000 Subject: [PATCH 011/213] vmm: Make vmm_dev.h more self-contained vmm.h is required for VM_MAX_SUFFIXLEN. vmm_snapshot.h is required for struct vm_snapshot_meta. This is a prerequisite for including vmm_dev.h in the headers parsed by libsysdecode. Reviewed by: jhb Differential Revision: https://reviews.freebsd.org/D46485 --- sys/amd64/include/vmm_dev.h | 3 ++- sys/arm64/include/vmm_dev.h | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/sys/amd64/include/vmm_dev.h b/sys/amd64/include/vmm_dev.h index 5f347e46b9c4..b77b0ef5d996 100644 --- a/sys/amd64/include/vmm_dev.h +++ b/sys/amd64/include/vmm_dev.h @@ -29,7 +29,8 @@ #ifndef _VMM_DEV_H_ #define _VMM_DEV_H_ -struct vm_snapshot_meta; +#include +#include struct vm_memmap { vm_paddr_t gpa; diff --git a/sys/arm64/include/vmm_dev.h b/sys/arm64/include/vmm_dev.h index 08c237d31046..938bea47c7f8 100644 --- a/sys/arm64/include/vmm_dev.h +++ b/sys/arm64/include/vmm_dev.h @@ -27,6 +27,8 @@ #ifndef _VMM_DEV_H_ #define _VMM_DEV_H_ +#include + struct vm_memmap { vm_paddr_t gpa; int segid; /* memory segment */ From 4008758105a6da9eaa0b96b81dfb3042a33259be Mon Sep 17 00:00:00 2001 From: Mark Johnston Date: Sun, 1 Sep 2024 14:00:32 +0000 Subject: [PATCH 012/213] vmm: Validate credentials when opening a vmmdev Rather than performing privilege checks after a specific VM's device file is opened, do it once at the time the device file is opened. This means that one can continue to access a VM via its device fd after attaching to a jail which does not have vmm enabled, but this seems like a reasonable semantic to have anyway. Reviewed by: jhb Differential Revision: https://reviews.freebsd.org/D46486 --- sys/dev/vmm/vmm_dev.c | 39 +++++++++++++++++++++++++++------------ 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/sys/dev/vmm/vmm_dev.c b/sys/dev/vmm/vmm_dev.c index f43429de4d4c..b4ae2997006f 100644 --- a/sys/dev/vmm/vmm_dev.c +++ b/sys/dev/vmm/vmm_dev.c @@ -186,10 +186,6 @@ vmmdev_rw(struct cdev *cdev, struct uio *uio, int flags) void *hpa, *cookie; struct vmmdev_softc *sc; - error = vmm_priv_check(curthread->td_ucred); - if (error) - return (error); - sc = vmmdev_lookup2(cdev); if (sc == NULL) return (ENXIO); @@ -327,6 +323,32 @@ vm_set_register_set(struct vcpu *vcpu, unsigned int count, int *regnum, return (error); } +static int +vmmdev_open(struct cdev *dev, int flags, int fmt, struct thread *td) +{ + struct vmmdev_softc *sc; + int error; + + sc = vmmdev_lookup2(dev); + KASSERT(sc != NULL, ("%s: device not found", __func__)); + + /* + * A user can only access VMs that they themselves have created. + */ + if (td->td_ucred != sc->ucred) + return (EPERM); + + /* + * A jail without vmm access shouldn't be able to access vmm device + * files at all, but check here just to be thorough. + */ + error = vmm_priv_check(td->td_ucred); + if (error != 0) + return (error); + + return (0); +} + static const struct vmmdev_ioctl vmmdev_ioctls[] = { VMMDEV_IOCTL(VM_GET_REGISTER, VMMDEV_IOCTL_LOCK_ONE_VCPU), VMMDEV_IOCTL(VM_SET_REGISTER, VMMDEV_IOCTL_LOCK_ONE_VCPU), @@ -375,10 +397,6 @@ vmmdev_ioctl(struct cdev *cdev, u_long cmd, caddr_t data, int fflag, const struct vmmdev_ioctl *ioctl; int error, vcpuid; - error = vmm_priv_check(td->td_ucred); - if (error) - return (error); - sc = vmmdev_lookup2(cdev); if (sc == NULL) return (ENXIO); @@ -681,10 +699,6 @@ vmmdev_mmap_single(struct cdev *cdev, vm_ooffset_t *offset, vm_size_t mapsize, int error, found, segid; bool sysmem; - error = vmm_priv_check(curthread->td_ucred); - if (error) - return (error); - first = *offset; last = first + mapsize; if ((nprot & PROT_EXEC) || first < 0 || first >= last) @@ -833,6 +847,7 @@ SYSCTL_PROC(_hw_vmm, OID_AUTO, destroy, static struct cdevsw vmmdevsw = { .d_name = "vmmdev", .d_version = D_VERSION, + .d_open = vmmdev_open, .d_ioctl = vmmdev_ioctl, .d_mmap_single = vmmdev_mmap_single, .d_read = vmmdev_rw, From 887c0877a642c7427aff0cfd0d844b2711e71e1e Mon Sep 17 00:00:00 2001 From: Mark Johnston Date: Sun, 1 Sep 2024 14:00:36 +0000 Subject: [PATCH 013/213] vmm: Use an sx lock for vmmdev_mtx This will make it easier to atomically create the device file and set its si_drv1 member. Reviewed by: jhb Differential Revision: https://reviews.freebsd.org/D46487 --- sys/dev/vmm/vmm_dev.c | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/sys/dev/vmm/vmm_dev.c b/sys/dev/vmm/vmm_dev.c index b4ae2997006f..91d33ccba261 100644 --- a/sys/dev/vmm/vmm_dev.c +++ b/sys/dev/vmm/vmm_dev.c @@ -13,9 +13,9 @@ #include #include #include -#include #include #include +#include #include #include #include @@ -63,8 +63,8 @@ struct vmmdev_softc { static SLIST_HEAD(, vmmdev_softc) head; static unsigned pr_allow_flag; -static struct mtx vmmdev_mtx; -MTX_SYSINIT(vmmdev_mtx, &vmmdev_mtx, "vmm device mutex", MTX_DEF); +static struct sx vmmdev_mtx; +SX_SYSINIT(vmmdev_mtx, &vmmdev_mtx, "vmm device mutex"); static MALLOC_DEFINE(M_VMMDEV, "vmmdev", "vmmdev"); @@ -156,7 +156,7 @@ vmmdev_lookup(const char *name, struct ucred *cred) { struct vmmdev_softc *sc; - mtx_assert(&vmmdev_mtx, MA_OWNED); + sx_assert(&vmmdev_mtx, SA_XLOCKED); SLIST_FOREACH(sc, &head, link) { if (strcmp(name, vm_name(sc->vm)) == 0) @@ -785,9 +785,9 @@ vmmdev_destroy(struct vmmdev_softc *sc) crfree(sc->ucred); if ((sc->flags & VSC_LINKED) != 0) { - mtx_lock(&vmmdev_mtx); + sx_xlock(&vmmdev_mtx); SLIST_REMOVE(&head, sc, vmmdev_softc, link); - mtx_unlock(&vmmdev_mtx); + sx_xunlock(&vmmdev_mtx); } free(sc, M_VMMDEV); @@ -799,10 +799,10 @@ vmmdev_lookup_and_destroy(const char *name, struct ucred *cred) struct cdev *cdev; struct vmmdev_softc *sc; - mtx_lock(&vmmdev_mtx); + sx_xlock(&vmmdev_mtx); sc = vmmdev_lookup(name, cred); if (sc == NULL || sc->cdev == NULL) { - mtx_unlock(&vmmdev_mtx); + sx_xunlock(&vmmdev_mtx); return (EINVAL); } @@ -812,7 +812,7 @@ vmmdev_lookup_and_destroy(const char *name, struct ucred *cred) */ cdev = sc->cdev; sc->cdev = NULL; - mtx_unlock(&vmmdev_mtx); + sx_xunlock(&vmmdev_mtx); destroy_dev(cdev); vmmdev_destroy(sc); @@ -874,9 +874,9 @@ vmmdev_create(const char *name, struct ucred *cred) struct vm *vm; int error; - mtx_lock(&vmmdev_mtx); + sx_xlock(&vmmdev_mtx); sc = vmmdev_lookup(name, cred); - mtx_unlock(&vmmdev_mtx); + sx_xunlock(&vmmdev_mtx); if (sc != NULL) return (EEXIST); @@ -890,16 +890,16 @@ vmmdev_create(const char *name, struct ucred *cred) * Lookup the name again just in case somebody sneaked in when we * dropped the lock. */ - mtx_lock(&vmmdev_mtx); + sx_xlock(&vmmdev_mtx); sc2 = vmmdev_lookup(name, cred); if (sc2 != NULL) { - mtx_unlock(&vmmdev_mtx); + sx_xunlock(&vmmdev_mtx); vmmdev_destroy(sc); return (EEXIST); } sc->flags |= VSC_LINKED; SLIST_INSERT_HEAD(&head, sc, link); - mtx_unlock(&vmmdev_mtx); + sx_xunlock(&vmmdev_mtx); error = make_dev_p(MAKEDEV_CHECKNAME, &cdev, &vmmdevsw, sc->ucred, UID_ROOT, GID_WHEEL, 0600, "vmm/%s", name); @@ -908,10 +908,10 @@ vmmdev_create(const char *name, struct ucred *cred) return (error); } - mtx_lock(&vmmdev_mtx); + sx_xlock(&vmmdev_mtx); sc->cdev = cdev; sc->cdev->si_drv1 = sc; - mtx_unlock(&vmmdev_mtx); + sx_xunlock(&vmmdev_mtx); return (0); } @@ -1019,10 +1019,10 @@ devmem_create_cdev(struct vmmdev_softc *sc, int segid, char *devname) dsc = malloc(sizeof(struct devmem_softc), M_VMMDEV, M_WAITOK | M_ZERO); - mtx_lock(&vmmdev_mtx); + sx_xlock(&vmmdev_mtx); if (sc->cdev == NULL) { /* virtual machine is being created or destroyed */ - mtx_unlock(&vmmdev_mtx); + sx_xunlock(&vmmdev_mtx); free(dsc, M_VMMDEV); destroy_dev_sched_cb(cdev, NULL, 0); return (ENODEV); @@ -1033,7 +1033,7 @@ devmem_create_cdev(struct vmmdev_softc *sc, int segid, char *devname) dsc->cdev = cdev; dsc->sc = sc; SLIST_INSERT_HEAD(&sc->devmem, dsc, link); - mtx_unlock(&vmmdev_mtx); + sx_xunlock(&vmmdev_mtx); /* The 'cdev' is ready for use after 'si_drv1' is initialized */ cdev->si_drv1 = dsc; From cef5f43f819cecdbd16f9686e8186d055b19479e Mon Sep 17 00:00:00 2001 From: Mark Johnston Date: Sun, 1 Sep 2024 14:00:39 +0000 Subject: [PATCH 014/213] vmm: Use make_dev_s() to create vmm devices This avoids creating windows where a device file is accessible but the device-specific field is not set. Now that vmmdev_mtx is a sleepable lock, avoid dropping it while creating devices files. This makes it easier to handle races and simplifies some code; for example, the VSC_LINKED flag is no longer needed. Suggested by: jhb Reviewed by: imp, jhb Differential Revision: https://reviews.freebsd.org/D46488 --- sys/dev/vmm/vmm_dev.c | 103 ++++++++++++++++++------------------------ 1 file changed, 44 insertions(+), 59 deletions(-) diff --git a/sys/dev/vmm/vmm_dev.c b/sys/dev/vmm/vmm_dev.c index 91d33ccba261..ea2aaace832c 100644 --- a/sys/dev/vmm/vmm_dev.c +++ b/sys/dev/vmm/vmm_dev.c @@ -58,7 +58,6 @@ struct vmmdev_softc { SLIST_HEAD(, devmem_softc) devmem; int flags; }; -#define VSC_LINKED 0x01 static SLIST_HEAD(, vmmdev_softc) head; @@ -750,6 +749,8 @@ vmmdev_destroy(struct vmmdev_softc *sc) struct devmem_softc *dsc; int error __diagused; + KASSERT(sc->cdev == NULL, ("%s: cdev not free", __func__)); + /* * Destroy all cdevs: * @@ -759,7 +760,6 @@ vmmdev_destroy(struct vmmdev_softc *sc) */ SLIST_FOREACH(dsc, &sc->devmem, link) { KASSERT(dsc->cdev != NULL, ("devmem cdev already destroyed")); - destroy_dev(dsc->cdev); devmem_destroy(dsc); } @@ -775,21 +775,15 @@ vmmdev_destroy(struct vmmdev_softc *sc) free(dsc, M_VMMDEV); } - if (sc->cdev != NULL) - destroy_dev(sc->cdev); - if (sc->vm != NULL) vm_destroy(sc->vm); if (sc->ucred != NULL) crfree(sc->ucred); - if ((sc->flags & VSC_LINKED) != 0) { - sx_xlock(&vmmdev_mtx); - SLIST_REMOVE(&head, sc, vmmdev_softc, link); - sx_xunlock(&vmmdev_mtx); - } - + sx_xlock(&vmmdev_mtx); + SLIST_REMOVE(&head, sc, vmmdev_softc, link); + sx_xunlock(&vmmdev_mtx); free(sc, M_VMMDEV); } @@ -869,50 +863,43 @@ vmmdev_alloc(struct vm *vm, struct ucred *cred) static int vmmdev_create(const char *name, struct ucred *cred) { + struct make_dev_args mda; struct cdev *cdev; - struct vmmdev_softc *sc, *sc2; + struct vmmdev_softc *sc; struct vm *vm; int error; sx_xlock(&vmmdev_mtx); sc = vmmdev_lookup(name, cred); - sx_xunlock(&vmmdev_mtx); - if (sc != NULL) + if (sc != NULL) { + sx_xunlock(&vmmdev_mtx); return (EEXIST); + } error = vm_create(name, &vm); - if (error != 0) - return (error); - - sc = vmmdev_alloc(vm, cred); - - /* - * Lookup the name again just in case somebody sneaked in when we - * dropped the lock. - */ - sx_xlock(&vmmdev_mtx); - sc2 = vmmdev_lookup(name, cred); - if (sc2 != NULL) { + if (error != 0) { sx_xunlock(&vmmdev_mtx); - vmmdev_destroy(sc); - return (EEXIST); + return (error); } - sc->flags |= VSC_LINKED; + sc = vmmdev_alloc(vm, cred); SLIST_INSERT_HEAD(&head, sc, link); - sx_xunlock(&vmmdev_mtx); - error = make_dev_p(MAKEDEV_CHECKNAME, &cdev, &vmmdevsw, sc->ucred, - UID_ROOT, GID_WHEEL, 0600, "vmm/%s", name); + make_dev_args_init(&mda); + mda.mda_devsw = &vmmdevsw; + mda.mda_cr = sc->ucred; + mda.mda_uid = UID_ROOT; + mda.mda_gid = GID_WHEEL; + mda.mda_mode = 0600; + mda.mda_si_drv1 = sc; + mda.mda_flags = MAKEDEV_CHECKNAME | MAKEDEV_WAITOK; + error = make_dev_s(&mda, &cdev, "vmm/%s", name); if (error != 0) { + sx_xunlock(&vmmdev_mtx); vmmdev_destroy(sc); return (error); } - - sx_xlock(&vmmdev_mtx); sc->cdev = cdev; - sc->cdev->si_drv1 = sc; sx_xunlock(&vmmdev_mtx); - return (0); } @@ -1005,39 +992,37 @@ static struct cdevsw devmemsw = { static int devmem_create_cdev(struct vmmdev_softc *sc, int segid, char *devname) { + struct make_dev_args mda; struct devmem_softc *dsc; - struct cdev *cdev; - const char *vmname; int error; - vmname = vm_name(sc->vm); - - error = make_dev_p(MAKEDEV_CHECKNAME, &cdev, &devmemsw, sc->ucred, - UID_ROOT, GID_WHEEL, 0600, "vmm.io/%s.%s", vmname, devname); - if (error) - return (error); - - dsc = malloc(sizeof(struct devmem_softc), M_VMMDEV, M_WAITOK | M_ZERO); - sx_xlock(&vmmdev_mtx); - if (sc->cdev == NULL) { - /* virtual machine is being created or destroyed */ - sx_xunlock(&vmmdev_mtx); - free(dsc, M_VMMDEV); - destroy_dev_sched_cb(cdev, NULL, 0); - return (ENODEV); - } + dsc = malloc(sizeof(struct devmem_softc), M_VMMDEV, M_WAITOK | M_ZERO); dsc->segid = segid; dsc->name = devname; - dsc->cdev = cdev; dsc->sc = sc; SLIST_INSERT_HEAD(&sc->devmem, dsc, link); + + make_dev_args_init(&mda); + mda.mda_devsw = &devmemsw; + mda.mda_cr = sc->ucred; + mda.mda_uid = UID_ROOT; + mda.mda_gid = GID_WHEEL; + mda.mda_mode = 0600; + mda.mda_si_drv1 = dsc; + mda.mda_flags = MAKEDEV_CHECKNAME | MAKEDEV_WAITOK; + error = make_dev_s(&mda, &dsc->cdev, "vmm.io/%s.%s", vm_name(sc->vm), + devname); + if (error != 0) { + SLIST_REMOVE(&sc->devmem, dsc, devmem_softc, link); + free(dsc->name, M_VMMDEV); + free(dsc, M_VMMDEV); + } + sx_xunlock(&vmmdev_mtx); - /* The 'cdev' is ready for use after 'si_drv1' is initialized */ - cdev->si_drv1 = dsc; - return (0); + return (error); } static void @@ -1045,7 +1030,7 @@ devmem_destroy(void *arg) { struct devmem_softc *dsc = arg; - KASSERT(dsc->cdev, ("%s: devmem cdev already destroyed", __func__)); + destroy_dev(dsc->cdev); dsc->cdev = NULL; dsc->sc = NULL; } From 7d508464f56cf262465fd23ab96e357d8e42c927 Mon Sep 17 00:00:00 2001 From: Mark Johnston Date: Sat, 31 Aug 2024 01:18:23 +0000 Subject: [PATCH 015/213] carp: Fix pullup checks The conditions used to test whether a pullup is needed were inverted. While here: - Fix a bogus assignment to "iplen": it's already initialized to *offp. - Use in_cksum_skip() instead of manually adjusting the data pointer. Otherwise the mbuf is temporarily in an invalid state, since m_len isn't updated to match. Reported by: KMSAN Reviewed by: kp Sponsored by: Klara, Inc. Fixes: 37115154672f ("carp: support VRRPv3") Differential Revision: https://reviews.freebsd.org/D46492 --- sys/netinet/ip_carp.c | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/sys/netinet/ip_carp.c b/sys/netinet/ip_carp.c index 9f163c1097ba..ab001d346313 100644 --- a/sys/netinet/ip_carp.c +++ b/sys/netinet/ip_carp.c @@ -516,7 +516,7 @@ static int carp_input(struct mbuf **mp, int *offp, int proto) { struct mbuf *m = *mp; - struct ip *ip = mtod(m, struct ip *); + struct ip *ip; struct vrrpv3_header *vh; int iplen; int minlen; @@ -532,9 +532,6 @@ carp_input(struct mbuf **mp, int *offp, int proto) return (IPPROTO_DONE); } - iplen = ip->ip_hl << 2; - totlen = ntohs(ip->ip_len); - /* Ensure we have enough header to figure out the version. */ if (m->m_pkthdr.len < iplen + sizeof(*vh)) { CARPSTATS_INC(carps_badlen); @@ -545,14 +542,15 @@ carp_input(struct mbuf **mp, int *offp, int proto) return (IPPROTO_DONE); } - if (iplen + sizeof(*vh) < m->m_len) { + if (m->m_len < iplen + sizeof(*vh)) { if ((m = m_pullup(m, iplen + sizeof(*vh))) == NULL) { CARPSTATS_INC(carps_hdrops); CARP_DEBUG("%s():%d: pullup failed\n", __func__, __LINE__); return (IPPROTO_DONE); } - ip = mtod(m, struct ip *); } + ip = mtod(m, struct ip *); + totlen = ntohs(ip->ip_len); vh = (struct vrrpv3_header *)((char *)ip + iplen); switch (vh->vrrp_version) { @@ -581,7 +579,7 @@ carp_input(struct mbuf **mp, int *offp, int proto) return (IPPROTO_DONE); } - if (iplen + minlen < m->m_len) { + if (m->m_len < iplen + minlen) { if ((m = m_pullup(m, iplen + minlen)) == NULL) { CARPSTATS_INC(carps_hdrops); CARP_DEBUG("%s():%d: pullup failed\n", __func__, __LINE__); @@ -596,15 +594,13 @@ carp_input(struct mbuf **mp, int *offp, int proto) struct carp_header *ch; /* verify the CARP checksum */ - m->m_data += iplen; - if (in_cksum(m, totlen - iplen)) { + if (in_cksum_skip(m, totlen, iplen)) { CARPSTATS_INC(carps_badsum); CARP_DEBUG("%s: checksum failed on %s\n", __func__, if_name(m->m_pkthdr.rcvif)); m_freem(m); break; } - m->m_data -= iplen; ch = (struct carp_header *)((char *)ip + iplen); carp_input_c(m, ch, AF_INET, ip->ip_ttl); break; @@ -689,7 +685,7 @@ carp6_input(struct mbuf **mp, int *offp, int proto) return (IPPROTO_DONE); } - if (sizeof (*ip6) + minlen < m->m_len) { + if (m->m_len < sizeof(*ip6) + minlen) { if ((m = m_pullup(m, sizeof(*ip6) + minlen)) == NULL) { CARPSTATS_INC(carps_hdrops); CARP_DEBUG("%s():%d: pullup failed\n", __func__, __LINE__); @@ -704,15 +700,14 @@ carp6_input(struct mbuf **mp, int *offp, int proto) struct carp_header *ch; /* verify the CARP checksum */ - m->m_data += *offp; - if (in_cksum(m, sizeof(struct carp_header))) { + if (in_cksum_skip(m, *offp + sizeof(struct carp_header), + *offp)) { CARPSTATS_INC(carps_badsum); CARP_DEBUG("%s: checksum failed, on %s\n", __func__, if_name(m->m_pkthdr.rcvif)); m_freem(m); break; } - m->m_data -= *offp; ch = (struct carp_header *)((char *)ip6 + sizeof(*ip6)); carp_input_c(m, ch, AF_INET6, ip6->ip6_hlim); break; From 61295e09859953cce5140daf9c2ff85b3feb0e74 Mon Sep 17 00:00:00 2001 From: Mark Johnston Date: Sat, 31 Aug 2024 01:19:09 +0000 Subject: [PATCH 016/213] dummymbuf: Avoid copyout of uninitialized memory from the sysctl handler If *rulesp was initially unset, we'll allocate a new buffer and pass it to sysctl_handle_string(), which copies the existing string out and then copies in the new string. We need to make sure the buffer containing the existing rules is initialized, otherwise we leak kernel memory to userspace. Fix some nearby style nits while here. Reported by: KMSAN Reviewed by: igoro, kp Fixes: 8aaffd78c0f5 ("Add dummymbuf module for testing purposes") Sponsored by: Klara, Inc. Differential Revision: https://reviews.freebsd.org/D46493 --- sys/net/dummymbuf.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/sys/net/dummymbuf.c b/sys/net/dummymbuf.c index 8c46421888ed..d4ba00b13235 100644 --- a/sys/net/dummymbuf.c +++ b/sys/net/dummymbuf.c @@ -74,7 +74,7 @@ dmb_sysctl_handle_rules(SYSCTL_HANDLER_ARGS) char **rulesp = (char **)arg1; if (req->newptr == NULL) { - // read only + /* read only */ DMB_RULES_SLOCK(); arg1 = *rulesp; if (arg1 == NULL) { @@ -84,10 +84,12 @@ dmb_sysctl_handle_rules(SYSCTL_HANDLER_ARGS) error = sysctl_handle_string(oidp, arg1, arg2, req); DMB_RULES_SUNLOCK(); } else { - // read and write + /* read and write */ DMB_RULES_XLOCK(); - if (*rulesp == NULL) - *rulesp = malloc(arg2, M_DUMMYMBUF_RULES, M_WAITOK); + if (*rulesp == NULL) { + *rulesp = malloc(arg2, M_DUMMYMBUF_RULES, + M_WAITOK | M_ZERO); + } arg1 = *rulesp; error = sysctl_handle_string(oidp, arg1, arg2, req); DMB_RULES_XUNLOCK(); @@ -99,8 +101,7 @@ dmb_sysctl_handle_rules(SYSCTL_HANDLER_ARGS) SYSCTL_PROC(_net_dummymbuf, OID_AUTO, rules, CTLTYPE_STRING | CTLFLAG_MPSAFE | CTLFLAG_RW | CTLFLAG_VNET, &VNET_NAME(dmb_rules), RULES_MAXLEN, dmb_sysctl_handle_rules, "A", - "{inet | inet6 | ethernet} {in | out} [ ];" - " ...;"); + "{inet | inet6 | ethernet} {in | out} []; ...;"); /* * Statistics From 5ab1e5f7e5585558a73b723f07528977a82cee82 Mon Sep 17 00:00:00 2001 From: Kristof Provost Date: Mon, 26 Aug 2024 14:59:38 +0200 Subject: [PATCH 017/213] pf: improve the ICMPv6 direction check Following bluhm's advice this changes the way we setup state keys and perform state lookups for ICMPv6 Neighbor Discovery packets: - replace the NS-dst with ND target address; - replace the NA-src with ND target address; - replace the NA-dst with unspecified address if it is a multicast. This allows pf to match Address Resolution, Neighbor Unreachability Detection and Duplicate Address Detection packets to the corresponding states without the need to create new ones or match unrelated ones. As a side effect we're doing now one state table lookup for ND packets instead of two. Fixes a bug uncovered by one of the previous commits that virtually breaks IPv6 connectivity after few minutes of use. ok stsp henning, with and ok bluhm PR: 280701 MFC after: 1 week Obtained from: OpenBSD, mikeb , 2633ae8c4c8a Sponsored by: Rubicon Communications, LLC ("Netgate") --- sys/net/pfvar.h | 4 +- sys/netpfil/pf/pf.c | 116 +++++++++++++++++++++++++++++------------ sys/netpfil/pf/pf_lb.c | 2 +- 3 files changed, 85 insertions(+), 37 deletions(-) diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h index 10bf527c025d..43d4b908a407 100644 --- a/sys/net/pfvar.h +++ b/sys/net/pfvar.h @@ -2576,8 +2576,8 @@ u_short pf_get_translation(struct pf_pdesc *, struct mbuf *, uint16_t, uint16_t, struct pf_kanchor_stackframe *, struct pf_krule **); -struct pf_state_key *pf_state_key_setup(struct pf_pdesc *, struct pf_addr *, - struct pf_addr *, u_int16_t, u_int16_t); +struct pf_state_key *pf_state_key_setup(struct pf_pdesc *, struct mbuf *, int, + struct pf_addr *, struct pf_addr *, u_int16_t, u_int16_t); struct pf_state_key *pf_state_key_clone(const struct pf_state_key *); void pf_rule_to_actions(struct pf_krule *, struct pf_rule_actions *); diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c index acbaf304995f..b4f8bdeeff24 100644 --- a/sys/netpfil/pf/pf.c +++ b/sys/netpfil/pf/pf.c @@ -331,6 +331,9 @@ static int pf_create_state(struct pf_krule *, struct pf_krule *, u_int16_t, u_int16_t, int *, struct pfi_kkif *, struct pf_kstate **, int, u_int16_t, u_int16_t, int, struct pf_krule_slist *); +static int pf_state_key_addr_setup(struct pf_pdesc *, struct mbuf *, + int, struct pf_state_key_cmp *, int, struct pf_addr *, + int, struct pf_addr *, int); static int pf_test_fragment(struct pf_krule **, struct pfi_kkif *, struct mbuf *, void *, struct pf_pdesc *, struct pf_krule **, struct pf_kruleset **); @@ -347,7 +350,7 @@ static int pf_test_state_udp(struct pf_kstate **, void *, struct pf_pdesc *); int pf_icmp_state_lookup(struct pf_state_key_cmp *, struct pf_pdesc *, struct pf_kstate **, struct mbuf *, - int, struct pfi_kkif *, u_int16_t, u_int16_t, + int, int, struct pfi_kkif *, u_int16_t, u_int16_t, int, int *, int, int); static int pf_test_state_icmp(struct pf_kstate **, struct pfi_kkif *, struct mbuf *, int, @@ -401,7 +404,7 @@ extern struct proc *pf_purge_proc; VNET_DEFINE(struct pf_limit, pf_limits[PF_LIMIT_MAX]); -enum { PF_ICMP_MULTI_NONE, PF_ICMP_MULTI_SOLICITED, PF_ICMP_MULTI_LINK }; +enum { PF_ICMP_MULTI_NONE, PF_ICMP_MULTI_LINK }; #define PACKET_UNDO_NAT(_m, _pd, _off, _s) \ do { \ @@ -1495,9 +1498,66 @@ pf_state_key_ctor(void *mem, int size, void *arg, int flags) return (0); } +static int +pf_state_key_addr_setup(struct pf_pdesc *pd, struct mbuf *m, int off, + struct pf_state_key_cmp *key, int sidx, struct pf_addr *saddr, + int didx, struct pf_addr *daddr, int multi) +{ +#ifdef INET6 + struct nd_neighbor_solicit nd; + struct pf_addr *target; + u_short action, reason; + + if (pd->af == AF_INET || pd->proto != IPPROTO_ICMPV6) + goto copy; + + switch (pd->hdr.icmp6.icmp6_type) { + case ND_NEIGHBOR_SOLICIT: + if (multi) + return (-1); + if (!pf_pull_hdr(m, off, &nd, sizeof(nd), &action, &reason, pd->af)) + return (-1); + target = (struct pf_addr *)&nd.nd_ns_target; + daddr = target; + break; + case ND_NEIGHBOR_ADVERT: + if (multi) + return (-1); + if (!pf_pull_hdr(m, off, &nd, sizeof(nd), &action, &reason, pd->af)) + return (-1); + target = (struct pf_addr *)&nd.nd_ns_target; + saddr = target; + if (IN6_IS_ADDR_MULTICAST(&pd->dst->v6)) { + key->addr[didx].addr32[0] = 0; + key->addr[didx].addr32[1] = 0; + key->addr[didx].addr32[2] = 0; + key->addr[didx].addr32[3] = 0; + daddr = NULL; /* overwritten */ + } + break; + default: + if (multi == PF_ICMP_MULTI_LINK) { + key->addr[sidx].addr32[0] = IPV6_ADDR_INT32_MLL; + key->addr[sidx].addr32[1] = 0; + key->addr[sidx].addr32[2] = 0; + key->addr[sidx].addr32[3] = IPV6_ADDR_INT32_ONE; + saddr = NULL; /* overwritten */ + } + } +copy: +#endif + if (saddr) + PF_ACPY(&key->addr[sidx], saddr, pd->af); + if (daddr) + PF_ACPY(&key->addr[didx], daddr, pd->af); + + return (0); +} + struct pf_state_key * -pf_state_key_setup(struct pf_pdesc *pd, struct pf_addr *saddr, - struct pf_addr *daddr, u_int16_t sport, u_int16_t dport) +pf_state_key_setup(struct pf_pdesc *pd, struct mbuf *m, int off, + struct pf_addr *saddr, struct pf_addr *daddr, u_int16_t sport, + u_int16_t dport) { struct pf_state_key *sk; @@ -1505,8 +1565,12 @@ pf_state_key_setup(struct pf_pdesc *pd, struct pf_addr *saddr, if (sk == NULL) return (NULL); - PF_ACPY(&sk->addr[pd->sidx], saddr, pd->af); - PF_ACPY(&sk->addr[pd->didx], daddr, pd->af); + if (pf_state_key_addr_setup(pd, m, off, (struct pf_state_key_cmp *)sk, + pd->sidx, pd->src, pd->didx, pd->dst, 0)) { + uma_zfree(V_pf_state_key_z, sk); + return (NULL); + } + sk->port[pd->sidx] = sport; sk->port[pd->didx] = dport; sk->proto = pd->proto; @@ -5210,7 +5274,7 @@ pf_create_state(struct pf_krule *r, struct pf_krule *nr, struct pf_krule *a, if (nr == NULL) { KASSERT((sk == NULL && nk == NULL), ("%s: nr %p sk %p, nk %p", __func__, nr, sk, nk)); - sk = pf_state_key_setup(pd, pd->src, pd->dst, sport, dport); + sk = pf_state_key_setup(pd, m, off, pd->src, pd->dst, sport, dport); if (sk == NULL) goto csfailed; nk = sk; @@ -6655,9 +6719,9 @@ pf_multihome_scan_asconf(struct mbuf *m, int start, int len, int pf_icmp_state_lookup(struct pf_state_key_cmp *key, struct pf_pdesc *pd, - struct pf_kstate **state, struct mbuf *m, int direction, struct pfi_kkif *kif, - u_int16_t icmpid, u_int16_t type, int icmp_dir, int *iidx, int multi, - int inner) + struct pf_kstate **state, struct mbuf *m, int off, int direction, + struct pfi_kkif *kif, u_int16_t icmpid, u_int16_t type, int icmp_dir, + int *iidx, int multi, int inner) { key->af = pd->af; key->proto = pd->proto; @@ -6670,25 +6734,9 @@ pf_icmp_state_lookup(struct pf_state_key_cmp *key, struct pf_pdesc *pd, key->port[pd->sidx] = type; key->port[pd->didx] = icmpid; } - if (pd->af == AF_INET6 && multi != PF_ICMP_MULTI_NONE) { - switch (multi) { - case PF_ICMP_MULTI_SOLICITED: - key->addr[pd->sidx].addr32[0] = IPV6_ADDR_INT32_MLL; - key->addr[pd->sidx].addr32[1] = 0; - key->addr[pd->sidx].addr32[2] = IPV6_ADDR_INT32_ONE; - key->addr[pd->sidx].addr32[3] = pd->src->addr32[3]; - key->addr[pd->sidx].addr8[12] = 0xff; - break; - case PF_ICMP_MULTI_LINK: - key->addr[pd->sidx].addr32[0] = IPV6_ADDR_INT32_MLL; - key->addr[pd->sidx].addr32[1] = 0; - key->addr[pd->sidx].addr32[2] = 0; - key->addr[pd->sidx].addr32[3] = IPV6_ADDR_INT32_ONE; - break; - } - } else - PF_ACPY(&key->addr[pd->sidx], pd->src, key->af); - PF_ACPY(&key->addr[pd->didx], pd->dst, key->af); + if (pf_state_key_addr_setup(pd, m, off, key, pd->sidx, pd->src, + pd->didx, pd->dst, multi)) + return (PF_DROP); STATE_LOOKUP(kif, key, *state, pd); @@ -6751,7 +6799,7 @@ pf_test_state_icmp(struct pf_kstate **state, struct pfi_kkif *kif, * ICMP query/reply message not related to a TCP/UDP packet. * Search for an ICMP state. */ - ret = pf_icmp_state_lookup(&key, pd, state, m, pd->dir, + ret = pf_icmp_state_lookup(&key, pd, state, m, off, pd->dir, kif, virtual_id, virtual_type, icmp_dir, &iidx, PF_ICMP_MULTI_NONE, 0); if (ret >= 0) { @@ -6759,7 +6807,7 @@ pf_test_state_icmp(struct pf_kstate **state, struct pfi_kkif *kif, icmp_dir == PF_OUT) { if (*state != NULL) PF_STATE_UNLOCK((*state)); - ret = pf_icmp_state_lookup(&key, pd, state, m, + ret = pf_icmp_state_lookup(&key, pd, state, m, off, pd->dir, kif, virtual_id, virtual_type, icmp_dir, &iidx, multi, 0); if (ret >= 0) @@ -7167,7 +7215,7 @@ pf_test_state_icmp(struct pf_kstate **state, struct pfi_kkif *kif, pf_icmp_mapping(&pd2, iih->icmp_type, &icmp_dir, &multi, &virtual_id, &virtual_type); - ret = pf_icmp_state_lookup(&key, &pd2, state, m, + ret = pf_icmp_state_lookup(&key, &pd2, state, m, off, pd2.dir, kif, virtual_id, virtual_type, icmp_dir, &iidx, PF_ICMP_MULTI_NONE, 1); if (ret >= 0) @@ -7222,7 +7270,7 @@ pf_test_state_icmp(struct pf_kstate **state, struct pfi_kkif *kif, pf_icmp_mapping(&pd2, iih->icmp6_type, &icmp_dir, &multi, &virtual_id, &virtual_type); - ret = pf_icmp_state_lookup(&key, &pd2, state, m, + ret = pf_icmp_state_lookup(&key, &pd2, state, m, off, pd->dir, kif, virtual_id, virtual_type, icmp_dir, &iidx, PF_ICMP_MULTI_NONE, 1); if (ret >= 0) { @@ -7231,7 +7279,7 @@ pf_test_state_icmp(struct pf_kstate **state, struct pfi_kkif *kif, if (*state != NULL) PF_STATE_UNLOCK((*state)); ret = pf_icmp_state_lookup(&key, pd, - state, m, pd->dir, kif, + state, m, off, pd->dir, kif, virtual_id, virtual_type, icmp_dir, &iidx, multi, 1); if (ret >= 0) diff --git a/sys/netpfil/pf/pf_lb.c b/sys/netpfil/pf/pf_lb.c index 68fc76233dab..6b0b95e9ce01 100644 --- a/sys/netpfil/pf/pf_lb.c +++ b/sys/netpfil/pf/pf_lb.c @@ -637,7 +637,7 @@ pf_get_translation(struct pf_pdesc *pd, struct mbuf *m, int off, return (PFRES_MAX); } - *skp = pf_state_key_setup(pd, saddr, daddr, sport, dport); + *skp = pf_state_key_setup(pd, m, off, saddr, daddr, sport, dport); if (*skp == NULL) return (PFRES_MEMORY); *nkp = pf_state_key_clone(*skp); From d154dc21130b607d7903f276dd6d463b990f33f7 Mon Sep 17 00:00:00 2001 From: Kristof Provost Date: Mon, 26 Aug 2024 15:02:22 +0200 Subject: [PATCH 018/213] pf tests: ensure that neighbour discovery works as expected Also check repeated calls. MFC after: 1 week Sponsored by: Rubicon Communications, LLC ("Netgate") --- tests/sys/netpfil/pf/icmp6.sh | 48 +++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/tests/sys/netpfil/pf/icmp6.sh b/tests/sys/netpfil/pf/icmp6.sh index b9b60a484afc..eb286e23ef4c 100644 --- a/tests/sys/netpfil/pf/icmp6.sh +++ b/tests/sys/netpfil/pf/icmp6.sh @@ -149,8 +149,56 @@ ttl_exceeded_cleanup() pft_cleanup } +atf_test_case "repeat" "cleanup" +repeat_head() +{ + atf_set descr 'Ensure that repeated NDs work' + atf_set require.user root + atf_set require.progs ndisc6 +} + +repeat_body() +{ + pft_init + + epair=$(vnet_mkepair) + ifconfig ${epair}a inet6 2001:db8::2/64 up no_dad + + vnet_mkjail alcatraz ${epair}b + jexec alcatraz ifconfig ${epair}b inet6 2001:db8::1/64 up no_dad + + # Sanity check + atf_check -s exit:0 -o ignore \ + ping -c 1 2001:db8::1 + + jexec alcatraz pfctl -e + pft_set_rules alcatraz \ + "block all" \ + "pass quick inet6 proto ipv6-icmp all icmp6-type neighbrsol keep state (if-bound) ridentifier 1000000107" + + jexec alcatraz pfctl -x loud + ndisc6 -m -n -r 1 2001:db8::1 ${epair}a + jexec alcatraz pfctl -ss -vv + + atf_check -s exit:0 -o ignore \ + ndisc6 -m -n -r 1 2001:db8::1 ${epair}a + jexec alcatraz pfctl -ss -vv + atf_check -s exit:0 -o ignore \ + ndisc6 -m -n -r 1 2001:db8::1 ${epair}a + jexec alcatraz pfctl -ss -vv + atf_check -s exit:0 -o ignore \ + ndisc6 -m -n -r 1 2001:db8::1 ${epair}a + jexec alcatraz pfctl -ss -vv +} + +repeat_cleanup() +{ + pft_cleanup +} + atf_init_test_cases() { atf_add_test_case "zero_id" atf_add_test_case "ttl_exceeded" + atf_add_test_case "repeat" } From b8cd169efa6ac0899b4998898129765ae5c685a6 Mon Sep 17 00:00:00 2001 From: Kristof Provost Date: Mon, 26 Aug 2024 16:42:05 +0200 Subject: [PATCH 019/213] pf: try to lookup the icmp state based on a correct packet descriptor MFC after: 1 week Obtained from: OpenBSD, mikeb , e467ea25dcd3 Sponsored by: Rubicon Communications, LLC ("Netgate") --- sys/netpfil/pf/pf.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c index b4f8bdeeff24..94c333e67c57 100644 --- a/sys/netpfil/pf/pf.c +++ b/sys/netpfil/pf/pf.c @@ -7274,11 +7274,11 @@ pf_test_state_icmp(struct pf_kstate **state, struct pfi_kkif *kif, pd->dir, kif, virtual_id, virtual_type, icmp_dir, &iidx, PF_ICMP_MULTI_NONE, 1); if (ret >= 0) { - if (ret == PF_DROP && pd->af == AF_INET6 && + if (ret == PF_DROP && pd2.af == AF_INET6 && icmp_dir == PF_OUT) { if (*state != NULL) PF_STATE_UNLOCK((*state)); - ret = pf_icmp_state_lookup(&key, pd, + ret = pf_icmp_state_lookup(&key, &pd2, state, m, off, pd->dir, kif, virtual_id, virtual_type, icmp_dir, &iidx, multi, 1); From 3da3eb6081a2e2f6ea2fed1728d5dd7f9e8786e5 Mon Sep 17 00:00:00 2001 From: Kristof Provost Date: Mon, 26 Aug 2024 16:44:20 +0200 Subject: [PATCH 020/213] pf: be less strict about icmp state checking for sloppy state tracking Sloppy state tracking renders ICMP direction check useless and harmful as we might see only half of the connection in the asymmetric setups but ignore the state match. The bug was reported and fix was verified by Insan Praja . Thanks! OK mcbride, henning MFC after: 1 week Obtained from: OpenBSD, mikeb , 538596657140 Sponsored by: Rubicon Communications, LLC ("Netgate") --- sys/netpfil/pf/pf.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c index 94c333e67c57..e28bad8750f9 100644 --- a/sys/netpfil/pf/pf.c +++ b/sys/netpfil/pf/pf.c @@ -6740,6 +6740,9 @@ pf_icmp_state_lookup(struct pf_state_key_cmp *key, struct pf_pdesc *pd, STATE_LOOKUP(kif, key, *state, pd); + if ((*state)->state_flags & PFSTATE_SLOPPY) + return (-1); + /* Is this ICMP message flowing in right direction? */ if ((*state)->rule.ptr->type && (((!inner && (*state)->direction == direction) || From 0578fe492284ded4745167060be794032e6e22f0 Mon Sep 17 00:00:00 2001 From: Kristof Provost Date: Fri, 30 Aug 2024 13:36:39 +0200 Subject: [PATCH 021/213] pf: rework pf_icmp_state_lookup() failure mode If pf_icmp_state_lookup() finds a state but rejects it for not matching the expected direction we should unlock the state (and NULL out *state). This simplifies life for callers, and also ensures there's no confusion about what a non-NULL returned state means. Previously it could have been left in there by the caller, resulting in callers unlocking the same state twice. MFC after: 1 week Sponsored by: Rubicon Communications, LLC ("Netgate") --- sys/net/pfvar.h | 4 ++-- sys/netpfil/pf/pf.c | 20 +++++++++++++------- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h index 43d4b908a407..7b3c1c49696a 100644 --- a/sys/net/pfvar.h +++ b/sys/net/pfvar.h @@ -374,8 +374,8 @@ struct pfi_dynaddr { mtx_unlock(_s->lock); \ } while (0) #else -#define PF_STATE_LOCK(s) mtx_lock(s->lock) -#define PF_STATE_UNLOCK(s) mtx_unlock(s->lock) +#define PF_STATE_LOCK(s) mtx_lock((s)->lock) +#define PF_STATE_UNLOCK(s) mtx_unlock((s)->lock) #endif #ifdef INVARIANTS diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c index e28bad8750f9..f7fe75184efd 100644 --- a/sys/netpfil/pf/pf.c +++ b/sys/netpfil/pf/pf.c @@ -6754,6 +6754,8 @@ pf_icmp_state_lookup(struct pf_state_key_cmp *key, struct pf_pdesc *pd, pf_print_state(*state); printf("\n"); } + PF_STATE_UNLOCK(*state); + *state = NULL; return (PF_DROP); } return (-1); @@ -6806,15 +6808,16 @@ pf_test_state_icmp(struct pf_kstate **state, struct pfi_kkif *kif, kif, virtual_id, virtual_type, icmp_dir, &iidx, PF_ICMP_MULTI_NONE, 0); if (ret >= 0) { + MPASS(*state == NULL); if (ret == PF_DROP && pd->af == AF_INET6 && icmp_dir == PF_OUT) { - if (*state != NULL) - PF_STATE_UNLOCK((*state)); ret = pf_icmp_state_lookup(&key, pd, state, m, off, pd->dir, kif, virtual_id, virtual_type, icmp_dir, &iidx, multi, 0); - if (ret >= 0) + if (ret >= 0) { + MPASS(*state == NULL); return (ret); + } } else return (ret); } @@ -7221,8 +7224,10 @@ pf_test_state_icmp(struct pf_kstate **state, struct pfi_kkif *kif, ret = pf_icmp_state_lookup(&key, &pd2, state, m, off, pd2.dir, kif, virtual_id, virtual_type, icmp_dir, &iidx, PF_ICMP_MULTI_NONE, 1); - if (ret >= 0) + if (ret >= 0) { + MPASS(*state == NULL); return (ret); + } /* translate source/destination address, if necessary */ if ((*state)->key[PF_SK_WIRE] != @@ -7277,16 +7282,17 @@ pf_test_state_icmp(struct pf_kstate **state, struct pfi_kkif *kif, pd->dir, kif, virtual_id, virtual_type, icmp_dir, &iidx, PF_ICMP_MULTI_NONE, 1); if (ret >= 0) { + MPASS(*state == NULL); if (ret == PF_DROP && pd2.af == AF_INET6 && icmp_dir == PF_OUT) { - if (*state != NULL) - PF_STATE_UNLOCK((*state)); ret = pf_icmp_state_lookup(&key, &pd2, state, m, off, pd->dir, kif, virtual_id, virtual_type, icmp_dir, &iidx, multi, 1); - if (ret >= 0) + if (ret >= 0) { + MPASS(*state == NULL); return (ret); + } } else return (ret); } From e60dbfd00b009d424dfc5446d132872c93dd0aed Mon Sep 17 00:00:00 2001 From: Viktor Dukhovni Date: Wed, 19 Jun 2024 21:04:11 +1000 Subject: [PATCH 022/213] Avoid type errors in EAI-related name check logic. The incorrectly typed data is read only, used in a compare operation, so neither remote code execution, nor memory content disclosure were possible. However, applications performing certificate name checks were vulnerable to denial of service. The GENERAL_TYPE data type is a union, and we must take care to access the correct member, based on `gen->type`, not all the member fields have the same structure, and a segfault is possible if the wrong member field is read. The code in question was lightly refactored with the intent to make it more obviously correct. CVE-2024-6119 (cherry picked from commit 1486960d6cdb052e4fc0109a56a0597b4e902ba1) --- crypto/x509/v3_utl.c | 78 +++++++++++++------ test/recipes/25-test_eai_data.t | 12 ++- test/recipes/25-test_eai_data/kdc-cert.pem | 21 +++++ .../25-test_eai_data/kdc-root-cert.pem | 16 ++++ test/recipes/25-test_eai_data/kdc.sh | 41 ++++++++++ 5 files changed, 142 insertions(+), 26 deletions(-) create mode 100644 test/recipes/25-test_eai_data/kdc-cert.pem create mode 100644 test/recipes/25-test_eai_data/kdc-root-cert.pem create mode 100755 test/recipes/25-test_eai_data/kdc.sh diff --git a/crypto/x509/v3_utl.c b/crypto/x509/v3_utl.c index 6e4ef26ed608..304463d572c6 100644 --- a/crypto/x509/v3_utl.c +++ b/crypto/x509/v3_utl.c @@ -916,36 +916,64 @@ static int do_x509_check(X509 *x, const char *chk, size_t chklen, ASN1_STRING *cstr; gen = sk_GENERAL_NAME_value(gens, i); - if ((gen->type == GEN_OTHERNAME) && (check_type == GEN_EMAIL)) { - if (OBJ_obj2nid(gen->d.otherName->type_id) == - NID_id_on_SmtpUTF8Mailbox) { - san_present = 1; - - /* - * If it is not a UTF8String then that is unexpected and we - * treat it as no match - */ - if (gen->d.otherName->value->type == V_ASN1_UTF8STRING) { - cstr = gen->d.otherName->value->value.utf8string; - - /* Positive on success, negative on error! */ - if ((rv = do_check_string(cstr, 0, equal, flags, - chk, chklen, peername)) != 0) - break; - } - } else + switch (gen->type) { + default: + continue; + case GEN_OTHERNAME: + switch (OBJ_obj2nid(gen->d.otherName->type_id)) { + default: continue; - } else { - if ((gen->type != check_type) && (gen->type != GEN_OTHERNAME)) + case NID_id_on_SmtpUTF8Mailbox: + /*- + * https://datatracker.ietf.org/doc/html/rfc8398#section-3 + * + * Due to name constraint compatibility reasons described + * in Section 6, SmtpUTF8Mailbox subjectAltName MUST NOT + * be used unless the local-part of the email address + * contains non-ASCII characters. When the local-part is + * ASCII, rfc822Name subjectAltName MUST be used instead + * of SmtpUTF8Mailbox. This is compatible with legacy + * software that supports only rfc822Name (and not + * SmtpUTF8Mailbox). [...] + * + * SmtpUTF8Mailbox is encoded as UTF8String. + * + * If it is not a UTF8String then that is unexpected, and + * we ignore the invalid SAN (neither set san_present nor + * consider it a candidate for equality). This does mean + * that the subject CN may be considered, as would be the + * case when the malformed SmtpUtf8Mailbox SAN is instead + * simply absent. + * + * When CN-ID matching is not desirable, applications can + * choose to turn it off, doing so is at this time a best + * practice. + */ + if (check_type != GEN_EMAIL + || gen->d.otherName->value->type != V_ASN1_UTF8STRING) + continue; + alt_type = 0; + cstr = gen->d.otherName->value->value.utf8string; + break; + } + break; + case GEN_EMAIL: + if (check_type != GEN_EMAIL) continue; - } - san_present = 1; - if (check_type == GEN_EMAIL) cstr = gen->d.rfc822Name; - else if (check_type == GEN_DNS) + break; + case GEN_DNS: + if (check_type != GEN_DNS) + continue; cstr = gen->d.dNSName; - else + break; + case GEN_IPADD: + if (check_type != GEN_IPADD) + continue; cstr = gen->d.iPAddress; + break; + } + san_present = 1; /* Positive on success, negative on error! */ if ((rv = do_check_string(cstr, alt_type, equal, flags, chk, chklen, peername)) != 0) diff --git a/test/recipes/25-test_eai_data.t b/test/recipes/25-test_eai_data.t index 522982ddfb80..e18735d89aad 100644 --- a/test/recipes/25-test_eai_data.t +++ b/test/recipes/25-test_eai_data.t @@ -21,16 +21,18 @@ setup("test_eai_data"); #./util/wrap.pl apps/openssl verify -nameopt utf8 -no_check_time -CAfile test/recipes/25-test_eai_data/utf8_chain.pem test/recipes/25-test_eai_data/ascii_leaf.pem #./util/wrap.pl apps/openssl verify -nameopt utf8 -no_check_time -CAfile test/recipes/25-test_eai_data/ascii_chain.pem test/recipes/25-test_eai_data/utf8_leaf.pem -plan tests => 12; +plan tests => 16; require_ok(srctop_file('test','recipes','tconversion.pl')); my $folder = "test/recipes/25-test_eai_data"; my $ascii_pem = srctop_file($folder, "ascii_leaf.pem"); my $utf8_pem = srctop_file($folder, "utf8_leaf.pem"); +my $kdc_pem = srctop_file($folder, "kdc-cert.pem"); my $ascii_chain_pem = srctop_file($folder, "ascii_chain.pem"); my $utf8_chain_pem = srctop_file($folder, "utf8_chain.pem"); +my $kdc_chain_pem = srctop_file($folder, "kdc-root-cert.pem"); my $out; my $outcnt = 0; @@ -56,10 +58,18 @@ SKIP: { ok(run(app(["openssl", "verify", "-nameopt", "utf8", "-no_check_time", "-CAfile", $ascii_chain_pem, $ascii_pem]))); ok(run(app(["openssl", "verify", "-nameopt", "utf8", "-no_check_time", "-CAfile", $utf8_chain_pem, $utf8_pem]))); +ok(run(app(["openssl", "verify", "-nameopt", "utf8", "-no_check_time", "-CAfile", $kdc_chain_pem, $kdc_pem]))); ok(!run(app(["openssl", "verify", "-nameopt", "utf8", "-no_check_time", "-CAfile", $ascii_chain_pem, $utf8_pem]))); ok(!run(app(["openssl", "verify", "-nameopt", "utf8", "-no_check_time", "-CAfile", $utf8_chain_pem, $ascii_pem]))); +# Check an otherName does not get misparsed as an DNS name, (should trigger ASAN errors if violated). +ok(run(app(["openssl", "verify", "-nameopt", "utf8", "-no_check_time", "-verify_hostname", 'mx1.example.com', "-CAfile", $kdc_chain_pem, $kdc_pem]))); +# Check an otherName does not get misparsed as an email address, (should trigger ASAN errors if violated). +ok(run(app(["openssl", "verify", "-nameopt", "utf8", "-no_check_time", "-verify_email", 'joe@example.com', "-CAfile", $kdc_chain_pem, $kdc_pem]))); +# We expect SmtpUTF8Mailbox to be a UTF8 String, not an IA5String. +ok(!run(app(["openssl", "verify", "-nameopt", "utf8", "-no_check_time", "-verify_email", 'moe@example.com', "-CAfile", $kdc_chain_pem, $kdc_pem]))); + #Check that we get the expected failure return code with({ exit_checker => sub { return shift == 2; } }, sub { diff --git a/test/recipes/25-test_eai_data/kdc-cert.pem b/test/recipes/25-test_eai_data/kdc-cert.pem new file mode 100644 index 000000000000..e8a2c6f55d45 --- /dev/null +++ b/test/recipes/25-test_eai_data/kdc-cert.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDbDCCAlSgAwIBAgIBAjANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARSb290 +MCAXDTI0MDYyMDA2MTQxNVoYDzIxMjQwNjIwMDYxNDE1WjAXMRUwEwYDVQQDDAxU +RVNULkVYQU1QTEUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6wfP+ +6go79dkpo/dGLMlPZ7Gw/Q6gUYrCWZWUEgEeRVHCrqOlgUEyA+PcWas/XDPUxXry +BQlJHLvlqamAQn8gs4QPBARFYWKNiTVGyaRkgNA1N5gqyZdrP9UE+ZJmdqxRAAe8 +vvpGZWSgevPhLUiSCFYDiD0Rtji2Hm3rGUrReQFBQDEw2pNGwz9zIaxUs08kQZcx +Yzyiplz5Oau+R/6sAgUwDlrD9xOlUxx/tA/MSDIfkK8qioU11uUZtO5VjkNQy/bT +7zQMmXxWgm2MIgOs1u4YN7YGOtgqHE9v9iPHHfgrkbQDtVDGQsa8AQEhkUDSCtW9 +3VFAKx6dGNXYzFwfAgMBAAGjgcgwgcUwHQYDVR0OBBYEFFR5tZycW19DmtbL4Zqj +te1c2vZLMAkGA1UdIwQCMAAwCQYDVR0TBAIwADCBjQYDVR0RBIGFMIGCoD8GBisG +AQUCAqA1MDOgDhsMVEVTVC5FWEFNUExFoSEwH6ADAgEBoRgwFhsGa3JidGd0GwxU +RVNULkVYQU1QTEWgHQYIKwYBBQUHCAmgERYPbW9lQGV4YW1wbGUuY29tgQ9qb2VA +ZXhhbXBsZS5jb22CD214MS5leGFtcGxlLmNvbTANBgkqhkiG9w0BAQsFAAOCAQEA +T0xzVtVpRtaOzIhgzw7XQUdzWD5UEGSJJ1cBCOmKUWwDLTAouCYLFB4TbEE7MMUb +iuMy60bjmVtvfJIXorGUgSadRe5RWJ5DamJWvPA0Q9x7blnEcXqEF+9Td+ypevgU +UYHFmg83OYwxOsFXZ5cRuXMk3WCsDHQIBi6D1L6oDDZ2pfArs5mqm3thQKVlqyl1 +El3XRYEdqAz/5eCOFNfwxF0ALxjxVr/Z50StUZU8I7Zfev6+kHhyrR7dqzYJImv9 +0fTCOBEMjIETDsrA70OxAMu4V16nrWZdJdvzblS2qrt97Omkj+2kiPAJFB76RpwI +oDQ9fKfUOAmUFth2/R/eGA== +-----END CERTIFICATE----- diff --git a/test/recipes/25-test_eai_data/kdc-root-cert.pem b/test/recipes/25-test_eai_data/kdc-root-cert.pem new file mode 100644 index 000000000000..a74c96bf3146 --- /dev/null +++ b/test/recipes/25-test_eai_data/kdc-root-cert.pem @@ -0,0 +1,16 @@ +-----BEGIN CERTIFICATE----- +MIICnDCCAYQCCQCBswYcrlZSHjANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARS +b290MCAXDTI0MDYyMDA2MTQxNVoYDzIxMjQwNjIwMDYxNDE1WjAPMQ0wCwYDVQQD +DARSb290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqRj8S4kBbIUj +61kZfi6nE35Q38U140+qt4uAiwAhKumfVHlBM0zQ98WFt5zMHIBQwIb3yjc2zj+0 +qzUnQfwm1r/RfcMmBPEti9Ge+aEMSsds2gMXziOFM8wd2aAFPy7UVE0XpEWofsRK +MGi61MKVdPSbGIxBwY9VW38/7D/wf1HtJe7y0xpuecR7GB2XAs+qST59NjuF+7wS +dLM8Hb3TATgeYbXXWsRJgwz+SPzExg5WmLnU+7y4brZ32dHtdSmkRVSgSlaIf7Xj +3Tc6Zi7I+W/JYk7hy1zUexVdWCak4PHcoWrXe0gNNN/t8VfLfMExt5z/HIylXnU7 +pGUyqZlTGQIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQAHpLF1UCRy7b6Hk0rLokxI +lgwiH9BU9mktigAGASvkbllpt+YbUbWnuYAvpHBGiP1qZtfX2r96UrSJaGO9BEzT +Gp9ThnSjoj4Srul0+s/NArU22irFLmDzbalgevAmm9gMGkdqkiIm/mXbwrPj0ncl +KGicevXryVpvaP62eZ8cc3C4p97frMmXxRX8sTdQpD/gRI7prdEILRSKveqT+AEW +7rFGM5AOevb4U8ddop8A3D/kX0wcCAIBF6jCNk3uEJ57jVcagL04kPnVfdRiedTS +vfq1DRNcD29d1H/9u0fHdSn1/+8Ep3X+afQ3C6//5NvOEaXcIGO4QSwkprQydfv8 +-----END CERTIFICATE----- diff --git a/test/recipes/25-test_eai_data/kdc.sh b/test/recipes/25-test_eai_data/kdc.sh new file mode 100755 index 000000000000..7a8dbc719fb7 --- /dev/null +++ b/test/recipes/25-test_eai_data/kdc.sh @@ -0,0 +1,41 @@ +#! /usr/bin/env bash + +# Create a root CA, signing a leaf cert with a KDC principal otherName SAN, and +# also a non-UTF8 smtpUtf8Mailbox SAN followed by an rfc822Name SAN and a DNS +# name SAN. In the vulnerable EAI code, the KDC principal `otherName` should +# trigger ASAN errors in DNS name checks, while the non-UTF8 `smtpUtf8Mailbox` +# should likewise lead to ASAN issues with email name checks. + +rm -f root-key.pem root-cert.pem +openssl req -nodes -new -newkey rsa:2048 -keyout kdc-root-key.pem \ + -x509 -subj /CN=Root -days 36524 -out kdc-root-cert.pem + +exts=$( + printf "%s\n%s\n%s\n%s = " \ + "subjectKeyIdentifier = hash" \ + "authorityKeyIdentifier = keyid" \ + "basicConstraints = CA:false" \ + "subjectAltName" + printf "%s, " "otherName:1.3.6.1.5.2.2;SEQUENCE:kdc_princ_name" + printf "%s, " "otherName:1.3.6.1.5.5.7.8.9;IA5:moe@example.com" + printf "%s, " "email:joe@example.com" + printf "%s\n" "DNS:mx1.example.com" + printf "[kdc_princ_name]\n" + printf "realm = EXP:0, GeneralString:TEST.EXAMPLE\n" + printf "principal_name = EXP:1, SEQUENCE:kdc_principal_seq\n" + printf "[kdc_principal_seq]\n" + printf "name_type = EXP:0, INTEGER:1\n" + printf "name_string = EXP:1, SEQUENCE:kdc_principal_components\n" + printf "[kdc_principal_components]\n" + printf "princ1 = GeneralString:krbtgt\n" + printf "princ2 = GeneralString:TEST.EXAMPLE\n" + ) + +printf "%s\n" "$exts" + +openssl req -nodes -new -newkey rsa:2048 -keyout kdc-key.pem \ + -subj "/CN=TEST.EXAMPLE" | + openssl x509 -req -out kdc-cert.pem \ + -CA "kdc-root-cert.pem" -CAkey "kdc-root-key.pem" \ + -set_serial 2 -days 36524 \ + -extfile <(printf "%s\n" "$exts") From e15b5ba77d693609c9a452d1b0a1cdd5eb29350d Mon Sep 17 00:00:00 2001 From: Zhenlei Huang Date: Mon, 2 Sep 2024 12:26:47 +0800 Subject: [PATCH 023/213] kernel: Fix defining of .init_array and .fini_array sections These input sections can have decimal numbers as the priority suffix. Clang emits the '%u' form, while SORT is an alias for SORT_BY_NAME, hence will result in wrong order of constructors / destructors in output sections. Fix by using the correct sorting command SORT_BY_INIT_PRIORITY instead [1]. The functions referenced by section .fini_array is in the normal order, but been executed in the reverse order. The order is same with .init_array section. Currently these sections are not used, there should be no functional change. Note: As for the .ctors and .dtors sections, both Clang and GCC emit the priority suffix in the form of '%05u', so there is no semantic difference between SORT_BY_NAME and SORT_BY_INIT_PRIORITY for those sections [2]. This fix is extracted from a bigger patch [3] of hselasky, with additional fix for .fini_array section. 1. https://sourceware.org/binutils/docs/ld/Input-Section-Wildcards.html 2. https://reviews.llvm.org/D91187 3. https://reviews.freebsd.org/D40467 Reviewed by: imp (previous version) Obtained from: hselasky MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D45194 --- sys/conf/ldscript.amd64 | 4 ++-- sys/conf/ldscript.i386 | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/sys/conf/ldscript.amd64 b/sys/conf/ldscript.amd64 index b3286612b41a..1c7fde2eada0 100644 --- a/sys/conf/ldscript.amd64 +++ b/sys/conf/ldscript.amd64 @@ -93,15 +93,15 @@ SECTIONS .init_array : { PROVIDE_HIDDEN (__init_array_start = .); - KEEP (*(SORT(.init_array.*))) + KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*))) KEEP (*(.init_array)) PROVIDE_HIDDEN (__init_array_end = .); } .fini_array : { PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*))) KEEP (*(.fini_array)) - KEEP (*(SORT(.fini_array.*))) PROVIDE_HIDDEN (__fini_array_end = .); } _start_ctors = .; diff --git a/sys/conf/ldscript.i386 b/sys/conf/ldscript.i386 index 66bdbc4a80cb..467cba24d43f 100644 --- a/sys/conf/ldscript.i386 +++ b/sys/conf/ldscript.i386 @@ -87,15 +87,15 @@ SECTIONS .init_array : { PROVIDE_HIDDEN (__init_array_start = .); - KEEP (*(SORT(.init_array.*))) + KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*))) KEEP (*(.init_array)) PROVIDE_HIDDEN (__init_array_end = .); } .fini_array : { PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*))) KEEP (*(.fini_array)) - KEEP (*(SORT(.fini_array.*))) PROVIDE_HIDDEN (__fini_array_end = .); } _start_ctors = .; From 3e76d05231b0aa77d922bdbc9abf62d9747a91ab Mon Sep 17 00:00:00 2001 From: Zhenlei Huang Date: Mon, 2 Sep 2024 12:26:48 +0800 Subject: [PATCH 024/213] kernel: Add defination of .init_array and .fini_array for all other platforms Currently these sections are not used but defined only for amd64 and i386. Added them for all other platforms to keep all platforms in sync. There should be no functional change. This change is extracted from a bigger patch [1] of hselasky, with additional fix for the order of .fini_array section. 1. https://reviews.freebsd.org/D40467 Obtained from: hselasky MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D45214 --- sys/conf/ldscript.arm | 14 ++++++++++++++ sys/conf/ldscript.arm64 | 14 ++++++++++++++ sys/conf/ldscript.powerpc | 16 ++++++++++++++-- sys/conf/ldscript.powerpc64 | 15 ++++++++++++++- sys/conf/ldscript.powerpc64le | 15 ++++++++++++++- sys/conf/ldscript.powerpcspe | 16 ++++++++++++++-- sys/conf/ldscript.riscv | 14 ++++++++++++++ 7 files changed, 98 insertions(+), 6 deletions(-) diff --git a/sys/conf/ldscript.arm b/sys/conf/ldscript.arm index 0764c99f9042..e8d2db3f854b 100644 --- a/sys/conf/ldscript.arm +++ b/sys/conf/ldscript.arm @@ -83,6 +83,20 @@ SECTIONS } .data1 : { *(.data1) } . = ALIGN(32 / 8); + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*))) + KEEP (*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + } + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*))) + KEEP (*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + } _start_ctors = .; PROVIDE (start_ctors = .); .ctors : diff --git a/sys/conf/ldscript.arm64 b/sys/conf/ldscript.arm64 index 32af035105d0..0d50eef431cf 100644 --- a/sys/conf/ldscript.arm64 +++ b/sys/conf/ldscript.arm64 @@ -100,6 +100,20 @@ SECTIONS . = ALIGN(128); .data1 : { *(.data1) } . = ALIGN(32 / 8); + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*))) + KEEP (*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + } + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*))) + KEEP (*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + } _start_ctors = .; PROVIDE (start_ctors = .); .ctors : diff --git a/sys/conf/ldscript.powerpc b/sys/conf/ldscript.powerpc index 0e11dd4459db..3a407a4dbf88 100644 --- a/sys/conf/ldscript.powerpc +++ b/sys/conf/ldscript.powerpc @@ -78,8 +78,20 @@ SECTIONS . = ALIGN(4096); .got : { *(.got) } .got.plt : { *(.got.plt) } - - + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*))) + KEEP (*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + } + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*))) + KEEP (*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + } .dynamic : { *(.dynamic) } :kernel :dynamic /* Put .ctors and .dtors next to the .got2 section, so that the pointers get relocated with -mrelocatable. Also put in the .fixup pointers. diff --git a/sys/conf/ldscript.powerpc64 b/sys/conf/ldscript.powerpc64 index 58a3dc69931b..a342a48b9daf 100644 --- a/sys/conf/ldscript.powerpc64 +++ b/sys/conf/ldscript.powerpc64 @@ -104,7 +104,20 @@ SECTIONS . = ALIGN(4096); .got : ALIGN(8) { __tocbase = .; *(.got) } .toc : ALIGN(8) { *(.toc) } - + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*))) + KEEP (*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + } + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*))) + KEEP (*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + } .dynamic : { *(.dynamic) } :kernel :dynamic /* Put .ctors and .dtors next to the .got2 section, so that the pointers get relocated with -mrelocatable. Also put in the .fixup pointers. diff --git a/sys/conf/ldscript.powerpc64le b/sys/conf/ldscript.powerpc64le index a65b39b3d9eb..1d5f3efe64fd 100644 --- a/sys/conf/ldscript.powerpc64le +++ b/sys/conf/ldscript.powerpc64le @@ -104,7 +104,20 @@ SECTIONS . = ALIGN(4096); .got : ALIGN(8) { __tocbase = .; *(.got) } .toc : ALIGN(8) { *(.toc) } - + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*))) + KEEP (*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + } + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*))) + KEEP (*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + } .dynamic : { *(.dynamic) } :kernel :dynamic /* Put .ctors and .dtors next to the .got2 section, so that the pointers get relocated with -mrelocatable. Also put in the .fixup pointers. diff --git a/sys/conf/ldscript.powerpcspe b/sys/conf/ldscript.powerpcspe index 66630aaabaae..fa82cbe8330f 100644 --- a/sys/conf/ldscript.powerpcspe +++ b/sys/conf/ldscript.powerpcspe @@ -79,8 +79,20 @@ SECTIONS . = ALIGN(4096); .got : { *(.got) } .got.plt : { *(.got.plt) } - - + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*))) + KEEP (*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + } + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*))) + KEEP (*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + } .dynamic : { *(.dynamic) } :kernel :dynamic /* Put .ctors and .dtors next to the .got2 section, so that the pointers get relocated with -mrelocatable. Also put in the .fixup pointers. diff --git a/sys/conf/ldscript.riscv b/sys/conf/ldscript.riscv index b964a8739b7c..c730b423ccc2 100644 --- a/sys/conf/ldscript.riscv +++ b/sys/conf/ldscript.riscv @@ -71,6 +71,20 @@ SECTIONS } .data1 : { *(.data1) } . = ALIGN(32 / 8); + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*))) + KEEP (*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + } + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*))) + KEEP (*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + } _start_ctors = .; PROVIDE (start_ctors = .); .ctors : From 9867b4af50c627586c68b26ddc5a7344286eefaf Mon Sep 17 00:00:00 2001 From: Wolfram Schneider Date: Mon, 2 Sep 2024 09:55:10 +0000 Subject: [PATCH 025/213] Makefile.inc1: show time for `make installworld' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For years we display the time in seconds how long it takes to run `make buildworld' (see PR 224433). Now we will display the time for "installworld" and "installkernel" as well. e.g.: -------------------------------------------------------------- >>> Installing everything completed on Sun Jul  7 16:11:37 UTC 2024 >>> Install world completed in 110 seconds, ncpu: 2, make -j2 -------------------------------------------------------------- This is an improved version of commit e5a0202f96948a95bf1b879727e155a4f1d1da93 PR: 280187 Differential Revision: https://reviews.freebsd.org/D45912 --- Makefile.inc1 | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/Makefile.inc1 b/Makefile.inc1 index 5400cb5e734a..a4e2889004b7 100644 --- a/Makefile.inc1 +++ b/Makefile.inc1 @@ -1241,11 +1241,19 @@ WMAKE_TGTS+= build${libcompat} .endif WMAKE_TGTS+= everything -# record buildworld time in seconds +# record buildworld / install time in seconds .if make(buildworld) _BUILDWORLD_START!= date '+%s' .export _BUILDWORLD_START .endif +.if make(reinstall) || make(restage) +_INSTALLWORLD_START!= date '+%s' +.export _INSTALLWORLD_START +.endif +.if make(*installkernel*) +_INSTALLKERNEL_START!= date '+%s' +.export _INSTALLKERNEL_START +.endif buildworld: buildworld_prologue ${WMAKE_TGTS} buildworld_epilogue .PHONY .ORDER: buildworld_prologue ${WMAKE_TGTS} buildworld_epilogue @@ -1313,11 +1321,11 @@ kernel-toolchain: ${KERNEL_TOOLCHAIN_TGTS} .PHONY installcheck: _installcheck_world _installcheck_kernel .PHONY _installcheck_world: .PHONY @echo "--------------------------------------------------------------" - @echo ">>> Install check world" + @echo ">>> Install check world started on `LC_ALL=C date`" @echo "--------------------------------------------------------------" _installcheck_kernel: .PHONY @echo "--------------------------------------------------------------" - @echo ">>> Install check kernel" + @echo ">>> Install check kernel started on `LC_ALL=C date`" @echo "--------------------------------------------------------------" # @@ -1641,6 +1649,8 @@ restage reinstall: .MAKE .PHONY .endfor @echo "--------------------------------------------------------------" @echo ">>> Installing everything completed on `LC_ALL=C date`" + @seconds=$$(($$(date '+%s') - ${_INSTALLWORLD_START})); \ + echo ">>> Install world completed in $$seconds seconds, ncpu: $$(${_ncpu_cmd})${.MAKE.JOBS:S/^/, make -j/}" @echo "--------------------------------------------------------------" redistribute: .MAKE .PHONY @@ -1873,6 +1883,9 @@ reinstallkernel reinstallkernel.debug: _installcheck_kernel .PHONY @echo "--------------------------------------------------------------" @echo ">>> Installing kernel ${INSTALLKERNEL} completed on $$(LC_ALL=C date)" @echo "--------------------------------------------------------------" + @seconds=$$(($$(date '+%s') - ${_INSTALLKERNEL_START})); \ + echo ">>> Install kernel(s) ${INSTALLKERNEL} completed in $$seconds seconds, ncpu: $$(${_ncpu_cmd})${.MAKE.JOBS:S/^/, make -j/}" + @echo "--------------------------------------------------------------" .endif .if ${BUILDKERNELS:[#]} > 1 && ${NO_INSTALLEXTRAKERNELS} != "yes" .for _kernel in ${BUILDKERNELS:[2..-1]} @@ -1887,6 +1900,9 @@ reinstallkernel reinstallkernel.debug: _installcheck_kernel .PHONY @echo ">>> Installing kernel ${_kernel} completed on $$(LC_ALL=C date)" @echo "--------------------------------------------------------------" .endfor + @seconds=$$(($$(date '+%s') - ${_INSTALLKERNEL_START})); \ + echo ">>> Install kernel(s) ${BUILDKERNELS} completed in $$seconds seconds, ncpu: $$(${_ncpu_cmd})${.MAKE.JOBS:S/^/, make -j/}" + @echo "--------------------------------------------------------------" .endif distributekernel distributekernel.debug: .PHONY From 209905ec384eedd58f1b9b7ab774029d22787dfb Mon Sep 17 00:00:00 2001 From: Helge Oldach Date: Mon, 2 Sep 2024 18:12:43 +0800 Subject: [PATCH 026/213] ndp: Fix libxo formatting for the header of neighbor cache PR: 272749 Reviewed by: zlei Fixes: e1c7783e220b ndp(8): add structured output formatting via libxo Fixes: 91fbe0819bb9 ndp: convert ndp(8) to netlink MFC after: 3 days --- usr.sbin/ndp/ndp.c | 2 +- usr.sbin/ndp/ndp_netlink.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/usr.sbin/ndp/ndp.c b/usr.sbin/ndp/ndp.c index 637aac2823ed..7c7bc60451c8 100644 --- a/usr.sbin/ndp/ndp.c +++ b/usr.sbin/ndp/ndp.c @@ -633,7 +633,7 @@ dump_rtsock(struct sockaddr_in6 *addr, int cflag) if (!opts.tflag && !cflag) { char xobuf[200]; snprintf(xobuf, sizeof(xobuf), - "{T:/%%-%d.%ds} {T:/%%-%d.%ds} {T:/%%%d.%ds} {T:/%%-9.9s} {T:%%1s} {T:%%5s}\n", + "{T:/%%-%d.%ds} {T:/%%-%d.%ds} {T:/%%%d.%ds} {T:/%%-9.9s} {T:/%%1s} {T:/%%5s}\n", W_ADDR, W_ADDR, W_LL, W_LL, W_IF, W_IF); xo_emit(xobuf, "Neighbor", "Linklayer Address", "Netif", "Expire", "S", "Flags"); } diff --git a/usr.sbin/ndp/ndp_netlink.c b/usr.sbin/ndp/ndp_netlink.c index e18d64175619..bafa9f2a143d 100644 --- a/usr.sbin/ndp/ndp_netlink.c +++ b/usr.sbin/ndp/ndp_netlink.c @@ -341,7 +341,7 @@ print_entries_nl(uint32_t ifindex, struct sockaddr_in6 *addr, bool cflag) if (!opts.tflag && !cflag) { char xobuf[200]; snprintf(xobuf, sizeof(xobuf), - "{T:/%%-%d.%ds} {T:/%%-%d.%ds} {T:/%%%d.%ds} {T:/%%-9.9s} {T:%%1s} {T:%%5s}\n", + "{T:/%%-%d.%ds} {T:/%%-%d.%ds} {T:/%%%d.%ds} {T:/%%-9.9s} {T:/%%1s} {T:/%%5s}\n", W_ADDR, W_ADDR, W_LL, W_LL, W_IF, W_IF); xo_emit(xobuf, "Neighbor", "Linklayer Address", "Netif", "Expire", "S", "Flags"); } From 1a19741860d777bea1b7fe000f87136538020c3b Mon Sep 17 00:00:00 2001 From: Ed Maste Date: Thu, 29 Aug 2024 08:43:16 -0400 Subject: [PATCH 027/213] UPDATING: remove 20240813 DMAR entry The associated commit has been reverted and DMAR is not enabled by default any longer. Reviewed by: imp Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D46474 --- UPDATING | 5 ----- 1 file changed, 5 deletions(-) diff --git a/UPDATING b/UPDATING index bbcbdad9bfd7..cffafdb5d247 100644 --- a/UPDATING +++ b/UPDATING @@ -27,11 +27,6 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 15.x IS SLOW: world, or to merely disable the most expensive debugging functionality at runtime, run "ln -s 'abort:false,junk:false' /etc/malloc.conf".) -20240813: - DMAR is now enabled by default on Intel. If your system crashes in the - dmar code on boot, please set 'hw.dmar.enable=0' in /boot/loader.conf - and file a bug. - 20240729: The build now defaults to WITHOUT_CLEAN - i.e., no automatic clean is performed at the beginning of buildworld or buildkernel. The From b162fc3f3094c50c8ed47ab50981c5448cf0052c Mon Sep 17 00:00:00 2001 From: Jessica Clarke Date: Mon, 2 Sep 2024 23:21:18 +0100 Subject: [PATCH 028/213] gpart: Add u-boot-env alias for U-Boot's environment GPT partition UUID This is a platform-independent UUID, and this is the name U-Boot uses. MFC after: 1 week --- lib/geom/part/gpart.8 | 7 ++++++- sys/geom/part/g_part.c | 1 + sys/geom/part/g_part.h | 1 + sys/geom/part/g_part_gpt.c | 2 ++ sys/sys/disk/gpt.h | 3 +++ 5 files changed, 13 insertions(+), 1 deletion(-) diff --git a/lib/geom/part/gpart.8 b/lib/geom/part/gpart.8 index fa0b247c6174..121e6d6a5119 100644 --- a/lib/geom/part/gpart.8 +++ b/lib/geom/part/gpart.8 @@ -22,7 +22,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd July 26, 2023 +.Dd September 2, 2024 .Dt GPART 8 .Os .Sh NAME @@ -1008,6 +1008,11 @@ A illumos/Solaris partition dedicated to reserved space. The scheme-specific type is .Qq Li "!6a945a3b-1dd2-11b2-99a6-080020736631" for GPT. +.It Cm u-boot-env +A raw partition dedicated to U-Boot for storing its environment. +The scheme-specific type is +.Qq Li "!3de21764-95bd-54bd-a5c3-4abe786f38a8" +for GPT. .It Cm vmware-vmfs A partition that contains a VMware File System (VMFS). The scheme-specific types are diff --git a/sys/geom/part/g_part.c b/sys/geom/part/g_part.c index f0807c83dacf..d72efa09c46d 100644 --- a/sys/geom/part/g_part.c +++ b/sys/geom/part/g_part.c @@ -130,6 +130,7 @@ struct g_part_alias_list { { "solaris-home", G_PART_ALIAS_SOLARIS_HOME }, { "solaris-altsec", G_PART_ALIAS_SOLARIS_ALTSEC }, { "solaris-reserved", G_PART_ALIAS_SOLARIS_RESERVED }, + { "u-boot-env", G_PART_ALIAS_U_BOOT_ENV }, { "vmware-reserved", G_PART_ALIAS_VMRESERVED }, { "vmware-vmfs", G_PART_ALIAS_VMFS }, { "vmware-vmkdiag", G_PART_ALIAS_VMKDIAG }, diff --git a/sys/geom/part/g_part.h b/sys/geom/part/g_part.h index ffeeca9022fe..13bbb1e4126a 100644 --- a/sys/geom/part/g_part.h +++ b/sys/geom/part/g_part.h @@ -103,6 +103,7 @@ enum g_part_alias { G_PART_ALIAS_SOLARIS_HOME, /* A Solaris /home partition entry. */ G_PART_ALIAS_SOLARIS_ALTSEC, /* A Solaris alternate sector partition entry. */ G_PART_ALIAS_SOLARIS_RESERVED, /* A Solaris reserved partition entry. */ + G_PART_ALIAS_U_BOOT_ENV, /* A U-Boot environment partition entry. */ G_PART_ALIAS_VMFS, /* A VMware VMFS partition entry */ G_PART_ALIAS_VMKDIAG, /* A VMware vmkDiagnostic partition entry */ G_PART_ALIAS_VMRESERVED, /* A VMware reserved partition entry */ diff --git a/sys/geom/part/g_part_gpt.c b/sys/geom/part/g_part_gpt.c index b269faee276c..a856a34f99d9 100644 --- a/sys/geom/part/g_part_gpt.c +++ b/sys/geom/part/g_part_gpt.c @@ -223,6 +223,7 @@ static struct uuid gpt_uuid_solaris_var = GPT_ENT_TYPE_SOLARIS_VAR; static struct uuid gpt_uuid_solaris_home = GPT_ENT_TYPE_SOLARIS_HOME; static struct uuid gpt_uuid_solaris_altsec = GPT_ENT_TYPE_SOLARIS_ALTSEC; static struct uuid gpt_uuid_solaris_reserved = GPT_ENT_TYPE_SOLARIS_RESERVED; +static struct uuid gpt_uuid_u_boot_env = GPT_ENT_TYPE_U_BOOT_ENV; static struct uuid gpt_uuid_unused = GPT_ENT_TYPE_UNUSED; static struct uuid gpt_uuid_vmfs = GPT_ENT_TYPE_VMFS; static struct uuid gpt_uuid_vmkdiag = GPT_ENT_TYPE_VMKDIAG; @@ -295,6 +296,7 @@ static struct g_part_uuid_alias { { &gpt_uuid_solaris_home, G_PART_ALIAS_SOLARIS_HOME, 0 }, { &gpt_uuid_solaris_altsec, G_PART_ALIAS_SOLARIS_ALTSEC, 0 }, { &gpt_uuid_solaris_reserved, G_PART_ALIAS_SOLARIS_RESERVED, 0 }, + { &gpt_uuid_u_boot_env, G_PART_ALIAS_U_BOOT_ENV, 0 }, { &gpt_uuid_vmfs, G_PART_ALIAS_VMFS, 0 }, { &gpt_uuid_vmkdiag, G_PART_ALIAS_VMKDIAG, 0 }, { &gpt_uuid_vmreserved, G_PART_ALIAS_VMRESERVED, 0 }, diff --git a/sys/sys/disk/gpt.h b/sys/sys/disk/gpt.h index 596a5cba1681..426ae835c0c1 100644 --- a/sys/sys/disk/gpt.h +++ b/sys/sys/disk/gpt.h @@ -259,6 +259,9 @@ CTASSERT(sizeof(struct gpt_ent) == 128); #define GPT_ENT_TYPE_HIFIVE_BBL \ {0x2e54b353,0x1271,0x4842,0x80,0x6f,{0xe4,0x36,0xd6,0xaf,0x69,0x85}} +#define GPT_ENT_TYPE_U_BOOT_ENV \ + {0x3de21764,0x95bd,0x54bd,0xa5,0xc3,{0x4a,0xbe,0x78,0x6f,0x38,0xa8}} + /* * Boot partition used by GRUB 2. */ From c7dd97ec99687996de49ec0b1a23bf007e5199b9 Mon Sep 17 00:00:00 2001 From: Bram Ton Date: Wed, 17 Jul 2024 09:23:30 +0200 Subject: [PATCH 029/213] vmstat: Add root element to libxo output Current libxo output does not have a root element. Valid XML requires a single root element. This commit adds this root element. The libxo output version bumped accordingly. PR: 254635 MFC after: 1 week Pull Request: https://github.com/freebsd/freebsd-src/pull/1330 --- usr.bin/vmstat/vmstat.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/usr.bin/vmstat/vmstat.c b/usr.bin/vmstat/vmstat.c index 21068d632a8c..e7790ad6e2f6 100644 --- a/usr.bin/vmstat/vmstat.c +++ b/usr.bin/vmstat/vmstat.c @@ -66,7 +66,7 @@ #include #include -#define VMSTAT_XO_VERSION "1" +#define VMSTAT_XO_VERSION "2" static char da[] = "da"; @@ -282,6 +282,7 @@ main(int argc, char *argv[]) argv += optind; xo_set_version(VMSTAT_XO_VERSION); + xo_open_container("vmstat"); if (!hflag) xo_set_options(NULL, "no-humanize"); if (todo == 0) @@ -383,6 +384,7 @@ main(int argc, char *argv[]) dointr(interval, reps); if (todo & VMSTAT) dovmstat(interval, reps); + xo_close_container("vmstat"); xo_finish(); exit(0); } From bac98f86c98421f6153c749b6c77995ef778e2fb Mon Sep 17 00:00:00 2001 From: WHR Date: Tue, 3 Sep 2024 13:12:20 +0800 Subject: [PATCH 030/213] mfiutil: Handle potential ioctl(2) failures in mfi_flash.c The return value of function 'mfi_dcmd_command' should always be checked for the potential ioctl(2) failure. PR: 281158 MFC after: 1 week Pull Request: https://github.com/freebsd/freebsd-src/pull/1403 --- usr.sbin/mfiutil/mfi_flash.c | 39 ++++++++++++++++++++++++++---------- 1 file changed, 28 insertions(+), 11 deletions(-) diff --git a/usr.sbin/mfiutil/mfi_flash.c b/usr.sbin/mfiutil/mfi_flash.c index 2fbfc978edac..4d1930af4941 100644 --- a/usr.sbin/mfiutil/mfi_flash.c +++ b/usr.sbin/mfiutil/mfi_flash.c @@ -129,9 +129,15 @@ flash_adapter(int ac, char **av) /* First, ask the firmware to allocate space for the flash file. */ mbox_store_word(mbox, sb.st_size); - mfi_dcmd_command(fd, MFI_DCMD_FLASH_FW_OPEN, NULL, 0, mbox, 4, &status); + if (mfi_dcmd_command(fd, MFI_DCMD_FLASH_FW_OPEN, NULL, 0, mbox, 4, + &status) < 0) { + error = errno; + warn("Failed to allocate flash memory"); + goto error; + } if (status != MFI_STAT_OK) { - warnx("Failed to alloc flash memory: %s", mfi_status(status)); + warnx("Failed to allocate flash memory: %s", + mfi_status(status)); error = EIO; goto error; } @@ -148,19 +154,26 @@ flash_adapter(int ac, char **av) nread = read(flash, buf, FLASH_BUF_SIZE); if (nread <= 0 || nread % 1024 != 0) { warnx("Bad read from flash file"); - mfi_dcmd_command(fd, MFI_DCMD_FLASH_FW_CLOSE, NULL, 0, - NULL, 0, NULL); + if (mfi_dcmd_command(fd, MFI_DCMD_FLASH_FW_CLOSE, + NULL, 0, NULL, 0, NULL) < 0) { + warn("Failed to discard flash memory"); + } error = ENXIO; goto error; } mbox_store_word(mbox, offset); - mfi_dcmd_command(fd, MFI_DCMD_FLASH_FW_DOWNLOAD, buf, nread, - mbox, 4, &status); + if (mfi_dcmd_command(fd, MFI_DCMD_FLASH_FW_DOWNLOAD, buf, nread, + mbox, 4, &status) < 0) { + error = errno; + warn("Failed to download firmware"); + goto error; + } if (status != MFI_STAT_OK) { - warnx("Flash download failed: %s", mfi_status(status)); - mfi_dcmd_command(fd, MFI_DCMD_FLASH_FW_CLOSE, NULL, 0, - NULL, 0, NULL); + warnx("Failed to download firmware: %s", + mfi_status(status)); + mfi_dcmd_command(fd, MFI_DCMD_FLASH_FW_CLOSE, NULL, + 0, NULL, 0, NULL); error = ENXIO; goto error; } @@ -171,8 +184,12 @@ flash_adapter(int ac, char **av) /* Kick off the flash. */ printf("WARNING: Firmware flash in progress, do not reboot machine... "); fflush(stdout); - mfi_dcmd_command(fd, MFI_DCMD_FLASH_FW_FLASH, &dummy, sizeof(dummy), - NULL, 0, &status); + if (mfi_dcmd_command(fd, MFI_DCMD_FLASH_FW_FLASH, &dummy, sizeof(dummy), + NULL, 0, &status) < 0) { + error = errno; + printf("failed:\n\t%s\n", strerror(error)); + goto error; + } if (status != MFI_STAT_OK) { printf("failed:\n\t%s\n", mfi_status(status)); error = ENXIO; From 6a2a385507c79abaa9db9eabfdd827362f3dc7ed Mon Sep 17 00:00:00 2001 From: Zhenlei Huang Date: Tue, 3 Sep 2024 18:25:16 +0800 Subject: [PATCH 031/213] kern_fail: Stop checking for failures from fp_malloc(M_WAITOK) `fp_malloc` is defined as a macro that redirects to `malloc`. MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D45852 --- sys/kern/kern_fail.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/sys/kern/kern_fail.c b/sys/kern/kern_fail.c index 883b664aef0d..258268bb874f 100644 --- a/sys/kern/kern_fail.c +++ b/sys/kern/kern_fail.c @@ -479,11 +479,10 @@ fail_point_init(struct fail_point *fp, const char *fmt, ...) /* Allocate the name and fill it in. */ name = fp_malloc(n + 1, M_WAITOK); - if (name != NULL) { - va_start(ap, fmt); - vsnprintf(name, n + 1, fmt, ap); - va_end(ap); - } + va_start(ap, fmt); + vsnprintf(name, n + 1, fmt, ap); + va_end(ap); + fp->fp_name = name; fp->fp_location = ""; fp->fp_flags |= FAIL_POINT_DYNAMIC_NAME; From f444db950e877596805aed897c3fbb975be28711 Mon Sep 17 00:00:00 2001 From: Zhenlei Huang Date: Tue, 3 Sep 2024 18:25:17 +0800 Subject: [PATCH 032/213] boottrace: Stop checking for failures from realloc(M_WAITOK) MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D45852 --- sys/kern/kern_boottrace.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/sys/kern/kern_boottrace.c b/sys/kern/kern_boottrace.c index 1b097e7378ad..5516f3160587 100644 --- a/sys/kern/kern_boottrace.c +++ b/sys/kern/kern_boottrace.c @@ -561,9 +561,6 @@ boottrace_resize(u_int newsize) } rt.table = realloc(rt.table, newsize * sizeof(struct bt_event), M_BOOTTRACE, M_WAITOK | M_ZERO); - if (rt.table == NULL) - return (ENOMEM); - rt.size = newsize; boottrace_reset("boottrace_resize"); return (0); From 99e3bb555cb1ef5572de54be0ffed2aa6fc080cd Mon Sep 17 00:00:00 2001 From: Zhenlei Huang Date: Tue, 3 Sep 2024 18:25:17 +0800 Subject: [PATCH 033/213] subr_bus: Stop checking for failures from malloc(M_WAITOK) MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D45852 --- sys/kern/subr_bus.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/sys/kern/subr_bus.c b/sys/kern/subr_bus.c index 71d04e483d4d..7fe46995ee54 100644 --- a/sys/kern/subr_bus.c +++ b/sys/kern/subr_bus.c @@ -5422,8 +5422,6 @@ sysctl_devices(SYSCTL_HANDLER_ARGS) * Populate the return item, careful not to overflow the buffer. */ udev = malloc(sizeof(*udev), M_BUS, M_WAITOK | M_ZERO); - if (udev == NULL) - return (ENOMEM); udev->dv_handle = (uintptr_t)dev; udev->dv_parent = (uintptr_t)dev->parent; udev->dv_devflags = dev->devflags; From 8e6dd4185871cd9b785869178ab2191a0d6c0b53 Mon Sep 17 00:00:00 2001 From: Zhenlei Huang Date: Tue, 3 Sep 2024 18:25:18 +0800 Subject: [PATCH 034/213] ctl: Stop checking for failures from malloc(M_WAITOK) MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D45852 --- sys/cam/ctl/ctl.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/sys/cam/ctl/ctl.c b/sys/cam/ctl/ctl.c index 845cffe77a5d..82420396aca1 100644 --- a/sys/cam/ctl/ctl.c +++ b/sys/cam/ctl/ctl.c @@ -2687,12 +2687,6 @@ ctl_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, } entries = malloc(ooa_hdr->alloc_len, M_CTL, M_WAITOK | M_ZERO); - if (entries == NULL) { - printf("%s: could not allocate %d bytes for OOA " - "dump\n", __func__, ooa_hdr->alloc_len); - retval = ENOMEM; - break; - } mtx_lock(&softc->ctl_lock); if ((ooa_hdr->flags & CTL_OOA_FLAG_ALL_LUNS) == 0 && From 3feb35dc465a8247d70e50792680c230954ef1c1 Mon Sep 17 00:00:00 2001 From: Zhenlei Huang Date: Tue, 3 Sep 2024 18:25:18 +0800 Subject: [PATCH 035/213] udf: Stop checking for failures from malloc(M_WAITOK) MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D45852 --- sys/fs/udf/udf_vnops.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/sys/fs/udf/udf_vnops.c b/sys/fs/udf/udf_vnops.c index f230ca0c72fa..98a779280690 100644 --- a/sys/fs/udf/udf_vnops.c +++ b/sys/fs/udf/udf_vnops.c @@ -800,8 +800,6 @@ udf_readdir(struct vop_readdir_args *a) */ ncookies = uio->uio_resid / 8; cookies = malloc(sizeof(*cookies) * ncookies, M_TEMP, M_WAITOK); - if (cookies == NULL) - return (ENOMEM); uiodir.ncookies = ncookies; uiodir.cookies = cookies; uiodir.acookies = 0; From 2a119886630bb5fe8283e20db5acb7c0cdba31c3 Mon Sep 17 00:00:00 2001 From: Zhenlei Huang Date: Tue, 3 Sep 2024 18:25:19 +0800 Subject: [PATCH 036/213] altq: Stop checking for failures from malloc(M_WAITOK) While here, prefer malloc(M_ZERO) over bzero(). MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D45852 --- sys/net/altq/altq_subr.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/sys/net/altq/altq_subr.c b/sys/net/altq/altq_subr.c index 3ade724818dd..534841289611 100644 --- a/sys/net/altq/altq_subr.c +++ b/sys/net/altq/altq_subr.c @@ -1327,12 +1327,7 @@ acc_add_filter(classifier, filter, class, phandle) return (EINVAL); #endif - afp = malloc(sizeof(struct acc_filter), - M_DEVBUF, M_WAITOK); - if (afp == NULL) - return (ENOMEM); - bzero(afp, sizeof(struct acc_filter)); - + afp = malloc(sizeof(*afp), M_DEVBUF, M_WAITOK | M_ZERO); afp->f_filter = *filter; afp->f_class = class; From 07b16b1e2aeab0b30f68a013de31a4c322a61246 Mon Sep 17 00:00:00 2001 From: Zhenlei Huang Date: Tue, 3 Sep 2024 18:25:19 +0800 Subject: [PATCH 037/213] if_vlan: Stop checking for failures from malloc(M_WAITOK) Fixes: b08d611de835 fix vlan locking to permit sx acquisition in ioctl calls MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D45852 --- sys/net/if_vlan.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/sys/net/if_vlan.c b/sys/net/if_vlan.c index a30db9173383..774298d4a53a 100644 --- a/sys/net/if_vlan.c +++ b/sys/net/if_vlan.c @@ -509,11 +509,6 @@ vlan_growhash(struct ifvlantrunk *trunk, int howmuch) return; hash2 = malloc(sizeof(struct ifvlanhead) * n2, M_VLAN, M_WAITOK); - if (hash2 == NULL) { - printf("%s: out of memory -- hash size not changed\n", - __func__); - return; /* We can live with the old hash table */ - } for (j = 0; j < n2; j++) CK_SLIST_INIT(&hash2[j]); for (i = 0; i < n; i++) From 5b00557330b3b69db84969e33f2e201288208dd9 Mon Sep 17 00:00:00 2001 From: Zhenlei Huang Date: Tue, 3 Sep 2024 18:25:20 +0800 Subject: [PATCH 038/213] pf: Stop checking for failures from malloc(M_WAITOK) MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D45852 --- sys/netpfil/pf/pf_ioctl.c | 32 -------------------------------- sys/netpfil/pf/pf_syncookies.c | 3 --- 2 files changed, 35 deletions(-) diff --git a/sys/netpfil/pf/pf_ioctl.c b/sys/netpfil/pf/pf_ioctl.c index d22ffc2245cb..64086bf08871 100644 --- a/sys/netpfil/pf/pf_ioctl.c +++ b/sys/netpfil/pf/pf_ioctl.c @@ -2823,9 +2823,6 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct thread *td /* Copy the request in */ packed = malloc(nv->len, M_NVLIST, M_WAITOK); - if (packed == NULL) - ERROUT(ENOMEM); - error = copyin(nv->data, packed, nv->len); if (error) ERROUT(error); @@ -2903,9 +2900,6 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct thread *td ERROUT(ENOMEM); nvlpacked = malloc(nv->len, M_NVLIST, M_WAITOK); - if (nvlpacked == NULL) - ERROUT(ENOMEM); - error = copyin(nv->data, nvlpacked, nv->len); if (error) ERROUT(error); @@ -3003,9 +2997,6 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct thread *td ERROUT(ENOMEM); nvlpacked = malloc(nv->len, M_NVLIST, M_WAITOK); - if (nvlpacked == NULL) - ERROUT(ENOMEM); - error = copyin(nv->data, nvlpacked, nv->len); if (error) ERROUT(error); @@ -3036,8 +3027,6 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct thread *td } rule = malloc(sizeof(*rule), M_PFRULE, M_WAITOK); - if (rule == NULL) - ERROUT(ENOMEM); rule->timestamp = NULL; error = pf_nveth_rule_to_keth_rule(nvl, rule); @@ -3136,9 +3125,6 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct thread *td ERROUT(ENOMEM); nvlpacked = malloc(nv->len, M_NVLIST, M_WAITOK); - if (nvlpacked == NULL) - ERROUT(ENOMEM); - error = copyin(nv->data, nvlpacked, nv->len); if (error) ERROUT(error); @@ -3214,9 +3200,6 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct thread *td ERROUT(ENOMEM); nvlpacked = malloc(nv->len, M_NVLIST, M_WAITOK); - if (nvlpacked == NULL) - ERROUT(ENOMEM); - error = copyin(nv->data, nvlpacked, nv->len); if (error) ERROUT(error); @@ -3409,9 +3392,6 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct thread *td /* Copy the request in */ nvlpacked = malloc(nv->len, M_NVLIST, M_WAITOK); - if (nvlpacked == NULL) - ERROUT(ENOMEM); - error = copyin(nv->data, nvlpacked, nv->len); if (error) ERROUT(error); @@ -6003,9 +5983,6 @@ pf_keepcounters(struct pfioc_nv *nv) ERROUT(ENOMEM); nvlpacked = malloc(nv->len, M_NVLIST, M_WAITOK); - if (nvlpacked == NULL) - ERROUT(ENOMEM); - error = copyin(nv->data, nvlpacked, nv->len); if (error) ERROUT(error); @@ -6131,9 +6108,6 @@ pf_killstates_nv(struct pfioc_nv *nv) ERROUT(ENOMEM); nvlpacked = malloc(nv->len, M_NVLIST, M_WAITOK); - if (nvlpacked == NULL) - ERROUT(ENOMEM); - error = copyin(nv->data, nvlpacked, nv->len); if (error) ERROUT(error); @@ -6192,9 +6166,6 @@ pf_clearstates_nv(struct pfioc_nv *nv) ERROUT(ENOMEM); nvlpacked = malloc(nv->len, M_NVLIST, M_WAITOK); - if (nvlpacked == NULL) - ERROUT(ENOMEM); - error = copyin(nv->data, nvlpacked, nv->len); if (error) ERROUT(error); @@ -6253,9 +6224,6 @@ pf_getstate(struct pfioc_nv *nv) ERROUT(ENOMEM); nvlpacked = malloc(nv->len, M_NVLIST, M_WAITOK); - if (nvlpacked == NULL) - ERROUT(ENOMEM); - error = copyin(nv->data, nvlpacked, nv->len); if (error) ERROUT(error); diff --git a/sys/netpfil/pf/pf_syncookies.c b/sys/netpfil/pf/pf_syncookies.c index c5ee64c6aed0..538ab1dfd94c 100644 --- a/sys/netpfil/pf/pf_syncookies.c +++ b/sys/netpfil/pf/pf_syncookies.c @@ -201,9 +201,6 @@ pf_set_syncookies(struct pfioc_nv *nv) return (ENOMEM); nvlpacked = malloc(nv->len, M_NVLIST, M_WAITOK); - if (nvlpacked == NULL) - return (ENOMEM); - error = copyin(nv->data, nvlpacked, nv->len); if (error) ERROUT(error); From 6e50988cf822f87a524b8da2fdc35b234078cc2f Mon Sep 17 00:00:00 2001 From: Zhenlei Huang Date: Tue, 3 Sep 2024 18:25:20 +0800 Subject: [PATCH 039/213] netsmb: Stop checking for failures from malloc(M_WAITOK) MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D45852 --- sys/netsmb/smb_rq.c | 4 ---- sys/netsmb/smb_subr.c | 2 -- 2 files changed, 6 deletions(-) diff --git a/sys/netsmb/smb_rq.c b/sys/netsmb/smb_rq.c index a33598489aa1..b2642f1aaa6d 100644 --- a/sys/netsmb/smb_rq.c +++ b/sys/netsmb/smb_rq.c @@ -64,8 +64,6 @@ smb_rq_alloc(struct smb_connobj *layer, u_char cmd, struct smb_cred *scred, int error; rqp = malloc(sizeof(*rqp), M_SMBRQ, M_WAITOK); - if (rqp == NULL) - return ENOMEM; error = smb_rq_init(rqp, layer, cmd, scred); rqp->sr_flags |= SMBR_ALLOCED; if (error) { @@ -376,8 +374,6 @@ smb_t2_alloc(struct smb_connobj *layer, u_short setup, struct smb_cred *scred, int error; t2p = malloc(sizeof(*t2p), M_SMBRQ, M_WAITOK); - if (t2p == NULL) - return ENOMEM; error = smb_t2_init(t2p, layer, setup, scred); t2p->t2_flags |= SMBT2_ALLOCED; if (error) { diff --git a/sys/netsmb/smb_subr.c b/sys/netsmb/smb_subr.c index fbb951a37cef..68469cf5cc35 100644 --- a/sys/netsmb/smb_subr.c +++ b/sys/netsmb/smb_subr.c @@ -149,8 +149,6 @@ smb_memdup(const void *umem, int len) if (len > 8 * 1024) return NULL; p = malloc(len, M_SMBSTR, M_WAITOK); - if (p == NULL) - return NULL; bcopy(umem, p, len); return p; } From 7a720bf67d73ba565a0a1130065f798870eb5faa Mon Sep 17 00:00:00 2001 From: Zhenlei Huang Date: Tue, 3 Sep 2024 18:25:20 +0800 Subject: [PATCH 040/213] xdr: Stop checking for failures from malloc(M_WAITOK) MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D45852 --- sys/xdr/xdr_sizeof.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/sys/xdr/xdr_sizeof.c b/sys/xdr/xdr_sizeof.c index 6b4ee0352c9e..bcacf918f4fd 100644 --- a/sys/xdr/xdr_sizeof.c +++ b/sys/xdr/xdr_sizeof.c @@ -94,10 +94,7 @@ x_inline(XDR *xdrs, u_int len) /* Free the earlier space and allocate new area */ if (xdrs->x_private) free(xdrs->x_private, M_RPC); - if ((xdrs->x_private = (caddr_t) malloc(len, M_RPC, M_WAITOK)) == NULL) { - xdrs->x_base = 0; - return (NULL); - } + xdrs->x_private = malloc(len, M_RPC, M_WAITOK); xdrs->x_base = (caddr_t)(uintptr_t) len; xdrs->x_handy += len; return ((int32_t *) xdrs->x_private); From 7bcb1228558b4325fab39616e2e3b2573a9e7da6 Mon Sep 17 00:00:00 2001 From: Zhenlei Huang Date: Tue, 3 Sep 2024 18:25:21 +0800 Subject: [PATCH 041/213] LinuxKPI: 802.11: Stop checking for failures from malloc(M_WAITOK) As a consequence lkpi_ieee80211_ifalloc() now does not fail. Remove unneeded NULL check. MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D45852 --- sys/compat/linuxkpi/common/src/linux_80211.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/sys/compat/linuxkpi/common/src/linux_80211.c b/sys/compat/linuxkpi/common/src/linux_80211.c index b46e56133725..a2791d20a727 100644 --- a/sys/compat/linuxkpi/common/src/linux_80211.c +++ b/sys/compat/linuxkpi/common/src/linux_80211.c @@ -4401,8 +4401,6 @@ lkpi_ieee80211_ifalloc(void) struct ieee80211com *ic; ic = malloc(sizeof(*ic), M_LKPI80211, M_WAITOK | M_ZERO); - if (ic == NULL) - return (NULL); /* Setting these happens later when we have device information. */ ic->ic_softc = NULL; @@ -4454,10 +4452,6 @@ linuxkpi_ieee80211_alloc_hw(size_t priv_len, const struct ieee80211_ops *ops) /* BSD Specific. */ lhw->ic = lkpi_ieee80211_ifalloc(); - if (lhw->ic == NULL) { - ieee80211_free_hw(hw); - return (NULL); - } IMPROVE(); From 66c35a6675ff987b52a2018871231658b1980a6c Mon Sep 17 00:00:00 2001 From: Zhenlei Huang Date: Tue, 3 Sep 2024 18:25:21 +0800 Subject: [PATCH 042/213] krping: Stop checking for failures from malloc(M_WAITOK) MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D45852 --- sys/contrib/rdma/krping/krping_dev.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/sys/contrib/rdma/krping/krping_dev.c b/sys/contrib/rdma/krping/krping_dev.c index eea3c772ea4f..59aa19672443 100644 --- a/sys/contrib/rdma/krping/krping_dev.c +++ b/sys/contrib/rdma/krping/krping_dev.c @@ -174,12 +174,7 @@ krping_write(struct cdev *dev, struct uio *uio, int ioflag) char *cp; krping_t *krpingmsg; - krpingmsg = malloc(sizeof *krpingmsg, M_DEVBUF, M_WAITOK|M_ZERO); - if (!krpingmsg) { - uprintf("Could not malloc mem!\n"); - return ENOMEM; - } - + krpingmsg = malloc(sizeof *krpingmsg, M_DEVBUF, M_WAITOK | M_ZERO); cp = krpingmsg->msg; while (uio->uio_resid) { amt = MIN(uio->uio_resid, remain); From aac6c41d4ba9b0a1aef561f6c4bfd284ab369ebf Mon Sep 17 00:00:00 2001 From: Zhenlei Huang Date: Tue, 3 Sep 2024 18:25:21 +0800 Subject: [PATCH 043/213] tests: Stop checking for failures from malloc(M_WAITOK) MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D45852 --- sys/tests/framework/kern_testfrwk.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/sys/tests/framework/kern_testfrwk.c b/sys/tests/framework/kern_testfrwk.c index 19691f1febfc..949300290b9d 100644 --- a/sys/tests/framework/kern_testfrwk.c +++ b/sys/tests/framework/kern_testfrwk.c @@ -192,10 +192,6 @@ kerntest_execute(SYSCTL_HANDLER_ARGS) } /* Grab some memory */ kte = malloc(sizeof(struct kern_test_entry), M_KTFRWK, M_WAITOK); - if (kte == NULL) { - error = ENOMEM; - goto out; - } KTFRWK_LOCK(); TAILQ_FOREACH(li, &kfrwk.kfrwk_testlist, next) { if (strcmp(li->name, kt.name) == 0) { @@ -244,10 +240,6 @@ kern_testframework_register(const char *name, kerntfunc func) return (E2BIG); } te = malloc(sizeof(struct kern_test_list), M_KTFRWK, M_WAITOK); - if (te == NULL) { - error = ENOMEM; - goto out; - } KTFRWK_LOCK(); /* First does it already exist? */ TAILQ_FOREACH(li, &kfrwk.kfrwk_testlist, next) { From fe6985ef87e1aedf8e5c9b3b959c7dd54a03e2fe Mon Sep 17 00:00:00 2001 From: Zhenlei Huang Date: Tue, 3 Sep 2024 18:25:22 +0800 Subject: [PATCH 044/213] arm ti: Stop checking for failures from malloc(M_WAITOK) MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D45852 --- sys/arm/ti/ti_pruss.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/sys/arm/ti/ti_pruss.c b/sys/arm/ti/ti_pruss.c index 85d075419fe8..b7a04f2cfb42 100644 --- a/sys/arm/ti/ti_pruss.c +++ b/sys/arm/ti/ti_pruss.c @@ -184,9 +184,6 @@ ti_pruss_irq_open(struct cdev *dev, int oflags, int devtype, struct thread *td) sc = dev->si_drv1; irqs = malloc(sizeof(struct ctl), M_DEVBUF, M_WAITOK); - if (!irqs) - return (ENOMEM); - irqs->cnt = sc->tstamps.ctl.cnt; irqs->idx = sc->tstamps.ctl.idx; From 1d321c1907c210a33192ff5293f5c23554c96867 Mon Sep 17 00:00:00 2001 From: Zhenlei Huang Date: Tue, 3 Sep 2024 18:25:22 +0800 Subject: [PATCH 045/213] cmn600: Stop checking for failures from malloc/mallocarray(M_WAITOK) MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D45852 --- sys/arm64/arm64/cmn600.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/sys/arm64/arm64/cmn600.c b/sys/arm64/arm64/cmn600.c index 4e3be8fee40e..530cdcdc3d06 100644 --- a/sys/arm64/arm64/cmn600.c +++ b/sys/arm64/arm64/cmn600.c @@ -332,9 +332,6 @@ cmn600_create_node(struct cmn600_softc *sc, off_t node_offset, int i; node = malloc(sizeof(struct cmn600_node), M_DEVBUF, M_WAITOK); - if (node == NULL) - return (NULL); - node->sc = sc; node->nd_offset = node_offset; node->nd_parent = parent; @@ -399,8 +396,6 @@ cmn600_create_node(struct cmn600_softc *sc, off_t node_offset, node->nd_children = (struct cmn600_node **)mallocarray( node->nd_child_count, sizeof(struct cmn600_node *), M_DEVBUF, M_WAITOK); - if (node->nd_children == NULL) - goto FAIL; for (i = 0; i < node->nd_child_count; i++) { val = node->nd_read8(node, child_offset + (i * 8)); node->nd_children[i] = cmn600_create_node(sc, val & @@ -420,9 +415,6 @@ cmn600_create_node(struct cmn600_softc *sc, off_t node_offset, break; } return (node); -FAIL: - free(node, M_DEVBUF); - return (NULL); } static void From f75ceecad2157a0d3aca61a4893ab78f2dec21ee Mon Sep 17 00:00:00 2001 From: Zhenlei Huang Date: Tue, 3 Sep 2024 18:25:23 +0800 Subject: [PATCH 046/213] smmu: Stop checking for failures from malloc(M_WAITOK) MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D45852 --- sys/arm64/iommu/smmu.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/sys/arm64/iommu/smmu.c b/sys/arm64/iommu/smmu.c index 93b0cbb7c8e4..a832f6a6ec70 100644 --- a/sys/arm64/iommu/smmu.c +++ b/sys/arm64/iommu/smmu.c @@ -960,10 +960,6 @@ smmu_init_strtab_2lvl(struct smmu_softc *sc) sz = strtab->num_l1_entries * sizeof(struct l1_desc); strtab->l1 = malloc(sz, M_SMMU, M_WAITOK | M_ZERO); - if (strtab->l1 == NULL) { - free(strtab->vaddr, M_SMMU); - return (ENOMEM); - } reg = STRTAB_BASE_CFG_FMT_2LVL; reg |= size << STRTAB_BASE_CFG_LOG2SIZE_S; From 00ae9c1be02e2db6ede1abd5b787bb9a3fbd76b0 Mon Sep 17 00:00:00 2001 From: Zhenlei Huang Date: Tue, 3 Sep 2024 18:25:23 +0800 Subject: [PATCH 047/213] al_eth: Stop checking for failures from malloc/buf_ring_alloc(M_WAITOK) MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D45852 --- sys/dev/al_eth/al_eth.c | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/sys/dev/al_eth/al_eth.c b/sys/dev/al_eth/al_eth.c index b8dd95e7ca58..e12c8dfcc281 100644 --- a/sys/dev/al_eth/al_eth.c +++ b/sys/dev/al_eth/al_eth.c @@ -2004,14 +2004,6 @@ al_eth_enable_msix(struct al_eth_adapter *adapter) adapter->msix_entries = malloc(msix_vecs*sizeof(*adapter->msix_entries), M_IFAL, M_ZERO | M_WAITOK); - - if (adapter->msix_entries == NULL) { - device_printf_dbg(adapter->dev, "failed to allocate" - " msix_entries %d\n", msix_vecs); - rc = ENOMEM; - goto exit; - } - /* management vector (GROUP_A) @2*/ adapter->msix_entries[AL_ETH_MGMT_IRQ_IDX].entry = 2; adapter->msix_entries[AL_ETH_MGMT_IRQ_IDX].vector = 0; @@ -2299,9 +2291,6 @@ al_eth_setup_tx_resources(struct al_eth_adapter *adapter, int qid) size = sizeof(struct al_eth_tx_buffer) * tx_ring->sw_count; tx_ring->tx_buffer_info = malloc(size, M_IFAL, M_ZERO | M_WAITOK); - if (tx_ring->tx_buffer_info == NULL) - return (ENOMEM); - tx_ring->descs_size = tx_ring->hw_count * sizeof(union al_udma_desc); q_params->size = tx_ring->hw_count; @@ -2324,10 +2313,6 @@ al_eth_setup_tx_resources(struct al_eth_adapter *adapter, int qid) mtx_init(&tx_ring->br_mtx, "AlRingMtx", NULL, MTX_DEF); tx_ring->br = buf_ring_alloc(AL_BR_SIZE, M_DEVBUF, M_WAITOK, &tx_ring->br_mtx); - if (tx_ring->br == NULL) { - device_printf(dev, "Critical Failure setting up buf ring\n"); - return (ENOMEM); - } /* Allocate taskqueues */ TASK_INIT(&tx_ring->enqueue_task, 0, al_eth_start_xmit, tx_ring); @@ -2476,9 +2461,6 @@ al_eth_setup_rx_resources(struct al_eth_adapter *adapter, unsigned int qid) size += 1; rx_ring->rx_buffer_info = malloc(size, M_IFAL, M_ZERO | M_WAITOK); - if (rx_ring->rx_buffer_info == NULL) - return (ENOMEM); - rx_ring->descs_size = rx_ring->hw_count * sizeof(union al_udma_desc); q_params->size = rx_ring->hw_count; From e06e2c84074740a0087193d5929d09f1bc7e1c4b Mon Sep 17 00:00:00 2001 From: Zhenlei Huang Date: Tue, 3 Sep 2024 18:25:24 +0800 Subject: [PATCH 048/213] altera: Stop checking for failures from malloc(M_WAITOK) MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D45852 --- sys/dev/altera/msgdma/msgdma.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/sys/dev/altera/msgdma/msgdma.c b/sys/dev/altera/msgdma/msgdma.c index bb35d7315b6c..c5c75a5fb5e1 100644 --- a/sys/dev/altera/msgdma/msgdma.c +++ b/sys/dev/altera/msgdma/msgdma.c @@ -356,11 +356,6 @@ msgdma_desc_alloc(struct msgdma_softc *sc, struct msgdma_channel *chan, /* Descriptors. */ chan->descs = malloc(nsegments * sizeof(struct msgdma_desc *), M_DEVBUF, (M_WAITOK | M_ZERO)); - if (chan->descs == NULL) { - device_printf(sc->dev, - "%s: Can't allocate memory.\n", __func__); - return (-1); - } chan->dma_map = malloc(nsegments * sizeof(bus_dmamap_t), M_DEVBUF, (M_WAITOK | M_ZERO)); chan->descs_phys = malloc(nsegments * sizeof(bus_dma_segment_t), From 3fdf587ab02f33018bd042094e3d0bd4169352ed Mon Sep 17 00:00:00 2001 From: Zhenlei Huang Date: Tue, 3 Sep 2024 18:25:24 +0800 Subject: [PATCH 049/213] ath(4): Stop checking for failures from malloc(M_WAITOK) MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D45852 --- sys/dev/ath/if_ath_lna_div.c | 6 ------ sys/dev/ath/if_ath_pci.c | 5 ----- sys/dev/ath/if_ath_spectral.c | 7 ------- 3 files changed, 18 deletions(-) diff --git a/sys/dev/ath/if_ath_lna_div.c b/sys/dev/ath/if_ath_lna_div.c index 1b20591fc64e..0755bb667716 100644 --- a/sys/dev/ath/if_ath_lna_div.c +++ b/sys/dev/ath/if_ath_lna_div.c @@ -96,12 +96,6 @@ ath_lna_div_attach(struct ath_softc *sc) ss = malloc(sizeof(struct if_ath_ant_comb_state), M_TEMP, M_WAITOK | M_ZERO); - if (ss == NULL) { - device_printf(sc->sc_dev, "%s: failed to allocate\n", - __func__); - /* Don't fail at this point */ - return (0); - } /* Fetch the hardware configuration */ OS_MEMZERO(&div_ant_conf, sizeof(div_ant_conf)); diff --git a/sys/dev/ath/if_ath_pci.c b/sys/dev/ath/if_ath_pci.c index 72f0a802aa5f..a242eab7a694 100644 --- a/sys/dev/ath/if_ath_pci.c +++ b/sys/dev/ath/if_ath_pci.c @@ -269,11 +269,6 @@ ath_pci_attach(device_t dev) __func__, fw->data); sc->sc_eepromdata = malloc(fw->datasize, M_TEMP, M_WAITOK | M_ZERO); - if (! sc->sc_eepromdata) { - device_printf(dev, "%s: can't malloc eepromdata\n", - __func__); - goto bad4; - } memcpy(sc->sc_eepromdata, fw->data, fw->datasize); firmware_put(fw, 0); } diff --git a/sys/dev/ath/if_ath_spectral.c b/sys/dev/ath/if_ath_spectral.c index 58f21b526e93..951d66605981 100644 --- a/sys/dev/ath/if_ath_spectral.c +++ b/sys/dev/ath/if_ath_spectral.c @@ -112,13 +112,6 @@ ath_spectral_attach(struct ath_softc *sc) ss = malloc(sizeof(struct ath_spectral_state), M_TEMP, M_WAITOK | M_ZERO); - - if (ss == NULL) { - device_printf(sc->sc_dev, "%s: failed to alloc memory\n", - __func__); - return (-ENOMEM); - } - sc->sc_spectral = ss; (void) ath_hal_spectral_get_config(sc->sc_ah, &ss->spectral_state); From ab0b996bddd96300d56b7d2aa830e2479cdfa92b Mon Sep 17 00:00:00 2001 From: Zhenlei Huang Date: Tue, 3 Sep 2024 18:25:25 +0800 Subject: [PATCH 050/213] axgbe: Stop checking for failures from malloc(M_WAITOK) MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D45852 --- sys/dev/axgbe/xgbe-phy-v2.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/sys/dev/axgbe/xgbe-phy-v2.c b/sys/dev/axgbe/xgbe-phy-v2.c index 5b39d61694e6..8c6069f83076 100644 --- a/sys/dev/axgbe/xgbe-phy-v2.c +++ b/sys/dev/axgbe/xgbe-phy-v2.c @@ -3771,8 +3771,6 @@ xgbe_phy_init(struct xgbe_prv_data *pdata) return (ret); phy_data = malloc(sizeof(*phy_data), M_AXGBE, M_WAITOK | M_ZERO); - if (!phy_data) - return (-ENOMEM); pdata->phy_data = phy_data; phy_data->port_mode = XP_GET_BITS(pdata->pp0, XP_PROP_0, PORT_MODE); From dcd387aaa5d4409a7e99376e0254029fce1a48a8 Mon Sep 17 00:00:00 2001 From: Zhenlei Huang Date: Tue, 3 Sep 2024 18:25:25 +0800 Subject: [PATCH 051/213] bnxt(4): Stop checking for failures from malloc(M_WAITOK) MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D45852 --- sys/dev/bnxt/bnxt_en/bnxt_mgmt.c | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/sys/dev/bnxt/bnxt_en/bnxt_mgmt.c b/sys/dev/bnxt/bnxt_en/bnxt_mgmt.c index 2f82580352cb..72704c3db452 100644 --- a/sys/dev/bnxt/bnxt_en/bnxt_mgmt.c +++ b/sys/dev/bnxt/bnxt_en/bnxt_mgmt.c @@ -205,19 +205,7 @@ bnxt_mgmt_process_hwrm(struct cdev *dev, u_long cmd, caddr_t data, } req = malloc(msg_temp.len_req, M_BNXT, M_WAITOK | M_ZERO); - if(!req) { - device_printf(softc->dev, "%s:%d Memory allocation failed", - __FUNCTION__, __LINE__); - return -ENOMEM; - } - resp = malloc(msg_temp.len_resp, M_BNXT, M_WAITOK | M_ZERO); - if(!resp) { - device_printf(softc->dev, "%s:%d Memory allocation failed", - __FUNCTION__, __LINE__); - ret = -ENOMEM; - goto end; - } if (copyin((void *)msg_temp.usr_req, req, msg_temp.len_req)) { device_printf(softc->dev, "%s:%d Failed to copy data from user\n", @@ -237,12 +225,6 @@ bnxt_mgmt_process_hwrm(struct cdev *dev, u_long cmd, caddr_t data, (num_ind * sizeof(struct dma_info)); msg2 = malloc(size, M_BNXT, M_WAITOK | M_ZERO); - if(!msg2) { - device_printf(softc->dev, "%s:%d Memory allocation failed", - __FUNCTION__, __LINE__); - ret = -ENOMEM; - goto end; - } if (copyin((void *)mgmt_req.req.hreq, msg2, size)) { device_printf(softc->dev, "%s:%d Failed to copy" From bb51f7c8a48a4cd5dfa67fefa81f3d5d199da92b Mon Sep 17 00:00:00 2001 From: Zhenlei Huang Date: Tue, 3 Sep 2024 18:25:25 +0800 Subject: [PATCH 052/213] cxgb(4): Stop checking for failures from malloc/buf_ring_alloc(M_WAITOK) MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D45852 --- sys/dev/cxgb/cxgb_main.c | 4 +--- sys/dev/cxgb/cxgb_sge.c | 7 ++----- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/sys/dev/cxgb/cxgb_main.c b/sys/dev/cxgb/cxgb_main.c index 9bcdb86312c4..4d754aa8b1b7 100644 --- a/sys/dev/cxgb/cxgb_main.c +++ b/sys/dev/cxgb/cxgb_main.c @@ -2472,9 +2472,7 @@ set_eeprom(struct port_info *pi, const uint8_t *data, int len, int offset) aligned_len = (len + (offset & 3) + 3) & ~3; if (aligned_offset != offset || aligned_len != len) { - buf = malloc(aligned_len, M_DEVBUF, M_WAITOK|M_ZERO); - if (!buf) - return (ENOMEM); + buf = malloc(aligned_len, M_DEVBUF, M_WAITOK | M_ZERO); err = t3_seeprom_read(adapter, aligned_offset, (u32 *)buf); if (!err && aligned_len > 4) err = t3_seeprom_read(adapter, diff --git a/sys/dev/cxgb/cxgb_sge.c b/sys/dev/cxgb/cxgb_sge.c index 1b82f2ebcaae..52ffa5cdaffa 100644 --- a/sys/dev/cxgb/cxgb_sge.c +++ b/sys/dev/cxgb/cxgb_sge.c @@ -2419,11 +2419,8 @@ t3_sge_alloc_qset(adapter_t *sc, u_int id, int nports, int irq_vec_idx, q->port = pi; q->adap = sc; - if ((q->txq[TXQ_ETH].txq_mr = buf_ring_alloc(cxgb_txq_buf_ring_size, - M_DEVBUF, M_WAITOK, &q->lock)) == NULL) { - device_printf(sc->dev, "failed to allocate mbuf ring\n"); - goto err; - } + q->txq[TXQ_ETH].txq_mr = buf_ring_alloc(cxgb_txq_buf_ring_size, + M_DEVBUF, M_WAITOK, &q->lock); if ((q->txq[TXQ_ETH].txq_ifq = malloc(sizeof(struct ifaltq), M_DEVBUF, M_NOWAIT | M_ZERO)) == NULL) { device_printf(sc->dev, "failed to allocate ifq\n"); From 955b380365af174b3d35905b7b8afae97506a0bd Mon Sep 17 00:00:00 2001 From: Zhenlei Huang Date: Tue, 3 Sep 2024 18:25:26 +0800 Subject: [PATCH 053/213] cxgbe(4): Stop checking for failures from malloc/mb_alloc_ext_pgs(M_WAITOK) MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D45852 --- sys/dev/cxgbe/cxgbei/cxgbei.c | 3 --- sys/dev/cxgbe/tom/t4_cpl_io.c | 5 ----- 2 files changed, 8 deletions(-) diff --git a/sys/dev/cxgbe/cxgbei/cxgbei.c b/sys/dev/cxgbe/cxgbei/cxgbei.c index 04454a98e247..ccca45f5f761 100644 --- a/sys/dev/cxgbe/cxgbei/cxgbei.c +++ b/sys/dev/cxgbe/cxgbei/cxgbei.c @@ -842,9 +842,6 @@ cxgbei_activate(struct adapter *sc) /* per-adapter softc for iSCSI */ ci = malloc(sizeof(*ci), M_CXGBE, M_ZERO | M_WAITOK); - if (ci == NULL) - return (ENOMEM); - rc = cxgbei_init(sc, ci); if (rc != 0) { free(ci, M_CXGBE); diff --git a/sys/dev/cxgbe/tom/t4_cpl_io.c b/sys/dev/cxgbe/tom/t4_cpl_io.c index cb229d327386..0a40bbda3f3f 100644 --- a/sys/dev/cxgbe/tom/t4_cpl_io.c +++ b/sys/dev/cxgbe/tom/t4_cpl_io.c @@ -2127,11 +2127,6 @@ alloc_aiotx_mbuf(struct kaiocb *job, int len) break; m = mb_alloc_ext_pgs(M_WAITOK, aiotx_free_pgs); - if (m == NULL) { - vm_page_unhold_pages(pgs, npages); - break; - } - m->m_epg_1st_off = pgoff; m->m_epg_npgs = npages; if (npages == 1) { From 6dbf3aca4f5c4f7287f186360c2391f2adfea8d6 Mon Sep 17 00:00:00 2001 From: Zhenlei Huang Date: Tue, 3 Sep 2024 18:25:26 +0800 Subject: [PATCH 054/213] drm2: Stop checking for failures from malloc(M_WAITOK) MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D45852 --- sys/dev/drm2/drm_buffer.c | 30 ----------------------- sys/dev/drm2/drm_crtc.c | 45 +---------------------------------- sys/dev/drm2/ttm/ttm_object.c | 5 ---- 3 files changed, 1 insertion(+), 79 deletions(-) diff --git a/sys/dev/drm2/drm_buffer.c b/sys/dev/drm2/drm_buffer.c index 8a674397262e..8069f2c8c4c6 100644 --- a/sys/dev/drm2/drm_buffer.c +++ b/sys/dev/drm2/drm_buffer.c @@ -50,45 +50,15 @@ int drm_buffer_alloc(struct drm_buffer **buf, int size) * variable sized */ *buf = malloc(sizeof(struct drm_buffer) + nr_pages*sizeof(char *), DRM_MEM_DRIVER, M_ZERO | M_WAITOK); - - if (*buf == NULL) { - DRM_ERROR("Failed to allocate drm buffer object to hold" - " %d bytes in %d pages.\n", - size, nr_pages); - return -ENOMEM; - } - (*buf)->size = size; for (idx = 0; idx < nr_pages; ++idx) { - (*buf)->data[idx] = malloc(min(PAGE_SIZE, size - idx * PAGE_SIZE), DRM_MEM_DRIVER, M_WAITOK); - - - if ((*buf)->data[idx] == NULL) { - DRM_ERROR("Failed to allocate %dth page for drm" - " buffer with %d bytes and %d pages.\n", - idx + 1, size, nr_pages); - goto error_out; - } - } return 0; - -error_out: - - /* Only last element can be null pointer so check for it first. */ - if ((*buf)->data[idx]) - free((*buf)->data[idx], DRM_MEM_DRIVER); - - for (--idx; idx >= 0; --idx) - free((*buf)->data[idx], DRM_MEM_DRIVER); - - free(*buf, DRM_MEM_DRIVER); - return -ENOMEM; } EXPORT_SYMBOL(drm_buffer_alloc); diff --git a/sys/dev/drm2/drm_crtc.c b/sys/dev/drm2/drm_crtc.c index b9415082e7a1..a163c7455773 100644 --- a/sys/dev/drm2/drm_crtc.c +++ b/sys/dev/drm2/drm_crtc.c @@ -662,13 +662,6 @@ int drm_plane_init(struct drm_device *dev, struct drm_plane *plane, plane->funcs = funcs; plane->format_types = malloc(sizeof(uint32_t) * format_count, DRM_MEM_KMS, M_WAITOK); - if (!plane->format_types) { - DRM_DEBUG_KMS("out of memory when allocating plane\n"); - drm_mode_object_put(dev, &plane->base); - ret = -ENOMEM; - goto out; - } - memcpy(plane->format_types, formats, format_count * sizeof(uint32_t)); plane->format_count = format_count; plane->possible_crtcs = possible_crtcs; @@ -725,8 +718,6 @@ struct drm_display_mode *drm_mode_create(struct drm_device *dev) nmode = malloc(sizeof(struct drm_display_mode), DRM_MEM_KMS, M_WAITOK | M_ZERO); - if (!nmode) - return NULL; if (drm_mode_object_get(dev, &nmode->base, DRM_MODE_OBJECT_MODE)) { free(nmode, DRM_MEM_KMS); @@ -1009,9 +1000,6 @@ int drm_mode_group_init(struct drm_device *dev, struct drm_mode_group *group) group->id_list = malloc(total_objects * sizeof(uint32_t), DRM_MEM_KMS, M_WAITOK | M_ZERO); - if (!group->id_list) - return -ENOMEM; - group->num_crtcs = 0; group->num_connectors = 0; group->num_encoders = 0; @@ -1997,10 +1985,6 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data, connector_set = malloc(crtc_req->count_connectors * sizeof(struct drm_connector *), DRM_MEM_KMS, M_WAITOK); - if (!connector_set) { - ret = -ENOMEM; - goto out; - } for (i = 0; i < crtc_req->count_connectors; i++) { set_connectors_ptr = (uint32_t __user *)(unsigned long)crtc_req->set_connectors_ptr; @@ -2522,11 +2506,6 @@ int drm_mode_dirtyfb_ioctl(struct drm_device *dev, } clips = malloc(num_clips * sizeof(*clips), DRM_MEM_KMS, M_WAITOK | M_ZERO); - if (!clips) { - ret = -ENOMEM; - goto out_err1; - } - ret = copy_from_user(clips, clips_ptr, num_clips * sizeof(*clips)); if (ret) { @@ -2773,15 +2752,10 @@ struct drm_property *drm_property_create(struct drm_device *dev, int flags, property = malloc(sizeof(struct drm_property), DRM_MEM_KMS, M_WAITOK | M_ZERO); - if (!property) - return NULL; - if (num_values) { + if (num_values) property->values = malloc(sizeof(uint64_t)*num_values, DRM_MEM_KMS, M_WAITOK | M_ZERO); - if (!property->values) - goto fail; - } ret = drm_mode_object_get(dev, &property->base, DRM_MODE_OBJECT_PROPERTY); if (ret) @@ -2907,9 +2881,6 @@ int drm_property_add_enum(struct drm_property *property, int index, prop_enum = malloc(sizeof(struct drm_property_enum), DRM_MEM_KMS, M_WAITOK | M_ZERO); - if (!prop_enum) - return -ENOMEM; - strncpy(prop_enum->name, name, DRM_PROP_NAME_LEN); prop_enum->name[DRM_PROP_NAME_LEN-1] = '\0'; prop_enum->value = value; @@ -3103,9 +3074,6 @@ static struct drm_property_blob *drm_property_create_blob(struct drm_device *dev blob = malloc(sizeof(struct drm_property_blob)+length, DRM_MEM_KMS, M_WAITOK | M_ZERO); - if (!blob) - return NULL; - ret = drm_mode_object_get(dev, &blob->base, DRM_MODE_OBJECT_BLOB); if (ret) { free(blob, DRM_MEM_KMS); @@ -3433,10 +3401,6 @@ int drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc, crtc->gamma_store = malloc(gamma_size * sizeof(uint16_t) * 3, DRM_MEM_KMS, M_WAITOK | M_ZERO); - if (!crtc->gamma_store) { - crtc->gamma_size = 0; - return -ENOMEM; - } return 0; } @@ -3631,13 +3595,6 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev, mtx_unlock(&dev->event_lock); e = malloc(sizeof *e, DRM_MEM_KMS, M_WAITOK | M_ZERO); - if (e == NULL) { - mtx_lock(&dev->event_lock); - file_priv->event_space += sizeof e->event; - mtx_unlock(&dev->event_lock); - goto out; - } - e->event.base.type = DRM_EVENT_FLIP_COMPLETE; e->event.base.length = sizeof e->event; e->event.user_data = page_flip->user_data; diff --git a/sys/dev/drm2/ttm/ttm_object.c b/sys/dev/drm2/ttm/ttm_object.c index 8c373618d7ac..31af15cf4c56 100644 --- a/sys/dev/drm2/ttm/ttm_object.c +++ b/sys/dev/drm2/ttm/ttm_object.c @@ -282,11 +282,6 @@ int ttm_ref_object_add(struct ttm_object_file *tfile, if (unlikely(ret != 0)) return ret; ref = malloc(sizeof(*ref), M_TTM_OBJ_REF, M_WAITOK); - if (unlikely(ref == NULL)) { - ttm_mem_global_free(mem_glob, sizeof(*ref)); - return -ENOMEM; - } - ref->hash.key = base->hash.key; ref->obj = base; ref->tfile = tfile; From 51971340bd3ff41591adbbfca68e9e753f6eb135 Mon Sep 17 00:00:00 2001 From: Zhenlei Huang Date: Tue, 3 Sep 2024 18:25:26 +0800 Subject: [PATCH 055/213] ena(4): Stop checking for failures from malloc(M_WAITOK) MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D45852 --- sys/dev/ena/ena_rss.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/sys/dev/ena/ena_rss.c b/sys/dev/ena/ena_rss.c index d90a7fbb253a..41fa9c62f94a 100644 --- a/sys/dev/ena/ena_rss.c +++ b/sys/dev/ena/ena_rss.c @@ -279,12 +279,9 @@ ena_rss_indir_init(struct ena_adapter *adapter) struct ena_indir *indir = adapter->rss_indir; int rc; - if (indir == NULL) { + if (indir == NULL) adapter->rss_indir = indir = malloc(sizeof(struct ena_indir), M_DEVBUF, M_WAITOK | M_ZERO); - if (indir == NULL) - return (ENOMEM); - } rc = ena_rss_indir_get(adapter, indir->table); if (rc != 0) { From 48741f4ceca71523aa1fa8da3bb78b184fad4aca Mon Sep 17 00:00:00 2001 From: Zhenlei Huang Date: Tue, 3 Sep 2024 18:25:27 +0800 Subject: [PATCH 056/213] etherswitch: Stop checking for failures from malloc(M_WAITOK) MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D45852 --- sys/dev/etherswitch/infineon/adm6996fc.c | 22 ++++------------------ sys/dev/etherswitch/micrel/ksz8995ma.c | 22 ++++------------------ 2 files changed, 8 insertions(+), 36 deletions(-) diff --git a/sys/dev/etherswitch/infineon/adm6996fc.c b/sys/dev/etherswitch/infineon/adm6996fc.c index 2c6c83a4388d..64f61df93db1 100644 --- a/sys/dev/etherswitch/infineon/adm6996fc.c +++ b/sys/dev/etherswitch/infineon/adm6996fc.c @@ -179,10 +179,6 @@ adm6996fc_attach_phys(struct adm6996fc_softc *sc) if_initname(sc->ifp[port], name, port); sc->miibus[port] = malloc(sizeof(device_t), M_ADM6996FC, M_WAITOK | M_ZERO); - if (sc->miibus[port] == NULL) { - err = ENOMEM; - goto failed; - } err = mii_attach(sc->sc_dev, sc->miibus[port], sc->ifp[port], adm6996fc_ifmedia_upd, adm6996fc_ifmedia_sts, \ BMSR_DEFCAPMASK, phy, MII_OFFSET_ANY, 0); @@ -255,12 +251,6 @@ adm6996fc_attach(device_t dev) sc->portphy = malloc(sizeof(int) * sc->numports, M_ADM6996FC, M_WAITOK | M_ZERO); - if (sc->ifp == NULL || sc->ifname == NULL || sc->miibus == NULL || - sc->portphy == NULL) { - err = ENOMEM; - goto failed; - } - /* * Attach the PHYs and complete the bus enumeration. */ @@ -281,14 +271,10 @@ adm6996fc_attach(device_t dev) return (0); failed: - if (sc->portphy != NULL) - free(sc->portphy, M_ADM6996FC); - if (sc->miibus != NULL) - free(sc->miibus, M_ADM6996FC); - if (sc->ifname != NULL) - free(sc->ifname, M_ADM6996FC); - if (sc->ifp != NULL) - free(sc->ifp, M_ADM6996FC); + free(sc->portphy, M_ADM6996FC); + free(sc->miibus, M_ADM6996FC); + free(sc->ifname, M_ADM6996FC); + free(sc->ifp, M_ADM6996FC); return (err); } diff --git a/sys/dev/etherswitch/micrel/ksz8995ma.c b/sys/dev/etherswitch/micrel/ksz8995ma.c index e512a86202c6..ccd7dbffa9e9 100644 --- a/sys/dev/etherswitch/micrel/ksz8995ma.c +++ b/sys/dev/etherswitch/micrel/ksz8995ma.c @@ -225,10 +225,6 @@ ksz8995ma_attach_phys(struct ksz8995ma_softc *sc) if_initname(sc->ifp[port], name, port); sc->miibus[port] = malloc(sizeof(device_t), M_KSZ8995MA, M_WAITOK | M_ZERO); - if (sc->miibus[port] == NULL) { - err = ENOMEM; - goto failed; - } err = mii_attach(sc->sc_dev, sc->miibus[port], sc->ifp[port], ksz8995ma_ifmedia_upd, ksz8995ma_ifmedia_sts, \ BMSR_DEFCAPMASK, phy, MII_OFFSET_ANY, 0); @@ -305,12 +301,6 @@ ksz8995ma_attach(device_t dev) sc->portphy = malloc(sizeof(int) * sc->numports, M_KSZ8995MA, M_WAITOK | M_ZERO); - if (sc->ifp == NULL || sc->ifname == NULL || sc->miibus == NULL || - sc->portphy == NULL) { - err = ENOMEM; - goto failed; - } - /* * Attach the PHYs and complete the bus enumeration. */ @@ -339,14 +329,10 @@ ksz8995ma_attach(device_t dev) return (0); failed: - if (sc->portphy != NULL) - free(sc->portphy, M_KSZ8995MA); - if (sc->miibus != NULL) - free(sc->miibus, M_KSZ8995MA); - if (sc->ifname != NULL) - free(sc->ifname, M_KSZ8995MA); - if (sc->ifp != NULL) - free(sc->ifp, M_KSZ8995MA); + free(sc->portphy, M_KSZ8995MA); + free(sc->miibus, M_KSZ8995MA); + free(sc->ifname, M_KSZ8995MA); + free(sc->ifp, M_KSZ8995MA); return (err); } From d1a89bd9b6eb1524902b619fa092c7d6de63e623 Mon Sep 17 00:00:00 2001 From: Zhenlei Huang Date: Tue, 3 Sep 2024 18:25:27 +0800 Subject: [PATCH 057/213] flexspi: Stop checking for failures from malloc(M_WAITOK) MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D45852 --- sys/dev/flash/flexspi/flex_spi.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/sys/dev/flash/flexspi/flex_spi.c b/sys/dev/flash/flexspi/flex_spi.c index 766a1cfaa332..9382b237ee71 100644 --- a/sys/dev/flash/flexspi/flex_spi.c +++ b/sys/dev/flash/flexspi/flex_spi.c @@ -781,12 +781,6 @@ flex_spi_attach(device_t dev) } sc->buf = malloc(sc->erasesize, SECTOR_BUFFER, M_WAITOK); - if (sc->buf == NULL) { - device_printf(sc->dev, "Unable to set up allocate internal buffer\n"); - flex_spi_detach(dev); - return (ENOMEM); - } - /* Move it to per-flash */ sc->disk = disk_alloc(); sc->disk->d_open = flex_spi_open; From 4d47c7ca7baa1ae76cc1fc72ec85b475f1efd41d Mon Sep 17 00:00:00 2001 From: Zhenlei Huang Date: Tue, 3 Sep 2024 18:25:28 +0800 Subject: [PATCH 058/213] fwip(4): Stop checking for failures from malloc(M_WAITOK) MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D45852 --- sys/dev/firewire/if_fwip.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/sys/dev/firewire/if_fwip.c b/sys/dev/firewire/if_fwip.c index 6350ec9cb56e..41143e2e59d4 100644 --- a/sys/dev/firewire/if_fwip.c +++ b/sys/dev/firewire/if_fwip.c @@ -304,13 +304,9 @@ fwip_init(void *arg) xferq->psize = MCLBYTES; xferq->queued = 0; xferq->buf = NULL; - xferq->bulkxfer = (struct fw_bulkxfer *) malloc( + xferq->bulkxfer = malloc( sizeof(struct fw_bulkxfer) * xferq->bnchunk, M_FWIP, M_WAITOK); - if (xferq->bulkxfer == NULL) { - printf("if_fwip: malloc failed\n"); - return; - } STAILQ_INIT(&xferq->stvalid); STAILQ_INIT(&xferq->stfree); STAILQ_INIT(&xferq->stdma); From 28e413a699838df6fa5b0504c9ceb92a515037d9 Mon Sep 17 00:00:00 2001 From: Zhenlei Huang Date: Tue, 3 Sep 2024 18:25:28 +0800 Subject: [PATCH 059/213] hpt27xx(4): Stop checking for failures from malloc(M_WAITOK) MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D45852 --- sys/dev/hpt27xx/hpt27xx_osm_bsd.c | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/sys/dev/hpt27xx/hpt27xx_osm_bsd.c b/sys/dev/hpt27xx/hpt27xx_osm_bsd.c index 225c91b44f21..e086a1554940 100644 --- a/sys/dev/hpt27xx/hpt27xx_osm_bsd.c +++ b/sys/dev/hpt27xx/hpt27xx_osm_bsd.c @@ -94,9 +94,6 @@ static int hpt_attach(device_t dev) size = him->get_adapter_size(&pci_id); hba->ldm_adapter.him_handle = malloc(size, M_DEVBUF, M_WAITOK); - if (!hba->ldm_adapter.him_handle) - return ENXIO; - hba->pcidev = dev; hba->pciaddr.tree = 0; hba->pciaddr.bus = pci_get_bus(dev); @@ -114,10 +111,6 @@ static int hpt_attach(device_t dev) if (!ldm_register_adapter(&hba->ldm_adapter)) { size = ldm_get_vbus_size(); vbus_ext = malloc(sizeof(VBUS_EXT) + size, M_DEVBUF, M_WAITOK); - if (!vbus_ext) { - free(hba->ldm_adapter.him_handle, M_DEVBUF); - return ENXIO; - } memset(vbus_ext, 0, sizeof(VBUS_EXT)); vbus_ext->ext_type = EXT_TYPE_VBUS; ldm_create_vbus((PVBUS)vbus_ext->vbus, vbus_ext); @@ -168,7 +161,6 @@ static int hpt_alloc_mem(PVBUS_EXT vbus_ext) f->tag, f->count, f->size, f->count*f->size)); for (i=0; icount; i++) { p = (void **)malloc(f->size, M_DEVBUF, M_WAITOK); - if (!p) return (ENXIO); *p = f->head; f->head = p; } @@ -1109,10 +1101,6 @@ static void hpt_final_init(void *dummy) for (i=0; ivbus_ext = vbus_ext; ext->next = vbus_ext->cmdext_list; vbus_ext->cmdext_list = ext; @@ -1327,18 +1315,13 @@ static int hpt_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag, stru if (ioctl_args.nInBufferSize) { ioctl_args.lpInBuffer = malloc(ioctl_args.nInBufferSize, M_DEVBUF, M_WAITOK); - if (!ioctl_args.lpInBuffer) - goto invalid; if (copyin((void*)piop->lpInBuffer, ioctl_args.lpInBuffer, piop->nInBufferSize)) goto invalid; } - if (ioctl_args.nOutBufferSize) { + if (ioctl_args.nOutBufferSize) ioctl_args.lpOutBuffer = malloc(ioctl_args.nOutBufferSize, M_DEVBUF, M_WAITOK | M_ZERO); - if (!ioctl_args.lpOutBuffer) - goto invalid; - } hpt_do_ioctl(&ioctl_args); From a3ec5d3ee7579a26790a86ca4c074512946ab964 Mon Sep 17 00:00:00 2001 From: Zhenlei Huang Date: Tue, 3 Sep 2024 18:25:29 +0800 Subject: [PATCH 060/213] hptnr(4): Stop checking for failures from malloc(M_WAITOK) MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D45852 --- sys/dev/hptnr/hptnr_osm_bsd.c | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/sys/dev/hptnr/hptnr_osm_bsd.c b/sys/dev/hptnr/hptnr_osm_bsd.c index a8ac77c5ad5a..7426873964fb 100644 --- a/sys/dev/hptnr/hptnr_osm_bsd.c +++ b/sys/dev/hptnr/hptnr_osm_bsd.c @@ -165,7 +165,6 @@ static int hpt_alloc_mem(PVBUS_EXT vbus_ext) f->tag, f->count, f->size, f->count*f->size)); for (i=0; icount; i++) { p = (void **)malloc(f->size, M_DEVBUF, M_WAITOK); - if (!p) return (ENXIO); *p = f->head; f->head = p; } @@ -1389,10 +1388,6 @@ static void hpt_final_init(void *dummy) for (i=0; ivbus_ext = vbus_ext; ext->next = vbus_ext->cmdext_list; vbus_ext->cmdext_list = ext; @@ -1610,19 +1605,14 @@ static int hpt_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag, stru if (ioctl_args.nInBufferSize) { ioctl_args.lpInBuffer = malloc(ioctl_args.nInBufferSize, M_DEVBUF, M_WAITOK); - if (!ioctl_args.lpInBuffer) - goto invalid; if (copyin((void*)piop->lpInBuffer, ioctl_args.lpInBuffer, piop->nInBufferSize)) goto invalid; } - if (ioctl_args.nOutBufferSize) { + if (ioctl_args.nOutBufferSize) ioctl_args.lpOutBuffer = malloc(ioctl_args.nOutBufferSize, M_DEVBUF, M_WAITOK | M_ZERO); - if (!ioctl_args.lpOutBuffer) - goto invalid; - } - + hpt_do_ioctl(&ioctl_args); if (ioctl_args.result==HPT_IOCTL_RESULT_OK) { From 92b0370ec65d5287a1deec84fd513e320a8da736 Mon Sep 17 00:00:00 2001 From: Zhenlei Huang Date: Tue, 3 Sep 2024 18:25:29 +0800 Subject: [PATCH 061/213] hptrr(4): Stop checking for failures from malloc(M_WAITOK) MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D45852 --- sys/dev/hptrr/hptrr_osm_bsd.c | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/sys/dev/hptrr/hptrr_osm_bsd.c b/sys/dev/hptrr/hptrr_osm_bsd.c index 68e9af3aff02..42866c1d4297 100644 --- a/sys/dev/hptrr/hptrr_osm_bsd.c +++ b/sys/dev/hptrr/hptrr_osm_bsd.c @@ -1032,10 +1032,6 @@ static void hpt_final_init(void *dummy) for (i=0; ivbus_ext = vbus_ext; ext->next = vbus_ext->cmdext_list; vbus_ext->cmdext_list = ext; @@ -1252,19 +1248,14 @@ static int hpt_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag, stru if (ioctl_args.nInBufferSize) { ioctl_args.lpInBuffer = malloc(ioctl_args.nInBufferSize, M_DEVBUF, M_WAITOK); - if (!ioctl_args.lpInBuffer) - goto invalid; if (copyin((void*)piop->lpInBuffer, ioctl_args.lpInBuffer, piop->nInBufferSize)) goto invalid; } - if (ioctl_args.nOutBufferSize) { + if (ioctl_args.nOutBufferSize) ioctl_args.lpOutBuffer = malloc(ioctl_args.nOutBufferSize, M_DEVBUF, M_WAITOK | M_ZERO); - if (!ioctl_args.lpOutBuffer) - goto invalid; - } - + hpt_do_ioctl(&ioctl_args); if (ioctl_args.result==HPT_IOCTL_RESULT_OK) { From 5f97656fa334b494d70866cb1bfff406d3efd92d Mon Sep 17 00:00:00 2001 From: Zhenlei Huang Date: Tue, 3 Sep 2024 18:25:29 +0800 Subject: [PATCH 062/213] ice(4): Stop checking for failures from malloc(M_WAITOK) As a consequence now ice_alloc_vsi_qmap() does not fail. Remove unneeded error checks. MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D45852 --- sys/dev/ice/ice_lib.c | 24 +++--------------------- sys/dev/ice/ice_lib.h | 2 +- sys/dev/ice/if_ice_iflib.c | 13 ++----------- 3 files changed, 6 insertions(+), 33 deletions(-) diff --git a/sys/dev/ice/ice_lib.c b/sys/dev/ice/ice_lib.c index 659412450fce..7077859cc877 100644 --- a/sys/dev/ice/ice_lib.c +++ b/sys/dev/ice/ice_lib.c @@ -426,31 +426,21 @@ ice_setup_pf_vsi(struct ice_softc *sc) * all queues for this VSI are not yet assigned an index and thus, * not ready for use. * - * Returns an error code on failure. */ -int +void ice_alloc_vsi_qmap(struct ice_vsi *vsi, const int max_tx_queues, const int max_rx_queues) { - struct ice_softc *sc = vsi->sc; int i; MPASS(max_tx_queues > 0); MPASS(max_rx_queues > 0); /* Allocate Tx queue mapping memory */ - if (!(vsi->tx_qmap = - (u16 *) malloc(sizeof(u16) * max_tx_queues, M_ICE, M_WAITOK))) { - device_printf(sc->dev, "Unable to allocate Tx qmap memory\n"); - return (ENOMEM); - } + vsi->tx_qmap = malloc(sizeof(u16) * max_tx_queues, M_ICE, M_WAITOK); /* Allocate Rx queue mapping memory */ - if (!(vsi->rx_qmap = - (u16 *) malloc(sizeof(u16) * max_rx_queues, M_ICE, M_WAITOK))) { - device_printf(sc->dev, "Unable to allocate Rx qmap memory\n"); - goto free_tx_qmap; - } + vsi->rx_qmap = malloc(sizeof(u16) * max_rx_queues, M_ICE, M_WAITOK); /* Mark every queue map as invalid to start with */ for (i = 0; i < max_tx_queues; i++) { @@ -459,14 +449,6 @@ ice_alloc_vsi_qmap(struct ice_vsi *vsi, const int max_tx_queues, for (i = 0; i < max_rx_queues; i++) { vsi->rx_qmap[i] = ICE_INVALID_RES_IDX; } - - return 0; - -free_tx_qmap: - free(vsi->tx_qmap, M_ICE); - vsi->tx_qmap = NULL; - - return (ENOMEM); } /** diff --git a/sys/dev/ice/ice_lib.h b/sys/dev/ice/ice_lib.h index cfd848d370bb..6c010cffc0fd 100644 --- a/sys/dev/ice/ice_lib.h +++ b/sys/dev/ice/ice_lib.h @@ -830,7 +830,7 @@ void ice_free_bar(device_t dev, struct ice_bar_info *bar); void ice_set_ctrlq_len(struct ice_hw *hw); void ice_release_vsi(struct ice_vsi *vsi); struct ice_vsi *ice_alloc_vsi(struct ice_softc *sc, enum ice_vsi_type type); -int ice_alloc_vsi_qmap(struct ice_vsi *vsi, const int max_tx_queues, +void ice_alloc_vsi_qmap(struct ice_vsi *vsi, const int max_tx_queues, const int max_rx_queues); void ice_free_vsi_qmaps(struct ice_vsi *vsi); int ice_initialize_vsi(struct ice_vsi *vsi); diff --git a/sys/dev/ice/if_ice_iflib.c b/sys/dev/ice/if_ice_iflib.c index 4e451bf3fb55..3de79787f6e8 100644 --- a/sys/dev/ice/if_ice_iflib.c +++ b/sys/dev/ice/if_ice_iflib.c @@ -631,12 +631,8 @@ ice_if_attach_pre(if_ctx_t ctx) */ ice_setup_pf_vsi(sc); - err = ice_alloc_vsi_qmap(&sc->pf_vsi, scctx->isc_ntxqsets_max, + ice_alloc_vsi_qmap(&sc->pf_vsi, scctx->isc_ntxqsets_max, scctx->isc_nrxqsets_max); - if (err) { - device_printf(dev, "Unable to allocate VSI Queue maps\n"); - goto free_main_vsi; - } /* Allocate MSI-X vectors (due to isc_flags IFLIB_SKIP_MSIX) */ err = ice_allocate_msix(sc); @@ -3518,12 +3514,7 @@ ice_setup_mirror_vsi(struct ice_mirr_if *mif) mif->vsi = vsi; /* Reserve VSI queue allocation from PF queues */ - ret = ice_alloc_vsi_qmap(vsi, ICE_DEFAULT_VF_QUEUES, ICE_DEFAULT_VF_QUEUES); - if (ret) { - device_printf(dev, "%s: Unable to allocate mirror VSI queue maps (%d queues): %s\n", - __func__, ICE_DEFAULT_VF_QUEUES, ice_err_str(ret)); - goto release_vsi; - } + ice_alloc_vsi_qmap(vsi, ICE_DEFAULT_VF_QUEUES, ICE_DEFAULT_VF_QUEUES); vsi->num_tx_queues = vsi->num_rx_queues = ICE_DEFAULT_VF_QUEUES; /* Assign Tx queues from PF space */ From 40a6bbc4284111790d9240f8a24ef11a9a9ecb07 Mon Sep 17 00:00:00 2001 From: Zhenlei Huang Date: Tue, 3 Sep 2024 18:25:30 +0800 Subject: [PATCH 063/213] iser(4): Stop checking for failures from malloc(M_WAITOK) MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D45852 --- sys/dev/iser/iser_verbs.c | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/sys/dev/iser/iser_verbs.c b/sys/dev/iser/iser_verbs.c index f5f057b961ef..f0c7e524ccf0 100644 --- a/sys/dev/iser/iser_verbs.c +++ b/sys/dev/iser/iser_verbs.c @@ -212,8 +212,6 @@ iser_create_device_ib_res(struct iser_device *device) device->comps = malloc(device->comps_used * sizeof(*device->comps), M_ISER_VERBS, M_WAITOK | M_ZERO); - if (!device->comps) - goto comps_err; max_cqe = min(ISER_MAX_CQ_LEN, ib_dev->attrs.max_cqe); @@ -280,7 +278,6 @@ iser_create_device_ib_res(struct iser_device *device) ib_dealloc_pd(device->pd); pd_err: free(device->comps, M_ISER_VERBS); -comps_err: ISER_ERR("failed to allocate an IB resource"); return (1); } @@ -343,11 +340,6 @@ iser_create_fastreg_desc(struct ib_device *ib_device, struct ib_pd *pd) int ret; desc = malloc(sizeof(*desc), M_ISER_VERBS, M_WAITOK | M_ZERO); - if (!desc) { - ISER_ERR("Failed to allocate a new fastreg descriptor"); - return (NULL); - } - ret = iser_alloc_reg_res(ib_device, pd, &desc->rsc); if (ret) { ISER_ERR("failed to allocate reg_resources"); @@ -509,9 +501,6 @@ iser_device_find_by_ib_device(struct rdma_cm_id *cma_id) goto inc_refcnt; device = malloc(sizeof *device, M_ISER_VERBS, M_WAITOK | M_ZERO); - if (device == NULL) - goto out; - /* assign this device to the device */ device->ib_device = cma_id->device; /* init the device and link it into ig device list */ From 1dc7a7b74b5ad37ff7c8dc22f1a710460a5f1dcd Mon Sep 17 00:00:00 2001 From: Zhenlei Huang Date: Tue, 3 Sep 2024 18:25:30 +0800 Subject: [PATCH 064/213] mana: Stop checking for failures from malloc/mallocarray/buf_ring_alloc(M_WAITOK) MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D45852 --- sys/dev/mana/gdma_main.c | 19 ------------------ sys/dev/mana/hw_channel.c | 17 ---------------- sys/dev/mana/mana_en.c | 41 --------------------------------------- 3 files changed, 77 deletions(-) diff --git a/sys/dev/mana/gdma_main.c b/sys/dev/mana/gdma_main.c index 6f3e182ba1eb..13f2617ad7d4 100644 --- a/sys/dev/mana/gdma_main.c +++ b/sys/dev/mana/gdma_main.c @@ -868,9 +868,6 @@ int mana_gd_create_hwc_queue(struct gdma_dev *gd, int err; queue = malloc(sizeof(*queue), M_DEVBUF, M_WAITOK | M_ZERO); - if (!queue) - return ENOMEM; - gmi = &queue->mem_info; err = mana_gd_alloc_memory(gc, spec->queue_size, gmi); if (err) @@ -962,9 +959,6 @@ mana_gd_create_dma_region(struct gdma_dev *gd, } req = malloc(req_msg_size, M_DEVBUF, M_WAITOK | M_ZERO); - if (!req) - return ENOMEM; - mana_gd_init_req_hdr(&req->hdr, GDMA_CREATE_DMA_REGION, req_msg_size, sizeof(resp)); req->length = length; @@ -1008,9 +1002,6 @@ mana_gd_create_mana_eq(struct gdma_dev *gd, return EINVAL; queue = malloc(sizeof(*queue), M_DEVBUF, M_WAITOK | M_ZERO); - if (!queue) - return ENOMEM; - gmi = &queue->mem_info; err = mana_gd_alloc_memory(gc, spec->queue_size, gmi); if (err) @@ -1056,9 +1047,6 @@ int mana_gd_create_mana_wq_cq(struct gdma_dev *gd, return EINVAL; queue = malloc(sizeof(*queue), M_DEVBUF, M_WAITOK | M_ZERO); - if (!queue) - return ENOMEM; - gmi = &queue->mem_info; err = mana_gd_alloc_memory(gc, spec->queue_size, gmi); if (err) @@ -1480,9 +1468,6 @@ mana_gd_alloc_res_map(uint32_t res_avail, r->map = malloc(n * sizeof(unsigned long), M_DEVBUF, M_WAITOK | M_ZERO); - if (!r->map) - return ENOMEM; - r->size = res_avail; mtx_init(&r->lock_spin, lock_name, NULL, MTX_SPIN); @@ -1616,10 +1601,6 @@ mana_gd_setup_irqs(device_t dev) gc->irq_contexts = malloc(nvec * sizeof(struct gdma_irq_context), M_DEVBUF, M_WAITOK | M_ZERO); - if (!gc->irq_contexts) { - rc = ENOMEM; - goto err_setup_irq_release; - } for (i = 0; i < nvec; i++) { gic = &gc->irq_contexts[i]; diff --git a/sys/dev/mana/hw_channel.c b/sys/dev/mana/hw_channel.c index 7a40a28894fb..5904389596a3 100644 --- a/sys/dev/mana/hw_channel.c +++ b/sys/dev/mana/hw_channel.c @@ -416,8 +416,6 @@ mana_hwc_create_cq(struct hw_channel_context *hwc, cq_size = MINIMUM_SUPPORTED_PAGE_SIZE; hwc_cq = malloc(sizeof(*hwc_cq), M_DEVBUF, M_WAITOK | M_ZERO); - if (!hwc_cq) - return ENOMEM; err = mana_hwc_create_gdma_eq(hwc, eq_size, ctx, callback, &eq); if (err) { @@ -438,10 +436,6 @@ mana_hwc_create_cq(struct hw_channel_context *hwc, comp_buf = mallocarray(q_depth, sizeof(struct gdma_comp), M_DEVBUF, M_WAITOK | M_ZERO); - if (!comp_buf) { - err = ENOMEM; - goto out; - } hwc_cq->hwc = hwc; hwc_cq->comp_buf = comp_buf; @@ -476,8 +470,6 @@ mana_hwc_alloc_dma_buf(struct hw_channel_context *hwc, uint16_t q_depth, dma_buf = malloc(sizeof(*dma_buf) + q_depth * sizeof(struct hwc_work_request), M_DEVBUF, M_WAITOK | M_ZERO); - if (!dma_buf) - return ENOMEM; dma_buf->num_reqs = q_depth; @@ -560,8 +552,6 @@ mana_hwc_create_wq(struct hw_channel_context *hwc, queue_size = MINIMUM_SUPPORTED_PAGE_SIZE; hwc_wq = malloc(sizeof(*hwc_wq), M_DEVBUF, M_WAITOK | M_ZERO); - if (!hwc_wq) - return ENOMEM; err = mana_hwc_create_gdma_wq(hwc, q_type, queue_size, &queue); if (err) @@ -669,8 +659,6 @@ mana_hwc_test_channel(struct hw_channel_context *hwc, uint16_t q_depth, ctx = malloc(q_depth * sizeof(struct hwc_caller_ctx), M_DEVBUF, M_WAITOK | M_ZERO); - if (!ctx) - return ENOMEM; for (i = 0; i < q_depth; ++i) init_completion(&ctx[i].comp_event); @@ -719,9 +707,6 @@ mana_hwc_establish_channel(struct gdma_context *gc, uint16_t *q_depth, gc->cq_table = malloc(gc->max_num_cqs * sizeof(struct gdma_queue *), M_DEVBUF, M_WAITOK | M_ZERO); - if (!gc->cq_table) - return ENOMEM; - gc->cq_table[cq->id] = cq; return 0; @@ -782,8 +767,6 @@ mana_hwc_create_channel(struct gdma_context *gc) int err; hwc = malloc(sizeof(*hwc), M_DEVBUF, M_WAITOK | M_ZERO); - if (!hwc) - return ENOMEM; gd->gdma_context = gc; gd->driver_data = hwc; diff --git a/sys/dev/mana/mana_en.c b/sys/dev/mana/mana_en.c index 961399172688..90db036ff59b 100644 --- a/sys/dev/mana/mana_en.c +++ b/sys/dev/mana/mana_en.c @@ -921,13 +921,6 @@ mana_init_port_context(struct mana_port_context *apc) apc->rxqs = mallocarray(apc->num_queues, sizeof(struct mana_rxq *), M_DEVBUF, M_WAITOK | M_ZERO); - if (!apc->rxqs) { - bus_dma_tag_destroy(apc->tx_buf_tag); - bus_dma_tag_destroy(apc->rx_buf_tag); - apc->rx_buf_tag = NULL; - return ENOMEM; - } - return 0; } @@ -1156,8 +1149,6 @@ mana_cfg_vport_steering(struct mana_port_context *apc, req_buf_size = sizeof(*req) + sizeof(mana_handle_t) * num_entries; req = malloc(req_buf_size, M_DEVBUF, M_WAITOK | M_ZERO); - if (!req) - return ENOMEM; mana_gd_init_req_hdr(&req->hdr, MANA_CONFIG_VPORT_RX, req_buf_size, sizeof(resp)); @@ -1325,8 +1316,6 @@ mana_create_eq(struct mana_context *ac) ac->eqs = mallocarray(gc->max_num_queues, sizeof(struct mana_eq), M_DEVBUF, M_WAITOK | M_ZERO); - if (!ac->eqs) - return ENOMEM; spec.type = GDMA_EQ; spec.monitor_avl_buf = false; @@ -2043,8 +2032,6 @@ mana_create_txq(struct mana_port_context *apc, if_t net) apc->tx_qp = mallocarray(apc->num_queues, sizeof(struct mana_tx_qp), M_DEVBUF, M_WAITOK | M_ZERO); - if (!apc->tx_qp) - return ENOMEM; /* The minimum size of the WQE is 32 bytes, hence * MAX_SEND_BUFFERS_PER_QUEUE represents the maximum number of WQEs @@ -2141,14 +2128,6 @@ mana_create_txq(struct mana_port_context *apc, if_t net) txq->tx_buf_info = malloc(MAX_SEND_BUFFERS_PER_QUEUE * sizeof(struct mana_send_buf_info), M_DEVBUF, M_WAITOK | M_ZERO); - if (unlikely(txq->tx_buf_info == NULL)) { - if_printf(net, - "Failed to allocate tx buf info for SQ %u\n", - txq->gdma_sq->id); - err = ENOMEM; - goto out; - } - snprintf(txq->txq_mtx_name, nitems(txq->txq_mtx_name), "mana:tx(%d)", i); @@ -2156,13 +2135,6 @@ mana_create_txq(struct mana_port_context *apc, if_t net) txq->txq_br = buf_ring_alloc(4 * MAX_SEND_BUFFERS_PER_QUEUE, M_DEVBUF, M_WAITOK, &txq->txq_mtx); - if (unlikely(txq->txq_br == NULL)) { - if_printf(net, - "Failed to allocate buf ring for SQ %u\n", - txq->gdma_sq->id); - err = ENOMEM; - goto out; - } /* Allocate taskqueue for deferred send */ TASK_INIT(&txq->enqueue_task, 0, mana_xmit_taskfunc, txq); @@ -2353,9 +2325,6 @@ mana_create_rxq(struct mana_port_context *apc, uint32_t rxq_idx, rxq = malloc(sizeof(*rxq) + RX_BUFFERS_PER_QUEUE * sizeof(struct mana_recv_buf_oob), M_DEVBUF, M_WAITOK | M_ZERO); - if (!rxq) - return NULL; - rxq->ndev = ndev; rxq->num_rx_buf = RX_BUFFERS_PER_QUEUE; rxq->rxq_idx = rxq_idx; @@ -2808,12 +2777,6 @@ mana_probe_port(struct mana_context *ac, int port_idx, *ndev_storage = ndev; apc = malloc(sizeof(*apc), M_DEVBUF, M_WAITOK | M_ZERO); - if (!apc) { - mana_err(NULL, "Failed to allocate port context\n"); - err = ENOMEM; - goto free_net; - } - apc->ac = ac; apc->ndev = ndev; apc->max_queues = gc->max_num_queues; @@ -2892,7 +2855,6 @@ mana_probe_port(struct mana_context *ac, int port_idx, reset_apc: free(apc, M_DEVBUF); -free_net: *ndev_storage = NULL; if_printf(ndev, "Failed to probe vPort %d: %d\n", port_idx, err); if_free(ndev); @@ -2915,9 +2877,6 @@ int mana_probe(struct gdma_dev *gd) return err; ac = malloc(sizeof(*ac), M_DEVBUF, M_WAITOK | M_ZERO); - if (!ac) - return ENOMEM; - ac->gdma_dev = gd; ac->num_ports = 1; gd->driver_data = ac; From 701308ef404f552034f8c3e3e912b41bfef28ee6 Mon Sep 17 00:00:00 2001 From: Zhenlei Huang Date: Tue, 3 Sep 2024 18:25:31 +0800 Subject: [PATCH 065/213] mfi(4): Stop checking for failures from malloc(M_WAITOK) MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D45852 --- sys/dev/mfi/mfi.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/sys/dev/mfi/mfi.c b/sys/dev/mfi/mfi.c index 2885bd695f50..328118ef9596 100644 --- a/sys/dev/mfi/mfi.c +++ b/sys/dev/mfi/mfi.c @@ -3633,11 +3633,8 @@ mfi_linux_ioctl_int(struct cdev *dev, u_long cmd, caddr_t arg, int flag, struct mfi_aen_entry = malloc(sizeof(struct mfi_aen), M_MFIBUF, M_WAITOK); mtx_lock(&sc->mfi_io_lock); - if (mfi_aen_entry != NULL) { - mfi_aen_entry->p = curproc; - TAILQ_INSERT_TAIL(&sc->mfi_aen_pids, mfi_aen_entry, - aen_link); - } + mfi_aen_entry->p = curproc; + TAILQ_INSERT_TAIL(&sc->mfi_aen_pids, mfi_aen_entry, aen_link); error = mfi_aen_register(sc, l_aen.laen_seq_num, l_aen.laen_class_locale); From 556cd18fb07604e3442819b221afb2a19b924dbd Mon Sep 17 00:00:00 2001 From: Zhenlei Huang Date: Tue, 3 Sep 2024 18:25:31 +0800 Subject: [PATCH 066/213] mlx(4): Stop checking for failures from malloc(M_WAITOK) MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D45852 --- sys/dev/mlx/mlx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/dev/mlx/mlx.c b/sys/dev/mlx/mlx.c index 8e86a00222da..7e4cb443894a 100644 --- a/sys/dev/mlx/mlx.c +++ b/sys/dev/mlx/mlx.c @@ -2075,8 +2075,8 @@ mlx_user_command(struct mlx_softc *sc, struct mlx_usercommand *mu) goto out; } MLX_IO_UNLOCK(sc); - if (((kbuf = malloc(mu->mu_datasize, M_DEVBUF, M_WAITOK)) == NULL) || - (error = copyin(mu->mu_buf, kbuf, mu->mu_datasize))) { + kbuf = malloc(mu->mu_datasize, M_DEVBUF, M_WAITOK); + if ((error = copyin(mu->mu_buf, kbuf, mu->mu_datasize))) { MLX_IO_LOCK(sc); goto out; } From 849f9ac370bd66993ce5cc6fca0d2ef9bd03c2c9 Mon Sep 17 00:00:00 2001 From: Zhenlei Huang Date: Tue, 3 Sep 2024 18:25:31 +0800 Subject: [PATCH 067/213] mpi3mr(4): Stop checking for failures from malloc(M_WAITOK) MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D45852 --- sys/dev/mpi3mr/mpi3mr_cam.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/sys/dev/mpi3mr/mpi3mr_cam.c b/sys/dev/mpi3mr/mpi3mr_cam.c index e00d61073d96..b4999e204ab7 100644 --- a/sys/dev/mpi3mr/mpi3mr_cam.c +++ b/sys/dev/mpi3mr/mpi3mr_cam.c @@ -2098,12 +2098,6 @@ mpi3mr_cam_attach(struct mpi3mr_softc *sc) mpi3mr_dprint(sc, MPI3MR_XINFO, "Starting CAM Attach\n"); cam_sc = malloc(sizeof(struct mpi3mr_cam_softc), M_MPI3MR, M_WAITOK|M_ZERO); - if (!cam_sc) { - mpi3mr_dprint(sc, MPI3MR_ERROR, - "Failed to allocate memory for controller CAM instance\n"); - return (ENOMEM); - } - cam_sc->maxtargets = sc->facts.max_perids + 1; TAILQ_INIT(&cam_sc->tgt_list); From a38d9ad473123dca86108651ba10740055720777 Mon Sep 17 00:00:00 2001 From: Zhenlei Huang Date: Tue, 3 Sep 2024 18:25:32 +0800 Subject: [PATCH 068/213] mrsas(4): Stop checking for failures from malloc(M_WAITOK) MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D45852 --- sys/dev/mrsas/mrsas_ioctl.c | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/sys/dev/mrsas/mrsas_ioctl.c b/sys/dev/mrsas/mrsas_ioctl.c index 74eacfbeb9fa..8a85544604a4 100644 --- a/sys/dev/mrsas/mrsas_ioctl.c +++ b/sys/dev/mrsas/mrsas_ioctl.c @@ -462,13 +462,6 @@ mrsas_user_command(struct mrsas_softc *sc, struct mfi_ioc_passthru *ioc) kern_sge[0].length = 0; } else { ioctl_temp_data_mem = malloc(ioc->buf_size, M_MRSAS, M_WAITOK); - if (ioctl_temp_data_mem == NULL) { - device_printf(sc->mrsas_dev, "Could not allocate " - "%d memory for temporary passthrough ioctl\n", - ioc->buf_size); - ret = ENOMEM; - goto out; - } /* Copy in data from user space */ ret = copyin(ioc->buf, ioctl_temp_data_mem, ioc->buf_size); @@ -483,12 +476,6 @@ mrsas_user_command(struct mrsas_softc *sc, struct mfi_ioc_passthru *ioc) */ passcmd = malloc(sizeof(struct mrsas_passthru_cmd), M_MRSAS, M_WAITOK); - if (passcmd == NULL) { - device_printf(sc->mrsas_dev, "Could not allocate " - "memory for temporary passthrough cb struct\n"); - ret = ENOMEM; - goto out; - } passcmd->complete = 0; passcmd->sc = sc; passcmd->cmd = cmd; From 4fb8a80a78aa65e0b30bd5a74373512c678841c9 Mon Sep 17 00:00:00 2001 From: Zhenlei Huang Date: Tue, 3 Sep 2024 18:25:32 +0800 Subject: [PATCH 069/213] pms(4): Stop checking for failures from malloc(M_WAITOK) MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D45852 --- sys/dev/pms/freebsd/driver/ini/src/agtiapi.c | 38 +++----------------- 1 file changed, 4 insertions(+), 34 deletions(-) diff --git a/sys/dev/pms/freebsd/driver/ini/src/agtiapi.c b/sys/dev/pms/freebsd/driver/ini/src/agtiapi.c index c8c9eb8c8dd8..cd1b80c3d712 100644 --- a/sys/dev/pms/freebsd/driver/ini/src/agtiapi.c +++ b/sys/dev/pms/freebsd/driver/ini/src/agtiapi.c @@ -318,13 +318,6 @@ int agtiapi_getdevlist( struct agtiapi_softc *pCard, sizeof(void *) ); AGTIAPI_PRINTK("agtiapi_getdevlist: portCount %d\n", pCard->portCount); devList = malloc(memNeeded1, TEMP2, M_WAITOK); - if (devList == NULL) - { - AGTIAPI_PRINTK("agtiapi_getdevlist: failed to allocate memory\n"); - ret_val = IOCTL_CALL_FAIL; - agIOCTLPayload->Status = IOCTL_ERR_STATUS_INTERNAL_ERROR; - return ret_val; - } osti_memset(devList, 0, memNeeded1); pPortalData = &pCard->pPortalData[0]; pDeviceHandleList = (bit8*)devList; @@ -970,13 +963,8 @@ static int agtiapi_attach( device_t devx ) } else { - pmsc->pPortalData = (ag_portal_data_t *) - malloc( sizeof(ag_portal_data_t) * pmsc->portCount, + pmsc->pPortalData = malloc( sizeof(ag_portal_data_t) * pmsc->portCount, M_PMC_MPRT, M_ZERO | M_WAITOK ); - if (pmsc->pPortalData == NULL) - { - AGTIAPI_PRINTK( "agtiapi_attach: Portal memory allocation ERROR\n" ); - } } pPortalData = pmsc->pPortalData; @@ -1227,32 +1215,14 @@ STATIC agBOOLEAN agtiapi_InitCardHW( struct agtiapi_softc *pmsc ) pmsc->flags |= AGTIAPI_SYS_INTR_ON; numVal = sizeof(ag_device_t) * pmsc->devDiscover; - pmsc->pDevList = - (ag_device_t *)malloc( numVal, M_PMC_MDVT, M_ZERO | M_WAITOK ); - if( !pmsc->pDevList ) { - AGTIAPI_PRINTK( "agtiapi_InitCardHW: kmalloc %d DevList ERROR\n", numVal ); - panic( "agtiapi_InitCardHW\n" ); - return AGTIAPI_FAIL; - } + pmsc->pDevList = malloc( numVal, M_PMC_MDVT, M_ZERO | M_WAITOK ); #ifdef LINUX_PERBI_SUPPORT numVal = sizeof(ag_slr_map_t) * pmsc->devDiscover; - pmsc->pSLRList = - (ag_slr_map_t *)malloc( numVal, M_PMC_MSLR, M_ZERO | M_WAITOK ); - if( !pmsc->pSLRList ) { - AGTIAPI_PRINTK( "agtiapi_InitCardHW: kmalloc %d SLRList ERROR\n", numVal ); - panic( "agtiapi_InitCardHW SLRL\n" ); - return AGTIAPI_FAIL; - } + pmsc->pSLRList = malloc( numVal, M_PMC_MSLR, M_ZERO | M_WAITOK ); numVal = sizeof(ag_tgt_map_t) * pmsc->devDiscover; - pmsc->pWWNList = - (ag_tgt_map_t *)malloc( numVal, M_PMC_MTGT, M_ZERO | M_WAITOK ); - if( !pmsc->pWWNList ) { - AGTIAPI_PRINTK( "agtiapi_InitCardHW: kmalloc %d WWNList ERROR\n", numVal ); - panic( "agtiapi_InitCardHW WWNL\n" ); - return AGTIAPI_FAIL; - } + pmsc->pWWNList = malloc( numVal, M_PMC_MTGT, M_ZERO | M_WAITOK ); // Get the WWN_to_target_ID mappings from the // holding area which contains the input of the From 866dc4bd81398b478daefe4b7447b92422b4a06c Mon Sep 17 00:00:00 2001 From: Zhenlei Huang Date: Tue, 3 Sep 2024 18:25:32 +0800 Subject: [PATCH 070/213] qat(4): Stop checking for failures from malloc(M_WAITOK) MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D45852 --- sys/dev/qat/qat_common/adf_freebsd_dev_processes.c | 8 -------- sys/dev/qat/qat_common/adf_freebsd_uio.c | 8 -------- sys/dev/qat/qat_common/adf_freebsd_uio_cleanup.c | 3 --- sys/dev/qat/qat_hw/qat_4xxxvf/adf_drv.c | 5 ----- 4 files changed, 24 deletions(-) diff --git a/sys/dev/qat/qat_common/adf_freebsd_dev_processes.c b/sys/dev/qat/qat_common/adf_freebsd_dev_processes.c index b8a17344bdea..a70f25d57dcb 100644 --- a/sys/dev/qat/qat_common/adf_freebsd_dev_processes.c +++ b/sys/dev/qat/qat_common/adf_freebsd_dev_processes.c @@ -146,8 +146,6 @@ adf_processes_open(struct cdev *dev, int oflags, int devtype, struct thread *td) return ENXIO; } prv_data = malloc(sizeof(*prv_data), M_QAT, M_WAITOK | M_ZERO); - if (!prv_data) - return ENOMEM; INIT_LIST_HEAD(&prv_data->list); error = devfs_set_cdevpriv(prv_data, adf_processes_release); if (error) { @@ -573,14 +571,8 @@ adf_state_open(struct cdev *dev, int oflags, int devtype, struct thread *td) int ret = 0; prv_data = malloc(sizeof(*prv_data), M_QAT, M_WAITOK | M_ZERO); - if (!prv_data) - return -ENOMEM; entry_proc_events = malloc(sizeof(struct entry_proc_events), M_QAT, M_WAITOK | M_ZERO); - if (!entry_proc_events) { - free(prv_data, M_QAT); - return -ENOMEM; - } mtx_lock(&mtx); prv_data->cdev = dev; prv_data->cdev->si_drv1 = prv_data; diff --git a/sys/dev/qat/qat_common/adf_freebsd_uio.c b/sys/dev/qat/qat_common/adf_freebsd_uio.c index c109fc79b0f4..64efde72b4b8 100644 --- a/sys/dev/qat/qat_common/adf_freebsd_uio.c +++ b/sys/dev/qat/qat_common/adf_freebsd_uio.c @@ -199,10 +199,6 @@ adf_alloc_bundle(struct adf_accel_dev *accel_dev, int bundle_nr) accel = accel_dev->accel; handle = malloc(sizeof(*handle), M_QAT, M_WAITOK | M_ZERO); - if (!handle) { - printf("ERROR in adf_alloc_bundle %d\n", __LINE__); - return ENOMEM; - } handle->accel = accel; handle->bundle = bundle_nr; @@ -294,10 +290,6 @@ adf_uio_mmap_single(struct cdev *dev, /* Adding pid to bundle list */ instance_rings = malloc(sizeof(*instance_rings), M_QAT, M_WAITOK | M_ZERO); - if (!instance_rings) { - printf("QAT: Memory allocation error - line: %d\n", __LINE__); - return -ENOMEM; - } instance_rings->user_pid = curproc->p_pid; instance_rings->ring_mask = 0; mutex_lock(&bundle->list_lock); diff --git a/sys/dev/qat/qat_common/adf_freebsd_uio_cleanup.c b/sys/dev/qat/qat_common/adf_freebsd_uio_cleanup.c index 6fb4cf0bf2f7..954e31c683ce 100644 --- a/sys/dev/qat/qat_common/adf_freebsd_uio_cleanup.c +++ b/sys/dev/qat/qat_common/adf_freebsd_uio_cleanup.c @@ -123,9 +123,6 @@ get_orphan_bundle(int bank, orphan_bundle = malloc(sizeof(*orphan_bundle), M_QAT, M_WAITOK | M_ZERO); - if (!orphan_bundle) - return ENOMEM; - csr_base = accel->bar->virt_addr; orphan_bundle->csr_base = csr_base; orphan_bundle->bank = bank; diff --git a/sys/dev/qat/qat_hw/qat_4xxxvf/adf_drv.c b/sys/dev/qat/qat_hw/qat_4xxxvf/adf_drv.c index 05a99ae43ab7..9b66ae4b2370 100644 --- a/sys/dev/qat/qat_hw/qat_4xxxvf/adf_drv.c +++ b/sys/dev/qat/qat_hw/qat_4xxxvf/adf_drv.c @@ -117,11 +117,6 @@ adf_attach(device_t dev) } /* Allocate and configure device configuration structure */ hw_data = malloc(sizeof(*hw_data), M_QAT_4XXXVF, M_WAITOK | M_ZERO); - if (!hw_data) { - ret = -ENOMEM; - goto out_err; - } - accel_dev->hw_device = hw_data; adf_init_hw_data_4xxxiov(accel_dev->hw_device); accel_pci_dev->revid = pci_get_revid(dev); From 761339c5544a360df9d3bab70675fea246eb6a83 Mon Sep 17 00:00:00 2001 From: Zhenlei Huang Date: Tue, 3 Sep 2024 18:25:33 +0800 Subject: [PATCH 071/213] sume(4): Stop checking for failures from malloc(M_WAITOK) MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D45852 --- sys/dev/sume/if_sume.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/sys/dev/sume/if_sume.c b/sys/dev/sume/if_sume.c index 319853ac3c7a..7b2a27135e43 100644 --- a/sys/dev/sume/if_sume.c +++ b/sys/dev/sume/if_sume.c @@ -1195,16 +1195,11 @@ sume_probe_riffa_buffer(const struct sume_adapter *adapter, { struct riffa_chnl_dir **rp; bus_addr_t hw_addr; - int error, ch; + int ch; device_t dev = adapter->dev; - error = ENOMEM; *p = malloc(SUME_RIFFA_CHANNELS * sizeof(struct riffa_chnl_dir *), M_SUME, M_ZERO | M_WAITOK); - if (*p == NULL) { - device_printf(dev, "malloc(%s) failed.\n", dir); - return (error); - } rp = *p; /* Allocate the chnl_dir structs themselves. */ @@ -1212,11 +1207,6 @@ sume_probe_riffa_buffer(const struct sume_adapter *adapter, /* One direction. */ rp[ch] = malloc(sizeof(struct riffa_chnl_dir), M_SUME, M_ZERO | M_WAITOK); - if (rp[ch] == NULL) { - device_printf(dev, "malloc(%s[%d]) riffa_chnl_dir " - "failed.\n", dir, ch); - return (error); - } int err = bus_dma_tag_create(bus_get_dma_tag(dev), 4, 0, From 59121599bbda1e4c3fc3c6e887cd48cd5e3afc70 Mon Sep 17 00:00:00 2001 From: Zhenlei Huang Date: Tue, 3 Sep 2024 18:25:33 +0800 Subject: [PATCH 072/213] sound: Stop checking for failures from malloc(M_WAITOK) Reviewed by: emaste MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D45852 --- sys/dev/sound/macio/i2s.c | 6 ++---- sys/dev/sound/usb/uaudio.c | 44 ++++++++++++++++---------------------- 2 files changed, 21 insertions(+), 29 deletions(-) diff --git a/sys/dev/sound/macio/i2s.c b/sys/dev/sound/macio/i2s.c index 5f8cb3aa15f7..647d66c27bba 100644 --- a/sys/dev/sound/macio/i2s.c +++ b/sys/dev/sound/macio/i2s.c @@ -241,10 +241,8 @@ i2s_attach(device_t self) * Register a hook for delayed attach in order to allow * the I2C controller to attach. */ - if ((i2s_delayed_attach = malloc(sizeof(struct intr_config_hook), - M_TEMP, M_WAITOK | M_ZERO)) == NULL) - return (ENOMEM); - + i2s_delayed_attach = malloc(sizeof(struct intr_config_hook), + M_TEMP, M_WAITOK | M_ZERO); i2s_delayed_attach->ich_func = i2s_postattach; i2s_delayed_attach->ich_arg = sc; diff --git a/sys/dev/sound/usb/uaudio.c b/sys/dev/sound/usb/uaudio.c index 166af8a0857d..0a8878c072d2 100644 --- a/sys/dev/sound/usb/uaudio.c +++ b/sys/dev/sound/usb/uaudio.c @@ -2687,8 +2687,6 @@ uaudio_chan_init(struct uaudio_chan *ch, struct snd_dbuf *b, DPRINTF("Worst case buffer is %d bytes\n", (int)buf_size); ch->buf = malloc(buf_size, M_DEVBUF, M_WAITOK | M_ZERO); - if (ch->buf == NULL) - goto error; if (sndbuf_setup(b, ch->buf, buf_size) != 0) goto error; @@ -3256,31 +3254,27 @@ uaudio_mixer_add_ctl_sub(struct uaudio_softc *sc, struct uaudio_mixer_node *mc) malloc(sizeof(*p_mc_new), M_USBDEV, M_WAITOK); int ch; - if (p_mc_new != NULL) { - memcpy(p_mc_new, mc, sizeof(*p_mc_new)); - p_mc_new->next = sc->sc_mixer_root; - sc->sc_mixer_root = p_mc_new; - sc->sc_mixer_count++; + memcpy(p_mc_new, mc, sizeof(*p_mc_new)); + p_mc_new->next = sc->sc_mixer_root; + sc->sc_mixer_root = p_mc_new; + sc->sc_mixer_count++; - /* set default value for all channels */ - for (ch = 0; ch < p_mc_new->nchan; ch++) { - switch (p_mc_new->val_default) { - case 1: - /* 50% */ - p_mc_new->wData[ch] = (p_mc_new->maxval + p_mc_new->minval) / 2; - break; - case 2: - /* 100% */ - p_mc_new->wData[ch] = p_mc_new->maxval; - break; - default: - /* 0% */ - p_mc_new->wData[ch] = p_mc_new->minval; - break; - } + /* set default value for all channels */ + for (ch = 0; ch < p_mc_new->nchan; ch++) { + switch (p_mc_new->val_default) { + case 1: + /* 50% */ + p_mc_new->wData[ch] = (p_mc_new->maxval + p_mc_new->minval) / 2; + break; + case 2: + /* 100% */ + p_mc_new->wData[ch] = p_mc_new->maxval; + break; + default: + /* 0% */ + p_mc_new->wData[ch] = p_mc_new->minval; + break; } - } else { - DPRINTF("out of memory\n"); } } From f80483cdd58a032ae2cfb2b9119824e9badc2c91 Mon Sep 17 00:00:00 2001 From: Zhenlei Huang Date: Tue, 3 Sep 2024 18:25:34 +0800 Subject: [PATCH 073/213] sdhci(4): Stop checking for failures from malloc(M_WAITOK) MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D45852 --- sys/dev/sdhci/sdhci_xenon_acpi.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/sys/dev/sdhci/sdhci_xenon_acpi.c b/sys/dev/sdhci/sdhci_xenon_acpi.c index 01b6c14dc5f2..3e8b2c4a349c 100644 --- a/sys/dev/sdhci/sdhci_xenon_acpi.c +++ b/sys/dev/sdhci/sdhci_xenon_acpi.c @@ -86,8 +86,6 @@ sdhci_xenon_acpi_attach(device_t dev) memset(&mmc_helper, 0, sizeof(mmc_helper)); slot = malloc(sizeof(*slot), M_DEVBUF, M_ZERO | M_WAITOK); - if (!slot) - return (ENOMEM); /* * Don't use regularators. From 778ea7ed5a23db9c4f9d8dc43a5cea26ded6231c Mon Sep 17 00:00:00 2001 From: Zhenlei Huang Date: Tue, 3 Sep 2024 18:25:34 +0800 Subject: [PATCH 074/213] vchiq(4): Stop checking for failures from malloc(M_WAITOK) MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D45852 --- sys/contrib/vchiq/interface/vchiq_arm/vchiq_2835_arm.c | 2 -- 1 file changed, 2 deletions(-) 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 279aacd0880a..ab8981e25cb2 100644 --- a/sys/contrib/vchiq/interface/vchiq_arm/vchiq_2835_arm.c +++ b/sys/contrib/vchiq/interface/vchiq_arm/vchiq_2835_arm.c @@ -278,8 +278,6 @@ vchiq_prepare_bulk_data(VCHIQ_BULK_T *bulk, VCHI_MEM_HANDLE_T memhandle, WARN_ON(memhandle != VCHI_MEM_HANDLE_INVALID); bi = malloc(sizeof(*bi), M_VCPAGELIST, M_WAITOK | M_ZERO); - if (bi == NULL) - return VCHIQ_ERROR; ret = create_pagelist((char __user *)offset, size, (dir == VCHIQ_BULK_RECEIVE) From 3f3f3ca25bc453315c6a1f5d16bfcc1189d41bdd Mon Sep 17 00:00:00 2001 From: Zhenlei Huang Date: Tue, 3 Sep 2024 18:25:34 +0800 Subject: [PATCH 075/213] ae(4): Stop checking for failures from taskqueue_create_fast(M_WAITOK) MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D45853 --- sys/dev/ae/if_ae.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/sys/dev/ae/if_ae.c b/sys/dev/ae/if_ae.c index e424e1bd0e76..adbb3e48a4e3 100644 --- a/sys/dev/ae/if_ae.c +++ b/sys/dev/ae/if_ae.c @@ -362,12 +362,6 @@ ae_attach(device_t dev) */ sc->tq = taskqueue_create_fast("ae_taskq", M_WAITOK, taskqueue_thread_enqueue, &sc->tq); - if (sc->tq == NULL) { - device_printf(dev, "could not create taskqueue.\n"); - ether_ifdetach(ifp); - error = ENXIO; - goto fail; - } taskqueue_start_threads(&sc->tq, 1, PI_NET, "%s taskq", device_get_nameunit(sc->dev)); From 5cece2c24bfa618091e778df488fb2380fcecafe Mon Sep 17 00:00:00 2001 From: Zhenlei Huang Date: Tue, 3 Sep 2024 18:25:35 +0800 Subject: [PATCH 076/213] age(4): Stop checking for failures from taskqueue_create_fast(M_WAITOK) MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D45853 --- sys/dev/age/if_age.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/sys/dev/age/if_age.c b/sys/dev/age/if_age.c index 6630f2cf782d..10f99129401a 100644 --- a/sys/dev/age/if_age.c +++ b/sys/dev/age/if_age.c @@ -628,12 +628,6 @@ age_attach(device_t dev) /* Create local taskq. */ sc->age_tq = taskqueue_create_fast("age_taskq", M_WAITOK, taskqueue_thread_enqueue, &sc->age_tq); - if (sc->age_tq == NULL) { - device_printf(dev, "could not create taskqueue.\n"); - ether_ifdetach(ifp); - error = ENXIO; - goto fail; - } taskqueue_start_threads(&sc->age_tq, 1, PI_NET, "%s taskq", device_get_nameunit(sc->age_dev)); From 0cd3976d076218ea10761dc3f38ecf8549768ad5 Mon Sep 17 00:00:00 2001 From: Zhenlei Huang Date: Tue, 3 Sep 2024 18:25:35 +0800 Subject: [PATCH 077/213] alc(4): Stop checking for failures from taskqueue_create_fast(M_WAITOK) MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D45853 --- sys/dev/alc/if_alc.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/sys/dev/alc/if_alc.c b/sys/dev/alc/if_alc.c index 859d1214b46a..07ba02c33c88 100644 --- a/sys/dev/alc/if_alc.c +++ b/sys/dev/alc/if_alc.c @@ -1639,12 +1639,6 @@ alc_attach(device_t dev) /* Create local taskq. */ sc->alc_tq = taskqueue_create_fast("alc_taskq", M_WAITOK, taskqueue_thread_enqueue, &sc->alc_tq); - if (sc->alc_tq == NULL) { - device_printf(dev, "could not create taskqueue.\n"); - ether_ifdetach(ifp); - error = ENXIO; - goto fail; - } taskqueue_start_threads(&sc->alc_tq, 1, PI_NET, "%s taskq", device_get_nameunit(sc->alc_dev)); From f5524be39e26e3d7fb774ffe7711602c676a8b9e Mon Sep 17 00:00:00 2001 From: Zhenlei Huang Date: Tue, 3 Sep 2024 18:25:35 +0800 Subject: [PATCH 078/213] ale(4): Stop checking for failures from taskqueue_create_fast(M_WAITOK) MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D45853 --- sys/dev/ale/if_ale.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/sys/dev/ale/if_ale.c b/sys/dev/ale/if_ale.c index 5b3ae438810c..e4d61e636f8b 100644 --- a/sys/dev/ale/if_ale.c +++ b/sys/dev/ale/if_ale.c @@ -655,12 +655,6 @@ ale_attach(device_t dev) /* Create local taskq. */ sc->ale_tq = taskqueue_create_fast("ale_taskq", M_WAITOK, taskqueue_thread_enqueue, &sc->ale_tq); - if (sc->ale_tq == NULL) { - device_printf(dev, "could not create taskqueue.\n"); - ether_ifdetach(ifp); - error = ENXIO; - goto fail; - } taskqueue_start_threads(&sc->ale_tq, 1, PI_NET, "%s taskq", device_get_nameunit(sc->ale_dev)); From b29adaaf44f6cf9433c782bbeeefd12d74d395a5 Mon Sep 17 00:00:00 2001 From: Zhenlei Huang Date: Tue, 3 Sep 2024 18:25:36 +0800 Subject: [PATCH 079/213] axgbe: Stop checking for failures from taskqueue_create(M_WAITOK) MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D45853 --- sys/dev/axgbe/if_axgbe_pci.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/sys/dev/axgbe/if_axgbe_pci.c b/sys/dev/axgbe/if_axgbe_pci.c index 320799e77188..d3078a1c33c1 100644 --- a/sys/dev/axgbe/if_axgbe_pci.c +++ b/sys/dev/axgbe/if_axgbe_pci.c @@ -561,11 +561,6 @@ axgbe_if_attach_pre(if_ctx_t ctx) /* create the workqueue */ pdata->dev_workqueue = taskqueue_create("axgbe", M_WAITOK, taskqueue_thread_enqueue, &pdata->dev_workqueue); - if (pdata->dev_workqueue == NULL) { - axgbe_error("Unable to allocate workqueue\n"); - ret = ENOMEM; - goto free_channels; - } ret = taskqueue_start_threads(&pdata->dev_workqueue, 1, PI_NET, "axgbe dev taskq"); if (ret) { @@ -581,8 +576,6 @@ axgbe_if_attach_pre(if_ctx_t ctx) free_task_queue: taskqueue_free(pdata->dev_workqueue); - -free_channels: axgbe_free_channels(sc); release_bus_resource: From d44bc2f07b971fe1f451a1fff0389650a2502422 Mon Sep 17 00:00:00 2001 From: Zhenlei Huang Date: Tue, 3 Sep 2024 18:25:36 +0800 Subject: [PATCH 080/213] bge(4): Stop checking for failures from taskqueue_create_fast(M_WAITOK) MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D45853 --- sys/dev/bge/if_bge.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/sys/dev/bge/if_bge.c b/sys/dev/bge/if_bge.c index 23259179cc62..6c3301b1473a 100644 --- a/sys/dev/bge/if_bge.c +++ b/sys/dev/bge/if_bge.c @@ -3890,12 +3890,6 @@ bge_attach(device_t dev) ~BGE_MSIMODE_ONE_SHOT_DISABLE); sc->bge_tq = taskqueue_create_fast("bge_taskq", M_WAITOK, taskqueue_thread_enqueue, &sc->bge_tq); - if (sc->bge_tq == NULL) { - device_printf(dev, "could not create taskqueue.\n"); - ether_ifdetach(ifp); - error = ENOMEM; - goto fail; - } error = taskqueue_start_threads(&sc->bge_tq, 1, PI_NET, "%s taskq", device_get_nameunit(sc->bge_dev)); if (error != 0) { From af28fc3c191cf572f7def767c60fff59d48947df Mon Sep 17 00:00:00 2001 From: Zhenlei Huang Date: Tue, 3 Sep 2024 18:25:37 +0800 Subject: [PATCH 081/213] cas(4): Stop checking for failures from taskqueue_create_fast(M_WAITOK) MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D45853 --- sys/dev/cas/if_cas.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/sys/dev/cas/if_cas.c b/sys/dev/cas/if_cas.c index 76d1b713e5bb..1f684097bd3a 100644 --- a/sys/dev/cas/if_cas.c +++ b/sys/dev/cas/if_cas.c @@ -205,11 +205,6 @@ cas_attach(struct cas_softc *sc) TASK_INIT(&sc->sc_tx_task, 1, cas_tx_task, ifp); sc->sc_tq = taskqueue_create_fast("cas_taskq", M_WAITOK, taskqueue_thread_enqueue, &sc->sc_tq); - if (sc->sc_tq == NULL) { - device_printf(sc->sc_dev, "could not create taskqueue\n"); - error = ENXIO; - goto fail_ifnet; - } error = taskqueue_start_threads(&sc->sc_tq, 1, PI_NET, "%s taskq", device_get_nameunit(sc->sc_dev)); if (error != 0) { @@ -462,7 +457,6 @@ cas_attach(struct cas_softc *sc) bus_dma_tag_destroy(sc->sc_pdmatag); fail_taskq: taskqueue_free(sc->sc_tq); - fail_ifnet: if_free(ifp); return (error); } From 36ef39831fe0e89f0b1672340a44c4ac1183158e Mon Sep 17 00:00:00 2001 From: Zhenlei Huang Date: Tue, 3 Sep 2024 18:25:37 +0800 Subject: [PATCH 082/213] dpaa2: Stop checking for failures from malloc/taskqueue_create(M_WAITOK) MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D45853 --- sys/dev/dpaa2/dpaa2_channel.c | 7 ------- sys/dev/dpaa2/dpaa2_mc.c | 2 -- sys/dev/dpaa2/dpaa2_ni.c | 15 --------------- 3 files changed, 24 deletions(-) diff --git a/sys/dev/dpaa2/dpaa2_channel.c b/sys/dev/dpaa2/dpaa2_channel.c index 87b76923a16d..654c6f2baf70 100644 --- a/sys/dev/dpaa2/dpaa2_channel.c +++ b/sys/dev/dpaa2/dpaa2_channel.c @@ -146,12 +146,6 @@ dpaa2_chan_setup(device_t dev, device_t iodev, device_t condev, device_t bpdev, } ch = malloc(sizeof(struct dpaa2_channel), M_DPAA2_CH, M_WAITOK | M_ZERO); - if (ch == NULL) { - device_printf(dev, "%s: malloc() failed\n", __func__); - error = ENOMEM; - goto fail_malloc; - } - ch->ni_dev = dev; ch->io_dev = iodev; ch->con_dev = condev; @@ -281,7 +275,6 @@ dpaa2_chan_setup(device_t dev, device_t iodev, device_t condev, device_t bpdev, /* taskqueue_drain(ch->cleanup_tq, &ch->cleanup_task); */ /* } */ /* taskqueue_free(ch->cleanup_tq); */ -fail_malloc: (void)DPAA2_CMD_CON_DISABLE(dev, child, DPAA2_CMD_TK(&cmd, contk)); fail_con_enable: (void)DPAA2_CMD_CON_CLOSE(dev, child, DPAA2_CMD_TK(&cmd, contk)); diff --git a/sys/dev/dpaa2/dpaa2_mc.c b/sys/dev/dpaa2/dpaa2_mc.c index 66867a18068c..da8f8a077d6b 100644 --- a/sys/dev/dpaa2/dpaa2_mc.c +++ b/sys/dev/dpaa2/dpaa2_mc.c @@ -462,8 +462,6 @@ dpaa2_mc_manage_dev(device_t mcdev, device_t dpaa2_dev, uint32_t flags) return (EINVAL); di = malloc(sizeof(*di), M_DPAA2_MC, M_WAITOK | M_ZERO); - if (!di) - return (ENOMEM); di->dpaa2_dev = dpaa2_dev; di->flags = flags; di->owners = 0; diff --git a/sys/dev/dpaa2/dpaa2_ni.c b/sys/dev/dpaa2/dpaa2_ni.c index a21351a20b49..6ed656849709 100644 --- a/sys/dev/dpaa2/dpaa2_ni.c +++ b/sys/dev/dpaa2/dpaa2_ni.c @@ -588,11 +588,6 @@ dpaa2_ni_attach(device_t dev) /* Create a taskqueue thread to release new buffers to the pool. */ sc->bp_taskq = taskqueue_create(tq_name, M_WAITOK, taskqueue_thread_enqueue, &sc->bp_taskq); - if (sc->bp_taskq == NULL) { - device_printf(dev, "%s: failed to allocate task queue: %s\n", - __func__, tq_name); - goto close_ni; - } taskqueue_start_threads(&sc->bp_taskq, 1, PI_NET, "%s", tq_name); /* sc->cleanup_taskq = taskqueue_create("dpaa2_ch cleanup", M_WAITOK, */ @@ -1339,21 +1334,11 @@ dpaa2_ni_setup_tx_flow(device_t dev, struct dpaa2_ni_fq *fq) for (uint64_t j = 0; j < DPAA2_NI_BUFS_PER_TX; j++) { buf = malloc(sizeof(struct dpaa2_buf), M_DPAA2_TXB, M_WAITOK); - if (buf == NULL) { - device_printf(dev, "%s: malloc() failed (buf)\n", - __func__); - return (ENOMEM); - } /* Keep DMA tag and Tx ring linked to the buffer */ DPAA2_BUF_INIT_TAGOPT(buf, ch->tx_dmat, tx); buf->sgt = malloc(sizeof(struct dpaa2_buf), M_DPAA2_TXB, M_WAITOK); - if (buf->sgt == NULL) { - device_printf(dev, "%s: malloc() failed (sgt)\n", - __func__); - return (ENOMEM); - } /* Link SGT to DMA tag and back to its Tx buffer */ DPAA2_BUF_INIT_TAGOPT(buf->sgt, ch->sgt_dmat, buf); From 3fdef8e855027d5c9bec06e2a53e8f99f7d5694b Mon Sep 17 00:00:00 2001 From: Zhenlei Huang Date: Tue, 3 Sep 2024 18:25:38 +0800 Subject: [PATCH 083/213] jme(4): Stop checking for failures from taskqueue_create_fast(M_WAITOK) MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D45853 --- sys/dev/jme/if_jme.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/sys/dev/jme/if_jme.c b/sys/dev/jme/if_jme.c index 96824e2d7f27..4f739ec26347 100644 --- a/sys/dev/jme/if_jme.c +++ b/sys/dev/jme/if_jme.c @@ -872,12 +872,6 @@ jme_attach(device_t dev) /* Create local taskq. */ sc->jme_tq = taskqueue_create_fast("jme_taskq", M_WAITOK, taskqueue_thread_enqueue, &sc->jme_tq); - if (sc->jme_tq == NULL) { - device_printf(dev, "could not create taskqueue.\n"); - ether_ifdetach(ifp); - error = ENXIO; - goto fail; - } taskqueue_start_threads(&sc->jme_tq, 1, PI_NET, "%s taskq", device_get_nameunit(sc->jme_dev)); From 57cd8f27b727e7a87312f6f141cfa13807dc81a0 Mon Sep 17 00:00:00 2001 From: Zhenlei Huang Date: Tue, 3 Sep 2024 18:25:38 +0800 Subject: [PATCH 084/213] liquidio(4): Stop checking for failures from malloc/taskqueue_create/buf_ring_alloc(M_WAITOK) MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D45853 --- sys/dev/liquidio/base/lio_request_manager.c | 9 --------- sys/dev/liquidio/base/lio_response_manager.c | 4 ---- sys/dev/liquidio/lio_main.c | 4 ---- sys/dev/liquidio/lio_sysctl.c | 3 --- 4 files changed, 20 deletions(-) diff --git a/sys/dev/liquidio/base/lio_request_manager.c b/sys/dev/liquidio/base/lio_request_manager.c index f4eae0c8bf31..95eac12ecf3b 100644 --- a/sys/dev/liquidio/base/lio_request_manager.c +++ b/sys/dev/liquidio/base/lio_request_manager.c @@ -159,11 +159,6 @@ lio_init_instr_queue(struct octeon_device *oct, union octeon_txpciq txpciq, db_tq = &oct->check_db_tq[iq_no]; db_tq->tq = taskqueue_create("lio_check_db_timeout", M_WAITOK, taskqueue_thread_enqueue, &db_tq->tq); - if (db_tq->tq == NULL) { - lio_dev_err(oct, "check db wq create failed for iq %d\n", - iq_no); - return (1); - } TIMEOUT_TASK_INIT(db_tq->tq, &db_tq->work, 0, lio_check_db_timeout, (void *)db_tq); @@ -179,10 +174,6 @@ lio_init_instr_queue(struct octeon_device *oct, union octeon_txpciq txpciq, oct->instr_queue[iq_no]->br = buf_ring_alloc(LIO_BR_SIZE, M_DEVBUF, M_WAITOK, &oct->instr_queue[iq_no]->enq_lock); - if (oct->instr_queue[iq_no]->br == NULL) { - lio_dev_err(oct, "Critical Failure setting up buf ring\n"); - return (1); - } return (0); } diff --git a/sys/dev/liquidio/base/lio_response_manager.c b/sys/dev/liquidio/base/lio_response_manager.c index 12a3ad60521e..ac5fc6229885 100644 --- a/sys/dev/liquidio/base/lio_response_manager.c +++ b/sys/dev/liquidio/base/lio_response_manager.c @@ -59,10 +59,6 @@ lio_setup_response_list(struct octeon_device *oct) ctq = &oct->dma_comp_tq; ctq->tq = taskqueue_create("lio_dma_comp", M_WAITOK, taskqueue_thread_enqueue, &ctq->tq); - if (ctq->tq == NULL) { - lio_dev_err(oct, "failed to create wq thread\n"); - return (-ENOMEM); - } TIMEOUT_TASK_INIT(ctq->tq, &ctq->work, 0, lio_poll_req_completion, (void *)ctq); diff --git a/sys/dev/liquidio/lio_main.c b/sys/dev/liquidio/lio_main.c index 7104ff07674f..3c73a6b10eed 100644 --- a/sys/dev/liquidio/lio_main.c +++ b/sys/dev/liquidio/lio_main.c @@ -1854,10 +1854,6 @@ lio_setup_rx_oom_poll_fn(if_t ifp) rx_status_tq->tq = taskqueue_create("lio_rx_oom_status", M_WAITOK, taskqueue_thread_enqueue, &rx_status_tq->tq); - if (rx_status_tq->tq == NULL) { - lio_dev_err(oct, "unable to create lio rx oom status tq\n"); - return (-1); - } TIMEOUT_TASK_INIT(rx_status_tq->tq, &rx_status_tq->work, 0, lio_poll_check_rx_oom_status, (void *)rx_status_tq); diff --git a/sys/dev/liquidio/lio_sysctl.c b/sys/dev/liquidio/lio_sysctl.c index 729f4d432274..61a7e96098c8 100644 --- a/sys/dev/liquidio/lio_sysctl.c +++ b/sys/dev/liquidio/lio_sysctl.c @@ -744,9 +744,6 @@ lio_get_regs(SYSCTL_HANDLER_ARGS) regbuf = malloc(sizeof(char) * LIO_REGDUMP_LEN_XXXX, M_DEVBUF, M_WAITOK | M_ZERO); - if (regbuf == NULL) - return (error); - switch (oct->chip_id) { case LIO_CN23XX_PF_VID: len += lio_cn23xx_pf_read_csr_reg(regbuf, oct); From 7ea3fd3bb5f4039c372fd72aeef004fe12454537 Mon Sep 17 00:00:00 2001 From: Zhenlei Huang Date: Tue, 3 Sep 2024 18:25:38 +0800 Subject: [PATCH 085/213] mxge(4): Stop checking for failures from taskqueue_create(M_WAITOK) MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D45853 --- sys/dev/mxge/if_mxge.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/sys/dev/mxge/if_mxge.c b/sys/dev/mxge/if_mxge.c index 47793232d8d5..f36f41d53b40 100644 --- a/sys/dev/mxge/if_mxge.c +++ b/sys/dev/mxge/if_mxge.c @@ -4615,10 +4615,6 @@ mxge_attach(device_t dev) TASK_INIT(&sc->watchdog_task, 1, mxge_watchdog_task, sc); sc->tq = taskqueue_create("mxge_taskq", M_WAITOK, taskqueue_thread_enqueue, &sc->tq); - if (sc->tq == NULL) { - err = ENOMEM; - goto abort_with_nothing; - } err = bus_dma_tag_create(bus_get_dma_tag(dev), /* parent */ 1, /* alignment */ @@ -4815,7 +4811,6 @@ mxge_attach(device_t dev) taskqueue_free(sc->tq); sc->tq = NULL; } -abort_with_nothing: return err; } From ffaf862df662d507e8dd2667bffcba91e3745fe6 Mon Sep 17 00:00:00 2001 From: Poul-Henning Kamp Date: Tue, 3 Sep 2024 10:44:20 +0000 Subject: [PATCH 086/213] Mention that SILI makes tcopy(1) slow on modern tape drives --- usr.bin/tcopy/tcopy.1 | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/usr.bin/tcopy/tcopy.1 b/usr.bin/tcopy/tcopy.1 index da6a5231a843..f608e0af07e4 100644 --- a/usr.bin/tcopy/tcopy.1 +++ b/usr.bin/tcopy/tcopy.1 @@ -97,6 +97,16 @@ command appeared in .Sh BUGS .Bl -item .It +Modern tape drives may return a SCSI "Incorrect Length Indicator (ILI)" +for reach read with a different block size that what is on the +tape, and that slows things down a lot. +This can be disabled with the +.Xr mt 1 +command: +.Bd -literal -offset indent +$ mt param sili -s 1 +.Ed +.It Writing an image of a tape to a file does not preserve much more than the raw data. Block size(s) and tape EOF marks are lost which would From ad4cf76ec4d4524381350e77b02b9abe24eb4b02 Mon Sep 17 00:00:00 2001 From: Olivier Certner Date: Tue, 3 Sep 2024 12:08:49 +0200 Subject: [PATCH 087/213] bitset: __BIT_FFS_AT(): Fix herald comment, take 2 Remove the reference to the nonexistent 'end' parameter. While here, rephrase a bit. I did the initial comment fix (commit "bitset: Fix __BIT_FFS_AT()'s herald comment", f3ab0d86e8070c73) as part of an experiment introducing macros to operate on ranges of bits in a bitset and subject to a predicate (a generalization of some code used in some pending modifications of the ULE scheduler), which was finally ditched as being too verbose and impractical to use. I however then forgot to remove the reference to 'end'. No functional change. Noted by: emaste Approved by: emaste (mentor) MFC after: 3 days MFC with: f3ab0d86e807 Sponsored by: The FreeBSD Foundation --- sys/sys/bitset.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/sys/sys/bitset.h b/sys/sys/bitset.h index 2b26e8bcdbf9..d7e0b4cd7e41 100644 --- a/sys/sys/bitset.h +++ b/sys/sys/bitset.h @@ -232,9 +232,8 @@ } while (0) /* - * 'start' and 'end' are 0-based bit (runtime) indices. Note that, as for ffs(), - * the returned index is 1-based, 0 being reserved to indicate that no bits are - * set. + * 'start' is a 0-based bit index. By contrast, and as for ffs(), the returned + * index is 1-based, 0 being reserved to indicate that no bits are set. */ #define __BIT_FFS_AT(_s, p, start) __extension__ ({ \ __size_t __i; \ From 83325e7b738ce87d88553585b135b0e7d15997a6 Mon Sep 17 00:00:00 2001 From: Ed Maste Date: Tue, 3 Sep 2024 10:21:46 -0400 Subject: [PATCH 088/213] beep: show error upon failure to open sound device If beep cannot open /dev/dsp provide more information to aid the user in diagnosing a problem. Reviewed by: christos Sponsored by: The FreeBSD Foundation --- usr.bin/beep/beep.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usr.bin/beep/beep.c b/usr.bin/beep/beep.c index 151236b4825b..2696bacfacf4 100644 --- a/usr.bin/beep/beep.c +++ b/usr.bin/beep/beep.c @@ -202,7 +202,7 @@ main(int argc, char **argv) f = open(oss_dev, O_WRONLY); if (f < 0) - errx(1, "Failed to open '%s'", oss_dev); + err(1, "Failed to open '%s'", oss_dev); c = 1; /* mono */ if (ioctl(f, SOUND_PCM_WRITE_CHANNELS, &c) != 0) From 4dabfcb6153868a03d3afb55a27edf00585790b8 Mon Sep 17 00:00:00 2001 From: Poul-Henning Kamp Date: Tue, 3 Sep 2024 16:00:17 +0000 Subject: [PATCH 089/213] Typo. Spotted by: ktullavik --- usr.bin/tcopy/tcopy.1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usr.bin/tcopy/tcopy.1 b/usr.bin/tcopy/tcopy.1 index f608e0af07e4..3f12a807e41e 100644 --- a/usr.bin/tcopy/tcopy.1 +++ b/usr.bin/tcopy/tcopy.1 @@ -98,7 +98,7 @@ command appeared in .Bl -item .It Modern tape drives may return a SCSI "Incorrect Length Indicator (ILI)" -for reach read with a different block size that what is on the +for each read with a different block size that what is on the tape, and that slows things down a lot. This can be disabled with the .Xr mt 1 From f8860353d4f4c25bacdae5bc1cfb7a95edc9bfe0 Mon Sep 17 00:00:00 2001 From: Guy Harris Date: Tue, 3 Sep 2024 14:11:16 -0300 Subject: [PATCH 090/213] tcpdump: ppp: Use the buffer stack for the de-escaping buffer This both saves the buffer for freeing later and saves the packet pointer and snapend to be restored when packet processing is complete, even if an exception is thrown with longjmp. This means that the hex/ASCII printing in pretty_print_packet() processes the packet data as captured or read from the savefile, rather than as modified by the PPP printer, so that the bounds checking is correct. That fixes CVE-2024-2397, which was caused by an exception being thrown by the hex/ASCII printer (which should only happen if those routines are called by a packet printer, not if they're called for the -X/-x/-A flag), which jumps back to the setjmp() that surrounds the packet printer. Hilarity^Winfinite looping ensues. Also, restore ndo->ndo_packetp before calling the hex/ASCII printing routine, in case nd_pop_all_packet_info() didn't restore it. Reviewed by: emaste --- contrib/tcpdump/print-ppp.c | 31 +++++++++++++++++-------------- contrib/tcpdump/print.c | 8 ++++++-- 2 files changed, 23 insertions(+), 16 deletions(-) diff --git a/contrib/tcpdump/print-ppp.c b/contrib/tcpdump/print-ppp.c index aba243ddb6f2..e5ae0646ebae 100644 --- a/contrib/tcpdump/print-ppp.c +++ b/contrib/tcpdump/print-ppp.c @@ -42,6 +42,8 @@ #include #endif +#include + #include "netdissect.h" #include "extract.h" #include "addrtoname.h" @@ -1363,7 +1365,6 @@ ppp_hdlc(netdissect_options *ndo, u_char *b, *t, c; const u_char *s; u_int i, proto; - const void *sb, *se; if (caplen == 0) return; @@ -1371,9 +1372,11 @@ ppp_hdlc(netdissect_options *ndo, if (length == 0) return; - b = (u_char *)nd_malloc(ndo, caplen); - if (b == NULL) - return; + b = (u_char *)malloc(caplen); + if (b == NULL) { + (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC, + "%s: malloc", __func__); + } /* * Unescape all the data into a temporary, private, buffer. @@ -1394,13 +1397,15 @@ ppp_hdlc(netdissect_options *ndo, } /* - * Change the end pointer, so bounds checks work. - * Change the pointer to packet data to help debugging. + * Switch to the output buffer for dissection, and save it + * on the buffer stack so it can be freed; our caller must + * pop it when done. */ - sb = ndo->ndo_packetp; - se = ndo->ndo_snapend; - ndo->ndo_packetp = b; - ndo->ndo_snapend = t; + if (!nd_push_buffer(ndo, b, b, (u_int)(t - b))) { + free(b); + (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC, + "%s: can't push buffer on buffer stack", __func__); + } length = ND_BYTES_AVAILABLE_AFTER(b); /* now lets guess about the payload codepoint format */ @@ -1442,13 +1447,11 @@ ppp_hdlc(netdissect_options *ndo, } cleanup: - ndo->ndo_packetp = sb; - ndo->ndo_snapend = se; + nd_pop_packet_info(ndo); return; trunc: - ndo->ndo_packetp = sb; - ndo->ndo_snapend = se; + nd_pop_packet_info(ndo); nd_print_trunc(ndo); } diff --git a/contrib/tcpdump/print.c b/contrib/tcpdump/print.c index 41a6b524fbf8..96d34b772f08 100644 --- a/contrib/tcpdump/print.c +++ b/contrib/tcpdump/print.c @@ -434,10 +434,14 @@ pretty_print_packet(netdissect_options *ndo, const struct pcap_pkthdr *h, nd_pop_all_packet_info(ndo); /* - * Restore the original snapend, as a printer might have - * changed it. + * Restore the originals snapend and packetp, as a printer + * might have changed them. + * + * XXX - nd_pop_all_packet_info() should have restored the + * original values, but, just in case.... */ ndo->ndo_snapend = sp + h->caplen; + ndo->ndo_packetp = sp; if (ndo->ndo_Xflag) { /* * Print the raw packet data in hex and ASCII. From 1b9cfd6a625dc82611846cb9a53c1886f7af3758 Mon Sep 17 00:00:00 2001 From: Ed Maste Date: Mon, 12 Aug 2024 09:11:09 -0400 Subject: [PATCH 091/213] stand: bump arbitrary build date to 2024-01-01 For build reproducibility we set PE headers to an arbitrary timestamp. Nothing in FreeBSD uses this timestamp, but bump it from 2016 to 2024 so that the timestamp does not seem "too old" in case some third party tool is used to inspect EFI boot components. Reviewed by: imp Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D46527 --- stand/efi/Makefile.inc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/stand/efi/Makefile.inc b/stand/efi/Makefile.inc index 3a13ca24f369..18751f0e4ecc 100644 --- a/stand/efi/Makefile.inc +++ b/stand/efi/Makefile.inc @@ -23,8 +23,8 @@ EFI_TARGET= efi-app-x86_64 EFI_TARGET= binary .endif -# Arbitrarily set the PE/COFF header timestamps to 1 Jan 2016 00:00:00 +# Arbitrarily set the PE/COFF header timestamps to 1 Jan 2024 00:00:00 # for build reproducibility. -SOURCE_DATE_EPOCH?=1451606400 +SOURCE_DATE_EPOCH?=1704067200 .include "../Makefile.inc" From f5541f9f473430a3e608e07f623294322853d25a Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Tue, 3 Sep 2024 16:12:04 -0400 Subject: [PATCH 092/213] nvmfd/nvmft: Fix a typo "whiled" -> "while" Sponsored by: Chelsio Communications --- sys/dev/nvmf/controller/nvmft_controller.c | 2 +- usr.sbin/nvmfd/controller.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/dev/nvmf/controller/nvmft_controller.c b/sys/dev/nvmf/controller/nvmft_controller.c index dee4d8c92d3d..3c10fea75c9d 100644 --- a/sys/dev/nvmf/controller/nvmft_controller.c +++ b/sys/dev/nvmf/controller/nvmft_controller.c @@ -954,7 +954,7 @@ nvmft_handle_admin_command(struct nvmft_controller *ctrlr, if (NVMEV(NVME_CC_REG_EN, ctrlr->cc) == 0 && cmd->opc != NVME_OPC_FABRICS_COMMANDS) { nvmft_printf(ctrlr, - "Unsupported admin opcode %#x whiled disabled\n", cmd->opc); + "Unsupported admin opcode %#x while disabled\n", cmd->opc); nvmft_send_generic_error(ctrlr->admin, nc, NVME_SC_COMMAND_SEQUENCE_ERROR); nvmf_free_capsule(nc); diff --git a/usr.sbin/nvmfd/controller.c b/usr.sbin/nvmfd/controller.c index 09baaea74ab4..e9435bce69da 100644 --- a/usr.sbin/nvmfd/controller.c +++ b/usr.sbin/nvmfd/controller.c @@ -192,7 +192,7 @@ controller_handle_admin_commands(struct controller *c, handle_command *cb, */ if (NVMEV(NVME_CC_REG_EN, c->cc) == 0 && cmd->opc != NVME_OPC_FABRICS_COMMANDS) { - warnx("Unsupported admin opcode %#x whiled disabled\n", + warnx("Unsupported admin opcode %#x while disabled\n", cmd->opc); nvmf_send_generic_error(nc, NVME_SC_COMMAND_SEQUENCE_ERROR); From 18f7683e0d6ee6858865d8b0c2d7e2c14abf0bc4 Mon Sep 17 00:00:00 2001 From: Jessica Clarke Date: Tue, 3 Sep 2024 21:14:44 +0100 Subject: [PATCH 093/213] loader.efi.8: Remove rogue duplicated lines Fixes: 871911a4ab73 ("loader.efi(8): beef up the updating the ESP") MFC after: 1 week --- stand/man/loader.efi.8 | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/stand/man/loader.efi.8 b/stand/man/loader.efi.8 index a0c0df9a9c35..3527d8b66a99 100644 --- a/stand/man/loader.efi.8 +++ b/stand/man/loader.efi.8 @@ -30,7 +30,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd August 20, 2024 +.Dd September 3, 2024 .Dt LOADER.EFI 8 .Os .Sh NAME @@ -450,9 +450,6 @@ copy the loader to the default location: # cp /boot/loader.efi /boot/efi/EFI/BOOT/BOOTX64.EFI .Ed .Pp -.Bd -literal -offset indent -# umount /boot/efi -.Ed Finally, if you mounted the ESP, you may wish to unmount it. .Bd -literal -offset indent # umount /boot/efi From a84d91d81a6f3eeb4949c4fb3440e0634f2b953a Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Sun, 21 Jan 2024 19:56:27 +0000 Subject: [PATCH 094/213] mmccam: fix mmcsd disk aliases For EXT_CSD_PART_CONFIG_ACC_BOOT and possibly others with suffixes we fail to create proper disk aliases (symlinks), which shows up as g_dev_taste: make_dev_alias_p() failed (name=mmcsd0, error=17) In this case we ended up with the followng two: /dev/mmcsd0 -> sdda0 /dev/mmcsd1 -> sdda0boot1 Note that (i) it should be mmcsd0boot1 and not mmcsd1 and that (ii) there is no mmcsd0boot0 (failed above as it tried to create a second mmcsd0). Adjust the code (using a highly simplified version--compared to my original approach--suggested by imp) using an extended format string with (sdda/mmcsd) prefix as first argument to create proper names. MFC after: 3 days Reviewed by: imp Differential Revision: https://reviews.freebsd.org/D43538 --- sys/cam/mmc/mmc_da.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/sys/cam/mmc/mmc_da.c b/sys/cam/mmc/mmc_da.c index 597ba0efb47e..fc29a1925c66 100644 --- a/sys/cam/mmc/mmc_da.c +++ b/sys/cam/mmc/mmc_da.c @@ -88,9 +88,11 @@ typedef enum { SDDA_STATE_PART_SWITCH, } sdda_state; -#define SDDA_FMT_BOOT "sdda%dboot" -#define SDDA_FMT_GP "sdda%dgp" -#define SDDA_FMT_RPMB "sdda%drpmb" +/* Purposefully ignore a '%d' argument to snprintf in SDDA_FMT! */ +#define SDDA_FMT "%s" +#define SDDA_FMT_BOOT "%s%dboot" +#define SDDA_FMT_GP "%s%dgp" +#define SDDA_FMT_RPMB "%s%drpmb" #define SDDA_LABEL_ENH "enh" #define SDDA_PART_NAMELEN (16 + 1) @@ -1480,7 +1482,7 @@ sdda_start_init(void *context, union ccb *start_ccb) sdda_process_mmc_partitions(periph, start_ccb); } else if (mmcp->card_features & CARD_FEATURE_MEMORY) { /* For SD[HC] cards, just add one partition that is the whole card */ - if (sdda_add_part(periph, 0, "sdda", + if (sdda_add_part(periph, 0, SDDA_FMT, periph->unit_number, mmc_get_media_size(periph), sdda_get_read_only(periph, start_ccb)) == false) @@ -1525,7 +1527,7 @@ sdda_add_part(struct cam_periph *periph, u_int type, const char *name, part->type = type; part->ro = ro; part->sc = sc; - snprintf(part->name, sizeof(part->name), name, periph->unit_number); + snprintf(part->name, sizeof(part->name), name, "sdda", periph->unit_number); /* * Due to the nature of RPMB partition it doesn't make much sense @@ -1592,8 +1594,11 @@ sdda_add_part(struct cam_periph *periph, u_int type, const char *name, part->disk->d_fwsectors = 0; part->disk->d_fwheads = 0; - if (sdda_mmcsd_compat) - disk_add_alias(part->disk, "mmcsd"); + if (sdda_mmcsd_compat) { + char cname[SDDA_PART_NAMELEN]; /* This equals the mmcsd namelen. */ + snprintf(cname, sizeof(cname), name, "mmcsd", periph->unit_number); + disk_add_alias(part->disk, cname); + } /* * Acquire a reference to the periph before we register with GEOM. @@ -1682,7 +1687,7 @@ sdda_process_mmc_partitions(struct cam_periph *periph, union ccb *ccb) * data area in case partitions are supported. */ ro = sdda_get_read_only(periph, ccb); - sdda_add_part(periph, EXT_CSD_PART_CONFIG_ACC_DEFAULT, "sdda", + sdda_add_part(periph, EXT_CSD_PART_CONFIG_ACC_DEFAULT, SDDA_FMT, periph->unit_number, mmc_get_media_size(periph), ro); sc->part_curr = EXT_CSD_PART_CONFIG_ACC_DEFAULT; From 81d3df02bcf5ed6e41a91fd9fbc3b81cfe809ff3 Mon Sep 17 00:00:00 2001 From: Colin Percival Date: Sat, 31 Aug 2024 16:38:02 -0700 Subject: [PATCH 095/213] vmimage.subr: Pass $INSTALLOPTS to install* This makes it possible for a VM build configuration file to pass options to make installworld/installkernel/distribution, e.g. WITHOUT_DEBUG_FILES=YES in order to produce smaller images. Note that these options are only applied at install time, not at build time (since the same build is installed into many different VM images), so not all src.conf options are usable here. Sponsored by: Amazon Differential Revision: https://reviews.freebsd.org/D46506 --- release/tools/vmimage.subr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/release/tools/vmimage.subr b/release/tools/vmimage.subr index 9a60be57acf3..5d98b8990705 100644 --- a/release/tools/vmimage.subr +++ b/release/tools/vmimage.subr @@ -52,7 +52,7 @@ vm_install_base() { # Installs the FreeBSD userland/kernel to the virtual machine disk. cd ${WORLDDIR} && \ - make DESTDIR=${DESTDIR} \ + make DESTDIR=${DESTDIR} ${INSTALLOPTS} \ installworld installkernel distribution || \ err "\n\nCannot install the base system to ${DESTDIR}." From f961ddb28d6909d4c67e3e0b6b60498bbcbf64cb Mon Sep 17 00:00:00 2001 From: Colin Percival Date: Sat, 31 Aug 2024 16:46:51 -0700 Subject: [PATCH 096/213] EC2: Move network config into a separate function Having the "base" FreeBSD network configuration (aka. what is used when not using cloud-init) in ec2.conf will allow us to reuse it in other AMIs. Sponsored by: Amazon Differential Revision: https://reviews.freebsd.org/D46507 --- release/tools/ec2-base.conf | 26 +++----------------------- release/tools/ec2.conf | 27 +++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 23 deletions(-) diff --git a/release/tools/ec2-base.conf b/release/tools/ec2-base.conf index d80035e11ed7..bd2c510cd1a7 100644 --- a/release/tools/ec2-base.conf +++ b/release/tools/ec2-base.conf @@ -22,29 +22,6 @@ vm_extra_pre_umount() { # via EC2 user-data. echo 'firstboot_pkgs_list="devel/py-awscli"' >> ${DESTDIR}/etc/rc.conf - # EC2 instances use DHCP to get their network configuration. IPv6 - # requires accept_rtadv. - echo 'ifconfig_DEFAULT="SYNCDHCP accept_rtadv"' >> ${DESTDIR}/etc/rc.conf - - # The EC2 DHCP server can be trusted to know whether an IP address is - # assigned to us; we don't need to ARP to check if anyone else is using - # the address before we start using it. - echo 'dhclient_arpwait="NO"' >> ${DESTDIR}/etc/rc.conf - - # Enable IPv6 on all interfaces, and spawn DHCPv6 via rtsold - echo 'ipv6_activate_all_interfaces="YES"' >> ${DESTDIR}/etc/rc.conf - echo 'rtsold_enable="YES"' >> ${DESTDIR}/etc/rc.conf - echo 'rtsold_flags="-M /usr/local/libexec/rtsold-M -a"' >> ${DESTDIR}/etc/rc.conf - - # Provide a script which rtsold can use to launch DHCPv6 - mkdir -p ${DESTDIR}/usr/local/libexec - cat > ${DESTDIR}/usr/local/libexec/rtsold-M <<'EOF' -#!/bin/sh - -/usr/local/sbin/dhclient -6 -nw -N -cf /dev/null $1 -EOF - chmod 755 ${DESTDIR}/usr/local/libexec/rtsold-M - # Any EC2 ephemeral disks seen when the system first boots will # be "new" disks; there is no "previous boot" when they might have # been seen and used already. @@ -53,5 +30,8 @@ EOF # Configuration common to all EC2 AMIs ec2_common + # Standard FreeBSD network configuration + ec2_base_networking + return 0 } diff --git a/release/tools/ec2.conf b/release/tools/ec2.conf index 602216d3c2d4..09cf1ce0017f 100644 --- a/release/tools/ec2.conf +++ b/release/tools/ec2.conf @@ -104,3 +104,30 @@ EOF return 0 } + +ec2_base_networking () { + # EC2 instances use DHCP to get their network configuration. IPv6 + # requires accept_rtadv. + echo 'ifconfig_DEFAULT="SYNCDHCP accept_rtadv"' >> ${DESTDIR}/etc/rc.conf + + # The EC2 DHCP server can be trusted to know whether an IP address is + # assigned to us; we don't need to ARP to check if anyone else is using + # the address before we start using it. + echo 'dhclient_arpwait="NO"' >> ${DESTDIR}/etc/rc.conf + + # Enable IPv6 on all interfaces, and spawn DHCPv6 via rtsold + echo 'ipv6_activate_all_interfaces="YES"' >> ${DESTDIR}/etc/rc.conf + echo 'rtsold_enable="YES"' >> ${DESTDIR}/etc/rc.conf + echo 'rtsold_flags="-M /usr/local/libexec/rtsold-M -a"' >> ${DESTDIR}/etc/rc.conf + + # Provide a script which rtsold can use to launch DHCPv6 + mkdir -p ${DESTDIR}/usr/local/libexec + cat > ${DESTDIR}/usr/local/libexec/rtsold-M <<'EOF' +#!/bin/sh + +/usr/local/sbin/dhclient -6 -nw -N -cf /dev/null $1 +EOF + chmod 755 ${DESTDIR}/usr/local/libexec/rtsold-M + + return 0 +} From 40ff0753abb9c00b5f1e5df9ea00c9fdded55ac4 Mon Sep 17 00:00:00 2001 From: Colin Percival Date: Sat, 31 Aug 2024 16:50:16 -0700 Subject: [PATCH 097/213] EC2: Make amazon-ssm-agent optional Move it from VM_EXTRA_PACKAGES in ec2.conf to VM_EXTRA_PACKAGES in ec2-{base,cloud-init}.conf Sponsored by: Amazon Differential Revision: https://reviews.freebsd.org/D46508 --- release/tools/ec2-base.conf | 4 +++- release/tools/ec2-cloud-init.conf | 4 ++-- release/tools/ec2.conf | 6 ++---- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/release/tools/ec2-base.conf b/release/tools/ec2-base.conf index bd2c510cd1a7..3ed20474a4e8 100644 --- a/release/tools/ec2-base.conf +++ b/release/tools/ec2-base.conf @@ -4,11 +4,13 @@ # Packages to install into the image we're creating. In addition to packages # present on all EC2 AMIs, we install: +# * amazon-ssm-agent (not enabled by default, but some users need to use +# it on systems not connected to the internet), # * ec2-scripts, which provides a range of EC2ification startup scripts, # * firstboot-freebsd-update, to install security updates at first boot, # * firstboot-pkgs, to install packages at first boot, and # * isc-dhcp44-client, used for IPv6 network setup. -export VM_EXTRA_PACKAGES="${VM_EXTRA_PACKAGES} ec2-scripts \ +export VM_EXTRA_PACKAGES="${VM_EXTRA_PACKAGES} amazon-ssm-agent ec2-scripts \ firstboot-freebsd-update firstboot-pkgs isc-dhcp44-client" # Services to enable in rc.conf(5). diff --git a/release/tools/ec2-cloud-init.conf b/release/tools/ec2-cloud-init.conf index 7682d635b1d6..048202e252f6 100644 --- a/release/tools/ec2-cloud-init.conf +++ b/release/tools/ec2-cloud-init.conf @@ -3,8 +3,8 @@ . ${WORLDDIR}/release/tools/ec2.conf # Packages to install into the image we're creating. In addition to packages -# present on all EC2 AMIs, we install cloud-init. -export VM_EXTRA_PACKAGES="${VM_EXTRA_PACKAGES} net/cloud-init" +# present on all EC2 AMIs, we install amazon-ssm-agent and cloud-init. +export VM_EXTRA_PACKAGES="${VM_EXTRA_PACKAGES} amazon-ssm-agent net/cloud-init" # Services to enable in rc.conf(5). export VM_RC_LIST="${VM_RC_LIST} cloudinit sshd" diff --git a/release/tools/ec2.conf b/release/tools/ec2.conf index 09cf1ce0017f..2cca5fa713af 100644 --- a/release/tools/ec2.conf +++ b/release/tools/ec2.conf @@ -1,11 +1,9 @@ #!/bin/sh -# Packages which should be installed onto all EC2 AMIs: +# Package which should be installed onto all EC2 AMIs: # * ebsnvme-id, which is very minimal and provides important EBS-specific # functionality, -# * amazon-ssm-agent (not enabled by default, but some users need to use -# it on systems not connected to the internet). -export VM_EXTRA_PACKAGES="${VM_EXTRA_PACKAGES} ebsnvme-id amazon-ssm-agent" +export VM_EXTRA_PACKAGES="${VM_EXTRA_PACKAGES} ebsnvme-id" # Services which should be enabled by default in rc.conf(5). export VM_RC_LIST="dev_aws_disk ntpd" From 647299caa06e38622dc05a4358f9407b62a9bdda Mon Sep 17 00:00:00 2001 From: Colin Percival Date: Sat, 31 Aug 2024 16:55:06 -0700 Subject: [PATCH 098/213] EC2: Add new "small" AMIs These are the same as the standard "base" images except: * They don't have kernel or world debug symbols, * They don't have FreeBSD tests, * They don't have 32-bit libraries, * They don't have LLDB, * They don't have the Amazon SSM Agent pre-installed, * They don't default to installing the awscli at first boot. This reduces the amount of disk space in use when the EC2 instance finishes booting from ~5 GB to ~1 GB. Sponsored by: Amazon Differential Revision: https://reviews.freebsd.org/D46509 --- release/Makefile.vm | 3 ++- release/tools/ec2-small.conf | 44 ++++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 release/tools/ec2-small.conf diff --git a/release/Makefile.vm b/release/Makefile.vm index d8914d305e2f..b4fe6e23ffcd 100644 --- a/release/Makefile.vm +++ b/release/Makefile.vm @@ -39,9 +39,10 @@ BASIC-CLOUDINIT_FSLIST?= ufs zfs BASIC-CLOUDINIT_DESC?= Images for VM with cloudinit disk config support EC2_FORMAT= raw EC2_FSLIST?= ufs zfs -EC2_FLAVOURS?= BASE CLOUD-INIT +EC2_FLAVOURS?= BASE CLOUD-INIT SMALL EC2-BASE_DESC= Amazon EC2 image EC2-CLOUD-INIT_DESC= Amazon EC2 Cloud-Init image +EC2-SMALL_DESC= Amazon EC2 small image GCE_FORMAT= raw GCE_FSLIST?= ufs zfs GCE_DESC= Google Compute Engine image diff --git a/release/tools/ec2-small.conf b/release/tools/ec2-small.conf new file mode 100644 index 000000000000..858836717f5a --- /dev/null +++ b/release/tools/ec2-small.conf @@ -0,0 +1,44 @@ +#!/bin/sh + +. ${WORLDDIR}/release/tools/ec2.conf + +# Build with a 4.9 GB partition; the growfs rc.d script will expand +# the partition to fill the root disk after the EC2 instance is launched. +# Note that if this is set to G, we will end up with an GB disk +# image since VMSIZE is the size of the filesystem partition, not the disk +# which it resides within. (This overrides the default in ec2.conf.) +export VMSIZE=5000m + +# Flags to installworld/kernel: We don't want debug symbols (kernel or +# userland), 32-bit libraries, tests, or the debugger. +export INSTALLOPTS="WITHOUT_DEBUG_FILES=YES WITHOUT_KERNEL_SYMBOLS=YES \ + WITHOUT_LIB32=YES WITHOUT_TESTS=YES WITHOUT_LLDB=YES" + +# Packages to install into the image we're creating. In addition to packages +# present on all EC2 AMIs, we install: +# * ec2-scripts, which provides a range of EC2ification startup scripts, +# * firstboot-freebsd-update, to install security updates at first boot, +# * firstboot-pkgs, to install packages at first boot, and +# * isc-dhcp44-client, used for IPv6 network setup. +export VM_EXTRA_PACKAGES="${VM_EXTRA_PACKAGES} ec2-scripts \ + firstboot-freebsd-update firstboot-pkgs isc-dhcp44-client" + +# Services to enable in rc.conf(5). +export VM_RC_LIST="${VM_RC_LIST} ec2_configinit ec2_ephemeral_swap \ + ec2_fetchkey ec2_loghostkey firstboot_freebsd_update firstboot_pkgs \ + growfs sshd" + +vm_extra_pre_umount() { + # Any EC2 ephemeral disks seen when the system first boots will + # be "new" disks; there is no "previous boot" when they might have + # been seen and used already. + touch ${DESTDIR}/var/db/ec2_ephemeral_diskseen + + # Configuration common to all EC2 AMIs + ec2_common + + # Standard FreeBSD network configuration + ec2_base_networking + + return 0 +} From 957e389ca77c8bceec15a685d01888a41ce73681 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Sat, 31 Aug 2024 02:38:19 +0300 Subject: [PATCH 099/213] dev/mlx5: remove some duplicated macros from device.h Sponsored by: NVidia networking --- sys/dev/mlx5/device.h | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/sys/dev/mlx5/device.h b/sys/dev/mlx5/device.h index 50995d4f70a7..67c129a0f2b3 100644 --- a/sys/dev/mlx5/device.h +++ b/sys/dev/mlx5/device.h @@ -1123,24 +1123,6 @@ enum mlx5_mcam_feature_groups { #define MLX5_CAP_FLOWTABLE_RDMA_TX_MAX(mdev, cap) \ MLX5_CAP_FLOWTABLE_MAX(mdev, flow_table_properties_nic_transmit_rdma.cap) -#define MLX5_CAP_FLOWTABLE_NIC_TX(mdev, cap) \ - MLX5_CAP_FLOWTABLE(mdev, flow_table_properties_nic_transmit.cap) - -#define MLX5_CAP_FLOWTABLE_NIC_TX_MAX(mdev, cap) \ - MLX5_CAP_FLOWTABLE_MAX(mdev, flow_table_properties_nic_transmit.cap) - -#define MLX5_CAP_FLOWTABLE_RDMA_RX(mdev, cap) \ - MLX5_CAP_FLOWTABLE(mdev, flow_table_properties_nic_receive_rdma.cap) - -#define MLX5_CAP_FLOWTABLE_RDMA_RX_MAX(mdev, cap) \ - MLX5_CAP_FLOWTABLE_MAX(mdev, flow_table_properties_nic_receive_rdma.cap) - -#define MLX5_CAP_FLOWTABLE_RDMA_TX(mdev, cap) \ - MLX5_CAP_FLOWTABLE(mdev, flow_table_properties_nic_transmit_rdma.cap) - -#define MLX5_CAP_FLOWTABLE_RDMA_TX_MAX(mdev, cap) \ - MLX5_CAP_FLOWTABLE_MAX(mdev, flow_table_properties_nic_transmit_rdma.cap) - #define MLX5_CAP_ESW_FLOWTABLE(mdev, cap) \ MLX5_GET(flow_table_eswitch_cap, \ mdev->hca_caps_cur[MLX5_CAP_ESWITCH_FLOW_TABLE], cap) From d02e1a3ffac76c17ac4d9fd45dd5edd8bc944c82 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Wed, 28 Aug 2024 13:16:38 +0300 Subject: [PATCH 100/213] ipsec_accel_output(): do not process packet if interface rejected offload Sponsored by: NVidia networking --- sys/netipsec/ipsec_offload.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sys/netipsec/ipsec_offload.c b/sys/netipsec/ipsec_offload.c index bbf98ac7a676..7453fb3818a6 100644 --- a/sys/netipsec/ipsec_offload.c +++ b/sys/netipsec/ipsec_offload.c @@ -876,7 +876,8 @@ ipsec_accel_output(struct ifnet *ifp, struct mbuf *m, struct inpcb *inp, } i = ipsec_accel_is_accel_sav_ptr(sav, ifp); - if (i == NULL) + if (i == NULL || (i->flags & (IFP_HS_HANDLED | IFP_HS_REJECTED)) != + IFP_HS_HANDLED) goto out; if ((m->m_pkthdr.csum_flags & CSUM_TSO) == 0) { From 1af77be32760a86df242a1ffc3292dc3a7e59e27 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Sun, 1 Sep 2024 19:20:14 +0300 Subject: [PATCH 101/213] ipsec_offlad: remove not needed IFP_HS_INPUT/OUTPUT flags Calculate the hdr_ext_size unconditionally, it is kept unused for SAs not handling the input. Sponsored by: NVidia networking --- sys/netipsec/ipsec_offload.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/sys/netipsec/ipsec_offload.c b/sys/netipsec/ipsec_offload.c index 7453fb3818a6..5e8755d5f243 100644 --- a/sys/netipsec/ipsec_offload.c +++ b/sys/netipsec/ipsec_offload.c @@ -97,8 +97,6 @@ struct ifp_handle_sav { #define IFP_HS_HANDLED 0x00000001 #define IFP_HS_REJECTED 0x00000002 -#define IFP_HS_INPUT 0x00000004 -#define IFP_HS_OUTPUT 0x00000008 #define IFP_HS_MARKER 0x00000010 static CK_LIST_HEAD(, ifp_handle_sav) ipsec_accel_all_sav_handles; @@ -405,8 +403,7 @@ ipsec_accel_handle_sav(struct secasvar *sav, struct ifnet *ifp, ihs->drv_spi = drv_spi; ihs->ifdata = priv; ihs->flags = flags; - if ((flags & IFP_HS_OUTPUT) != 0) - ihs->hdr_ext_size = esp_hdrsiz(sav); + ihs->hdr_ext_size = esp_hdrsiz(sav); mtx_lock(&ipsec_accel_sav_tmp); CK_LIST_FOREACH(i, &sav->accel_ifps, sav_link) { if (i->ifp == ifp) { From f76826b892de38ed25e407c9d5e73aec1229f728 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Fri, 30 Aug 2024 20:17:50 +0300 Subject: [PATCH 102/213] ipsec offload: use private taskqueue thread Using global taskqueue_thread XXX with the vnet tasks scheduled during VNET destruction. VNET shutdown needs to wait for all vnet-scoped SAs/SPs to be handled, and doing that from taskqueue_thread task deadlocks because the same thread proceeds the removals. Reviewed by: markj Sponsored by: NVidia networking Differential revision: https://reviews.freebsd.org/D46494 --- sys/netipsec/ipsec_offload.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/sys/netipsec/ipsec_offload.c b/sys/netipsec/ipsec_offload.c index 5e8755d5f243..a06e91ada1a1 100644 --- a/sys/netipsec/ipsec_offload.c +++ b/sys/netipsec/ipsec_offload.c @@ -69,6 +69,7 @@ static struct mtx ipsec_accel_sav_tmp; static struct unrhdr *drv_spi_unr; static struct mtx ipsec_accel_cnt_lock; +static struct taskqueue *ipsec_accel_tq; struct ipsec_accel_install_newkey_tq { struct secasvar *sav; @@ -166,6 +167,11 @@ ipsec_accel_init(void *arg) mtx_init(&ipsec_accel_cnt_lock, "ipascn", MTX_DEF, 0); drv_spi_unr = new_unrhdr(IPSEC_ACCEL_DRV_SPI_MIN, IPSEC_ACCEL_DRV_SPI_MAX, &ipsec_accel_sav_tmp); + ipsec_accel_tq = taskqueue_create("ipsec_offload", M_WAITOK, + taskqueue_thread_enqueue, &ipsec_accel_tq); + (void)taskqueue_start_threads(&ipsec_accel_tq, + 1 /* Must be single-threaded */, PWAIT, + "ipsec_offload"); ipsec_accel_sa_newkey_p = ipsec_accel_sa_newkey_impl; ipsec_accel_forget_sav_p = ipsec_accel_forget_sav_impl; ipsec_accel_spdadd_p = ipsec_accel_spdadd_impl; @@ -207,6 +213,8 @@ ipsec_accel_fini(void *arg) clean_unrhdr(drv_spi_unr); /* avoid panic, should go later */ clear_unrhdr(drv_spi_unr); delete_unrhdr(drv_spi_unr); + taskqueue_drain_all(ipsec_accel_tq); + taskqueue_free(ipsec_accel_tq); mtx_destroy(&ipsec_accel_sav_tmp); mtx_destroy(&ipsec_accel_cnt_lock); } @@ -344,7 +352,7 @@ ipsec_accel_sa_newkey_act(void *context, int pending) /* * If ipsec_accel_forget_sav() raced with us and set * the flag, do its work. Its task cannot execute in - * parallel since taskqueue_thread is single-threaded. + * parallel since ipsec_accel taskqueue is single-threaded. */ if ((sav->accel_flags & SADB_KEY_ACCEL_DEINST) != 0) { tqf = (void *)sav->accel_forget_tq; @@ -385,7 +393,7 @@ ipsec_accel_sa_newkey_impl(struct secasvar *sav) TASK_INIT(&tq->install_task, 0, ipsec_accel_sa_newkey_act, tq); tq->sav = sav; tq->install_vnet = curthread->td_vnet; /* XXXKIB liveness */ - taskqueue_enqueue(taskqueue_thread, &tq->install_task); + taskqueue_enqueue(ipsec_accel_tq, &tq->install_task); } static int @@ -508,7 +516,7 @@ ipsec_accel_forget_sav_impl(struct secasvar *sav) TASK_INIT(&tq->forget_task, 0, ipsec_accel_forget_sav_act, tq); tq->forget_vnet = curthread->td_vnet; tq->sav = sav; - taskqueue_enqueue(taskqueue_thread, &tq->forget_task); + taskqueue_enqueue(ipsec_accel_tq, &tq->forget_task); } static void @@ -696,7 +704,7 @@ ipsec_accel_spdadd_impl(struct secpolicy *sp, struct inpcb *inp) in_pcbref(inp); TASK_INIT(&tq->adddel_task, 0, ipsec_accel_spdadd_act, sp); key_addref(sp); - taskqueue_enqueue(taskqueue_thread, &tq->adddel_task); + taskqueue_enqueue(ipsec_accel_tq, &tq->adddel_task); } static void @@ -751,7 +759,7 @@ ipsec_accel_spddel_impl(struct secpolicy *sp) tq->adddel_vnet = curthread->td_vnet; TASK_INIT(&tq->adddel_task, 0, ipsec_accel_spddel_act, sp); key_addref(sp); - taskqueue_enqueue(taskqueue_thread, &tq->adddel_task); + taskqueue_enqueue(ipsec_accel_tq, &tq->adddel_task); } static void @@ -1124,7 +1132,7 @@ ipsec_accel_sa_lifetime_op_impl(struct secasvar *sav, static void ipsec_accel_sync_imp(void) { - taskqueue_drain_all(taskqueue_thread); + taskqueue_drain_all(ipsec_accel_tq); } static struct mbuf * From e29afe64efd22b5f503d1f2558c38362b56be812 Mon Sep 17 00:00:00 2001 From: Ruslan Bukin Date: Wed, 4 Sep 2024 10:04:11 +0100 Subject: [PATCH 103/213] riscv: fix csr_swap() Fix csr_swap() macro so that we don't overwrite the argument (which is not even possible when the argument is an immediate value) Reviewed by: jrtc27 Differential Revision: https://reviews.freebsd.org/D46526 --- sys/riscv/include/riscvreg.h | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/sys/riscv/include/riscvreg.h b/sys/riscv/include/riscvreg.h index 6a59b0132b1b..e1ad09acedc8 100644 --- a/sys/riscv/include/riscvreg.h +++ b/sys/riscv/include/riscvreg.h @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2015-2017 Ruslan Bukin + * Copyright (c) 2015-2024 Ruslan Bukin * All rights reserved. * * Portions of this software were developed by SRI International and the @@ -189,13 +189,14 @@ (__builtin_constant_p(val) && ((u_long)(val) < 32)) #define csr_swap(csr, val) \ -({ if (CSR_ZIMM(val)) \ +({ u_long ret; \ + if (CSR_ZIMM(val)) \ __asm __volatile("csrrwi %0, " #csr ", %1" \ - : "=r" (val) : "i" (val)); \ + : "=r" (ret) : "i" (val)); \ else \ __asm __volatile("csrrw %0, " #csr ", %1" \ - : "=r" (val) : "r" (val)); \ - val; \ + : "=r" (ret) : "r" (val)); \ + ret; \ }) #define csr_write(csr, val) \ From 36fa90dbde0060aacb5677d0b113ee168e839071 Mon Sep 17 00:00:00 2001 From: Mariusz Zaborski Date: Mon, 26 Aug 2024 20:10:25 +0200 Subject: [PATCH 104/213] libnv: allocate buffer in a safe way Ensure that the calculation of size of array doesn't overflow. Security: FreeBSD-24:09.libnv Security: CVE-2024-45287 Security: CAP-02 Reported by: Synacktiv Reported by: Taylor R Campbell (NetBSD) Sponsored by: The Alpha-Omega Project Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D46131 --- sys/contrib/libnv/bsd_nvpair.c | 18 +++++++++--------- sys/contrib/libnv/nvlist.c | 8 ++++++-- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/sys/contrib/libnv/bsd_nvpair.c b/sys/contrib/libnv/bsd_nvpair.c index 0c76fefeebb6..9560ebc74f83 100644 --- a/sys/contrib/libnv/bsd_nvpair.c +++ b/sys/contrib/libnv/bsd_nvpair.c @@ -999,7 +999,7 @@ nvpair_unpack_string_array(bool isbe __unused, nvpair_t *nvp, return (NULL); } - value = nv_malloc(sizeof(*value) * nvp->nvp_nitems); + value = nv_calloc(nvp->nvp_nitems, sizeof(*value)); if (value == NULL) return (NULL); @@ -1092,7 +1092,7 @@ nvpair_unpack_nvlist_array(bool isbe __unused, nvpair_t *nvp, return (NULL); } - value = nv_malloc(nvp->nvp_nitems * sizeof(*value)); + value = nv_calloc(nvp->nvp_nitems, sizeof(*value)); if (value == NULL) return (NULL); @@ -1330,10 +1330,10 @@ nvpair_create_bool_array(const char *name, const bool *value, size_t nitems) return (NULL); } - size = sizeof(value[0]) * nitems; - data = nv_malloc(size); + data = nv_calloc(nitems, sizeof(value[0])); if (data == NULL) return (NULL); + size = sizeof(value[0]) * nitems; memcpy(data, value, size); nvp = nvpair_allocv(name, NV_TYPE_BOOL_ARRAY, (uint64_t)(uintptr_t)data, @@ -1360,10 +1360,10 @@ nvpair_create_number_array(const char *name, const uint64_t *value, return (NULL); } - size = sizeof(value[0]) * nitems; - data = nv_malloc(size); + data = nv_calloc(nitems, sizeof(value[0])); if (data == NULL) return (NULL); + size = sizeof(value[0]) * nitems; memcpy(data, value, size); nvp = nvpair_allocv(name, NV_TYPE_NUMBER_ARRAY, @@ -1393,7 +1393,7 @@ nvpair_create_string_array(const char *name, const char * const *value, nvp = NULL; datasize = 0; - data = nv_malloc(sizeof(value[0]) * nitems); + data = nv_calloc(nitems, sizeof(value[0])); if (data == NULL) return (NULL); @@ -1440,7 +1440,7 @@ nvpair_create_nvlist_array(const char *name, const nvlist_t * const *value, return (NULL); } - nvls = nv_malloc(sizeof(value[0]) * nitems); + nvls = nv_calloc(nitems, sizeof(value[0])); if (nvls == NULL) return (NULL); @@ -1507,7 +1507,7 @@ nvpair_create_descriptor_array(const char *name, const int *value, nvp = NULL; - fds = nv_malloc(sizeof(value[0]) * nitems); + fds = nv_calloc(nitems, sizeof(value[0])); if (fds == NULL) return (NULL); for (ii = 0; ii < nitems; ii++) { diff --git a/sys/contrib/libnv/nvlist.c b/sys/contrib/libnv/nvlist.c index 57343f953e94..64078b10973e 100644 --- a/sys/contrib/libnv/nvlist.c +++ b/sys/contrib/libnv/nvlist.c @@ -758,7 +758,7 @@ nvlist_descriptors(const nvlist_t *nvl, size_t *nitemsp) int *fds; nitems = nvlist_ndescriptors(nvl); - fds = nv_malloc(sizeof(fds[0]) * (nitems + 1)); + fds = nv_calloc(nitems + 1, sizeof(fds[0])); if (fds == NULL) return (NULL); if (nitems > 0) @@ -1029,6 +1029,10 @@ static bool nvlist_check_header(struct nvlist_header *nvlhdrp) { + if (nvlhdrp->nvlh_size > SIZE_MAX - sizeof(nvlhdrp)) { + ERRNO_SET(EINVAL); + return (false); + } if (nvlhdrp->nvlh_magic != NVLIST_HEADER_MAGIC) { ERRNO_SET(EINVAL); return (false); @@ -1313,7 +1317,7 @@ nvlist_recv(int sock, int flags) goto out; if (nfds > 0) { - fds = nv_malloc(nfds * sizeof(fds[0])); + fds = nv_calloc(nfds, sizeof(fds[0])); if (fds == NULL) goto out; if (fd_recv(sock, fds, nfds) == -1) From 3aaaca1b51ad844ef9e9b3d945217ab3dd189bae Mon Sep 17 00:00:00 2001 From: Mariusz Zaborski Date: Mon, 26 Aug 2024 20:20:24 +0200 Subject: [PATCH 105/213] libnv: verify that string is null terminated During unpacking, we ensure that we do not read beyond the declared size. However, unpack uses a function that copies null-terminated strings. Prior to this commit, if the last string was not null-terminated, it could result in copying data into a buffer smaller than the allocated size. Security: FreeBSD-24:09.libnv Security: CVE-2024-45288 Security: CAP-03 Reported by: Synacktiv Sponsored by: The Alpha-Omega Project Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D46138 --- sys/contrib/libnv/bsd_nvpair.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sys/contrib/libnv/bsd_nvpair.c b/sys/contrib/libnv/bsd_nvpair.c index 9560ebc74f83..a977d7941aa3 100644 --- a/sys/contrib/libnv/bsd_nvpair.c +++ b/sys/contrib/libnv/bsd_nvpair.c @@ -988,6 +988,10 @@ nvpair_unpack_string_array(bool isbe __unused, nvpair_t *nvp, for (ii = 0; ii < nvp->nvp_nitems; ii++) { len = strnlen(tmp, size - 1) + 1; size -= len; + if (tmp[len - 1] != '\0') { + ERRNO_SET(EINVAL); + return (NULL); + } if (size < 0) { ERRNO_SET(EINVAL); return (NULL); From 2981431e044fae3bc87e6fa891b8230b484dc84b Mon Sep 17 00:00:00 2001 From: Mariusz Zaborski Date: Thu, 29 Aug 2024 15:44:03 +0200 Subject: [PATCH 106/213] libnv: add test to verify null termination of string in array Differential Revision: https://reviews.freebsd.org/D46138 --- lib/libnv/tests/nv_array_tests.cc | 58 +++++++++++++++++++++++++++++-- 1 file changed, 56 insertions(+), 2 deletions(-) diff --git a/lib/libnv/tests/nv_array_tests.cc b/lib/libnv/tests/nv_array_tests.cc index 06d7525c3e1d..9acbaef67eba 100644 --- a/lib/libnv/tests/nv_array_tests.cc +++ b/lib/libnv/tests/nv_array_tests.cc @@ -1,6 +1,5 @@ /*- - * Copyright (c) 2015 Mariusz Zaborski - * All rights reserved. + * Copyright (c) 2015-2024 Mariusz Zaborski * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -27,6 +26,7 @@ #include #include #include +#include #include #include @@ -1161,6 +1161,58 @@ ATF_TEST_CASE_BODY(nvlist_nvlist_array__pack) free(packed); } + +ATF_TEST_CASE_WITHOUT_HEAD(nvlist_string_array_nonull__pack); +ATF_TEST_CASE_BODY(nvlist_string_array_nonull__pack) +{ + nvlist_t *testnvl, *unpacked; + const char *somestr[3] = { "a", "b", "XXX" }; + uint8_t *packed, *twopages, *dataptr, *secondpage; + size_t packed_size, page_size; + bool found; + + page_size = sysconf(_SC_PAGESIZE); + testnvl = nvlist_create(0); + ATF_REQUIRE(testnvl != NULL); + ATF_REQUIRE_EQ(nvlist_error(testnvl), 0); + nvlist_add_string_array(testnvl, "nvl/string", somestr, + nitems(somestr)); + ATF_REQUIRE_EQ(nvlist_error(testnvl), 0); + + packed = (uint8_t *)nvlist_pack(testnvl, &packed_size); + ATF_REQUIRE(packed != NULL); + + twopages = (uint8_t *)mmap(NULL, page_size * 2, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + ATF_REQUIRE(twopages != MAP_FAILED); + dataptr = &twopages[page_size - packed_size]; + secondpage = &twopages[page_size]; + + memset(twopages, 'A', page_size * 2); + + mprotect(secondpage, page_size, PROT_NONE); + memcpy(dataptr, packed, packed_size); + + found = false; + for (size_t i = 0; i < packed_size - 3; i++) { + if (dataptr[i] == 'X' && dataptr[i + 1] == 'X' && + dataptr[i + 2] == 'X' && dataptr[i + 3] == '\0') { + dataptr[i + 3] = 'X'; + found = true; + break; + } + } + ATF_REQUIRE(found == true); + + unpacked = nvlist_unpack(dataptr, packed_size, 0); + ATF_REQUIRE(unpacked == NULL); + + nvlist_destroy(testnvl); + free(packed); + munmap(twopages, page_size * 2); +} + + ATF_INIT_TEST_CASES(tp) { @@ -1190,5 +1242,7 @@ ATF_INIT_TEST_CASES(tp) ATF_ADD_TEST_CASE(tp, nvlist_descriptor_array__pack) ATF_ADD_TEST_CASE(tp, nvlist_string_array__pack) ATF_ADD_TEST_CASE(tp, nvlist_nvlist_array__pack) + + ATF_ADD_TEST_CASE(tp, nvlist_string_array_nonull__pack) } From 241a7ddd7112982ed41ccdd047c1dad59ee0256e Mon Sep 17 00:00:00 2001 From: Mariusz Zaborski Date: Thu, 29 Aug 2024 15:46:01 +0200 Subject: [PATCH 107/213] libnv: add tests to verify potential overflow issues Differential Revision: https://reviews.freebsd.org/D46131 --- lib/libnv/tests/Makefile | 10 ++ lib/libnv/tests/nvlist_send_recv_test.c | 193 ++++++++++++++++++++++++ sys/contrib/libnv/nv_impl.h | 8 + sys/contrib/libnv/nvlist.c | 7 - 4 files changed, 211 insertions(+), 7 deletions(-) diff --git a/lib/libnv/tests/Makefile b/lib/libnv/tests/Makefile index 2e6563a83077..aea416539c4a 100644 --- a/lib/libnv/tests/Makefile +++ b/lib/libnv/tests/Makefile @@ -1,6 +1,16 @@ +.include + ATF_TESTS_C= \ nvlist_send_recv_test +.PATH: ${SRCTOP}/lib/libnv +SRCS.nvlist_send_recv_test= msgio.c nvlist_send_recv_test.c +CFLAGS.nvlist_send_recv_test+=-I${SRCTOP}/sys/contrib/libnv +CFLAGS.nvlist_send_recv_test+=-I${SRCTOP}/lib/libnv +.if ${MK_ASAN} != "yes" +CFLAGS.nvlist_send_recv_test+=-DNO_ASAN +.endif + ATF_TESTS_CXX= \ cnv_tests \ dnv_tests \ diff --git a/lib/libnv/tests/nvlist_send_recv_test.c b/lib/libnv/tests/nvlist_send_recv_test.c index f060ee2684d5..79297dfe2043 100644 --- a/lib/libnv/tests/nvlist_send_recv_test.c +++ b/lib/libnv/tests/nvlist_send_recv_test.c @@ -43,6 +43,9 @@ #include +#include +#include + #define ALPHABET "abcdefghijklmnopqrstuvwxyz" #define fd_is_valid(fd) (fcntl((fd), F_GETFL) != -1 || errno != EBADF) @@ -542,6 +545,192 @@ ATF_TC_BODY(nvlist_send_recv__send_closed_fd__stream, tc) nvlist_send_recv__send_closed_fd(SOCK_STREAM); } +ATF_TC_WITHOUT_HEAD(nvlist_send_recv__overflow_header_size); +ATF_TC_BODY(nvlist_send_recv__overflow_header_size, tc) +{ + nvlist_t *nvl; + void *packed; + size_t packed_size; + struct nvlist_header *header; + int fd, socks[2], status; + pid_t pid; + +#ifdef NO_ASAN + atf_tc_skip("This test requires ASAN"); +#endif + + ATF_REQUIRE_EQ(socketpair(PF_UNIX, SOCK_STREAM, 0, socks), 0); + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + /* Child. */ + fd = socks[0]; + close(socks[1]); + + nvl = nvlist_create(0); + ATF_REQUIRE(nvl != NULL); + ATF_REQUIRE(nvlist_empty(nvl)); + + packed = nvlist_pack(nvl, &packed_size); + ATF_REQUIRE(packed != NULL); + ATF_REQUIRE(packed_size >= sizeof(struct nvlist_header)); + + header = (struct nvlist_header *)packed; + header->nvlh_size = SIZE_MAX - sizeof(struct nvlist_header) + 2; + + ATF_REQUIRE_EQ(write(fd, packed, packed_size), + (ssize_t)sizeof(struct nvlist_header)); + + nvlist_destroy(nvl); + free(packed); + + exit(0); + } else { + /* Parent */ + fd = socks[1]; + close(socks[0]); + + errno = 0; + nvl = nvlist_recv(fd, 0); + ATF_REQUIRE(nvl == NULL); + + /* + * Make sure it has failed on EINVAL, and not on + * errors returned by malloc or recv. + */ + ATF_REQUIRE(errno == EINVAL); + + ATF_REQUIRE(waitpid(pid, &status, 0) == pid); + ATF_REQUIRE(status == 0); + close(fd); + } +} + +ATF_TC_WITHOUT_HEAD(nvlist_send_recv__invalid_fd_size); +ATF_TC_BODY(nvlist_send_recv__invalid_fd_size, tc) +{ + nvlist_t *nvl; + void *packed; + size_t packed_size; + struct nvlist_header *header; + int fd, socks[2], status; + pid_t pid; + + ATF_REQUIRE_EQ(socketpair(PF_UNIX, SOCK_STREAM, 0, socks), 0); + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + /* Child. */ + fd = socks[0]; + close(socks[1]); + + nvl = nvlist_create(0); + ATF_REQUIRE(nvl != NULL); + ATF_REQUIRE(nvlist_empty(nvl)); + + nvlist_add_string(nvl, "nvl/string", "test"); + ATF_REQUIRE_EQ(nvlist_error(nvl), 0); + + packed = nvlist_pack(nvl, &packed_size); + ATF_REQUIRE(packed != NULL); + ATF_REQUIRE(packed_size >= sizeof(struct nvlist_header)); + + header = (struct nvlist_header *)packed; + header->nvlh_descriptors = 0x20; + + ATF_REQUIRE_EQ(write(fd, packed, packed_size), + (ssize_t)packed_size); + + nvlist_destroy(nvl); + free(packed); + + exit(0); + } else { + /* Parent */ + fd = socks[1]; + close(socks[0]); + + nvl = nvlist_recv(fd, 0); + ATF_REQUIRE(nvl == NULL); + + ATF_REQUIRE(waitpid(pid, &status, 0) == pid); + ATF_REQUIRE(status == 0); + } + + close(fd); +} + +ATF_TC_WITHOUT_HEAD(nvlist_send_recv__overflow_fd_size); +ATF_TC_BODY(nvlist_send_recv__overflow_fd_size, tc) +{ + nvlist_t *nvl; + void *packed; + size_t packed_size; + struct nvlist_header *header; + int fd, socks[2], fds[1], status; + pid_t pid; + + ATF_REQUIRE_EQ(socketpair(PF_UNIX, SOCK_STREAM, 0, socks), 0); + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + /* Child. */ + fd = socks[0]; + close(socks[1]); + + nvl = nvlist_create(0); + ATF_REQUIRE(nvl != NULL); + ATF_REQUIRE(nvlist_empty(nvl)); + + nvlist_add_string(nvl, "nvl/string", "test"); + ATF_REQUIRE_EQ(nvlist_error(nvl), 0); + + packed = nvlist_pack(nvl, &packed_size); + ATF_REQUIRE(packed != NULL); + ATF_REQUIRE(packed_size >= sizeof(struct nvlist_header)); + + header = (struct nvlist_header *)packed; + header->nvlh_descriptors = 0x4000000000000002; + + ATF_REQUIRE_EQ(write(fd, packed, packed_size), + (ssize_t)packed_size); + + fds[0] = dup(STDERR_FILENO); + ATF_REQUIRE(fds[0] >= 0); + ATF_REQUIRE_EQ(fd_send(fd, fds, 1), 0); + + nvlist_destroy(nvl); + free(packed); + + close(fds[0]); + close(fd); + + exit(0); + } else { + /* Parent */ + fd = socks[1]; + close(socks[0]); + + nvl = nvlist_recv(fd, 0); + ATF_REQUIRE(nvl == NULL); + + /* Make sure that fd was not parsed by nvlist */ + ATF_REQUIRE(fd_recv(fd, fds, 1) == 0); + + ATF_REQUIRE(waitpid(pid, &status, 0) == pid); + ATF_REQUIRE(status == 0); + + close(fds[0]); + close(fd); + } +} + ATF_TP_ADD_TCS(tp) { @@ -552,5 +741,9 @@ ATF_TP_ADD_TCS(tp) ATF_TP_ADD_TC(tp, nvlist_send_recv__send_many_fds__dgram); ATF_TP_ADD_TC(tp, nvlist_send_recv__send_many_fds__stream); + ATF_TP_ADD_TC(tp, nvlist_send_recv__overflow_header_size); + ATF_TP_ADD_TC(tp, nvlist_send_recv__invalid_fd_size); + ATF_TP_ADD_TC(tp, nvlist_send_recv__overflow_fd_size); + return (atf_no_error()); } diff --git a/sys/contrib/libnv/nv_impl.h b/sys/contrib/libnv/nv_impl.h index e9cd3ffabc3f..4ac57fc7b497 100644 --- a/sys/contrib/libnv/nv_impl.h +++ b/sys/contrib/libnv/nv_impl.h @@ -42,6 +42,14 @@ struct nvpair; typedef struct nvpair nvpair_t; #endif +struct nvlist_header { + uint8_t nvlh_magic; + uint8_t nvlh_version; + uint8_t nvlh_flags; + uint64_t nvlh_descriptors; + uint64_t nvlh_size; +} __packed; + #define NV_TYPE_NVLIST_ARRAY_NEXT 254 #define NV_TYPE_NVLIST_UP 255 diff --git a/sys/contrib/libnv/nvlist.c b/sys/contrib/libnv/nvlist.c index 64078b10973e..1dc0bb8c1141 100644 --- a/sys/contrib/libnv/nvlist.c +++ b/sys/contrib/libnv/nvlist.c @@ -118,13 +118,6 @@ MALLOC_DEFINE(M_NVLIST, "nvlist", "kernel nvlist"); #define NVLIST_HEADER_MAGIC 0x6c #define NVLIST_HEADER_VERSION 0x00 -struct nvlist_header { - uint8_t nvlh_magic; - uint8_t nvlh_version; - uint8_t nvlh_flags; - uint64_t nvlh_descriptors; - uint64_t nvlh_size; -} __packed; nvlist_t * nvlist_create(int flags) From fcef359272fdda27eef770a512b15bb40232cbd2 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Wed, 4 Sep 2024 09:56:21 -0400 Subject: [PATCH 108/213] uart: Use uintptr_t instead of vm_offset_t for pointer arithmetic Reviewed by: imp Obtained from: CheriBSD Sponsored by: AFRL, DARPA Differential Revision: https://reviews.freebsd.org/D46490 --- sys/dev/uart/uart_cpu_acpi.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/sys/dev/uart/uart_cpu_acpi.c b/sys/dev/uart/uart_cpu_acpi.c index 53fe459e64a1..7892437e11de 100644 --- a/sys/dev/uart/uart_cpu_acpi.c +++ b/sys/dev/uart/uart_cpu_acpi.c @@ -235,10 +235,10 @@ uart_cpu_acpi_dbg2(struct uart_devinfo *di) error = ENXIO; - dbg2_dev = (ACPI_DBG2_DEVICE *)((vm_offset_t)dbg2 + dbg2->InfoOffset); + dbg2_dev = (ACPI_DBG2_DEVICE *)((uintptr_t)dbg2 + dbg2->InfoOffset); found = false; - while ((vm_offset_t)dbg2_dev + dbg2_dev->Length <= - (vm_offset_t)dbg2 + dbg2->Header.Length) { + while ((uintptr_t)dbg2_dev + dbg2_dev->Length <= + (uintptr_t)dbg2 + dbg2->Header.Length) { if (dbg2_dev->PortType != ACPI_DBG2_SERIAL_PORT) goto next; @@ -252,7 +252,7 @@ uart_cpu_acpi_dbg2(struct uart_devinfo *di) class = cd->cd_class; base_address = (ACPI_GENERIC_ADDRESS *) - ((vm_offset_t)dbg2_dev + dbg2_dev->BaseAddressOffset); + ((uintptr_t)dbg2_dev + dbg2_dev->BaseAddressOffset); error = uart_cpu_acpi_init_devinfo(di, class, base_address); if (error == 0) { @@ -262,7 +262,7 @@ uart_cpu_acpi_dbg2(struct uart_devinfo *di) next: dbg2_dev = (ACPI_DBG2_DEVICE *) - ((vm_offset_t)dbg2_dev + dbg2_dev->Length); + ((uintptr_t)dbg2_dev + dbg2_dev->Length); } if (!found) goto out; From b5d3f8252fe8b74249ed49e87981d190c3ec3d05 Mon Sep 17 00:00:00 2001 From: Mark Johnston Date: Fri, 14 Jun 2024 20:10:42 -0400 Subject: [PATCH 109/213] ggate tests: Use unique ports among tests This helps avoid failures when running tests in parallel. MFC after: 1 week --- tests/sys/geom/class/gate/ggate_test.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/sys/geom/class/gate/ggate_test.sh b/tests/sys/geom/class/gate/ggate_test.sh index 3ca5c3a2531a..4cbc5d80ae89 100644 --- a/tests/sys/geom/class/gate/ggate_test.sh +++ b/tests/sys/geom/class/gate/ggate_test.sh @@ -1,7 +1,5 @@ - PIDFILE=ggated.pid PLAINFILES=plainfiles -PORT=33080 CONF=gg.exports atf_test_case ggatec_trim cleanup @@ -17,13 +15,14 @@ ggatec_trim_body() { load_ggate + port=33080 us=$(alloc_ggate_dev) work=$(alloc_md) atf_check -e ignore -o ignore dd if=/dev/random of=/dev/$work bs=1m count=1 conv=notrunc echo $CONF >> $PLAINFILES echo "localhost RW /dev/$work" > $CONF - atf_check ggated -p $PORT -F $PIDFILE $CONF - atf_check ggatec create -p $PORT -u $us localhost /dev/$work + atf_check ggated -p $port -F $PIDFILE $CONF + atf_check ggatec create -p $port -u $us localhost /dev/$work ggate_dev=/dev/ggate${us} wait_for_ggate_device ${ggate_dev} @@ -55,6 +54,7 @@ ggated_body() load_ggate + port=33081 us=$(alloc_ggate_dev) work=$(alloc_md) src=$(alloc_md) @@ -67,8 +67,8 @@ ggated_body() echo $CONF >> $PLAINFILES echo "127.0.0.1 RW /dev/$work" > $CONF - atf_check ggated -p $PORT -F $PIDFILE $CONF - atf_check ggatec create -p $PORT -u $us 127.0.0.1 /dev/$work + atf_check ggated -p $port -F $PIDFILE $CONF + atf_check ggatec create -p $port -u $us 127.0.0.1 /dev/$work ggate_dev=/dev/ggate${us} From 41ece3c036bda3d4da321989ee59d0555c10d603 Mon Sep 17 00:00:00 2001 From: Mark Johnston Date: Tue, 3 Sep 2024 14:39:02 +0000 Subject: [PATCH 110/213] capsicum tests: Serialize functional tests The test suite runs the same tests twice, as different users, and these can trample over each other when run in parallel, causing spurious test failures. MFC after: 1 week --- tests/sys/capsicum/Makefile | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/sys/capsicum/Makefile b/tests/sys/capsicum/Makefile index 6d37cfa08056..fd8dcb29d65c 100644 --- a/tests/sys/capsicum/Makefile +++ b/tests/sys/capsicum/Makefile @@ -13,6 +13,10 @@ CFLAGS+= -I${SRCTOP}/tests GTESTS+= capsicum-test GTESTS_WRAPPER_SH.capsicum-test= functional +# This test script runs the same test suite twice, once as root and once as an +# unprivileged user. Serialize them since some tests access global namespaces, +# e.g., mqueuefs, and can trample on each other. +TEST_METADATA.functional+= is_exclusive="true" SRCS.capsicum-test+= \ capsicum-test-main.cc \ From 408c909dc64f77d2696d6fec77a2e0b00255cf96 Mon Sep 17 00:00:00 2001 From: Mark Johnston Date: Wed, 4 Sep 2024 13:07:11 +0000 Subject: [PATCH 111/213] ifnet: Remove if_getamcount() All uses of this function were incorrect. if_amcount is a reference count which tracks the number of times the network stack internally set IFF_ALLMULTI. (if_pcount is the corresponding counter for IFF_PROMISC.) Remove if_getamcount() and fix up callers to get the number of assigned multicast addresses instead, since that's what they actually want. Sponsored by: Klara, Inc. Reviewed by: zlei, glebius MFC after: 2 weeks Differential Revision: https://reviews.freebsd.org/D46523 --- sys/dev/bxe/bxe.c | 2 +- sys/dev/liquidio/lio_ioctl.c | 2 +- sys/net/if.c | 6 ------ sys/net/if_var.h | 1 - 4 files changed, 2 insertions(+), 9 deletions(-) diff --git a/sys/dev/bxe/bxe.c b/sys/dev/bxe/bxe.c index 26a87354e5b1..3e7120a42a90 100644 --- a/sys/dev/bxe/bxe.c +++ b/sys/dev/bxe/bxe.c @@ -12174,7 +12174,7 @@ bxe_set_rx_mode(struct bxe_softc *sc) if (if_getflags(ifp) & IFF_PROMISC) { rx_mode = BXE_RX_MODE_PROMISC; } else if ((if_getflags(ifp) & IFF_ALLMULTI) || - ((if_getamcount(ifp) > BXE_MAX_MULTICAST) && + (if_llmaddr_count(ifp) > BXE_MAX_MULTICAST && CHIP_IS_E1(sc))) { rx_mode = BXE_RX_MODE_ALLMULTI; } else { diff --git a/sys/dev/liquidio/lio_ioctl.c b/sys/dev/liquidio/lio_ioctl.c index 10c88b209051..b2fd54f59580 100644 --- a/sys/dev/liquidio/lio_ioctl.c +++ b/sys/dev/liquidio/lio_ioctl.c @@ -481,7 +481,7 @@ lio_get_new_flags(if_t ifp) * Accept all multicast addresses if there are more than we * can handle */ - if (if_getamcount(ifp) > LIO_MAX_MULTICAST_ADDR) + if (if_llmaddr_count(ifp) > LIO_MAX_MULTICAST_ADDR) f |= LIO_IFFLAG_ALLMULTI; } if (if_getflags(ifp) & IFF_BROADCAST) diff --git a/sys/net/if.c b/sys/net/if.c index c71643a41bc5..4458d710d826 100644 --- a/sys/net/if.c +++ b/sys/net/if.c @@ -4780,12 +4780,6 @@ if_getifaddr(const if_t ifp) return (ifp->if_addr); } -int -if_getamcount(const if_t ifp) -{ - return (ifp->if_amcount); -} - int if_setsendqready(if_t ifp) { diff --git a/sys/net/if_var.h b/sys/net/if_var.h index e493f8c7951e..cd074e4a8f4e 100644 --- a/sys/net/if_var.h +++ b/sys/net/if_var.h @@ -675,7 +675,6 @@ u_int if_lladdr_count(if_t); u_int if_llmaddr_count(if_t); bool if_maddr_empty(if_t); -int if_getamcount(const if_t ifp); struct ifaddr * if_getifaddr(const if_t ifp); typedef u_int if_addr_cb_t(void *, struct ifaddr *, u_int); u_int if_foreach_addr_type(if_t ifp, int type, if_addr_cb_t cb, void *cb_arg); From 01f43479b5925d5e1f996a5ae2929aa2d2aab83b Mon Sep 17 00:00:00 2001 From: Mark Johnston Date: Fri, 30 Aug 2024 00:44:45 +0000 Subject: [PATCH 112/213] ipsec: Drain async ipsec_offload work when destroying a vnet Re-apply commit e196b12f4d4d. This was reverted by commit 28294dc92476 because it could trigger a deadlock, but the underlying problem there was fixed in commit f76826b892de. Reported by: KASAN Reviewed by: kib Fixes: ef2a572bf6bd ("ipsec_offload: kernel infrastructure") Sponsored by: Klara, Inc. Differential Revision: https://reviews.freebsd.org/D46483 --- sys/netipsec/ipsec_offload.c | 2 +- sys/netipsec/key.c | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/sys/netipsec/ipsec_offload.c b/sys/netipsec/ipsec_offload.c index a06e91ada1a1..19719a8f171b 100644 --- a/sys/netipsec/ipsec_offload.c +++ b/sys/netipsec/ipsec_offload.c @@ -392,7 +392,7 @@ ipsec_accel_sa_newkey_impl(struct secasvar *sav) TASK_INIT(&tq->install_task, 0, ipsec_accel_sa_newkey_act, tq); tq->sav = sav; - tq->install_vnet = curthread->td_vnet; /* XXXKIB liveness */ + tq->install_vnet = curthread->td_vnet; taskqueue_enqueue(ipsec_accel_tq, &tq->install_task); } diff --git a/sys/netipsec/key.c b/sys/netipsec/key.c index 5a3e5727bc2e..ad1d6164f158 100644 --- a/sys/netipsec/key.c +++ b/sys/netipsec/key.c @@ -8713,6 +8713,9 @@ key_vnet_destroy(void *arg __unused) } SAHTREE_WUNLOCK(); + /* Wait for async work referencing this VNET to finish. */ + ipsec_accel_sync(); + key_freesah_flushed(&sahdrainq); hashdestroy(V_sphashtbl, M_IPSEC_SP, V_sphash_mask); hashdestroy(V_savhashtbl, M_IPSEC_SA, V_savhash_mask); From a06fc21e770a482c8915411ebc98c870e42dd29b Mon Sep 17 00:00:00 2001 From: Pierre Pronchery Date: Wed, 4 Sep 2024 14:38:11 +0000 Subject: [PATCH 113/213] bhyve: fix Out-Of-Bounds read/write heap in tpm_ppi_mem_handler The function tpm_ppi_mem_handler is vulnerable to buffer over-read and over-write, the MMIO handler serves the heap allocated structure tpm_ppi_qemu. The issue is that the structure size is smaller than 0x1000 and the handler does not validate the offset and size (sizeof is 0x15A while the handler allows up to 0x1000 bytes) Reported by: Synacktiv Reviewed by: corvink Security: FreeBSD-SA-24:10.bhyve Security: CVE-2024-41928 Security: HYP-01 Sponsored by: The Alpha-Omega Project Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D45980 --- usr.sbin/bhyve/tpm_ppi_qemu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/usr.sbin/bhyve/tpm_ppi_qemu.c b/usr.sbin/bhyve/tpm_ppi_qemu.c index 239d39184589..01b8493e7273 100644 --- a/usr.sbin/bhyve/tpm_ppi_qemu.c +++ b/usr.sbin/bhyve/tpm_ppi_qemu.c @@ -25,7 +25,7 @@ #include "tpm_ppi.h" #define TPM_PPI_ADDRESS 0xFED45000 -#define TPM_PPI_SIZE 0x1000 +#define TPM_PPI_SIZE 0x400 #define TPM_PPI_FWCFG_FILE "etc/tpm/config" @@ -100,7 +100,7 @@ tpm_ppi_init(void **sc) struct tpm_ppi_fwcfg *fwcfg = NULL; int error; - ppi = calloc(1, sizeof(*ppi)); + ppi = calloc(1, TPM_PPI_SIZE); if (ppi == NULL) { warnx("%s: failed to allocate acpi region for ppi", __func__); error = ENOMEM; From 5c9308a4130858598c76f3ae6e3e3dfb41ccfe68 Mon Sep 17 00:00:00 2001 From: Pierre Pronchery Date: Wed, 4 Sep 2024 14:38:11 +0000 Subject: [PATCH 114/213] bhyve: fix off by one error in pci_xhci The function pci_xhci_find_stream validates that the streamid is valid but the bound check accepts up to ep_MaxPStreams included. The bug results in an out-of-bounds write on the heap with controlled data. Reported by: Synacktiv Reviewed by: jhb Security: FreeBSD-SA-24:12.bhyve Security: CVE-2024-32668 Security: HYP-04 Sponsored by: The Alpha-Omega Project Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D45994 --- usr.sbin/bhyve/pci_xhci.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/usr.sbin/bhyve/pci_xhci.c b/usr.sbin/bhyve/pci_xhci.c index 8654dd9e7a14..b72c839c807b 100644 --- a/usr.sbin/bhyve/pci_xhci.c +++ b/usr.sbin/bhyve/pci_xhci.c @@ -660,7 +660,7 @@ pci_xhci_init_ep(struct pci_xhci_dev_emu *dev, int epid) devep = &dev->eps[epid]; pstreams = XHCI_EPCTX_0_MAXP_STREAMS_GET(ep_ctx->dwEpCtx0); if (pstreams > 0) { - DPRINTF(("init_ep %d with pstreams %d", epid, pstreams)); + DPRINTF(("init_ep %d with pstreams %u", epid, pstreams)); assert(devep->ep_sctx_trbs == NULL); devep->ep_sctx = XHCI_GADDR(dev->xsc, ep_ctx->qwEpCtx2 & @@ -1202,7 +1202,7 @@ pci_xhci_find_stream(struct pci_xhci_softc *sc, struct xhci_endp_ctx *ep, } /* only support primary stream */ - if (streamid > devep->ep_MaxPStreams) + if (streamid >= devep->ep_MaxPStreams) return (XHCI_TRB_ERROR_STREAM_TYPE); sctx = (struct xhci_stream_ctx *)XHCI_GADDR(sc, ep->qwEpCtx2 & ~0xFUL) + From 670b582db6cb827a8760df942ed8af0020a0b4d0 Mon Sep 17 00:00:00 2001 From: Alan Somers Date: Wed, 4 Sep 2024 14:38:11 +0000 Subject: [PATCH 115/213] ctl: fix Use-After-Free in ctl_write_buffer The virtio_scsi device allows a guest VM to directly send SCSI commands to the kernel driver exposed on /dev/cam/ctl. This setup makes the vulnerability directly accessible from VMs through the pci_virtio_scsi bhyve device. The function ctl_write_buffer sets the CTL_FLAG_ALLOCATED flag, causing the kern_data_ptr to be freed when the command finishes processing. However, the buffer is still stored in lun->write_buffer, leading to a Use-After-Free vulnerability. Since the buffer needs to persist indefinitely, so it can be accessed by READ BUFFER, do not set CTL_FLAG_ALLOCATED. Reported by: Synacktiv Reviewed by: Pierre Pronchery Reviewed by: jhb Security: FreeBSD-SA-24:11.ctl Security: CVE-2024-45063 Security: HYP-03 Sponsored by: Axcient Sponsored by: The Alpha-Omega Project Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D46424 --- sys/cam/ctl/ctl.c | 19 +++++++++++-------- sys/cam/ctl/ctl_private.h | 8 ++++++++ 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/sys/cam/ctl/ctl.c b/sys/cam/ctl/ctl.c index 82420396aca1..2124903f4ac1 100644 --- a/sys/cam/ctl/ctl.c +++ b/sys/cam/ctl/ctl.c @@ -5625,21 +5625,24 @@ ctl_write_buffer(struct ctl_scsiio *ctsio) return (CTL_RETVAL_COMPLETE); } + if (lun->write_buffer == NULL) { + lun->write_buffer = malloc(CTL_WRITE_BUFFER_SIZE, + M_CTL, M_WAITOK); + } + /* - * If we've got a kernel request that hasn't been malloced yet, - * malloc it and tell the caller the data buffer is here. + * If this kernel request hasn't started yet, initialize the data + * buffer to the correct region of the LUN's write buffer. Note that + * this doesn't set CTL_FLAG_ALLOCATED since this points into a + * persistent buffer belonging to the LUN rather than a buffer + * dedicated to this request. */ - if ((ctsio->io_hdr.flags & CTL_FLAG_ALLOCATED) == 0) { - if (lun->write_buffer == NULL) { - lun->write_buffer = malloc(CTL_WRITE_BUFFER_SIZE, - M_CTL, M_WAITOK); - } + if (ctsio->kern_data_ptr == NULL) { ctsio->kern_data_ptr = lun->write_buffer + buffer_offset; ctsio->kern_data_len = len; ctsio->kern_total_len = len; ctsio->kern_rel_offset = 0; ctsio->kern_sg_entries = 0; - ctsio->io_hdr.flags |= CTL_FLAG_ALLOCATED; ctsio->be_move_done = ctl_config_move_done; ctl_datamove((union ctl_io *)ctsio); diff --git a/sys/cam/ctl/ctl_private.h b/sys/cam/ctl/ctl_private.h index cd7e499c60a6..821aa0aa681b 100644 --- a/sys/cam/ctl/ctl_private.h +++ b/sys/cam/ctl/ctl_private.h @@ -355,6 +355,14 @@ struct ctl_lun { uint8_t pr_res_type; int prevent_count; uint32_t *prevent; + + /* + * The READ_BUFFER and WRITE_BUFFER commands permit access to a logical + * data buffer associated with a LUN. Accesses to the data buffer do + * not affect data stored on the storage medium. To support this, + * allocate a buffer on first use that persists until the LUN is + * destroyed. + */ uint8_t *write_buffer; struct ctl_devid *lun_devid; TAILQ_HEAD(tpc_lists, tpc_list) tpc_lists; From ea44766b78d639d3a89afd5302ec6feffaade813 Mon Sep 17 00:00:00 2001 From: Pierre Pronchery Date: Wed, 4 Sep 2024 14:38:11 +0000 Subject: [PATCH 116/213] ctl: fix memory disclosure in read/write buffer commands The functions ctl_write_buffer() and ctl_read_buffer() are vulnerable to a kernel memory disclosure caused by an uninitialized kernel allocation. If one of these functions is called for the first time for a given LUN, a kernel allocation is performed without the M_ZERO flag. Then a call to ctl_read_buffer() returns the content of this allocation, which may contain kernel data. Reported by: Synacktiv Reviewed by: asomers Reviewed by: jhb Security: FreeBSD-SA-24:11.ctl Security: CVE-2024-8178 Security: HYP-05 Sponsored by: The Alpha-Omega Project Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D45952 --- sys/cam/ctl/ctl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/cam/ctl/ctl.c b/sys/cam/ctl/ctl.c index 2124903f4ac1..e58299951540 100644 --- a/sys/cam/ctl/ctl.c +++ b/sys/cam/ctl/ctl.c @@ -5586,7 +5586,7 @@ ctl_read_buffer(struct ctl_scsiio *ctsio) } else { if (lun->write_buffer == NULL) { lun->write_buffer = malloc(CTL_WRITE_BUFFER_SIZE, - M_CTL, M_WAITOK); + M_CTL, M_WAITOK | M_ZERO); } ctsio->kern_data_ptr = lun->write_buffer + buffer_offset; } @@ -5627,7 +5627,7 @@ ctl_write_buffer(struct ctl_scsiio *ctsio) if (lun->write_buffer == NULL) { lun->write_buffer = malloc(CTL_WRITE_BUFFER_SIZE, - M_CTL, M_WAITOK); + M_CTL, M_WAITOK | M_ZERO); } /* From af438acbfde3d25dbdc82b2b3d72380f0191e9d9 Mon Sep 17 00:00:00 2001 From: Pierre Pronchery Date: Wed, 4 Sep 2024 14:38:12 +0000 Subject: [PATCH 117/213] ctl: fix Out-Of-Bounds access in ctl_report_supported_opcodes This vulnerability is directly accessible to a guest VM through the pci_virtio_scsi bhyve device. In the function ctl_report_supported_opcodes() accessible from the VM, the option RSO_OPTIONS_OC_ASA does not check the requested service_action value before accessing &ctl_cmd_table[]. Reported by: Synacktiv Reviewed by: asomers Security: FreeBSD-SA-24:11.ctl Security: CVE-2024-42416 Security: HYP-06 Sponsored by: The Alpha-Omega Project Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D46027 --- sys/cam/ctl/ctl.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/sys/cam/ctl/ctl.c b/sys/cam/ctl/ctl.c index e58299951540..53858edc2a1d 100644 --- a/sys/cam/ctl/ctl.c +++ b/sys/cam/ctl/ctl.c @@ -7470,20 +7470,19 @@ ctl_report_supported_opcodes(struct ctl_scsiio *ctsio) case RSO_OPTIONS_OC_SA: if ((ctl_cmd_table[opcode].flags & CTL_CMD_FLAG_SA5) == 0 || service_action >= 32) { - ctl_set_invalid_field(/*ctsio*/ ctsio, - /*sks_valid*/ 1, - /*command*/ 1, - /*field*/ 2, - /*bit_valid*/ 1, - /*bit*/ 2); - ctl_done((union ctl_io *)ctsio); - return (CTL_RETVAL_COMPLETE); + goto invalid; } - /* FALLTHROUGH */ + total_len = sizeof(struct scsi_report_supported_opcodes_one) + 32; + break; case RSO_OPTIONS_OC_ASA: + if ((ctl_cmd_table[opcode].flags & CTL_CMD_FLAG_SA5) != 0 && + service_action >= 32) { + goto invalid; + } total_len = sizeof(struct scsi_report_supported_opcodes_one) + 32; break; default: +invalid: ctl_set_invalid_field(/*ctsio*/ ctsio, /*sks_valid*/ 1, /*command*/ 1, From 60d717baf2144cf344ec9b47d715ce837b5d46d4 Mon Sep 17 00:00:00 2001 From: Alan Somers Date: Wed, 4 Sep 2024 14:38:12 +0000 Subject: [PATCH 118/213] ctl: add some ATF tests for READ BUFFER Reviewed by: Pierre Pronchery Reviewed by: jhb MFC after: 2 weeks Sponsored by: Axcient --- etc/mtree/BSD.tests.dist | 4 + tests/sys/Makefile | 1 + tests/sys/cam/Makefile | 7 + tests/sys/cam/ctl/Makefile | 10 ++ tests/sys/cam/ctl/read_buffer.sh | 226 +++++++++++++++++++++++++++++++ 5 files changed, 248 insertions(+) create mode 100644 tests/sys/cam/Makefile create mode 100644 tests/sys/cam/ctl/Makefile create mode 100644 tests/sys/cam/ctl/read_buffer.sh diff --git a/etc/mtree/BSD.tests.dist b/etc/mtree/BSD.tests.dist index ba03881bcc27..ac53de071c11 100644 --- a/etc/mtree/BSD.tests.dist +++ b/etc/mtree/BSD.tests.dist @@ -791,6 +791,10 @@ .. compat32 .. + cam + ctl + .. + .. devrandom .. dtrace diff --git a/tests/sys/Makefile b/tests/sys/Makefile index e64268e5a397..535e627d22cb 100644 --- a/tests/sys/Makefile +++ b/tests/sys/Makefile @@ -6,6 +6,7 @@ TESTS_SUBDIRS+= acl TESTS_SUBDIRS+= aio TESTS_SUBDIRS+= ${_audit} TESTS_SUBDIRS+= auditpipe +TESTS_SUBDIRS+= cam TESTS_SUBDIRS+= capsicum TESTS_SUBDIRS+= ${_cddl} # XXX: Currently broken in CI diff --git a/tests/sys/cam/Makefile b/tests/sys/cam/Makefile new file mode 100644 index 000000000000..4cc36604280a --- /dev/null +++ b/tests/sys/cam/Makefile @@ -0,0 +1,7 @@ +.include + +TESTSDIR= ${TESTSBASE}/sys/cam + +TESTS_SUBDIRS+= ctl + +.include diff --git a/tests/sys/cam/ctl/Makefile b/tests/sys/cam/ctl/Makefile new file mode 100644 index 000000000000..0e6f39a1a56f --- /dev/null +++ b/tests/sys/cam/ctl/Makefile @@ -0,0 +1,10 @@ +PACKAGE= tests + +TESTSDIR= ${TESTSBASE}/sys/cam/ctl + +ATF_TESTS_SH+= read_buffer + +# Must be exclusive because it disables/enables camsim +TEST_METADATA.read_buffer+= is_exclusive="true" + +.include diff --git a/tests/sys/cam/ctl/read_buffer.sh b/tests/sys/cam/ctl/read_buffer.sh new file mode 100644 index 000000000000..4a84eb6b9725 --- /dev/null +++ b/tests/sys/cam/ctl/read_buffer.sh @@ -0,0 +1,226 @@ +# SPDX-License-Identifier: BSD-2-Clause +# +# Copyright (c) 2024 Axcient +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS DOCUMENTATION IS PROVIDED BY THE AUTHOR ``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 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. + +# Not tested +# * modes other than "Data" and "Desc". We don't support those. +# * Buffer ID other than 0. We don't support those. +# * The Mode Specific field. We don't support it. + +load_modules() { + if ! kldstat -q -m ctl; then + kldload ctl || atf_skip "could not load ctl kernel mod" + fi + if ! ctladm port -o on -p 0; then + atf_skip "could not enable the camsim frontend" + fi +} + +find_da_device() { + SERIAL=$1 + + # Rescan camsim + # XXX camsim doesn't update when creating a new device. Worse, a + # rescan won't look for new devices. So we must disable/re-enable it. + # Worse still, enabling it isn't synchronous, so we need a retry loop + # https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=281000 + retries=5 + ctladm port -o off -p 0 >/dev/null + ctladm port -o on -p 0 >/dev/null + while true; do + + # Find the corresponding da device + da=`geom disk list | awk -v serial=$SERIAL ' /Geom name:/ { devname=$NF } /ident:/ && $NF ~ serial { print devname; exit } '` + if [ -z "$da" ]; then + retries=$(( $retries - 1 )) + if [ $retries -eq 0 ]; then + cat lun-create.txt + geom disk list + atf_fail "Could not find da device" + fi + sleep 0.1 + continue + fi + break + done +} + +# Create a CTL LUN +create_ramdisk() { + atf_check -o save:lun-create.txt ctladm create -b ramdisk -s 1048576 + atf_check egrep -q "LUN created successfully" lun-create.txt + SERIAL=`awk '/Serial Number:/ {print $NF}' lun-create.txt` + if [ -z "$SERIAL" ]; then + atf_fail "Could not find serial number" + fi + find_da_device $SERIAL +} + +cleanup() { + if [ -e "lun-create.txt" ]; then + lun_id=`awk '/LUN ID:/ {print $NF}' lun-create.txt` + ctladm remove -b ramdisk -l $lun_id > /dev/null + fi +} + +atf_test_case basic cleanup +basic_head() +{ + atf_set "descr" "READ BUFFER can retrieve data previously written by WRITE BUFFER" + atf_set "require.user" "root" + atf_set "require.progs" sg_read_buffer sg_write_buffer +} +basic_body() +{ + create_ramdisk + + # Write to its buffer + cp /etc/passwd input + len=`wc -c input | cut -wf 2` + atf_check -o ignore sg_write_buffer --mode data --in=input /dev/$da + + # Read it back + atf_check -o save:output sg_read_buffer --mode data -l $len --raw /dev/$da + + # And verify + if ! diff -q input output; then + atf_fail "Miscompare!" + fi +} +basic_cleanup() +{ + cleanup +} + +# Read from the Descriptor mode. Along with Data, these are the only two modes +# we support. +atf_test_case desc cleanup +desc_head() +{ + atf_set "descr" "READ BUFFER can retrieve the buffer size via the DESCRIPTOR mode" + atf_set "require.user" "root" + atf_set "require.progs" sg_read_buffer +} +desc_body() +{ + create_ramdisk + + atf_check -o inline:" 00 00 04 00 00\n" sg_read_buffer --hex --mode desc /dev/$da +} +desc_cleanup() +{ + cleanup +} + +atf_test_case length cleanup +length_head() +{ + atf_set "descr" "READ BUFFER can limit its length with the LENGTH field" + atf_set "require.user" "root" + atf_set "require.progs" sg_read_buffer sg_write_buffer +} +length_body() +{ + create_ramdisk + + # Write to its buffer + atf_check -o ignore -e ignore dd if=/dev/random of=input bs=4096 count=1 + atf_check -o ignore -e ignore dd if=input bs=2048 count=1 of=expected + atf_check -o ignore sg_write_buffer --mode data --in=input /dev/$da + + # Read it back + atf_check -o save:output sg_read_buffer --mode data -l 2048 --raw /dev/$da + + # And verify + if ! diff -q expected output; then + atf_fail "Miscompare!" + fi +} +length_cleanup() +{ + cleanup +} + +atf_test_case offset cleanup +offset_head() +{ + atf_set "descr" "READ BUFFER accepts the BUFFER OFFSET field" + atf_set "require.user" "root" + atf_set "require.progs" sg_read_buffer sg_write_buffer +} +offset_body() +{ + create_ramdisk + + # Write to its buffer + atf_check -o ignore -e ignore dd if=/dev/random of=input bs=4096 count=1 + atf_check -o ignore -e ignore dd if=input iseek=2 bs=512 count=1 of=expected + atf_check -o ignore sg_write_buffer --mode data --in=input /dev/$da + + # Read it back + atf_check -o save:output sg_read_buffer --mode data -l 512 -o 1024 --raw /dev/$da + + # And verify + if ! diff -q expected output; then + atf_fail "Miscompare!" + fi +} +offset_cleanup() +{ + cleanup +} + +atf_test_case uninitialized cleanup +uninitialized_head() +{ + atf_set "descr" "READ BUFFER buffers are zero-initialized" + atf_set "require.user" "root" + atf_set "require.progs" sg_read_buffer +} +uninitialized_body() +{ + create_ramdisk + + # Read an uninitialized buffer + atf_check -o save:output sg_read_buffer --mode data -l 262144 --raw /dev/$da + + # And verify + atf_check -o ignore -e ignore dd if=/dev/zero bs=262144 count=1 of=expected + if ! diff -q expected output; then + atf_fail "Miscompare!" + fi +} +uninitialized_cleanup() +{ + cleanup +} + +atf_init_test_cases() +{ + atf_add_test_case basic + atf_add_test_case desc + atf_add_test_case length + atf_add_test_case offset + atf_add_test_case uninitialized +} From dd83da532c36830a0c0aac624903849262ec6f68 Mon Sep 17 00:00:00 2001 From: Olivier Certner Date: Wed, 4 Sep 2024 14:38:12 +0000 Subject: [PATCH 119/213] umtx: shm: Collapse USHMF_REG_LINKED and USHMF_OBJ_LINKED flags ...into the only USHMF_LINKED, as they are always set or unset together. This is both to stop giving the impression that they can be set/unset independently, which they can't with the current code, and to make it clearer that an upcoming reference counting fix is correct. Reviewed by: kib Approved by: emaste (mentor) Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D46126 --- sys/kern/kern_umtx.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/sys/kern/kern_umtx.c b/sys/kern/kern_umtx.c index e6d5e2de5e88..8d70438ea195 100644 --- a/sys/kern/kern_umtx.c +++ b/sys/kern/kern_umtx.c @@ -4293,8 +4293,7 @@ __umtx_op_sem2_wake(struct thread *td, struct _umtx_op_args *uap, #define USHM_OBJ_UMTX(o) \ ((struct umtx_shm_obj_list *)(&(o)->umtx_data)) -#define USHMF_REG_LINKED 0x0001 -#define USHMF_OBJ_LINKED 0x0002 +#define USHMF_LINKED 0x0001 struct umtx_shm_reg { TAILQ_ENTRY(umtx_shm_reg) ushm_reg_link; LIST_ENTRY(umtx_shm_reg) ushm_obj_link; @@ -4354,7 +4353,7 @@ umtx_shm_find_reg_locked(const struct umtx_key *key) KASSERT(reg->ushm_key.type == TYPE_SHM, ("TYPE_USHM")); KASSERT(reg->ushm_refcnt > 0, ("reg %p refcnt 0 onlist", reg)); - KASSERT((reg->ushm_flags & USHMF_REG_LINKED) != 0, + KASSERT((reg->ushm_flags & USHMF_LINKED) != 0, ("reg %p not linked", reg)); reg->ushm_refcnt++; return (reg); @@ -4394,14 +4393,11 @@ umtx_shm_unref_reg_locked(struct umtx_shm_reg *reg, bool force) reg->ushm_refcnt--; res = reg->ushm_refcnt == 0; if (res || force) { - if ((reg->ushm_flags & USHMF_REG_LINKED) != 0) { + if ((reg->ushm_flags & USHMF_LINKED) != 0) { TAILQ_REMOVE(&umtx_shm_registry[reg->ushm_key.hash], reg, ushm_reg_link); - reg->ushm_flags &= ~USHMF_REG_LINKED; - } - if ((reg->ushm_flags & USHMF_OBJ_LINKED) != 0) { LIST_REMOVE(reg, ushm_obj_link); - reg->ushm_flags &= ~USHMF_OBJ_LINKED; + reg->ushm_flags &= ~USHMF_LINKED; } } return (res); @@ -4494,7 +4490,7 @@ umtx_shm_create_reg(struct thread *td, const struct umtx_key *key, TAILQ_INSERT_TAIL(&umtx_shm_registry[key->hash], reg, ushm_reg_link); LIST_INSERT_HEAD(USHM_OBJ_UMTX(key->info.shared.object), reg, ushm_obj_link); - reg->ushm_flags = USHMF_REG_LINKED | USHMF_OBJ_LINKED; + reg->ushm_flags = USHMF_LINKED; mtx_unlock(&umtx_shm_lock); *res = reg; return (0); From 62f40433ab47ad4a9694a22a0313d57661502ca1 Mon Sep 17 00:00:00 2001 From: Olivier Certner Date: Wed, 4 Sep 2024 14:38:12 +0000 Subject: [PATCH 120/213] umtx: shm: Fix use-after-free due to multiple drops of the registry reference umtx_shm_unref_reg_locked() would unconditionally drop the "registry" reference, tied to USHMF_LINKED. This is not a problem for caller umtx_shm_object_terminated(), which operates under the 'umtx_shm_lock' lock end-to-end, but it is for indirect caller umtx_shm(), which drops the lock between umtx_shm_find_reg() and the call to umtx_shm_unref_reg(true) that deregisters the umtx shared region (from 'umtx_shm_registry'; umtx_shm_find_reg() only finds registered shared mutexes). Thus, two concurrent user-space callers of _umtx_op() with UMTX_OP_SHM and flags UMTX_SHM_DESTROY, both progressing past umtx_shm_find_reg() but before umtx_shm_unref_reg(true), would then decrease twice the reference count for the single reference standing for the shared mutex's registration. Reported by: Synacktiv Reviewed by: kib Approved by: emaste (mentor) Security: FreeBSD-SA-24:14.umtx Security: CVE-2024-43102 Security: CAP-01 Sponsored by: The Alpha-Omega Project Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D46126 --- sys/kern/kern_umtx.c | 51 ++++++++++++++++++++++++++++---------------- 1 file changed, 33 insertions(+), 18 deletions(-) diff --git a/sys/kern/kern_umtx.c b/sys/kern/kern_umtx.c index 8d70438ea195..37c44f969a27 100644 --- a/sys/kern/kern_umtx.c +++ b/sys/kern/kern_umtx.c @@ -4384,39 +4384,49 @@ umtx_shm_free_reg(struct umtx_shm_reg *reg) } static bool -umtx_shm_unref_reg_locked(struct umtx_shm_reg *reg, bool force) +umtx_shm_unref_reg_locked(struct umtx_shm_reg *reg, bool linked_ref) { - bool res; - mtx_assert(&umtx_shm_lock, MA_OWNED); KASSERT(reg->ushm_refcnt > 0, ("ushm_reg %p refcnt 0", reg)); - reg->ushm_refcnt--; - res = reg->ushm_refcnt == 0; - if (res || force) { - if ((reg->ushm_flags & USHMF_LINKED) != 0) { - TAILQ_REMOVE(&umtx_shm_registry[reg->ushm_key.hash], - reg, ushm_reg_link); - LIST_REMOVE(reg, ushm_obj_link); - reg->ushm_flags &= ~USHMF_LINKED; - } + + if (linked_ref) { + if ((reg->ushm_flags & USHMF_LINKED) == 0) + /* + * The reference tied to USHMF_LINKED has already been + * released concurrently. + */ + return (false); + + TAILQ_REMOVE(&umtx_shm_registry[reg->ushm_key.hash], reg, + ushm_reg_link); + LIST_REMOVE(reg, ushm_obj_link); + reg->ushm_flags &= ~USHMF_LINKED; } - return (res); + + reg->ushm_refcnt--; + return (reg->ushm_refcnt == 0); } static void -umtx_shm_unref_reg(struct umtx_shm_reg *reg, bool force) +umtx_shm_unref_reg(struct umtx_shm_reg *reg, bool linked_ref) { vm_object_t object; bool dofree; - if (force) { + if (linked_ref) { + /* + * Note: This may be executed multiple times on the same + * shared-memory VM object in presence of concurrent callers + * because 'umtx_shm_lock' is not held all along in umtx_shm() + * and here. + */ object = reg->ushm_obj->shm_object; VM_OBJECT_WLOCK(object); vm_object_set_flag(object, OBJ_UMTXDEAD); VM_OBJECT_WUNLOCK(object); } mtx_lock(&umtx_shm_lock); - dofree = umtx_shm_unref_reg_locked(reg, force); + dofree = umtx_shm_unref_reg_locked(reg, linked_ref); mtx_unlock(&umtx_shm_lock); if (dofree) umtx_shm_free_reg(reg); @@ -4469,7 +4479,6 @@ umtx_shm_create_reg(struct thread *td, const struct umtx_key *key, if (!chgumtxcnt(cred->cr_ruidinfo, 1, lim_cur(td, RLIMIT_UMTXP))) return (ENOMEM); reg = uma_zalloc(umtx_shm_reg_zone, M_WAITOK | M_ZERO); - reg->ushm_refcnt = 1; bcopy(key, ®->ushm_key, sizeof(*key)); reg->ushm_obj = shm_alloc(td->td_ucred, O_RDWR, false); reg->ushm_cred = crhold(cred); @@ -4486,11 +4495,17 @@ umtx_shm_create_reg(struct thread *td, const struct umtx_key *key, *res = reg1; return (0); } - reg->ushm_refcnt++; TAILQ_INSERT_TAIL(&umtx_shm_registry[key->hash], reg, ushm_reg_link); LIST_INSERT_HEAD(USHM_OBJ_UMTX(key->info.shared.object), reg, ushm_obj_link); reg->ushm_flags = USHMF_LINKED; + /* + * This is one reference for the registry and the list of shared + * mutexes referenced by the VM object containing the lock pointer, and + * another for the caller, which it will free after use. So, one of + * these is tied to the presence of USHMF_LINKED. + */ + reg->ushm_refcnt = 2; mtx_unlock(&umtx_shm_lock); *res = reg; return (0); From c3e6dfe55c0e81d0717b0458bc95128384c3ebe8 Mon Sep 17 00:00:00 2001 From: Olivier Certner Date: Wed, 4 Sep 2024 14:38:12 +0000 Subject: [PATCH 121/213] umtx: shm: Prevent reference counting overflow This hardens against provoked use-after-free occurences should there be reference counting leaks in the future (which is currently not the case). At the deepest level, umtx_shm_find_reg_unlocked() now returns EOVERFLOW when it cannot grant an additional reference to the registry object, and so will umtx_shm_find_reg(). umtx_shm_create_reg() will fail if calling umtx_shm_find_reg() returns EOVERFLOW (meaning a SHM object for the passed key already exists, but we can't acquire another reference on it), avoiding the creation of a duplicate registry entry for a given key (this wouldn't pose problem for the rest of the code in its current form, but is expressly avoided for intelligibility and hardening purposes). Since umtx_shm_find_reg*(), and consequently the whole _umtx_op() system call, can only return EOVERFLOW on such a bug manifesting, we don't document that return value. Reviewed by: kib, emaste Approved by: emaste (mentor) Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D46126 --- sys/kern/kern_umtx.c | 76 +++++++++++++++++++++++++++++++------------- 1 file changed, 54 insertions(+), 22 deletions(-) diff --git a/sys/kern/kern_umtx.c b/sys/kern/kern_umtx.c index 37c44f969a27..a6c160ab6283 100644 --- a/sys/kern/kern_umtx.c +++ b/sys/kern/kern_umtx.c @@ -4334,8 +4334,17 @@ umtx_shm_reg_delfree_tq(void *context __unused, int pending __unused) static struct task umtx_shm_reg_delfree_task = TASK_INITIALIZER(0, umtx_shm_reg_delfree_tq, NULL); -static struct umtx_shm_reg * -umtx_shm_find_reg_locked(const struct umtx_key *key) +/* + * Returns 0 if a SHM with the passed key is found in the registry, in which + * case it is returned through 'oreg'. Otherwise, returns an error among ESRCH + * (no corresponding SHM; ESRCH was chosen for compatibility, ENOENT would have + * been preferable) or EOVERFLOW (there is a corresponding SHM, but reference + * count would overflow, so can't return it), in which case '*oreg' is left + * unchanged. + */ +static int +umtx_shm_find_reg_locked(const struct umtx_key *key, + struct umtx_shm_reg **const oreg) { struct umtx_shm_reg *reg; struct umtx_shm_reg_head *reg_head; @@ -4355,22 +4364,34 @@ umtx_shm_find_reg_locked(const struct umtx_key *key) ("reg %p refcnt 0 onlist", reg)); KASSERT((reg->ushm_flags & USHMF_LINKED) != 0, ("reg %p not linked", reg)); + /* + * Don't let overflow happen, just deny a new reference + * (this is additional protection against some reference + * count leak, which is known not to be the case at the + * time of this writing). + */ + if (__predict_false(reg->ushm_refcnt == UINT_MAX)) + return (EOVERFLOW); reg->ushm_refcnt++; - return (reg); + *oreg = reg; + return (0); } } - return (NULL); + return (ESRCH); } -static struct umtx_shm_reg * -umtx_shm_find_reg(const struct umtx_key *key) +/* + * Calls umtx_shm_find_reg_unlocked() under the 'umtx_shm_lock'. + */ +static int +umtx_shm_find_reg(const struct umtx_key *key, struct umtx_shm_reg **const oreg) { - struct umtx_shm_reg *reg; + int error; mtx_lock(&umtx_shm_lock); - reg = umtx_shm_find_reg_locked(key); + error = umtx_shm_find_reg_locked(key, oreg); mtx_unlock(&umtx_shm_lock); - return (reg); + return (error); } static void @@ -4470,11 +4491,18 @@ umtx_shm_create_reg(struct thread *td, const struct umtx_key *key, struct ucred *cred; int error; - reg = umtx_shm_find_reg(key); - if (reg != NULL) { - *res = reg; - return (0); + error = umtx_shm_find_reg(key, res); + if (error != ESRCH) { + /* + * Either no error occured, and '*res' was filled, or EOVERFLOW + * was returned, indicating a reference count limit, and we + * won't create a duplicate registration. In both cases, we are + * done. + */ + return (error); } + /* No entry, we will create one. */ + cred = td->td_ucred; if (!chgumtxcnt(cred->cr_ruidinfo, 1, lim_cur(td, RLIMIT_UMTXP))) return (ENOMEM); @@ -4488,12 +4516,20 @@ umtx_shm_create_reg(struct thread *td, const struct umtx_key *key, return (error); } mtx_lock(&umtx_shm_lock); - reg1 = umtx_shm_find_reg_locked(key); - if (reg1 != NULL) { + /* Re-lookup as 'umtx_shm_lock' has been temporarily released. */ + error = umtx_shm_find_reg_locked(key, ®1); + switch (error) { + case 0: mtx_unlock(&umtx_shm_lock); umtx_shm_free_reg(reg); *res = reg1; return (0); + case ESRCH: + break; + default: + mtx_unlock(&umtx_shm_lock); + umtx_shm_free_reg(reg); + return (error); } TAILQ_INSERT_TAIL(&umtx_shm_registry[key->hash], reg, ushm_reg_link); LIST_INSERT_HEAD(USHM_OBJ_UMTX(key->info.shared.object), reg, @@ -4564,13 +4600,9 @@ umtx_shm(struct thread *td, void *addr, u_int flags) if (error != 0) return (error); KASSERT(key.shared == 1, ("non-shared key")); - if ((flags & UMTX_SHM_CREAT) != 0) { - error = umtx_shm_create_reg(td, &key, ®); - } else { - reg = umtx_shm_find_reg(&key); - if (reg == NULL) - error = ESRCH; - } + error = (flags & UMTX_SHM_CREAT) != 0 ? + umtx_shm_create_reg(td, &key, ®) : + umtx_shm_find_reg(&key, ®); umtx_key_release(&key); if (error != 0) return (error); From c75a18905e308f69b01f19c3d7d613883a008e79 Mon Sep 17 00:00:00 2001 From: Olivier Certner Date: Wed, 4 Sep 2024 14:38:12 +0000 Subject: [PATCH 122/213] umtx: shm: 'ushm_refcnt > 0' => 'ushm_refcnt != 0' 'ushm_refcnt' is unsigned. Don't leave the impression it isn't. No functional change (intended). Reviewed by: kib Approved by: emaste (mentor) Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D46126 --- sys/kern/kern_umtx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/kern/kern_umtx.c b/sys/kern/kern_umtx.c index a6c160ab6283..705571930d7b 100644 --- a/sys/kern/kern_umtx.c +++ b/sys/kern/kern_umtx.c @@ -4360,7 +4360,7 @@ umtx_shm_find_reg_locked(const struct umtx_key *key, reg->ushm_key.info.shared.offset == key->info.shared.offset) { KASSERT(reg->ushm_key.type == TYPE_SHM, ("TYPE_USHM")); - KASSERT(reg->ushm_refcnt > 0, + KASSERT(reg->ushm_refcnt != 0, ("reg %p refcnt 0 onlist", reg)); KASSERT((reg->ushm_flags & USHMF_LINKED) != 0, ("reg %p not linked", reg)); @@ -4408,7 +4408,7 @@ static bool umtx_shm_unref_reg_locked(struct umtx_shm_reg *reg, bool linked_ref) { mtx_assert(&umtx_shm_lock, MA_OWNED); - KASSERT(reg->ushm_refcnt > 0, ("ushm_reg %p refcnt 0", reg)); + KASSERT(reg->ushm_refcnt != 0, ("ushm_reg %p refcnt 0", reg)); if (linked_ref) { if ((reg->ushm_flags & USHMF_LINKED) == 0) From a8ddd1926a34fc20970d9ceaad71b31fc414b1c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dag-Erling=20Sm=C3=B8rgrav?= Date: Wed, 4 Sep 2024 19:32:23 +0200 Subject: [PATCH 123/213] date: Fix a few nits. * Don't use `asprintf()` when `strdup()` can do the job just as well. * Fix a couple of typos in a comment. Fixes: eeb04a736cb9 MFC after: 3 days Sponsored by: Klara, Inc. Reviewed by: markj Differential Revision: https://reviews.freebsd.org/D46533 --- bin/date/date.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/bin/date/date.c b/bin/date/date.c index 3ce9ee3235fb..01797084c0d6 100644 --- a/bin/date/date.c +++ b/bin/date/date.c @@ -382,8 +382,8 @@ strftime_ns(char * __restrict s, size_t maxsize, const char * __restrict format, bool seen_percent; seen_percent = false; - if (asprintf(&newformat, "%s", format) < 0) - err(1, "asprintf"); + if ((newformat = strdup(format)) == NULL) + err(1, "strdup"); tok = newformat; for (tok = newformat; *tok != '\0'; tok++) { switch (*tok) { @@ -405,9 +405,9 @@ strftime_ns(char * __restrict s, size_t maxsize, const char * __restrict format, suffix = tok + 1; /* * Construct a new format string from the - * prefix (i.e., the part of the old fromat + * prefix (i.e., the part of the old format * from its beginning to the currently handled - * "%N" conversion specification, the + * "%N" conversion specification), the * nanoseconds, and the suffix (i.e., the part * of the old format from the next token to the * end). From 77eb877714d69ee0279d70eb3331920fba90db95 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Wed, 4 Sep 2024 15:53:17 -0400 Subject: [PATCH 124/213] grep: Fix various bugs in recursive tree handling The -OpS options were effectively ignored due to a collection of bugs in the use of fts(3): - fts_open(3) requires one of FTS_PHYSICAL or FTS_LOGICAL to be specified, but in the -O case, only FTS_COMFOLLOW was given. Fix this to use FTS_COMFOLLOW | FTS_PHYSICAL. - The switch on the entry type returned by fts_read() did not check for symbolic links, so symbolic links fell into the default case and were always passed to procfile() even when -p was given. Fix this by adding cases in the switch statement to explicitly ignore FTS_SL. - FTS_NOSTAT was passed to fts_open(), so fts_open() couldn't detect symbolic links when FTS_PHYSICAL was passed, instead both regular files and symbolic links were returned as FTS_NSOK entries. Fix by only using FTS_NOSTAT with FTS_LOGICAL. While here, fix a few other nits: - Treat FTS_NS as an error like FTS_DNR and FTS_ERR. - Just ignore FTS_DP. The logic to skip descending into skipped directories is only relevant when a directory is first visited, not after the directory has been visited. - Use warnc instead of warnx + strerror. PR: 280676 Reviewed by: kevans MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D46255 --- usr.bin/grep/util.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/usr.bin/grep/util.c b/usr.bin/grep/util.c index 936abc41b3ef..4e1c44b442f2 100644 --- a/usr.bin/grep/util.c +++ b/usr.bin/grep/util.c @@ -136,16 +136,16 @@ grep_tree(char **argv) /* This switch effectively initializes 'fts_flags' */ switch(linkbehave) { case LINK_EXPLICIT: - fts_flags = FTS_COMFOLLOW; + fts_flags = FTS_COMFOLLOW | FTS_PHYSICAL; break; case LINK_SKIP: fts_flags = FTS_PHYSICAL; break; default: - fts_flags = FTS_LOGICAL; + fts_flags = FTS_LOGICAL | FTS_NOSTAT; } - fts_flags |= FTS_NOSTAT | FTS_NOCHDIR; + fts_flags |= FTS_NOCHDIR; fts = fts_open((argv[0] == NULL) ? __DECONST(char * const *, wd) : argv, fts_flags, NULL); @@ -154,15 +154,13 @@ grep_tree(char **argv) while (errno = 0, (p = fts_read(fts)) != NULL) { switch (p->fts_info) { case FTS_DNR: - /* FALLTHROUGH */ case FTS_ERR: + case FTS_NS: file_err = true; if(!sflag) - warnx("%s: %s", p->fts_path, strerror(p->fts_errno)); + warnc(p->fts_errno, "%s", p->fts_path); break; case FTS_D: - /* FALLTHROUGH */ - case FTS_DP: if (dexclude || dinclude) if (!dir_matching(p->fts_name) || !dir_matching(p->fts_path)) @@ -173,6 +171,17 @@ grep_tree(char **argv) warnx("warning: %s: recursive directory loop", p->fts_path); break; + case FTS_DP: + break; + case FTS_SL: + /* + * Skip symlinks for LINK_EXPLICIT and + * LINK_SKIP. Note that due to FTS_COMFOLLOW, + * symlinks on the command line are followed + * for LINK_EXPLICIT and not reported as + * symlinks. + */ + break; default: /* Check for file exclusion/inclusion */ ok = true; From fc12c191c087b63e1204fee210ba76082ea40b96 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Wed, 4 Sep 2024 15:53:22 -0400 Subject: [PATCH 125/213] grep: Default to -p instead of -S. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This matches the documented behavior in the manpage as well as the default behavior on macOS. PR: 280676 Reported by: Radosław Piliszek Reviewed by: kevans MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D46256 --- usr.bin/grep/grep.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usr.bin/grep/grep.c b/usr.bin/grep/grep.c index 9f960f74dbb6..feaf17d7c1e1 100644 --- a/usr.bin/grep/grep.c +++ b/usr.bin/grep/grep.c @@ -112,7 +112,7 @@ int binbehave = BINFILE_BIN; /* -aIU: handling of binary files */ int filebehave = FILE_STDIO; int devbehave = DEV_READ; /* -D: handling of devices */ int dirbehave = DIR_READ; /* -dRr: handling of directories */ -int linkbehave = LINK_READ; /* -OpS: handling of symlinks */ +int linkbehave = LINK_SKIP; /* -OpS: handling of symlinks */ bool dexclude, dinclude; /* --exclude-dir and --include-dir */ bool fexclude, finclude; /* --exclude and --include */ From c47229ae66764fec85477e89d4f3861ac29abf48 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Thu, 6 Jun 2024 03:52:39 +0300 Subject: [PATCH 126/213] Intel DMAR: improve X2X macros to fix failures in certain syntax contexts Sponsored by: Advanced Micro Devices (AMD) Sponsored by: The FreeBSD Foundation MFC after: 1 week --- sys/x86/iommu/intel_dmar.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sys/x86/iommu/intel_dmar.h b/sys/x86/iommu/intel_dmar.h index b7f0300e16f0..9eb87bcfdc35 100644 --- a/sys/x86/iommu/intel_dmar.h +++ b/sys/x86/iommu/intel_dmar.h @@ -87,15 +87,15 @@ struct dmar_ctx { #define DMAR_DOMAIN_UNLOCK(dom) mtx_unlock(&(dom)->iodom.lock) #define DMAR_DOMAIN_ASSERT_LOCKED(dom) mtx_assert(&(dom)->iodom.lock, MA_OWNED) -#define DMAR2IOMMU(dmar) &((dmar)->iommu) +#define DMAR2IOMMU(dmar) (&((dmar)->iommu)) #define IOMMU2DMAR(dmar) \ __containerof((dmar), struct dmar_unit, iommu) -#define DOM2IODOM(domain) &((domain)->iodom) +#define DOM2IODOM(domain) (&((domain)->iodom)) #define IODOM2DOM(domain) \ __containerof((domain), struct dmar_domain, iodom) -#define CTX2IOCTX(ctx) &((ctx)->context) +#define CTX2IOCTX(ctx) (&((ctx)->context)) #define IOCTX2CTX(ctx) \ __containerof((ctx), struct dmar_ctx, context) From 0fcbf4944cb9865c6db0154c2f479fdd05b115c1 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Thu, 6 Jun 2024 03:39:52 +0300 Subject: [PATCH 127/213] DMAR: use DMAR2IOMMU() for DMAR_LOCK() and related macros Sponsored by: Advanced Micro Devices (AMD) Sponsored by: The FreeBSD Foundation MFC after: 1 week --- sys/x86/iommu/intel_dmar.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sys/x86/iommu/intel_dmar.h b/sys/x86/iommu/intel_dmar.h index 9eb87bcfdc35..4ae005238074 100644 --- a/sys/x86/iommu/intel_dmar.h +++ b/sys/x86/iommu/intel_dmar.h @@ -205,9 +205,9 @@ struct dmar_unit { struct taskqueue *qi_taskqueue; }; -#define DMAR_LOCK(dmar) mtx_lock(&(dmar)->iommu.lock) -#define DMAR_UNLOCK(dmar) mtx_unlock(&(dmar)->iommu.lock) -#define DMAR_ASSERT_LOCKED(dmar) mtx_assert(&(dmar)->iommu.lock, MA_OWNED) +#define DMAR_LOCK(dmar) mtx_lock(&DMAR2IOMMU(dmar)->lock) +#define DMAR_UNLOCK(dmar) mtx_unlock(&DMAR2IOMMU(dmar)->lock) +#define DMAR_ASSERT_LOCKED(dmar) mtx_assert(&DMAR2IOMMU(dmar)->lock, MA_OWNED) #define DMAR_FAULT_LOCK(dmar) mtx_lock_spin(&(dmar)->fault_lock) #define DMAR_FAULT_UNLOCK(dmar) mtx_unlock_spin(&(dmar)->fault_lock) From 65b133e5d292686fe20f11dd39b53812226a8684 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Wed, 29 May 2024 17:38:14 +0300 Subject: [PATCH 128/213] x86: allow to have more than one kind of IOMMU Sponsored by: Advanced Micro Devices (AMD) Sponsored by: The FreeBSD Foundation MFC after: 1 week --- sys/x86/iommu/intel_ctx.c | 22 ++++----- sys/x86/iommu/intel_dmar.h | 18 ++++++- sys/x86/iommu/intel_drv.c | 30 ++++++++++-- sys/x86/iommu/intel_intrmap.c | 10 ++-- sys/x86/iommu/iommu_utils.c | 91 ++++++++++++++++++++++++++++++++++- sys/x86/iommu/x86_iommu.h | 25 +++++++++- 6 files changed, 173 insertions(+), 23 deletions(-) diff --git a/sys/x86/iommu/intel_ctx.c b/sys/x86/iommu/intel_ctx.c index baee0109e5a9..a3ff35dc527e 100644 --- a/sys/x86/iommu/intel_ctx.c +++ b/sys/x86/iommu/intel_ctx.c @@ -75,6 +75,9 @@ static void dmar_unref_domain_locked(struct dmar_unit *dmar, struct dmar_domain *domain); static void dmar_domain_destroy(struct dmar_domain *domain); +static void dmar_free_ctx_locked(struct dmar_unit *dmar, struct dmar_ctx *ctx); +static void dmar_free_ctx(struct dmar_ctx *ctx); + static void dmar_ensure_ctx_page(struct dmar_unit *dmar, int bus) { @@ -745,7 +748,7 @@ dmar_unref_domain_locked(struct dmar_unit *dmar, struct dmar_domain *domain) dmar_domain_destroy(domain); } -void +static void dmar_free_ctx_locked(struct dmar_unit *dmar, struct dmar_ctx *ctx) { struct sf_buf *sf; @@ -819,7 +822,7 @@ dmar_free_ctx_locked(struct dmar_unit *dmar, struct dmar_ctx *ctx) TD_PINNED_ASSERT; } -void +static void dmar_free_ctx(struct dmar_ctx *ctx) { struct dmar_unit *dmar; @@ -867,7 +870,7 @@ dmar_domain_free_entry(struct iommu_map_entry *entry, bool free) * the entry's dmamap_link field. */ void -iommu_domain_unload_entry(struct iommu_map_entry *entry, bool free, +dmar_domain_unload_entry(struct iommu_map_entry *entry, bool free, bool cansleep) { struct dmar_domain *domain; @@ -909,7 +912,7 @@ dmar_domain_unload_emit_wait(struct dmar_domain *domain, } void -iommu_domain_unload(struct iommu_domain *iodom, +dmar_domain_unload(struct iommu_domain *iodom, struct iommu_map_entries_tailq *entries, bool cansleep) { struct dmar_domain *domain; @@ -947,37 +950,34 @@ iommu_domain_unload(struct iommu_domain *iodom, } struct iommu_ctx * -iommu_get_ctx(struct iommu_unit *iommu, device_t dev, uint16_t rid, +dmar_get_ctx(struct iommu_unit *iommu, device_t dev, uint16_t rid, bool id_mapped, bool rmrr_init) { struct dmar_unit *dmar; struct dmar_ctx *ret; dmar = IOMMU2DMAR(iommu); - ret = dmar_get_ctx_for_dev(dmar, dev, rid, id_mapped, rmrr_init); - return (CTX2IOCTX(ret)); } void -iommu_free_ctx_locked(struct iommu_unit *iommu, struct iommu_ctx *context) +dmar_free_ctx_locked_method(struct iommu_unit *iommu, + struct iommu_ctx *context) { struct dmar_unit *dmar; struct dmar_ctx *ctx; dmar = IOMMU2DMAR(iommu); ctx = IOCTX2CTX(context); - dmar_free_ctx_locked(dmar, ctx); } void -iommu_free_ctx(struct iommu_ctx *context) +dmar_free_ctx_method(struct iommu_ctx *context) { struct dmar_ctx *ctx; ctx = IOCTX2CTX(context); - dmar_free_ctx(ctx); } diff --git a/sys/x86/iommu/intel_dmar.h b/sys/x86/iommu/intel_dmar.h index 4ae005238074..0ede955e12b9 100644 --- a/sys/x86/iommu/intel_dmar.h +++ b/sys/x86/iommu/intel_dmar.h @@ -293,10 +293,17 @@ struct dmar_ctx *dmar_get_ctx_for_devpath(struct dmar_unit *dmar, uint16_t rid, int dev_domain, int dev_busno, const void *dev_path, int dev_path_len, bool id_mapped, bool rmrr_init); int dmar_move_ctx_to_domain(struct dmar_domain *domain, struct dmar_ctx *ctx); -void dmar_free_ctx_locked(struct dmar_unit *dmar, struct dmar_ctx *ctx); -void dmar_free_ctx(struct dmar_ctx *ctx); +void dmar_free_ctx_locked_method(struct iommu_unit *dmar, + struct iommu_ctx *ctx); +void dmar_free_ctx_method(struct iommu_ctx *ctx); struct dmar_ctx *dmar_find_ctx_locked(struct dmar_unit *dmar, uint16_t rid); +struct iommu_ctx *dmar_get_ctx(struct iommu_unit *iommu, device_t dev, + uint16_t rid, bool id_mapped, bool rmrr_init); void dmar_domain_free_entry(struct iommu_map_entry *entry, bool free); +void dmar_domain_unload_entry(struct iommu_map_entry *entry, bool free, + bool cansleep); +void dmar_domain_unload(struct iommu_domain *iodom, + struct iommu_map_entries_tailq *entries, bool cansleep); void dmar_dev_parse_rmrr(struct dmar_domain *domain, int dev_domain, int dev_busno, const void *dev_path, int dev_path_len, @@ -308,6 +315,13 @@ void dmar_quirks_pre_use(struct iommu_unit *dmar); int dmar_init_irt(struct dmar_unit *unit); void dmar_fini_irt(struct dmar_unit *unit); +int dmar_alloc_msi_intr(device_t src, u_int *cookies, u_int count); +int dmar_map_msi_intr(device_t src, u_int cpu, u_int vector, u_int cookie, + uint64_t *addr, uint32_t *data); +int dmar_unmap_msi_intr(device_t src, u_int cookie); +int dmar_map_ioapic_intr(u_int ioapic_id, u_int cpu, u_int vector, bool edge, + bool activehi, int irq, u_int *cookie, uint32_t *hi, uint32_t *lo); +int dmar_unmap_ioapic_intr(u_int ioapic_id, u_int *cookie); extern int haw; extern int dmar_batch_coalesce; diff --git a/sys/x86/iommu/intel_drv.c b/sys/x86/iommu/intel_drv.c index 636534173715..79350358cced 100644 --- a/sys/x86/iommu/intel_drv.c +++ b/sys/x86/iommu/intel_drv.c @@ -64,6 +64,8 @@ #include #include #include +#include +#include #include #include #include @@ -1357,12 +1359,34 @@ DB_SHOW_ALL_COMMAND(dmars, db_show_all_dmars) } #endif -struct iommu_unit * -iommu_find(device_t dev, bool verbose) +static struct iommu_unit * +dmar_find_method(device_t dev, bool verbose) { struct dmar_unit *dmar; dmar = dmar_find(dev, verbose); - return (&dmar->iommu); } + +static struct x86_iommu dmar_x86_iommu = { + .domain_unload_entry = dmar_domain_unload_entry, + .domain_unload = dmar_domain_unload, + .get_ctx = dmar_get_ctx, + .free_ctx_locked = dmar_free_ctx_locked_method, + .free_ctx = dmar_free_ctx_method, + .find = dmar_find_method, + .alloc_msi_intr = dmar_alloc_msi_intr, + .map_msi_intr = dmar_map_msi_intr, + .unmap_msi_intr = dmar_unmap_msi_intr, + .map_ioapic_intr = dmar_map_ioapic_intr, + .unmap_ioapic_intr = dmar_unmap_ioapic_intr, +}; + +static void +x86_iommu_set_intel(void *arg __unused) +{ + if (cpu_vendor_id == CPU_VENDOR_INTEL) + set_x86_iommu(&dmar_x86_iommu); +} + +SYSINIT(x86_iommu, SI_SUB_TUNABLES, SI_ORDER_ANY, x86_iommu_set_intel, NULL); diff --git a/sys/x86/iommu/intel_intrmap.c b/sys/x86/iommu/intel_intrmap.c index 22fd51bc8be9..a6979a9d2501 100644 --- a/sys/x86/iommu/intel_intrmap.c +++ b/sys/x86/iommu/intel_intrmap.c @@ -65,7 +65,7 @@ static void dmar_ir_program_irte(struct dmar_unit *unit, u_int idx, static int dmar_ir_free_irte(struct dmar_unit *unit, u_int cookie); int -iommu_alloc_msi_intr(device_t src, u_int *cookies, u_int count) +dmar_alloc_msi_intr(device_t src, u_int *cookies, u_int count) { struct dmar_unit *unit; vmem_addr_t vmem_res; @@ -93,7 +93,7 @@ iommu_alloc_msi_intr(device_t src, u_int *cookies, u_int count) } int -iommu_map_msi_intr(device_t src, u_int cpu, u_int vector, u_int cookie, +dmar_map_msi_intr(device_t src, u_int cpu, u_int vector, u_int cookie, uint64_t *addr, uint32_t *data) { struct dmar_unit *unit; @@ -139,7 +139,7 @@ iommu_map_msi_intr(device_t src, u_int cpu, u_int vector, u_int cookie, } int -iommu_unmap_msi_intr(device_t src, u_int cookie) +dmar_unmap_msi_intr(device_t src, u_int cookie) { struct dmar_unit *unit; @@ -150,7 +150,7 @@ iommu_unmap_msi_intr(device_t src, u_int cookie) } int -iommu_map_ioapic_intr(u_int ioapic_id, u_int cpu, u_int vector, bool edge, +dmar_map_ioapic_intr(u_int ioapic_id, u_int cpu, u_int vector, bool edge, bool activehi, int irq, u_int *cookie, uint32_t *hi, uint32_t *lo) { struct dmar_unit *unit; @@ -213,7 +213,7 @@ iommu_map_ioapic_intr(u_int ioapic_id, u_int cpu, u_int vector, bool edge, } int -iommu_unmap_ioapic_intr(u_int ioapic_id, u_int *cookie) +dmar_unmap_ioapic_intr(u_int ioapic_id, u_int *cookie) { struct dmar_unit *unit; u_int idx; diff --git a/sys/x86/iommu/iommu_utils.c b/sys/x86/iommu/iommu_utils.c index ffea1cc1a190..ea2c0358e072 100644 --- a/sys/x86/iommu/iommu_utils.c +++ b/sys/x86/iommu/iommu_utils.c @@ -1,7 +1,7 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * - * Copyright (c) 2013, 2014 The FreeBSD Foundation + * Copyright (c) 2013, 2014, 2024 The FreeBSD Foundation * * This software was developed by Konstantin Belousov * under sponsorship from the FreeBSD Foundation. @@ -50,6 +50,7 @@ #include #include #include +#include vm_page_t iommu_pgalloc(vm_object_t obj, vm_pindex_t idx, int flags) @@ -162,3 +163,91 @@ SYSCTL_NODE(_hw_iommu, OID_AUTO, dmar, CTLFLAG_RD | CTLFLAG_MPSAFE, SYSCTL_INT(_hw_iommu_dmar, OID_AUTO, tbl_pagecnt, CTLFLAG_RD, &iommu_tbl_pagecnt, 0, "Count of pages used for DMAR pagetables"); + +static struct x86_iommu *x86_iommu; + +void +set_x86_iommu(struct x86_iommu *x) +{ + MPASS(x86_iommu == NULL); + x86_iommu = x; +} + +struct x86_iommu * +get_x86_iommu(void) +{ + return (x86_iommu); +} + +void +iommu_domain_unload_entry(struct iommu_map_entry *entry, bool free, + bool cansleep) +{ + x86_iommu->domain_unload_entry(entry, free, cansleep); +} + +void +iommu_domain_unload(struct iommu_domain *iodom, + struct iommu_map_entries_tailq *entries, bool cansleep) +{ + x86_iommu->domain_unload(iodom, entries, cansleep); +} + +struct iommu_ctx * +iommu_get_ctx(struct iommu_unit *iommu, device_t dev, uint16_t rid, + bool id_mapped, bool rmrr_init) +{ + return (x86_iommu->get_ctx(iommu, dev, rid, id_mapped, rmrr_init)); +} + +void +iommu_free_ctx_locked(struct iommu_unit *iommu, struct iommu_ctx *context) +{ + x86_iommu->free_ctx_locked(iommu, context); +} + +void +iommu_free_ctx(struct iommu_ctx *context) +{ + x86_iommu->free_ctx(context); +} + +struct iommu_unit * +iommu_find(device_t dev, bool verbose) +{ + return (x86_iommu->find(dev, verbose)); +} + +int +iommu_alloc_msi_intr(device_t src, u_int *cookies, u_int count) +{ + return (x86_iommu->alloc_msi_intr(src, cookies, count)); +} + +int +iommu_map_msi_intr(device_t src, u_int cpu, u_int vector, u_int cookie, + uint64_t *addr, uint32_t *data) +{ + return (x86_iommu->map_msi_intr(src, cpu, vector, cookie, + addr, data)); +} + +int +iommu_unmap_msi_intr(device_t src, u_int cookie) +{ + return (x86_iommu->unmap_msi_intr(src, cookie)); +} + +int +iommu_map_ioapic_intr(u_int ioapic_id, u_int cpu, u_int vector, bool edge, + bool activehi, int irq, u_int *cookie, uint32_t *hi, uint32_t *lo) +{ + return (x86_iommu->map_ioapic_intr(ioapic_id, cpu, vector, edge, + activehi, irq, cookie, hi, lo)); +} + +int +iommu_unmap_ioapic_intr(u_int ioapic_id, u_int *cookie) +{ + return (x86_iommu->unmap_ioapic_intr(ioapic_id, cookie)); +} diff --git a/sys/x86/iommu/x86_iommu.h b/sys/x86/iommu/x86_iommu.h index 3789586f1eaf..8c908964acd0 100644 --- a/sys/x86/iommu/x86_iommu.h +++ b/sys/x86/iommu/x86_iommu.h @@ -1,7 +1,7 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * - * Copyright (c) 2013-2015 The FreeBSD Foundation + * Copyright (c) 2013-2015, 2024 The FreeBSD Foundation * * This software was developed by Konstantin Belousov * under sponsorship from the FreeBSD Foundation. @@ -59,4 +59,27 @@ extern int iommu_tbl_pagecnt; SYSCTL_DECL(_hw_iommu); SYSCTL_DECL(_hw_iommu_dmar); +struct x86_iommu { + void (*domain_unload_entry)(struct iommu_map_entry *entry, bool free, + bool cansleep); + void (*domain_unload)(struct iommu_domain *iodom, + struct iommu_map_entries_tailq *entries, bool cansleep); + struct iommu_ctx *(*get_ctx)(struct iommu_unit *iommu, + device_t dev, uint16_t rid, bool id_mapped, bool rmrr_init); + void (*free_ctx_locked)(struct iommu_unit *iommu, + struct iommu_ctx *context); + void (*free_ctx)(struct iommu_ctx *context); + struct iommu_unit *(*find)(device_t dev, bool verbose); + int (*alloc_msi_intr)(device_t src, u_int *cookies, u_int count); + int (*map_msi_intr)(device_t src, u_int cpu, u_int vector, + u_int cookie, uint64_t *addr, uint32_t *data); + int (*unmap_msi_intr)(device_t src, u_int cookie); + int (*map_ioapic_intr)(u_int ioapic_id, u_int cpu, u_int vector, + bool edge, bool activehi, int irq, u_int *cookie, uint32_t *hi, + uint32_t *lo); + int (*unmap_ioapic_intr)(u_int ioapic_id, u_int *cookie); +}; +void set_x86_iommu(struct x86_iommu *); +struct x86_iommu *get_x86_iommu(void); + #endif From ad794e6d7d02a11b01e721859e096efeb258a4d4 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Thu, 6 Jun 2024 04:16:36 +0300 Subject: [PATCH 129/213] x86 iommu: move DMAR-independent parts of the qi code into common Sponsored by: Advanced Micro Devices (AMD) Sponsored by: The FreeBSD Foundation MFC after: 1 week --- sys/x86/iommu/intel_ctx.c | 7 +- sys/x86/iommu/intel_dmar.h | 42 +---- sys/x86/iommu/intel_drv.c | 26 ++- sys/x86/iommu/intel_qi.c | 330 ++++++++++-------------------------- sys/x86/iommu/iommu_utils.c | 234 ++++++++++++++++++++++++- sys/x86/iommu/x86_iommu.h | 72 ++++++++ 6 files changed, 413 insertions(+), 298 deletions(-) diff --git a/sys/x86/iommu/intel_ctx.c b/sys/x86/iommu/intel_ctx.c index a3ff35dc527e..03ef196c4cb0 100644 --- a/sys/x86/iommu/intel_ctx.c +++ b/sys/x86/iommu/intel_ctx.c @@ -887,10 +887,11 @@ dmar_domain_unload_entry(struct iommu_map_entry *entry, bool free, if (unit->qi_enabled) { if (free) { DMAR_LOCK(unit); - dmar_qi_invalidate_locked(domain, entry, true); + iommu_qi_invalidate_locked(&domain->iodom, entry, + true); DMAR_UNLOCK(unit); } else { - dmar_qi_invalidate_sync(domain, entry->start, + iommu_qi_invalidate_sync(&domain->iodom, entry->start, entry->end - entry->start, cansleep); dmar_domain_free_entry(entry, false); } @@ -943,7 +944,7 @@ dmar_domain_unload(struct iommu_domain *iodom, DMAR_LOCK(unit); while ((entry = TAILQ_FIRST(entries)) != NULL) { TAILQ_REMOVE(entries, entry, dmamap_link); - dmar_qi_invalidate_locked(domain, entry, + iommu_qi_invalidate_locked(&domain->iodom, entry, dmar_domain_unload_emit_wait(domain, entry)); } DMAR_UNLOCK(unit); diff --git a/sys/x86/iommu/intel_dmar.h b/sys/x86/iommu/intel_dmar.h index 0ede955e12b9..8a815d5cfca6 100644 --- a/sys/x86/iommu/intel_dmar.h +++ b/sys/x86/iommu/intel_dmar.h @@ -123,6 +123,7 @@ struct dmar_msi_data { struct dmar_unit { struct iommu_unit iommu; + struct x86_unit_common x86c; uint16_t segment; uint64_t base; @@ -155,17 +156,6 @@ struct dmar_unit { /* QI */ int qi_enabled; - char *inv_queue; - vm_size_t inv_queue_size; - uint32_t inv_queue_avail; - uint32_t inv_queue_tail; - volatile uint32_t inv_waitd_seq_hw; /* hw writes there on wait - descr completion */ - uint64_t inv_waitd_seq_hw_phys; - uint32_t inv_waitd_seq; /* next sequence number to use for wait descr */ - u_int inv_waitd_gen; /* seq number generation AKA seq overflows */ - u_int inv_seq_waiters; /* count of waiters for seq */ - u_int inv_queue_full; /* informational counter */ /* IR */ int ir_enabled; @@ -173,36 +163,6 @@ struct dmar_unit { dmar_irte_t *irt; u_int irte_cnt; vmem_t *irtids; - - /* - * Delayed freeing of map entries queue processing: - * - * tlb_flush_head and tlb_flush_tail are used to implement a FIFO - * queue that supports concurrent dequeues and enqueues. However, - * there can only be a single dequeuer (accessing tlb_flush_head) and - * a single enqueuer (accessing tlb_flush_tail) at a time. Since the - * unit's qi_task is the only dequeuer, it can access tlb_flush_head - * without any locking. In contrast, there may be multiple enqueuers, - * so the enqueuers acquire the iommu unit lock to serialize their - * accesses to tlb_flush_tail. - * - * In this FIFO queue implementation, the key to enabling concurrent - * dequeues and enqueues is that the dequeuer never needs to access - * tlb_flush_tail and the enqueuer never needs to access - * tlb_flush_head. In particular, tlb_flush_head and tlb_flush_tail - * are never NULL, so neither a dequeuer nor an enqueuer ever needs to - * update both. Instead, tlb_flush_head always points to a "zombie" - * struct, which previously held the last dequeued item. Thus, the - * zombie's next field actually points to the struct holding the first - * item in the queue. When an item is dequeued, the current zombie is - * finally freed, and the struct that held the just dequeued item - * becomes the new zombie. When the queue is empty, tlb_flush_tail - * also points to the zombie. - */ - struct iommu_map_entry *tlb_flush_head; - struct iommu_map_entry *tlb_flush_tail; - struct task qi_task; - struct taskqueue *qi_taskqueue; }; #define DMAR_LOCK(dmar) mtx_lock(&DMAR2IOMMU(dmar)->lock) diff --git a/sys/x86/iommu/intel_drv.c b/sys/x86/iommu/intel_drv.c index 79350358cced..9fa1b3f98dc6 100644 --- a/sys/x86/iommu/intel_drv.c +++ b/sys/x86/iommu/intel_drv.c @@ -1303,19 +1303,19 @@ dmar_print_one(int idx, bool show_domains, bool show_mappings) "size 0x%jx\n" " head 0x%x tail 0x%x avail 0x%x status 0x%x ctrl 0x%x\n" " hw compl 0x%x@%p/phys@%jx next seq 0x%x gen 0x%x\n", - (uintmax_t)unit->inv_queue, + (uintmax_t)unit->x86c.inv_queue, (uintmax_t)dmar_read8(unit, DMAR_IQA_REG), - (uintmax_t)unit->inv_queue_size, + (uintmax_t)unit->x86c.inv_queue_size, dmar_read4(unit, DMAR_IQH_REG), dmar_read4(unit, DMAR_IQT_REG), - unit->inv_queue_avail, + unit->x86c.inv_queue_avail, dmar_read4(unit, DMAR_ICS_REG), dmar_read4(unit, DMAR_IECTL_REG), - unit->inv_waitd_seq_hw, - &unit->inv_waitd_seq_hw, - (uintmax_t)unit->inv_waitd_seq_hw_phys, - unit->inv_waitd_seq, - unit->inv_waitd_gen); + unit->x86c.inv_waitd_seq_hw, + &unit->x86c.inv_waitd_seq_hw, + (uintmax_t)unit->x86c.inv_waitd_seq_hw_phys, + unit->x86c.inv_waitd_seq, + unit->x86c.inv_waitd_gen); } else { db_printf("qi is disabled\n"); } @@ -1368,7 +1368,17 @@ dmar_find_method(device_t dev, bool verbose) return (&dmar->iommu); } +static struct x86_unit_common * +dmar_get_x86_common(struct iommu_unit *unit) +{ + struct dmar_unit *dmar; + + dmar = IOMMU2DMAR(unit); + return (&dmar->x86c); +} + static struct x86_iommu dmar_x86_iommu = { + .get_x86_common = dmar_get_x86_common, .domain_unload_entry = dmar_domain_unload_entry, .domain_unload = dmar_domain_unload, .get_ctx = dmar_get_ctx, diff --git a/sys/x86/iommu/intel_qi.c b/sys/x86/iommu/intel_qi.c index 590cbac9bcbd..a94fbb54e7f7 100644 --- a/sys/x86/iommu/intel_qi.c +++ b/sys/x86/iommu/intel_qi.c @@ -58,17 +58,6 @@ #include #include -static bool -dmar_qi_seq_processed(const struct dmar_unit *unit, - const struct iommu_qi_genseq *pseq) -{ - u_int gen; - - gen = unit->inv_waitd_gen; - return (pseq->gen < gen || - (pseq->gen == gen && pseq->seq <= unit->inv_waitd_seq_hw)); -} - static int dmar_enable_qi(struct dmar_unit *unit) { @@ -96,32 +85,36 @@ dmar_disable_qi(struct dmar_unit *unit) } static void -dmar_qi_advance_tail(struct dmar_unit *unit) +dmar_qi_advance_tail(struct iommu_unit *iommu) { + struct dmar_unit *unit; + unit = IOMMU2DMAR(iommu); DMAR_ASSERT_LOCKED(unit); - dmar_write4(unit, DMAR_IQT_REG, unit->inv_queue_tail); + dmar_write4(unit, DMAR_IQT_REG, unit->x86c.inv_queue_tail); } static void -dmar_qi_ensure(struct dmar_unit *unit, int descr_count) +dmar_qi_ensure(struct iommu_unit *iommu, int descr_count) { + struct dmar_unit *unit; uint32_t head; int bytes; + unit = IOMMU2DMAR(iommu); DMAR_ASSERT_LOCKED(unit); bytes = descr_count << DMAR_IQ_DESCR_SZ_SHIFT; for (;;) { - if (bytes <= unit->inv_queue_avail) + if (bytes <= unit->x86c.inv_queue_avail) break; /* refill */ head = dmar_read4(unit, DMAR_IQH_REG); head &= DMAR_IQH_MASK; - unit->inv_queue_avail = head - unit->inv_queue_tail - + unit->x86c.inv_queue_avail = head - unit->x86c.inv_queue_tail - DMAR_IQ_DESCR_SZ; - if (head <= unit->inv_queue_tail) - unit->inv_queue_avail += unit->inv_queue_size; - if (bytes <= unit->inv_queue_avail) + if (head <= unit->x86c.inv_queue_tail) + unit->x86c.inv_queue_avail += unit->x86c.inv_queue_size; + if (bytes <= unit->x86c.inv_queue_avail) break; /* @@ -134,11 +127,11 @@ dmar_qi_ensure(struct dmar_unit *unit, int descr_count) * See dmar_qi_invalidate_locked() for a discussion * about data race prevention. */ - dmar_qi_advance_tail(unit); - unit->inv_queue_full++; + dmar_qi_advance_tail(DMAR2IOMMU(unit)); + unit->x86c.inv_queue_full++; cpu_spinwait(); } - unit->inv_queue_avail -= bytes; + unit->x86c.inv_queue_avail -= bytes; } static void @@ -146,162 +139,60 @@ dmar_qi_emit(struct dmar_unit *unit, uint64_t data1, uint64_t data2) { DMAR_ASSERT_LOCKED(unit); - *(volatile uint64_t *)(unit->inv_queue + unit->inv_queue_tail) = data1; - unit->inv_queue_tail += DMAR_IQ_DESCR_SZ / 2; - KASSERT(unit->inv_queue_tail <= unit->inv_queue_size, - ("tail overflow 0x%x 0x%jx", unit->inv_queue_tail, - (uintmax_t)unit->inv_queue_size)); - unit->inv_queue_tail &= unit->inv_queue_size - 1; - *(volatile uint64_t *)(unit->inv_queue + unit->inv_queue_tail) = data2; - unit->inv_queue_tail += DMAR_IQ_DESCR_SZ / 2; - KASSERT(unit->inv_queue_tail <= unit->inv_queue_size, - ("tail overflow 0x%x 0x%jx", unit->inv_queue_tail, - (uintmax_t)unit->inv_queue_size)); - unit->inv_queue_tail &= unit->inv_queue_size - 1; + *(volatile uint64_t *)(unit->x86c.inv_queue + + unit->x86c.inv_queue_tail) = data1; + unit->x86c.inv_queue_tail += DMAR_IQ_DESCR_SZ / 2; + KASSERT(unit->x86c.inv_queue_tail <= unit->x86c.inv_queue_size, + ("tail overflow 0x%x 0x%jx", unit->x86c.inv_queue_tail, + (uintmax_t)unit->x86c.inv_queue_size)); + unit->x86c.inv_queue_tail &= unit->x86c.inv_queue_size - 1; + *(volatile uint64_t *)(unit->x86c.inv_queue + + unit->x86c.inv_queue_tail) = data2; + unit->x86c.inv_queue_tail += DMAR_IQ_DESCR_SZ / 2; + KASSERT(unit->x86c.inv_queue_tail <= unit->x86c.inv_queue_size, + ("tail overflow 0x%x 0x%jx", unit->x86c.inv_queue_tail, + (uintmax_t)unit->x86c.inv_queue_size)); + unit->x86c.inv_queue_tail &= unit->x86c.inv_queue_size - 1; } static void -dmar_qi_emit_wait_descr(struct dmar_unit *unit, uint32_t seq, bool intr, +dmar_qi_emit_wait_descr(struct iommu_unit *iommu, uint32_t seq, bool intr, bool memw, bool fence) { + struct dmar_unit *unit; + unit = IOMMU2DMAR(iommu); DMAR_ASSERT_LOCKED(unit); dmar_qi_emit(unit, DMAR_IQ_DESCR_WAIT_ID | (intr ? DMAR_IQ_DESCR_WAIT_IF : 0) | (memw ? DMAR_IQ_DESCR_WAIT_SW : 0) | (fence ? DMAR_IQ_DESCR_WAIT_FN : 0) | (memw ? DMAR_IQ_DESCR_WAIT_SD(seq) : 0), - memw ? unit->inv_waitd_seq_hw_phys : 0); -} - -static void -dmar_qi_emit_wait_seq(struct dmar_unit *unit, struct iommu_qi_genseq *pseq, - bool emit_wait) -{ - struct iommu_qi_genseq gsec; - uint32_t seq; - - KASSERT(pseq != NULL, ("wait descriptor with no place for seq")); - DMAR_ASSERT_LOCKED(unit); - if (unit->inv_waitd_seq == 0xffffffff) { - gsec.gen = unit->inv_waitd_gen; - gsec.seq = unit->inv_waitd_seq; - dmar_qi_ensure(unit, 1); - dmar_qi_emit_wait_descr(unit, gsec.seq, false, true, false); - dmar_qi_advance_tail(unit); - while (!dmar_qi_seq_processed(unit, &gsec)) - cpu_spinwait(); - unit->inv_waitd_gen++; - unit->inv_waitd_seq = 1; - } - seq = unit->inv_waitd_seq++; - pseq->gen = unit->inv_waitd_gen; - pseq->seq = seq; - if (emit_wait) { - dmar_qi_ensure(unit, 1); - dmar_qi_emit_wait_descr(unit, seq, true, true, false); - } + memw ? unit->x86c.inv_waitd_seq_hw_phys : 0); } -/* - * To avoid missed wakeups, callers must increment the unit's waiters count - * before advancing the tail past the wait descriptor. - */ static void -dmar_qi_wait_for_seq(struct dmar_unit *unit, const struct iommu_qi_genseq *gseq, - bool nowait) -{ - - DMAR_ASSERT_LOCKED(unit); - KASSERT(unit->inv_seq_waiters > 0, ("%s: no waiters", __func__)); - while (!dmar_qi_seq_processed(unit, gseq)) { - if (cold || nowait) { - cpu_spinwait(); - } else { - msleep(&unit->inv_seq_waiters, &unit->iommu.lock, 0, - "dmarse", hz); - } - } - unit->inv_seq_waiters--; -} - -static void -dmar_qi_invalidate_emit(struct dmar_domain *domain, iommu_gaddr_t base, +dmar_qi_invalidate_emit(struct iommu_domain *idomain, iommu_gaddr_t base, iommu_gaddr_t size, struct iommu_qi_genseq *pseq, bool emit_wait) { struct dmar_unit *unit; + struct dmar_domain *domain; iommu_gaddr_t isize; int am; + domain = __containerof(idomain, struct dmar_domain, iodom); unit = domain->dmar; DMAR_ASSERT_LOCKED(unit); for (; size > 0; base += isize, size -= isize) { am = calc_am(unit, base, size, &isize); - dmar_qi_ensure(unit, 1); + dmar_qi_ensure(DMAR2IOMMU(unit), 1); dmar_qi_emit(unit, DMAR_IQ_DESCR_IOTLB_INV | DMAR_IQ_DESCR_IOTLB_PAGE | DMAR_IQ_DESCR_IOTLB_DW | DMAR_IQ_DESCR_IOTLB_DR | DMAR_IQ_DESCR_IOTLB_DID(domain->domain), base | am); } - dmar_qi_emit_wait_seq(unit, pseq, emit_wait); -} - -/* - * The caller must not be using the entry's dmamap_link field. - */ -void -dmar_qi_invalidate_locked(struct dmar_domain *domain, - struct iommu_map_entry *entry, bool emit_wait) -{ - struct dmar_unit *unit; - - unit = domain->dmar; - DMAR_ASSERT_LOCKED(unit); - dmar_qi_invalidate_emit(domain, entry->start, entry->end - - entry->start, &entry->gseq, emit_wait); - - /* - * To avoid a data race in dmar_qi_task(), the entry's gseq must be - * initialized before the entry is added to the TLB flush list, and the - * entry must be added to that list before the tail is advanced. More - * precisely, the tail must not be advanced past the wait descriptor - * that will generate the interrupt that schedules dmar_qi_task() for - * execution before the entry is added to the list. While an earlier - * call to dmar_qi_ensure() might have advanced the tail, it will not - * advance it past the wait descriptor. - * - * See the definition of struct dmar_unit for more information on - * synchronization. - */ - entry->tlb_flush_next = NULL; - atomic_store_rel_ptr((uintptr_t *)&unit->tlb_flush_tail->tlb_flush_next, - (uintptr_t)entry); - unit->tlb_flush_tail = entry; - - dmar_qi_advance_tail(unit); -} - -void -dmar_qi_invalidate_sync(struct dmar_domain *domain, iommu_gaddr_t base, - iommu_gaddr_t size, bool cansleep) -{ - struct dmar_unit *unit; - struct iommu_qi_genseq gseq; - - unit = domain->dmar; - DMAR_LOCK(unit); - dmar_qi_invalidate_emit(domain, base, size, &gseq, true); - - /* - * To avoid a missed wakeup in dmar_qi_task(), the unit's waiters count - * must be incremented before the tail is advanced. - */ - unit->inv_seq_waiters++; - - dmar_qi_advance_tail(unit); - dmar_qi_wait_for_seq(unit, &gseq, !cansleep); - DMAR_UNLOCK(unit); + iommu_qi_emit_wait_seq(DMAR2IOMMU(unit), pseq, emit_wait); } void @@ -310,13 +201,13 @@ dmar_qi_invalidate_ctx_glob_locked(struct dmar_unit *unit) struct iommu_qi_genseq gseq; DMAR_ASSERT_LOCKED(unit); - dmar_qi_ensure(unit, 2); + dmar_qi_ensure(DMAR2IOMMU(unit), 2); dmar_qi_emit(unit, DMAR_IQ_DESCR_CTX_INV | DMAR_IQ_DESCR_CTX_GLOB, 0); - dmar_qi_emit_wait_seq(unit, &gseq, true); + iommu_qi_emit_wait_seq(DMAR2IOMMU(unit), &gseq, true); /* See dmar_qi_invalidate_sync(). */ - unit->inv_seq_waiters++; - dmar_qi_advance_tail(unit); - dmar_qi_wait_for_seq(unit, &gseq, false); + unit->x86c.inv_seq_waiters++; + dmar_qi_advance_tail(DMAR2IOMMU(unit)); + iommu_qi_wait_for_seq(DMAR2IOMMU(unit), &gseq, false); } void @@ -325,14 +216,14 @@ dmar_qi_invalidate_iotlb_glob_locked(struct dmar_unit *unit) struct iommu_qi_genseq gseq; DMAR_ASSERT_LOCKED(unit); - dmar_qi_ensure(unit, 2); + dmar_qi_ensure(DMAR2IOMMU(unit), 2); dmar_qi_emit(unit, DMAR_IQ_DESCR_IOTLB_INV | DMAR_IQ_DESCR_IOTLB_GLOB | DMAR_IQ_DESCR_IOTLB_DW | DMAR_IQ_DESCR_IOTLB_DR, 0); - dmar_qi_emit_wait_seq(unit, &gseq, true); + iommu_qi_emit_wait_seq(DMAR2IOMMU(unit), &gseq, true); /* See dmar_qi_invalidate_sync(). */ - unit->inv_seq_waiters++; - dmar_qi_advance_tail(unit); - dmar_qi_wait_for_seq(unit, &gseq, false); + unit->x86c.inv_seq_waiters++; + dmar_qi_advance_tail(DMAR2IOMMU(unit)); + iommu_qi_wait_for_seq(DMAR2IOMMU(unit), &gseq, false); } void @@ -341,13 +232,13 @@ dmar_qi_invalidate_iec_glob(struct dmar_unit *unit) struct iommu_qi_genseq gseq; DMAR_ASSERT_LOCKED(unit); - dmar_qi_ensure(unit, 2); + dmar_qi_ensure(DMAR2IOMMU(unit), 2); dmar_qi_emit(unit, DMAR_IQ_DESCR_IEC_INV, 0); - dmar_qi_emit_wait_seq(unit, &gseq, true); + iommu_qi_emit_wait_seq(DMAR2IOMMU(unit), &gseq, true); /* See dmar_qi_invalidate_sync(). */ - unit->inv_seq_waiters++; - dmar_qi_advance_tail(unit); - dmar_qi_wait_for_seq(unit, &gseq, false); + unit->x86c.inv_seq_waiters++; + dmar_qi_advance_tail(DMAR2IOMMU(unit)); + iommu_qi_wait_for_seq(DMAR2IOMMU(unit), &gseq, false); } void @@ -363,21 +254,21 @@ dmar_qi_invalidate_iec(struct dmar_unit *unit, u_int start, u_int cnt) for (; cnt > 0; cnt -= c, start += c) { l = ffs(start | cnt) - 1; c = 1 << l; - dmar_qi_ensure(unit, 1); + dmar_qi_ensure(DMAR2IOMMU(unit), 1); dmar_qi_emit(unit, DMAR_IQ_DESCR_IEC_INV | DMAR_IQ_DESCR_IEC_IDX | DMAR_IQ_DESCR_IEC_IIDX(start) | DMAR_IQ_DESCR_IEC_IM(l), 0); } - dmar_qi_ensure(unit, 1); - dmar_qi_emit_wait_seq(unit, &gseq, true); + dmar_qi_ensure(DMAR2IOMMU(unit), 1); + iommu_qi_emit_wait_seq(DMAR2IOMMU(unit), &gseq, true); /* - * Since dmar_qi_wait_for_seq() will not sleep, this increment's + * Since iommu_qi_wait_for_seq() will not sleep, this increment's * placement relative to advancing the tail doesn't matter. */ - unit->inv_seq_waiters++; + unit->x86c.inv_seq_waiters++; - dmar_qi_advance_tail(unit); + dmar_qi_advance_tail(DMAR2IOMMU(unit)); /* * The caller of the function, in particular, @@ -394,7 +285,7 @@ dmar_qi_invalidate_iec(struct dmar_unit *unit, u_int start, u_int cnt) * queue is processed, which includes requests possibly issued * before our request. */ - dmar_qi_wait_for_seq(unit, &gseq, true); + iommu_qi_wait_for_seq(DMAR2IOMMU(unit), &gseq, true); } int @@ -405,38 +296,18 @@ dmar_qi_intr(void *arg) unit = arg; KASSERT(unit->qi_enabled, ("dmar%d: QI is not enabled", unit->iommu.unit)); - taskqueue_enqueue(unit->qi_taskqueue, &unit->qi_task); + taskqueue_enqueue(unit->x86c.qi_taskqueue, &unit->x86c.qi_task); return (FILTER_HANDLED); } -static void -dmar_qi_drain_tlb_flush(struct dmar_unit *unit) -{ - struct iommu_map_entry *entry, *head; - - for (head = unit->tlb_flush_head;; head = entry) { - entry = (struct iommu_map_entry *) - atomic_load_acq_ptr((uintptr_t *)&head->tlb_flush_next); - if (entry == NULL || - !dmar_qi_seq_processed(unit, &entry->gseq)) - break; - unit->tlb_flush_head = entry; - iommu_gas_free_entry(head); - if ((entry->flags & IOMMU_MAP_ENTRY_RMRR) != 0) - iommu_gas_free_region(entry); - else - iommu_gas_free_space(entry); - } -} - static void dmar_qi_task(void *arg, int pending __unused) { struct dmar_unit *unit; uint32_t ics; - unit = arg; - dmar_qi_drain_tlb_flush(unit); + unit = IOMMU2DMAR(arg); + iommu_qi_drain_tlb_flush(DMAR2IOMMU(unit)); /* * Request an interrupt on the completion of the next invalidation @@ -453,16 +324,16 @@ dmar_qi_task(void *arg, int pending __unused) * Otherwise, such entries will linger until a later entry * that requests an interrupt is processed. */ - dmar_qi_drain_tlb_flush(unit); + iommu_qi_drain_tlb_flush(DMAR2IOMMU(unit)); } - if (unit->inv_seq_waiters > 0) { + if (unit->x86c.inv_seq_waiters > 0) { /* * Acquire the DMAR lock so that wakeup() is called only after * the waiter is sleeping. */ DMAR_LOCK(unit); - wakeup(&unit->inv_seq_waiters); + wakeup(&unit->x86c.inv_seq_waiters); DMAR_UNLOCK(unit); } } @@ -472,7 +343,7 @@ dmar_init_qi(struct dmar_unit *unit) { uint64_t iqa; uint32_t ics; - int qi_sz; + u_int qi_sz; if (!DMAR_HAS_QI(unit) || (unit->hw_cap & DMAR_CAP_CM) != 0) return (0); @@ -481,34 +352,19 @@ dmar_init_qi(struct dmar_unit *unit) if (!unit->qi_enabled) return (0); - unit->tlb_flush_head = unit->tlb_flush_tail = - iommu_gas_alloc_entry(NULL, 0); - TASK_INIT(&unit->qi_task, 0, dmar_qi_task, unit); - unit->qi_taskqueue = taskqueue_create_fast("dmarqf", M_WAITOK, - taskqueue_thread_enqueue, &unit->qi_taskqueue); - taskqueue_start_threads(&unit->qi_taskqueue, 1, PI_AV, - "dmar%d qi taskq", unit->iommu.unit); - - unit->inv_waitd_gen = 0; - unit->inv_waitd_seq = 1; - - qi_sz = DMAR_IQA_QS_DEF; - TUNABLE_INT_FETCH("hw.dmar.qi_size", &qi_sz); - if (qi_sz > DMAR_IQA_QS_MAX) - qi_sz = DMAR_IQA_QS_MAX; - unit->inv_queue_size = (1ULL << qi_sz) * PAGE_SIZE; - /* Reserve one descriptor to prevent wraparound. */ - unit->inv_queue_avail = unit->inv_queue_size - DMAR_IQ_DESCR_SZ; - - /* The invalidation queue reads by DMARs are always coherent. */ - unit->inv_queue = kmem_alloc_contig(unit->inv_queue_size, M_WAITOK | - M_ZERO, 0, iommu_high, PAGE_SIZE, 0, VM_MEMATTR_DEFAULT); - unit->inv_waitd_seq_hw_phys = pmap_kextract( - (vm_offset_t)&unit->inv_waitd_seq_hw); + unit->x86c.qi_buf_maxsz = DMAR_IQA_QS_MAX; + unit->x86c.qi_cmd_sz = DMAR_IQ_DESCR_SZ; + iommu_qi_common_init(DMAR2IOMMU(unit), dmar_qi_task); + get_x86_iommu()->qi_ensure = dmar_qi_ensure; + get_x86_iommu()->qi_emit_wait_descr = dmar_qi_emit_wait_descr; + get_x86_iommu()->qi_advance_tail = dmar_qi_advance_tail; + get_x86_iommu()->qi_invalidate_emit = dmar_qi_invalidate_emit; + + qi_sz = ilog2(unit->x86c.inv_queue_size / PAGE_SIZE); DMAR_LOCK(unit); dmar_write8(unit, DMAR_IQT_REG, 0); - iqa = pmap_kextract((uintptr_t)unit->inv_queue); + iqa = pmap_kextract((uintptr_t)unit->x86c.inv_queue); iqa |= qi_sz; dmar_write8(unit, DMAR_IQA_REG, iqa); dmar_enable_qi(unit); @@ -523,35 +379,19 @@ dmar_init_qi(struct dmar_unit *unit) return (0); } +static void +dmar_fini_qi_helper(struct iommu_unit *iommu) +{ + dmar_disable_qi_intr(IOMMU2DMAR(iommu)); + dmar_disable_qi(IOMMU2DMAR(iommu)); +} + void dmar_fini_qi(struct dmar_unit *unit) { - struct iommu_qi_genseq gseq; - if (!unit->qi_enabled) return; - taskqueue_drain(unit->qi_taskqueue, &unit->qi_task); - taskqueue_free(unit->qi_taskqueue); - unit->qi_taskqueue = NULL; - - DMAR_LOCK(unit); - /* quisce */ - dmar_qi_ensure(unit, 1); - dmar_qi_emit_wait_seq(unit, &gseq, true); - /* See dmar_qi_invalidate_sync_locked(). */ - unit->inv_seq_waiters++; - dmar_qi_advance_tail(unit); - dmar_qi_wait_for_seq(unit, &gseq, false); - /* only after the quisce, disable queue */ - dmar_disable_qi_intr(unit); - dmar_disable_qi(unit); - KASSERT(unit->inv_seq_waiters == 0, - ("dmar%d: waiters on disabled queue", unit->iommu.unit)); - DMAR_UNLOCK(unit); - - kmem_free(unit->inv_queue, unit->inv_queue_size); - unit->inv_queue = NULL; - unit->inv_queue_size = 0; + iommu_qi_common_fini(DMAR2IOMMU(unit), dmar_fini_qi_helper); unit->qi_enabled = 0; } diff --git a/sys/x86/iommu/iommu_utils.c b/sys/x86/iommu/iommu_utils.c index ea2c0358e072..571e5a2e65cd 100644 --- a/sys/x86/iommu/iommu_utils.c +++ b/sys/x86/iommu/iommu_utils.c @@ -29,7 +29,9 @@ */ #include +#include #include +#include #include #include #include @@ -40,8 +42,11 @@ #include #include #include -#include +#include +#include +#include #include +#include #include #include #include @@ -251,3 +256,230 @@ iommu_unmap_ioapic_intr(u_int ioapic_id, u_int *cookie) { return (x86_iommu->unmap_ioapic_intr(ioapic_id, cookie)); } + +#define IOMMU2X86C(iommu) (x86_iommu->get_x86_common(iommu)) + +static bool +iommu_qi_seq_processed(struct iommu_unit *unit, + const struct iommu_qi_genseq *pseq) +{ + struct x86_unit_common *x86c; + u_int gen; + + x86c = IOMMU2X86C(unit); + gen = x86c->inv_waitd_gen; + return (pseq->gen < gen || + (pseq->gen == gen && pseq->seq <= x86c->inv_waitd_seq_hw)); +} + +void +iommu_qi_emit_wait_seq(struct iommu_unit *unit, struct iommu_qi_genseq *pseq, + bool emit_wait) +{ + struct x86_unit_common *x86c; + struct iommu_qi_genseq gsec; + uint32_t seq; + + KASSERT(pseq != NULL, ("wait descriptor with no place for seq")); + IOMMU_ASSERT_LOCKED(unit); + x86c = IOMMU2X86C(unit); + + if (x86c->inv_waitd_seq == 0xffffffff) { + gsec.gen = x86c->inv_waitd_gen; + gsec.seq = x86c->inv_waitd_seq; + x86_iommu->qi_ensure(unit, 1); + x86_iommu->qi_emit_wait_descr(unit, gsec.seq, false, + true, false); + x86_iommu->qi_advance_tail(unit); + while (!iommu_qi_seq_processed(unit, &gsec)) + cpu_spinwait(); + x86c->inv_waitd_gen++; + x86c->inv_waitd_seq = 1; + } + seq = x86c->inv_waitd_seq++; + pseq->gen = x86c->inv_waitd_gen; + pseq->seq = seq; + if (emit_wait) { + x86_iommu->qi_ensure(unit, 1); + x86_iommu->qi_emit_wait_descr(unit, seq, true, true, false); + } +} + +/* + * To avoid missed wakeups, callers must increment the unit's waiters count + * before advancing the tail past the wait descriptor. + */ +void +iommu_qi_wait_for_seq(struct iommu_unit *unit, const struct iommu_qi_genseq * + gseq, bool nowait) +{ + struct x86_unit_common *x86c; + + IOMMU_ASSERT_LOCKED(unit); + x86c = IOMMU2X86C(unit); + + KASSERT(x86c->inv_seq_waiters > 0, ("%s: no waiters", __func__)); + while (!iommu_qi_seq_processed(unit, gseq)) { + if (cold || nowait) { + cpu_spinwait(); + } else { + msleep(&x86c->inv_seq_waiters, &unit->lock, 0, + "dmarse", hz); + } + } + x86c->inv_seq_waiters--; +} + +/* + * The caller must not be using the entry's dmamap_link field. + */ +void +iommu_qi_invalidate_locked(struct iommu_domain *domain, + struct iommu_map_entry *entry, bool emit_wait) +{ + struct iommu_unit *unit; + struct x86_unit_common *x86c; + + unit = domain->iommu; + x86c = IOMMU2X86C(unit); + IOMMU_ASSERT_LOCKED(unit); + + x86_iommu->qi_invalidate_emit(domain, entry->start, entry->end - + entry->start, &entry->gseq, emit_wait); + + /* + * To avoid a data race in dmar_qi_task(), the entry's gseq must be + * initialized before the entry is added to the TLB flush list, and the + * entry must be added to that list before the tail is advanced. More + * precisely, the tail must not be advanced past the wait descriptor + * that will generate the interrupt that schedules dmar_qi_task() for + * execution before the entry is added to the list. While an earlier + * call to dmar_qi_ensure() might have advanced the tail, it will not + * advance it past the wait descriptor. + * + * See the definition of struct dmar_unit for more information on + * synchronization. + */ + entry->tlb_flush_next = NULL; + atomic_store_rel_ptr((uintptr_t *)&x86c->tlb_flush_tail-> + tlb_flush_next, (uintptr_t)entry); + x86c->tlb_flush_tail = entry; + + x86_iommu->qi_advance_tail(unit); +} + +void +iommu_qi_invalidate_sync(struct iommu_domain *domain, iommu_gaddr_t base, + iommu_gaddr_t size, bool cansleep) +{ + struct iommu_unit *unit; + struct iommu_qi_genseq gseq; + + unit = domain->iommu; + IOMMU_LOCK(unit); + x86_iommu->qi_invalidate_emit(domain, base, size, &gseq, true); + + /* + * To avoid a missed wakeup in iommu_qi_task(), the unit's + * waiters count must be incremented before the tail is + * advanced. + */ + IOMMU2X86C(unit)->inv_seq_waiters++; + + x86_iommu->qi_advance_tail(unit); + iommu_qi_wait_for_seq(unit, &gseq, !cansleep); + IOMMU_UNLOCK(unit); +} + +void +iommu_qi_drain_tlb_flush(struct iommu_unit *unit) +{ + struct x86_unit_common *x86c; + struct iommu_map_entry *entry, *head; + + x86c = IOMMU2X86C(unit); + for (head = x86c->tlb_flush_head;; head = entry) { + entry = (struct iommu_map_entry *) + atomic_load_acq_ptr((uintptr_t *)&head->tlb_flush_next); + if (entry == NULL || + !iommu_qi_seq_processed(unit, &entry->gseq)) + break; + x86c->tlb_flush_head = entry; + iommu_gas_free_entry(head); + if ((entry->flags & IOMMU_MAP_ENTRY_RMRR) != 0) + iommu_gas_free_region(entry); + else + iommu_gas_free_space(entry); + } +} + +void +iommu_qi_common_init(struct iommu_unit *unit, task_fn_t qi_task) +{ + struct x86_unit_common *x86c; + u_int qi_sz; + + x86c = IOMMU2X86C(unit); + + x86c->tlb_flush_head = x86c->tlb_flush_tail = + iommu_gas_alloc_entry(NULL, 0); + TASK_INIT(&x86c->qi_task, 0, qi_task, unit); + x86c->qi_taskqueue = taskqueue_create_fast("iommuqf", M_WAITOK, + taskqueue_thread_enqueue, &x86c->qi_taskqueue); + taskqueue_start_threads(&x86c->qi_taskqueue, 1, PI_AV, + "iommu%d qi taskq", unit->unit); + + x86c->inv_waitd_gen = 0; + x86c->inv_waitd_seq = 1; + + qi_sz = 3; + TUNABLE_INT_FETCH("hw.iommu.qi_size", &qi_sz); + if (qi_sz > x86c->qi_buf_maxsz) + qi_sz = x86c->qi_buf_maxsz; + x86c->inv_queue_size = (1ULL << qi_sz) * PAGE_SIZE; + /* Reserve one descriptor to prevent wraparound. */ + x86c->inv_queue_avail = x86c->inv_queue_size - + x86c->qi_cmd_sz; + + /* + * The invalidation queue reads by DMARs/AMDIOMMUs are always + * coherent. + */ + x86c->inv_queue = kmem_alloc_contig(x86c->inv_queue_size, + M_WAITOK | M_ZERO, 0, iommu_high, PAGE_SIZE, 0, + VM_MEMATTR_DEFAULT); + x86c->inv_waitd_seq_hw_phys = pmap_kextract( + (vm_offset_t)&x86c->inv_waitd_seq_hw); +} + +void +iommu_qi_common_fini(struct iommu_unit *unit, void (*disable_qi)( + struct iommu_unit *)) +{ + struct x86_unit_common *x86c; + struct iommu_qi_genseq gseq; + + x86c = IOMMU2X86C(unit); + + taskqueue_drain(x86c->qi_taskqueue, &x86c->qi_task); + taskqueue_free(x86c->qi_taskqueue); + x86c->qi_taskqueue = NULL; + + IOMMU_LOCK(unit); + /* quisce */ + x86_iommu->qi_ensure(unit, 1); + iommu_qi_emit_wait_seq(unit, &gseq, true); + /* See iommu_qi_invalidate_locked(). */ + x86c->inv_seq_waiters++; + x86_iommu->qi_advance_tail(unit); + iommu_qi_wait_for_seq(unit, &gseq, false); + /* only after the quisce, disable queue */ + disable_qi(unit); + KASSERT(x86c->inv_seq_waiters == 0, + ("iommu%d: waiters on disabled queue", unit->unit)); + IOMMU_UNLOCK(unit); + + kmem_free(x86c->inv_queue, x86c->inv_queue_size); + x86c->inv_queue = NULL; + x86c->inv_queue_size = 0; +} diff --git a/sys/x86/iommu/x86_iommu.h b/sys/x86/iommu/x86_iommu.h index 8c908964acd0..eb1bbafbeb77 100644 --- a/sys/x86/iommu/x86_iommu.h +++ b/sys/x86/iommu/x86_iommu.h @@ -59,7 +59,18 @@ extern int iommu_tbl_pagecnt; SYSCTL_DECL(_hw_iommu); SYSCTL_DECL(_hw_iommu_dmar); +struct x86_unit_common; + struct x86_iommu { + struct x86_unit_common *(*get_x86_common)(struct + iommu_unit *iommu); + void (*qi_ensure)(struct iommu_unit *unit, int descr_count); + void (*qi_emit_wait_descr)(struct iommu_unit *unit, uint32_t seq, + bool, bool, bool); + void (*qi_advance_tail)(struct iommu_unit *unit); + void (*qi_invalidate_emit)(struct iommu_domain *idomain, + iommu_gaddr_t base, iommu_gaddr_t size, struct iommu_qi_genseq * + pseq, bool emit_wait); void (*domain_unload_entry)(struct iommu_map_entry *entry, bool free, bool cansleep); void (*domain_unload)(struct iommu_domain *iodom, @@ -82,4 +93,65 @@ struct x86_iommu { void set_x86_iommu(struct x86_iommu *); struct x86_iommu *get_x86_iommu(void); +struct x86_unit_common { + uint32_t qi_buf_maxsz; + uint32_t qi_cmd_sz; + + char *inv_queue; + vm_size_t inv_queue_size; + uint32_t inv_queue_avail; + uint32_t inv_queue_tail; + volatile uint32_t inv_waitd_seq_hw; /* hw writes there on wait + descr completion */ + + uint64_t inv_waitd_seq_hw_phys; + uint32_t inv_waitd_seq; /* next sequence number to use for wait descr */ + u_int inv_waitd_gen; /* seq number generation AKA seq overflows */ + u_int inv_seq_waiters; /* count of waiters for seq */ + u_int inv_queue_full; /* informational counter */ + + /* + * Delayed freeing of map entries queue processing: + * + * tlb_flush_head and tlb_flush_tail are used to implement a FIFO + * queue that supports concurrent dequeues and enqueues. However, + * there can only be a single dequeuer (accessing tlb_flush_head) and + * a single enqueuer (accessing tlb_flush_tail) at a time. Since the + * unit's qi_task is the only dequeuer, it can access tlb_flush_head + * without any locking. In contrast, there may be multiple enqueuers, + * so the enqueuers acquire the iommu unit lock to serialize their + * accesses to tlb_flush_tail. + * + * In this FIFO queue implementation, the key to enabling concurrent + * dequeues and enqueues is that the dequeuer never needs to access + * tlb_flush_tail and the enqueuer never needs to access + * tlb_flush_head. In particular, tlb_flush_head and tlb_flush_tail + * are never NULL, so neither a dequeuer nor an enqueuer ever needs to + * update both. Instead, tlb_flush_head always points to a "zombie" + * struct, which previously held the last dequeued item. Thus, the + * zombie's next field actually points to the struct holding the first + * item in the queue. When an item is dequeued, the current zombie is + * finally freed, and the struct that held the just dequeued item + * becomes the new zombie. When the queue is empty, tlb_flush_tail + * also points to the zombie. + */ + struct iommu_map_entry *tlb_flush_head; + struct iommu_map_entry *tlb_flush_tail; + struct task qi_task; + struct taskqueue *qi_taskqueue; +}; + +void iommu_qi_emit_wait_seq(struct iommu_unit *unit, struct iommu_qi_genseq * + pseq, bool emit_wait); +void iommu_qi_wait_for_seq(struct iommu_unit *unit, const struct + iommu_qi_genseq *gseq, bool nowait); +void iommu_qi_drain_tlb_flush(struct iommu_unit *unit); +void iommu_qi_invalidate_locked(struct iommu_domain *domain, + struct iommu_map_entry *entry, bool emit_wait); +void iommu_qi_invalidate_sync(struct iommu_domain *domain, iommu_gaddr_t base, + iommu_gaddr_t size, bool cansleep); +void iommu_qi_common_init(struct iommu_unit *unit, task_fn_t taskfunc); +void iommu_qi_common_fini(struct iommu_unit *unit, void (*disable_qi)( + struct iommu_unit *)); + #endif From f776a2b849726e7b86735b2930be64f5a2edf731 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Sun, 9 Jun 2024 20:24:31 +0300 Subject: [PATCH 130/213] dmar_qi_XXX_invalidate_glob(): reduce code duplication Sponsored by: Advanced Micro Devices (AMD) Sponsored by: The FreeBSD Foundation MFC after: 1 week --- sys/x86/iommu/intel_qi.c | 38 ++++++++++++++------------------------ 1 file changed, 14 insertions(+), 24 deletions(-) diff --git a/sys/x86/iommu/intel_qi.c b/sys/x86/iommu/intel_qi.c index a94fbb54e7f7..b474d695552f 100644 --- a/sys/x86/iommu/intel_qi.c +++ b/sys/x86/iommu/intel_qi.c @@ -195,14 +195,14 @@ dmar_qi_invalidate_emit(struct iommu_domain *idomain, iommu_gaddr_t base, iommu_qi_emit_wait_seq(DMAR2IOMMU(unit), pseq, emit_wait); } -void -dmar_qi_invalidate_ctx_glob_locked(struct dmar_unit *unit) +static void +dmar_qi_invalidate_glob_impl(struct dmar_unit *unit, uint64_t data1) { struct iommu_qi_genseq gseq; DMAR_ASSERT_LOCKED(unit); dmar_qi_ensure(DMAR2IOMMU(unit), 2); - dmar_qi_emit(unit, DMAR_IQ_DESCR_CTX_INV | DMAR_IQ_DESCR_CTX_GLOB, 0); + dmar_qi_emit(unit, data1, 0); iommu_qi_emit_wait_seq(DMAR2IOMMU(unit), &gseq, true); /* See dmar_qi_invalidate_sync(). */ unit->x86c.inv_seq_waiters++; @@ -211,34 +211,24 @@ dmar_qi_invalidate_ctx_glob_locked(struct dmar_unit *unit) } void -dmar_qi_invalidate_iotlb_glob_locked(struct dmar_unit *unit) +dmar_qi_invalidate_ctx_glob_locked(struct dmar_unit *unit) { - struct iommu_qi_genseq gseq; + dmar_qi_invalidate_glob_impl(unit, DMAR_IQ_DESCR_CTX_INV | + DMAR_IQ_DESCR_CTX_GLOB); +} - DMAR_ASSERT_LOCKED(unit); - dmar_qi_ensure(DMAR2IOMMU(unit), 2); - dmar_qi_emit(unit, DMAR_IQ_DESCR_IOTLB_INV | DMAR_IQ_DESCR_IOTLB_GLOB | - DMAR_IQ_DESCR_IOTLB_DW | DMAR_IQ_DESCR_IOTLB_DR, 0); - iommu_qi_emit_wait_seq(DMAR2IOMMU(unit), &gseq, true); - /* See dmar_qi_invalidate_sync(). */ - unit->x86c.inv_seq_waiters++; - dmar_qi_advance_tail(DMAR2IOMMU(unit)); - iommu_qi_wait_for_seq(DMAR2IOMMU(unit), &gseq, false); +void +dmar_qi_invalidate_iotlb_glob_locked(struct dmar_unit *unit) +{ + dmar_qi_invalidate_glob_impl(unit, DMAR_IQ_DESCR_IOTLB_INV | + DMAR_IQ_DESCR_IOTLB_GLOB | DMAR_IQ_DESCR_IOTLB_DW | + DMAR_IQ_DESCR_IOTLB_DR); } void dmar_qi_invalidate_iec_glob(struct dmar_unit *unit) { - struct iommu_qi_genseq gseq; - - DMAR_ASSERT_LOCKED(unit); - dmar_qi_ensure(DMAR2IOMMU(unit), 2); - dmar_qi_emit(unit, DMAR_IQ_DESCR_IEC_INV, 0); - iommu_qi_emit_wait_seq(DMAR2IOMMU(unit), &gseq, true); - /* See dmar_qi_invalidate_sync(). */ - unit->x86c.inv_seq_waiters++; - dmar_qi_advance_tail(DMAR2IOMMU(unit)); - iommu_qi_wait_for_seq(DMAR2IOMMU(unit), &gseq, false); + dmar_qi_invalidate_glob_impl(unit, DMAR_IQ_DESCR_IEC_INV); } void From b563be66998ddd9dbc83364c8b515398d984c140 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Thu, 6 Jun 2024 06:21:31 +0300 Subject: [PATCH 131/213] dmar_qi_emit(): use atomic_store_64() when available Sponsored by: Advanced Micro Devices (AMD) Sponsored by: The FreeBSD Foundation MFC after: 1 week --- sys/x86/iommu/intel_qi.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/sys/x86/iommu/intel_qi.c b/sys/x86/iommu/intel_qi.c index b474d695552f..8b5cfe3c0205 100644 --- a/sys/x86/iommu/intel_qi.c +++ b/sys/x86/iommu/intel_qi.c @@ -139,15 +139,25 @@ dmar_qi_emit(struct dmar_unit *unit, uint64_t data1, uint64_t data2) { DMAR_ASSERT_LOCKED(unit); +#ifdef __LP64__ + atomic_store_64((uint64_t *)(unit->x86c.inv_queue + + unit->x86c.inv_queue_tail), data1); +#else *(volatile uint64_t *)(unit->x86c.inv_queue + unit->x86c.inv_queue_tail) = data1; +#endif unit->x86c.inv_queue_tail += DMAR_IQ_DESCR_SZ / 2; KASSERT(unit->x86c.inv_queue_tail <= unit->x86c.inv_queue_size, ("tail overflow 0x%x 0x%jx", unit->x86c.inv_queue_tail, (uintmax_t)unit->x86c.inv_queue_size)); unit->x86c.inv_queue_tail &= unit->x86c.inv_queue_size - 1; +#ifdef __LP64__ + atomic_store_64((uint64_t *)(unit->x86c.inv_queue + + unit->x86c.inv_queue_tail), data2); +#else *(volatile uint64_t *)(unit->x86c.inv_queue + unit->x86c.inv_queue_tail) = data2; +#endif unit->x86c.inv_queue_tail += DMAR_IQ_DESCR_SZ / 2; KASSERT(unit->x86c.inv_queue_tail <= unit->x86c.inv_queue_size, ("tail overflow 0x%x 0x%jx", unit->x86c.inv_queue_tail, From 23145534154c279e3e8cbcd17d155f7ee67d8aa9 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Sun, 30 Jun 2024 06:52:52 +0300 Subject: [PATCH 132/213] DMAR: rename domain_{alloc,free}_pgtbl to domain_domain_$1_pgtbl Sponsored by: Advanced Micro Devices (AMD) Sponsored by: The FreeBSD Foundation MFC after: 1 week --- sys/x86/iommu/intel_ctx.c | 4 ++-- sys/x86/iommu/intel_dmar.h | 4 ++-- sys/x86/iommu/intel_idpgtbl.c | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/sys/x86/iommu/intel_ctx.c b/sys/x86/iommu/intel_ctx.c index 03ef196c4cb0..e39d2a136d8a 100644 --- a/sys/x86/iommu/intel_ctx.c +++ b/sys/x86/iommu/intel_ctx.c @@ -423,7 +423,7 @@ dmar_domain_alloc(struct dmar_unit *dmar, bool id_mapped) } domain->iodom.flags |= IOMMU_DOMAIN_IDMAP; } else { - error = domain_alloc_pgtbl(domain); + error = dmar_domain_alloc_pgtbl(domain); if (error != 0) goto fail; /* Disable local apic region access */ @@ -509,7 +509,7 @@ dmar_domain_destroy(struct dmar_domain *domain) if ((domain->iodom.flags & IOMMU_DOMAIN_PGTBL_INITED) != 0) { if (domain->pgtbl_obj != NULL) DMAR_DOMAIN_PGLOCK(domain); - domain_free_pgtbl(domain); + dmar_domain_free_pgtbl(domain); } iommu_domain_fini(iodom); dmar = DOM2DMAR(domain); diff --git a/sys/x86/iommu/intel_dmar.h b/sys/x86/iommu/intel_dmar.h index 8a815d5cfca6..7b4a7900fa25 100644 --- a/sys/x86/iommu/intel_dmar.h +++ b/sys/x86/iommu/intel_dmar.h @@ -240,8 +240,8 @@ vm_object_t domain_get_idmap_pgtbl(struct dmar_domain *domain, void put_idmap_pgtbl(vm_object_t obj); void domain_flush_iotlb_sync(struct dmar_domain *domain, iommu_gaddr_t base, iommu_gaddr_t size); -int domain_alloc_pgtbl(struct dmar_domain *domain); -void domain_free_pgtbl(struct dmar_domain *domain); +int dmar_domain_alloc_pgtbl(struct dmar_domain *domain); +void dmar_domain_free_pgtbl(struct dmar_domain *domain); extern const struct iommu_domain_map_ops dmar_domain_map_ops; int dmar_dev_depth(device_t child); diff --git a/sys/x86/iommu/intel_idpgtbl.c b/sys/x86/iommu/intel_idpgtbl.c index de38a6fece94..eb6a51216dfd 100644 --- a/sys/x86/iommu/intel_idpgtbl.c +++ b/sys/x86/iommu/intel_idpgtbl.c @@ -696,7 +696,7 @@ domain_unmap_buf(struct iommu_domain *iodom, iommu_gaddr_t base, } int -domain_alloc_pgtbl(struct dmar_domain *domain) +dmar_domain_alloc_pgtbl(struct dmar_domain *domain) { vm_page_t m; @@ -718,7 +718,7 @@ domain_alloc_pgtbl(struct dmar_domain *domain) } void -domain_free_pgtbl(struct dmar_domain *domain) +dmar_domain_free_pgtbl(struct dmar_domain *domain) { vm_object_t obj; vm_page_t m; From fc8da73b93be3f5cc50f7607dbcfc1edb911de65 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Sun, 9 Jun 2024 17:08:28 +0300 Subject: [PATCH 133/213] x86 iommu x86_unit_common: expand hw completion write-out area to 8 bytes in preparation to share it with AMD IOMMU. AMD writes out 8 bytes. We use 32-bit completion sequence numbers, and CPUs are little-endian. So the expansion is acceptable on Intel. Sponsored by: Advanced Micro Devices (AMD) Sponsored by: The FreeBSD Foundation MFC after: 1 week --- sys/x86/iommu/intel_drv.c | 4 ++-- sys/x86/iommu/x86_iommu.h | 10 ++++++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/sys/x86/iommu/intel_drv.c b/sys/x86/iommu/intel_drv.c index 9fa1b3f98dc6..66d99748888f 100644 --- a/sys/x86/iommu/intel_drv.c +++ b/sys/x86/iommu/intel_drv.c @@ -1302,7 +1302,7 @@ dmar_print_one(int idx, bool show_domains, bool show_mappings) db_printf("qi is enabled: queue @0x%jx (IQA 0x%jx) " "size 0x%jx\n" " head 0x%x tail 0x%x avail 0x%x status 0x%x ctrl 0x%x\n" - " hw compl 0x%x@%p/phys@%jx next seq 0x%x gen 0x%x\n", + " hw compl 0x%jx@%p/phys@%jx next seq 0x%x gen 0x%x\n", (uintmax_t)unit->x86c.inv_queue, (uintmax_t)dmar_read8(unit, DMAR_IQA_REG), (uintmax_t)unit->x86c.inv_queue_size, @@ -1311,7 +1311,7 @@ dmar_print_one(int idx, bool show_domains, bool show_mappings) unit->x86c.inv_queue_avail, dmar_read4(unit, DMAR_ICS_REG), dmar_read4(unit, DMAR_IECTL_REG), - unit->x86c.inv_waitd_seq_hw, + (uintmax_t)unit->x86c.inv_waitd_seq_hw, &unit->x86c.inv_waitd_seq_hw, (uintmax_t)unit->x86c.inv_waitd_seq_hw_phys, unit->x86c.inv_waitd_seq, diff --git a/sys/x86/iommu/x86_iommu.h b/sys/x86/iommu/x86_iommu.h index eb1bbafbeb77..966a13c19b6e 100644 --- a/sys/x86/iommu/x86_iommu.h +++ b/sys/x86/iommu/x86_iommu.h @@ -101,8 +101,14 @@ struct x86_unit_common { vm_size_t inv_queue_size; uint32_t inv_queue_avail; uint32_t inv_queue_tail; - volatile uint32_t inv_waitd_seq_hw; /* hw writes there on wait - descr completion */ + + /* + * Hw writes there on completion of wait descriptor + * processing. Intel writes 4 bytes, while AMD does the + * 8-bytes write. Due to little-endian, and use of 4-byte + * sequence numbers, the difference does not matter for us. + */ + volatile uint64_t inv_waitd_seq_hw; uint64_t inv_waitd_seq_hw_phys; uint32_t inv_waitd_seq; /* next sequence number to use for wait descr */ From 5967352a923efe6676bdf794d6b73f7354719a43 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Sun, 9 Jun 2024 22:36:10 +0300 Subject: [PATCH 134/213] x86 iommu: move DMAR-independent parts of the interrupt setup code into common Sponsored by: Advanced Micro Devices (AMD) Sponsored by: The FreeBSD Foundation MFC after: 1 week --- sys/x86/iommu/intel_dmar.h | 24 +----- sys/x86/iommu/intel_drv.c | 151 ++++++++++-------------------------- sys/x86/iommu/intel_fault.c | 16 ++-- sys/x86/iommu/intel_qi.c | 14 ++-- sys/x86/iommu/iommu_utils.c | 105 +++++++++++++++++++++++++ sys/x86/iommu/x86_iommu.h | 23 ++++++ 6 files changed, 193 insertions(+), 140 deletions(-) diff --git a/sys/x86/iommu/intel_dmar.h b/sys/x86/iommu/intel_dmar.h index 7b4a7900fa25..0242e0cb954f 100644 --- a/sys/x86/iommu/intel_dmar.h +++ b/sys/x86/iommu/intel_dmar.h @@ -103,20 +103,6 @@ struct dmar_ctx { #define CTX2DMAR(ctx) (CTX2DOM(ctx)->dmar) #define DOM2DMAR(domain) ((domain)->dmar) -struct dmar_msi_data { - int irq; - int irq_rid; - struct resource *irq_res; - void *intr_handle; - int (*handler)(void *); - int msi_data_reg; - int msi_addr_reg; - int msi_uaddr_reg; - void (*enable_intr)(struct dmar_unit *); - void (*disable_intr)(struct dmar_unit *); - const char *name; -}; - #define DMAR_INTR_FAULT 0 #define DMAR_INTR_QI 1 #define DMAR_INTR_TOTAL 2 @@ -131,8 +117,6 @@ struct dmar_unit { int reg_rid; struct resource *regs; - struct dmar_msi_data intrs[DMAR_INTR_TOTAL]; - /* Hardware registers cache */ uint32_t hw_ver; uint64_t hw_cap; @@ -216,14 +200,14 @@ uint64_t dmar_get_timeout(void); void dmar_update_timeout(uint64_t newval); int dmar_fault_intr(void *arg); -void dmar_enable_fault_intr(struct dmar_unit *unit); -void dmar_disable_fault_intr(struct dmar_unit *unit); +void dmar_enable_fault_intr(struct iommu_unit *unit); +void dmar_disable_fault_intr(struct iommu_unit *unit); int dmar_init_fault_log(struct dmar_unit *unit); void dmar_fini_fault_log(struct dmar_unit *unit); int dmar_qi_intr(void *arg); -void dmar_enable_qi_intr(struct dmar_unit *unit); -void dmar_disable_qi_intr(struct dmar_unit *unit); +void dmar_enable_qi_intr(struct iommu_unit *unit); +void dmar_disable_qi_intr(struct iommu_unit *unit); int dmar_init_qi(struct dmar_unit *unit); void dmar_fini_qi(struct dmar_unit *unit); void dmar_qi_invalidate_locked(struct dmar_domain *domain, diff --git a/sys/x86/iommu/intel_drv.c b/sys/x86/iommu/intel_drv.c index 66d99748888f..2439ef9e4ef5 100644 --- a/sys/x86/iommu/intel_drv.c +++ b/sys/x86/iommu/intel_drv.c @@ -230,22 +230,6 @@ dmar_probe(device_t dev) return (BUS_PROBE_NOWILDCARD); } -static void -dmar_release_intr(device_t dev, struct dmar_unit *unit, int idx) -{ - struct dmar_msi_data *dmd; - - dmd = &unit->intrs[idx]; - if (dmd->irq == -1) - return; - bus_teardown_intr(dev, dmd->irq_res, dmd->intr_handle); - bus_release_resource(dev, SYS_RES_IRQ, dmd->irq_rid, dmd->irq_res); - bus_delete_resource(dev, SYS_RES_IRQ, dmd->irq_rid); - PCIB_RELEASE_MSIX(device_get_parent(device_get_parent(dev)), - dev, dmd->irq); - dmd->irq = -1; -} - static void dmar_release_resources(device_t dev, struct dmar_unit *unit) { @@ -256,7 +240,7 @@ dmar_release_resources(device_t dev, struct dmar_unit *unit) dmar_fini_qi(unit); dmar_fini_fault_log(unit); for (i = 0; i < DMAR_INTR_TOTAL; i++) - dmar_release_intr(dev, unit, i); + iommu_release_intr(DMAR2IOMMU(unit), i); if (unit->regs != NULL) { bus_deactivate_resource(dev, SYS_RES_MEMORY, unit->reg_rid, unit->regs); @@ -274,84 +258,19 @@ dmar_release_resources(device_t dev, struct dmar_unit *unit) } } -static int -dmar_alloc_irq(device_t dev, struct dmar_unit *unit, int idx) -{ - device_t pcib; - struct dmar_msi_data *dmd; - uint64_t msi_addr; - uint32_t msi_data; - int error; - - dmd = &unit->intrs[idx]; - pcib = device_get_parent(device_get_parent(dev)); /* Really not pcib */ - error = PCIB_ALLOC_MSIX(pcib, dev, &dmd->irq); - if (error != 0) { - device_printf(dev, "cannot allocate %s interrupt, %d\n", - dmd->name, error); - goto err1; - } - error = bus_set_resource(dev, SYS_RES_IRQ, dmd->irq_rid, - dmd->irq, 1); - if (error != 0) { - device_printf(dev, "cannot set %s interrupt resource, %d\n", - dmd->name, error); - goto err2; - } - dmd->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, - &dmd->irq_rid, RF_ACTIVE); - if (dmd->irq_res == NULL) { - device_printf(dev, - "cannot allocate resource for %s interrupt\n", dmd->name); - error = ENXIO; - goto err3; - } - error = bus_setup_intr(dev, dmd->irq_res, INTR_TYPE_MISC, - dmd->handler, NULL, unit, &dmd->intr_handle); - if (error != 0) { - device_printf(dev, "cannot setup %s interrupt, %d\n", - dmd->name, error); - goto err4; - } - bus_describe_intr(dev, dmd->irq_res, dmd->intr_handle, "%s", dmd->name); - error = PCIB_MAP_MSI(pcib, dev, dmd->irq, &msi_addr, &msi_data); - if (error != 0) { - device_printf(dev, "cannot map %s interrupt, %d\n", - dmd->name, error); - goto err5; - } - dmar_write4(unit, dmd->msi_data_reg, msi_data); - dmar_write4(unit, dmd->msi_addr_reg, msi_addr); - /* Only for xAPIC mode */ - dmar_write4(unit, dmd->msi_uaddr_reg, msi_addr >> 32); - return (0); - -err5: - bus_teardown_intr(dev, dmd->irq_res, dmd->intr_handle); -err4: - bus_release_resource(dev, SYS_RES_IRQ, dmd->irq_rid, dmd->irq_res); -err3: - bus_delete_resource(dev, SYS_RES_IRQ, dmd->irq_rid); -err2: - PCIB_RELEASE_MSIX(pcib, dev, dmd->irq); - dmd->irq = -1; -err1: - return (error); -} - #ifdef DEV_APIC static int dmar_remap_intr(device_t dev, device_t child, u_int irq) { struct dmar_unit *unit; - struct dmar_msi_data *dmd; + struct iommu_msi_data *dmd; uint64_t msi_addr; uint32_t msi_data; int i, error; unit = device_get_softc(dev); for (i = 0; i < DMAR_INTR_TOTAL; i++) { - dmd = &unit->intrs[i]; + dmd = &unit->x86c.intrs[i]; if (irq == dmd->irq) { error = PCIB_MAP_MSI(device_get_parent( device_get_parent(dev)), @@ -359,11 +278,14 @@ dmar_remap_intr(device_t dev, device_t child, u_int irq) if (error != 0) return (error); DMAR_LOCK(unit); - (dmd->disable_intr)(unit); - dmar_write4(unit, dmd->msi_data_reg, msi_data); - dmar_write4(unit, dmd->msi_addr_reg, msi_addr); - dmar_write4(unit, dmd->msi_uaddr_reg, msi_addr >> 32); - (dmd->enable_intr)(unit); + dmd->msi_data = msi_data; + dmd->msi_addr = msi_addr; + (dmd->disable_intr)(DMAR2IOMMU(unit)); + dmar_write4(unit, dmd->msi_data_reg, dmd->msi_data); + dmar_write4(unit, dmd->msi_addr_reg, dmd->msi_addr); + dmar_write4(unit, dmd->msi_uaddr_reg, + dmd->msi_addr >> 32); + (dmd->enable_intr)(DMAR2IOMMU(unit)); DMAR_UNLOCK(unit); return (0); } @@ -407,6 +329,7 @@ dmar_attach(device_t dev) { struct dmar_unit *unit; ACPI_DMAR_HARDWARE_UNIT *dmaru; + struct iommu_msi_data *dmd; uint64_t timeout; int disable_pmr; int i, error; @@ -439,37 +362,47 @@ dmar_attach(device_t dev) dmar_update_timeout(timeout); for (i = 0; i < DMAR_INTR_TOTAL; i++) - unit->intrs[i].irq = -1; - - unit->intrs[DMAR_INTR_FAULT].name = "fault"; - unit->intrs[DMAR_INTR_FAULT].irq_rid = DMAR_FAULT_IRQ_RID; - unit->intrs[DMAR_INTR_FAULT].handler = dmar_fault_intr; - unit->intrs[DMAR_INTR_FAULT].msi_data_reg = DMAR_FEDATA_REG; - unit->intrs[DMAR_INTR_FAULT].msi_addr_reg = DMAR_FEADDR_REG; - unit->intrs[DMAR_INTR_FAULT].msi_uaddr_reg = DMAR_FEUADDR_REG; - unit->intrs[DMAR_INTR_FAULT].enable_intr = dmar_enable_fault_intr; - unit->intrs[DMAR_INTR_FAULT].disable_intr = dmar_disable_fault_intr; - error = dmar_alloc_irq(dev, unit, DMAR_INTR_FAULT); + unit->x86c.intrs[i].irq = -1; + + dmd = &unit->x86c.intrs[DMAR_INTR_FAULT]; + dmd->name = "fault"; + dmd->irq_rid = DMAR_FAULT_IRQ_RID; + dmd->handler = dmar_fault_intr; + dmd->msi_data_reg = DMAR_FEDATA_REG; + dmd->msi_addr_reg = DMAR_FEADDR_REG; + dmd->msi_uaddr_reg = DMAR_FEUADDR_REG; + dmd->enable_intr = dmar_enable_fault_intr; + dmd->disable_intr = dmar_disable_fault_intr; + error = iommu_alloc_irq(DMAR2IOMMU(unit), DMAR_INTR_FAULT); if (error != 0) { dmar_release_resources(dev, unit); dmar_devs[unit->iommu.unit] = NULL; return (error); } + dmar_write4(unit, dmd->msi_data_reg, dmd->msi_data); + dmar_write4(unit, dmd->msi_addr_reg, dmd->msi_addr); + dmar_write4(unit, dmd->msi_uaddr_reg, dmd->msi_addr >> 32); + if (DMAR_HAS_QI(unit)) { - unit->intrs[DMAR_INTR_QI].name = "qi"; - unit->intrs[DMAR_INTR_QI].irq_rid = DMAR_QI_IRQ_RID; - unit->intrs[DMAR_INTR_QI].handler = dmar_qi_intr; - unit->intrs[DMAR_INTR_QI].msi_data_reg = DMAR_IEDATA_REG; - unit->intrs[DMAR_INTR_QI].msi_addr_reg = DMAR_IEADDR_REG; - unit->intrs[DMAR_INTR_QI].msi_uaddr_reg = DMAR_IEUADDR_REG; - unit->intrs[DMAR_INTR_QI].enable_intr = dmar_enable_qi_intr; - unit->intrs[DMAR_INTR_QI].disable_intr = dmar_disable_qi_intr; - error = dmar_alloc_irq(dev, unit, DMAR_INTR_QI); + dmd = &unit->x86c.intrs[DMAR_INTR_QI]; + dmd->name = "qi"; + dmd->irq_rid = DMAR_QI_IRQ_RID; + dmd->handler = dmar_qi_intr; + dmd->msi_data_reg = DMAR_IEDATA_REG; + dmd->msi_addr_reg = DMAR_IEADDR_REG; + dmd->msi_uaddr_reg = DMAR_IEUADDR_REG; + dmd->enable_intr = dmar_enable_qi_intr; + dmd->disable_intr = dmar_disable_qi_intr; + error = iommu_alloc_irq(DMAR2IOMMU(unit), DMAR_INTR_QI); if (error != 0) { dmar_release_resources(dev, unit); dmar_devs[unit->iommu.unit] = NULL; return (error); } + + dmar_write4(unit, dmd->msi_data_reg, dmd->msi_data); + dmar_write4(unit, dmd->msi_addr_reg, dmd->msi_addr); + dmar_write4(unit, dmd->msi_uaddr_reg, dmd->msi_addr >> 32); } mtx_init(&unit->iommu.lock, "dmarhw", NULL, MTX_DEF); diff --git a/sys/x86/iommu/intel_fault.c b/sys/x86/iommu/intel_fault.c index 59b482720cf1..1064165ea5d7 100644 --- a/sys/x86/iommu/intel_fault.c +++ b/sys/x86/iommu/intel_fault.c @@ -127,7 +127,7 @@ dmar_fault_intr(void *arg) int fri, frir, faultp; bool enqueue; - unit = arg; + unit = IOMMU2DMAR((struct iommu_unit *)arg); enqueue = false; fsts = dmar_read4(unit, DMAR_FSTS_REG); dmar_fault_intr_clear(unit, fsts); @@ -276,9 +276,9 @@ dmar_init_fault_log(struct dmar_unit *unit) "dmar%d fault taskq", unit->iommu.unit); DMAR_LOCK(unit); - dmar_disable_fault_intr(unit); + dmar_disable_fault_intr(&unit->iommu); dmar_clear_faults(unit); - dmar_enable_fault_intr(unit); + dmar_enable_fault_intr(&unit->iommu); DMAR_UNLOCK(unit); return (0); @@ -292,7 +292,7 @@ dmar_fini_fault_log(struct dmar_unit *unit) return; DMAR_LOCK(unit); - dmar_disable_fault_intr(unit); + dmar_disable_fault_intr(&unit->iommu); DMAR_UNLOCK(unit); taskqueue_drain(unit->fault_taskqueue, &unit->fault_task); @@ -306,10 +306,12 @@ dmar_fini_fault_log(struct dmar_unit *unit) } void -dmar_enable_fault_intr(struct dmar_unit *unit) +dmar_enable_fault_intr(struct iommu_unit *iommu) { + struct dmar_unit *unit; uint32_t fectl; + unit = IOMMU2DMAR(iommu); DMAR_ASSERT_LOCKED(unit); fectl = dmar_read4(unit, DMAR_FECTL_REG); fectl &= ~DMAR_FECTL_IM; @@ -317,10 +319,12 @@ dmar_enable_fault_intr(struct dmar_unit *unit) } void -dmar_disable_fault_intr(struct dmar_unit *unit) +dmar_disable_fault_intr(struct iommu_unit *iommu) { + struct dmar_unit *unit; uint32_t fectl; + unit = IOMMU2DMAR(iommu); DMAR_ASSERT_LOCKED(unit); fectl = dmar_read4(unit, DMAR_FECTL_REG); dmar_write4(unit, DMAR_FECTL_REG, fectl | DMAR_FECTL_IM); diff --git a/sys/x86/iommu/intel_qi.c b/sys/x86/iommu/intel_qi.c index 8b5cfe3c0205..c11946ad9447 100644 --- a/sys/x86/iommu/intel_qi.c +++ b/sys/x86/iommu/intel_qi.c @@ -293,7 +293,7 @@ dmar_qi_intr(void *arg) { struct dmar_unit *unit; - unit = arg; + unit = IOMMU2DMAR((struct iommu_unit *)arg); KASSERT(unit->qi_enabled, ("dmar%d: QI is not enabled", unit->iommu.unit)); taskqueue_enqueue(unit->x86c.qi_taskqueue, &unit->x86c.qi_task); @@ -373,7 +373,7 @@ dmar_init_qi(struct dmar_unit *unit) ics = DMAR_ICS_IWC; dmar_write4(unit, DMAR_ICS_REG, ics); } - dmar_enable_qi_intr(unit); + dmar_enable_qi_intr(DMAR2IOMMU(unit)); DMAR_UNLOCK(unit); return (0); @@ -382,7 +382,7 @@ dmar_init_qi(struct dmar_unit *unit) static void dmar_fini_qi_helper(struct iommu_unit *iommu) { - dmar_disable_qi_intr(IOMMU2DMAR(iommu)); + dmar_disable_qi_intr(iommu); dmar_disable_qi(IOMMU2DMAR(iommu)); } @@ -396,10 +396,12 @@ dmar_fini_qi(struct dmar_unit *unit) } void -dmar_enable_qi_intr(struct dmar_unit *unit) +dmar_enable_qi_intr(struct iommu_unit *iommu) { + struct dmar_unit *unit; uint32_t iectl; + unit = IOMMU2DMAR(iommu); DMAR_ASSERT_LOCKED(unit); KASSERT(DMAR_HAS_QI(unit), ("dmar%d: QI is not supported", unit->iommu.unit)); @@ -409,10 +411,12 @@ dmar_enable_qi_intr(struct dmar_unit *unit) } void -dmar_disable_qi_intr(struct dmar_unit *unit) +dmar_disable_qi_intr(struct iommu_unit *iommu) { + struct dmar_unit *unit; uint32_t iectl; + unit = IOMMU2DMAR(iommu); DMAR_ASSERT_LOCKED(unit); KASSERT(DMAR_HAS_QI(unit), ("dmar%d: QI is not supported", unit->iommu.unit)); diff --git a/sys/x86/iommu/iommu_utils.c b/sys/x86/iommu/iommu_utils.c index 571e5a2e65cd..04d42799310e 100644 --- a/sys/x86/iommu/iommu_utils.c +++ b/sys/x86/iommu/iommu_utils.c @@ -28,7 +28,15 @@ * SUCH DAMAGE. */ +#include "opt_acpi.h" +#if defined(__amd64__) +#define DEV_APIC +#else +#include "opt_apic.h" +#endif + #include +#include #include #include #include @@ -38,6 +46,7 @@ #include #include #include +#include #include #include #include @@ -48,6 +57,7 @@ #include #include #include +#include #include #include #include @@ -56,6 +66,12 @@ #include #include #include +#ifdef DEV_APIC +#include "pcib_if.h" +#include +#include +#include +#endif vm_page_t iommu_pgalloc(vm_object_t obj, vm_pindex_t idx, int flags) @@ -483,3 +499,92 @@ iommu_qi_common_fini(struct iommu_unit *unit, void (*disable_qi)( x86c->inv_queue = NULL; x86c->inv_queue_size = 0; } + +int +iommu_alloc_irq(struct iommu_unit *unit, int idx) +{ + device_t dev, pcib; + struct iommu_msi_data *dmd; + uint64_t msi_addr; + uint32_t msi_data; + int error; + + MPASS(idx >= 0 || idx < IOMMU_MAX_MSI); + + dev = unit->dev; + dmd = &IOMMU2X86C(unit)->intrs[idx]; + pcib = device_get_parent(device_get_parent(dev)); /* Really not pcib */ + error = PCIB_ALLOC_MSIX(pcib, dev, &dmd->irq); + if (error != 0) { + device_printf(dev, "cannot allocate %s interrupt, %d\n", + dmd->name, error); + goto err1; + } + error = bus_set_resource(dev, SYS_RES_IRQ, dmd->irq_rid, + dmd->irq, 1); + if (error != 0) { + device_printf(dev, "cannot set %s interrupt resource, %d\n", + dmd->name, error); + goto err2; + } + dmd->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, + &dmd->irq_rid, RF_ACTIVE); + if (dmd->irq_res == NULL) { + device_printf(dev, + "cannot allocate resource for %s interrupt\n", dmd->name); + error = ENXIO; + goto err3; + } + error = bus_setup_intr(dev, dmd->irq_res, INTR_TYPE_MISC, + dmd->handler, NULL, unit, &dmd->intr_handle); + if (error != 0) { + device_printf(dev, "cannot setup %s interrupt, %d\n", + dmd->name, error); + goto err4; + } + bus_describe_intr(dev, dmd->irq_res, dmd->intr_handle, "%s", dmd->name); + error = PCIB_MAP_MSI(pcib, dev, dmd->irq, &msi_addr, &msi_data); + if (error != 0) { + device_printf(dev, "cannot map %s interrupt, %d\n", + dmd->name, error); + goto err5; + } + + dmd->msi_data = msi_data; + dmd->msi_addr = msi_addr; + + return (0); + +err5: + bus_teardown_intr(dev, dmd->irq_res, dmd->intr_handle); +err4: + bus_release_resource(dev, SYS_RES_IRQ, dmd->irq_rid, dmd->irq_res); +err3: + bus_delete_resource(dev, SYS_RES_IRQ, dmd->irq_rid); +err2: + PCIB_RELEASE_MSIX(pcib, dev, dmd->irq); + dmd->irq = -1; +err1: + return (error); +} + +void +iommu_release_intr(struct iommu_unit *unit, int idx) +{ + device_t dev; + struct iommu_msi_data *dmd; + + MPASS(idx >= 0 || idx < IOMMU_MAX_MSI); + + dmd = &IOMMU2X86C(unit)->intrs[idx]; + if (dmd->handler == NULL || dmd->irq == -1) + return; + dev = unit->dev; + + bus_teardown_intr(dev, dmd->irq_res, dmd->intr_handle); + bus_release_resource(dev, SYS_RES_IRQ, dmd->irq_rid, dmd->irq_res); + bus_delete_resource(dev, SYS_RES_IRQ, dmd->irq_rid); + PCIB_RELEASE_MSIX(device_get_parent(device_get_parent(dev)), + dev, dmd->irq); + dmd->irq = -1; +} diff --git a/sys/x86/iommu/x86_iommu.h b/sys/x86/iommu/x86_iommu.h index 966a13c19b6e..d6e3ea56bd2c 100644 --- a/sys/x86/iommu/x86_iommu.h +++ b/sys/x86/iommu/x86_iommu.h @@ -93,6 +93,24 @@ struct x86_iommu { void set_x86_iommu(struct x86_iommu *); struct x86_iommu *get_x86_iommu(void); +struct iommu_msi_data { + int irq; + int irq_rid; + struct resource *irq_res; + void *intr_handle; + int (*handler)(void *); + int msi_data_reg; + int msi_addr_reg; + int msi_uaddr_reg; + uint64_t msi_addr; + uint32_t msi_data; + void (*enable_intr)(struct iommu_unit *); + void (*disable_intr)(struct iommu_unit *); + const char *name; +}; + +#define IOMMU_MAX_MSI 3 + struct x86_unit_common { uint32_t qi_buf_maxsz; uint32_t qi_cmd_sz; @@ -145,6 +163,8 @@ struct x86_unit_common { struct iommu_map_entry *tlb_flush_tail; struct task qi_task; struct taskqueue *qi_taskqueue; + + struct iommu_msi_data intrs[IOMMU_MAX_MSI]; }; void iommu_qi_emit_wait_seq(struct iommu_unit *unit, struct iommu_qi_genseq * @@ -160,4 +180,7 @@ void iommu_qi_common_init(struct iommu_unit *unit, task_fn_t taskfunc); void iommu_qi_common_fini(struct iommu_unit *unit, void (*disable_qi)( struct iommu_unit *)); +int iommu_alloc_irq(struct iommu_unit *unit, int idx); +void iommu_release_intr(struct iommu_unit *unit, int idx); + #endif From ff54674b09501f4302e675bb2d3e34a752a63405 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Sun, 30 Jun 2024 04:16:51 +0300 Subject: [PATCH 135/213] x86 iommu: move device_tag_init() to utils Sponsored by: Advanced Micro Devices (AMD) Sponsored by: The FreeBSD Foundation MFC after: 1 week --- sys/x86/iommu/intel_ctx.c | 21 +-------------------- sys/x86/iommu/iommu_utils.c | 17 +++++++++++++++++ sys/x86/iommu/x86_iommu.h | 2 ++ 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/sys/x86/iommu/intel_ctx.c b/sys/x86/iommu/intel_ctx.c index e39d2a136d8a..12dd0f0a5259 100644 --- a/sys/x86/iommu/intel_ctx.c +++ b/sys/x86/iommu/intel_ctx.c @@ -124,25 +124,6 @@ dmar_map_ctx_entry(struct dmar_ctx *ctx, struct sf_buf **sfp) return (ctxp); } -static void -device_tag_init(struct dmar_ctx *ctx, device_t dev) -{ - struct dmar_domain *domain; - bus_addr_t maxaddr; - - domain = CTX2DOM(ctx); - maxaddr = MIN(domain->iodom.end, BUS_SPACE_MAXADDR); - ctx->context.tag->common.impl = &bus_dma_iommu_impl; - ctx->context.tag->common.boundary = 0; - ctx->context.tag->common.lowaddr = maxaddr; - ctx->context.tag->common.highaddr = maxaddr; - ctx->context.tag->common.maxsize = maxaddr; - ctx->context.tag->common.nsegments = BUS_SPACE_UNRESTRICTED; - ctx->context.tag->common.maxsegsz = maxaddr; - ctx->context.tag->ctx = CTX2IOCTX(ctx); - ctx->context.tag->owner = dev; -} - static void ctx_id_entry_init_one(dmar_ctx_entry_t *ctxp, struct dmar_domain *domain, vm_page_t ctx_root) @@ -586,7 +567,7 @@ dmar_get_ctx_for_dev1(struct dmar_unit *dmar, device_t dev, uint16_t rid, ctx = ctx1; dmar_ctx_link(ctx); ctx->context.tag->owner = dev; - device_tag_init(ctx, dev); + iommu_device_tag_init(CTX2IOCTX(ctx), dev); /* * This is the first activated context for the diff --git a/sys/x86/iommu/iommu_utils.c b/sys/x86/iommu/iommu_utils.c index 04d42799310e..20ca7890ce65 100644 --- a/sys/x86/iommu/iommu_utils.c +++ b/sys/x86/iommu/iommu_utils.c @@ -588,3 +588,20 @@ iommu_release_intr(struct iommu_unit *unit, int idx) dev, dmd->irq); dmd->irq = -1; } + +void +iommu_device_tag_init(struct iommu_ctx *ctx, device_t dev) +{ + bus_addr_t maxaddr; + + maxaddr = MIN(ctx->domain->end, BUS_SPACE_MAXADDR); + ctx->tag->common.impl = &bus_dma_iommu_impl; + ctx->tag->common.boundary = 0; + ctx->tag->common.lowaddr = maxaddr; + ctx->tag->common.highaddr = maxaddr; + ctx->tag->common.maxsize = maxaddr; + ctx->tag->common.nsegments = BUS_SPACE_UNRESTRICTED; + ctx->tag->common.maxsegsz = maxaddr; + ctx->tag->ctx = ctx; + ctx->tag->owner = dev; +} diff --git a/sys/x86/iommu/x86_iommu.h b/sys/x86/iommu/x86_iommu.h index d6e3ea56bd2c..5f56a2db74b5 100644 --- a/sys/x86/iommu/x86_iommu.h +++ b/sys/x86/iommu/x86_iommu.h @@ -183,4 +183,6 @@ void iommu_qi_common_fini(struct iommu_unit *unit, void (*disable_qi)( int iommu_alloc_irq(struct iommu_unit *unit, int idx); void iommu_release_intr(struct iommu_unit *unit, int idx); +void iommu_device_tag_init(struct iommu_ctx *ctx, device_t dev); + #endif From b3042e3a7c6ffee3867d52b192c6a9f4f49faf4b Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Sun, 7 Jul 2024 06:22:00 +0300 Subject: [PATCH 136/213] x86 dmar: generalize dmar_domain_free_entry() into iommu_domain_free_entry() Sponsored by: Advanced Micro Devices (AMD) Sponsored by: The FreeBSD Foundation MFC after: 1 week --- sys/x86/iommu/intel_ctx.c | 19 +++---------------- sys/x86/iommu/intel_dmar.h | 1 - sys/x86/iommu/iommu_utils.c | 14 ++++++++++++++ sys/x86/iommu/x86_iommu.h | 2 ++ 4 files changed, 19 insertions(+), 17 deletions(-) diff --git a/sys/x86/iommu/intel_ctx.c b/sys/x86/iommu/intel_ctx.c index 12dd0f0a5259..9167bfd13589 100644 --- a/sys/x86/iommu/intel_ctx.c +++ b/sys/x86/iommu/intel_ctx.c @@ -833,19 +833,6 @@ dmar_find_ctx_locked(struct dmar_unit *dmar, uint16_t rid) return (NULL); } -void -dmar_domain_free_entry(struct iommu_map_entry *entry, bool free) -{ - if ((entry->flags & IOMMU_MAP_ENTRY_RMRR) != 0) - iommu_gas_free_region(entry); - else - iommu_gas_free_space(entry); - if (free) - iommu_gas_free_entry(entry); - else - entry->flags = 0; -} - /* * If the given value for "free" is true, then the caller must not be using * the entry's dmamap_link field. @@ -874,12 +861,12 @@ dmar_domain_unload_entry(struct iommu_map_entry *entry, bool free, } else { iommu_qi_invalidate_sync(&domain->iodom, entry->start, entry->end - entry->start, cansleep); - dmar_domain_free_entry(entry, false); + iommu_domain_free_entry(entry, false); } } else { domain_flush_iotlb_sync(domain, entry->start, entry->end - entry->start); - dmar_domain_free_entry(entry, free); + iommu_domain_free_entry(entry, free); } } @@ -915,7 +902,7 @@ dmar_domain_unload(struct iommu_domain *iodom, domain_flush_iotlb_sync(domain, entry->start, entry->end - entry->start); TAILQ_REMOVE(entries, entry, dmamap_link); - dmar_domain_free_entry(entry, true); + iommu_domain_free_entry(entry, true); } } if (TAILQ_EMPTY(entries)) diff --git a/sys/x86/iommu/intel_dmar.h b/sys/x86/iommu/intel_dmar.h index 0242e0cb954f..edb152f42fe7 100644 --- a/sys/x86/iommu/intel_dmar.h +++ b/sys/x86/iommu/intel_dmar.h @@ -243,7 +243,6 @@ void dmar_free_ctx_method(struct iommu_ctx *ctx); struct dmar_ctx *dmar_find_ctx_locked(struct dmar_unit *dmar, uint16_t rid); struct iommu_ctx *dmar_get_ctx(struct iommu_unit *iommu, device_t dev, uint16_t rid, bool id_mapped, bool rmrr_init); -void dmar_domain_free_entry(struct iommu_map_entry *entry, bool free); void dmar_domain_unload_entry(struct iommu_map_entry *entry, bool free, bool cansleep); void dmar_domain_unload(struct iommu_domain *iodom, diff --git a/sys/x86/iommu/iommu_utils.c b/sys/x86/iommu/iommu_utils.c index 20ca7890ce65..9c6cae5ff51f 100644 --- a/sys/x86/iommu/iommu_utils.c +++ b/sys/x86/iommu/iommu_utils.c @@ -605,3 +605,17 @@ iommu_device_tag_init(struct iommu_ctx *ctx, device_t dev) ctx->tag->ctx = ctx; ctx->tag->owner = dev; } + +void +iommu_domain_free_entry(struct iommu_map_entry *entry, bool free) +{ + if ((entry->flags & IOMMU_MAP_ENTRY_RMRR) != 0) + iommu_gas_free_region(entry); + else + iommu_gas_free_space(entry); + if (free) + iommu_gas_free_entry(entry); + else + entry->flags = 0; +} + diff --git a/sys/x86/iommu/x86_iommu.h b/sys/x86/iommu/x86_iommu.h index 5f56a2db74b5..9e3a82283729 100644 --- a/sys/x86/iommu/x86_iommu.h +++ b/sys/x86/iommu/x86_iommu.h @@ -167,6 +167,8 @@ struct x86_unit_common { struct iommu_msi_data intrs[IOMMU_MAX_MSI]; }; +void iommu_domain_free_entry(struct iommu_map_entry *entry, bool free); + void iommu_qi_emit_wait_seq(struct iommu_unit *unit, struct iommu_qi_genseq * pseq, bool emit_wait); void iommu_qi_wait_for_seq(struct iommu_unit *unit, const struct From 29e227047065c6b1d08fdb72a21f33560637332b Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Sat, 20 Jul 2024 02:47:48 +0300 Subject: [PATCH 137/213] x86 iommu: move page level related functions to common utils Also improve pglvl_page_size() to handle level 6. Sponsored by: Advanced Micro Devices (AMD) Sponsored by: The FreeBSD Foundation MFC after: 1 week --- sys/x86/iommu/intel_dmar.h | 2 - sys/x86/iommu/intel_idpgtbl.c | 38 +------------------ sys/x86/iommu/intel_utils.c | 37 ------------------ sys/x86/iommu/iommu_utils.c | 71 +++++++++++++++++++++++++++++++++++ sys/x86/iommu/x86_iommu.h | 5 +++ 5 files changed, 78 insertions(+), 75 deletions(-) diff --git a/sys/x86/iommu/intel_dmar.h b/sys/x86/iommu/intel_dmar.h index edb152f42fe7..c1e6c8f06f64 100644 --- a/sys/x86/iommu/intel_dmar.h +++ b/sys/x86/iommu/intel_dmar.h @@ -175,9 +175,7 @@ bool dmar_pglvl_supported(struct dmar_unit *unit, int pglvl); int domain_set_agaw(struct dmar_domain *domain, int mgaw); int dmar_maxaddr2mgaw(struct dmar_unit *unit, iommu_gaddr_t maxaddr, bool allow_less); -vm_pindex_t pglvl_max_pages(int pglvl); int domain_is_sp_lvl(struct dmar_domain *domain, int lvl); -iommu_gaddr_t pglvl_page_size(int total_pglvl, int lvl); iommu_gaddr_t domain_page_size(struct dmar_domain *domain, int lvl); int calc_am(struct dmar_unit *unit, iommu_gaddr_t base, iommu_gaddr_t size, iommu_gaddr_t *isizep); diff --git a/sys/x86/iommu/intel_idpgtbl.c b/sys/x86/iommu/intel_idpgtbl.c index eb6a51216dfd..53851622340b 100644 --- a/sys/x86/iommu/intel_idpgtbl.c +++ b/sys/x86/iommu/intel_idpgtbl.c @@ -316,40 +316,6 @@ put_idmap_pgtbl(vm_object_t obj) * address. Support superpages. */ -/* - * Index of the pte for the guest address base in the page table at - * the level lvl. - */ -static int -domain_pgtbl_pte_off(struct dmar_domain *domain, iommu_gaddr_t base, int lvl) -{ - - base >>= IOMMU_PAGE_SHIFT + (domain->pglvl - lvl - 1) * - IOMMU_NPTEPGSHIFT; - return (base & IOMMU_PTEMASK); -} - -/* - * Returns the page index of the page table page in the page table - * object, which maps the given address base at the page table level - * lvl. - */ -static vm_pindex_t -domain_pgtbl_get_pindex(struct dmar_domain *domain, iommu_gaddr_t base, int lvl) -{ - vm_pindex_t idx, pidx; - int i; - - KASSERT(lvl >= 0 && lvl < domain->pglvl, - ("wrong lvl %p %d", domain, lvl)); - - for (pidx = idx = 0, i = 0; i < lvl; i++, pidx = idx) { - idx = domain_pgtbl_pte_off(domain, base, i) + - pidx * IOMMU_NPTEPG + 1; - } - return (idx); -} - static iommu_pte_t * domain_pgtbl_map_pte(struct dmar_domain *domain, iommu_gaddr_t base, int lvl, int flags, vm_pindex_t *idxp, struct sf_buf **sf) @@ -362,7 +328,7 @@ domain_pgtbl_map_pte(struct dmar_domain *domain, iommu_gaddr_t base, int lvl, DMAR_DOMAIN_ASSERT_PGLOCKED(domain); KASSERT((flags & IOMMU_PGF_OBJL) != 0, ("lost PGF_OBJL")); - idx = domain_pgtbl_get_pindex(domain, base, lvl); + idx = pglvl_pgtbl_get_pindex(domain->pglvl, base, lvl); if (*sf != NULL && idx == *idxp) { pte = (iommu_pte_t *)sf_buf_kva(*sf); } else { @@ -414,7 +380,7 @@ domain_pgtbl_map_pte(struct dmar_domain *domain, iommu_gaddr_t base, int lvl, goto retry; } } - pte += domain_pgtbl_pte_off(domain, base, lvl); + pte += pglvl_pgtbl_pte_off(domain->pglvl, base, lvl); return (pte); } diff --git a/sys/x86/iommu/intel_utils.c b/sys/x86/iommu/intel_utils.c index a96f65fddfc5..141452b3393d 100644 --- a/sys/x86/iommu/intel_utils.c +++ b/sys/x86/iommu/intel_utils.c @@ -172,23 +172,6 @@ dmar_maxaddr2mgaw(struct dmar_unit *unit, iommu_gaddr_t maxaddr, bool allow_less return (-1); } -/* - * Calculate the total amount of page table pages needed to map the - * whole bus address space on the context with the selected agaw. - */ -vm_pindex_t -pglvl_max_pages(int pglvl) -{ - vm_pindex_t res; - int i; - - for (res = 0, i = pglvl; i > 0; i--) { - res *= IOMMU_NPTEPG; - res++; - } - return (res); -} - /* * Return true if the page table level lvl supports the superpage for * the context ctx. @@ -209,26 +192,6 @@ domain_is_sp_lvl(struct dmar_domain *domain, int lvl) return (alvl < nitems(sagaw_sp) && (sagaw_sp[alvl] & cap_sps) != 0); } -iommu_gaddr_t -pglvl_page_size(int total_pglvl, int lvl) -{ - int rlvl; - static const iommu_gaddr_t pg_sz[] = { - (iommu_gaddr_t)IOMMU_PAGE_SIZE, - (iommu_gaddr_t)IOMMU_PAGE_SIZE << IOMMU_NPTEPGSHIFT, - (iommu_gaddr_t)IOMMU_PAGE_SIZE << (2 * IOMMU_NPTEPGSHIFT), - (iommu_gaddr_t)IOMMU_PAGE_SIZE << (3 * IOMMU_NPTEPGSHIFT), - (iommu_gaddr_t)IOMMU_PAGE_SIZE << (4 * IOMMU_NPTEPGSHIFT), - (iommu_gaddr_t)IOMMU_PAGE_SIZE << (5 * IOMMU_NPTEPGSHIFT), - }; - - KASSERT(lvl >= 0 && lvl < total_pglvl, - ("total %d lvl %d", total_pglvl, lvl)); - rlvl = total_pglvl - lvl - 1; - KASSERT(rlvl < nitems(pg_sz), ("sizeof pg_sz lvl %d", lvl)); - return (pg_sz[rlvl]); -} - iommu_gaddr_t domain_page_size(struct dmar_domain *domain, int lvl) { diff --git a/sys/x86/iommu/iommu_utils.c b/sys/x86/iommu/iommu_utils.c index 9c6cae5ff51f..645c7e15740a 100644 --- a/sys/x86/iommu/iommu_utils.c +++ b/sys/x86/iommu/iommu_utils.c @@ -619,3 +619,74 @@ iommu_domain_free_entry(struct iommu_map_entry *entry, bool free) entry->flags = 0; } +/* + * Index of the pte for the guest address base in the page table at + * the level lvl. + */ +int +pglvl_pgtbl_pte_off(int pglvl, iommu_gaddr_t base, int lvl) +{ + + base >>= IOMMU_PAGE_SHIFT + (pglvl - lvl - 1) * + IOMMU_NPTEPGSHIFT; + return (base & IOMMU_PTEMASK); +} + +/* + * Returns the page index of the page table page in the page table + * object, which maps the given address base at the page table level + * lvl. + */ +vm_pindex_t +pglvl_pgtbl_get_pindex(int pglvl, iommu_gaddr_t base, int lvl) +{ + vm_pindex_t idx, pidx; + int i; + + KASSERT(lvl >= 0 && lvl < pglvl, + ("wrong lvl %d %d", pglvl, lvl)); + + for (pidx = idx = 0, i = 0; i < lvl; i++, pidx = idx) { + idx = pglvl_pgtbl_pte_off(pglvl, base, i) + + pidx * IOMMU_NPTEPG + 1; + } + return (idx); +} + +/* + * Calculate the total amount of page table pages needed to map the + * whole bus address space on the context with the selected agaw. + */ +vm_pindex_t +pglvl_max_pages(int pglvl) +{ + vm_pindex_t res; + int i; + + for (res = 0, i = pglvl; i > 0; i--) { + res *= IOMMU_NPTEPG; + res++; + } + return (res); +} + +iommu_gaddr_t +pglvl_page_size(int total_pglvl, int lvl) +{ + int rlvl; + static const iommu_gaddr_t pg_sz[] = { + (iommu_gaddr_t)IOMMU_PAGE_SIZE, + (iommu_gaddr_t)IOMMU_PAGE_SIZE << IOMMU_NPTEPGSHIFT, + (iommu_gaddr_t)IOMMU_PAGE_SIZE << (2 * IOMMU_NPTEPGSHIFT), + (iommu_gaddr_t)IOMMU_PAGE_SIZE << (3 * IOMMU_NPTEPGSHIFT), + (iommu_gaddr_t)IOMMU_PAGE_SIZE << (4 * IOMMU_NPTEPGSHIFT), + (iommu_gaddr_t)IOMMU_PAGE_SIZE << (5 * IOMMU_NPTEPGSHIFT), + (iommu_gaddr_t)IOMMU_PAGE_SIZE << (6 * IOMMU_NPTEPGSHIFT), + }; + + KASSERT(lvl >= 0 && lvl < total_pglvl, + ("total %d lvl %d", total_pglvl, lvl)); + rlvl = total_pglvl - lvl - 1; + KASSERT(rlvl < nitems(pg_sz), ("sizeof pg_sz lvl %d", lvl)); + return (pg_sz[rlvl]); +} diff --git a/sys/x86/iommu/x86_iommu.h b/sys/x86/iommu/x86_iommu.h index 9e3a82283729..b2caed550e35 100644 --- a/sys/x86/iommu/x86_iommu.h +++ b/sys/x86/iommu/x86_iommu.h @@ -187,4 +187,9 @@ void iommu_release_intr(struct iommu_unit *unit, int idx); void iommu_device_tag_init(struct iommu_ctx *ctx, device_t dev); +int pglvl_pgtbl_pte_off(int pglvl, iommu_gaddr_t base, int lvl); +vm_pindex_t pglvl_pgtbl_get_pindex(int pglvl, iommu_gaddr_t base, int lvl); +vm_pindex_t pglvl_max_pages(int pglvl); +iommu_gaddr_t pglvl_page_size(int total_pglvl, int lvl); + #endif From 0386b2451592ec04e4cff826b698f978a45ab3e4 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Sat, 24 Aug 2024 00:10:14 +0300 Subject: [PATCH 138/213] DMAR: move hw.iommu.dmar.{tbl_pagecnt,batch_coalesce} sysctls up one level Sponsored by: Advanced Micro Devices (AMD) Sponsored by: The FreeBSD Foundation MFC after: 1 week --- sys/x86/iommu/intel_ctx.c | 2 +- sys/x86/iommu/intel_dmar.h | 3 ++- sys/x86/iommu/intel_utils.c | 4 ---- sys/x86/iommu/iommu_utils.c | 9 +++++++-- sys/x86/iommu/x86_iommu.h | 2 +- 5 files changed, 11 insertions(+), 9 deletions(-) diff --git a/sys/x86/iommu/intel_ctx.c b/sys/x86/iommu/intel_ctx.c index 9167bfd13589..5047acd283e9 100644 --- a/sys/x86/iommu/intel_ctx.c +++ b/sys/x86/iommu/intel_ctx.c @@ -877,7 +877,7 @@ dmar_domain_unload_emit_wait(struct dmar_domain *domain, if (TAILQ_NEXT(entry, dmamap_link) == NULL) return (true); - return (domain->batch_no++ % dmar_batch_coalesce == 0); + return (domain->batch_no++ % iommu_qi_batch_coalesce == 0); } void diff --git a/sys/x86/iommu/intel_dmar.h b/sys/x86/iommu/intel_dmar.h index c1e6c8f06f64..188e40dec36c 100644 --- a/sys/x86/iommu/intel_dmar.h +++ b/sys/x86/iommu/intel_dmar.h @@ -166,6 +166,8 @@ struct dmar_unit { #define DMAR_BARRIER_RMRR 0 #define DMAR_BARRIER_USEQ 1 +SYSCTL_DECL(_hw_iommu_dmar); + struct dmar_unit *dmar_find(device_t dev, bool verbose); struct dmar_unit *dmar_find_hpet(device_t dev, uint16_t *rid); struct dmar_unit *dmar_find_ioapic(u_int apic_id, uint16_t *rid); @@ -265,7 +267,6 @@ int dmar_map_ioapic_intr(u_int ioapic_id, u_int cpu, u_int vector, bool edge, int dmar_unmap_ioapic_intr(u_int ioapic_id, u_int *cookie); extern int haw; -extern int dmar_batch_coalesce; extern int dmar_rmrr_enable; static inline uint32_t diff --git a/sys/x86/iommu/intel_utils.c b/sys/x86/iommu/intel_utils.c index 141452b3393d..287b5fe9376a 100644 --- a/sys/x86/iommu/intel_utils.c +++ b/sys/x86/iommu/intel_utils.c @@ -507,7 +507,6 @@ dmar_barrier_exit(struct dmar_unit *dmar, u_int barrier_id) DMAR_UNLOCK(dmar); } -int dmar_batch_coalesce = 100; struct timespec dmar_hw_timeout = { .tv_sec = 0, .tv_nsec = 1000000 @@ -546,9 +545,6 @@ dmar_timeout_sysctl(SYSCTL_HANDLER_ARGS) return (error); } -SYSCTL_INT(_hw_iommu_dmar, OID_AUTO, batch_coalesce, CTLFLAG_RWTUN, - &dmar_batch_coalesce, 0, - "Number of qi batches between interrupt"); SYSCTL_PROC(_hw_iommu_dmar, OID_AUTO, timeout, CTLTYPE_U64 | CTLFLAG_RW | CTLFLAG_MPSAFE, 0, 0, dmar_timeout_sysctl, "QU", diff --git a/sys/x86/iommu/iommu_utils.c b/sys/x86/iommu/iommu_utils.c index 645c7e15740a..5d22c6584ab7 100644 --- a/sys/x86/iommu/iommu_utils.c +++ b/sys/x86/iommu/iommu_utils.c @@ -181,9 +181,14 @@ int iommu_tbl_pagecnt; SYSCTL_NODE(_hw_iommu, OID_AUTO, dmar, CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, ""); -SYSCTL_INT(_hw_iommu_dmar, OID_AUTO, tbl_pagecnt, CTLFLAG_RD, +SYSCTL_INT(_hw_iommu, OID_AUTO, tbl_pagecnt, CTLFLAG_RD, &iommu_tbl_pagecnt, 0, - "Count of pages used for DMAR pagetables"); + "Count of pages used for IOMMU pagetables"); + +int iommu_qi_batch_coalesce = 100; +SYSCTL_INT(_hw_iommu, OID_AUTO, batch_coalesce, CTLFLAG_RWTUN, + &iommu_qi_batch_coalesce, 0, + "Number of qi batches between interrupt"); static struct x86_iommu *x86_iommu; diff --git a/sys/x86/iommu/x86_iommu.h b/sys/x86/iommu/x86_iommu.h index b2caed550e35..210ce82c8f6d 100644 --- a/sys/x86/iommu/x86_iommu.h +++ b/sys/x86/iommu/x86_iommu.h @@ -55,9 +55,9 @@ void iommu_unmap_pgtbl(struct sf_buf *sf); extern iommu_haddr_t iommu_high; extern int iommu_tbl_pagecnt; +extern int iommu_qi_batch_coalesce; SYSCTL_DECL(_hw_iommu); -SYSCTL_DECL(_hw_iommu_dmar); struct x86_unit_common; From 22bf8cf32f355705eb40cfbd7892492ac8140c50 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Sat, 24 Aug 2024 00:12:15 +0300 Subject: [PATCH 139/213] DMAR: provide hw.iommu.ir alias for the hw.dmar.ir tunable Sponsored by: Advanced Micro Devices (AMD) Sponsored by: The FreeBSD Foundation MFC after: 1 week --- sys/x86/iommu/intel_intrmap.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sys/x86/iommu/intel_intrmap.c b/sys/x86/iommu/intel_intrmap.c index a6979a9d2501..ec3cd35e4f4e 100644 --- a/sys/x86/iommu/intel_intrmap.c +++ b/sys/x86/iommu/intel_intrmap.c @@ -323,6 +323,7 @@ dmar_init_irt(struct dmar_unit *unit) return (0); unit->ir_enabled = 1; TUNABLE_INT_FETCH("hw.dmar.ir", &unit->ir_enabled); + TUNABLE_INT_FETCH("hw.iommu.ir", &unit->ir_enabled); if (!unit->ir_enabled) return (0); if (!unit->qi_enabled) { From ba33e74c7d48479784896807eb8a1c2e1012d163 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Sat, 27 Jul 2024 19:28:01 +0300 Subject: [PATCH 140/213] busdma_iommu: indirect dmar-specific method calls in iommu_get_dev_ctx() Sponsored by: Advanced Micro Devices (AMD) Sponsored by: The FreeBSD Foundation MFC after: 1 week --- sys/arm64/iommu/iommu.c | 5 +++++ sys/dev/iommu/busdma_iommu.c | 6 +----- sys/dev/iommu/iommu.h | 1 + sys/x86/iommu/intel_drv.c | 8 ++++++++ sys/x86/iommu/iommu_utils.c | 6 ++++++ sys/x86/iommu/x86_iommu.h | 1 + 6 files changed, 22 insertions(+), 5 deletions(-) diff --git a/sys/arm64/iommu/iommu.c b/sys/arm64/iommu/iommu.c index b765763e3a60..af0edfee70d8 100644 --- a/sys/arm64/iommu/iommu.c +++ b/sys/arm64/iommu/iommu.c @@ -501,6 +501,11 @@ iommu_find(device_t dev, bool verbose) return (NULL); } +void +iommu_unit_pre_instantiate_ctx(struct iommu_unit *unit) +{ +} + void iommu_domain_unload_entry(struct iommu_map_entry *entry, bool free, bool cansleep __unused) diff --git a/sys/dev/iommu/busdma_iommu.c b/sys/dev/iommu/busdma_iommu.c index 3d554249ba3f..bddb466547d1 100644 --- a/sys/dev/iommu/busdma_iommu.c +++ b/sys/dev/iommu/busdma_iommu.c @@ -278,11 +278,7 @@ iommu_get_dev_ctx(device_t dev) if (!unit->dma_enabled) return (NULL); -#if defined(__amd64__) || defined(__i386__) - dmar_quirks_pre_use(unit); - dmar_instantiate_rmrr_ctxs(unit); -#endif - + iommu_unit_pre_instantiate_ctx(unit); return (iommu_instantiate_ctx(unit, dev, false)); } diff --git a/sys/dev/iommu/iommu.h b/sys/dev/iommu/iommu.h index 157f4c62423f..9845b09e8732 100644 --- a/sys/dev/iommu/iommu.h +++ b/sys/dev/iommu/iommu.h @@ -158,6 +158,7 @@ void iommu_domain_unload_entry(struct iommu_map_entry *entry, bool free, void iommu_domain_unload(struct iommu_domain *domain, struct iommu_map_entries_tailq *entries, bool cansleep); +void iommu_unit_pre_instantiate_ctx(struct iommu_unit *iommu); struct iommu_ctx *iommu_instantiate_ctx(struct iommu_unit *iommu, device_t dev, bool rmrr); device_t iommu_get_requester(device_t dev, uint16_t *rid); diff --git a/sys/x86/iommu/intel_drv.c b/sys/x86/iommu/intel_drv.c index 2439ef9e4ef5..05fb49538add 100644 --- a/sys/x86/iommu/intel_drv.c +++ b/sys/x86/iommu/intel_drv.c @@ -1310,8 +1310,16 @@ dmar_get_x86_common(struct iommu_unit *unit) return (&dmar->x86c); } +static void +dmar_unit_pre_instantiate_ctx(struct iommu_unit *unit) +{ + dmar_quirks_pre_use(unit); + dmar_instantiate_rmrr_ctxs(unit); +} + static struct x86_iommu dmar_x86_iommu = { .get_x86_common = dmar_get_x86_common, + .unit_pre_instantiate_ctx = dmar_unit_pre_instantiate_ctx, .domain_unload_entry = dmar_domain_unload_entry, .domain_unload = dmar_domain_unload, .get_ctx = dmar_get_ctx, diff --git a/sys/x86/iommu/iommu_utils.c b/sys/x86/iommu/iommu_utils.c index 5d22c6584ab7..2c647fd21c67 100644 --- a/sys/x86/iommu/iommu_utils.c +++ b/sys/x86/iommu/iommu_utils.c @@ -278,6 +278,12 @@ iommu_unmap_ioapic_intr(u_int ioapic_id, u_int *cookie) return (x86_iommu->unmap_ioapic_intr(ioapic_id, cookie)); } +void +iommu_unit_pre_instantiate_ctx(struct iommu_unit *unit) +{ + x86_iommu->unit_pre_instantiate_ctx(unit); +} + #define IOMMU2X86C(iommu) (x86_iommu->get_x86_common(iommu)) static bool diff --git a/sys/x86/iommu/x86_iommu.h b/sys/x86/iommu/x86_iommu.h index 210ce82c8f6d..a1ed5c71c513 100644 --- a/sys/x86/iommu/x86_iommu.h +++ b/sys/x86/iommu/x86_iommu.h @@ -64,6 +64,7 @@ struct x86_unit_common; struct x86_iommu { struct x86_unit_common *(*get_x86_common)(struct iommu_unit *iommu); + void (*unit_pre_instantiate_ctx)(struct iommu_unit *iommu); void (*qi_ensure)(struct iommu_unit *unit, int descr_count); void (*qi_emit_wait_descr)(struct iommu_unit *unit, uint32_t seq, bool, bool, bool); From 09fc33d1d75f93ed04fc6b18e7fe2911b7e770e0 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Sat, 20 Jul 2024 03:15:22 +0300 Subject: [PATCH 141/213] dmar: avoid excessive indirection in KASSERT() in domain_map_buf() Sponsored by: Advanced Micro Devices (AMD) Sponsored by: The FreeBSD Foundation MFC after: 1 week --- sys/x86/iommu/intel_idpgtbl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/x86/iommu/intel_idpgtbl.c b/sys/x86/iommu/intel_idpgtbl.c index 53851622340b..fbc0e9e97b64 100644 --- a/sys/x86/iommu/intel_idpgtbl.c +++ b/sys/x86/iommu/intel_idpgtbl.c @@ -478,7 +478,7 @@ domain_map_buf(struct iommu_domain *iodom, iommu_gaddr_t base, domain = IODOM2DOM(iodom); unit = domain->dmar; - KASSERT((domain->iodom.flags & IOMMU_DOMAIN_IDMAP) == 0, + KASSERT((iodom->flags & IOMMU_DOMAIN_IDMAP) == 0, ("modifying idmap pagetable domain %p", domain)); KASSERT((base & IOMMU_PAGE_MASK) == 0, ("non-aligned base %p %jx %jx", domain, (uintmax_t)base, From 5681ddfd9f80c3aa25f900a1bcaa69b36a4e9e27 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Tue, 27 Aug 2024 05:28:10 +0300 Subject: [PATCH 142/213] msi_alloc(): do not leak msi_lock in error case Sponsored by: Advanced Micro Devices (AMD) Sponsored by: The FreeBSD Foundation MFC after: 1 week --- sys/x86/x86/msi.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sys/x86/x86/msi.c b/sys/x86/x86/msi.c index 888635cba3f4..177bd7868ec4 100644 --- a/sys/x86/x86/msi.c +++ b/sys/x86/x86/msi.c @@ -480,6 +480,7 @@ msi_alloc(device_t dev, int count, int maxcount, int *irqs) if (error != 0) { for (i = 0; i < count; i++) apic_free_vector(cpu, vector + i, irqs[i]); + mtx_unlock(&msi_lock); free(mirqs, M_MSI); return (error); } From e8fc8eb8b8f55072379f65f5f058b81870031b7d Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Tue, 27 Aug 2024 05:28:49 +0300 Subject: [PATCH 143/213] msi_release(): consistently unlock msi_lock around iommu_unmap_msi_intr() Sponsored by: Advanced Micro Devices (AMD) Sponsored by: The FreeBSD Foundation MFC after: 1 week --- sys/x86/x86/msi.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sys/x86/x86/msi.c b/sys/x86/x86/msi.c index 177bd7868ec4..c8e7db9469ed 100644 --- a/sys/x86/x86/msi.c +++ b/sys/x86/x86/msi.c @@ -555,7 +555,9 @@ msi_release(int *irqs, int count) KASSERT(msi->msi_first == first, ("message not in group")); KASSERT(msi->msi_dev == first->msi_dev, ("owner mismatch")); #ifdef IOMMU + mtx_unlock(&msi_lock); iommu_unmap_msi_intr(first->msi_dev, msi->msi_remap_cookie); + mtx_lock(&msi_lock); #endif msi->msi_first = NULL; msi->msi_dev = NULL; From e28ee29d2d13dc24cd3d5e19fa1fe6bef0085d41 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Tue, 3 Sep 2024 06:42:54 +0300 Subject: [PATCH 144/213] vfs_default.c: trim whitespace Sponsored by: The FreeBSD Foundation MFC after: 3 days --- sys/kern/vfs_default.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sys/kern/vfs_default.c b/sys/kern/vfs_default.c index 1393f2fce9f3..d612642a6bc9 100644 --- a/sys/kern/vfs_default.c +++ b/sys/kern/vfs_default.c @@ -113,10 +113,10 @@ struct vop_vector default_vnodeops = { .vop_fsync = VOP_NULL, .vop_stat = vop_stdstat, .vop_fdatasync = vop_stdfdatasync, - .vop_getlowvnode = vop_stdgetlowvnode, + .vop_getlowvnode = vop_stdgetlowvnode, .vop_getpages = vop_stdgetpages, .vop_getpages_async = vop_stdgetpages_async, - .vop_getwritemount = vop_stdgetwritemount, + .vop_getwritemount = vop_stdgetwritemount, .vop_inactive = VOP_NULL, .vop_need_inactive = vop_stdneed_inactive, .vop_ioctl = vop_stdioctl, @@ -1087,7 +1087,7 @@ vop_stdadvise(struct vop_advise_args *ap) /* * Round to block boundaries (and later possibly further to - * page boundaries). Applications cannot reasonably be aware + * page boundaries). Applications cannot reasonably be aware * of the boundaries, and the rounding must be to expand at * both extremities to cover enough. It still doesn't cover * read-ahead. For partial blocks, this gives unnecessary From 66fc442421f868b01bee4e299d7e3a4c4df37d21 Mon Sep 17 00:00:00 2001 From: Mark Johnston Date: Wed, 4 Sep 2024 20:05:33 +0000 Subject: [PATCH 145/213] vmm: Remove an incorrect credential check in vmmdev_open() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Checking pointer equality here is too strict and can lead to incorrect errors, as credentials are frequently copied to avoid reference counting overhead. The check is new with commit 4008758105a6 and was added with the goal of allowing non-root users to create VMs in mind. Just remove it for now. Reported by: Alonso Cárdenas Márquez Reviewed by: jhb Fixes: 4008758105a6 ("vmm: Validate credentials when opening a vmmdev") Differential Revision: https://reviews.freebsd.org/D46535 --- sys/dev/vmm/vmm_dev.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/sys/dev/vmm/vmm_dev.c b/sys/dev/vmm/vmm_dev.c index ea2aaace832c..353b58dd8a2c 100644 --- a/sys/dev/vmm/vmm_dev.c +++ b/sys/dev/vmm/vmm_dev.c @@ -331,12 +331,6 @@ vmmdev_open(struct cdev *dev, int flags, int fmt, struct thread *td) sc = vmmdev_lookup2(dev); KASSERT(sc != NULL, ("%s: device not found", __func__)); - /* - * A user can only access VMs that they themselves have created. - */ - if (td->td_ucred != sc->ucred) - return (EPERM); - /* * A jail without vmm access shouldn't be able to access vmm device * files at all, but check here just to be thorough. From dc450b388bba182d0b3ce2f1a04c20acda7ff922 Mon Sep 17 00:00:00 2001 From: Mark Johnston Date: Thu, 5 Sep 2024 00:36:27 +0000 Subject: [PATCH 146/213] vmm: Remove more of vmmdev_open() The softc pointer is now unused, just remove it. Reported by: se Fixes: 66fc442421f8 ("vmm: Remove an incorrect credential check in vmmdev_open()") --- sys/dev/vmm/vmm_dev.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/sys/dev/vmm/vmm_dev.c b/sys/dev/vmm/vmm_dev.c index 353b58dd8a2c..a43d642b3925 100644 --- a/sys/dev/vmm/vmm_dev.c +++ b/sys/dev/vmm/vmm_dev.c @@ -325,12 +325,8 @@ vm_set_register_set(struct vcpu *vcpu, unsigned int count, int *regnum, static int vmmdev_open(struct cdev *dev, int flags, int fmt, struct thread *td) { - struct vmmdev_softc *sc; int error; - sc = vmmdev_lookup2(dev); - KASSERT(sc != NULL, ("%s: device not found", __func__)); - /* * A jail without vmm access shouldn't be able to access vmm device * files at all, but check here just to be thorough. From 79eba754bec39d88a6494318a2176d19743cf993 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Tue, 3 Sep 2024 07:20:40 +0300 Subject: [PATCH 147/213] vop_stdadvise(): restore correct handling of length == 0 Switch to unsigned arithmetic to handle overflow not relying on -fwrap, and specially treat the case of length == 0 from posix_fadvise() which passes OFF_MAX as the end to VOP. There, roundup() overflows and -fwrap causes bend and endn become negative. Using uintmax_t gives the place for roundup() to not wrap. Also remove locals with single use, and move calculations out from under bo lock. Reported by: tmunro Reviewed by: markj, tmunro Sponsored by: The FreeBSD Foundation MFC after: 1 week Differential revision: https://reviews.freebsd.org/D46518 --- sys/kern/vfs_default.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/sys/kern/vfs_default.c b/sys/kern/vfs_default.c index d612642a6bc9..f5722851d729 100644 --- a/sys/kern/vfs_default.c +++ b/sys/kern/vfs_default.c @@ -1063,8 +1063,8 @@ vop_stdadvise(struct vop_advise_args *ap) { struct vnode *vp; struct bufobj *bo; + uintmax_t bstart, bend; daddr_t startn, endn; - off_t bstart, bend, start, end; int bsize, error; vp = ap->a_vp; @@ -1096,7 +1096,8 @@ vop_stdadvise(struct vop_advise_args *ap) */ bsize = vp->v_bufobj.bo_bsize; bstart = rounddown(ap->a_start, bsize); - bend = roundup(ap->a_end, bsize); + bend = ap->a_end; + bend = roundup(bend, bsize); /* * Deactivate pages in the specified range from the backing VM @@ -1105,18 +1106,17 @@ vop_stdadvise(struct vop_advise_args *ap) * below. */ if (vp->v_object != NULL) { - start = trunc_page(bstart); - end = round_page(bend); VM_OBJECT_RLOCK(vp->v_object); - vm_object_page_noreuse(vp->v_object, OFF_TO_IDX(start), - OFF_TO_IDX(end)); + vm_object_page_noreuse(vp->v_object, + OFF_TO_IDX(trunc_page(bstart)), + OFF_TO_IDX(round_page(bend))); VM_OBJECT_RUNLOCK(vp->v_object); } bo = &vp->v_bufobj; - BO_RLOCK(bo); startn = bstart / bsize; endn = bend / bsize; + BO_RLOCK(bo); error = bnoreuselist(&bo->bo_clean, bo, startn, endn); if (error == 0) error = bnoreuselist(&bo->bo_dirty, bo, startn, endn); From 99e3d96fc1a2b1d5cac5a635608ec3044ec4fa13 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Thu, 5 Sep 2024 03:33:34 +0300 Subject: [PATCH 148/213] x86: always provide dummy x86_iommu virtual methods to make configurations where vendor-specific IOMMU not yet implemented but IOMMU is enabled in config, work when calling into MSI/IOAPIC interrupt remapping. Reported by: cy Sponsored by: Advanced Micro Devices (AMD) Sponsored by: The FreeBSD Foundation MFC after: 1 week --- sys/x86/iommu/iommu_utils.c | 52 +++++++++++++++++++++++++++++++++++-- 1 file changed, 50 insertions(+), 2 deletions(-) diff --git a/sys/x86/iommu/iommu_utils.c b/sys/x86/iommu/iommu_utils.c index 2c647fd21c67..2011c632f770 100644 --- a/sys/x86/iommu/iommu_utils.c +++ b/sys/x86/iommu/iommu_utils.c @@ -190,12 +190,60 @@ SYSCTL_INT(_hw_iommu, OID_AUTO, batch_coalesce, CTLFLAG_RWTUN, &iommu_qi_batch_coalesce, 0, "Number of qi batches between interrupt"); -static struct x86_iommu *x86_iommu; +static struct iommu_unit * +x86_no_iommu_find(device_t dev, bool verbose) +{ + return (NULL); +} + +static int +x86_no_iommu_alloc_msi_intr(device_t src, u_int *cookies, u_int count) +{ + return (EOPNOTSUPP); +} + +static int +x86_no_iommu_map_msi_intr(device_t src, u_int cpu, u_int vector, + u_int cookie, uint64_t *addr, uint32_t *data) +{ + return (EOPNOTSUPP); +} + +static int +x86_no_iommu_unmap_msi_intr(device_t src, u_int cookie) +{ + return (0); +} + +static int +x86_no_iommu_map_ioapic_intr(u_int ioapic_id, u_int cpu, u_int vector, + bool edge, bool activehi, int irq, u_int *cookie, uint32_t *hi, + uint32_t *lo) +{ + return (EOPNOTSUPP); +} + +static int +x86_no_iommu_unmap_ioapic_intr(u_int ioapic_id, u_int *cookie) +{ + return (0); +} + +static struct x86_iommu x86_no_iommu = { + .find = x86_no_iommu_find, + .alloc_msi_intr = x86_no_iommu_alloc_msi_intr, + .map_msi_intr = x86_no_iommu_map_msi_intr, + .unmap_msi_intr = x86_no_iommu_unmap_msi_intr, + .map_ioapic_intr = x86_no_iommu_map_ioapic_intr, + .unmap_ioapic_intr = x86_no_iommu_unmap_ioapic_intr, +}; + +static struct x86_iommu *x86_iommu = &x86_no_iommu; void set_x86_iommu(struct x86_iommu *x) { - MPASS(x86_iommu == NULL); + MPASS(x86_iommu == &x86_no_iommu); x86_iommu = x; } From ef438f7706be48f1cf7fd4c8a60329e1619cfe30 Mon Sep 17 00:00:00 2001 From: Michael Tuexen Date: Thu, 5 Sep 2024 03:33:13 +0200 Subject: [PATCH 149/213] tcp: improve consistency of syncache_respond() failure handling When the initial sending of the SYN ACK segment using syncache_respond() fails, it is handled as a permanent error. To improve consistency, apply this policy in all cases, where syncache_respond() is called. These include * timer based retransmissions of the SYN ACK * retransmitting a SYN ACK in response to a SYN retransmission * sending of challenge ACKs in response to received RST segments In these cases, fall back to SYN cookies, if enabled. While there, also improve consistency of the TCP stats counters. Reviewed by: cc, glebius (earlier version) MFC after: 1 week Sponsored by: Netflix, Inc. Differential Revision: https://reviews.freebsd.org/D46428 --- sys/netinet/tcp_syncache.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/sys/netinet/tcp_syncache.c b/sys/netinet/tcp_syncache.c index 33a6a66b7138..d0a7690256f4 100644 --- a/sys/netinet/tcp_syncache.c +++ b/sys/netinet/tcp_syncache.c @@ -527,10 +527,16 @@ syncache_timer(void *xsch) } NET_EPOCH_ENTER(et); - syncache_respond(sc, NULL, TH_SYN|TH_ACK); + if (syncache_respond(sc, NULL, TH_SYN|TH_ACK) == 0) { + syncache_timeout(sc, sch, 0); + TCPSTAT_INC(tcps_sndacks); + TCPSTAT_INC(tcps_sndtotal); + TCPSTAT_INC(tcps_sc_retransmitted); + } else { + syncache_drop(sc, sch); + TCPSTAT_INC(tcps_sc_dropped); + } NET_EPOCH_EXIT(et); - TCPSTAT_INC(tcps_sc_retransmitted); - syncache_timeout(sc, sch, 0); } if (!TAILQ_EMPTY(&(sch)->sch_bucket)) callout_reset(&(sch)->sch_timer, (sch)->sch_nextc - tick, @@ -688,7 +694,13 @@ syncache_chkrst(struct in_conninfo *inc, struct tcphdr *th, struct mbuf *m, "sending challenge ACK\n", s, __func__, th->th_seq, sc->sc_irs + 1, sc->sc_wnd); - syncache_respond(sc, m, TH_ACK); + if (syncache_respond(sc, m, TH_ACK) == 0) { + TCPSTAT_INC(tcps_sndacks); + TCPSTAT_INC(tcps_sndtotal); + } else { + syncache_drop(sc, sch); + TCPSTAT_INC(tcps_sc_dropped); + } } } else { if ((s = tcp_log_addrs(inc, th, NULL, NULL))) @@ -1549,6 +1561,9 @@ syncache_add(struct in_conninfo *inc, struct tcpopt *to, struct tcphdr *th, syncache_timeout(sc, sch, 1); TCPSTAT_INC(tcps_sndacks); TCPSTAT_INC(tcps_sndtotal); + } else { + syncache_drop(sc, sch); + TCPSTAT_INC(tcps_sc_dropped); } SCH_UNLOCK(sch); goto donenoprobe; From 7aeec281b8b2620d7d88c9abdfadd7e20a485b9c Mon Sep 17 00:00:00 2001 From: Navdeep Parhar Date: Wed, 4 Sep 2024 19:28:09 -0700 Subject: [PATCH 150/213] cxgbe(4): Always report link-down on an abrupt stop. This fixes a regression in 5241b210a4e1 where the driver stopped reporting link down after a fatal error unless t4_reset_on_fatal_err was also set. Fixes: 5241b210a4e1 cxgbe(4): Basic infrastructure for ULDs to participate in adapter reset. MFC after: 1 week Sponsored by: Chelsio Communications --- sys/dev/cxgbe/t4_main.c | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/sys/dev/cxgbe/t4_main.c b/sys/dev/cxgbe/t4_main.c index 0606f383b879..540edbb568c0 100644 --- a/sys/dev/cxgbe/t4_main.c +++ b/sys/dev/cxgbe/t4_main.c @@ -1920,6 +1920,9 @@ t4_detach_common(device_t dev) static inline int stop_adapter(struct adapter *sc) { + struct port_info *pi; + int i; + if (atomic_testandset_int(&sc->error_flags, ilog2(ADAP_STOPPED))) { CH_ALERT(sc, "%s from %p, flags 0x%08x,0x%08x, EALREADY\n", __func__, curthread, sc->flags, sc->error_flags); @@ -1927,7 +1930,24 @@ stop_adapter(struct adapter *sc) } CH_ALERT(sc, "%s from %p, flags 0x%08x,0x%08x\n", __func__, curthread, sc->flags, sc->error_flags); - return (t4_shutdown_adapter(sc)); + t4_shutdown_adapter(sc); + for_each_port(sc, i) { + pi = sc->port[i]; + PORT_LOCK(pi); + if (pi->up_vis > 0 && pi->link_cfg.link_ok) { + /* + * t4_shutdown_adapter has already shut down all the + * PHYs but it also disables interrupts and DMA so there + * won't be a link interrupt. Update the state manually + * if the link was up previously and inform the kernel. + */ + pi->link_cfg.link_ok = false; + t4_os_link_changed(pi); + } + PORT_UNLOCK(pi); + } + + return (0); } static inline int @@ -2020,20 +2040,6 @@ stop_lld(struct adapter *sc) for_each_port(sc, i) { pi = sc->port[i]; pi->vxlan_tcam_entry = false; - - PORT_LOCK(pi); - if (pi->up_vis > 0) { - /* - * t4_shutdown_adapter has already shut down all the - * PHYs but it also disables interrupts and DMA so there - * won't be a link interrupt. So we update the state - * manually and inform the kernel. - */ - pi->link_cfg.link_ok = false; - t4_os_link_changed(pi); - } - PORT_UNLOCK(pi); - for_each_vi(pi, j, vi) { vi->xact_addr_filt = -1; mtx_lock(&vi->tick_mtx); From a9ac25d65f640a0a06a96e20c60bb34111db8ef6 Mon Sep 17 00:00:00 2001 From: Kristof Provost Date: Mon, 2 Sep 2024 15:34:50 +0200 Subject: [PATCH 151/213] pf.4: document missing sysctls Sponsored by: Rubicon Communications, LLC ("Netgate") Differential Revision: https://reviews.freebsd.org/D46510 --- share/man/man4/pf.4 | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/share/man/man4/pf.4 b/share/man/man4/pf.4 index 645f31e6e395..9bfc75cb490d 100644 --- a/share/man/man4/pf.4 +++ b/share/man/man4/pf.4 @@ -26,7 +26,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd October 20, 2023 +.Dd September 2, 2024 .Dt PF 4 .Os .Sh NAME @@ -80,17 +80,26 @@ The following tunables are available. .Bl -tag -width indent .It Va net.pf.states_hashsize -Size of hash tables that store states. +Size of hash table that stores states. Should be power of 2. Default value is 131072. .It Va net.pf.source_nodes_hashsize -Size of hash table that store source nodes. +Size of hash table that stores source nodes. Should be power of 2. Default value is 32768. +.It Va net.pf.rule_tag_hashsize +Size of the hash table that stores tags. .It Va net.pf.default_to_drop This value overrides .Cd "options PF_DEFAULT_TO_DROP" from kernel configuration file. +.It Va net.pf.filter_local +This tells +.Nm +to also filter on the loopback output hook. +This is typically used to allow redirect rules to adjust the source address. +.It net.pf.request_maxcount +The maximum number of items in a single ioctl call. .El .Pp Read only From 5644e2c6d47c6113a61ab7fc0776b7227677656a Mon Sep 17 00:00:00 2001 From: Kristof Provost Date: Wed, 4 Sep 2024 14:54:23 +0200 Subject: [PATCH 152/213] if_ovpn: ensure it's safe to modify the mbuf PR: 280036 Reviewed by: ae MFC after: 1 week Sponsored by: Rubicon Communications, LLC ("Netgate") Differential Revision: https://reviews.freebsd.org/D46529 --- sys/net/if_ovpn.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/sys/net/if_ovpn.c b/sys/net/if_ovpn.c index f6f640a65f61..ee097cfa24b3 100644 --- a/sys/net/if_ovpn.c +++ b/sys/net/if_ovpn.c @@ -2115,6 +2115,12 @@ ovpn_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst, sc = ifp->if_softc; + m = m_unshare(m, M_NOWAIT); + if (m == NULL) { + OVPN_COUNTER_ADD(sc, lost_data_pkts_out, 1); + return (ENOBUFS); + } + OVPN_RLOCK(sc); SDT_PROBE1(if_ovpn, tx, transmit, start, m); @@ -2233,6 +2239,12 @@ ovpn_udp_input(struct mbuf *m, int off, struct inpcb *inp, M_ASSERTPKTHDR(m); + m = m_unshare(m, M_NOWAIT); + if (m == NULL) { + OVPN_COUNTER_ADD(sc, nomem_data_pkts_in, 1); + return (true); + } + OVPN_COUNTER_ADD(sc, transport_bytes_received, m->m_pkthdr.len - off); ohdrlen = sizeof(*ohdr) - sizeof(ohdr->auth_tag); From 7be11454edd4eca6cbd299cb5b486294f912ffbd Mon Sep 17 00:00:00 2001 From: Andrew Turner Date: Thu, 5 Sep 2024 13:11:42 +0100 Subject: [PATCH 153/213] arm64: Add the tcr_el2 ds field This will be used to support FEAT_LPA2 to allow more than 48 bits of physical address space. Reviewed by: alc, kib, markj Sponsored by: Arm Ltd Differential Revision: https://reviews.freebsd.org/D46392 --- sys/arm64/include/armreg.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sys/arm64/include/armreg.h b/sys/arm64/include/armreg.h index a04afd57585c..b4adc3d2c254 100644 --- a/sys/arm64/include/armreg.h +++ b/sys/arm64/include/armreg.h @@ -2444,6 +2444,8 @@ #define TCR_EL1_CRm 0 #define TCR_EL1_op2 2 /* Bits 63:59 are reserved */ +#define TCR_DS_SHIFT 59 +#define TCR_DS (UL(1) << TCR_DS_SHIFT) #define TCR_TCMA1_SHIFT 58 #define TCR_TCMA1 (UL(1) << TCR_TCMA1_SHIFT) #define TCR_TCMA0_SHIFT 57 From 3a3aa2cc07563e288950affbda6b743487e9d49d Mon Sep 17 00:00:00 2001 From: Andrew Turner Date: Thu, 5 Sep 2024 13:11:48 +0100 Subject: [PATCH 154/213] arm64: Remove TCR_CACHE_ATTRS and TCR_SMP_ATTRS These are only used in one place so expand them there. While here always set TCR_SH0_IS and TCR_SH1_IS. There is no advantage to not set them in a UP kernel. Reviewed by: alc, kib, markj Sponsored by: Arm Ltd Differential Revision: https://reviews.freebsd.org/D46393 --- sys/arm64/arm64/locore.S | 5 +++-- sys/arm64/include/armreg.h | 8 -------- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/sys/arm64/arm64/locore.S b/sys/arm64/arm64/locore.S index ae1a005fd68f..daf8a936eda2 100644 --- a/sys/arm64/arm64/locore.S +++ b/sys/arm64/arm64/locore.S @@ -945,8 +945,9 @@ tcr: #error Unsupported page size #endif - .quad (TCR_TxSZ(64 - VIRT_BITS) | TCR_TG | \ - TCR_CACHE_ATTRS | TCR_SMP_ATTRS) + .quad (TCR_TxSZ(64 - VIRT_BITS) | TCR_TG | \ + TCR_SH1_IS | TCR_ORGN1_WBWA | TCR_IRGN1_WBWA | \ + TCR_SH0_IS | TCR_ORGN0_WBWA | TCR_IRGN0_WBWA) sctlr_set: /* Bits to set */ .quad (SCTLR_LSMAOE | SCTLR_nTLSMD | SCTLR_UCI | SCTLR_SPAN | \ diff --git a/sys/arm64/include/armreg.h b/sys/arm64/include/armreg.h index b4adc3d2c254..54600d63891e 100644 --- a/sys/arm64/include/armreg.h +++ b/sys/arm64/include/armreg.h @@ -2543,14 +2543,6 @@ #define TCR_T0SZ(x) ((x) << TCR_T0SZ_SHIFT) #define TCR_TxSZ(x) (TCR_T1SZ(x) | TCR_T0SZ(x)) -#define TCR_CACHE_ATTRS ((TCR_IRGN0_WBWA | TCR_IRGN1_WBWA) |\ - (TCR_ORGN0_WBWA | TCR_ORGN1_WBWA)) -#ifdef SMP -#define TCR_SMP_ATTRS (TCR_SH0_IS | TCR_SH1_IS) -#else -#define TCR_SMP_ATTRS 0 -#endif - /* TCR_EL12 */ #define TCR_EL12_REG MRS_REG_ALT_NAME(TCR_EL12) #define TCR_EL12_op0 3 From e2990a9ee479b7d31bceb75310c0f290cdfb8504 Mon Sep 17 00:00:00 2001 From: Andrew Turner Date: Thu, 5 Sep 2024 13:11:55 +0100 Subject: [PATCH 155/213] arm64: Remove ATTR_DEFAULT from pte.h ATTR_SH(ATTR_SH_IS) will soon be dynamic as the field is moved out of the page tables in FEAT_LPA2. When this happens ATTR_DEFAULT will just be ATTR_AF. Rather than keeping ATTR_DEFAULT with one attribute remove it. Reviewed by: alc, kib, markj Sponsored by: Arm Ltd Differential Revision: https://reviews.freebsd.org/D46466 --- sys/arm64/arm64/efirt_machdep.c | 2 +- sys/arm64/arm64/locore.S | 4 +-- sys/arm64/arm64/minidump_machdep.c | 6 ++-- sys/arm64/arm64/pmap.c | 53 ++++++++++++++++-------------- sys/arm64/include/pte.h | 2 -- sys/arm64/iommu/iommu_pmap.c | 2 +- sys/arm64/vmm/vmm_mmu.c | 2 +- 7 files changed, 36 insertions(+), 35 deletions(-) diff --git a/sys/arm64/arm64/efirt_machdep.c b/sys/arm64/arm64/efirt_machdep.c index 0c46d2e6dcc6..7c1d12b0b9b4 100644 --- a/sys/arm64/arm64/efirt_machdep.c +++ b/sys/arm64/arm64/efirt_machdep.c @@ -214,7 +214,7 @@ efi_create_1t1_map(struct efi_md *map, int ndesc, int descsz) p->md_phys, mode, p->md_pages); } - l3_attr = ATTR_DEFAULT | ATTR_S1_IDX(mode) | + l3_attr = ATTR_AF | ATTR_SH(ATTR_SH_IS) | ATTR_S1_IDX(mode) | ATTR_S1_AP(ATTR_S1_AP_RW) | ATTR_S1_nG | L3_PAGE; if (mode == VM_MEMATTR_DEVICE || p->md_attr & EFI_MD_ATTR_XP) l3_attr |= ATTR_S1_XN; diff --git a/sys/arm64/arm64/locore.S b/sys/arm64/arm64/locore.S index daf8a936eda2..e37ea5aa3b48 100644 --- a/sys/arm64/arm64/locore.S +++ b/sys/arm64/arm64/locore.S @@ -747,7 +747,7 @@ LENTRY(build_l2_block_pagetable) /* Build the L2 block entry */ orr x12, x7, #L2_BLOCK - orr x12, x12, #(ATTR_DEFAULT) + orr x12, x12, #(ATTR_AF | ATTR_SH(ATTR_SH_IS)) orr x12, x12, #(ATTR_S1_UXN) #ifdef __ARM_FEATURE_BTI_DEFAULT orr x12, x12, #(ATTR_S1_GP) @@ -823,7 +823,7 @@ LENTRY(build_l3_page_pagetable) /* Build the L3 page entry */ orr x12, x7, #L3_PAGE - orr x12, x12, #(ATTR_DEFAULT) + orr x12, x12, #(ATTR_AF | ATTR_SH(ATTR_SH_IS)) orr x12, x12, #(ATTR_S1_UXN) #ifdef __ARM_FEATURE_BTI_DEFAULT orr x12, x12, #(ATTR_S1_GP) diff --git a/sys/arm64/arm64/minidump_machdep.c b/sys/arm64/arm64/minidump_machdep.c index 8ee626953aef..ac0a2c2dc96e 100644 --- a/sys/arm64/arm64/minidump_machdep.c +++ b/sys/arm64/arm64/minidump_machdep.c @@ -310,8 +310,8 @@ cpu_minidumpsys(struct dumperinfo *di, const struct minidumpstate *state) for (i = 0; i < Ln_ENTRIES; i++) { for (j = 0; j < Ln_ENTRIES; j++) { tmpbuffer[j] = (pa + i * L2_SIZE + - j * PAGE_SIZE) | ATTR_DEFAULT | - L3_PAGE; + j * PAGE_SIZE) | ATTR_AF | + ATTR_SH(ATTR_SH_IS) | L3_PAGE; } error = blk_write(di, (char *)&tmpbuffer, 0, PAGE_SIZE); @@ -330,7 +330,7 @@ cpu_minidumpsys(struct dumperinfo *di, const struct minidumpstate *state) /* Generate fake l3 entries based upon the l1 entry */ for (i = 0; i < Ln_ENTRIES; i++) { tmpbuffer[i] = (pa + i * PAGE_SIZE) | - ATTR_DEFAULT | L3_PAGE; + ATTR_AF | ATTR_SH(ATTR_SH_IS) | L3_PAGE; } error = blk_write(di, (char *)&tmpbuffer, 0, PAGE_SIZE); if (error) diff --git a/sys/arm64/arm64/pmap.c b/sys/arm64/arm64/pmap.c index 224ecbdc4577..5f09f4cbcf1b 100644 --- a/sys/arm64/arm64/pmap.c +++ b/sys/arm64/arm64/pmap.c @@ -185,8 +185,8 @@ #else #define ATTR_KERN_GP 0 #endif -#define PMAP_SAN_PTE_BITS (ATTR_DEFAULT | ATTR_S1_XN | ATTR_KERN_GP | \ - ATTR_S1_IDX(VM_MEMATTR_WRITE_BACK) | ATTR_S1_AP(ATTR_S1_AP_RW)) +#define PMAP_SAN_PTE_BITS (ATTR_AF | ATTR_SH(ATTR_SH_IS) | ATTR_S1_XN | \ + ATTR_KERN_GP | ATTR_S1_IDX(VM_MEMATTR_WRITE_BACK) | ATTR_S1_AP(ATTR_S1_AP_RW)) struct pmap_large_md_page { struct rwlock pv_lock; @@ -1150,7 +1150,7 @@ pmap_bootstrap_l2_block(struct pmap_bootstrap_state *state, int i) MPASS((state->pa & L2_OFFSET) == 0); MPASS(state->l2[l2_slot] == 0); pmap_store(&state->l2[l2_slot], PHYS_TO_PTE(state->pa) | - ATTR_DEFAULT | ATTR_S1_XN | ATTR_KERN_GP | + ATTR_AF | ATTR_SH(ATTR_SH_IS) | ATTR_S1_XN | ATTR_KERN_GP | ATTR_S1_IDX(VM_MEMATTR_WRITE_BACK) | contig | L2_BLOCK); } MPASS(state->va == (state->pa - dmap_phys_base + DMAP_MIN_ADDRESS)); @@ -1200,7 +1200,7 @@ pmap_bootstrap_l3_page(struct pmap_bootstrap_state *state, int i) MPASS((state->pa & L3_OFFSET) == 0); MPASS(state->l3[l3_slot] == 0); pmap_store(&state->l3[l3_slot], PHYS_TO_PTE(state->pa) | - ATTR_DEFAULT | ATTR_S1_XN | ATTR_KERN_GP | + ATTR_AF | ATTR_SH(ATTR_SH_IS) | ATTR_S1_XN | ATTR_KERN_GP | ATTR_S1_IDX(VM_MEMATTR_WRITE_BACK) | contig | L3_PAGE); } MPASS(state->va == (state->pa - dmap_phys_base + DMAP_MIN_ADDRESS)); @@ -1242,7 +1242,8 @@ pmap_bootstrap_dmap(void) MPASS((bs_state.pa & L1_OFFSET) == 0); pmap_store( &bs_state.l1[pmap_l1_index(bs_state.va)], - PHYS_TO_PTE(bs_state.pa) | ATTR_DEFAULT | + PHYS_TO_PTE(bs_state.pa) | ATTR_AF | + ATTR_SH(ATTR_SH_IS) | ATTR_S1_IDX(VM_MEMATTR_WRITE_BACK) | ATTR_S1_XN | ATTR_KERN_GP | L1_BLOCK); } @@ -2111,8 +2112,8 @@ pmap_kenter(vm_offset_t sva, vm_size_t size, vm_paddr_t pa, int mode) KASSERT((size & PAGE_MASK) == 0, ("pmap_kenter: Mapping is not page-sized")); - attr = ATTR_DEFAULT | ATTR_S1_AP(ATTR_S1_AP_RW) | ATTR_S1_XN | - ATTR_KERN_GP | ATTR_S1_IDX(mode); + attr = ATTR_AF | ATTR_SH(ATTR_SH_IS) | ATTR_S1_AP(ATTR_S1_AP_RW) | + ATTR_S1_XN | ATTR_KERN_GP | ATTR_S1_IDX(mode); old_l3e = 0; va = sva; while (size != 0) { @@ -2326,7 +2327,8 @@ pmap_qenter(vm_offset_t sva, vm_page_t *ma, int count) ("pmap_qenter: Invalid level %d", lvl)); m = ma[i]; - attr = ATTR_DEFAULT | ATTR_S1_AP(ATTR_S1_AP_RW) | ATTR_S1_XN | + attr = ATTR_AF | ATTR_SH(ATTR_SH_IS) | + ATTR_S1_AP(ATTR_S1_AP_RW) | ATTR_S1_XN | ATTR_KERN_GP | ATTR_S1_IDX(m->md.pv_memattr) | L3_PAGE; pte = pmap_l2_to_l3(pde, va); old_l3e |= pmap_load_store(pte, VM_PAGE_TO_PTE(m) | attr); @@ -5122,7 +5124,8 @@ pmap_enter(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot, if ((m->oflags & VPO_UNMANAGED) == 0) VM_PAGE_OBJECT_BUSY_ASSERT(m); pa = VM_PAGE_TO_PHYS(m); - new_l3 = (pt_entry_t)(PHYS_TO_PTE(pa) | ATTR_DEFAULT | L3_PAGE); + new_l3 = (pt_entry_t)(PHYS_TO_PTE(pa) | ATTR_AF | ATTR_SH(ATTR_SH_IS) | + L3_PAGE); new_l3 |= pmap_pte_memattr(pmap, m->md.pv_memattr); new_l3 |= pmap_pte_prot(pmap, prot); if ((flags & PMAP_ENTER_WIRED) != 0) @@ -5465,13 +5468,13 @@ pmap_enter_l2_rx(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot, KASSERT(ADDR_IS_CANONICAL(va), ("%s: Address not in canonical form: %lx", __func__, va)); - new_l2 = (pd_entry_t)(VM_PAGE_TO_PTE(m) | ATTR_DEFAULT | + new_l2 = (pd_entry_t)(VM_PAGE_TO_PTE(m) | ATTR_SH(ATTR_SH_IS) | ATTR_S1_IDX(m->md.pv_memattr) | ATTR_S1_AP(ATTR_S1_AP_RO) | L2_BLOCK); - if ((m->oflags & VPO_UNMANAGED) == 0) { + if ((m->oflags & VPO_UNMANAGED) == 0) new_l2 |= ATTR_SW_MANAGED; - new_l2 &= ~ATTR_AF; - } + else + new_l2 |= ATTR_AF; if ((prot & VM_PROT_EXECUTE) == 0 || m->md.pv_memattr == VM_MEMATTR_DEVICE) new_l2 |= ATTR_S1_XN; @@ -5694,13 +5697,13 @@ pmap_enter_l3c_rx(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_page_t *ml3p, KASSERT(ADDR_IS_CANONICAL(va), ("%s: Address not in canonical form: %lx", __func__, va)); - l3e = VM_PAGE_TO_PTE(m) | ATTR_DEFAULT | + l3e = VM_PAGE_TO_PTE(m) | ATTR_SH(ATTR_SH_IS) | ATTR_S1_IDX(m->md.pv_memattr) | ATTR_S1_AP(ATTR_S1_AP_RO) | ATTR_CONTIGUOUS | L3_PAGE; - if ((m->oflags & VPO_UNMANAGED) == 0) { + if ((m->oflags & VPO_UNMANAGED) == 0) l3e |= ATTR_SW_MANAGED; - l3e &= ~ATTR_AF; - } + else + l3e |= ATTR_AF; if ((prot & VM_PROT_EXECUTE) == 0 || m->md.pv_memattr == VM_MEMATTR_DEVICE) l3e |= ATTR_S1_XN; @@ -6091,8 +6094,8 @@ pmap_enter_quick_locked(pmap_t pmap, vm_offset_t va, vm_page_t m, pmap_resident_count_inc(pmap, 1); pa = VM_PAGE_TO_PHYS(m); - l3_val = PHYS_TO_PTE(pa) | ATTR_DEFAULT | ATTR_S1_IDX(m->md.pv_memattr) | - ATTR_S1_AP(ATTR_S1_AP_RO) | L3_PAGE; + l3_val = PHYS_TO_PTE(pa) | ATTR_SH(ATTR_SH_IS) | + ATTR_S1_IDX(m->md.pv_memattr) | ATTR_S1_AP(ATTR_S1_AP_RO) | L3_PAGE; l3_val |= pmap_pte_bti(pmap, va); if ((prot & VM_PROT_EXECUTE) == 0 || m->md.pv_memattr == VM_MEMATTR_DEVICE) @@ -6107,10 +6110,10 @@ pmap_enter_quick_locked(pmap_t pmap, vm_offset_t va, vm_page_t m, /* * Now validate mapping with RO protection */ - if ((m->oflags & VPO_UNMANAGED) == 0) { + if ((m->oflags & VPO_UNMANAGED) == 0) l3_val |= ATTR_SW_MANAGED; - l3_val &= ~ATTR_AF; - } + else + l3_val |= ATTR_AF; /* Sync icache before the mapping is stored to PTE */ if ((prot & VM_PROT_EXECUTE) && pmap != kernel_pmap && @@ -7741,9 +7744,9 @@ pmap_mapbios(vm_paddr_t pa, vm_size_t size) /* Insert L2_BLOCK */ l2 = pmap_l1_to_l2(pde, va); old_l2e |= pmap_load_store(l2, - PHYS_TO_PTE(pa) | ATTR_DEFAULT | ATTR_S1_XN | - ATTR_KERN_GP | ATTR_S1_IDX(VM_MEMATTR_WRITE_BACK) | - L2_BLOCK); + PHYS_TO_PTE(pa) | ATTR_AF | ATTR_SH(ATTR_SH_IS) | + ATTR_S1_XN | ATTR_KERN_GP | + ATTR_S1_IDX(VM_MEMATTR_WRITE_BACK) | L2_BLOCK); va += L2_SIZE; pa += L2_SIZE; diff --git a/sys/arm64/include/pte.h b/sys/arm64/include/pte.h index 1f36655a45e2..02eba21448ba 100644 --- a/sys/arm64/include/pte.h +++ b/sys/arm64/include/pte.h @@ -111,8 +111,6 @@ typedef uint64_t pt_entry_t; /* page table entry */ #define ATTR_S2_MEMATTR_WT 0xa #define ATTR_S2_MEMATTR_WB 0xf -#define ATTR_DEFAULT (ATTR_AF | ATTR_SH(ATTR_SH_IS)) - #define ATTR_DESCR_MASK 3 #define ATTR_DESCR_VALID 1 #define ATTR_DESCR_TYPE_MASK 2 diff --git a/sys/arm64/iommu/iommu_pmap.c b/sys/arm64/iommu/iommu_pmap.c index 8a0ea641e231..dc5c09239c04 100644 --- a/sys/arm64/iommu/iommu_pmap.c +++ b/sys/arm64/iommu/iommu_pmap.c @@ -708,7 +708,7 @@ smmu_pmap_enter(struct smmu_pmap *pmap, vm_offset_t va, vm_paddr_t pa, KASSERT(va < VM_MAXUSER_ADDRESS, ("wrong address space")); va = trunc_page(va); - new_l3 = (pt_entry_t)(pa | ATTR_DEFAULT | + new_l3 = (pt_entry_t)(pa | ATTR_AF | ATTR_SH(ATTR_SH_IS) | ATTR_S1_IDX(VM_MEMATTR_DEVICE) | IOMMU_L3_PAGE); if ((prot & VM_PROT_WRITE) == 0) new_l3 |= ATTR_S1_AP(ATTR_S1_AP_RO); diff --git a/sys/arm64/vmm/vmm_mmu.c b/sys/arm64/vmm/vmm_mmu.c index 1f2d248a743b..42537254e27b 100644 --- a/sys/arm64/vmm/vmm_mmu.c +++ b/sys/arm64/vmm/vmm_mmu.c @@ -294,7 +294,7 @@ vmmpmap_enter(vm_offset_t va, vm_size_t size, vm_paddr_t pa, vm_prot_t prot) KASSERT((size & PAGE_MASK) == 0, ("%s: Mapping is not page-sized", __func__)); - l3e = ATTR_DEFAULT | L3_PAGE; + l3e = ATTR_AF | ATTR_SH(ATTR_SH_IS) | L3_PAGE; /* This bit is res1 at EL2 */ l3e |= ATTR_S1_AP(ATTR_S1_AP_USER); /* Only normal memory is used at EL2 */ From d52c31904218c79424435b69b9ec4098885d800f Mon Sep 17 00:00:00 2001 From: Andrew Turner Date: Thu, 5 Sep 2024 13:12:04 +0100 Subject: [PATCH 156/213] arm64: Make shareability attributes dynamic When LPA2 is enabled the shareability attribute in the page table are replaces with output address bits. To support a larger physical address space make this attribute dynamic so we only set it when appropriate. Reviewed by: alc, kib Sponsored by: Arm Ltd Differential Revision: https://reviews.freebsd.org/D46394 --- sys/arm64/arm64/efirt_machdep.c | 2 +- sys/arm64/arm64/locore.S | 44 ++++++++++++++++++++++++++++-- sys/arm64/arm64/minidump_machdep.c | 4 +-- sys/arm64/arm64/pmap.c | 24 ++++++++-------- sys/arm64/include/hypervisor.h | 2 ++ sys/arm64/include/pmap.h | 2 ++ sys/arm64/vmm/vmm_arm64.c | 8 ++++++ 7 files changed, 70 insertions(+), 16 deletions(-) diff --git a/sys/arm64/arm64/efirt_machdep.c b/sys/arm64/arm64/efirt_machdep.c index 7c1d12b0b9b4..47e0a209d8b1 100644 --- a/sys/arm64/arm64/efirt_machdep.c +++ b/sys/arm64/arm64/efirt_machdep.c @@ -214,7 +214,7 @@ efi_create_1t1_map(struct efi_md *map, int ndesc, int descsz) p->md_phys, mode, p->md_pages); } - l3_attr = ATTR_AF | ATTR_SH(ATTR_SH_IS) | ATTR_S1_IDX(mode) | + l3_attr = ATTR_AF | pmap_sh_attr | ATTR_S1_IDX(mode) | ATTR_S1_AP(ATTR_S1_AP_RW) | ATTR_S1_nG | L3_PAGE; if (mode == VM_MEMATTR_DEVICE || p->md_attr & EFI_MD_ATTR_XP) l3_attr |= ATTR_S1_XN; diff --git a/sys/arm64/arm64/locore.S b/sys/arm64/arm64/locore.S index e37ea5aa3b48..7c60a2c5bf0a 100644 --- a/sys/arm64/arm64/locore.S +++ b/sys/arm64/arm64/locore.S @@ -86,6 +86,7 @@ ENTRY(_start) * x27 = TTBR0 table * x26 = Kernel L1 table * x24 = TTBR1 table + * x22 = PTE shareability attributes */ /* Enable the mmu */ @@ -135,6 +136,10 @@ virtdone: str x27, [x0, #BP_KERN_TTBR0] str x23, [x0, #BP_BOOT_EL] + /* Set this before it's used in kasan_init_early */ + adrp x1, pmap_sh_attr + str x22, [x1, :lo12:pmap_sh_attr] + #ifdef KASAN /* Save bootparams */ mov x19, x0 @@ -476,6 +481,30 @@ LENTRY(create_pagetables) cmp x6, x27 b.lo 1b + /* + * Find the shareability attribute we should use. If FEAT_LPA2 is + * enabled then the shareability field is moved from the page table + * to tcr_el1 and the bits in the page table are reused by the + * address field. + */ +#if PAGE_SIZE == PAGE_SIZE_4K +#define LPA2_MASK ID_AA64MMFR0_TGran4_MASK +#define LPA2_VAL ID_AA64MMFR0_TGran4_LPA2 +#elif PAGE_SIZE == PAGE_SIZE_16K +#define LPA2_MASK ID_AA64MMFR0_TGran16_MASK +#define LPA2_VAL ID_AA64MMFR0_TGran16_LPA2 +#else +#error Unsupported page size +#endif + mrs x6, id_aa64mmfr0_el1 + mov x7, LPA2_VAL + and x6, x6, LPA2_MASK + cmp x6, x7 + ldr x22, =(ATTR_SH(ATTR_SH_IS)) + csel x22, xzr, x22, eq +#undef LPA2_MASK +#undef LPA2_VAL + /* * Build the TTBR1 maps. */ @@ -747,11 +776,13 @@ LENTRY(build_l2_block_pagetable) /* Build the L2 block entry */ orr x12, x7, #L2_BLOCK - orr x12, x12, #(ATTR_AF | ATTR_SH(ATTR_SH_IS)) + orr x12, x12, #(ATTR_AF) orr x12, x12, #(ATTR_S1_UXN) #ifdef __ARM_FEATURE_BTI_DEFAULT orr x12, x12, #(ATTR_S1_GP) #endif + /* Set the shareability attribute */ + orr x12, x12, x22 /* Only use the output address bits */ lsr x9, x9, #L2_SHIFT @@ -823,11 +854,13 @@ LENTRY(build_l3_page_pagetable) /* Build the L3 page entry */ orr x12, x7, #L3_PAGE - orr x12, x12, #(ATTR_AF | ATTR_SH(ATTR_SH_IS)) + orr x12, x12, #(ATTR_AF) orr x12, x12, #(ATTR_S1_UXN) #ifdef __ARM_FEATURE_BTI_DEFAULT orr x12, x12, #(ATTR_S1_GP) #endif + /* Set the shareability attribute */ + orr x12, x12, x22 /* Only use the output address bits */ lsr x9, x9, #L3_SHIFT @@ -886,6 +919,13 @@ LENTRY(start_mmu) * to 1 only if the ASIDBits field equals 0b0010. */ ldr x2, tcr + + /* If x22 contains a non-zero value then LPA2 is not implemented */ + cbnz x22, .Lno_lpa2 + ldr x3, =(TCR_DS) + orr x2, x2, x3 +.Lno_lpa2: + mrs x3, id_aa64mmfr0_el1 /* Copy the bottom 3 bits from id_aa64mmfr0_el1 into TCR.IPS */ diff --git a/sys/arm64/arm64/minidump_machdep.c b/sys/arm64/arm64/minidump_machdep.c index ac0a2c2dc96e..749c96545506 100644 --- a/sys/arm64/arm64/minidump_machdep.c +++ b/sys/arm64/arm64/minidump_machdep.c @@ -311,7 +311,7 @@ cpu_minidumpsys(struct dumperinfo *di, const struct minidumpstate *state) for (j = 0; j < Ln_ENTRIES; j++) { tmpbuffer[j] = (pa + i * L2_SIZE + j * PAGE_SIZE) | ATTR_AF | - ATTR_SH(ATTR_SH_IS) | L3_PAGE; + pmap_sh_attr | L3_PAGE; } error = blk_write(di, (char *)&tmpbuffer, 0, PAGE_SIZE); @@ -330,7 +330,7 @@ cpu_minidumpsys(struct dumperinfo *di, const struct minidumpstate *state) /* Generate fake l3 entries based upon the l1 entry */ for (i = 0; i < Ln_ENTRIES; i++) { tmpbuffer[i] = (pa + i * PAGE_SIZE) | - ATTR_AF | ATTR_SH(ATTR_SH_IS) | L3_PAGE; + ATTR_AF | pmap_sh_attr | L3_PAGE; } error = blk_write(di, (char *)&tmpbuffer, 0, PAGE_SIZE); if (error) diff --git a/sys/arm64/arm64/pmap.c b/sys/arm64/arm64/pmap.c index 5f09f4cbcf1b..dc02e732568f 100644 --- a/sys/arm64/arm64/pmap.c +++ b/sys/arm64/arm64/pmap.c @@ -185,7 +185,7 @@ #else #define ATTR_KERN_GP 0 #endif -#define PMAP_SAN_PTE_BITS (ATTR_AF | ATTR_SH(ATTR_SH_IS) | ATTR_S1_XN | \ +#define PMAP_SAN_PTE_BITS (ATTR_AF | ATTR_S1_XN | pmap_sh_attr | \ ATTR_KERN_GP | ATTR_S1_IDX(VM_MEMATTR_WRITE_BACK) | ATTR_S1_AP(ATTR_S1_AP_RW)) struct pmap_large_md_page { @@ -355,6 +355,8 @@ static u_int physmap_idx; static SYSCTL_NODE(_vm, OID_AUTO, pmap, CTLFLAG_RD | CTLFLAG_MPSAFE, 0, "VM/pmap parameters"); +pt_entry_t pmap_sh_attr __read_mostly = ATTR_SH(ATTR_SH_IS); + #if PAGE_SIZE == PAGE_SIZE_4K #define L1_BLOCKS_SUPPORTED 1 #else @@ -1150,7 +1152,7 @@ pmap_bootstrap_l2_block(struct pmap_bootstrap_state *state, int i) MPASS((state->pa & L2_OFFSET) == 0); MPASS(state->l2[l2_slot] == 0); pmap_store(&state->l2[l2_slot], PHYS_TO_PTE(state->pa) | - ATTR_AF | ATTR_SH(ATTR_SH_IS) | ATTR_S1_XN | ATTR_KERN_GP | + ATTR_AF | pmap_sh_attr | ATTR_S1_XN | ATTR_KERN_GP | ATTR_S1_IDX(VM_MEMATTR_WRITE_BACK) | contig | L2_BLOCK); } MPASS(state->va == (state->pa - dmap_phys_base + DMAP_MIN_ADDRESS)); @@ -1200,7 +1202,7 @@ pmap_bootstrap_l3_page(struct pmap_bootstrap_state *state, int i) MPASS((state->pa & L3_OFFSET) == 0); MPASS(state->l3[l3_slot] == 0); pmap_store(&state->l3[l3_slot], PHYS_TO_PTE(state->pa) | - ATTR_AF | ATTR_SH(ATTR_SH_IS) | ATTR_S1_XN | ATTR_KERN_GP | + ATTR_AF | pmap_sh_attr | ATTR_S1_XN | ATTR_KERN_GP | ATTR_S1_IDX(VM_MEMATTR_WRITE_BACK) | contig | L3_PAGE); } MPASS(state->va == (state->pa - dmap_phys_base + DMAP_MIN_ADDRESS)); @@ -1243,7 +1245,7 @@ pmap_bootstrap_dmap(void) pmap_store( &bs_state.l1[pmap_l1_index(bs_state.va)], PHYS_TO_PTE(bs_state.pa) | ATTR_AF | - ATTR_SH(ATTR_SH_IS) | + pmap_sh_attr | ATTR_S1_IDX(VM_MEMATTR_WRITE_BACK) | ATTR_S1_XN | ATTR_KERN_GP | L1_BLOCK); } @@ -2112,7 +2114,7 @@ pmap_kenter(vm_offset_t sva, vm_size_t size, vm_paddr_t pa, int mode) KASSERT((size & PAGE_MASK) == 0, ("pmap_kenter: Mapping is not page-sized")); - attr = ATTR_AF | ATTR_SH(ATTR_SH_IS) | ATTR_S1_AP(ATTR_S1_AP_RW) | + attr = ATTR_AF | pmap_sh_attr | ATTR_S1_AP(ATTR_S1_AP_RW) | ATTR_S1_XN | ATTR_KERN_GP | ATTR_S1_IDX(mode); old_l3e = 0; va = sva; @@ -2327,7 +2329,7 @@ pmap_qenter(vm_offset_t sva, vm_page_t *ma, int count) ("pmap_qenter: Invalid level %d", lvl)); m = ma[i]; - attr = ATTR_AF | ATTR_SH(ATTR_SH_IS) | + attr = ATTR_AF | pmap_sh_attr | ATTR_S1_AP(ATTR_S1_AP_RW) | ATTR_S1_XN | ATTR_KERN_GP | ATTR_S1_IDX(m->md.pv_memattr) | L3_PAGE; pte = pmap_l2_to_l3(pde, va); @@ -5124,7 +5126,7 @@ pmap_enter(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot, if ((m->oflags & VPO_UNMANAGED) == 0) VM_PAGE_OBJECT_BUSY_ASSERT(m); pa = VM_PAGE_TO_PHYS(m); - new_l3 = (pt_entry_t)(PHYS_TO_PTE(pa) | ATTR_AF | ATTR_SH(ATTR_SH_IS) | + new_l3 = (pt_entry_t)(PHYS_TO_PTE(pa) | ATTR_AF | pmap_sh_attr | L3_PAGE); new_l3 |= pmap_pte_memattr(pmap, m->md.pv_memattr); new_l3 |= pmap_pte_prot(pmap, prot); @@ -5468,7 +5470,7 @@ pmap_enter_l2_rx(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot, KASSERT(ADDR_IS_CANONICAL(va), ("%s: Address not in canonical form: %lx", __func__, va)); - new_l2 = (pd_entry_t)(VM_PAGE_TO_PTE(m) | ATTR_SH(ATTR_SH_IS) | + new_l2 = (pd_entry_t)(VM_PAGE_TO_PTE(m) | pmap_sh_attr | ATTR_S1_IDX(m->md.pv_memattr) | ATTR_S1_AP(ATTR_S1_AP_RO) | L2_BLOCK); if ((m->oflags & VPO_UNMANAGED) == 0) @@ -5697,7 +5699,7 @@ pmap_enter_l3c_rx(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_page_t *ml3p, KASSERT(ADDR_IS_CANONICAL(va), ("%s: Address not in canonical form: %lx", __func__, va)); - l3e = VM_PAGE_TO_PTE(m) | ATTR_SH(ATTR_SH_IS) | + l3e = VM_PAGE_TO_PTE(m) | pmap_sh_attr | ATTR_S1_IDX(m->md.pv_memattr) | ATTR_S1_AP(ATTR_S1_AP_RO) | ATTR_CONTIGUOUS | L3_PAGE; if ((m->oflags & VPO_UNMANAGED) == 0) @@ -6094,7 +6096,7 @@ pmap_enter_quick_locked(pmap_t pmap, vm_offset_t va, vm_page_t m, pmap_resident_count_inc(pmap, 1); pa = VM_PAGE_TO_PHYS(m); - l3_val = PHYS_TO_PTE(pa) | ATTR_SH(ATTR_SH_IS) | + l3_val = PHYS_TO_PTE(pa) | pmap_sh_attr | ATTR_S1_IDX(m->md.pv_memattr) | ATTR_S1_AP(ATTR_S1_AP_RO) | L3_PAGE; l3_val |= pmap_pte_bti(pmap, va); if ((prot & VM_PROT_EXECUTE) == 0 || @@ -7744,7 +7746,7 @@ pmap_mapbios(vm_paddr_t pa, vm_size_t size) /* Insert L2_BLOCK */ l2 = pmap_l1_to_l2(pde, va); old_l2e |= pmap_load_store(l2, - PHYS_TO_PTE(pa) | ATTR_AF | ATTR_SH(ATTR_SH_IS) | + PHYS_TO_PTE(pa) | ATTR_AF | pmap_sh_attr | ATTR_S1_XN | ATTR_KERN_GP | ATTR_S1_IDX(VM_MEMATTR_WRITE_BACK) | L2_BLOCK); diff --git a/sys/arm64/include/hypervisor.h b/sys/arm64/include/hypervisor.h index 4c501e2722a9..1a27a8dd919b 100644 --- a/sys/arm64/include/hypervisor.h +++ b/sys/arm64/include/hypervisor.h @@ -241,6 +241,8 @@ #define VTCR_EL2_PS_42BIT (0x3UL << VTCR_EL2_PS_SHIFT) #define VTCR_EL2_PS_44BIT (0x4UL << VTCR_EL2_PS_SHIFT) #define VTCR_EL2_PS_48BIT (0x5UL << VTCR_EL2_PS_SHIFT) +#define VTCR_EL2_DS_SHIFT 32 +#define VTCR_EL2_DS (0x1UL << VTCR_EL2_DS_SHIFT) /* VTTBR_EL2 - Virtualization Translation Table Base Register */ #define VTTBR_VMID_MASK 0xffff000000000000 diff --git a/sys/arm64/include/pmap.h b/sys/arm64/include/pmap.h index d604f705e596..c9552ebc326a 100644 --- a/sys/arm64/include/pmap.h +++ b/sys/arm64/include/pmap.h @@ -127,6 +127,8 @@ extern struct pmap kernel_pmap_store; extern vm_offset_t virtual_avail; extern vm_offset_t virtual_end; +extern pt_entry_t pmap_sh_attr; + /* * Macros to test if a mapping is mappable with an L1 Section mapping * or an L2 Large Page mapping. diff --git a/sys/arm64/vmm/vmm_arm64.c b/sys/arm64/vmm/vmm_arm64.c index 164ff65cfe2c..80d985241c69 100644 --- a/sys/arm64/vmm/vmm_arm64.c +++ b/sys/arm64/vmm/vmm_arm64.c @@ -396,6 +396,14 @@ vmmops_modinit(int ipinum) #ifdef SMP el2_regs.vtcr_el2 |= VTCR_EL2_SH0_IS; #endif + /* + * If FEAT_LPA2 is enabled in the host then we need to enable it here + * so the page tables created by pmap.c are correct. The meaning of + * the shareability field changes to become address bits when this + * is set. + */ + if ((READ_SPECIALREG(tcr_el1) & TCR_DS) != 0) + el2_regs.vtcr_el2 |= VTCR_EL2_DS; smp_rendezvous(NULL, arm_setup_vectors, NULL, &el2_regs); From f5c7feee7129dc88a2e5dc3ce0a075cb5e4f534a Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Wed, 28 Aug 2024 14:21:33 +0000 Subject: [PATCH 157/213] LinuxKPI: add general module_driver(), use it for module_pci_driver() Factor out module_pci_driver() from 366d68f283793 into a general module_driver() so other bus attachments can also use the same kind of macro without duplicating all the lines. Redefine module_pci_driver() using the new general macro. No functional changes intended. Sponsored by: The FreeBSD Foundation MFC after: 3 days Reviewed by: manu Differential Revision: https://reviews.freebsd.org/D46467 --- .../common/include/linux/device/driver.h | 33 +++++++++++++++++++ .../linuxkpi/common/include/linux/pci.h | 21 ++---------- 2 files changed, 36 insertions(+), 18 deletions(-) create mode 100644 sys/compat/linuxkpi/common/include/linux/device/driver.h diff --git a/sys/compat/linuxkpi/common/include/linux/device/driver.h b/sys/compat/linuxkpi/common/include/linux/device/driver.h new file mode 100644 index 000000000000..03b510c9c8b7 --- /dev/null +++ b/sys/compat/linuxkpi/common/include/linux/device/driver.h @@ -0,0 +1,33 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2021 Bjoern A. Zeeb + * Copyright (c) 2024 The FreeBSD Foundation + * + * Portions of this software were developed by Björn Zeeb + * under sponsorship from the FreeBSD Foundation. + */ + +#ifndef LINUXKPI_LINUX_DEVICE_DRIVER_H +#define LINUXKPI_LINUX_DEVICE_DRIVER_H + +#include +#include + +#define module_driver(_drv, _regf, _unregf) \ +static inline int \ +__CONCAT(__CONCAT(_, _drv), _init)(void) \ +{ \ + return (_regf(&(_drv))); \ +} \ + \ +static inline void \ +__CONCAT(__CONCAT(_, _drv), _exit)(void) \ +{ \ + _unregf(&(_drv)); \ +} \ + \ +module_init(__CONCAT(__CONCAT(_, _drv), _init)); \ +module_exit(__CONCAT(__CONCAT(_, _drv), _exit)) + +#endif /* LINUXKPI_LINUX_DEVICE_DRIVER_H */ diff --git a/sys/compat/linuxkpi/common/include/linux/pci.h b/sys/compat/linuxkpi/common/include/linux/pci.h index 9457599d31d3..36b970154ad2 100644 --- a/sys/compat/linuxkpi/common/include/linux/pci.h +++ b/sys/compat/linuxkpi/common/include/linux/pci.h @@ -36,6 +36,7 @@ #define CONFIG_PCI_MSI #include +#include #include #include @@ -274,24 +275,8 @@ extern spinlock_t pci_lock; #define __devexit_p(x) x -#define module_pci_driver(_driver) \ - \ -static inline int \ -_pci_init(void) \ -{ \ - \ - return (linux_pci_register_driver(&_driver)); \ -} \ - \ -static inline void \ -_pci_exit(void) \ -{ \ - \ - linux_pci_unregister_driver(&_driver); \ -} \ - \ -module_init(_pci_init); \ -module_exit(_pci_exit) +#define module_pci_driver(_drv) \ + module_driver(_drv, linux_pci_register_driver, linux_pci_unregister_driver) struct msi_msg { uint32_t data; From d8fffc3704a0d7f4ea5b866f689e58480ddebaa1 Mon Sep 17 00:00:00 2001 From: Tom Jones Date: Wed, 4 Sep 2024 16:32:56 +0100 Subject: [PATCH 158/213] imx_gpio: Add gpio compat string for imx8 SOCs Several imx8* device trees have a compatible gpio controller which identifies as working with the soc and imx35-gpio. Add a compat string for the commonly included 'imx35-gpio', rather than adding each to the table. From a grep of our dts mirror this includes the following arm64 SOCs: - imx8dxl - imx8mm - imx8mn - imx8mp - imx8mq - imx8qm - imx8qxp Reviewed by: manu Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D46532 --- sys/arm/freescale/imx/imx_gpio.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sys/arm/freescale/imx/imx_gpio.c b/sys/arm/freescale/imx/imx_gpio.c index c5e92992a36b..7610d28af90e 100644 --- a/sys/arm/freescale/imx/imx_gpio.c +++ b/sys/arm/freescale/imx/imx_gpio.c @@ -134,6 +134,7 @@ static struct ofw_compat_data compat_data[] = { {"fsl,imx6q-gpio", 1}, {"fsl,imx53-gpio", 1}, {"fsl,imx51-gpio", 1}, + {"fsl,imx35-gpio", 1}, {NULL, 0} }; From fe1755fa6bb4039c1e00f5226c473a024685005b Mon Sep 17 00:00:00 2001 From: Alan Somers Date: Fri, 23 Aug 2024 14:51:32 -0600 Subject: [PATCH 159/213] ctl: add tests for START STOP UNIT MFC after: 2 weeks Sponsored by: Axcient Reviewed by: emaste, markj Pull Request: https://github.com/freebsd/freebsd-src/pull/1409 --- tests/sys/cam/ctl/Makefile | 5 +- tests/sys/cam/ctl/ctl.subr | 94 +++++++++++++++++ tests/sys/cam/ctl/read_buffer.sh | 72 ++----------- tests/sys/cam/ctl/start_stop_unit.sh | 150 +++++++++++++++++++++++++++ 4 files changed, 257 insertions(+), 64 deletions(-) create mode 100644 tests/sys/cam/ctl/ctl.subr create mode 100644 tests/sys/cam/ctl/start_stop_unit.sh diff --git a/tests/sys/cam/ctl/Makefile b/tests/sys/cam/ctl/Makefile index 0e6f39a1a56f..1b857bb0c291 100644 --- a/tests/sys/cam/ctl/Makefile +++ b/tests/sys/cam/ctl/Makefile @@ -2,9 +2,12 @@ PACKAGE= tests TESTSDIR= ${TESTSBASE}/sys/cam/ctl +${PACKAGE}FILES+= ctl.subr + ATF_TESTS_SH+= read_buffer +ATF_TESTS_SH+= start_stop_unit # Must be exclusive because it disables/enables camsim -TEST_METADATA.read_buffer+= is_exclusive="true" +TEST_METADATA+= is_exclusive="true" .include diff --git a/tests/sys/cam/ctl/ctl.subr b/tests/sys/cam/ctl/ctl.subr new file mode 100644 index 000000000000..18991e0fa144 --- /dev/null +++ b/tests/sys/cam/ctl/ctl.subr @@ -0,0 +1,94 @@ +# vim: filetype=sh + +# SPDX-License-Identifier: BSD-2-Clause +# +# Copyright (c) 2024 Axcient +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS DOCUMENTATION IS PROVIDED BY THE AUTHOR ``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 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. + +load_modules() { + if ! kldstat -q -m ctl; then + kldload ctl || atf_skip "could not load ctl kernel mod" + fi + if ! ctladm port -o on -p 0; then + atf_skip "could not enable the camsim frontend" + fi +} + +find_device() { + LUN=$1 + + # Rescan camsim + # XXX camsim doesn't update when creating a new device. Worse, a + # rescan won't look for new devices. So we must disable/re-enable it. + # Worse still, enabling it isn't synchronous, so we need a retry loop + # https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=281000 + retries=5 + ctladm port -o off -p 0 >/dev/null + ctladm port -o on -p 0 >/dev/null + HEXLUN=`printf %x $LUN` + while true; do + dev=`camcontrol devlist | awk -v lun=$HEXLUN '/FREEBSD CTL/ && $9==lun {split($10, fields, /[,]/); print fields[1];}' | sed 's:[()]::'` + if [ -z "$dev" -o ! -c /dev/$dev ]; then + retries=$(( $retries - 1 )) + if [ $retries -eq 0 ]; then + cat lun-create.txt + camcontrol devlist + atf_fail "Could not find GEOM device" + fi + sleep 0.1 + continue + fi + break + done + # Ensure that it's actually ready. camcontrol may report the disk's + # ident before it's actually ready to receive commands. Maybe that's + # because all of the GEOM providers must probe it? + while true; do + dd if=/dev/$dev bs=4096 count=1 of=/dev/null >/dev/null 2>/dev/null && break + retries=$(( $retries - 1 )) + if [ $retries -eq 0 ]; then + atf_fail "Device never became ready" + fi + sleep 0.1 + done +} + +# Create a CTL LUN +create_ramdisk() { + EXTRA_ARGS=$* + + atf_check -o save:lun-create.txt ctladm create -b ramdisk -s 1048576 $EXTRA_ARGS + atf_check egrep -q "LUN created successfully" lun-create.txt + LUN=`awk '/LUN ID:/ {print $NF}' lun-create.txt` + if [ -z "$LUN" ]; then + atf_fail "Could not find LUN id" + fi + find_device $LUN +} + +cleanup() { + if [ -e "lun-create.txt" ]; then + lun_id=`awk '/LUN ID:/ {print $NF}' lun-create.txt` + ctladm remove -b ramdisk -l $lun_id > /dev/null + fi +} diff --git a/tests/sys/cam/ctl/read_buffer.sh b/tests/sys/cam/ctl/read_buffer.sh index 4a84eb6b9725..e54b0dadc134 100644 --- a/tests/sys/cam/ctl/read_buffer.sh +++ b/tests/sys/cam/ctl/read_buffer.sh @@ -28,61 +28,7 @@ # * Buffer ID other than 0. We don't support those. # * The Mode Specific field. We don't support it. -load_modules() { - if ! kldstat -q -m ctl; then - kldload ctl || atf_skip "could not load ctl kernel mod" - fi - if ! ctladm port -o on -p 0; then - atf_skip "could not enable the camsim frontend" - fi -} - -find_da_device() { - SERIAL=$1 - - # Rescan camsim - # XXX camsim doesn't update when creating a new device. Worse, a - # rescan won't look for new devices. So we must disable/re-enable it. - # Worse still, enabling it isn't synchronous, so we need a retry loop - # https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=281000 - retries=5 - ctladm port -o off -p 0 >/dev/null - ctladm port -o on -p 0 >/dev/null - while true; do - - # Find the corresponding da device - da=`geom disk list | awk -v serial=$SERIAL ' /Geom name:/ { devname=$NF } /ident:/ && $NF ~ serial { print devname; exit } '` - if [ -z "$da" ]; then - retries=$(( $retries - 1 )) - if [ $retries -eq 0 ]; then - cat lun-create.txt - geom disk list - atf_fail "Could not find da device" - fi - sleep 0.1 - continue - fi - break - done -} - -# Create a CTL LUN -create_ramdisk() { - atf_check -o save:lun-create.txt ctladm create -b ramdisk -s 1048576 - atf_check egrep -q "LUN created successfully" lun-create.txt - SERIAL=`awk '/Serial Number:/ {print $NF}' lun-create.txt` - if [ -z "$SERIAL" ]; then - atf_fail "Could not find serial number" - fi - find_da_device $SERIAL -} - -cleanup() { - if [ -e "lun-create.txt" ]; then - lun_id=`awk '/LUN ID:/ {print $NF}' lun-create.txt` - ctladm remove -b ramdisk -l $lun_id > /dev/null - fi -} +. $(atf_get_srcdir)/ctl.subr atf_test_case basic cleanup basic_head() @@ -98,10 +44,10 @@ basic_body() # Write to its buffer cp /etc/passwd input len=`wc -c input | cut -wf 2` - atf_check -o ignore sg_write_buffer --mode data --in=input /dev/$da + atf_check -o ignore sg_write_buffer --mode data --in=input /dev/$dev # Read it back - atf_check -o save:output sg_read_buffer --mode data -l $len --raw /dev/$da + atf_check -o save:output sg_read_buffer --mode data -l $len --raw /dev/$dev # And verify if ! diff -q input output; then @@ -126,7 +72,7 @@ desc_body() { create_ramdisk - atf_check -o inline:" 00 00 04 00 00\n" sg_read_buffer --hex --mode desc /dev/$da + atf_check -o inline:" 00 00 04 00 00\n" sg_read_buffer --hex --mode desc /dev/$dev } desc_cleanup() { @@ -147,10 +93,10 @@ length_body() # Write to its buffer atf_check -o ignore -e ignore dd if=/dev/random of=input bs=4096 count=1 atf_check -o ignore -e ignore dd if=input bs=2048 count=1 of=expected - atf_check -o ignore sg_write_buffer --mode data --in=input /dev/$da + atf_check -o ignore sg_write_buffer --mode data --in=input /dev/$dev # Read it back - atf_check -o save:output sg_read_buffer --mode data -l 2048 --raw /dev/$da + atf_check -o save:output sg_read_buffer --mode data -l 2048 --raw /dev/$dev # And verify if ! diff -q expected output; then @@ -176,10 +122,10 @@ offset_body() # Write to its buffer atf_check -o ignore -e ignore dd if=/dev/random of=input bs=4096 count=1 atf_check -o ignore -e ignore dd if=input iseek=2 bs=512 count=1 of=expected - atf_check -o ignore sg_write_buffer --mode data --in=input /dev/$da + atf_check -o ignore sg_write_buffer --mode data --in=input /dev/$dev # Read it back - atf_check -o save:output sg_read_buffer --mode data -l 512 -o 1024 --raw /dev/$da + atf_check -o save:output sg_read_buffer --mode data -l 512 -o 1024 --raw /dev/$dev # And verify if ! diff -q expected output; then @@ -203,7 +149,7 @@ uninitialized_body() create_ramdisk # Read an uninitialized buffer - atf_check -o save:output sg_read_buffer --mode data -l 262144 --raw /dev/$da + atf_check -o save:output sg_read_buffer --mode data -l 262144 --raw /dev/$dev # And verify atf_check -o ignore -e ignore dd if=/dev/zero bs=262144 count=1 of=expected diff --git a/tests/sys/cam/ctl/start_stop_unit.sh b/tests/sys/cam/ctl/start_stop_unit.sh new file mode 100644 index 000000000000..163011c8f574 --- /dev/null +++ b/tests/sys/cam/ctl/start_stop_unit.sh @@ -0,0 +1,150 @@ +# SPDX-License-Identifier: BSD-2-Clause +# +# Copyright (c) 2024 Axcient +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS DOCUMENTATION IS PROVIDED BY THE AUTHOR ``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 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. + +. $(atf_get_srcdir)/ctl.subr + +# TODO: +# * format layer +# * IMM bit +# * LOEJ +# * noflush +# * power conditions + +# Not Tested +# * Power Condition Modifier (not implemented in CTL) + +atf_test_case eject cleanup +eject_head() +{ + atf_set "descr" "START STOP UNIT can eject a CDROM device" + atf_set "require.user" "root" + atf_set "require.progs" sg_start sg_readcap +} +eject_body() +{ + # -t 5 for CD/DVD device type + create_ramdisk -t 5 + + # Verify that the device is online + # Too bad I don't know of any other way to check that it's stopped but + # by using sg_readcap. + atf_check -o ignore -e not-match:"Device not ready" sg_readcap /dev/$dev + + # eject the device + atf_check sg_start --eject /dev/$dev + + # Ejected, it should now return ENXIO + atf_check -s exit:1 -o ignore -e match:"Device not configured" dd if=/dev/$dev bs=4096 count=1 of=/dev/null +} +eject_cleanup() +{ + cleanup +} + +atf_test_case load cleanup +load_head() +{ + atf_set "descr" "START STOP UNIT can load a CDROM device" + atf_set "require.user" "root" + atf_set "require.progs" sg_start sg_readcap +} +load_body() +{ + # -t 5 for CD/DVD device type + create_ramdisk -t 5 + + # eject the device + atf_check sg_start --eject /dev/$dev + + # Verify that it's offline it should now return ENXIO + atf_check -s exit:1 -o ignore -e match:"Device not configured" dd if=/dev/$dev bs=4096 count=1 of=/dev/null + + # Load it again + atf_check sg_start --load /dev/$dev + + atf_check -o ignore -e ignore dd if=/dev/$dev bs=4096 count=1 of=/dev/null + atf_check -o ignore -e not-match:"Device not ready" sg_readcap /dev/$dev +} +load_cleanup() +{ + cleanup +} + +atf_test_case start cleanup +start_head() +{ + atf_set "descr" "START STOP UNIT can start a device" + atf_set "require.user" "root" + atf_set "require.progs" sg_start sg_readcap +} +start_body() +{ + create_ramdisk + + # stop the device + atf_check sg_start --stop /dev/$dev + + # And start it again + atf_check sg_start /dev/$dev + + # Now sg_readcap should succeed. Too bad I don't know of any other way + # to check that it's stopped. + atf_check -o ignore -e not-match:"Device not ready" sg_readcap /dev/$dev +} +start_cleanup() +{ + cleanup +} + +atf_test_case stop cleanup +stop_head() +{ + atf_set "descr" "START STOP UNIT can stop a device" + atf_set "require.user" "root" + atf_set "require.progs" sg_start sg_readcap +} +stop_body() +{ + create_ramdisk + + # Stop the device + atf_check sg_start --stop /dev/$dev + + # Now sg_readcap should fail. Too bad I don't know of any other way to + # check that it's stopped. + atf_check -s exit:2 -e match:"Device not ready" sg_readcap /dev/$dev +} +stop_cleanup() +{ + cleanup +} + +atf_init_test_cases() +{ + atf_add_test_case eject + atf_add_test_case load + atf_add_test_case start + atf_add_test_case stop +} From e234a72bb8c0e8e25ea8a879582e85bb2e09f096 Mon Sep 17 00:00:00 2001 From: Alan Somers Date: Mon, 26 Aug 2024 14:01:44 -0600 Subject: [PATCH 160/213] ctl: add tests for PREVENT ALLOW MEDIUM REMOVAL MFC after: 2 weeks Sponsored by: Axcient Reviewed by: emaste, markj Pull Request: https://github.com/freebsd/freebsd-src/pull/1409 --- tests/sys/cam/ctl/Makefile | 1 + tests/sys/cam/ctl/prevent.sh | 161 +++++++++++++++++++++++++++++++++++ 2 files changed, 162 insertions(+) create mode 100644 tests/sys/cam/ctl/prevent.sh diff --git a/tests/sys/cam/ctl/Makefile b/tests/sys/cam/ctl/Makefile index 1b857bb0c291..1333397af464 100644 --- a/tests/sys/cam/ctl/Makefile +++ b/tests/sys/cam/ctl/Makefile @@ -4,6 +4,7 @@ TESTSDIR= ${TESTSBASE}/sys/cam/ctl ${PACKAGE}FILES+= ctl.subr +ATF_TESTS_SH+= prevent ATF_TESTS_SH+= read_buffer ATF_TESTS_SH+= start_stop_unit diff --git a/tests/sys/cam/ctl/prevent.sh b/tests/sys/cam/ctl/prevent.sh new file mode 100644 index 000000000000..a5a187dad8ff --- /dev/null +++ b/tests/sys/cam/ctl/prevent.sh @@ -0,0 +1,161 @@ +# SPDX-License-Identifier: BSD-2-Clause +# +# Copyright (c) 2024 Axcient +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS DOCUMENTATION IS PROVIDED BY THE AUTHOR ``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 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. + +. $(atf_get_srcdir)/ctl.subr + +# TODO +# * multiple initiators may block removal + +# Not Tested +# * persistent removal (not implemented in CTL) + +atf_test_case allow cleanup +allow_head() +{ + atf_set "descr" "SCSI PREVENT ALLOW MEDIUM REMOVAL will prevent a CD from being ejected" + atf_set "require.user" "root" + atf_set "require.progs" sg_prevent sg_start +} +allow_body() +{ + # -t 5 for CD/DVD device type + create_ramdisk -t 5 + + atf_check sg_prevent --prevent 1 /dev/$dev + + # Now sg_start --eject should fail + atf_check -s exit:5 -e match:"Illegal request" sg_start --eject /dev/$dev + + atf_check sg_prevent --allow /dev/$dev + + # Now sg_start --eject should work again + atf_check -s exit:0 sg_start --eject /dev/$dev +} +allow_cleanup() +{ + cleanup +} + +atf_test_case allow_idempotent cleanup +allow_idempotent_head() +{ + atf_set "descr" "SCSI PREVENT ALLOW MEDIUM REMOVAL is idempotent when run from the same initiator" + atf_set "require.user" "root" + atf_set "require.progs" sg_prevent sg_start +} +allow_idempotent_body() +{ + # -t 5 for CD/DVD device type + create_ramdisk -t 5 + + atf_check sg_prevent --allow /dev/$dev + atf_check sg_prevent --allow /dev/$dev + atf_check sg_prevent --prevent 1 /dev/$dev + + # Even though we ran --allow twice, a single --prevent command should + # suffice to prevent ejecting. Multiple ALLOW/PREVENT commands from + # the same initiator don't have any additional effect. + atf_check -s exit:5 -e match:"Illegal request" sg_start --eject /dev/$dev +} +allow_idempotent_cleanup() +{ + cleanup +} + +atf_test_case nonremovable cleanup +nonremovable_head() +{ + atf_set "descr" "SCSI PREVENT ALLOW MEDIUM REMOVAL may not be used on non-removable media" + atf_set "require.user" "root" + atf_set "require.progs" sg_prevent +} +nonremovable_body() +{ + # Create a HDD, not a CD, device + create_ramdisk -t 0 + + atf_check -s exit:9 -e match:"Invalid opcode" sg_prevent /dev/$dev +} +nonremovable_cleanup() +{ + cleanup +} + +atf_test_case prevent cleanup +prevent_head() +{ + atf_set "descr" "SCSI PREVENT ALLOW MEDIUM REMOVAL will prevent a CD from being ejected" + atf_set "require.user" "root" + atf_set "require.progs" sg_prevent sg_start +} +prevent_body() +{ + # -t 5 for CD/DVD device type + create_ramdisk -t 5 + + atf_check sg_prevent --prevent 1 /dev/$dev + + # Now sg_start --eject should fail + atf_check -s exit:5 -e match:"Illegal request" sg_start --eject /dev/$dev +} +prevent_cleanup() +{ + cleanup +} + +atf_test_case prevent_idempotent cleanup +prevent_idempotent_head() +{ + atf_set "descr" "SCSI PREVENT ALLOW MEDIUM REMOVAL is idempotent when run from the same initiator" + atf_set "require.user" "root" + atf_set "require.progs" sg_prevent sg_start +} +prevent_idempotent_body() +{ + # -t 5 for CD/DVD device type + create_ramdisk -t 5 + + atf_check sg_prevent --prevent 1 /dev/$dev + atf_check sg_prevent --prevent 1 /dev/$dev + atf_check sg_prevent --allow /dev/$dev + + # Even though we ran prevent idempotent and allow only once, eject + # should be allowed. Multiple PREVENT commands from the same initiator + # don't have any additional effect. + atf_check sg_start --eject /dev/$dev +} +prevent_idempotent_cleanup() +{ + cleanup +} + +atf_init_test_cases() +{ + atf_add_test_case allow + atf_add_test_case allow_idempotent + atf_add_test_case nonremovable + atf_add_test_case prevent + atf_add_test_case prevent_idempotent +} From 0f2b2276abc305905e7d88619a7abca26b0dd7eb Mon Sep 17 00:00:00 2001 From: Alan Somers Date: Mon, 26 Aug 2024 14:44:24 -0600 Subject: [PATCH 161/213] ctl: fix uninitialized data used by PREVENT ALLOW MEDIUM REMOVAL Zero-initialize the bitmap of preventers. Otherwise, the START STOP UNIT command may not have the intended effect. MFC after: 2 weeks Sponsored by: Axcient Reviewed by: emaste, markj Pull Request: https://github.com/freebsd/freebsd-src/pull/1409 --- sys/cam/ctl/ctl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/cam/ctl/ctl.c b/sys/cam/ctl/ctl.c index 53858edc2a1d..1505e0886f57 100644 --- a/sys/cam/ctl/ctl.c +++ b/sys/cam/ctl/ctl.c @@ -4630,7 +4630,7 @@ ctl_add_lun(struct ctl_be_lun *be_lun) ctl_tpc_lun_init(lun); if (lun->flags & CTL_LUN_REMOVABLE) { lun->prevent = malloc((CTL_MAX_INITIATORS + 31) / 32 * 4, - M_CTL, M_WAITOK); + M_CTL, M_WAITOK | M_ZERO); } /* From 5203dcce2527fd235648e2b855a13f62247eb2de Mon Sep 17 00:00:00 2001 From: Michael Tuexen Date: Thu, 5 Sep 2024 17:31:31 +0200 Subject: [PATCH 162/213] neta: improve TCP LRO Use the appropriate function to flush correctly all entries. The old code does not remove the element from the hash table, only from the active queue. Reviewed by: Peter Lei, rscheff MFC after: 1 week Sponsored by: Netflix, Inc. Differential Revision: https://reviews.freebsd.org/D46433 --- sys/dev/neta/if_mvneta.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/sys/dev/neta/if_mvneta.c b/sys/dev/neta/if_mvneta.c index e663306509a0..bc57b10b6d8e 100644 --- a/sys/dev/neta/if_mvneta.c +++ b/sys/dev/neta/if_mvneta.c @@ -3000,8 +3000,6 @@ mvneta_rx_queue(struct mvneta_softc *sc, int q, int npkt) struct mvneta_rx_desc *r; struct mvneta_buf *rxbuf; struct mbuf *m; - struct lro_ctrl *lro; - struct lro_entry *queued; void *pktbuf; int i, pktlen, processed, ndma; @@ -3115,11 +3113,7 @@ mvneta_rx_queue(struct mvneta_softc *sc, int q, int npkt) /* * Flush any outstanding LRO work */ - lro = &rx->lro; - while (__predict_false((queued = LIST_FIRST(&lro->lro_active)) != NULL)) { - LIST_REMOVE(LIST_FIRST((&lro->lro_active)), next); - tcp_lro_flush(lro, queued); - } + tcp_lro_flush_all(&rx->lro); } STATIC void From 0b45d36510d8c629fcc49805bc64e5893f4ba63c Mon Sep 17 00:00:00 2001 From: Michael Tuexen Date: Thu, 5 Sep 2024 17:35:40 +0200 Subject: [PATCH 163/213] al_eth: improve TCP LRO Use the appropriate function to flush correctly all entries. The old code does not remove the element from the hash table, only from the active queue. Reviewed by: Peter Lei, rscheff MFC after: 1 week Sponsored by: Netflix, Inc. Differential Revision: https://reviews.freebsd.org/D46434 --- sys/dev/al_eth/al_eth.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/sys/dev/al_eth/al_eth.c b/sys/dev/al_eth/al_eth.c index e12c8dfcc281..f4fec7c6aa94 100644 --- a/sys/dev/al_eth/al_eth.c +++ b/sys/dev/al_eth/al_eth.c @@ -1580,7 +1580,6 @@ al_eth_rx_recv_work(void *arg, int pending) { struct al_eth_ring *rx_ring = arg; struct mbuf *mbuf; - struct lro_entry *queued; unsigned int qid = rx_ring->ring_id; struct al_eth_pkt *hal_pkt = &rx_ring->hal_pkt; uint16_t next_to_clean = rx_ring->next_to_clean; @@ -1671,10 +1670,7 @@ al_eth_rx_recv_work(void *arg, int pending) "%s: not filling rx queue %d\n", __func__, qid); } - while (((queued = LIST_FIRST(&rx_ring->lro.lro_active)) != NULL)) { - LIST_REMOVE(queued, next); - tcp_lro_flush(&rx_ring->lro, queued); - } + tcp_lro_flush_all(&rx_ring->lro); if (napi != 0) { rx_ring->enqueue_is_running = 0; From e06cf0fc5dd626c34acdef308b696b4995371a4b Mon Sep 17 00:00:00 2001 From: Michael Tuexen Date: Thu, 5 Sep 2024 17:44:33 +0200 Subject: [PATCH 164/213] tcp: make tcp_lro_flush() static tcp_lro_flush() is not used anymore outside of tcp_lro.c. Therefore make it static. Reviewed by: rscheff, glebius, Peter Lei Sponsored by: Netflix, Inc. Differential Revision: https://reviews.freebsd.org/D46435 --- sys/netinet/tcp_lro.c | 3 ++- sys/netinet/tcp_lro.h | 1 - 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/netinet/tcp_lro.c b/sys/netinet/tcp_lro.c index 906e01257a04..10afed17bf3b 100644 --- a/sys/netinet/tcp_lro.c +++ b/sys/netinet/tcp_lro.c @@ -83,6 +83,7 @@ static MALLOC_DEFINE(M_LRO, "LRO", "LRO control structures"); static void tcp_lro_rx_done(struct lro_ctrl *lc); static int tcp_lro_rx_common(struct lro_ctrl *lc, struct mbuf *m, uint32_t csum, bool use_hash); +static void tcp_lro_flush(struct lro_ctrl *lc, struct lro_entry *le); SYSCTL_NODE(_net_inet_tcp, OID_AUTO, lro, CTLFLAG_RW | CTLFLAG_MPSAFE, 0, "TCP LRO"); @@ -1104,7 +1105,7 @@ tcp_lro_condense(struct lro_ctrl *lc, struct lro_entry *le) } } -void +static void tcp_lro_flush(struct lro_ctrl *lc, struct lro_entry *le) { diff --git a/sys/netinet/tcp_lro.h b/sys/netinet/tcp_lro.h index b4b5e3f811e4..a94eca665eb5 100644 --- a/sys/netinet/tcp_lro.h +++ b/sys/netinet/tcp_lro.h @@ -216,7 +216,6 @@ int tcp_lro_init(struct lro_ctrl *); int tcp_lro_init_args(struct lro_ctrl *, struct ifnet *, unsigned, unsigned); void tcp_lro_free(struct lro_ctrl *); void tcp_lro_flush_inactive(struct lro_ctrl *, const struct timeval *); -void tcp_lro_flush(struct lro_ctrl *, struct lro_entry *); void tcp_lro_flush_all(struct lro_ctrl *); extern int (*tcp_lro_flush_tcphpts)(struct lro_ctrl *, struct lro_entry *); int tcp_lro_rx(struct lro_ctrl *, struct mbuf *, uint32_t); From 1726db7af6b3738eb04d962b351d7f4017e1fc77 Mon Sep 17 00:00:00 2001 From: Mark Johnston Date: Thu, 5 Sep 2024 15:16:29 +0000 Subject: [PATCH 165/213] flua: Add wrappers for sys/utsname.h This allows one to invoke uname from lua scripts. Reviewed by: bapt, kevans, emaste MFC after: 1 month Differential Revision: https://reviews.freebsd.org/D42017 --- libexec/flua/linit_flua.c | 1 + libexec/flua/modules/lposix.c | 47 ++++++++++++++++++++++++++++++++++- libexec/flua/modules/lposix.h | 1 + 3 files changed, 48 insertions(+), 1 deletion(-) diff --git a/libexec/flua/linit_flua.c b/libexec/flua/linit_flua.c index 4d4d69920e94..1b7d83016cfe 100644 --- a/libexec/flua/linit_flua.c +++ b/libexec/flua/linit_flua.c @@ -59,6 +59,7 @@ static const luaL_Reg loadedlibs[] = { /* FreeBSD Extensions */ {"lfs", luaopen_lfs}, {"posix.sys.stat", luaopen_posix_sys_stat}, + {"posix.sys.utsname", luaopen_posix_sys_utsname}, {"posix.unistd", luaopen_posix_unistd}, {"ucl", luaopen_ucl}, {"fbsd", luaopen_fbsd}, diff --git a/libexec/flua/modules/lposix.c b/libexec/flua/modules/lposix.c index 5b6e80a0309f..fa3fd5f8e589 100644 --- a/libexec/flua/modules/lposix.c +++ b/libexec/flua/modules/lposix.c @@ -24,8 +24,8 @@ * */ -#include #include +#include #include #include @@ -130,12 +130,50 @@ lua_getpid(lua_State *L) return 1; } +static int +lua_uname(lua_State *L) +{ + struct utsname name; + int error, n; + + n = lua_gettop(L); + luaL_argcheck(L, n == 0, 1, "too many arguments"); + + error = uname(&name); + if (error != 0) { + error = errno; + lua_pushnil(L); + lua_pushstring(L, strerror(error)); + lua_pushinteger(L, error); + return (3); + } + + lua_newtable(L); +#define setkv(f) do { \ + lua_pushstring(L, name.f); \ + lua_setfield(L, -2, #f); \ +} while (0) + setkv(sysname); + setkv(nodename); + setkv(release); + setkv(version); + setkv(machine); +#undef setkv + + return (1); +} + #define REG_SIMPLE(n) { #n, lua_ ## n } static const struct luaL_Reg sys_statlib[] = { REG_SIMPLE(chmod), { NULL, NULL }, }; +static const struct luaL_Reg sys_utsnamelib[] = { + REG_SIMPLE(uname), + { NULL, NULL }, +}; + static const struct luaL_Reg unistdlib[] = { REG_SIMPLE(getpid), REG_SIMPLE(chown), @@ -150,6 +188,13 @@ luaopen_posix_sys_stat(lua_State *L) return 1; } +int +luaopen_posix_sys_utsname(lua_State *L) +{ + luaL_newlib(L, sys_utsnamelib); + return 1; +} + int luaopen_posix_unistd(lua_State *L) { diff --git a/libexec/flua/modules/lposix.h b/libexec/flua/modules/lposix.h index 6085bf045d79..e37caaae9d04 100644 --- a/libexec/flua/modules/lposix.h +++ b/libexec/flua/modules/lposix.h @@ -8,4 +8,5 @@ #include int luaopen_posix_sys_stat(lua_State *L); +int luaopen_posix_sys_utsname(lua_State *L); int luaopen_posix_unistd(lua_State *L); From 6aede562b438ad9be7197f04307d8bc58d43e6ee Mon Sep 17 00:00:00 2001 From: Doug Moore Date: Thu, 5 Sep 2024 11:17:53 -0500 Subject: [PATCH 166/213] vm_phys: hide alloc_freelist_pages Make vm_phys_alloc_freelist_pages static. There are no longer any callers outside of vm_phys.c. Reviewed by: alc, markj Differential Revision: https://reviews.freebsd.org/D46539 --- sys/vm/vm_phys.c | 42 +++++++++++++++++++++--------------------- sys/vm/vm_phys.h | 2 -- 2 files changed, 21 insertions(+), 23 deletions(-) diff --git a/sys/vm/vm_phys.c b/sys/vm/vm_phys.c index 59ab7d13c55d..cf1ed5818b2f 100644 --- a/sys/vm/vm_phys.c +++ b/sys/vm/vm_phys.c @@ -903,26 +903,6 @@ vm_phys_alloc_npages(int domain, int pool, int npages, vm_page_t ma[]) return (i); } -/* - * Allocate a contiguous, power of two-sized set of physical pages - * from the free lists. - * - * The free page queues must be locked. - */ -vm_page_t -vm_phys_alloc_pages(int domain, int pool, int order) -{ - vm_page_t m; - int freelist; - - for (freelist = 0; freelist < VM_NFREELIST; freelist++) { - m = vm_phys_alloc_freelist_pages(domain, freelist, pool, order); - if (m != NULL) - return (m); - } - return (NULL); -} - /* * Allocate a contiguous, power of two-sized set of physical pages from the * specified free list. The free list must be specified using one of the @@ -930,7 +910,7 @@ vm_phys_alloc_pages(int domain, int pool, int order) * * The free page queues must be locked. */ -vm_page_t +static vm_page_t vm_phys_alloc_freelist_pages(int domain, int freelist, int pool, int order) { struct vm_freelist *alt, *fl; @@ -987,6 +967,26 @@ vm_phys_alloc_freelist_pages(int domain, int freelist, int pool, int order) return (NULL); } +/* + * Allocate a contiguous, power of two-sized set of physical pages + * from the free lists. + * + * The free page queues must be locked. + */ +vm_page_t +vm_phys_alloc_pages(int domain, int pool, int order) +{ + vm_page_t m; + int freelist; + + for (freelist = 0; freelist < VM_NFREELIST; freelist++) { + m = vm_phys_alloc_freelist_pages(domain, freelist, pool, order); + if (m != NULL) + return (m); + } + return (NULL); +} + /* * Find the vm_page corresponding to the given physical address, which must lie * within the given physical memory segment. diff --git a/sys/vm/vm_phys.h b/sys/vm/vm_phys.h index bd086fd5571f..43d94a9420f2 100644 --- a/sys/vm/vm_phys.h +++ b/sys/vm/vm_phys.h @@ -61,8 +61,6 @@ extern int *mem_locality; void vm_phys_add_seg(vm_paddr_t start, vm_paddr_t end); vm_page_t vm_phys_alloc_contig(int domain, u_long npages, vm_paddr_t low, vm_paddr_t high, u_long alignment, vm_paddr_t boundary); -vm_page_t vm_phys_alloc_freelist_pages(int domain, int freelist, int pool, - int order); int vm_phys_alloc_npages(int domain, int pool, int npages, vm_page_t ma[]); vm_page_t vm_phys_alloc_pages(int domain, int pool, int order); int vm_phys_domain_match(int prefer, vm_paddr_t low, vm_paddr_t high); From 7b86593f0f6cbfba2883058c6c9d2389f1c581aa Mon Sep 17 00:00:00 2001 From: Justin Hibbits Date: Thu, 5 Sep 2024 13:20:14 -0400 Subject: [PATCH 167/213] sdhci: Match quirk_set/quirk_clear sysctls to type These quirk fields are u_int, so match the sysctl type to the actual types, and use SYSCTL_UINT. This provides room for setting bit 31 quirk as needed. Sponsored by: Juniper Networks, Inc. MFC after: 1 week --- sys/dev/sdhci/sdhci.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/dev/sdhci/sdhci.c b/sys/dev/sdhci/sdhci.c index 2403f60d613c..c747f54cb32c 100644 --- a/sys/dev/sdhci/sdhci.c +++ b/sys/dev/sdhci/sdhci.c @@ -72,10 +72,10 @@ static int sdhci_debug = 0; SYSCTL_INT(_hw_sdhci, OID_AUTO, debug, CTLFLAG_RWTUN, &sdhci_debug, 0, "Debug level"); u_int sdhci_quirk_clear = 0; -SYSCTL_INT(_hw_sdhci, OID_AUTO, quirk_clear, CTLFLAG_RWTUN, &sdhci_quirk_clear, +SYSCTL_UINT(_hw_sdhci, OID_AUTO, quirk_clear, CTLFLAG_RWTUN, &sdhci_quirk_clear, 0, "Mask of quirks to clear"); u_int sdhci_quirk_set = 0; -SYSCTL_INT(_hw_sdhci, OID_AUTO, quirk_set, CTLFLAG_RWTUN, &sdhci_quirk_set, 0, +SYSCTL_UINT(_hw_sdhci, OID_AUTO, quirk_set, CTLFLAG_RWTUN, &sdhci_quirk_set, 0, "Mask of quirks to set"); #define RD1(slot, off) SDHCI_READ_1((slot)->bus, (slot), (off)) From d59a76183470685bdf0b88013d2baad1f04f030f Mon Sep 17 00:00:00 2001 From: Rob Norris Date: Wed, 4 Sep 2024 12:09:43 +1000 Subject: [PATCH 168/213] spa_prop_get: require caller to supply output nvlist All callers to spa_prop_get() and spa_prop_get_nvlist() supplied their own preallocated nvlist (except ztest), so we can remove the option to have them allocate one if none is supplied. This sidesteps a bug in spa_prop_get(), where the error var wasn't initialised, which could lead to the provided nvlist being freed at the end. Sponsored-by: Klara, Inc. Sponsored-by: Wasabi Technology, Inc. Signed-off-by: Rob Norris (cherry picked from commit 366d6fecf6bb3c59668b0f3b89f2a610595f3d2f) --- sys/contrib/openzfs/cmd/ztest.c | 5 +- sys/contrib/openzfs/include/sys/spa.h | 4 +- sys/contrib/openzfs/module/zfs/spa.c | 100 +++++++++------------ sys/contrib/openzfs/module/zfs/zfs_ioctl.c | 10 +-- 4 files changed, 53 insertions(+), 66 deletions(-) diff --git a/sys/contrib/openzfs/cmd/ztest.c b/sys/contrib/openzfs/cmd/ztest.c index 6a9264ddcc4c..eb68c27b1dc1 100644 --- a/sys/contrib/openzfs/cmd/ztest.c +++ b/sys/contrib/openzfs/cmd/ztest.c @@ -6211,13 +6211,14 @@ void ztest_spa_prop_get_set(ztest_ds_t *zd, uint64_t id) { (void) zd, (void) id; - nvlist_t *props = NULL; (void) pthread_rwlock_rdlock(&ztest_name_lock); (void) ztest_spa_prop_set_uint64(ZPOOL_PROP_AUTOTRIM, ztest_random(2)); - VERIFY0(spa_prop_get(ztest_spa, &props)); + nvlist_t *props = fnvlist_alloc(); + + VERIFY0(spa_prop_get(ztest_spa, props)); if (ztest_opts.zo_verbose >= 6) dump_nvlist(props, 4); diff --git a/sys/contrib/openzfs/include/sys/spa.h b/sys/contrib/openzfs/include/sys/spa.h index 3998f5a6de73..0fa3149e6c6f 100644 --- a/sys/contrib/openzfs/include/sys/spa.h +++ b/sys/contrib/openzfs/include/sys/spa.h @@ -1196,9 +1196,9 @@ extern void spa_boot_init(void); /* properties */ extern int spa_prop_set(spa_t *spa, nvlist_t *nvp); -extern int spa_prop_get(spa_t *spa, nvlist_t **nvp); +extern int spa_prop_get(spa_t *spa, nvlist_t *nvp); extern int spa_prop_get_nvlist(spa_t *spa, char **props, - unsigned int n_props, nvlist_t **outnvl); + unsigned int n_props, nvlist_t *outnvl); extern void spa_prop_clear_bootfs(spa_t *spa, uint64_t obj, dmu_tx_t *tx); extern void spa_configfile_set(spa_t *, nvlist_t *, boolean_t); diff --git a/sys/contrib/openzfs/module/zfs/spa.c b/sys/contrib/openzfs/module/zfs/spa.c index cafc7196c354..7a3dd29769ca 100644 --- a/sys/contrib/openzfs/module/zfs/spa.c +++ b/sys/contrib/openzfs/module/zfs/spa.c @@ -366,21 +366,15 @@ spa_prop_add(spa_t *spa, const char *propname, nvlist_t *outnvl) int spa_prop_get_nvlist(spa_t *spa, char **props, unsigned int n_props, - nvlist_t **outnvl) + nvlist_t *outnvl) { int err = 0; if (props == NULL) return (0); - if (*outnvl == NULL) { - err = nvlist_alloc(outnvl, NV_UNIQUE_NAME, KM_SLEEP); - if (err) - return (err); - } - for (unsigned int i = 0; i < n_props && err == 0; i++) { - err = spa_prop_add(spa, props[i], *outnvl); + err = spa_prop_add(spa, props[i], outnvl); } return (err); @@ -406,7 +400,7 @@ spa_prop_add_user(nvlist_t *nvl, const char *propname, char *strval, * Get property values from the spa configuration. */ static void -spa_prop_get_config(spa_t *spa, nvlist_t **nvp) +spa_prop_get_config(spa_t *spa, nvlist_t *nv) { vdev_t *rvd = spa->spa_root_vdev; dsl_pool_t *pool = spa->spa_dsl_pool; @@ -428,48 +422,48 @@ spa_prop_get_config(spa_t *spa, nvlist_t **nvp) size += metaslab_class_get_space(spa_dedup_class(spa)); size += metaslab_class_get_space(spa_embedded_log_class(spa)); - spa_prop_add_list(*nvp, ZPOOL_PROP_NAME, spa_name(spa), 0, src); - spa_prop_add_list(*nvp, ZPOOL_PROP_SIZE, NULL, size, src); - spa_prop_add_list(*nvp, ZPOOL_PROP_ALLOCATED, NULL, alloc, src); - spa_prop_add_list(*nvp, ZPOOL_PROP_FREE, NULL, + spa_prop_add_list(nv, ZPOOL_PROP_NAME, spa_name(spa), 0, src); + spa_prop_add_list(nv, ZPOOL_PROP_SIZE, NULL, size, src); + spa_prop_add_list(nv, ZPOOL_PROP_ALLOCATED, NULL, alloc, src); + spa_prop_add_list(nv, ZPOOL_PROP_FREE, NULL, size - alloc, src); - spa_prop_add_list(*nvp, ZPOOL_PROP_CHECKPOINT, NULL, + spa_prop_add_list(nv, ZPOOL_PROP_CHECKPOINT, NULL, spa->spa_checkpoint_info.sci_dspace, src); - spa_prop_add_list(*nvp, ZPOOL_PROP_FRAGMENTATION, NULL, + spa_prop_add_list(nv, ZPOOL_PROP_FRAGMENTATION, NULL, metaslab_class_fragmentation(mc), src); - spa_prop_add_list(*nvp, ZPOOL_PROP_EXPANDSZ, NULL, + spa_prop_add_list(nv, ZPOOL_PROP_EXPANDSZ, NULL, metaslab_class_expandable_space(mc), src); - spa_prop_add_list(*nvp, ZPOOL_PROP_READONLY, NULL, + spa_prop_add_list(nv, ZPOOL_PROP_READONLY, NULL, (spa_mode(spa) == SPA_MODE_READ), src); cap = (size == 0) ? 0 : (alloc * 100 / size); - spa_prop_add_list(*nvp, ZPOOL_PROP_CAPACITY, NULL, cap, src); + spa_prop_add_list(nv, ZPOOL_PROP_CAPACITY, NULL, cap, src); - spa_prop_add_list(*nvp, ZPOOL_PROP_DEDUPRATIO, NULL, + spa_prop_add_list(nv, ZPOOL_PROP_DEDUPRATIO, NULL, ddt_get_pool_dedup_ratio(spa), src); - spa_prop_add_list(*nvp, ZPOOL_PROP_BCLONEUSED, NULL, + spa_prop_add_list(nv, ZPOOL_PROP_BCLONEUSED, NULL, brt_get_used(spa), src); - spa_prop_add_list(*nvp, ZPOOL_PROP_BCLONESAVED, NULL, + spa_prop_add_list(nv, ZPOOL_PROP_BCLONESAVED, NULL, brt_get_saved(spa), src); - spa_prop_add_list(*nvp, ZPOOL_PROP_BCLONERATIO, NULL, + spa_prop_add_list(nv, ZPOOL_PROP_BCLONERATIO, NULL, brt_get_ratio(spa), src); - spa_prop_add_list(*nvp, ZPOOL_PROP_DEDUP_TABLE_SIZE, NULL, + spa_prop_add_list(nv, ZPOOL_PROP_DEDUP_TABLE_SIZE, NULL, ddt_get_ddt_dsize(spa), src); - spa_prop_add_list(*nvp, ZPOOL_PROP_HEALTH, NULL, + spa_prop_add_list(nv, ZPOOL_PROP_HEALTH, NULL, rvd->vdev_state, src); version = spa_version(spa); if (version == zpool_prop_default_numeric(ZPOOL_PROP_VERSION)) { - spa_prop_add_list(*nvp, ZPOOL_PROP_VERSION, NULL, + spa_prop_add_list(nv, ZPOOL_PROP_VERSION, NULL, version, ZPROP_SRC_DEFAULT); } else { - spa_prop_add_list(*nvp, ZPOOL_PROP_VERSION, NULL, + spa_prop_add_list(nv, ZPOOL_PROP_VERSION, NULL, version, ZPROP_SRC_LOCAL); } - spa_prop_add_list(*nvp, ZPOOL_PROP_LOAD_GUID, + spa_prop_add_list(nv, ZPOOL_PROP_LOAD_GUID, NULL, spa_load_guid(spa), src); } @@ -479,62 +473,62 @@ spa_prop_get_config(spa_t *spa, nvlist_t **nvp) * when opening pools before this version freedir will be NULL. */ if (pool->dp_free_dir != NULL) { - spa_prop_add_list(*nvp, ZPOOL_PROP_FREEING, NULL, + spa_prop_add_list(nv, ZPOOL_PROP_FREEING, NULL, dsl_dir_phys(pool->dp_free_dir)->dd_used_bytes, src); } else { - spa_prop_add_list(*nvp, ZPOOL_PROP_FREEING, + spa_prop_add_list(nv, ZPOOL_PROP_FREEING, NULL, 0, src); } if (pool->dp_leak_dir != NULL) { - spa_prop_add_list(*nvp, ZPOOL_PROP_LEAKED, NULL, + spa_prop_add_list(nv, ZPOOL_PROP_LEAKED, NULL, dsl_dir_phys(pool->dp_leak_dir)->dd_used_bytes, src); } else { - spa_prop_add_list(*nvp, ZPOOL_PROP_LEAKED, + spa_prop_add_list(nv, ZPOOL_PROP_LEAKED, NULL, 0, src); } } - spa_prop_add_list(*nvp, ZPOOL_PROP_GUID, NULL, spa_guid(spa), src); + spa_prop_add_list(nv, ZPOOL_PROP_GUID, NULL, spa_guid(spa), src); if (spa->spa_comment != NULL) { - spa_prop_add_list(*nvp, ZPOOL_PROP_COMMENT, spa->spa_comment, + spa_prop_add_list(nv, ZPOOL_PROP_COMMENT, spa->spa_comment, 0, ZPROP_SRC_LOCAL); } if (spa->spa_compatibility != NULL) { - spa_prop_add_list(*nvp, ZPOOL_PROP_COMPATIBILITY, + spa_prop_add_list(nv, ZPOOL_PROP_COMPATIBILITY, spa->spa_compatibility, 0, ZPROP_SRC_LOCAL); } if (spa->spa_root != NULL) - spa_prop_add_list(*nvp, ZPOOL_PROP_ALTROOT, spa->spa_root, + spa_prop_add_list(nv, ZPOOL_PROP_ALTROOT, spa->spa_root, 0, ZPROP_SRC_LOCAL); if (spa_feature_is_enabled(spa, SPA_FEATURE_LARGE_BLOCKS)) { - spa_prop_add_list(*nvp, ZPOOL_PROP_MAXBLOCKSIZE, NULL, + spa_prop_add_list(nv, ZPOOL_PROP_MAXBLOCKSIZE, NULL, MIN(zfs_max_recordsize, SPA_MAXBLOCKSIZE), ZPROP_SRC_NONE); } else { - spa_prop_add_list(*nvp, ZPOOL_PROP_MAXBLOCKSIZE, NULL, + spa_prop_add_list(nv, ZPOOL_PROP_MAXBLOCKSIZE, NULL, SPA_OLD_MAXBLOCKSIZE, ZPROP_SRC_NONE); } if (spa_feature_is_enabled(spa, SPA_FEATURE_LARGE_DNODE)) { - spa_prop_add_list(*nvp, ZPOOL_PROP_MAXDNODESIZE, NULL, + spa_prop_add_list(nv, ZPOOL_PROP_MAXDNODESIZE, NULL, DNODE_MAX_SIZE, ZPROP_SRC_NONE); } else { - spa_prop_add_list(*nvp, ZPOOL_PROP_MAXDNODESIZE, NULL, + spa_prop_add_list(nv, ZPOOL_PROP_MAXDNODESIZE, NULL, DNODE_MIN_SIZE, ZPROP_SRC_NONE); } if ((dp = list_head(&spa->spa_config_list)) != NULL) { if (dp->scd_path == NULL) { - spa_prop_add_list(*nvp, ZPOOL_PROP_CACHEFILE, + spa_prop_add_list(nv, ZPOOL_PROP_CACHEFILE, "none", 0, ZPROP_SRC_LOCAL); } else if (strcmp(dp->scd_path, spa_config_path) != 0) { - spa_prop_add_list(*nvp, ZPOOL_PROP_CACHEFILE, + spa_prop_add_list(nv, ZPOOL_PROP_CACHEFILE, dp->scd_path, 0, ZPROP_SRC_LOCAL); } } @@ -544,19 +538,13 @@ spa_prop_get_config(spa_t *spa, nvlist_t **nvp) * Get zpool property values. */ int -spa_prop_get(spa_t *spa, nvlist_t **nvp) +spa_prop_get(spa_t *spa, nvlist_t *nv) { objset_t *mos = spa->spa_meta_objset; zap_cursor_t zc; zap_attribute_t za; dsl_pool_t *dp; - int err; - - if (*nvp == NULL) { - err = nvlist_alloc(nvp, NV_UNIQUE_NAME, KM_SLEEP); - if (err) - return (err); - } + int err = 0; dp = spa_get_dsl(spa); dsl_pool_config_enter(dp, FTAG); @@ -565,7 +553,7 @@ spa_prop_get(spa_t *spa, nvlist_t **nvp) /* * Get properties from the spa config. */ - spa_prop_get_config(spa, nvp); + spa_prop_get_config(spa, nv); /* If no pool property object, no more prop to get. */ if (mos == NULL || spa->spa_pool_props_object == 0) @@ -610,7 +598,7 @@ spa_prop_get(spa_t *spa, nvlist_t **nvp) intval = za.za_first_integer; } - spa_prop_add_list(*nvp, prop, strval, intval, src); + spa_prop_add_list(nv, prop, strval, intval, src); if (strval != NULL) kmem_free(strval, ZFS_MAX_DATASET_NAME_LEN); @@ -627,10 +615,10 @@ spa_prop_get(spa_t *spa, nvlist_t **nvp) break; } if (prop != ZPOOL_PROP_INVAL) { - spa_prop_add_list(*nvp, prop, strval, 0, src); + spa_prop_add_list(nv, prop, strval, 0, src); } else { src = ZPROP_SRC_LOCAL; - spa_prop_add_user(*nvp, za.za_name, strval, + spa_prop_add_user(nv, za.za_name, strval, src); } kmem_free(strval, za.za_num_integers); @@ -644,11 +632,9 @@ spa_prop_get(spa_t *spa, nvlist_t **nvp) out: mutex_exit(&spa->spa_props_lock); dsl_pool_config_exit(dp, FTAG); - if (err && err != ENOENT) { - nvlist_free(*nvp); - *nvp = NULL; + + if (err && err != ENOENT) return (err); - } return (0); } diff --git a/sys/contrib/openzfs/module/zfs/zfs_ioctl.c b/sys/contrib/openzfs/module/zfs/zfs_ioctl.c index 897335dd4e4f..3e2fb73b11ed 100644 --- a/sys/contrib/openzfs/module/zfs/zfs_ioctl.c +++ b/sys/contrib/openzfs/module/zfs/zfs_ioctl.c @@ -3022,7 +3022,6 @@ static const zfs_ioc_key_t zfs_keys_get_props[] = { static int zfs_ioc_pool_get_props(const char *pool, nvlist_t *innvl, nvlist_t *outnvl) { - nvlist_t *nvp = outnvl; spa_t *spa; char **props = NULL; unsigned int n_props = 0; @@ -3041,16 +3040,17 @@ zfs_ioc_pool_get_props(const char *pool, nvlist_t *innvl, nvlist_t *outnvl) */ mutex_enter(&spa_namespace_lock); if ((spa = spa_lookup(pool)) != NULL) { - error = spa_prop_get(spa, &nvp); + error = spa_prop_get(spa, outnvl); if (error == 0 && props != NULL) error = spa_prop_get_nvlist(spa, props, n_props, - &nvp); + outnvl); } mutex_exit(&spa_namespace_lock); } else { - error = spa_prop_get(spa, &nvp); + error = spa_prop_get(spa, outnvl); if (error == 0 && props != NULL) - error = spa_prop_get_nvlist(spa, props, n_props, &nvp); + error = spa_prop_get_nvlist(spa, props, n_props, + outnvl); spa_close(spa, FTAG); } From ed4d2a54fc7a0397c2042f496f176305ca03ebdd Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Wed, 4 Sep 2024 19:03:49 +0000 Subject: [PATCH 169/213] rc: network.subr update consitency with older change (v6/v4 order) As of 1b5be7204eaeeaf58eefdebe5b308f90792c693b we setup parts of IPv6 before IPv4 if configured. For consistency change a case in ifn_start() calling ipv6_up() before ipv4_up() and reverse in ifn_stop(). MFC after: 10 days Reviewed by: zlei Differential Revision: https://reviews.freebsd.org/D33426 --- libexec/rc/network.subr | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libexec/rc/network.subr b/libexec/rc/network.subr index 257643f48ba5..931fbec19a60 100644 --- a/libexec/rc/network.subr +++ b/libexec/rc/network.subr @@ -46,8 +46,8 @@ ifn_start() ifscript_up ${ifn} && cfg=0 ifconfig_up ${ifn} && cfg=0 if ! noafif $ifn; then - afexists inet && ipv4_up ${ifn} && cfg=0 afexists inet6 && ipv6_up ${ifn} && cfg=0 + afexists inet && ipv4_up ${ifn} && cfg=0 fi childif_create ${ifn} && cfg=0 @@ -67,8 +67,8 @@ ifn_stop() [ -z "$ifn" ] && err 1 "ifn_stop called without an interface" if ! noafif $ifn; then - afexists inet6 && ipv6_down ${ifn} && cfg=0 afexists inet && ipv4_down ${ifn} && cfg=0 + afexists inet6 && ipv6_down ${ifn} && cfg=0 fi ifconfig_down ${ifn} && cfg=0 ifscript_down ${ifn} && cfg=0 From 157802238b5aa7722aff40317fe6d05f5c975d71 Mon Sep 17 00:00:00 2001 From: Dimitry Andric Date: Thu, 5 Sep 2024 21:55:44 +0200 Subject: [PATCH 170/213] Add UPDATING note about running make delete-old after libc++ 18 upgrade PR: 279692 MFC after: 3 days --- UPDATING | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/UPDATING b/UPDATING index cffafdb5d247..1aae85df0a70 100644 --- a/UPDATING +++ b/UPDATING @@ -55,6 +55,13 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 15.x IS SLOW: own packages. If you use pkgbase, you should install the relevant packages: FreeBSD-cron, FreeBSD-lp, or FreeBSD-ntp. +20240406: + Clang, llvm, lld, lldb, compiler-rt, libc++, libunwind and openmp have + been upgraded to 18.1.6. It is important that you run `make delete-old` + as described in the COMMON ITEMS section, otherwise several libc++ + headers that are obsolete and need to be removed can cause compilation + errors in C++ programs. + 20240205: For dynamically linked programs, system calls are now made from libsys rather than libc. No change in linkage is required as From bedfac1f026fa8e2e6572ca380d89d74a01d5def Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Thu, 5 Sep 2024 17:14:36 -0400 Subject: [PATCH 171/213] nvmf_tcp: Fully honor kern.nvmf.tcp.max_transmit_data for C2H_DATA PDUs The previous version of tcp_send_controller_data avoided sending a chain of multiple mbufs that exceeded the limit, but if an individual mbuf was larger than the limit it was sent as a single, over-sized PDU. Fix by using m_split() to split individual mbufs larger than the limit. Note that this is not a protocol error, per se, as there is no limit on C2H_DATA PDU lengths (unlike the MAXH2CDATA parameter). This fix just honors the administrative limit more faithfully. This case is also very unlikely with the default limit of 256k. Sponsored by: Chelsio Communications --- sys/dev/nvmf/nvmf_tcp.c | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/sys/dev/nvmf/nvmf_tcp.c b/sys/dev/nvmf/nvmf_tcp.c index 67d239b63faf..22275aaa835b 100644 --- a/sys/dev/nvmf/nvmf_tcp.c +++ b/sys/dev/nvmf/nvmf_tcp.c @@ -1784,7 +1784,6 @@ tcp_send_controller_data(struct nvmf_capsule *nc, uint32_t data_offset, { struct nvmf_tcp_qpair *qp = TQP(nc->nc_qpair); struct nvme_sgl_descriptor *sgl; - struct mbuf *n, *p; uint32_t data_len; bool last_pdu, last_xfer; @@ -1813,21 +1812,29 @@ tcp_send_controller_data(struct nvmf_capsule *nc, uint32_t data_offset, /* Queue one more C2H_DATA PDUs containing the data from 'm'. */ while (m != NULL) { + struct mbuf *n; uint32_t todo; - todo = m->m_len; - p = m; - n = p->m_next; - while (n != NULL) { - if (todo + n->m_len > qp->max_tx_data) { - p->m_next = NULL; - break; - } - todo += n->m_len; - p = n; + if (m->m_len > qp->max_tx_data) { + n = m_split(m, qp->max_tx_data, M_WAITOK); + todo = m->m_len; + } else { + struct mbuf *p; + + todo = m->m_len; + p = m; n = p->m_next; + while (n != NULL) { + if (todo + n->m_len > qp->max_tx_data) { + p->m_next = NULL; + break; + } + todo += n->m_len; + p = n; + n = p->m_next; + } + MPASS(m_length(m, NULL) == todo); } - MPASS(m_length(m, NULL) == todo); last_pdu = (n == NULL && last_xfer); tcp_send_c2h_pdu(qp, nc->nc_sqe.cid, data_offset, m, todo, From 62ad5eff805323c79d60cd902863fa8c29b863a8 Mon Sep 17 00:00:00 2001 From: Philip Paeps Date: Fri, 6 Sep 2024 09:33:05 +0800 Subject: [PATCH 172/213] Import tzdata 2024b --- CONTRIBUTING | 18 +- Makefile | 412 ++++++++++++++------------- NEWS | 124 +++++++- africa | 73 +++-- antarctica | 58 ++-- asia | 442 ++++++++++++++-------------- australasia | 130 ++++----- backward | 15 +- backzone | 35 ++- checknow.awk | 4 +- etcetera | 54 ++-- europe | 713 +++++++++++++++++++++++++++++----------------- leap-seconds.list | 30 +- leapseconds | 8 +- northamerica | 145 +++++++--- southamerica | 486 +++++++++++++++---------------- theory.html | 214 +++++++++----- version | 2 +- ziguard.awk | 32 +-- zone.tab | 3 +- zone1970.tab | 3 +- zonenow.tab | 8 +- 22 files changed, 1768 insertions(+), 1241 deletions(-) diff --git a/CONTRIBUTING b/CONTRIBUTING index 6d800e4c03a3..f6edbd3be7d3 100644 --- a/CONTRIBUTING +++ b/CONTRIBUTING @@ -23,10 +23,10 @@ such as renaming, adding or removing zones, please read "Theory and pragmatics of the tz code and data" . It is also good to browse the mailing list archives - for examples of patches that tend -to work well. Additions to data should contain commentary citing -reliable sources as justification. Citations should use "https:" URLs -if available. + +for examples of patches that tend to work well. +Changes should contain commentary citing reliable sources. +Citations should use "https:" URLs if available. For changes that fix sensitive security-related bugs, please see the distribution's 'SECURITY' file. @@ -63,12 +63,16 @@ If you use Git the following workflow may be helpful: * Edit source files. Include commentary that justifies the changes by citing reliable sources. - * Debug the changes, e.g.: + * Debug the changes locally, e.g.: - make check - make install + make TOPDIR=$PWD/tz clean check install ./zdump -v America/Los_Angeles + Although builds assume only basic POSIX, they use extra features + if available. 'make check' accesses validator.w3.org unless you + lack 'curl' or use 'make CURL=:'. If you have the latest GCC, + "make CFLAGS='$(GCC_DEBUG_FLAGS)'" does extra checking. + * For each separable change, commit it in the new branch, e.g.: git add northamerica diff --git a/Makefile b/Makefile index d48354c72df4..0087b4596515 100644 --- a/Makefile +++ b/Makefile @@ -3,17 +3,17 @@ # 2009-05-17 by Arthur David Olson. # Request POSIX conformance; this must be the first non-comment line. .POSIX: -# On older platforms you may need to scrounge for a POSIX-conforming 'make'. -# For example, on Solaris 10 (2005), use /usr/sfw/bin/gmake or -# /usr/xpg4/bin/make, not /usr/ccs/bin/make. +# On older platforms you may need to scrounge for POSIX conformance. +# For example, on Solaris 10 (2005) with Sun Studio 12 aka Sun C 5.9 (2007), +# use 'PATH=/usr/xpg4/bin:$PATH make CC=c99'. # To affect how this Makefile works, you can run a shell script like this: # # #!/bin/sh -# make CC='gcc -std=gnu11' "$@" +# make CC='gcc -std=gnu23' "$@" # -# This example script is appropriate for a pre-2017 GNU/Linux system -# where a non-default setting is needed to support this package's use of C99. +# This example script is appropriate for a circa 2024 GNU/Linux system +# where a non-default setting enables this package's optional use of C23. # # Alternatively, you can simply edit this Makefile to tailor the following # macro definitions. @@ -53,7 +53,7 @@ DATAFORM= main LOCALTIME= Factory -# The POSIXRULES macro controls interpretation of POSIX-2017.1-like TZ +# The POSIXRULES macro controls interpretation of POSIX-like TZ # settings like TZ='EET-2EEST' that lack DST transition rules. # If POSIXRULES is '-', no template is installed; this is the default. # Any other value for POSIXRULES is obsolete and should not be relied on, as: @@ -132,8 +132,9 @@ LIBDIR = $(TOPDIR)/$(USRDIR)/lib # Types to try, as an alternative to time_t. TIME_T_ALTERNATIVES = $(TIME_T_ALTERNATIVES_HEAD) $(TIME_T_ALTERNATIVES_TAIL) -TIME_T_ALTERNATIVES_HEAD = int_least64_t -TIME_T_ALTERNATIVES_TAIL = int_least32_t uint_least32_t uint_least64_t +TIME_T_ALTERNATIVES_HEAD = int_least64_t.ck +TIME_T_ALTERNATIVES_TAIL = int_least32_t.ck uint_least32_t.ck \ + uint_least64_t.ck # What kind of TZif data files to generate. (TZif is the binary time # zone data format that zic generates; see Internet RFC 8536.) @@ -219,6 +220,7 @@ LDLIBS= # than what POSIX specifies, assuming local time is UT. # For example, N is 252460800 on AmigaOS. # -DHAVE_DECL_ASCTIME_R=0 if does not declare asctime_r +# on POSIX platforms predating POSIX.1-2024 # -DHAVE_DECL_ENVIRON if declares 'environ' # -DHAVE_DECL_TIMEGM=0 if does not declare timegm # -DHAVE_DIRECT_H if mkdir needs (MS-Windows) @@ -229,7 +231,7 @@ LDLIBS= # where LDLIBS also needs to contain -lintl on some hosts; # -DHAVE_GETTEXT=0 to avoid using gettext # -DHAVE_INCOMPATIBLE_CTIME_R if your system's time.h declares -# ctime_r and asctime_r incompatibly with the POSIX standard +# ctime_r and asctime_r incompatibly with POSIX.1-2017 and earlier # (Solaris when _POSIX_PTHREAD_SEMANTICS is not defined). # -DHAVE_INTTYPES_H=0 if does not work*+ # -DHAVE_LINK=0 if your system lacks a link function @@ -261,8 +263,11 @@ LDLIBS= # -DRESERVE_STD_EXT_IDS if your platform reserves standard identifiers # with external linkage, e.g., applications cannot define 'localtime'. # -Dssize_t=long on hosts like MS-Windows that lack ssize_t -# -DSUPPORT_C89 if the tzcode library should support C89 callers+ -# However, this might trigger latent bugs in C99-or-later callers. +# -DSUPPORT_C89=0 if the tzcode library should not support C89 callers +# Although -DSUPPORT_C89=0 might work around latent bugs in callers, +# it does not conform to POSIX. +# -DSUPPORT_POSIX2008 if the library should support older POSIX callers+ +# However, this might cause problems in POSIX.1-2024-or-later callers. # -DSUPPRESS_TZDIR to not prepend TZDIR to file names; this has # security implications and is not recommended for general use # -DTHREAD_SAFE to make localtime.c thread-safe, as POSIX requires; @@ -274,7 +279,7 @@ LDLIBS= # -DTZ_DOMAINDIR=\"/path\" to use "/path" for gettext directory; # the default is system-supplied, typically "/usr/lib/locale" # -DTZDEFRULESTRING=\",date/time,date/time\" to default to the specified -# DST transitions for POSIX.1-2017-style TZ strings lacking them, +# DST transitions for proleptic format TZ strings lacking them, # in the usual case where POSIXRULES is '-'. If not specified, # TZDEFRULESTRING defaults to US rules for future DST transitions. # This mishandles some past timestamps, as US DST rules have changed. @@ -302,23 +307,25 @@ LDLIBS= # # * Options marked "*" can be omitted if your compiler is C23 compatible. # * Options marked "+" are obsolescent and are planned to be removed -# once the code assumes C99 or later, say in the year 2029. +# once the code assumes C99 or later (say in the year 2029) +# and POSIX.1-2024 or later (say in the year 2034). # # Select instrumentation via "make GCC_INSTRUMENT='whatever'". GCC_INSTRUMENT = \ -fsanitize=undefined -fsanitize-address-use-after-scope \ -fsanitize-undefined-trap-on-error -fstack-protector # Omit -fanalyzer from GCC_DEBUG_FLAGS, as it makes GCC too slow. -GCC_DEBUG_FLAGS = -DGCC_LINT -g3 -O3 -fno-common \ +GCC_DEBUG_FLAGS = -DGCC_LINT -g3 -O3 \ $(GCC_INSTRUMENT) \ -Wall -Wextra \ -Walloc-size-larger-than=100000 -Warray-bounds=2 \ -Wbad-function-cast -Wbidi-chars=any,ucn -Wcast-align=strict -Wdate-time \ -Wdeclaration-after-statement -Wdouble-promotion \ - -Wduplicated-branches -Wduplicated-cond \ + -Wduplicated-branches -Wduplicated-cond -Wflex-array-member-not-at-end \ -Wformat=2 -Wformat-overflow=2 -Wformat-signedness -Wformat-truncation \ -Wimplicit-fallthrough=5 -Winit-self -Wlogical-op \ - -Wmissing-declarations -Wmissing-prototypes -Wnested-externs \ + -Wmissing-declarations -Wmissing-prototypes \ + -Wmissing-variable-declarations -Wnested-externs \ -Wnull-dereference \ -Wold-style-definition -Woverlength-strings -Wpointer-arith \ -Wshadow -Wshift-overflow=2 -Wstrict-overflow \ @@ -327,10 +334,9 @@ GCC_DEBUG_FLAGS = -DGCC_LINT -g3 -O3 -fno-common \ -Wsuggest-attribute=const -Wsuggest-attribute=format \ -Wsuggest-attribute=malloc \ -Wsuggest-attribute=noreturn -Wsuggest-attribute=pure \ - -Wtrampolines -Wundef -Wuninitialized -Wunused-macros -Wuse-after-free=3 \ + -Wtrampolines -Wundef -Wunused-macros -Wuse-after-free=3 \ -Wvariadic-macros -Wvla -Wwrite-strings \ - -Wno-address -Wno-format-nonliteral -Wno-sign-compare \ - -Wno-type-limits + -Wno-format-nonliteral -Wno-sign-compare # # If your system has a "GMT offset" field in its "struct tm"s # (or if you decide to add such a field in your system's "time.h" file), @@ -341,9 +347,8 @@ GCC_DEBUG_FLAGS = -DGCC_LINT -g3 -O3 -fno-common \ # Similarly, if your system has a "zone abbreviation" field, define # -DTM_ZONE=tm_zone # and define NO_TM_ZONE to suppress any guessing. -# Although these two fields are not required by POSIX.1-2017, -# POSIX 202x/D4 requires them and they are widely available -# on GNU/Linux and BSD systems. +# Although POSIX.1-2024 requires these fields and they are widely available +# on GNU/Linux and BSD systems, some older systems lack them. # # The next batch of options control support for external variables # exported by tzcode. In practice these variables are less useful @@ -353,7 +358,9 @@ GCC_DEBUG_FLAGS = -DGCC_LINT -g3 -O3 -fno-common \ # # -DHAVE_TZNAME=0 # do not support "tzname" # # -DHAVE_TZNAME=1 # support "tzname", which is defined by system library # # -DHAVE_TZNAME=2 # support and define "tzname" -# # to the "CFLAGS=" line. "tzname" is required by POSIX.1-1988 and later. +# # to the "CFLAGS=" line. Although "tzname" is required by POSIX.1-1988 +# # and later, its contents are unspecified if you use a geographical TZ +# # and the variable is planned to be removed in a future POSIX edition. # # If not defined, the code attempts to guess HAVE_TZNAME from other macros. # # Warning: unless time_tz is also defined, HAVE_TZNAME=1 can cause # # crashes when combined with some platforms' standard libraries, @@ -364,7 +371,9 @@ GCC_DEBUG_FLAGS = -DGCC_LINT -g3 -O3 -fno-common \ # # -DUSG_COMPAT=1 # support, and variables are defined by system library # # -DUSG_COMPAT=2 # support and define variables # # to the "CFLAGS=" line; "timezone" and "daylight" are inspired by Unix -# # Systems Group code and are required by POSIX.1-2008 and later (with XSI). +# # Systems Group code and are required by POSIX.1-2008 and later (with XSI), +# # although their contents are unspecified if you use a geographical TZ +# # and the variables are planned to be removed in a future edition of POSIX. # # If not defined, the code attempts to guess USG_COMPAT from other macros. # # # # To support the external variable "altzone", add @@ -428,18 +437,13 @@ GCC_DEBUG_FLAGS = -DGCC_LINT -g3 -O3 -fno-common \ # The name of a POSIX-like library archiver, its flags, C compiler, # linker flags, and 'make' utility. Ordinarily the defaults suffice. -# The commented-out values are the defaults specified by POSIX.1-202x/D4. +# The commented-out values are the defaults specified by POSIX.1-2024. #AR = ar #ARFLAGS = -rv #CC = c17 #LDFLAGS = #MAKE = make -# For leap seconds, this Makefile uses LEAPSECONDS='-L leapseconds' in -# submake command lines. The default is no leap seconds. - -LEAPSECONDS= - # Where to fetch leap-seconds.list from. leaplist_URI = \ https://hpiers.obspm.fr/iers/bul/bulc/ntp/leap-seconds.list @@ -461,7 +465,7 @@ ZFLAGS= # How to use zic to install TZif files. -ZIC_INSTALL= $(ZIC) -d '$(DESTDIR)$(TZDIR)' $(LEAPSECONDS) +ZIC_INSTALL= $(ZIC) -d '$(DESTDIR)$(TZDIR)' # The name of a POSIX-compliant 'awk' on your system. # mawk 1.3.3 and Solaris 10 /usr/bin/awk do not work. @@ -480,6 +484,7 @@ KSHELL= /bin/bash # Name of curl , used for HTML validation # and to fetch leap-seconds.list from upstream. +# Set CURL=: to disable use of the Internet. CURL= curl # Name of GNU Privacy Guard , used to sign distributions. @@ -533,21 +538,28 @@ OK_LINE= '^'$(OK_CHAR)'*$$' # Flags to give 'tar' when making a distribution. # Try to use flags appropriate for GNU tar. -GNUTARFLAGS= --format=pax --pax-option='delete=atime,delete=ctime' \ +GNUTARFLAGS= --format=pax --pax-option=delete=atime,delete=ctime \ --numeric-owner --owner=0 --group=0 \ --mode=go+u,go-w --sort=name -TARFLAGS= `if tar $(GNUTARFLAGS) --version >/dev/null 2>&1; \ - then echo $(GNUTARFLAGS); \ - else :; \ - fi` +SETUP_TAR= \ + export LC_ALL=C && \ + if tar $(GNUTARFLAGS) --version >/dev/null 2>&1; then \ + TAR='tar $(GNUTARFLAGS)'; \ + else \ + TAR=tar; \ + fi # Flags to give 'gzip' when making a distribution. GZIPFLAGS= -9n # When comparing .tzs files, use GNU diff's -F'^TZ=' option if supported. # This makes it easier to see which Zone has been affected. -DIFF_TZS= diff -u$$(! diff -u -F'^TZ=' - - <>/dev/null >&0 2>&1 \ - || echo ' -F^TZ=') +SETUP_DIFF_TZS = \ + if diff -u -F'^TZ=' - - <>/dev/null >&0 2>&1; then \ + DIFF_TZS='diff -u -F^TZ='; \ + else \ + DIFF_TZS='diff -u'; \ + fi # ':' on typical hosts; 'ranlib' on the ancient hosts that still need ranlib. RANLIB= : @@ -561,8 +573,8 @@ RANLIB= : TZCOBJS= zic.o -TZDOBJS= zdump.o localtime.o asctime.o strftime.o -DATEOBJS= date.o localtime.o strftime.o asctime.o +TZDOBJS= zdump.o localtime.o strftime.o +DATEOBJS= date.o localtime.o strftime.o LIBSRCS= localtime.c asctime.c difftime.c strftime.c LIBOBJS= localtime.o asctime.o difftime.o strftime.o HEADERS= tzfile.h private.h @@ -579,8 +591,7 @@ MANTXTS= newctime.3.txt newstrftime.3.txt newtzset.3.txt \ COMMON= calendars CONTRIBUTING LICENSE Makefile \ NEWS README SECURITY theory.html version WEB_PAGES= tz-art.html tz-how-to.html tz-link.html -CHECK_WEB_PAGES=check_theory.html check_tz-art.html \ - check_tz-how-to.html check_tz-link.html +CHECK_WEB_PAGES=theory.ck tz-art.ck tz-how-to.ck tz-link.ck DOCS= $(MANS) date.1 $(MANTXTS) $(WEB_PAGES) PRIMARY_YDATA= africa antarctica asia australasia \ europe northamerica southamerica @@ -641,8 +652,7 @@ install: all $(DATA) $(REDO) $(MANS) '$(DESTDIR)$(MANDIR)/man3' '$(DESTDIR)$(MANDIR)/man5' \ '$(DESTDIR)$(MANDIR)/man8' $(ZIC_INSTALL) -l $(LOCALTIME) \ - `case '$(POSIXRULES)' in ?*) echo '-p';; esac \ - ` $(POSIXRULES) \ + -p $(POSIXRULES) \ -t '$(DESTDIR)$(TZDEFAULT)' cp -f $(TABDATA) '$(DESTDIR)$(TZDIR)/.' cp tzselect '$(DESTDIR)$(BINDIR)/.' @@ -665,10 +675,10 @@ INSTALL: ALL install date.1 # and append "-dirty" if the contents do not already end in "-dirty". version: $(VERSION_DEPS) { (type git) >/dev/null 2>&1 && \ - V=`git describe --match '[0-9][0-9][0-9][0-9][a-z]*' \ - --abbrev=7 --dirty` || \ - if test '$(VERSION)' = unknown && V=`cat $@`; then \ - case $$V in *-dirty);; *) V=$$V-dirty;; esac; \ + V=$$(git describe --match '[0-9][0-9][0-9][0-9][a-z]*' \ + --abbrev=7 --dirty) || \ + if test '$(VERSION)' = unknown && read -r V <$@; then \ + V=$${V%-dirty}-dirty; \ else \ V='$(VERSION)'; \ fi; } && \ @@ -678,7 +688,7 @@ version: $(VERSION_DEPS) # These files can be tailored by setting BACKWARD, PACKRATDATA, PACKRATLIST. vanguard.zi main.zi rearguard.zi: $(DSTDATA_ZI_DEPS) $(AWK) \ - -v DATAFORM=`expr $@ : '\(.*\).zi'` \ + -v DATAFORM=$(@:.zi=) \ -v PACKRATDATA='$(PACKRATDATA)' \ -v PACKRATLIST='$(PACKRATLIST)' \ -f ziguard.awk \ @@ -687,7 +697,7 @@ vanguard.zi main.zi rearguard.zi: $(DSTDATA_ZI_DEPS) # This file has a version comment that attempts to capture any tailoring # via BACKWARD, DATAFORM, PACKRATDATA, PACKRATLIST, and REDO. tzdata.zi: $(DATAFORM).zi version zishrink.awk - version=`sed 1q version` && \ + read -r version $@ + ./zdump -i $(TZS_CUTOFF_FLAG) "$$PWD/$(@:.zd=)" >$@ TZS_NEW_DEPS = tzdata.zi zdump zic $(TZS_NEW): $(TZS_NEW_DEPS) @@ -812,20 +815,19 @@ $(TZS_NEW): $(TZS_NEW_DEPS) $(zic) -d tzs$(TZS_YEAR).dir tzdata.zi $(AWK) '/^L/{print "Link\t" $$2 "\t" $$3}' \ tzdata.zi | LC_ALL=C sort >$@.out - wd=`pwd` && \ - x=`$(AWK) '/^Z/{print "tzs$(TZS_YEAR).dir/" $$2 ".zd"}' \ + x=$$($(AWK) '/^Z/{print "tzs$(TZS_YEAR).dir/" $$2 ".zd"}' \ tzdata.zi \ - | LC_ALL=C sort -t . -k 2,2` && \ + | LC_ALL=C sort -t . -k 2,2) && \ set x $$x && \ shift && \ ZDS=$$* && \ - $(MAKE) wd="$$wd" TZS_CUTOFF_FLAG="$(TZS_CUTOFF_FLAG)" \ + $(MAKE) TZS_CUTOFF_FLAG="$(TZS_CUTOFF_FLAG)" \ ZDS="$$ZDS" $$ZDS && \ sed 's,^TZ=".*\.dir/,TZ=",' $$ZDS >>$@.out rm -fr tzs$(TZS_YEAR).dir mv $@.out $@ -# If $(TZS) exists but 'make check_tzs' fails, a maintainer should inspect the +# If $(TZS) exists but 'make tzs.ck' fails, a maintainer should inspect the # failed output and fix the inconsistency, perhaps by running 'make force_tzs'. $(TZS): touch $@ @@ -842,7 +844,7 @@ date: $(DATEOBJS) $(CC) -o $@ $(CFLAGS) $(LDFLAGS) $(DATEOBJS) $(LDLIBS) tzselect: tzselect.ksh version - VERSION=`cat version` && sed \ + read -r VERSION /dev/null 2>&1 \ - || { LC_ALL='$(UTF8_LOCALE)'; export LC_ALL; false; }; } + || { export LC_ALL='$(UTF8_LOCALE)'; false; }; } -check_character_set: $(ENCHILADA) +character-set.ck: $(ENCHILADA) $(UTF8_LOCALE_MISSING) || { \ sharp='#' && \ ! grep -Env $(SAFE_LINE) $(MANS) date.1 $(MANTXTS) \ @@ -882,48 +884,55 @@ check_character_set: $(ENCHILADA) } touch $@ -check_white_space: $(ENCHILADA) +white-space.ck: $(ENCHILADA) $(UTF8_LOCALE_MISSING) || { \ - patfmt=' \t|[\f\r\v]' && pat=`printf "$$patfmt\\n"` && \ + enchilada='$(ENCHILADA)' && \ + patfmt=' \t|[\f\r\v]' && pat=$$(printf "$$patfmt\\n") && \ ! grep -En "$$pat|[$s]\$$" \ - $$(ls $(ENCHILADA) | grep -Fvx leap-seconds.list); \ + $${enchilada%leap-seconds.list*} \ + $${enchilada#*leap-seconds.list}; \ } touch $@ PRECEDES_FILE_NAME = ^(Zone|Link[$s]+[^$s]+)[$s]+ FILE_NAME_COMPONENT_TOO_LONG = $(PRECEDES_FILE_NAME)[^$s]*[^/$s]{15} -check_name_lengths: $(TDATA_TO_CHECK) backzone - ! grep -En '$(FILE_NAME_COMPONENT_TOO_LONG)' \ +name-lengths.ck: $(TDATA_TO_CHECK) backzone + :;! grep -En '$(FILE_NAME_COMPONENT_TOO_LONG)' \ $(TDATA_TO_CHECK) backzone touch $@ +mainguard.ck: main.zi + test '$(PACKRATLIST)' || \ + cat $(TDATA) $(PACKRATDATA) | diff -u - main.zi + touch $@ + PRECEDES_STDOFF = ^(Zone[$s]+[^$s]+)?[$s]+ STDOFF = [-+]?[0-9:.]+ RULELESS_SAVE = (-|$(STDOFF)[sd]?) RULELESS_SLASHED_ABBRS = \ $(PRECEDES_STDOFF)$(STDOFF)[$s]+$(RULELESS_SAVE)[$s]+[^$s]*/ -check_slashed_abbrs: $(TDATA_TO_CHECK) - ! grep -En '$(RULELESS_SLASHED_ABBRS)' $(TDATA_TO_CHECK) +slashed-abbrs.ck: $(TDATA_TO_CHECK) + :;! grep -En '$(RULELESS_SLASHED_ABBRS)' $(TDATA_TO_CHECK) touch $@ CHECK_CC_LIST = { n = split($$1,a,/,/); for (i=2; i<=n; i++) print a[1], a[i]; } -check_sorted: backward backzone +sorted.ck: backward backzone $(AWK) '/^Link/ {printf "%.5d %s\n", g, $$3} !/./ {g++}' \ backward | LC_ALL=C sort -cu - $(AWK) '/^Zone/ {print $$2}' backzone | LC_ALL=C sort -cu + $(AWK) '/^Zone.*\// {print $$2}' backzone | LC_ALL=C sort -cu touch $@ -check_back: checklinks.awk $(TDATA_TO_CHECK) +back.ck: checklinks.awk $(TDATA_TO_CHECK) $(AWK) \ -v DATAFORM=$(DATAFORM) \ -v backcheck=backward \ -f checklinks.awk $(TDATA_TO_CHECK) touch $@ -check_links: checklinks.awk tzdata.zi +links.ck: checklinks.awk tzdata.zi $(AWK) \ -v DATAFORM=$(DATAFORM) \ -f checklinks.awk tzdata.zi @@ -932,26 +941,36 @@ check_links: checklinks.awk tzdata.zi # Check timestamps from now through 28 years from now, to make sure # that zonenow.tab contains all sequences of planned timestamps, # without any duplicate sequences. In theory this might require -# 2800 years but that would take a long time to check. -CHECK_NOW_TIMESTAMP = `./date +%s` +# 2800+ years but that would take a long time to check. +CHECK_NOW_TIMESTAMP = $$(./date +%s) CHECK_NOW_FUTURE_YEARS = 28 -CHECK_NOW_FUTURE_SECS = $(CHECK_NOW_FUTURE_YEARS) '*' 366 '*' 24 '*' 60 '*' 60 -check_now: checknow.awk date tzdata.zi zdump zic zone1970.tab zonenow.tab - rm -fr $@.dir - mkdir $@.dir - ./zic -d $@.dir tzdata.zi +CHECK_NOW_FUTURE_SECS = $(CHECK_NOW_FUTURE_YEARS) * 366 * 24 * 60 * 60 +now.ck: checknow.awk date tzdata.zi zdump zic zone1970.tab zonenow.tab + rm -fr $@d + mkdir $@d + ./zic -d $@d tzdata.zi now=$(CHECK_NOW_TIMESTAMP) && \ - future=`expr $(CHECK_NOW_FUTURE_SECS) + $$now` && \ + future=$$(($(CHECK_NOW_FUTURE_SECS) + $$now)) && \ ./zdump -i -t $$now,$$future \ - $$(find $$PWD/$@.dir/????*/ -type f) \ - >$@.dir/zdump.tab + $$(find "$$PWD/$@d"/????*/ -type f) \ + >$@d/zdump-now.tab && \ + ./zdump -i -t 0,$$future \ + $$(find "$$PWD/$@d" -name Etc -prune \ + -o -type f ! -name '*.tab' -print) \ + >$@d/zdump-1970.tab $(AWK) \ - -v zdump_table=$@.dir/zdump.tab \ + -v zdump_table=$@d/zdump-now.tab \ -f checknow.awk zonenow.tab - rm -fr $@.dir + $(AWK) \ + 'BEGIN {print "-\t-\tUTC"} /^Zone/ {print "-\t-\t" $$2}' \ + $(PRIMARY_YDATA) backward factory | \ + $(AWK) \ + -v zdump_table=$@d/zdump-1970.tab \ + -f checknow.awk + rm -fr $@d touch $@ -check_tables: checktab.awk $(YDATA) backward zone.tab zone1970.tab +tables.ck: checktab.awk $(YDATA) backward zone.tab zone1970.tab for tab in $(ZONETABLES); do \ test "$$tab" = zone.tab && links='$(BACKWARD)' || links=''; \ $(AWK) -f checktab.awk -v zone_table=$$tab $(YDATA) $$links \ @@ -959,26 +978,24 @@ check_tables: checktab.awk $(YDATA) backward zone.tab zone1970.tab done touch $@ -check_tzs: $(TZS) $(TZS_NEW) +tzs.ck: $(TZS) $(TZS_NEW) if test -s $(TZS); then \ - $(DIFF_TZS) $(TZS) $(TZS_NEW); \ + $(SETUP_DIFF_TZS) && $$DIFF_TZS $(TZS) $(TZS_NEW); \ else \ cp $(TZS_NEW) $(TZS); \ fi touch $@ check_web: $(CHECK_WEB_PAGES) -check_theory.html: theory.html -check_tz-art.html: tz-art.html -check_tz-how-to.html: tz-how-to.html -check_tz-link.html: tz-link.html -check_theory.html check_tz-art.html check_tz-how-to.html check_tz-link.html: - $(CURL) -sS --url https://validator.w3.org/nu/ -F out=gnu \ - -F file=@$$(expr $@ : 'check_\(.*\)') -o $@.out && \ +.SUFFIXES: .ck .html +.html.ck: + { ! ($(CURL) --version) >/dev/null 2>&1 || \ + $(CURL) -sS --url https://validator.w3.org/nu/ -F out=gnu \ + -F file=@$<; } >$@.out && \ test ! -s $@.out || { cat $@.out; exit 1; } mv $@.out $@ -check_ziguard: rearguard.zi vanguard.zi ziguard.awk +ziguard.ck: rearguard.zi vanguard.zi ziguard.awk $(AWK) -v DATAFORM=rearguard -f ziguard.awk vanguard.zi | \ diff -u rearguard.zi - $(AWK) -v DATAFORM=vanguard -f ziguard.awk rearguard.zi | \ @@ -987,36 +1004,35 @@ check_ziguard: rearguard.zi vanguard.zi ziguard.awk # Check that zishrink.awk does not alter the data, and that ziguard.awk # preserves main-format data. -check_zishrink: check_zishrink_posix check_zishrink_right -check_zishrink_posix check_zishrink_right: \ +check_zishrink: zishrink-posix.ck zishrink-right.ck +zishrink-posix.ck zishrink-right.ck: \ zic leapseconds $(PACKRATDATA) $(PACKRATLIST) \ $(TDATA) $(DATAFORM).zi tzdata.zi - rm -fr $@.dir $@-t.dir $@-shrunk.dir - mkdir $@.dir $@-t.dir $@-shrunk.dir + rm -fr $@d t-$@d shrunk-$@d + mkdir $@d t-$@d shrunk-$@d case $@ in \ - *_right) leap='-L leapseconds';; \ + *right*) leap='-L leapseconds';; \ *) leap=;; \ esac && \ - $(ZIC) $$leap -d $@.dir $(DATAFORM).zi && \ - $(ZIC) $$leap -d $@-shrunk.dir tzdata.zi && \ + $(ZIC) $$leap -d $@d $(DATAFORM).zi && \ + $(ZIC) $$leap -d shrunk-$@d tzdata.zi && \ case $(DATAFORM),$(PACKRATLIST) in \ main,) \ - $(ZIC) $$leap -d $@-t.dir $(TDATA) && \ + $(ZIC) $$leap -d t-$@d $(TDATA) && \ $(AWK) '/^Rule/' $(TDATA) | \ - $(ZIC) $$leap -d $@-t.dir - $(PACKRATDATA) && \ - diff -r $@.dir $@-t.dir;; \ + $(ZIC) $$leap -d t-$@d - $(PACKRATDATA) && \ + diff -r $@d t-$@d;; \ esac - diff -r $@.dir $@-shrunk.dir - rm -fr $@.dir $@-t.dir $@-shrunk.dir + diff -r $@d shrunk-$@d + rm -fr $@d t-$@d shrunk-$@d touch $@ clean_misc: - rm -fr check_*.dir typecheck_*.dir - rm -f *.o *.out $(TIME_T_ALTERNATIVES) \ - check_* core typecheck_* \ + rm -fr *.ckd *.dir + rm -f *.ck *.core *.o *.out core core.* \ date tzdir.h tzselect version.h zdump zic libtz.a clean: clean_misc - rm -fr *.dir tzdb-*/ + rm -fr tzdb-*/ rm -f *.zi $(TZS_NEW) maintainer-clean: clean @@ -1027,7 +1043,7 @@ maintainer-clean: clean names: @echo $(ENCHILADA) -public: check check_public $(CHECK_TIME_T_ALTERNATIVES) \ +public: check public.ck $(CHECK_TIME_T_ALTERNATIVES) \ tarballs signatures date.1.txt: date.1 @@ -1041,7 +1057,7 @@ zdump.8.txt: zdump.8 zic.8.txt: zic.8 $(MANTXTS): workman.sh - LC_ALL=C sh workman.sh `expr $@ : '\(.*\)\.txt$$'` >$@.out + LC_ALL=C sh workman.sh $(@:.txt=) >$@.out mv $@.out $@ # Set file timestamps deterministically if possible, @@ -1054,13 +1070,13 @@ SET_TIMESTAMP_N = sh -c '\ n=$$0 dest=$$1; shift; \ <"$$dest" && \ if test $$n != 0 && \ - lsout=`ls -nt --time-style="+%s" "$$@" 2>/dev/null`; then \ + lsout=$$(ls -nt --time-style="+%s" "$$@" 2>/dev/null); then \ set x $$lsout && \ - timestamp=`expr $$7 + $$n` && \ + timestamp=$$(($$7 + $$n)) && \ echo "+ touch -md @$$timestamp $$dest" && \ touch -md @$$timestamp "$$dest"; \ else \ - newest=`ls -t "$$@" | sed 1q` && \ + newest=$$(ls -t "$$@" | sed 1q) && \ echo "+ touch -mr $$newest $$dest" && \ touch -mr "$$newest" "$$dest"; \ fi' @@ -1083,15 +1099,15 @@ SET_TIMESTAMP_DEP = $(SET_TIMESTAMP_N) 1 set-timestamps.out: $(EIGHT_YARDS) rm -f $@ if (type git) >/dev/null 2>&1 && \ - files=`git ls-files $(EIGHT_YARDS)` && \ + files=$$(git ls-files $(EIGHT_YARDS)) && \ touch -md @1 test.out; then \ rm -f test.out && \ for file in $$files; do \ if git diff --quiet $$file; then \ - time=`TZ=UTC0 git log -1 \ + time=$$(TZ=UTC0 git log -1 \ --format='tformat:%cd' \ --date='format:%Y-%m-%dT%H:%M:%SZ' \ - $$file` && \ + $$file) && \ echo "+ touch -md $$time $$file" && \ touch -md $$time $$file; \ else \ @@ -1100,8 +1116,8 @@ set-timestamps.out: $(EIGHT_YARDS) done; \ fi $(SET_TIMESTAMP_DEP) leapseconds $(LEAP_DEPS) - for file in `ls $(MANTXTS) | sed 's/\.txt$$//'`; do \ - $(SET_TIMESTAMP_DEP) $$file.txt $$file workman.sh || \ + for file in $(MANTXTS); do \ + $(SET_TIMESTAMP_DEP) $$file $${file%.txt} workman.sh || \ exit; \ done $(SET_TIMESTAMP_DEP) version $(VERSION_DEPS) @@ -1114,30 +1130,29 @@ set-tzs-timestamp.out: $(TZS) # The zics below ensure that each data file can stand on its own. # We also do an all-files run to catch links to links. -check_public: $(VERSION_DEPS) - rm -fr public.dir - mkdir public.dir - ln $(VERSION_DEPS) public.dir - cd public.dir \ +public.ck: $(VERSION_DEPS) + rm -fr $@d + mkdir $@d + ln $(VERSION_DEPS) $@d + cd $@d \ && $(MAKE) CFLAGS='$(GCC_DEBUG_FLAGS)' TZDIR='$(TZDIR)' ALL - for i in $(TDATA_TO_CHECK) public.dir/tzdata.zi \ - public.dir/vanguard.zi public.dir/main.zi \ - public.dir/rearguard.zi; \ + for i in $(TDATA_TO_CHECK) \ + tzdata.zi vanguard.zi main.zi rearguard.zi; \ do \ - public.dir/zic -v -d public.dir/zoneinfo $$i 2>&1 || exit; \ + $@d/zic -v -d $@d/zoneinfo $@d/$$i || exit; \ done - public.dir/zic -v -d public.dir/zoneinfo-all $(TDATA_TO_CHECK) + $@d/zic -v -d $@d/zoneinfo-all $(TDATA_TO_CHECK) : : Also check 'backzone' syntax. - rm public.dir/main.zi - cd public.dir && $(MAKE) PACKRATDATA=backzone main.zi - public.dir/zic -d public.dir/zoneinfo main.zi - rm public.dir/main.zi - cd public.dir && \ + rm $@d/main.zi + cd $@d && $(MAKE) PACKRATDATA=backzone main.zi + $@d/zic -d $@d/zoneinfo main.zi + rm $@d/main.zi + cd $@d && \ $(MAKE) PACKRATDATA=backzone PACKRATLIST=zone.tab main.zi - public.dir/zic -d public.dir/zoneinfo main.zi + $@d/zic -d $@d/zoneinfo main.zi : - rm -fr public.dir + rm -fr $@d touch $@ # Check that the code works under various alternative @@ -1145,46 +1160,47 @@ check_public: $(VERSION_DEPS) check_time_t_alternatives: $(TIME_T_ALTERNATIVES) $(TIME_T_ALTERNATIVES_TAIL): $(TIME_T_ALTERNATIVES_HEAD) $(TIME_T_ALTERNATIVES): $(VERSION_DEPS) - rm -fr $@.dir - mkdir $@.dir - ln $(VERSION_DEPS) $@.dir + rm -fr $@d + mkdir $@d + ln $(VERSION_DEPS) $@d case $@ in \ - int*32_t) range=-2147483648,2147483648;; \ + *32_t*) range=-2147483648,2147483648;; \ u*) range=0,4294967296;; \ *) range=-4294967296,4294967296;; \ esac && \ - wd=`pwd` && \ - zones=`$(AWK) '/^[^#]/ { print $$3 }' /dev/null; then \ quiet_option='-q'; \ else \ quiet_option=''; \ fi && \ - diff $$quiet_option -r $(TIME_T_ALTERNATIVES_HEAD).dir/etc \ - $@.dir/etc && \ + diff $$quiet_option -r $(TIME_T_ALTERNATIVES_HEAD)d/etc \ + $@d/etc && \ diff $$quiet_option -r \ - $(TIME_T_ALTERNATIVES_HEAD).dir/usr/share \ - $@.dir/usr/share; \ + $(TIME_T_ALTERNATIVES_HEAD)d/usr/share \ + $@d/usr/share; \ } touch $@ @@ -1199,7 +1215,7 @@ ALL_ASC = $(TRADITIONAL_ASC) $(REARGUARD_ASC) \ tarballs rearguard_tarballs tailored_tarballs traditional_tarballs \ signatures rearguard_signatures traditional_signatures: \ version set-timestamps.out rearguard.zi vanguard.zi - VERSION=`cat version` && \ + read -r VERSION $@.out mv $@.out $@ tzdata$(VERSION).tar.gz: set-timestamps.out - LC_ALL=C && export LC_ALL && \ - tar $(TARFLAGS) -cf - $(TZDATA_DIST) | \ + $(SETUP_TAR) && \ + $$TAR -cf - $(TZDATA_DIST) | \ gzip $(GZIPFLAGS) >$@.out mv $@.out $@ @@ -1251,9 +1267,9 @@ tzdata$(VERSION)-rearguard.tar.gz: rearguard.zi set-timestamps.out : The dummy pacificnew pacifies TZUpdater 2.3.1 and earlier. $(CREATE_EMPTY) $@.dir/pacificnew touch -mr version $@.dir/version - LC_ALL=C && export LC_ALL && \ + $(SETUP_TAR) && \ (cd $@.dir && \ - tar $(TARFLAGS) -cf - \ + $$TAR -cf - \ $(TZDATA_DIST) pacificnew | \ gzip $(GZIPFLAGS)) >$@.out mv $@.out $@ @@ -1269,9 +1285,14 @@ tzdata$(VERSION)-tailored.tar.gz: set-timestamps.out rm -fr $@.dir mkdir $@.dir : The dummy pacificnew pacifies TZUpdater 2.3.1 and earlier. + if test $(DATAFORM) = vanguard; then \ + pacificnew=; \ + else \ + pacificnew=pacificnew; \ + fi && \ cd $@.dir && \ $(CREATE_EMPTY) $(PRIMARY_YDATA) $(NDATA) backward \ - `test $(DATAFORM) = vanguard || echo pacificnew` + $$pacificnew (grep '^#' tzdata.zi && echo && cat $(DATAFORM).zi) \ >$@.dir/etcetera touch -mr tzdata.zi $@.dir/etcetera @@ -1291,9 +1312,9 @@ tzdata$(VERSION)-tailored.tar.gz: set-timestamps.out test -f $@.dir/$$file || links="$$links $$file"; \ done && \ ln $$links $@.dir - LC_ALL=C && export LC_ALL && \ + $(SETUP_TAR) && \ (cd $@.dir && \ - tar $(TARFLAGS) -cf - * | gzip $(GZIPFLAGS)) >$@.out + $$TAR -cf - * | gzip $(GZIPFLAGS)) >$@.out mv $@.out $@ tzdb-$(VERSION).tar.lz: set-timestamps.out set-tzs-timestamp.out @@ -1301,8 +1322,8 @@ tzdb-$(VERSION).tar.lz: set-timestamps.out set-tzs-timestamp.out mkdir tzdb-$(VERSION) ln $(ENCHILADA) tzdb-$(VERSION) $(SET_TIMESTAMP) tzdb-$(VERSION) tzdb-$(VERSION)/* - LC_ALL=C && export LC_ALL && \ - tar $(TARFLAGS) -cf - tzdb-$(VERSION) | lzip -9 >$@.out + $(SETUP_TAR) && \ + $$TAR -cf - tzdb-$(VERSION) | lzip -9 >$@.out mv $@.out $@ tzcode$(VERSION).tar.gz.asc: tzcode$(VERSION).tar.gz @@ -1313,22 +1334,21 @@ $(ALL_ASC): $(GPG) --armor --detach-sign $? TYPECHECK_CFLAGS = $(CFLAGS) -DTYPECHECK -D__time_t_defined -D_TIME_T -typecheck: typecheck_long_long typecheck_unsigned -typecheck_long_long typecheck_unsigned: $(VERSION_DEPS) - rm -fr $@.dir - mkdir $@.dir - ln $(VERSION_DEPS) $@.dir - cd $@.dir && \ +typecheck: long-long.ck unsigned.ck +long-long.ck unsigned.ck: $(VERSION_DEPS) + rm -fr $@d + mkdir $@d + ln $(VERSION_DEPS) $@d + cd $@d && \ case $@ in \ - *_long_long) i="long long";; \ - *_unsigned ) i="unsigned" ;; \ + long-long.*) i="long long";; \ + unsigned.* ) i="unsigned" ;; \ esac && \ - typecheck_cflags='' && \ $(MAKE) \ CFLAGS="$(TYPECHECK_CFLAGS) \"-Dtime_t=$$i\"" \ - TOPDIR="`pwd`" \ + TOPDIR="$$PWD" \ install - $@.dir/zdump -i -c 1970,1971 Europe/Rome + $@d/zdump -i -c 1970,1971 Europe/Rome touch $@ zonenames: tzdata.zi @@ -1347,7 +1367,7 @@ zic.o: private.h tzfile.h tzdir.h version.h .PHONY: check_web check_zishrink .PHONY: clean clean_misc commit-leap-seconds.list dummy.zd .PHONY: fetch-leap-seconds.list force_tzs -.PHONY: install install_data maintainer-clean names +.PHONY: install maintainer-clean names .PHONY: posix_only posix_right public .PHONY: rearguard_signatures rearguard_signatures_version .PHONY: rearguard_tarballs rearguard_tarballs_version diff --git a/NEWS b/NEWS index d407342a50e6..83b8b8c8d39c 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,125 @@ News for the tz database +Release 2024b - 2024-09-04 12:27:47 -0700 + + Briefly: + Improve historical data for Mexico, Mongolia, and Portugal. + System V names are now obsolescent. + The main data form now uses %z. + The code now conforms to RFC 8536 for early timestamps. + Support POSIX.1-2024, which removes asctime_r and ctime_r. + Assume POSIX.2-1992 or later for shell scripts. + SUPPORT_C89 now defaults to 1. + + Changes to past timestamps + + Asia/Choibalsan is now an alias for Asia/Ulaanbaatar rather than + being a separate Zone with differing behavior before April 2008. + This seems better given our wildly conflicting information about + Mongolia's time zone history. (Thanks to Heitor David Pinto.) + + Historical transitions for Mexico have been updated based on + official Mexican decrees. The affected timestamps occur during + the years 1921-1927, 1931, 1945, 1949-1970, and 1981-1997. + The affected zones are America/Bahia_Banderas, America/Cancun, + America/Chihuahua, America/Ciudad_Juarez, America/Hermosillo, + America/Mazatlan, America/Merida, America/Mexico_City, + America/Monterrey, America/Ojinaga, and America/Tijuana. + (Thanks to Heitor David Pinto.) + + Historical transitions for Portugal, represented by Europe/Lisbon, + Atlantic/Azores, and Atlantic/Madeira, have been updated based on a + close reading of old Portuguese legislation, replacing previous data + mainly originating from Whitman and Shanks & Pottenger. These + changes affect a few transitions in 1917-1921, 1924, and 1940 + throughout these regions by a few hours or days, and various + timestamps between 1977 and 1993 depending on the region. In + particular, the Azores and Madeira did not observe DST from 1977 to + 1981. Additionally, the adoption of standard zonal time in former + Portuguese colonies have been adjusted: Africa/Maputo in 1909, and + Asia/Dili by 22 minutes at the start of 1912. + (Thanks to Tim Parenti.) + + Changes to past tm_isdst flags + + The period from 1966-04-03 through 1966-10-02 in Portugal is now + modeled as DST, to more closely reflect how contemporaneous changes + in law entered into force. + + Changes to data + + Names present only for compatibility with UNIX System V + (last released in the 1990s) have been moved to 'backward'. + These names, which for post-1970 timestamps mostly just duplicate + data of geographical names, were confusing downstream uses. + Names moved to 'backward' are now links to geographical names. + This affects behavior for TZ='EET' for some pre-1981 timestamps, + for TZ='CET' for some pre-1947 timestamps, and for TZ='WET' for + some pre-1996 timestamps. Also, TZ='MET' now behaves like + TZ='CET' and so uses the abbreviation "CET" rather than "MET". + Those needing the previous TZDB behavior, which does not match any + real-world clocks, can find the old entries in 'backzone'. + (Problem reported by Justin Grant.) + + The main source files' time zone abbreviations now use %z, + supported by zic since release 2015f and used in vanguard form + since release 2022b. For example, America/Sao_Paulo now contains + the zone continuation line "-3:00 Brazil %z", which is less error + prone than the old "-3:00 Brazil -03/-02". This does not change + the represented data: the generated TZif files are unchanged. + Rearguard form still avoids %z, to support obsolescent parsers. + + Asia/Almaty has been removed from zonenow.tab as it now agrees + with Asia/Tashkent for future timestamps, due to Kazakhstan's + 2024-02-29 time zone change. Similarly, America/Scoresbysund + has been removed, as it now agrees with America/Nuuk due to + its 2024-03-31 time zone change. + + Changes to code + + localtime.c now always uses a TZif file's time type 0 to handle + timestamps before the file's first transition. Formerly, + localtime.c sometimes inferred a different time type, in order to + handle problematic data generated by zic 2018e or earlier. As it + is now safe to assume more recent versions of zic, there is no + longer a pressing need to fail to conform RFC 8536 section 3.2, + which requires using time type 0 in this situation. This change + does not affect behavior when reading TZif files generated by zic + 2018f and later. + + POSIX.1-2024 removes asctime_r and ctime_r and does not let + libraries define them, so remove them except when needed to + conform to earlier POSIX. These functions are dangerous as they + can overrun user buffers. If you still need them, add + -DSUPPORT_POSIX2008 to CFLAGS. + + The SUPPORT_C89 option now defaults to 1 instead of 0, fixing a + POSIX-conformance bug introduced in 2023a. + + tzselect now supports POSIX.1-2024 proleptic TZ strings. Also, it + assumes POSIX.2-1992 or later, as practical porting targets now + all support that, and it uses some features from POSIX.1-2024 if + available. + + Changes to build procedure + + 'make check' no longer requires curl and Internet access. + + The build procedure now assumes POSIX.2-1992 or later, to simplify + maintenance. To build on Solaris 10, the only extant system still + defaulting to pre-POSIX, prepend /usr/xpg4/bin to PATH. + + Changes to documentation + + The documentation now reflects POSIX.1-2024. + + Changes to commentary + + Commentary about historical transitions in Portugal and her former + colonies has been expanded with links to many relevant legislation. + (Thanks to Tim Parenti.) + + Release 2024a - 2024-02-01 09:28:56 -0800 Briefly: @@ -161,7 +281,7 @@ Release 2023d - 2023-12-21 20:02:24 -0800 * It uses the special .POSIX target. * It quotes special characters more carefully. * It no longer mishandles builds in an ISO 8859 locale. - Due to the CC changes, TZDIR is now #defined in a file tzfile.h + Due to the CC changes, TZDIR is now #defined in a file tzdir.h built by 'make', not in a $(CC) -D option. Also, TZDEFAULT is now treated like TZDIR as they have similar roles. @@ -283,7 +403,7 @@ Release 2023a - 2023-03-22 12:39:33 -0700 To improve tzselect diagnostics, zone1970.tab's comments column is now limited to countries that have multiple timezones. - Note that leap seconds are planned to be discontinued by 2035. + Note that there are plans to discontinue leap seconds by 2035. Release 2022g - 2022-11-29 08:58:31 -0800 diff --git a/africa b/africa index 92d823a0515c..fd6c44aaa5b7 100644 --- a/africa +++ b/africa @@ -103,17 +103,16 @@ Zone Africa/Algiers 0:12:12 - LMT 1891 Mar 16 # Cape Verde / Cabo Verde # -# From Paul Eggert (2018-02-16): -# Shanks gives 1907 for the transition to +02. -# For now, ignore that and follow the 1911-05-26 Portuguese decree -# (see Europe/Lisbon). +# From Tim Parenti (2024-07-01), per Paul Eggert (2018-02-16): +# For timestamps before independence, see commentary for Europe/Lisbon. +# Shanks gives 1907 instead for the transition to -02. # # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone Atlantic/Cape_Verde -1:34:04 - LMT 1912 Jan 01 2:00u # Praia - -2:00 - -02 1942 Sep - -2:00 1:00 -01 1945 Oct 15 - -2:00 - -02 1975 Nov 25 2:00 - -1:00 - -01 + -2:00 - %z 1942 Sep + -2:00 1:00 %z 1945 Oct 15 + -2:00 - %z 1975 Nov 25 2:00 + -1:00 - %z # Chad # Zone NAME STDOFF RULES FORMAT [UNTIL] @@ -345,14 +344,12 @@ Zone Africa/Cairo 2:05:09 - LMT 1900 Oct # Guinea-Bissau # -# From Paul Eggert (2018-02-16): -# Shanks gives 1911-05-26 for the transition to WAT, -# evidently confusing the date of the Portuguese decree -# (see Europe/Lisbon) with the date that it took effect. +# From Tim Parenti (2024-07-01), per Paul Eggert (2018-02-16): +# For timestamps before independence, see commentary for Europe/Lisbon. # # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone Africa/Bissau -1:02:20 - LMT 1912 Jan 1 1:00u - -1:00 - -01 1975 + -1:00 - %z 1975 0:00 - GMT # Comoros @@ -417,10 +414,10 @@ Zone Africa/Bissau -1:02:20 - LMT 1912 Jan 1 1:00u # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone Africa/Nairobi 2:27:16 - LMT 1908 May - 2:30 - +0230 1928 Jun 30 24:00 + 2:30 - %z 1928 Jun 30 24:00 3:00 - EAT 1930 Jan 4 24:00 - 2:30 - +0230 1936 Dec 31 24:00 - 2:45 - +0245 1942 Jul 31 24:00 + 2:30 - %z 1936 Dec 31 24:00 + 2:45 - %z 1942 Jul 31 24:00 3:00 - EAT # Liberia @@ -591,7 +588,7 @@ Rule Mauritius 2008 only - Oct lastSun 2:00 1:00 - Rule Mauritius 2009 only - Mar lastSun 2:00 0 - # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone Indian/Mauritius 3:50:00 - LMT 1907 # Port Louis - 4:00 Mauritius +04/+05 + 4:00 Mauritius %z # Agalega Is, Rodriguez # no information; probably like Indian/Mauritius @@ -1071,10 +1068,10 @@ Rule Morocco 2087 only - May 11 2:00 0 - # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone Africa/Casablanca -0:30:20 - LMT 1913 Oct 26 - 0:00 Morocco +00/+01 1984 Mar 16 - 1:00 - +01 1986 - 0:00 Morocco +00/+01 2018 Oct 28 3:00 - 1:00 Morocco +01/+00 + 0:00 Morocco %z 1984 Mar 16 + 1:00 - %z 1986 + 0:00 Morocco %z 2018 Oct 28 3:00 + 1:00 Morocco %z # Western Sahara # @@ -1088,9 +1085,9 @@ Zone Africa/Casablanca -0:30:20 - LMT 1913 Oct 26 # since most of it was then controlled by Morocco. Zone Africa/El_Aaiun -0:52:48 - LMT 1934 Jan # El Aaiún - -1:00 - -01 1976 Apr 14 - 0:00 Morocco +00/+01 2018 Oct 28 3:00 - 1:00 Morocco +01/+00 + -1:00 - %z 1976 Apr 14 + 0:00 Morocco %z 2018 Oct 28 3:00 + 1:00 Morocco %z # Botswana # Burundi @@ -1101,13 +1098,27 @@ Zone Africa/El_Aaiun -0:52:48 - LMT 1934 Jan # El Aaiún # Zambia # Zimbabwe # -# Shanks gives 1903-03-01 for the transition to CAT. -# Perhaps the 1911-05-26 Portuguese decree -# https://dre.pt/pdf1sdip/1911/05/12500/23132313.pdf -# merely made it official? +# From Tim Parenti (2024-07-01): +# For timestamps before Mozambique's independence, see commentary for +# Europe/Lisbon. +# +# From Paul Eggert (2024-05-24): +# The London Gazette, 1903-04-03, page 2245, says that +# as of 1903-03-03 a time ball at the port of Lourenço Marques +# (as Maputo was then called) was dropped daily at 13:00:00 LMT, +# corresponding to 22:49:41.7 GMT, so local time was +02:10:18.3. +# Conversely, the newspaper South Africa, 1909-02-09, page 321, +# says the port had just installed an apparatus that communicated +# "from the controlling clock in the new Observatory at Reuben Point ... +# exact mean South African time, i.e., 30 deg., or 2 hours East of Greenwich". +# Although Shanks gives 1903-03-01 for the transition to CAT, +# evidently the port transitioned to CAT after 1903-03-03 but before +# the Portuguese legal transition of 1912-01-01 (see Europe/Lisbon commentary). +# For lack of better info, list 1909 as the transition date. # # Zone NAME STDOFF RULES FORMAT [UNTIL] -Zone Africa/Maputo 2:10:20 - LMT 1903 Mar + #STDOFF 2:10:18.3 +Zone Africa/Maputo 2:10:18 - LMT 1909 2:00 - CAT # Namibia @@ -1172,7 +1183,7 @@ Rule Namibia 1995 2017 - Apr Sun>=1 2:00 -1:00 WAT # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone Africa/Windhoek 1:08:24 - LMT 1892 Feb 8 - 1:30 - +0130 1903 Mar + 1:30 - %z 1903 Mar 2:00 - SAST 1942 Sep 20 2:00 2:00 1:00 SAST 1943 Mar 21 2:00 2:00 - SAST 1990 Mar 21 # independence @@ -1260,7 +1271,7 @@ Zone Africa/Windhoek 1:08:24 - LMT 1892 Feb 8 Zone Africa/Lagos 0:13:35 - LMT 1905 Jul 1 0:00 - GMT 1908 Jul 1 0:13:35 - LMT 1914 Jan 1 - 0:30 - +0030 1919 Sep 1 + 0:30 - %z 1919 Sep 1 1:00 - WAT # São Tomé and Príncipe diff --git a/antarctica b/antarctica index 763c27253c99..8d5d6cd1cdd0 100644 --- a/antarctica +++ b/antarctica @@ -87,34 +87,34 @@ # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone Antarctica/Casey 0 - -00 1969 - 8:00 - +08 2009 Oct 18 2:00 - 11:00 - +11 2010 Mar 5 2:00 - 8:00 - +08 2011 Oct 28 2:00 - 11:00 - +11 2012 Feb 21 17:00u - 8:00 - +08 2016 Oct 22 - 11:00 - +11 2018 Mar 11 4:00 - 8:00 - +08 2018 Oct 7 4:00 - 11:00 - +11 2019 Mar 17 3:00 - 8:00 - +08 2019 Oct 4 3:00 - 11:00 - +11 2020 Mar 8 3:00 - 8:00 - +08 2020 Oct 4 0:01 - 11:00 - +11 2021 Mar 14 0:00 - 8:00 - +08 2021 Oct 3 0:01 - 11:00 - +11 2022 Mar 13 0:00 - 8:00 - +08 2022 Oct 2 0:01 - 11:00 - +11 2023 Mar 9 3:00 - 8:00 - +08 + 8:00 - %z 2009 Oct 18 2:00 + 11:00 - %z 2010 Mar 5 2:00 + 8:00 - %z 2011 Oct 28 2:00 + 11:00 - %z 2012 Feb 21 17:00u + 8:00 - %z 2016 Oct 22 + 11:00 - %z 2018 Mar 11 4:00 + 8:00 - %z 2018 Oct 7 4:00 + 11:00 - %z 2019 Mar 17 3:00 + 8:00 - %z 2019 Oct 4 3:00 + 11:00 - %z 2020 Mar 8 3:00 + 8:00 - %z 2020 Oct 4 0:01 + 11:00 - %z 2021 Mar 14 0:00 + 8:00 - %z 2021 Oct 3 0:01 + 11:00 - %z 2022 Mar 13 0:00 + 8:00 - %z 2022 Oct 2 0:01 + 11:00 - %z 2023 Mar 9 3:00 + 8:00 - %z Zone Antarctica/Davis 0 - -00 1957 Jan 13 - 7:00 - +07 1964 Nov + 7:00 - %z 1964 Nov 0 - -00 1969 Feb - 7:00 - +07 2009 Oct 18 2:00 - 5:00 - +05 2010 Mar 10 20:00u - 7:00 - +07 2011 Oct 28 2:00 - 5:00 - +05 2012 Feb 21 20:00u - 7:00 - +07 + 7:00 - %z 2009 Oct 18 2:00 + 5:00 - %z 2010 Mar 10 20:00u + 7:00 - %z 2011 Oct 28 2:00 + 5:00 - %z 2012 Feb 21 20:00u + 7:00 - %z Zone Antarctica/Mawson 0 - -00 1954 Feb 13 - 6:00 - +06 2009 Oct 18 2:00 - 5:00 - +05 + 6:00 - %z 2009 Oct 18 2:00 + 5:00 - %z # References: # Casey Weather (1998-02-26) # http://www.antdiv.gov.au/aad/exop/sfo/casey/casey_aws.html @@ -290,10 +290,10 @@ Zone Antarctica/Troll 0 - -00 2005 Feb 12 # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone Antarctica/Vostok 0 - -00 1957 Dec 16 - 7:00 - +07 1994 Feb + 7:00 - %z 1994 Feb 0 - -00 1994 Nov - 7:00 - +07 2023 Dec 18 2:00 - 5:00 - +05 + 7:00 - %z 2023 Dec 18 2:00 + 5:00 - %z # S Africa - year-round bases # Marion Island, -4653+03752 @@ -326,7 +326,7 @@ Zone Antarctica/Vostok 0 - -00 1957 Dec 16 # # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone Antarctica/Rothera 0 - -00 1976 Dec 1 - -3:00 - -03 + -3:00 - %z # Uruguay - year round base # Artigas, King George Island, -621104-0585107 diff --git a/asia b/asia index 05683b9ebaa3..a2480b021225 100644 --- a/asia +++ b/asia @@ -83,8 +83,8 @@ Rule RussiaAsia 1996 2010 - Oct lastSun 2:00s 0 - # Afghanistan # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone Asia/Kabul 4:36:48 - LMT 1890 - 4:00 - +04 1945 - 4:30 - +0430 + 4:00 - %z 1945 + 4:30 - %z # Armenia # From Paul Eggert (2006-03-22): @@ -116,12 +116,12 @@ Rule Armenia 2011 only - Mar lastSun 2:00s 1:00 - Rule Armenia 2011 only - Oct lastSun 2:00s 0 - # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone Asia/Yerevan 2:58:00 - LMT 1924 May 2 - 3:00 - +03 1957 Mar - 4:00 RussiaAsia +04/+05 1991 Mar 31 2:00s - 3:00 RussiaAsia +03/+04 1995 Sep 24 2:00s - 4:00 - +04 1997 - 4:00 RussiaAsia +04/+05 2011 - 4:00 Armenia +04/+05 + 3:00 - %z 1957 Mar + 4:00 RussiaAsia %z 1991 Mar 31 2:00s + 3:00 RussiaAsia %z 1995 Sep 24 2:00s + 4:00 - %z 1997 + 4:00 RussiaAsia %z 2011 + 4:00 Armenia %z # Azerbaijan @@ -142,12 +142,12 @@ Rule Azer 1997 2015 - Mar lastSun 4:00 1:00 - Rule Azer 1997 2015 - Oct lastSun 5:00 0 - # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone Asia/Baku 3:19:24 - LMT 1924 May 2 - 3:00 - +03 1957 Mar - 4:00 RussiaAsia +04/+05 1991 Mar 31 2:00s - 3:00 RussiaAsia +03/+04 1992 Sep lastSun 2:00s - 4:00 - +04 1996 - 4:00 EUAsia +04/+05 1997 - 4:00 Azer +04/+05 + 3:00 - %z 1957 Mar + 4:00 RussiaAsia %z 1991 Mar 31 2:00s + 3:00 RussiaAsia %z 1992 Sep lastSun 2:00s + 4:00 - %z 1996 + 4:00 EUAsia %z 1997 + 4:00 Azer %z # Bangladesh # From Alexander Krivenyshev (2009-05-13): @@ -228,17 +228,17 @@ Rule Dhaka 2009 only - Dec 31 24:00 0 - # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone Asia/Dhaka 6:01:40 - LMT 1890 5:53:20 - HMT 1941 Oct # Howrah Mean Time? - 6:30 - +0630 1942 May 15 - 5:30 - +0530 1942 Sep - 6:30 - +0630 1951 Sep 30 - 6:00 - +06 2009 - 6:00 Dhaka +06/+07 + 6:30 - %z 1942 May 15 + 5:30 - %z 1942 Sep + 6:30 - %z 1951 Sep 30 + 6:00 - %z 2009 + 6:00 Dhaka %z # Bhutan # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone Asia/Thimphu 5:58:36 - LMT 1947 Aug 15 # or Thimbu - 5:30 - +0530 1987 Oct - 6:00 - +06 + 5:30 - %z 1987 Oct + 6:00 - %z # British Indian Ocean Territory # Whitman and the 1995 CIA time zone map say 5:00, but the @@ -248,8 +248,8 @@ Zone Asia/Thimphu 5:58:36 - LMT 1947 Aug 15 # or Thimbu # then contained the Chagos Archipelago). # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone Indian/Chagos 4:49:40 - LMT 1907 - 5:00 - +05 1996 - 6:00 - +06 + 5:00 - %z 1996 + 6:00 - %z # Cocos (Keeling) Islands # Myanmar (Burma) @@ -265,9 +265,9 @@ Zone Indian/Chagos 4:49:40 - LMT 1907 # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone Asia/Yangon 6:24:47 - LMT 1880 # or Rangoon 6:24:47 - RMT 1920 # Rangoon local time - 6:30 - +0630 1942 May - 9:00 - +09 1945 May 3 - 6:30 - +0630 + 6:30 - %z 1942 May + 9:00 - %z 1945 May 3 + 6:30 - %z # China @@ -656,7 +656,7 @@ Zone Asia/Shanghai 8:05:43 - LMT 1901 # Xinjiang time, used by many in western China; represented by Ürümqi / Ürümchi # / Wulumuqi. (Please use Asia/Shanghai if you prefer Beijing time.) Zone Asia/Urumqi 5:50:20 - LMT 1928 - 6:00 - +06 + 6:00 - %z # Hong Kong @@ -1114,7 +1114,7 @@ Rule Macau 1979 only - Oct Sun>=16 03:30 0 S # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone Asia/Macau 7:34:10 - LMT 1904 Oct 30 8:00 - CST 1941 Dec 21 23:00 - 9:00 Macau +09/+10 1945 Sep 30 24:00 + 9:00 Macau %z 1945 Sep 30 24:00 8:00 Macau C%sT @@ -1157,7 +1157,7 @@ Zone Asia/Nicosia 2:13:28 - LMT 1921 Nov 14 Zone Asia/Famagusta 2:15:48 - LMT 1921 Nov 14 2:00 Cyprus EE%sT 1998 Sep 2:00 EUAsia EE%sT 2016 Sep 8 - 3:00 - +03 2017 Oct 29 1:00u + 3:00 - %z 2017 Oct 29 1:00u 2:00 EUAsia EE%sT # Georgia @@ -1198,18 +1198,25 @@ Zone Asia/Famagusta 2:15:48 - LMT 1921 Nov 14 # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone Asia/Tbilisi 2:59:11 - LMT 1880 2:59:11 - TBMT 1924 May 2 # Tbilisi Mean Time - 3:00 - +03 1957 Mar - 4:00 RussiaAsia +04/+05 1991 Mar 31 2:00s - 3:00 RussiaAsia +03/+04 1992 - 3:00 E-EurAsia +03/+04 1994 Sep lastSun - 4:00 E-EurAsia +04/+05 1996 Oct lastSun - 4:00 1:00 +05 1997 Mar lastSun - 4:00 E-EurAsia +04/+05 2004 Jun 27 - 3:00 RussiaAsia +03/+04 2005 Mar lastSun 2:00 - 4:00 - +04 + 3:00 - %z 1957 Mar + 4:00 RussiaAsia %z 1991 Mar 31 2:00s + 3:00 RussiaAsia %z 1992 + 3:00 E-EurAsia %z 1994 Sep lastSun + 4:00 E-EurAsia %z 1996 Oct lastSun + 4:00 1:00 %z 1997 Mar lastSun + 4:00 E-EurAsia %z 2004 Jun 27 + 3:00 RussiaAsia %z 2005 Mar lastSun 2:00 + 4:00 - %z # East Timor +# From Tim Parenti (2024-07-01): +# The 1912-01-01 transition occurred at 00:00 new time, per the 1911-05-24 +# Portuguese decree (see Europe/Lisbon). A provision in article 5(c) of the +# decree prescribed that Timor "will keep counting time in harmony with +# neighboring foreign colonies, [for] as long as they do not adopt the time +# that belongs to them in [the Washington Convention] system." + # See Indonesia for the 1945 transition. # From João Carrascalão, brother of the former governor of East Timor, in @@ -1233,11 +1240,11 @@ Zone Asia/Tbilisi 2:59:11 - LMT 1880 # midnight on Saturday, September 16. # Zone NAME STDOFF RULES FORMAT [UNTIL] -Zone Asia/Dili 8:22:20 - LMT 1912 Jan 1 - 8:00 - +08 1942 Feb 21 23:00 - 9:00 - +09 1976 May 3 - 8:00 - +08 2000 Sep 17 0:00 - 9:00 - +09 +Zone Asia/Dili 8:22:20 - LMT 1911 Dec 31 16:00u + 8:00 - %z 1942 Feb 21 23:00 + 9:00 - %z 1976 May 3 + 8:00 - %z 2000 Sep 17 0:00 + 9:00 - %z # India @@ -1303,9 +1310,9 @@ Zone Asia/Kolkata 5:53:28 - LMT 1854 Jun 28 # Kolkata 5:53:20 - HMT 1870 # Howrah Mean Time? 5:21:10 - MMT 1906 Jan 1 # Madras local time 5:30 - IST 1941 Oct - 5:30 1:00 +0630 1942 May 15 + 5:30 1:00 %z 1942 May 15 5:30 - IST 1942 Sep - 5:30 1:00 +0630 1945 Oct 15 + 5:30 1:00 %z 1945 Oct 15 5:30 - IST # Since 1970 the following are like Asia/Kolkata: # Andaman Is @@ -1357,33 +1364,33 @@ Zone Asia/Jakarta 7:07:12 - LMT 1867 Aug 10 # Shanks & Pottenger say the next transition was at 1924 Jan 1 0:13, # but this must be a typo. 7:07:12 - BMT 1923 Dec 31 16:40u # Batavia - 7:20 - +0720 1932 Nov - 7:30 - +0730 1942 Mar 23 - 9:00 - +09 1945 Sep 23 - 7:30 - +0730 1948 May - 8:00 - +08 1950 May - 7:30 - +0730 1964 + 7:20 - %z 1932 Nov + 7:30 - %z 1942 Mar 23 + 9:00 - %z 1945 Sep 23 + 7:30 - %z 1948 May + 8:00 - %z 1950 May + 7:30 - %z 1964 7:00 - WIB # west and central Borneo Zone Asia/Pontianak 7:17:20 - LMT 1908 May 7:17:20 - PMT 1932 Nov # Pontianak MT - 7:30 - +0730 1942 Jan 29 - 9:00 - +09 1945 Sep 23 - 7:30 - +0730 1948 May - 8:00 - +08 1950 May - 7:30 - +0730 1964 + 7:30 - %z 1942 Jan 29 + 9:00 - %z 1945 Sep 23 + 7:30 - %z 1948 May + 8:00 - %z 1950 May + 7:30 - %z 1964 8:00 - WITA 1988 Jan 1 7:00 - WIB # Sulawesi, Lesser Sundas, east and south Borneo Zone Asia/Makassar 7:57:36 - LMT 1920 7:57:36 - MMT 1932 Nov # Macassar MT - 8:00 - +08 1942 Feb 9 - 9:00 - +09 1945 Sep 23 + 8:00 - %z 1942 Feb 9 + 9:00 - %z 1945 Sep 23 8:00 - WITA # Maluku Islands, West Papua, Papua Zone Asia/Jayapura 9:22:48 - LMT 1932 Nov - 9:00 - +09 1944 Sep 1 - 9:30 - +0930 1964 + 9:00 - %z 1944 Sep 1 + 9:30 - %z 1964 9:00 - WIT # Iran @@ -1619,9 +1626,9 @@ Rule Iran 2021 2022 - Sep 21 24:00 0 - # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone Asia/Tehran 3:25:44 - LMT 1916 3:25:44 - TMT 1935 Jun 13 # Tehran Mean Time - 3:30 Iran +0330/+0430 1977 Oct 20 24:00 - 4:00 Iran +04/+05 1979 - 3:30 Iran +0330/+0430 + 3:30 Iran %z 1977 Oct 20 24:00 + 4:00 Iran %z 1979 + 3:30 Iran %z # Iraq @@ -1664,8 +1671,8 @@ Rule Iraq 1991 2007 - Oct 1 3:00s 0 - # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone Asia/Baghdad 2:57:40 - LMT 1890 2:57:36 - BMT 1918 # Baghdad Mean Time? - 3:00 - +03 1982 May - 3:00 Iraq +03/+04 + 3:00 - %z 1982 May + 3:00 Iraq %z ############################################################################### @@ -2262,7 +2269,7 @@ Rule Jordan 2022 only - Feb lastThu 24:00 1:00 S # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone Asia/Amman 2:23:44 - LMT 1931 2:00 Jordan EE%sT 2022 Oct 28 0:00s - 3:00 - +03 + 3:00 - %z # Kazakhstan @@ -2473,88 +2480,88 @@ Zone Asia/Amman 2:23:44 - LMT 1931 # Almaty (formerly Alma-Ata), representing most locations in Kazakhstan # This includes Abai/Abay (ISO 3166-2 code KZ-10), Aqmola/Akmola (KZ-11), # Almaty (KZ-19), Almaty city (KZ-75), Astana city (KZ-71), -# East Kazkhstan (KZ-63), Jambyl/Zhambyl (KZ-31), Jetisu/Zhetysu (KZ-33), +# East Kazakhstan (KZ-63), Jambyl/Zhambyl (KZ-31), Jetisu/Zhetysu (KZ-33), # Karaganda (KZ-35), North Kazakhstan (KZ-59), Pavlodar (KZ-55), -# Shyumkent city (KZ-79), Turkistan (KZ-61), and Ulytau (KZ-62). +# Shymkent city (KZ-79), Turkistan (KZ-61), and Ulytau (KZ-62). Zone Asia/Almaty 5:07:48 - LMT 1924 May 2 # or Alma-Ata - 5:00 - +05 1930 Jun 21 - 6:00 RussiaAsia +06/+07 1991 Mar 31 2:00s - 5:00 RussiaAsia +05/+06 1992 Jan 19 2:00s - 6:00 RussiaAsia +06/+07 2004 Oct 31 2:00s - 6:00 - +06 2024 Mar 1 0:00 - 5:00 - +05 + 5:00 - %z 1930 Jun 21 + 6:00 RussiaAsia %z 1991 Mar 31 2:00s + 5:00 RussiaAsia %z 1992 Jan 19 2:00s + 6:00 RussiaAsia %z 2004 Oct 31 2:00s + 6:00 - %z 2024 Mar 1 0:00 + 5:00 - %z # Qyzylorda (aka Kyzylorda, Kizilorda, Kzyl-Orda, etc.) (KZ-43) Zone Asia/Qyzylorda 4:21:52 - LMT 1924 May 2 - 4:00 - +04 1930 Jun 21 - 5:00 - +05 1981 Apr 1 - 5:00 1:00 +06 1981 Oct 1 - 6:00 - +06 1982 Apr 1 - 5:00 RussiaAsia +05/+06 1991 Mar 31 2:00s - 4:00 RussiaAsia +04/+05 1991 Sep 29 2:00s - 5:00 RussiaAsia +05/+06 1992 Jan 19 2:00s - 6:00 RussiaAsia +06/+07 1992 Mar 29 2:00s - 5:00 RussiaAsia +05/+06 2004 Oct 31 2:00s - 6:00 - +06 2018 Dec 21 0:00 - 5:00 - +05 + 4:00 - %z 1930 Jun 21 + 5:00 - %z 1981 Apr 1 + 5:00 1:00 %z 1981 Oct 1 + 6:00 - %z 1982 Apr 1 + 5:00 RussiaAsia %z 1991 Mar 31 2:00s + 4:00 RussiaAsia %z 1991 Sep 29 2:00s + 5:00 RussiaAsia %z 1992 Jan 19 2:00s + 6:00 RussiaAsia %z 1992 Mar 29 2:00s + 5:00 RussiaAsia %z 2004 Oct 31 2:00s + 6:00 - %z 2018 Dec 21 0:00 + 5:00 - %z # Qostanay (aka Kostanay, Kustanay) (KZ-39) # The 1991/2 rules are unclear partly because of the 1997 Turgai # reorganization. Zone Asia/Qostanay 4:14:28 - LMT 1924 May 2 - 4:00 - +04 1930 Jun 21 - 5:00 - +05 1981 Apr 1 - 5:00 1:00 +06 1981 Oct 1 - 6:00 - +06 1982 Apr 1 - 5:00 RussiaAsia +05/+06 1991 Mar 31 2:00s - 4:00 RussiaAsia +04/+05 1992 Jan 19 2:00s - 5:00 RussiaAsia +05/+06 2004 Oct 31 2:00s - 6:00 - +06 2024 Mar 1 0:00 - 5:00 - +05 + 4:00 - %z 1930 Jun 21 + 5:00 - %z 1981 Apr 1 + 5:00 1:00 %z 1981 Oct 1 + 6:00 - %z 1982 Apr 1 + 5:00 RussiaAsia %z 1991 Mar 31 2:00s + 4:00 RussiaAsia %z 1992 Jan 19 2:00s + 5:00 RussiaAsia %z 2004 Oct 31 2:00s + 6:00 - %z 2024 Mar 1 0:00 + 5:00 - %z # Aqtöbe (aka Aktobe, formerly Aktyubinsk) (KZ-15) Zone Asia/Aqtobe 3:48:40 - LMT 1924 May 2 - 4:00 - +04 1930 Jun 21 - 5:00 - +05 1981 Apr 1 - 5:00 1:00 +06 1981 Oct 1 - 6:00 - +06 1982 Apr 1 - 5:00 RussiaAsia +05/+06 1991 Mar 31 2:00s - 4:00 RussiaAsia +04/+05 1992 Jan 19 2:00s - 5:00 RussiaAsia +05/+06 2004 Oct 31 2:00s - 5:00 - +05 + 4:00 - %z 1930 Jun 21 + 5:00 - %z 1981 Apr 1 + 5:00 1:00 %z 1981 Oct 1 + 6:00 - %z 1982 Apr 1 + 5:00 RussiaAsia %z 1991 Mar 31 2:00s + 4:00 RussiaAsia %z 1992 Jan 19 2:00s + 5:00 RussiaAsia %z 2004 Oct 31 2:00s + 5:00 - %z # Mangghystaū (KZ-47) # Aqtau was not founded until 1963, but it represents an inhabited region, # so include timestamps before 1963. Zone Asia/Aqtau 3:21:04 - LMT 1924 May 2 - 4:00 - +04 1930 Jun 21 - 5:00 - +05 1981 Oct 1 - 6:00 - +06 1982 Apr 1 - 5:00 RussiaAsia +05/+06 1991 Mar 31 2:00s - 4:00 RussiaAsia +04/+05 1992 Jan 19 2:00s - 5:00 RussiaAsia +05/+06 1994 Sep 25 2:00s - 4:00 RussiaAsia +04/+05 2004 Oct 31 2:00s - 5:00 - +05 + 4:00 - %z 1930 Jun 21 + 5:00 - %z 1981 Oct 1 + 6:00 - %z 1982 Apr 1 + 5:00 RussiaAsia %z 1991 Mar 31 2:00s + 4:00 RussiaAsia %z 1992 Jan 19 2:00s + 5:00 RussiaAsia %z 1994 Sep 25 2:00s + 4:00 RussiaAsia %z 2004 Oct 31 2:00s + 5:00 - %z # Atyraū (KZ-23) is like Mangghystaū except it switched from # +04/+05 to +05/+06 in spring 1999, not fall 1994. Zone Asia/Atyrau 3:27:44 - LMT 1924 May 2 - 3:00 - +03 1930 Jun 21 - 5:00 - +05 1981 Oct 1 - 6:00 - +06 1982 Apr 1 - 5:00 RussiaAsia +05/+06 1991 Mar 31 2:00s - 4:00 RussiaAsia +04/+05 1992 Jan 19 2:00s - 5:00 RussiaAsia +05/+06 1999 Mar 28 2:00s - 4:00 RussiaAsia +04/+05 2004 Oct 31 2:00s - 5:00 - +05 + 3:00 - %z 1930 Jun 21 + 5:00 - %z 1981 Oct 1 + 6:00 - %z 1982 Apr 1 + 5:00 RussiaAsia %z 1991 Mar 31 2:00s + 4:00 RussiaAsia %z 1992 Jan 19 2:00s + 5:00 RussiaAsia %z 1999 Mar 28 2:00s + 4:00 RussiaAsia %z 2004 Oct 31 2:00s + 5:00 - %z # West Kazakhstan (KZ-27) # From Paul Eggert (2016-03-18): # The 1989 transition is from USSR act No. 227 (1989-03-14). Zone Asia/Oral 3:25:24 - LMT 1924 May 2 # or Ural'sk - 3:00 - +03 1930 Jun 21 - 5:00 - +05 1981 Apr 1 - 5:00 1:00 +06 1981 Oct 1 - 6:00 - +06 1982 Apr 1 - 5:00 RussiaAsia +05/+06 1989 Mar 26 2:00s - 4:00 RussiaAsia +04/+05 1992 Jan 19 2:00s - 5:00 RussiaAsia +05/+06 1992 Mar 29 2:00s - 4:00 RussiaAsia +04/+05 2004 Oct 31 2:00s - 5:00 - +05 + 3:00 - %z 1930 Jun 21 + 5:00 - %z 1981 Apr 1 + 5:00 1:00 %z 1981 Oct 1 + 6:00 - %z 1982 Apr 1 + 5:00 RussiaAsia %z 1989 Mar 26 2:00s + 4:00 RussiaAsia %z 1992 Jan 19 2:00s + 5:00 RussiaAsia %z 1992 Mar 29 2:00s + 4:00 RussiaAsia %z 2004 Oct 31 2:00s + 5:00 - %z # Kyrgyzstan (Kirgizstan) # Transitions through 1991 are from Shanks & Pottenger. @@ -2575,11 +2582,11 @@ Rule Kyrgyz 1997 2005 - Mar lastSun 2:30 1:00 - Rule Kyrgyz 1997 2004 - Oct lastSun 2:30 0 - # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone Asia/Bishkek 4:58:24 - LMT 1924 May 2 - 5:00 - +05 1930 Jun 21 - 6:00 RussiaAsia +06/+07 1991 Mar 31 2:00s - 5:00 RussiaAsia +05/+06 1991 Aug 31 2:00 - 5:00 Kyrgyz +05/+06 2005 Aug 12 - 6:00 - +06 + 5:00 - %z 1930 Jun 21 + 6:00 RussiaAsia %z 1991 Mar 31 2:00s + 5:00 RussiaAsia %z 1991 Aug 31 2:00 + 5:00 Kyrgyz %z 2005 Aug 12 + 6:00 - %z ############################################################################### @@ -2786,16 +2793,16 @@ Rule NBorneo 1935 1941 - Dec 14 0:00 0 - # and 1982 transition dates are from Mok Ly Yng. # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone Asia/Kuching 7:21:20 - LMT 1926 Mar - 7:30 - +0730 1933 - 8:00 NBorneo +08/+0820 1942 Feb 16 - 9:00 - +09 1945 Sep 12 - 8:00 - +08 + 7:30 - %z 1933 + 8:00 NBorneo %z 1942 Feb 16 + 9:00 - %z 1945 Sep 12 + 8:00 - %z # Maldives # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone Indian/Maldives 4:54:00 - LMT 1880 # Malé 4:54:00 - MMT 1960 # Malé Mean Time - 5:00 - +05 + 5:00 - %z # Mongolia @@ -2897,9 +2904,37 @@ Zone Indian/Maldives 4:54:00 - LMT 1880 # Malé # From Arthur David Olson (2008-05-19): # Assume that Choibalsan is indeed offset by 8:00. -# XXX--in the absence of better information, assume that transition -# was at the start of 2008-03-31 (the day of Steffen Thorsen's report); -# this is almost surely wrong. + +# From Heitor David Pinto (2024-06-23): +# Sources about time zones in Mongolia seem to list one of two conflicting +# configurations. The first configuration, mentioned in a comment to the TZ +# database in 1999, citing a Mongolian government website, lists the provinces +# of Bayan-Ölgii, Khovd and Uvs in UTC+7, and the rest of the country in +# UTC+8. The second configuration, mentioned in a comment to the database in +# 2001, lists Bayan-Ölgii, Khovd, Uvs, Govi-Altai and Zavkhan in UTC+7, Dornod +# and Sükhbaatar in UTC+9, and the rest of the country in UTC+8. +# +# The first configuration is still mentioned by several Mongolian travel +# agencies: +# https://www.adventurerider.mn/en/page/about_mongolia +# http://www.naturetours.mn/nt/mongolia.php +# https://www.newjuulchin.mn/web/content/7506?unique=fa24a0f6e96e022a3578ee5195ac879638c734ce +# +# It also matches these flight schedules in 2013: +# http://web.archive.org/web/20130722023600/https://www.hunnuair.com/en/timetabled +# The flight times imply that the airports of Uliastai (Zavkhan), Choibalsan +# (Dornod) and Altai (Govi-Altai) are in the same time zone as Ulaanbaatar, +# and Khovd is one hour behind.... +# +# The second configuration was mentioned by an official of the Mongolian +# standards agency in an interview in 2014: https://ikon.mn/n/9v6 +# And it's still listed by the Mongolian aviation agency: +# https://ais.mn/files/aip/eAIP/2023-12-25/html/eSUP/ZM-eSUP-23-04-en-MN.html +# +# ... I believe that the first configuration is what is actually observed in +# Mongolia and has been so all along, at least since 1999. The second +# configuration closely matches the ideal time zone boundaries at 97.5° E and +# 112.5° E but it doesn't seem to be used in practice. # From Ganbold Tsagaankhuu (2015-03-10): # It seems like yesterday Mongolian Government meeting has concluded to use @@ -2938,25 +2973,18 @@ Rule Mongol 2015 2016 - Sep lastSat 0:00 0 - # Zone NAME STDOFF RULES FORMAT [UNTIL] # Hovd, a.k.a. Chovd, Dund-Us, Dzhargalant, Khovd, Jirgalanta Zone Asia/Hovd 6:06:36 - LMT 1905 Aug - 6:00 - +06 1978 - 7:00 Mongol +07/+08 + 6:00 - %z 1978 + 7:00 Mongol %z # Ulaanbaatar, a.k.a. Ulan Bataar, Ulan Bator, Urga Zone Asia/Ulaanbaatar 7:07:32 - LMT 1905 Aug - 7:00 - +07 1978 - 8:00 Mongol +08/+09 -# Choibalsan, a.k.a. Bajan Tümen, Bajan Tumen, Chojbalsan, -# Choybalsan, Sanbejse, Tchoibalsan -Zone Asia/Choibalsan 7:38:00 - LMT 1905 Aug - 7:00 - +07 1978 - 8:00 - +08 1983 Apr - 9:00 Mongol +09/+10 2008 Mar 31 - 8:00 Mongol +08/+09 + 7:00 - %z 1978 + 8:00 Mongol %z # Nepal # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone Asia/Kathmandu 5:41:16 - LMT 1920 - 5:30 - +0530 1986 - 5:45 - +0545 + 5:30 - %z 1986 + 5:45 - %z # Pakistan @@ -3102,10 +3130,10 @@ Rule Pakistan 2009 only - Apr 15 0:00 1:00 S # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone Asia/Karachi 4:28:12 - LMT 1907 - 5:30 - +0530 1942 Sep - 5:30 1:00 +0630 1945 Oct 15 - 5:30 - +0530 1951 Sep 30 - 5:00 - +05 1971 Mar 26 + 5:30 - %z 1942 Sep + 5:30 1:00 %z 1945 Oct 15 + 5:30 - %z 1951 Sep 30 + 5:00 - %z 1971 Mar 26 5:00 Pakistan PK%sT # Pakistan Time # Palestine @@ -3653,14 +3681,14 @@ Zone Asia/Hebron 2:20:23 - LMT 1900 Oct # Philippine Star 2014-08-05 # http://www.philstar.com/headlines/2014/08/05/1354152/pnoy-urged-declare-use-daylight-saving-time -# From Paul Goyette (2018-06-15): +# From Paul Goyette (2018-06-15) with URLs updated by Guy Harris (2024-02-15): # In the Philippines, there is a national law, Republic Act No. 10535 # which declares the official time here as "Philippine Standard Time". # The act [1] even specifies use of PST as the abbreviation, although # the FAQ provided by PAGASA [2] uses the "acronym PhST to distinguish # it from the Pacific Standard Time (PST)." -# [1] http://www.officialgazette.gov.ph/2013/05/15/republic-act-no-10535/ -# [2] https://www1.pagasa.dost.gov.ph/index.php/astronomy/philippine-standard-time#republic-act-10535 +# [1] https://www.officialgazette.gov.ph/2013/05/15/republic-act-no-10535/ +# [2] https://prsd.pagasa.dost.gov.ph/index.php/28-astronomy/302-philippine-standard-time # # From Paul Eggert (2018-06-19): # I surveyed recent news reports, and my impression is that "PST" is @@ -3693,8 +3721,8 @@ Zone Asia/Manila -15:56:00 - LMT 1844 Dec 31 # Qatar # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone Asia/Qatar 3:26:08 - LMT 1920 # Al Dawhah / Doha - 4:00 - +04 1972 Jun - 3:00 - +03 + 4:00 - %z 1972 Jun + 3:00 - %z # Kuwait # Saudi Arabia @@ -3744,7 +3772,7 @@ Zone Asia/Qatar 3:26:08 - LMT 1920 # Al Dawhah / Doha # # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone Asia/Riyadh 3:06:52 - LMT 1947 Mar 14 - 3:00 - +03 + 3:00 - %z # Singapore # taken from Mok Ly Yng (2003-10-30) @@ -3752,13 +3780,13 @@ Zone Asia/Riyadh 3:06:52 - LMT 1947 Mar 14 # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone Asia/Singapore 6:55:25 - LMT 1901 Jan 1 6:55:25 - SMT 1905 Jun 1 # Singapore M.T. - 7:00 - +07 1933 Jan 1 - 7:00 0:20 +0720 1936 Jan 1 - 7:20 - +0720 1941 Sep 1 - 7:30 - +0730 1942 Feb 16 - 9:00 - +09 1945 Sep 12 - 7:30 - +0730 1981 Dec 31 16:00u - 8:00 - +08 + 7:00 - %z 1933 Jan 1 + 7:00 0:20 %z 1936 Jan 1 + 7:20 - %z 1941 Sep 1 + 7:30 - %z 1942 Feb 16 + 9:00 - %z 1945 Sep 12 + 7:30 - %z 1981 Dec 31 16:00u + 8:00 - %z # Spratly Is # no information @@ -3816,13 +3844,13 @@ Zone Asia/Singapore 6:55:25 - LMT 1901 Jan 1 # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone Asia/Colombo 5:19:24 - LMT 1880 5:19:32 - MMT 1906 # Moratuwa Mean Time - 5:30 - +0530 1942 Jan 5 - 5:30 0:30 +06 1942 Sep - 5:30 1:00 +0630 1945 Oct 16 2:00 - 5:30 - +0530 1996 May 25 0:00 - 6:30 - +0630 1996 Oct 26 0:30 - 6:00 - +06 2006 Apr 15 0:30 - 5:30 - +0530 + 5:30 - %z 1942 Jan 5 + 5:30 0:30 %z 1942 Sep + 5:30 1:00 %z 1945 Oct 16 2:00 + 5:30 - %z 1996 May 25 0:00 + 6:30 - %z 1996 Oct 26 0:30 + 6:00 - %z 2006 Apr 15 0:30 + 5:30 - %z # Syria # Rule NAME FROM TO - IN ON AT SAVE LETTER/S @@ -3993,16 +4021,16 @@ Rule Syria 2009 2022 - Oct lastFri 0:00 0 - # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone Asia/Damascus 2:25:12 - LMT 1920 # Dimashq 2:00 Syria EE%sT 2022 Oct 28 0:00 - 3:00 - +03 + 3:00 - %z # Tajikistan # From Shanks & Pottenger. # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone Asia/Dushanbe 4:35:12 - LMT 1924 May 2 - 5:00 - +05 1930 Jun 21 - 6:00 RussiaAsia +06/+07 1991 Mar 31 2:00s - 5:00 1:00 +06 1991 Sep 9 2:00s - 5:00 - +05 + 5:00 - %z 1930 Jun 21 + 6:00 RussiaAsia %z 1991 Mar 31 2:00s + 5:00 1:00 %z 1991 Sep 9 2:00s + 5:00 - %z # Cambodia # Christmas I @@ -4012,16 +4040,16 @@ Zone Asia/Dushanbe 4:35:12 - LMT 1924 May 2 # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone Asia/Bangkok 6:42:04 - LMT 1880 6:42:04 - BMT 1920 Apr # Bangkok Mean Time - 7:00 - +07 + 7:00 - %z # Turkmenistan # From Shanks & Pottenger. # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone Asia/Ashgabat 3:53:32 - LMT 1924 May 2 # or Ashkhabad - 4:00 - +04 1930 Jun 21 - 5:00 RussiaAsia +05/+06 1991 Mar 31 2:00 - 4:00 RussiaAsia +04/+05 1992 Jan 19 2:00 - 5:00 - +05 + 4:00 - %z 1930 Jun 21 + 5:00 RussiaAsia %z 1991 Mar 31 2:00 + 4:00 RussiaAsia %z 1992 Jan 19 2:00 + 5:00 - %z # Oman # Réunion @@ -4031,25 +4059,25 @@ Zone Asia/Ashgabat 3:53:32 - LMT 1924 May 2 # or Ashkhabad # The Crozet Is also observe Réunion time; see the 'antarctica' file. # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone Asia/Dubai 3:41:12 - LMT 1920 - 4:00 - +04 + 4:00 - %z # Uzbekistan # Byalokoz 1919 says Uzbekistan was 4:27:53. # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone Asia/Samarkand 4:27:53 - LMT 1924 May 2 - 4:00 - +04 1930 Jun 21 - 5:00 - +05 1981 Apr 1 - 5:00 1:00 +06 1981 Oct 1 - 6:00 - +06 1982 Apr 1 - 5:00 RussiaAsia +05/+06 1992 - 5:00 - +05 + 4:00 - %z 1930 Jun 21 + 5:00 - %z 1981 Apr 1 + 5:00 1:00 %z 1981 Oct 1 + 6:00 - %z 1982 Apr 1 + 5:00 RussiaAsia %z 1992 + 5:00 - %z # Milne says Tashkent was 4:37:10.8. #STDOFF 4:37:10.8 Zone Asia/Tashkent 4:37:11 - LMT 1924 May 2 - 5:00 - +05 1930 Jun 21 - 6:00 RussiaAsia +06/+07 1991 Mar 31 2:00 - 5:00 RussiaAsia +05/+06 1992 - 5:00 - +05 + 5:00 - %z 1930 Jun 21 + 6:00 RussiaAsia %z 1991 Mar 31 2:00 + 5:00 RussiaAsia %z 1992 + 5:00 - %z # Vietnam (southern) @@ -4107,7 +4135,7 @@ Zone Asia/Tashkent 4:37:11 - LMT 1924 May 2 # Võ Nguyên Giáp, Việt Nam Dân Quốc Công Báo, No. 1 (1945-09-29), page 13 # http://baochi.nlv.gov.vn/baochi/cgi-bin/baochi?a=d&d=JwvzO19450929.2.5&dliv=none # It says that on 1945-09-01 at 24:00, Vietnam moved back two hours, to +07. -# It also mentions a 1945-03-29 decree (by a Japanese Goveror-General) +# It also mentions a 1945-03-29 decree (by a Japanese Governor-General) # to set the time zone to +09, but does not say whether that decree # merely legalized an earlier change to +09. # @@ -4128,14 +4156,14 @@ Zone Asia/Tashkent 4:37:11 - LMT 1924 May 2 #STDOFF 7:06:30.13 Zone Asia/Ho_Chi_Minh 7:06:30 - LMT 1906 Jul 1 7:06:30 - PLMT 1911 May 1 # Phù Liễn MT - 7:00 - +07 1942 Dec 31 23:00 - 8:00 - +08 1945 Mar 14 23:00 - 9:00 - +09 1945 Sep 1 24:00 - 7:00 - +07 1947 Apr 1 - 8:00 - +08 1955 Jul 1 01:00 - 7:00 - +07 1959 Dec 31 23:00 - 8:00 - +08 1975 Jun 13 - 7:00 - +07 + 7:00 - %z 1942 Dec 31 23:00 + 8:00 - %z 1945 Mar 14 23:00 + 9:00 - %z 1945 Sep 1 24:00 + 7:00 - %z 1947 Apr 1 + 8:00 - %z 1955 Jul 1 01:00 + 7:00 - %z 1959 Dec 31 23:00 + 8:00 - %z 1975 Jun 13 + 7:00 - %z # From Paul Eggert (2019-02-19): # diff --git a/australasia b/australasia index 0e9c2592e4be..359f9c1f1e10 100644 --- a/australasia +++ b/australasia @@ -43,8 +43,8 @@ Zone Australia/Perth 7:43:24 - LMT 1895 Dec 8:00 Aus AW%sT 1943 Jul 8:00 AW AW%sT Zone Australia/Eucla 8:35:28 - LMT 1895 Dec - 8:45 Aus +0845/+0945 1943 Jul - 8:45 AW +0845/+0945 + 8:45 Aus %z 1943 Jul + 8:45 AW %z # Queensland # @@ -209,8 +209,8 @@ Rule LH 2008 max - Apr Sun>=1 2:00 0 - Rule LH 2008 max - Oct Sun>=1 2:00 0:30 - Zone Australia/Lord_Howe 10:36:20 - LMT 1895 Feb 10:00 - AEST 1981 Mar - 10:30 LH +1030/+1130 1985 Jul - 10:30 LH +1030/+11 + 10:30 LH %z 1985 Jul + 10:30 LH %z # Australian miscellany # @@ -416,16 +416,16 @@ Rule Fiji 2019 only - Nov Sun>=8 2:00 1:00 - Rule Fiji 2020 only - Dec 20 2:00 1:00 - # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone Pacific/Fiji 11:55:44 - LMT 1915 Oct 26 # Suva - 12:00 Fiji +12/+13 + 12:00 Fiji %z # French Polynesia # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone Pacific/Gambier -8:59:48 - LMT 1912 Oct 1 # Rikitea - -9:00 - -09 + -9:00 - %z Zone Pacific/Marquesas -9:18:00 - LMT 1912 Oct 1 - -9:30 - -0930 + -9:30 - %z Zone Pacific/Tahiti -9:58:16 - LMT 1912 Oct 1 # Papeete - -10:00 - -10 + -10:00 - %z # Clipperton (near North America) is administered from French Polynesia; # it is uninhabited. @@ -468,7 +468,7 @@ Rule Guam 1977 only - Aug 28 2:00 0 S Zone Pacific/Guam -14:21:00 - LMT 1844 Dec 31 9:39:00 - LMT 1901 # Agana 10:00 - GST 1941 Dec 10 # Guam - 9:00 - +09 1944 Jul 31 + 9:00 - %z 1944 Jul 31 10:00 Guam G%sT 2000 Dec 23 10:00 - ChST # Chamorro Standard Time @@ -480,30 +480,30 @@ Zone Pacific/Guam -14:21:00 - LMT 1844 Dec 31 # Wallis & Futuna # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone Pacific/Tarawa 11:32:04 - LMT 1901 # Bairiki - 12:00 - +12 + 12:00 - %z # Kiribati (except Gilbert Is) # See Pacific/Tarawa for the Gilbert Is. # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone Pacific/Kanton 0 - -00 1937 Aug 31 - -12:00 - -12 1979 Oct - -11:00 - -11 1994 Dec 31 - 13:00 - +13 + -12:00 - %z 1979 Oct + -11:00 - %z 1994 Dec 31 + 13:00 - %z Zone Pacific/Kiritimati -10:29:20 - LMT 1901 - -10:40 - -1040 1979 Oct - -10:00 - -10 1994 Dec 31 - 14:00 - +14 + -10:40 - %z 1979 Oct + -10:00 - %z 1994 Dec 31 + 14:00 - %z # Marshall Is # See Pacific/Tarawa for most locations. # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone Pacific/Kwajalein 11:09:20 - LMT 1901 - 11:00 - +11 1937 - 10:00 - +10 1941 Apr 1 - 9:00 - +09 1944 Feb 6 - 11:00 - +11 1969 Oct - -12:00 - -12 1993 Aug 20 24:00 - 12:00 - +12 + 11:00 - %z 1937 + 10:00 - %z 1941 Apr 1 + 9:00 - %z 1944 Feb 6 + 11:00 - %z 1969 Oct + -12:00 - %z 1993 Aug 20 24:00 + 12:00 - %z # Micronesia # For Chuuk and Yap see Pacific/Port_Moresby. @@ -511,22 +511,22 @@ Zone Pacific/Kwajalein 11:09:20 - LMT 1901 # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone Pacific/Kosrae -13:08:04 - LMT 1844 Dec 31 10:51:56 - LMT 1901 - 11:00 - +11 1914 Oct - 9:00 - +09 1919 Feb 1 - 11:00 - +11 1937 - 10:00 - +10 1941 Apr 1 - 9:00 - +09 1945 Aug - 11:00 - +11 1969 Oct - 12:00 - +12 1999 - 11:00 - +11 + 11:00 - %z 1914 Oct + 9:00 - %z 1919 Feb 1 + 11:00 - %z 1937 + 10:00 - %z 1941 Apr 1 + 9:00 - %z 1945 Aug + 11:00 - %z 1969 Oct + 12:00 - %z 1999 + 11:00 - %z # Nauru # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone Pacific/Nauru 11:07:40 - LMT 1921 Jan 15 # Uaobe - 11:30 - +1130 1942 Aug 29 - 9:00 - +09 1945 Sep 8 - 11:30 - +1130 1979 Feb 10 2:00 - 12:00 - +12 + 11:30 - %z 1942 Aug 29 + 9:00 - %z 1945 Sep 8 + 11:30 - %z 1979 Feb 10 2:00 + 12:00 - %z # New Caledonia # Rule NAME FROM TO - IN ON AT SAVE LETTER/S @@ -537,7 +537,7 @@ Rule NC 1996 only - Dec 1 2:00s 1:00 - Rule NC 1997 only - Mar 2 2:00s 0 - # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone Pacific/Noumea 11:05:48 - LMT 1912 Jan 13 # Nouméa - 11:00 NC +11/+12 + 11:00 NC %z ############################################################################### @@ -581,8 +581,8 @@ Zone Pacific/Auckland 11:39:04 - LMT 1868 Nov 2 12:00 NZ NZ%sT Zone Pacific/Chatham 12:13:48 - LMT 1868 Nov 2 - 12:15 - +1215 1946 Jan 1 - 12:45 Chatham +1245/+1345 + 12:15 - %z 1946 Jan 1 + 12:45 Chatham %z # Auckland Is # uninhabited; Māori and Moriori, colonial settlers, pastoralists, sealers, @@ -635,8 +635,8 @@ Rule Cook 1979 1990 - Oct lastSun 0:00 0:30 - # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone Pacific/Rarotonga 13:20:56 - LMT 1899 Dec 26 # Avarua -10:39:04 - LMT 1952 Oct 16 - -10:30 - -1030 1978 Nov 12 - -10:00 Cook -10/-0930 + -10:30 - %z 1978 Nov 12 + -10:00 Cook %z ############################################################################### @@ -653,30 +653,30 @@ Zone Pacific/Rarotonga 13:20:56 - LMT 1899 Dec 26 # Avarua # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone Pacific/Niue -11:19:40 - LMT 1952 Oct 16 # Alofi - -11:20 - -1120 1964 Jul - -11:00 - -11 + -11:20 - %z 1964 Jul + -11:00 - %z # Norfolk # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone Pacific/Norfolk 11:11:52 - LMT 1901 # Kingston - 11:12 - +1112 1951 - 11:30 - +1130 1974 Oct 27 02:00s - 11:30 1:00 +1230 1975 Mar 2 02:00s - 11:30 - +1130 2015 Oct 4 02:00s - 11:00 - +11 2019 Jul - 11:00 AN +11/+12 + 11:12 - %z 1951 + 11:30 - %z 1974 Oct 27 02:00s + 11:30 1:00 %z 1975 Mar 2 02:00s + 11:30 - %z 2015 Oct 4 02:00s + 11:00 - %z 2019 Jul + 11:00 AN %z # Palau (Belau) # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone Pacific/Palau -15:02:04 - LMT 1844 Dec 31 # Koror 8:57:56 - LMT 1901 - 9:00 - +09 + 9:00 - %z # Papua New Guinea # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone Pacific/Port_Moresby 9:48:40 - LMT 1880 9:48:32 - PMMT 1895 # Port Moresby Mean Time - 10:00 - +10 + 10:00 - %z # # From Paul Eggert (2014-10-13): # Base the Bougainville entry on the Arawa-Kieta region, which appears to have @@ -697,16 +697,16 @@ Zone Pacific/Port_Moresby 9:48:40 - LMT 1880 # Zone Pacific/Bougainville 10:22:16 - LMT 1880 9:48:32 - PMMT 1895 - 10:00 - +10 1942 Jul - 9:00 - +09 1945 Aug 21 - 10:00 - +10 2014 Dec 28 2:00 - 11:00 - +11 + 10:00 - %z 1942 Jul + 9:00 - %z 1945 Aug 21 + 10:00 - %z 2014 Dec 28 2:00 + 11:00 - %z # Pitcairn # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone Pacific/Pitcairn -8:40:20 - LMT 1901 # Adamstown - -8:30 - -0830 1998 Apr 27 0:00 - -8:00 - -08 + -8:30 - %z 1998 Apr 27 0:00 + -8:00 - %z # American Samoa # Midway @@ -795,15 +795,15 @@ Rule WS 2012 2020 - Sep lastSun 3:00 1 - # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone Pacific/Apia 12:33:04 - LMT 1892 Jul 5 -11:26:56 - LMT 1911 - -11:30 - -1130 1950 - -11:00 WS -11/-10 2011 Dec 29 24:00 - 13:00 WS +13/+14 + -11:30 - %z 1950 + -11:00 WS %z 2011 Dec 29 24:00 + 13:00 WS %z # Solomon Is # excludes Bougainville, for which see Papua New Guinea # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone Pacific/Guadalcanal 10:39:48 - LMT 1912 Oct 1 # Honiara - 11:00 - +11 + 11:00 - %z # Tokelau # @@ -826,8 +826,8 @@ Zone Pacific/Guadalcanal 10:39:48 - LMT 1912 Oct 1 # Honiara # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone Pacific/Fakaofo -11:24:56 - LMT 1901 - -11:00 - -11 2011 Dec 30 - 13:00 - +13 + -11:00 - %z 2011 Dec 30 + 13:00 - %z # Tonga # Rule NAME FROM TO - IN ON AT SAVE LETTER/S @@ -839,9 +839,9 @@ Rule Tonga 2016 only - Nov Sun>=1 2:00 1:00 - Rule Tonga 2017 only - Jan Sun>=15 3:00 0 - # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone Pacific/Tongatapu 12:19:12 - LMT 1945 Sep 10 - 12:20 - +1220 1961 - 13:00 - +13 1999 - 13:00 Tonga +13/+14 + 12:20 - %z 1961 + 13:00 - %z 1999 + 13:00 Tonga %z # US minor outlying islands @@ -930,7 +930,7 @@ Rule Vanuatu 1992 1993 - Jan Sat>=22 24:00 0 - Rule Vanuatu 1992 only - Oct Sat>=22 24:00 1:00 - # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone Pacific/Efate 11:13:16 - LMT 1912 Jan 13 # Vila - 11:00 Vanuatu +11/+12 + 11:00 Vanuatu %z ############################################################################### diff --git a/backward b/backward index 65c711b37bf4..0236751df1da 100644 --- a/backward +++ b/backward @@ -1,9 +1,10 @@ -# tzdb links for backward compatibility +# Links and zones for backward compatibility # This file is in the public domain, so clarified as of # 2009-05-17 by Arthur David Olson. # This file provides links from old or merged timezone names to current ones. +# It also provides a few zone entries for old naming conventions. # Many names changed in 1993 and in 1995, and many merged names moved here # in the period from 2013 through 2022. Several of these names are # also present in the file 'backzone', which has data important only @@ -44,6 +45,8 @@ Link America/Rio_Branco Brazil/Acre #= America/Porto_Acre Link America/Noronha Brazil/DeNoronha Link America/Sao_Paulo Brazil/East Link America/Manaus Brazil/West +Link Europe/Brussels CET +Link America/Chicago CST6CDT Link America/Halifax Canada/Atlantic Link America/Winnipeg Canada/Central # This line is commented out, as the name exceeded the 14-character limit @@ -58,6 +61,9 @@ Link America/Whitehorse Canada/Yukon Link America/Santiago Chile/Continental Link Pacific/Easter Chile/EasterIsland Link America/Havana Cuba +Link Europe/Athens EET +Link America/Panama EST +Link America/New_York EST5EDT Link Africa/Cairo Egypt Link Europe/Dublin Eire # Vanguard section, for most .zi parsers. @@ -96,6 +102,9 @@ Link America/Jamaica Jamaica Link Asia/Tokyo Japan Link Pacific/Kwajalein Kwajalein Link Africa/Tripoli Libya +Link Europe/Brussels MET +Link America/Phoenix MST +Link America/Denver MST7MDT Link America/Tijuana Mexico/BajaNorte Link America/Mazatlan Mexico/BajaSur Link America/Mexico_City Mexico/General @@ -275,6 +284,7 @@ Link America/Denver America/Shiprock Link America/Toronto America/Thunder_Bay Link America/Edmonton America/Yellowknife Link Pacific/Auckland Antarctica/South_Pole +Link Asia/Ulaanbaatar Asia/Choibalsan Link Asia/Shanghai Asia/Chongqing Link Asia/Shanghai Asia/Harbin Link Asia/Urumqi Asia/Kashgar @@ -289,6 +299,7 @@ Link Europe/Kyiv Europe/Zaporozhye Link Pacific/Kanton Pacific/Enderbury Link Pacific/Honolulu Pacific/Johnston Link Pacific/Port_Moresby Pacific/Yap +Link Europe/Lisbon WET # Alternate names for the same location @@ -314,5 +325,7 @@ Link Europe/Kyiv Europe/Kiev # Classically, Cyprus is in Asia; e.g. see Herodotus, Histories, I.72. # However, for various reasons many users expect to find it under Europe. Link Asia/Nicosia Europe/Nicosia +Link Pacific/Honolulu HST +Link America/Los_Angeles PST8PDT Link Pacific/Guadalcanal Pacific/Ponape #= Pacific/Pohnpei Link Pacific/Port_Moresby Pacific/Truk #= Pacific/Chuuk diff --git a/backzone b/backzone index f45250340493..dd7a86758374 100644 --- a/backzone +++ b/backzone @@ -346,10 +346,8 @@ Zone Africa/Lome 0:04:52 - LMT 1893 # Angola # -# From Paul Eggert (2018-02-16): -# Shanks gives 1911-05-26 for the transition to WAT, -# evidently confusing the date of the Portuguese decree -# (see Europe/Lisbon) with the date that it took effect. +# From Tim Parenti (2024-07-01), per Paul Eggert (2018-02-16): +# For timestamps before independence, see commentary for Europe/Lisbon. # Zone Africa/Luanda 0:52:56 - LMT 1892 0:52:04 - LMT 1911 Dec 31 23:00u # Luanda MT? @@ -1086,10 +1084,10 @@ Zone Asia/Muscat 3:54:24 - LMT 1920 4:00 - +04 # India -# From Paul Eggert (2014-08-11), after a heads-up from Stephen Colebourne: -# According to a Portuguese decree (1911-05-26) -# https://dre.pt/pdf1sdip/1911/05/12500/23132313.pdf -# Portuguese India switched to UT +05 on 1912-01-01. +# From Tim Parenti (2024-07-01), per Paul Eggert (2014-08-11), after a +# heads-up from Stephen Colebourne: +# According to a Portuguese decree (1911-05-24), Portuguese India switched to +# UT +05 on 1912-01-01 (see Europe/Lisbon). #Zone Asia/Panaji [not enough info to complete] # Cambodia @@ -1829,6 +1827,27 @@ Zone Pacific/Wake 11:06:28 - LMT 1901 Zone Pacific/Wallis 12:15:20 - LMT 1901 12:00 - +12 + +# From Paul Eggert (2024-05-22): +# The following zones pretend that standard time extends backward +# indefinitely into the past, and so are ahistorical. +# In current TZDB these entries are links to geographical locations +# that agree with the ahistorical zones since 1970. +# These are in numeric rather than alphabetic order. + +# Zone NAME STDOFF RULES FORMAT [UNTIL] +Zone HST -10:00 - HST +Zone PST8PDT -8:00 US P%sT +Zone MST -7:00 - MST +Zone MST7MDT -7:00 US M%sT +Zone CST6CDT -6:00 US C%sT +Zone EST -5:00 - EST +Zone EST5EDT -5:00 US E%sT +Zone WET 0:00 EU WE%sT +Zone CET 1:00 C-Eur CE%sT +Zone MET 1:00 C-Eur ME%sT +Zone EET 2:00 EU EE%sT + # Local Variables: # coding: utf-8 # End: diff --git a/checknow.awk b/checknow.awk index 57ff3c02e789..8b7881d2e27f 100644 --- a/checknow.awk +++ b/checknow.awk @@ -14,7 +14,7 @@ BEGIN { if ($0 ~ /^TZ/) { record_zone(zone, data) zone = $0 - sub(/.*\.dir\//, "", zone) + sub(/.*\.ckd\//, "", zone) sub(/\/\//, "/", zone) sub(/"/, "", zone) data = "" @@ -45,7 +45,7 @@ END { for (zone in zone_data) { data = zone_data[zone] if (!zonenow[data]) { - printf "zonenow.tab should have one of:%s\n", zones[data] + printf "Zone table should have one of:%s\n", zones[data] zonenow[data] = zone # This suppresses duplicate diagnostics. status = 1 } diff --git a/etcetera b/etcetera index 29fbed9b9290..a5ecd6de1f6e 100644 --- a/etcetera +++ b/etcetera @@ -5,7 +5,7 @@ # These entries are for uses not otherwise covered by the tz database. # Their main practical use is for platforms like Android that lack -# support for POSIX.1-2017-style TZ strings. On such platforms these entries +# support for POSIX proleptic TZ strings. On such platforms these entries # can be useful if the timezone database is wrong or if a ship or # aircraft at sea is not in a timezone. @@ -51,29 +51,29 @@ Link Etc/GMT GMT # so we moved the names into the Etc subdirectory. # Also, the time zone abbreviations are now compatible with %z. -Zone Etc/GMT-14 14 - +14 -Zone Etc/GMT-13 13 - +13 -Zone Etc/GMT-12 12 - +12 -Zone Etc/GMT-11 11 - +11 -Zone Etc/GMT-10 10 - +10 -Zone Etc/GMT-9 9 - +09 -Zone Etc/GMT-8 8 - +08 -Zone Etc/GMT-7 7 - +07 -Zone Etc/GMT-6 6 - +06 -Zone Etc/GMT-5 5 - +05 -Zone Etc/GMT-4 4 - +04 -Zone Etc/GMT-3 3 - +03 -Zone Etc/GMT-2 2 - +02 -Zone Etc/GMT-1 1 - +01 -Zone Etc/GMT+1 -1 - -01 -Zone Etc/GMT+2 -2 - -02 -Zone Etc/GMT+3 -3 - -03 -Zone Etc/GMT+4 -4 - -04 -Zone Etc/GMT+5 -5 - -05 -Zone Etc/GMT+6 -6 - -06 -Zone Etc/GMT+7 -7 - -07 -Zone Etc/GMT+8 -8 - -08 -Zone Etc/GMT+9 -9 - -09 -Zone Etc/GMT+10 -10 - -10 -Zone Etc/GMT+11 -11 - -11 -Zone Etc/GMT+12 -12 - -12 +Zone Etc/GMT-14 14 - %z +Zone Etc/GMT-13 13 - %z +Zone Etc/GMT-12 12 - %z +Zone Etc/GMT-11 11 - %z +Zone Etc/GMT-10 10 - %z +Zone Etc/GMT-9 9 - %z +Zone Etc/GMT-8 8 - %z +Zone Etc/GMT-7 7 - %z +Zone Etc/GMT-6 6 - %z +Zone Etc/GMT-5 5 - %z +Zone Etc/GMT-4 4 - %z +Zone Etc/GMT-3 3 - %z +Zone Etc/GMT-2 2 - %z +Zone Etc/GMT-1 1 - %z +Zone Etc/GMT+1 -1 - %z +Zone Etc/GMT+2 -2 - %z +Zone Etc/GMT+3 -3 - %z +Zone Etc/GMT+4 -4 - %z +Zone Etc/GMT+5 -5 - %z +Zone Etc/GMT+6 -6 - %z +Zone Etc/GMT+7 -7 - %z +Zone Etc/GMT+8 -8 - %z +Zone Etc/GMT+9 -9 - %z +Zone Etc/GMT+10 -10 - %z +Zone Etc/GMT+11 -11 - %z +Zone Etc/GMT+12 -12 - %z diff --git a/europe b/europe index c6b5270316b9..f9063949eb83 100644 --- a/europe +++ b/europe @@ -730,14 +730,6 @@ Rule Russia 1996 2010 - Oct lastSun 2:00s 0 - # Take "abolishing daylight saving time" to mean that time is now considered # to be standard. -# These are for backward compatibility with older versions. - -# Zone NAME STDOFF RULES FORMAT [UNTIL] -Zone WET 0:00 EU WE%sT -Zone CET 1:00 C-Eur CE%sT -Zone MET 1:00 C-Eur ME%sT -Zone EET 2:00 EU EE%sT - # Previous editions of this database used abbreviations like MET DST # for Central European Summer Time, but this didn't agree with common usage. @@ -871,7 +863,7 @@ Zone Europe/Minsk 1:50:16 - LMT 1880 3:00 Russia MSK/MSD 1990 3:00 - MSK 1991 Mar 31 2:00s 2:00 Russia EE%sT 2011 Mar 27 2:00s - 3:00 - +03 + 3:00 - %z # Belgium # Luxembourg @@ -1176,22 +1168,22 @@ Rule Thule 2007 max - Nov Sun>=1 2:00 0 S # # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone America/Danmarkshavn -1:14:40 - LMT 1916 Jul 28 - -3:00 - -03 1980 Apr 6 2:00 - -3:00 EU -03/-02 1996 + -3:00 - %z 1980 Apr 6 2:00 + -3:00 EU %z 1996 0:00 - GMT # # Use the old name Scoresbysund, as the current name Ittoqqortoormiit # exceeds tzdb's 14-letter limit and has no common English abbreviation. Zone America/Scoresbysund -1:27:52 - LMT 1916 Jul 28 # Ittoqqortoormiit - -2:00 - -02 1980 Apr 6 2:00 - -2:00 C-Eur -02/-01 1981 Mar 29 - -1:00 EU -01/+00 2024 Mar 31 - -2:00 EU -02/-01 + -2:00 - %z 1980 Apr 6 2:00 + -2:00 C-Eur %z 1981 Mar 29 + -1:00 EU %z 2024 Mar 31 + -2:00 EU %z Zone America/Nuuk -3:26:56 - LMT 1916 Jul 28 # Godthåb - -3:00 - -03 1980 Apr 6 2:00 - -3:00 EU -03/-02 2023 Mar 26 1:00u - -2:00 - -02 2023 Oct 29 1:00u - -2:00 EU -02/-01 + -3:00 - %z 1980 Apr 6 2:00 + -3:00 EU %z 2023 Mar 26 1:00u + -2:00 - %z 2023 Oct 29 1:00u + -2:00 EU %z Zone America/Thule -4:35:08 - LMT 1916 Jul 28 # Pituffik -4:00 Thule A%sT @@ -2063,10 +2055,39 @@ Zone Europe/Warsaw 1:24:00 - LMT 1880 # Portugal -# From Paul Eggert (2014-08-11), after a heads-up from Stephen Colebourne: -# According to a Portuguese decree (1911-05-26) -# https://dre.pt/application/dir/pdf1sdip/1911/05/12500/23132313.pdf -# Lisbon was at -0:36:44.68, but switched to GMT on 1912-01-01 at 00:00. +# From Tim Parenti (2024-07-01), per Alois Treindl (2021-02-07) and Michael +# Deckers (2021-02-10): +# http://oal.ul.pt/documentos/2018/01/hl1911a2018.pdf/ +# The Astronomical Observatory of Lisbon has published a list detailing the +# historical transitions in legal time within continental Portugal. It +# directly references many decrees and ordinances which are, in turn, +# referenced below. They can be viewed in the public archives of the Diário da +# República (until 1976-04-09 known as the Diário do Govêrno) at +# https://dre.pt/ (in Portuguese). +# +# Most of the Rules below have been updated simply to match the Observatory's +# listing for continental (mainland) Portugal. Although there are over 50 +# referenced decrees and ordinances, only the handful with comments below have +# been verified against the text, typically to provide additional confidence +# wherever dates provided by Whitman and Shanks & Pottenger had disagreed. +# See further below for the Azores and Madeira. + +# From Tim Parenti (2024-07-01), per Paul Eggert (2014-08-11), after a +# heads-up from Stephen Colebourne: +# According to a 1911-05-24 Portuguese decree, Lisbon was at -0:36:44.68, but +# switched to GMT on 1912-01-01 at 00:00. +# https://dre.pt/dr/detalhe/decreto/593090 +# https://dre.pt/application/conteudo/593090 +# The decree made legal time throughout Portugal and her possessions +# "subordinate to the Greenwich meridian, according to the principle adopted at +# the Washington Convention in 1884" and eliminated the "difference of five +# minutes between the internal and external clocks of railway stations". +# +# The decree was gazetted in the 1911-05-30 issue of Diário do Govêrno, and is +# considered to be dated 1911-05-24 by that issue's summary; however, the text +# of the decree itself is dated 1911-05-26. The Diário da República website +# notes the discrepancy, but later laws and the Observatory all seem to refer +# to this decree by the 1911-05-24 date. # # From Michael Deckers (2018-02-15): # article 5 [of the 1911 decree; Deckers's translation] ...: @@ -2074,37 +2095,62 @@ Zone Europe/Warsaw 1:24:00 - LMT 1880 # according to the 2nd article, the civil day January 1, 1912 begins, # all clocks therefore having to be advanced or set back correspondingly ... -# From Rui Pedro Salgueiro (1992-11-12): -# Portugal has recently (September, 27) changed timezone -# (from WET to MET or CET) to harmonize with EEC. -# -# Martin Bruckmann (1996-02-29) reports via Peter Ilieve -# that Portugal is reverting to 0:00 by not moving its clocks this spring. -# The new Prime Minister was fed up with getting up in the dark in the winter. -# -# From Paul Eggert (1996-11-12): -# IATA SSIM (1991-09) reports several 1991-09 and 1992-09 transitions -# at 02:00u, not 01:00u. Assume that these are typos. -# IATA SSIM (1991/1992) reports that the Azores were at -1:00. -# IATA SSIM (1993-02) says +0:00; later issues (through 1996-09) say -1:00. -# Guess that the Azores changed to EU rules in 1992 (since that's when Portugal -# harmonized with EU rules), and that they stayed +0:00 that winter. -# # Rule NAME FROM TO - IN ON AT SAVE LETTER/S -# DSH writes that despite Decree 1,469 (1915), the change to the clocks was not -# done every year, depending on what Spain did, because of railroad schedules. -# Go with Shanks & Pottenger. +# From Tim Parenti (2024-07-01), per Paul Eggert (1999-01-30): +# DSH writes in their history that Decreto 1469 of 1915-03-30 established +# summer time and that, "despite" this, the change to the clocks was not done +# every year, depending on what Spain did, because of railroad schedules. +# In fact, that decree had nothing to do with DST; rather, it regulated the +# sending of time signals. But we do see linkage to Spain in the 1920s below. +# https://dre.pt/dr/detalhe/decreto/1469-1915-285721 +# https://dre.pt/application/conteudo/285721 +# +# According to the Observatory, standard time was first advanced by Decreto +# 2433 of 1916-06-09 and restored by Decreto 2712 of 1916-10-28. While Whitman +# gives 1916-10-31 for the latter transition, Shanks & Pottenger agrees more +# closely with the decree, which stated that its provision "will start sixty +# minutes after the end of 31 October, according to the current time," i.e., +# 01:00 on 1 November. +# https://dre.pt/dr/detalhe/decreto/2433-1916-267192 +# https://dre.pt/application/conteudo/267192 +# https://dre.pt/dr/detalhe/decreto/2712-1916-590937 +# https://dre.pt/application/conteudo/590937 Rule Port 1916 only - Jun 17 23:00 1:00 S -# Whitman gives 1916 Oct 31; go with Shanks & Pottenger. Rule Port 1916 only - Nov 1 1:00 0 - -Rule Port 1917 only - Feb 28 23:00s 1:00 S -Rule Port 1917 1921 - Oct 14 23:00s 0 - -Rule Port 1918 only - Mar 1 23:00s 1:00 S -Rule Port 1919 only - Feb 28 23:00s 1:00 S -Rule Port 1920 only - Feb 29 23:00s 1:00 S -Rule Port 1921 only - Feb 28 23:00s 1:00 S +# From Tim Parenti (2024-07-01): +# Article 7 of Decreto 2922 of 1916-12-30 stated that "the legal time will be +# advanced by sixty minutes from 1 March to 31 October." Per Article 15, this +# came into force from 1917-01-01. Just before the first fall back, Decreto +# 3446 of 1917-10-11 changed the annual end date to 14 October. +# https://dre.pt/dr/detalhe/decreto/2922-1916-261894 +# https://dre.pt/application/conteudo/261894 +# https://dre.pt/dr/detalhe/decreto/3446-1917-495161 +# https://dre.pt/application/conteudo/495161 +# This annual change was revoked by Decreto 8038 of 1922-02-18. +# https://dre.pt/dr/detalhe/decreto/8038-1922-569751 +# https://dre.pt/application/conteudo/569751 +Rule Port 1917 1921 - Mar 1 0:00 1:00 S +Rule Port 1917 1921 - Oct 14 24:00 0 - +# From Tim Parenti (2024-07-01): +# Decreto 9592 of 1924-04-14 noted that "France maintains the advance of legal +# time in the summer and Spain has now adopted it for the first time" and +# considered "that the absence of similar measures would cause serious +# difficulties for international rail connections with consequent repercussions +# on domestic service hours..." along with "inconvenient analogues...for postal +# and telegraph services." Summer time would be in effect from 17 April to 4 +# October, with the spring change explicitly specified by bringing clocks +# forward from 16 April 23:00. +# https://dre.pt/dr/detalhe/decreto/9592-1924-652133 +# https://dre.pt/application/conteudo/652133 +# +# Decreto 10700, issued 1925-04-16, noted that Spain had not continued summer +# time, declared that "the current legal hour prior to 17 April remains +# unchanged from that day forward", and revoked legislation to the contrary, +# just a day before summer time would have otherwise resumed. +# https://dre.pt/dr/detalhe/decreto/10700-1925-437826 +# https://dre.pt/application/conteudo/437826 Rule Port 1924 only - Apr 16 23:00s 1:00 S -Rule Port 1924 only - Oct 14 23:00s 0 - +Rule Port 1924 only - Oct 4 23:00s 0 - Rule Port 1926 only - Apr 17 23:00s 1:00 S Rule Port 1926 1929 - Oct Sat>=1 23:00s 0 - Rule Port 1927 only - Apr 9 23:00s 1:00 S @@ -2116,6 +2162,8 @@ Rule Port 1931 1932 - Oct Sat>=1 23:00s 0 - Rule Port 1932 only - Apr 2 23:00s 1:00 S Rule Port 1934 only - Apr 7 23:00s 1:00 S # Whitman gives 1934 Oct 5; go with Shanks & Pottenger. +# Note: The 1935 law specified 10-06 00:00, not 10-05 24:00, but the following +# is equivalent and more succinct. Rule Port 1934 1938 - Oct Sat>=1 23:00s 0 - # Shanks & Pottenger give 1935 Apr 30; go with Whitman. Rule Port 1935 only - Mar 30 23:00s 1:00 S @@ -2126,10 +2174,19 @@ Rule Port 1938 only - Mar 26 23:00s 1:00 S Rule Port 1939 only - Apr 15 23:00s 1:00 S # Whitman gives 1939 Oct 7; go with Shanks & Pottenger. Rule Port 1939 only - Nov 18 23:00s 0 - +# From Tim Parenti (2024-07-01): +# Portaria 9465 of 1940-02-17 advanced clocks from Saturday 1940-02-24 23:00. +# The clocks were restored by Portaria 9658, issued Monday 1940-10-07, +# effective from 24:00 that very night, which agrees with Shanks & Pottenger; +# Whitman gives Saturday 1940-10-05 instead. +# https://dre.pt/dr/detalhe/portaria/9465-1940-189096 +# https://dre.pt/application/conteudo/189096 +# https://dre.pt/dr/detalhe/portaria/9658-1940-196729 +# https://dre.pt/application/conteudo/196729 Rule Port 1940 only - Feb 24 23:00s 1:00 S -# Shanks & Pottenger give 1940 Oct 7; go with Whitman. -Rule Port 1940 1941 - Oct 5 23:00s 0 - +Rule Port 1940 only - Oct 7 23:00s 0 - Rule Port 1941 only - Apr 5 23:00s 1:00 S +Rule Port 1941 only - Oct 5 23:00s 0 - Rule Port 1942 1945 - Mar Sat>=8 23:00s 1:00 S Rule Port 1942 only - Apr 25 22:00s 2:00 M # Midsummer Rule Port 1942 only - Aug 15 22:00s 1:00 S @@ -2139,66 +2196,195 @@ Rule Port 1943 1945 - Aug Sat>=25 22:00s 1:00 S Rule Port 1944 1945 - Apr Sat>=21 22:00s 2:00 M Rule Port 1946 only - Apr Sat>=1 23:00s 1:00 S Rule Port 1946 only - Oct Sat>=1 23:00s 0 - -# Whitman says DST was not observed in 1950; go with Shanks & Pottenger. -# Whitman gives Oct lastSun for 1952 on; go with Shanks & Pottenger. -Rule Port 1947 1965 - Apr Sun>=1 2:00s 1:00 S +# From Tim Parenti (2024-07-01), per Alois Treindl (2021-02-07): +# The Astronomical Observatory of Lisbon cites Portaria 11767 of 1947-03-28 for +# 1947 and Portaria 12286 of 1948-02-19 for 1948. +# https://dre.pt/dr/detalhe/portaria/11767-1947-414787 +# https://dre.pt/application/conteudo/414787 +# https://dre.pt/dr/detalhe/portaria/12286-1948-152953 +# https://dre.pt/application/conteudo/152953 +# +# Although the latter ordinance explicitly had the 1948-10-03 transition +# scheduled for 02:00 rather than 03:00 as had been used in 1947, Decreto-Lei +# 37048 of 1948-09-07 recognized "that it is advisable to definitely set...the +# 'summer time' regime", and fixed the fall transition at 03:00 moving forward. +# https://dre.pt/dr/detalhe/decreto-lei/37048-1948-373810 +# https://dre.pt/application/conteudo/373810 +# While the Observatory only cites this act for 1949-1965 and not for 1948, it +# does not appear to have had any provision delaying its effect, so assume that +# it overrode the prior ordinance for 1948-10-03. +# +# Whitman says DST was not observed in 1950 and gives Oct lastSun for 1952 on. +# The Observatory, however, agrees with Shanks & Pottenger that 1950 was not an +# exception and that Oct Sun>=1 was maintained through 1965. +Rule Port 1947 1966 - Apr Sun>=1 2:00s 1:00 S Rule Port 1947 1965 - Oct Sun>=1 2:00s 0 - -Rule Port 1977 only - Mar 27 0:00s 1:00 S -Rule Port 1977 only - Sep 25 0:00s 0 - -Rule Port 1978 1979 - Apr Sun>=1 0:00s 1:00 S -Rule Port 1978 only - Oct 1 0:00s 0 - -Rule Port 1979 1982 - Sep lastSun 1:00s 0 - -Rule Port 1980 only - Mar lastSun 0:00s 1:00 S -Rule Port 1981 1982 - Mar lastSun 1:00s 1:00 S -Rule Port 1983 only - Mar lastSun 2:00s 1:00 S +# From Tim Parenti (2024-07-01): +# Decreto-Lei 47233 of 1966-10-01 considered that the "duality" in time was +# "the cause of serious disturbances" and noted that "the countries with which +# we have the most frequent contacts...have already adopted" a solution +# coinciding with the extant "summer time". It established that the former +# "summer time" would apply year-round on the mainland and adjacent islands +# with immediate effect, as the fall back would have otherwise occurred later +# that evening. +# https://dre.pt/dr/detalhe/decreto-lei/47233-1966-293729 +# Model this by changing zones without changing clocks at the +# previously-appointed fall back time. +# +# Decreto-Lei 309/76 of 1976-04-27 acknowledged that those international +# contacts had returned to adopting seasonal times, and considered that the +# year-round advancement "entails considerable sacrifices for the vast majority +# of the working population during the winter months", including morning +# visibility concerns for schoolchildren. It specified, beginning 1976-09-26 +# 01:00, an annual return to UT+00 on the mainland from 00:00 UT on Sep lastSun +# to 00:00 UT on Mar lastSun (unless the latter date fell on Easter, in which +# case it was to be brought forward to the preceding Sunday). It also assigned +# the Permanent Time Commission to study and propose revisions for the Azores +# and Madeira, neither of which resumed DST until 1982 (as described further +# below). +# https://dre.pt/dr/detalhe/decreto-lei/309-1976-502063 +Rule Port 1976 only - Sep lastSun 1:00 0 - +Rule Port 1977 only - Mar lastSun 0:00s 1:00 S +Rule Port 1977 only - Sep lastSun 0:00s 0 - +# From Tim Parenti (2024-07-01): +# Beginning in 1978, rather than triggering the Easter rule of the 1976 decree +# (Easter fell on 1978-03-26), Article 5 was used instead, which allowed DST +# dates to be changed by order of the Minister of Education and Scientific +# Research, upon consultation with the Permanent Time Commission, "whenever +# considered convenient." As such, a series of one-off ordinances were +# promulgated for the mainland in 1978 through 1980, after which the 1976 +# decree naturally came back into force from 1981. +Rule Port 1978 1980 - Apr Sun>=1 1:00s 1:00 S +Rule Port 1978 only - Oct 1 1:00s 0 - +Rule Port 1979 1980 - Sep lastSun 1:00s 0 - +Rule Port 1981 1986 - Mar lastSun 0:00s 1:00 S +Rule Port 1981 1985 - Sep lastSun 0:00s 0 - +# From Tim Parenti (2024-07-01): +# Decreto-Lei 44-B/86 of 1986-03-07 switched mainland Portugal's transition +# times from 0:00s to 1:00u to harmonize with the EEC from 1986-03-30. +# https://dre.pt/dr/detalhe/decreto-lei/44-b-1986-628280 +# (Transitions of 1:00s as previously reported and used by the W-Eur rules, +# though equivalent, appear to have been fiction here.) Madeira continued to +# use 0:00s for spring 1986 before joining with the mainland using 1:00u in the +# fall; meanwhile, in the Azores the two were equivalent, so the law specifying +# 0:00s wasn't touched until 1992. (See below for more on the islands.) +# +# From Rui Pedro Salgueiro (1992-11-12): +# Portugal has recently (September, 27) changed timezone +# (from WET to MET or CET) to harmonize with EEC. +# +# Martin Bruckmann (1996-02-29) reports via Peter Ilieve +# that Portugal is reverting to 0:00 by not moving its clocks this spring. +# The new Prime Minister was fed up with getting up in the dark in the winter. +# +# From Paul Eggert (1996-11-12): +# IATA SSIM (1991-09) reports several 1991-09 and 1992-09 transitions +# at 02:00u, not 01:00u. Assume that these are typos. # # Zone NAME STDOFF RULES FORMAT [UNTIL] #STDOFF -0:36:44.68 Zone Europe/Lisbon -0:36:45 - LMT 1884 -0:36:45 - LMT 1912 Jan 1 0:00u # Lisbon MT - 0:00 Port WE%sT 1966 Apr 3 2:00 + 0:00 Port WE%sT 1966 Oct 2 2:00s 1:00 - CET 1976 Sep 26 1:00 - 0:00 Port WE%sT 1983 Sep 25 1:00s - 0:00 W-Eur WE%sT 1992 Sep 27 1:00s + 0:00 Port WE%sT 1986 + 0:00 EU WE%sT 1992 Sep 27 1:00u 1:00 EU CE%sT 1996 Mar 31 1:00u 0:00 EU WE%sT + +# From Tim Parenti (2024-07-01): +# For the Azores and Madeira, legislation was followed from the laws currently +# in force as listed at: +# https://oal.ul.pt/hora-legal/legislacao/ +# working backward through references of revocation and abrogation to +# Decreto-Lei 47233 of 1966-10-01, the last time DST was abolished across the +# mainland and its adjacent islands. Because of that reference, it is +# therefore assumed that DST rules in the islands prior to 1966 were like that +# of the mainland, though most legislation of the time didn't explicitly +# specify DST practices for the islands. Zone Atlantic/Azores -1:42:40 - LMT 1884 # Ponta Delgada -1:54:32 - HMT 1912 Jan 1 2:00u # Horta MT # Vanguard section, for zic and other parsers that support %z. -# -2:00 Port %z 1966 Apr 3 2:00 -# -1:00 Port %z 1983 Sep 25 1:00s -# -1:00 W-Eur %z 1992 Sep 27 1:00s + -2:00 Port %z 1966 Oct 2 2:00s +# From Tim Parenti (2024-07-01): +# While Decreto-Lei 309/76 of 1976-04-27 reintroduced DST on the mainland by +# falling back on 1976-09-26, it assigned the Permanent Time Commission to +# study and propose revisions for the Azores and Madeira. Decreto Regional +# 9/77/A of 1977-05-17 affirmed that "the legal time remained unchanged in the +# Azores" at UT-1, and would remain there year-round. +# https://dre.pt/dr/detalhe/decreto-regional/9-1977-252066 +# +# Decreto Regional 2/82/A, published 1982-03-02, adopted DST in the same +# fashion as the mainland used at the time. +# https://dre.pt/dr/detalhe/decreto-regional/2-1982-599965 +# Though transitions in the Azores officially remained at 0:00s through 1992, +# this was equivalent to the EU-style 1:00u adopted by the mainland in 1986, so +# model it as such. + -1:00 - %z 1982 Mar 28 0:00s + -1:00 Port %z 1986 # Rearguard section, for parsers lacking %z; see ziguard.awk. - -2:00 Port -02/-01 1942 Apr 25 22:00s - -2:00 Port +00 1942 Aug 15 22:00s - -2:00 Port -02/-01 1943 Apr 17 22:00s - -2:00 Port +00 1943 Aug 28 22:00s - -2:00 Port -02/-01 1944 Apr 22 22:00s - -2:00 Port +00 1944 Aug 26 22:00s - -2:00 Port -02/-01 1945 Apr 21 22:00s - -2:00 Port +00 1945 Aug 25 22:00s - -2:00 Port -02/-01 1966 Apr 3 2:00 - -1:00 Port -01/+00 1983 Sep 25 1:00s - -1:00 W-Eur -01/+00 1992 Sep 27 1:00s +# -2:00 Port -02/-01 1942 Apr 25 22:00s +# -2:00 Port +00 1942 Aug 15 22:00s +# -2:00 Port -02/-01 1943 Apr 17 22:00s +# -2:00 Port +00 1943 Aug 28 22:00s +# -2:00 Port -02/-01 1944 Apr 22 22:00s +# -2:00 Port +00 1944 Aug 26 22:00s +# -2:00 Port -02/-01 1945 Apr 21 22:00s +# -2:00 Port +00 1945 Aug 25 22:00s +# -2:00 Port -02/-01 1966 Oct 2 2:00s +# -1:00 - -01 1982 Mar 28 0:00s +# -1:00 Port -01/+00 1986 # End of rearguard section. - 0:00 EU WE%sT 1993 Mar 28 1:00u - -1:00 EU -01/+00 +# +# From Paul Eggert (1996-11-12): +# IATA SSIM (1991/1992) reports that the Azores were at -1:00. +# IATA SSIM (1993-02) says +0:00; later issues (through 1996-09) say -1:00. +# +# From Tim Parenti (2024-07-01): +# After mainland Portugal had shifted forward an hour from 1992-09-27, Decreto +# Legislativo Regional 29/92/A of 1992-12-23 sought to "reduce the time +# difference" by shifting the Azores forward as well from 1992-12-27. Just six +# months later, this was revoked by Decreto Legislativo Regional 9/93/A, citing +# "major changes in work habits and way of life." Though the revocation didn't +# give a transition time, it was signed Wednesday 1993-06-16; assume it took +# effect later that evening, and that an EU-style spring forward (to +01) was +# still observed in the interim on 1993-03-28. +# https://dre.pt/dr/detalhe/decreto-legislativo-regional/29-1992-621553 +# https://dre.pt/dr/detalhe/decreto-legislativo-regional/9-1993-389633 + -1:00 EU %z 1992 Dec 27 1:00s + 0:00 EU WE%sT 1993 Jun 17 1:00u + -1:00 EU %z + Zone Atlantic/Madeira -1:07:36 - LMT 1884 # Funchal -1:07:36 - FMT 1912 Jan 1 1:00u # Funchal MT # Vanguard section, for zic and other parsers that support %z. -# -1:00 Port %z 1966 Apr 3 2:00 + -1:00 Port %z 1966 Oct 2 2:00s # Rearguard section, for parsers lacking %z; see ziguard.awk. - -1:00 Port -01/+00 1942 Apr 25 22:00s - -1:00 Port +01 1942 Aug 15 22:00s - -1:00 Port -01/+00 1943 Apr 17 22:00s - -1:00 Port +01 1943 Aug 28 22:00s - -1:00 Port -01/+00 1944 Apr 22 22:00s - -1:00 Port +01 1944 Aug 26 22:00s - -1:00 Port -01/+00 1945 Apr 21 22:00s - -1:00 Port +01 1945 Aug 25 22:00s - -1:00 Port -01/+00 1966 Apr 3 2:00 +# -1:00 Port -01/+00 1942 Apr 25 22:00s +# -1:00 Port +01 1942 Aug 15 22:00s +# -1:00 Port -01/+00 1943 Apr 17 22:00s +# -1:00 Port +01 1943 Aug 28 22:00s +# -1:00 Port -01/+00 1944 Apr 22 22:00s +# -1:00 Port +01 1944 Aug 26 22:00s +# -1:00 Port -01/+00 1945 Apr 21 22:00s +# -1:00 Port +01 1945 Aug 25 22:00s +# -1:00 Port -01/+00 1966 Oct 2 2:00s # End of rearguard section. - 0:00 Port WE%sT 1983 Sep 25 1:00s +# +# From Tim Parenti (2024-07-01): +# Decreto Regional 5/82/M, published 1982-04-03, established DST transitions at +# 0:00u, which for Madeira is equivalent to the mainland's rules (0:00s) at the +# time. It came into effect the day following its publication, Sunday +# 1982-04-04, thus resuming Madeira's DST practice about a week later than the +# mainland and the Azores. +# https://dre.pt/dr/detalhe/decreto-regional/5-1982-608273 +# +# Decreto Legislativo Regional 18/86/M, published 1986-10-01, adopted EU-style +# rules (1:00u) and entered into immediate force after being signed on +# 1986-07-31. +# https://dre.pt/dr/detalhe/decreto-legislativo-regional/18-1986-221705 + 0:00 - WET 1982 Apr 4 + 0:00 Port WE%sT 1986 Jul 31 0:00 EU WE%sT # Romania @@ -2410,7 +2596,7 @@ Zone Europe/Kaliningrad 1:22:00 - LMT 1893 Apr 2:00 Poland EE%sT 1946 Apr 7 3:00 Russia MSK/MSD 1989 Mar 26 2:00s 2:00 Russia EE%sT 2011 Mar 27 2:00s - 3:00 - +03 2014 Oct 26 2:00s + 3:00 - %z 2014 Oct 26 2:00s 2:00 - EET @@ -2660,14 +2846,14 @@ Zone Europe/Simferopol 2:16:24 - LMT 1880 # http://publication.pravo.gov.ru/Document/View/0001201602150056 Zone Europe/Astrakhan 3:12:12 - LMT 1924 May - 3:00 - +03 1930 Jun 21 - 4:00 Russia +04/+05 1989 Mar 26 2:00s - 3:00 Russia +03/+04 1991 Mar 31 2:00s - 4:00 - +04 1992 Mar 29 2:00s - 3:00 Russia +03/+04 2011 Mar 27 2:00s - 4:00 - +04 2014 Oct 26 2:00s - 3:00 - +03 2016 Mar 27 2:00s - 4:00 - +04 + 3:00 - %z 1930 Jun 21 + 4:00 Russia %z 1989 Mar 26 2:00s + 3:00 Russia %z 1991 Mar 31 2:00s + 4:00 - %z 1992 Mar 29 2:00s + 3:00 Russia %z 2011 Mar 27 2:00s + 4:00 - %z 2014 Oct 26 2:00s + 3:00 - %z 2016 Mar 27 2:00s + 4:00 - %z # From Paul Eggert (2016-11-11): # Europe/Volgograd covers: @@ -2697,15 +2883,15 @@ Zone Europe/Astrakhan 3:12:12 - LMT 1924 May # http://publication.pravo.gov.ru/Document/View/0001202012220002 Zone Europe/Volgograd 2:57:40 - LMT 1920 Jan 3 - 3:00 - +03 1930 Jun 21 - 4:00 - +04 1961 Nov 11 - 4:00 Russia +04/+05 1988 Mar 27 2:00s + 3:00 - %z 1930 Jun 21 + 4:00 - %z 1961 Nov 11 + 4:00 Russia %z 1988 Mar 27 2:00s 3:00 Russia MSK/MSD 1991 Mar 31 2:00s - 4:00 - +04 1992 Mar 29 2:00s + 4:00 - %z 1992 Mar 29 2:00s 3:00 Russia MSK/MSD 2011 Mar 27 2:00s 4:00 - MSK 2014 Oct 26 2:00s 3:00 - MSK 2018 Oct 28 2:00s - 4:00 - +04 2020 Dec 27 2:00s + 4:00 - %z 2020 Dec 27 2:00s 3:00 - MSK # From Paul Eggert (2016-11-11): @@ -2720,14 +2906,14 @@ Zone Europe/Volgograd 2:57:40 - LMT 1920 Jan 3 # http://publication.pravo.gov.ru/Document/View/0001201611220031 Zone Europe/Saratov 3:04:18 - LMT 1919 Jul 1 0:00u - 3:00 - +03 1930 Jun 21 - 4:00 Russia +04/+05 1988 Mar 27 2:00s - 3:00 Russia +03/+04 1991 Mar 31 2:00s - 4:00 - +04 1992 Mar 29 2:00s - 3:00 Russia +03/+04 2011 Mar 27 2:00s - 4:00 - +04 2014 Oct 26 2:00s - 3:00 - +03 2016 Dec 4 2:00s - 4:00 - +04 + 3:00 - %z 1930 Jun 21 + 4:00 Russia %z 1988 Mar 27 2:00s + 3:00 Russia %z 1991 Mar 31 2:00s + 4:00 - %z 1992 Mar 29 2:00s + 3:00 Russia %z 2011 Mar 27 2:00s + 4:00 - %z 2014 Oct 26 2:00s + 3:00 - %z 2016 Dec 4 2:00s + 4:00 - %z # From Paul Eggert (2016-03-18): # Europe/Kirov covers: @@ -2735,10 +2921,10 @@ Zone Europe/Saratov 3:04:18 - LMT 1919 Jul 1 0:00u # The 1989 transition is from USSR act No. 227 (1989-03-14). # Zone Europe/Kirov 3:18:48 - LMT 1919 Jul 1 0:00u - 3:00 - +03 1930 Jun 21 - 4:00 Russia +04/+05 1989 Mar 26 2:00s + 3:00 - %z 1930 Jun 21 + 4:00 Russia %z 1989 Mar 26 2:00s 3:00 Russia MSK/MSD 1991 Mar 31 2:00s - 4:00 - +04 1992 Mar 29 2:00s + 4:00 - %z 1992 Mar 29 2:00s 3:00 Russia MSK/MSD 2011 Mar 27 2:00s 4:00 - MSK 2014 Oct 26 2:00s 3:00 - MSK @@ -2753,15 +2939,15 @@ Zone Europe/Kirov 3:18:48 - LMT 1919 Jul 1 0:00u # The 1989 transition is from USSR act No. 227 (1989-03-14). Zone Europe/Samara 3:20:20 - LMT 1919 Jul 1 0:00u - 3:00 - +03 1930 Jun 21 - 4:00 - +04 1935 Jan 27 - 4:00 Russia +04/+05 1989 Mar 26 2:00s - 3:00 Russia +03/+04 1991 Mar 31 2:00s - 2:00 Russia +02/+03 1991 Sep 29 2:00s - 3:00 - +03 1991 Oct 20 3:00 - 4:00 Russia +04/+05 2010 Mar 28 2:00s - 3:00 Russia +03/+04 2011 Mar 27 2:00s - 4:00 - +04 + 3:00 - %z 1930 Jun 21 + 4:00 - %z 1935 Jan 27 + 4:00 Russia %z 1989 Mar 26 2:00s + 3:00 Russia %z 1991 Mar 31 2:00s + 2:00 Russia %z 1991 Sep 29 2:00s + 3:00 - %z 1991 Oct 20 3:00 + 4:00 Russia %z 2010 Mar 28 2:00s + 3:00 Russia %z 2011 Mar 27 2:00s + 4:00 - %z # From Paul Eggert (2016-03-18): # Europe/Ulyanovsk covers: @@ -2777,14 +2963,14 @@ Zone Europe/Samara 3:20:20 - LMT 1919 Jul 1 0:00u # http://publication.pravo.gov.ru/Document/View/0001201603090051 Zone Europe/Ulyanovsk 3:13:36 - LMT 1919 Jul 1 0:00u - 3:00 - +03 1930 Jun 21 - 4:00 Russia +04/+05 1989 Mar 26 2:00s - 3:00 Russia +03/+04 1991 Mar 31 2:00s - 2:00 Russia +02/+03 1992 Jan 19 2:00s - 3:00 Russia +03/+04 2011 Mar 27 2:00s - 4:00 - +04 2014 Oct 26 2:00s - 3:00 - +03 2016 Mar 27 2:00s - 4:00 - +04 + 3:00 - %z 1930 Jun 21 + 4:00 Russia %z 1989 Mar 26 2:00s + 3:00 Russia %z 1991 Mar 31 2:00s + 2:00 Russia %z 1992 Jan 19 2:00s + 3:00 Russia %z 2011 Mar 27 2:00s + 4:00 - %z 2014 Oct 26 2:00s + 3:00 - %z 2016 Mar 27 2:00s + 4:00 - %z # From Tim Parenti (2014-07-03), per Oscar van Vlijmen (2001-08-25): # Asia/Yekaterinburg covers... @@ -2809,12 +2995,12 @@ Zone Europe/Ulyanovsk 3:13:36 - LMT 1919 Jul 1 0:00u #STDOFF 4:02:32.9 Zone Asia/Yekaterinburg 4:02:33 - LMT 1916 Jul 3 3:45:05 - PMT 1919 Jul 15 4:00 - 4:00 - +04 1930 Jun 21 - 5:00 Russia +05/+06 1991 Mar 31 2:00s - 4:00 Russia +04/+05 1992 Jan 19 2:00s - 5:00 Russia +05/+06 2011 Mar 27 2:00s - 6:00 - +06 2014 Oct 26 2:00s - 5:00 - +05 + 4:00 - %z 1930 Jun 21 + 5:00 Russia %z 1991 Mar 31 2:00s + 4:00 Russia %z 1992 Jan 19 2:00s + 5:00 Russia %z 2011 Mar 27 2:00s + 6:00 - %z 2014 Oct 26 2:00s + 5:00 - %z # From Tim Parenti (2014-07-03), per Oscar van Vlijmen (2001-08-25): @@ -2824,12 +3010,12 @@ Zone Asia/Yekaterinburg 4:02:33 - LMT 1916 Jul 3 # Byalokoz 1919 says Omsk was 4:53:30. Zone Asia/Omsk 4:53:30 - LMT 1919 Nov 14 - 5:00 - +05 1930 Jun 21 - 6:00 Russia +06/+07 1991 Mar 31 2:00s - 5:00 Russia +05/+06 1992 Jan 19 2:00s - 6:00 Russia +06/+07 2011 Mar 27 2:00s - 7:00 - +07 2014 Oct 26 2:00s - 6:00 - +06 + 5:00 - %z 1930 Jun 21 + 6:00 Russia %z 1991 Mar 31 2:00s + 5:00 Russia %z 1992 Jan 19 2:00s + 6:00 Russia %z 2011 Mar 27 2:00s + 7:00 - %z 2014 Oct 26 2:00s + 6:00 - %z # From Paul Eggert (2016-02-22): # Asia/Barnaul covers: @@ -2862,14 +3048,14 @@ Zone Asia/Omsk 4:53:30 - LMT 1919 Nov 14 # http://publication.pravo.gov.ru/Document/View/0001201603090038 Zone Asia/Barnaul 5:35:00 - LMT 1919 Dec 10 - 6:00 - +06 1930 Jun 21 - 7:00 Russia +07/+08 1991 Mar 31 2:00s - 6:00 Russia +06/+07 1992 Jan 19 2:00s - 7:00 Russia +07/+08 1995 May 28 - 6:00 Russia +06/+07 2011 Mar 27 2:00s - 7:00 - +07 2014 Oct 26 2:00s - 6:00 - +06 2016 Mar 27 2:00s - 7:00 - +07 + 6:00 - %z 1930 Jun 21 + 7:00 Russia %z 1991 Mar 31 2:00s + 6:00 Russia %z 1992 Jan 19 2:00s + 7:00 Russia %z 1995 May 28 + 6:00 Russia %z 2011 Mar 27 2:00s + 7:00 - %z 2014 Oct 26 2:00s + 6:00 - %z 2016 Mar 27 2:00s + 7:00 - %z # From Paul Eggert (2016-03-18): # Asia/Novosibirsk covers: @@ -2883,14 +3069,14 @@ Zone Asia/Barnaul 5:35:00 - LMT 1919 Dec 10 # http://publication.pravo.gov.ru/Document/View/0001201607040064 Zone Asia/Novosibirsk 5:31:40 - LMT 1919 Dec 14 6:00 - 6:00 - +06 1930 Jun 21 - 7:00 Russia +07/+08 1991 Mar 31 2:00s - 6:00 Russia +06/+07 1992 Jan 19 2:00s - 7:00 Russia +07/+08 1993 May 23 # say Shanks & P. - 6:00 Russia +06/+07 2011 Mar 27 2:00s - 7:00 - +07 2014 Oct 26 2:00s - 6:00 - +06 2016 Jul 24 2:00s - 7:00 - +07 + 6:00 - %z 1930 Jun 21 + 7:00 Russia %z 1991 Mar 31 2:00s + 6:00 Russia %z 1992 Jan 19 2:00s + 7:00 Russia %z 1993 May 23 # say Shanks & P. + 6:00 Russia %z 2011 Mar 27 2:00s + 7:00 - %z 2014 Oct 26 2:00s + 6:00 - %z 2016 Jul 24 2:00s + 7:00 - %z # From Paul Eggert (2016-03-18): # Asia/Tomsk covers: @@ -2935,14 +3121,14 @@ Zone Asia/Novosibirsk 5:31:40 - LMT 1919 Dec 14 6:00 # http://publication.pravo.gov.ru/Document/View/0001201604260048 Zone Asia/Tomsk 5:39:51 - LMT 1919 Dec 22 - 6:00 - +06 1930 Jun 21 - 7:00 Russia +07/+08 1991 Mar 31 2:00s - 6:00 Russia +06/+07 1992 Jan 19 2:00s - 7:00 Russia +07/+08 2002 May 1 3:00 - 6:00 Russia +06/+07 2011 Mar 27 2:00s - 7:00 - +07 2014 Oct 26 2:00s - 6:00 - +06 2016 May 29 2:00s - 7:00 - +07 + 6:00 - %z 1930 Jun 21 + 7:00 Russia %z 1991 Mar 31 2:00s + 6:00 Russia %z 1992 Jan 19 2:00s + 7:00 Russia %z 2002 May 1 3:00 + 6:00 Russia %z 2011 Mar 27 2:00s + 7:00 - %z 2014 Oct 26 2:00s + 6:00 - %z 2016 May 29 2:00s + 7:00 - %z # From Tim Parenti (2014-07-03): @@ -2973,12 +3159,12 @@ Zone Asia/Tomsk 5:39:51 - LMT 1919 Dec 22 # realigning itself with KRAT. Zone Asia/Novokuznetsk 5:48:48 - LMT 1924 May 1 - 6:00 - +06 1930 Jun 21 - 7:00 Russia +07/+08 1991 Mar 31 2:00s - 6:00 Russia +06/+07 1992 Jan 19 2:00s - 7:00 Russia +07/+08 2010 Mar 28 2:00s - 6:00 Russia +06/+07 2011 Mar 27 2:00s - 7:00 - +07 + 6:00 - %z 1930 Jun 21 + 7:00 Russia %z 1991 Mar 31 2:00s + 6:00 Russia %z 1992 Jan 19 2:00s + 7:00 Russia %z 2010 Mar 28 2:00s + 6:00 Russia %z 2011 Mar 27 2:00s + 7:00 - %z # From Tim Parenti (2014-07-03), per Oscar van Vlijmen (2001-08-25): # Asia/Krasnoyarsk covers... @@ -2992,12 +3178,12 @@ Zone Asia/Novokuznetsk 5:48:48 - LMT 1924 May 1 # Byalokoz 1919 says Krasnoyarsk was 6:11:26. Zone Asia/Krasnoyarsk 6:11:26 - LMT 1920 Jan 6 - 6:00 - +06 1930 Jun 21 - 7:00 Russia +07/+08 1991 Mar 31 2:00s - 6:00 Russia +06/+07 1992 Jan 19 2:00s - 7:00 Russia +07/+08 2011 Mar 27 2:00s - 8:00 - +08 2014 Oct 26 2:00s - 7:00 - +07 + 6:00 - %z 1930 Jun 21 + 7:00 Russia %z 1991 Mar 31 2:00s + 6:00 Russia %z 1992 Jan 19 2:00s + 7:00 Russia %z 2011 Mar 27 2:00s + 8:00 - %z 2014 Oct 26 2:00s + 7:00 - %z # From Tim Parenti (2014-07-03), per Oscar van Vlijmen (2001-08-25): @@ -3014,12 +3200,12 @@ Zone Asia/Krasnoyarsk 6:11:26 - LMT 1920 Jan 6 Zone Asia/Irkutsk 6:57:05 - LMT 1880 6:57:05 - IMT 1920 Jan 25 # Irkutsk Mean Time - 7:00 - +07 1930 Jun 21 - 8:00 Russia +08/+09 1991 Mar 31 2:00s - 7:00 Russia +07/+08 1992 Jan 19 2:00s - 8:00 Russia +08/+09 2011 Mar 27 2:00s - 9:00 - +09 2014 Oct 26 2:00s - 8:00 - +08 + 7:00 - %z 1930 Jun 21 + 8:00 Russia %z 1991 Mar 31 2:00s + 7:00 Russia %z 1992 Jan 19 2:00s + 8:00 Russia %z 2011 Mar 27 2:00s + 9:00 - %z 2014 Oct 26 2:00s + 8:00 - %z # From Tim Parenti (2014-07-06): @@ -3036,13 +3222,13 @@ Zone Asia/Irkutsk 6:57:05 - LMT 1880 # http://publication.pravo.gov.ru/Document/View/0001201512300107 Zone Asia/Chita 7:33:52 - LMT 1919 Dec 15 - 8:00 - +08 1930 Jun 21 - 9:00 Russia +09/+10 1991 Mar 31 2:00s - 8:00 Russia +08/+09 1992 Jan 19 2:00s - 9:00 Russia +09/+10 2011 Mar 27 2:00s - 10:00 - +10 2014 Oct 26 2:00s - 8:00 - +08 2016 Mar 27 2:00 - 9:00 - +09 + 8:00 - %z 1930 Jun 21 + 9:00 Russia %z 1991 Mar 31 2:00s + 8:00 Russia %z 1992 Jan 19 2:00s + 9:00 Russia %z 2011 Mar 27 2:00s + 10:00 - %z 2014 Oct 26 2:00s + 8:00 - %z 2016 Mar 27 2:00 + 9:00 - %z # From Tim Parenti (2014-07-03), per Oscar van Vlijmen (2009-11-29): @@ -3082,12 +3268,12 @@ Zone Asia/Chita 7:33:52 - LMT 1919 Dec 15 # Byalokoz 1919 says Yakutsk was 8:38:58. Zone Asia/Yakutsk 8:38:58 - LMT 1919 Dec 15 - 8:00 - +08 1930 Jun 21 - 9:00 Russia +09/+10 1991 Mar 31 2:00s - 8:00 Russia +08/+09 1992 Jan 19 2:00s - 9:00 Russia +09/+10 2011 Mar 27 2:00s - 10:00 - +10 2014 Oct 26 2:00s - 9:00 - +09 + 8:00 - %z 1930 Jun 21 + 9:00 Russia %z 1991 Mar 31 2:00s + 8:00 Russia %z 1992 Jan 19 2:00s + 9:00 Russia %z 2011 Mar 27 2:00s + 10:00 - %z 2014 Oct 26 2:00s + 9:00 - %z # From Tim Parenti (2014-07-03), per Oscar van Vlijmen (2009-11-29): @@ -3105,12 +3291,12 @@ Zone Asia/Yakutsk 8:38:58 - LMT 1919 Dec 15 # Go with Byalokoz. Zone Asia/Vladivostok 8:47:31 - LMT 1922 Nov 15 - 9:00 - +09 1930 Jun 21 - 10:00 Russia +10/+11 1991 Mar 31 2:00s - 9:00 Russia +09/+10 1992 Jan 19 2:00s - 10:00 Russia +10/+11 2011 Mar 27 2:00s - 11:00 - +11 2014 Oct 26 2:00s - 10:00 - +10 + 9:00 - %z 1930 Jun 21 + 10:00 Russia %z 1991 Mar 31 2:00s + 9:00 Russia %z 1992 Jan 19 2:00s + 10:00 Russia %z 2011 Mar 27 2:00s + 11:00 - %z 2014 Oct 26 2:00s + 10:00 - %z # From Tim Parenti (2014-07-03): @@ -3128,14 +3314,14 @@ Zone Asia/Vladivostok 8:47:31 - LMT 1922 Nov 15 # This transition is no doubt wrong, but we have no better info. Zone Asia/Khandyga 9:02:13 - LMT 1919 Dec 15 - 8:00 - +08 1930 Jun 21 - 9:00 Russia +09/+10 1991 Mar 31 2:00s - 8:00 Russia +08/+09 1992 Jan 19 2:00s - 9:00 Russia +09/+10 2004 - 10:00 Russia +10/+11 2011 Mar 27 2:00s - 11:00 - +11 2011 Sep 13 0:00s # Decree 725? - 10:00 - +10 2014 Oct 26 2:00s - 9:00 - +09 + 8:00 - %z 1930 Jun 21 + 9:00 Russia %z 1991 Mar 31 2:00s + 8:00 Russia %z 1992 Jan 19 2:00s + 9:00 Russia %z 2004 + 10:00 Russia %z 2011 Mar 27 2:00s + 11:00 - %z 2011 Sep 13 0:00s # Decree 725? + 10:00 - %z 2014 Oct 26 2:00s + 9:00 - %z # From Tim Parenti (2014-07-03): @@ -3151,14 +3337,14 @@ Zone Asia/Khandyga 9:02:13 - LMT 1919 Dec 15 # The Zone name should be Asia/Yuzhno-Sakhalinsk, but that's too long. Zone Asia/Sakhalin 9:30:48 - LMT 1905 Aug 23 - 9:00 - +09 1945 Aug 25 - 11:00 Russia +11/+12 1991 Mar 31 2:00s # Sakhalin T - 10:00 Russia +10/+11 1992 Jan 19 2:00s - 11:00 Russia +11/+12 1997 Mar lastSun 2:00s - 10:00 Russia +10/+11 2011 Mar 27 2:00s - 11:00 - +11 2014 Oct 26 2:00s - 10:00 - +10 2016 Mar 27 2:00s - 11:00 - +11 + 9:00 - %z 1945 Aug 25 + 11:00 Russia %z 1991 Mar 31 2:00s # Sakhalin T + 10:00 Russia %z 1992 Jan 19 2:00s + 11:00 Russia %z 1997 Mar lastSun 2:00s + 10:00 Russia %z 2011 Mar 27 2:00s + 11:00 - %z 2014 Oct 26 2:00s + 10:00 - %z 2016 Mar 27 2:00s + 11:00 - %z # From Tim Parenti (2014-07-03), per Oscar van Vlijmen (2009-11-29): @@ -3181,13 +3367,13 @@ Zone Asia/Sakhalin 9:30:48 - LMT 1905 Aug 23 # http://publication.pravo.gov.ru/Document/View/0001201604050038 Zone Asia/Magadan 10:03:12 - LMT 1924 May 2 - 10:00 - +10 1930 Jun 21 # Magadan Time - 11:00 Russia +11/+12 1991 Mar 31 2:00s - 10:00 Russia +10/+11 1992 Jan 19 2:00s - 11:00 Russia +11/+12 2011 Mar 27 2:00s - 12:00 - +12 2014 Oct 26 2:00s - 10:00 - +10 2016 Apr 24 2:00s - 11:00 - +11 + 10:00 - %z 1930 Jun 21 # Magadan Time + 11:00 Russia %z 1991 Mar 31 2:00s + 10:00 Russia %z 1992 Jan 19 2:00s + 11:00 Russia %z 2011 Mar 27 2:00s + 12:00 - %z 2014 Oct 26 2:00s + 10:00 - %z 2016 Apr 24 2:00s + 11:00 - %z # From Tim Parenti (2014-07-06): @@ -3232,12 +3418,12 @@ Zone Asia/Magadan 10:03:12 - LMT 1924 May 2 # Go with Srednekolymsk. Zone Asia/Srednekolymsk 10:14:52 - LMT 1924 May 2 - 10:00 - +10 1930 Jun 21 - 11:00 Russia +11/+12 1991 Mar 31 2:00s - 10:00 Russia +10/+11 1992 Jan 19 2:00s - 11:00 Russia +11/+12 2011 Mar 27 2:00s - 12:00 - +12 2014 Oct 26 2:00s - 11:00 - +11 + 10:00 - %z 1930 Jun 21 + 11:00 Russia %z 1991 Mar 31 2:00s + 10:00 Russia %z 1992 Jan 19 2:00s + 11:00 Russia %z 2011 Mar 27 2:00s + 12:00 - %z 2014 Oct 26 2:00s + 11:00 - %z # From Tim Parenti (2014-07-03): @@ -3255,14 +3441,14 @@ Zone Asia/Srednekolymsk 10:14:52 - LMT 1924 May 2 # UTC+12 since at least then, too. Zone Asia/Ust-Nera 9:32:54 - LMT 1919 Dec 15 - 8:00 - +08 1930 Jun 21 - 9:00 Russia +09/+10 1981 Apr 1 - 11:00 Russia +11/+12 1991 Mar 31 2:00s - 10:00 Russia +10/+11 1992 Jan 19 2:00s - 11:00 Russia +11/+12 2011 Mar 27 2:00s - 12:00 - +12 2011 Sep 13 0:00s # Decree 725? - 11:00 - +11 2014 Oct 26 2:00s - 10:00 - +10 + 8:00 - %z 1930 Jun 21 + 9:00 Russia %z 1981 Apr 1 + 11:00 Russia %z 1991 Mar 31 2:00s + 10:00 Russia %z 1992 Jan 19 2:00s + 11:00 Russia %z 2011 Mar 27 2:00s + 12:00 - %z 2011 Sep 13 0:00s # Decree 725? + 11:00 - %z 2014 Oct 26 2:00s + 10:00 - %z # From Tim Parenti (2014-07-03), per Oscar van Vlijmen (2001-08-25): @@ -3275,12 +3461,12 @@ Zone Asia/Ust-Nera 9:32:54 - LMT 1919 Dec 15 # The Zone name should be Asia/Petropavlovsk-Kamchatski or perhaps # Asia/Petropavlovsk-Kamchatsky, but these are too long. Zone Asia/Kamchatka 10:34:36 - LMT 1922 Nov 10 - 11:00 - +11 1930 Jun 21 - 12:00 Russia +12/+13 1991 Mar 31 2:00s - 11:00 Russia +11/+12 1992 Jan 19 2:00s - 12:00 Russia +12/+13 2010 Mar 28 2:00s - 11:00 Russia +11/+12 2011 Mar 27 2:00s - 12:00 - +12 + 11:00 - %z 1930 Jun 21 + 12:00 Russia %z 1991 Mar 31 2:00s + 11:00 Russia %z 1992 Jan 19 2:00s + 12:00 Russia %z 2010 Mar 28 2:00s + 11:00 Russia %z 2011 Mar 27 2:00s + 12:00 - %z # From Tim Parenti (2014-07-03): @@ -3288,13 +3474,13 @@ Zone Asia/Kamchatka 10:34:36 - LMT 1922 Nov 10 # 87 RU-CHU Chukotka Autonomous Okrug Zone Asia/Anadyr 11:49:56 - LMT 1924 May 2 - 12:00 - +12 1930 Jun 21 - 13:00 Russia +13/+14 1982 Apr 1 0:00s - 12:00 Russia +12/+13 1991 Mar 31 2:00s - 11:00 Russia +11/+12 1992 Jan 19 2:00s - 12:00 Russia +12/+13 2010 Mar 28 2:00s - 11:00 Russia +11/+12 2011 Mar 27 2:00s - 12:00 - +12 + 12:00 - %z 1930 Jun 21 + 13:00 Russia %z 1982 Apr 1 0:00s + 12:00 Russia %z 1991 Mar 31 2:00s + 11:00 Russia %z 1992 Jan 19 2:00s + 12:00 Russia %z 2010 Mar 28 2:00s + 11:00 Russia %z 2011 Mar 27 2:00s + 12:00 - %z # Bosnia & Herzegovina # Croatia @@ -3413,7 +3599,7 @@ Zone Africa/Ceuta -0:21:16 - LMT 1901 Jan 1 0:00u 1:00 - CET 1986 1:00 EU CE%sT Zone Atlantic/Canary -1:01:36 - LMT 1922 Mar # Las Palmas de Gran C. - -1:00 - -01 1946 Sep 30 1:00 + -1:00 - %z 1946 Sep 30 1:00 0:00 - WET 1980 Apr 6 0:00s 0:00 1:00 WEST 1980 Sep 28 1:00u 0:00 EU WE%sT @@ -3494,8 +3680,8 @@ Zone Atlantic/Canary -1:01:36 - LMT 1922 Mar # Las Palmas de Gran C. # but if no one is present after 11 at night, could be postponed until one # hour before the beginning of service. -# From Paul Eggert (2013-09-11): -# Round BMT to the nearest even second, 0:29:46. +# From Paul Eggert (2024-05-24): +# Express BMT as 0:29:45.500, approximately the same precision 7° 26' 22.50". # # We can find no reliable source for Shanks's assertion that all of Switzerland # except Geneva switched to Bern Mean Time at 00:00 on 1848-09-12. This book: @@ -3534,6 +3720,7 @@ Rule Swiss 1941 1942 - May Mon>=1 1:00 1:00 S Rule Swiss 1941 1942 - Oct Mon>=1 2:00 0 - # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone Europe/Zurich 0:34:08 - LMT 1853 Jul 16 # See above comment. + #STDOFF 0:29:45.500 0:29:46 - BMT 1894 Jun # Bern Mean Time 1:00 Swiss CE%sT 1981 1:00 EU CE%sT @@ -3731,7 +3918,7 @@ Rule Turkey 1996 2006 - Oct lastSun 1:00s 0 - Zone Europe/Istanbul 1:55:52 - LMT 1880 1:56:56 - IMT 1910 Oct # Istanbul Mean Time? 2:00 Turkey EE%sT 1978 Jun 29 - 3:00 Turkey +03/+04 1984 Nov 1 2:00 + 3:00 Turkey %z 1984 Nov 1 2:00 2:00 Turkey EE%sT 2007 2:00 EU EE%sT 2011 Mar 27 1:00u 2:00 - EET 2011 Mar 28 1:00u @@ -3740,7 +3927,7 @@ Zone Europe/Istanbul 1:55:52 - LMT 1880 2:00 EU EE%sT 2015 Oct 25 1:00u 2:00 1:00 EEST 2015 Nov 8 1:00u 2:00 EU EE%sT 2016 Sep 7 - 3:00 - +03 + 3:00 - %z # Ukraine # diff --git a/leap-seconds.list b/leap-seconds.list index e52effc257b2..da0efc8c8566 100644 --- a/leap-seconds.list +++ b/leap-seconds.list @@ -1,5 +1,5 @@ -# ATOMIC TIME. -# The Coordinated Universal Time (UTC) is the reference time scale derived +# ATOMIC TIME +# Coordinated Universal Time (UTC) is the reference time scale derived # from The "Temps Atomique International" (TAI) calculated by the Bureau # International des Poids et Mesures (BIPM) using a worldwide network of atomic # clocks. UTC differs from TAI by an integer number of seconds; it is the basis @@ -8,34 +8,34 @@ # # ASTRONOMICAL TIME (UT1) is the time scale based on the rate of rotation of the earth. # It is now mainly derived from Very Long Baseline Interferometry (VLBI). The various -# irregular fluctuations progressively detected in the rotation rate of the Earth lead +# irregular fluctuations progressively detected in the rotation rate of the Earth led # in 1972 to the replacement of UT1 by UTC as the reference time scale. # # # LEAP SECOND -# Atomic clocks are more stable than the rate of the earth rotation since the latter +# Atomic clocks are more stable than the rate of the earth's rotation since the latter # undergoes a full range of geophysical perturbations at various time scales: lunisolar -# and core-mantle torques, atmospheric and oceanic effetcs, etc. +# and core-mantle torques, atmospheric and oceanic effects, etc. # Leap seconds are needed to keep the two time scales in agreement, i.e. UT1-UTC smaller -# than 0.9 second. Therefore, when necessary a "leap second" is applied to UTC. +# than 0.9 seconds. Therefore, when necessary a "leap second" is applied to UTC. # Since the adoption of this system in 1972 it has been necessary to add a number of seconds to UTC, # firstly due to the initial choice of the value of the second (1/86400 mean solar day of # the year 1820) and secondly to the general slowing down of the Earth's rotation. It is -# theorically possible to have a negative leap second (a second removed from UTC), but so far, +# theoretically possible to have a negative leap second (a second removed from UTC), but so far, # all leap seconds have been positive (a second has been added to UTC). Based on what we know about # the earth's rotation, it is unlikely that we will ever have a negative leap second. # # # HISTORY -# The first leap second was added on June 30, 1972. Until yhe year 2000, it was necessary in average to add a +# The first leap second was added on June 30, 1972. Until the year 2000, it was necessary in average to add a # leap second at a rate of 1 to 2 years. Since the year 2000 leap seconds are introduced with an -# average interval of 3 to 4 years due to the acceleration of the Earth rotation speed. +# average interval of 3 to 4 years due to the acceleration of the Earth's rotation speed. # # -# RESPONSABILITY OF THE DECISION TO INTRODUCE A LEAP SECOND IN UTC +# RESPONSIBILITY OF THE DECISION TO INTRODUCE A LEAP SECOND IN UTC # The decision to introduce a leap second in UTC is the responsibility of the Earth Orientation Center of # the International Earth Rotation and reference System Service (IERS). This center is located at Paris -# Observatory. According to international agreements, leap seconds should only be scheduled for certain dates: +# Observatory. According to international agreements, leap seconds should be scheduled only for certain dates: # first preference is given to the end of December and June, and second preference at the end of March # and September. Since the introduction of leap seconds in 1972, only dates in June and December were used. # @@ -60,15 +60,15 @@ # # The following line shows the last update of this file in NTP timestamp: # -#$ 3913697179 +#$ 3929093563 # # 2) Expiration date of the file given on a semi-annual basis: last June or last December # -# File expires on 28 December 2024 +# File expires on 28 June 2025 # # Expire date in NTP timestamp: # -#@ 3944332800 +#@ 3960057600 # # # LIST OF LEAP SECONDS @@ -117,4 +117,4 @@ # please see the readme file in the 'source' directory : # https://hpiers.obspm.fr/iers/bul/bulc/ntp/sources/README # -#h 9dac5845 8acd32c0 2947d462 daf4a943 f58d9391 +#h be738595 57b0cf1b b0218343 fb77062f 5a775e7 diff --git a/leapseconds b/leapseconds index ce150bfe0dca..6c715cb20b01 100644 --- a/leapseconds +++ b/leapseconds @@ -69,11 +69,11 @@ Leap 2016 Dec 31 23:59:60 + S # Any additional leap seconds will come after this. # This Expires line is commented out for now, # so that pre-2020a zic implementations do not reject this file. -#Expires 2024 Dec 28 00:00:00 +#Expires 2025 Jun 28 00:00:00 # POSIX timestamps for the data in this file: -#updated 1704708379 (2024-01-08 10:06:19 UTC) -#expires 1735344000 (2024-12-28 00:00:00 UTC) +#updated 1720104763 (2024-07-04 14:52:43 UTC) +#expires 1751068800 (2025-06-28 00:00:00 UTC) # Updated through IERS Bulletin C (https://hpiers.obspm.fr/iers/bul/bulc/bulletinc.dat) -# File expires on 28 December 2024 +# File expires on 28 June 2025 diff --git a/northamerica b/northamerica index bbfce49ba193..01f392e0e6a4 100644 --- a/northamerica +++ b/northamerica @@ -185,26 +185,6 @@ Rule US 1987 2006 - Apr Sun>=1 2:00 1:00 D Rule US 2007 max - Mar Sun>=8 2:00 1:00 D Rule US 2007 max - Nov Sun>=1 2:00 0 S -# From Arthur David Olson, 2005-12-19 -# We generate the files specified below to guard against old files with -# obsolete information being left in the time zone binary directory. -# We limit the list to names that have appeared in previous versions of -# this time zone package. -# We do these as separate Zones rather than as Links to avoid problems if -# a particular place changes whether it observes DST. -# We put these specifications here in the northamerica file both to -# increase the chances that they'll actually get compiled and to -# avoid the need to duplicate the US rules in another file. - -# Zone NAME STDOFF RULES FORMAT [UNTIL] -Zone EST -5:00 - EST -Zone MST -7:00 - MST -Zone HST -10:00 - HST -Zone EST5EDT -5:00 US E%sT -Zone CST6CDT -6:00 US C%sT -Zone MST7MDT -7:00 US M%sT -Zone PST8PDT -8:00 US P%sT - # From U. S. Naval Observatory (1989-01-19): # USA EASTERN 5 H BEHIND UTC NEW YORK, WASHINGTON # USA EASTERN 4 H BEHIND UTC APR 3 - OCT 30 @@ -2373,6 +2353,81 @@ Zone America/Dawson -9:17:40 - LMT 1900 Aug 20 # the researchers who prepared the Decrees page failed to find some of # the relevant documents. +# From Heitor David Pinto (2024-08-04): +# In 1931, the decree implementing DST specified that it would take +# effect on 30 April.... +# https://www.dof.gob.mx/nota_to_imagen_fs.php?cod_diario=192270&pagina=2&seccion=1 +# +# In 1981, the decree changing Campeche, Yucatán and Quintana Roo to UTC-5 +# specified that it would enter into force on 26 December 1981 at 2:00.... +# https://www.dof.gob.mx/nota_to_imagen_fs.php?codnota=4705667&fecha=23/12/1981&cod_diario=202796 +# +# In 1982, the decree returning Campeche and Yucatán to UTC-6 specified that +# it would enter into force on 2 November 1982 at 2:00.... +# https://www.dof.gob.mx/nota_to_imagen_fs.php?cod_diario=205689&pagina=3&seccion=0 +# +# Quintana Roo changed to UTC-6 on 4 January 1983 at 0:00, and again +# to UTC-5 on 26 October 1997 at 2:00.... +# https://www.dof.gob.mx/nota_to_imagen_fs.php?codnota=4787355&fecha=28/12/1982&cod_diario=206112 +# https://www.dof.gob.mx/nota_to_imagen_fs.php?cod_diario=209559&pagina=15&seccion=0 +# +# Durango, Coahuila, Nuevo León and Tamaulipas were set to UTC-7 on 1 January +# 1922, and changed to UTC-6 on 10 June 1927. Then Durango, Coahuila and +# Nuevo León (but not Tamaulipas) returned to UTC-7 on 15 November 1930, +# observed DST in 1931, and changed again to UTC-6 on 1 April 1932.... +# https://www.dof.gob.mx/nota_to_imagen_fs.php?codnota=4441846&fecha=29/12/1921&cod_diario=187468 +# https://www.dof.gob.mx/nota_to_imagen_fs.php?codnota=4541520&fecha=09/06/1927&cod_diario=193920 +# https://www.dof.gob.mx/nota_to_imagen_fs.php?codnota=4491963&fecha=15/11/1930&cod_diario=190835 +# https://www.dof.gob.mx/nota_to_imagen_fs.php?codnota=4418437&fecha=21/01/1932&cod_diario=185588 +# +# ... the ... 10 June 1927 ... decree only said 10 June 1927, without +# specifying a time, so I suppose that it should be considered at 0:00. +# https://www.dof.gob.mx/nota_to_imagen_fs.php?codnota=4541520&fecha=09/06/1927&cod_diario=193920 +# +# In 1942, the decree changing Baja California, Baja California Sur, Sonora, +# Sinaloa and Nayarit to UTC-7 was published on 24 April, but it said that it +# would apply from 1 April, so it's unclear when the change actually +# occurred. The database currently shows 24 April 1942. +# https://www.dof.gob.mx/nota_to_imagen_fs.php?cod_diario=192203&pagina=2&seccion=1 +# +# Baja California Sur, Sonora, Sinaloa and Nayarit never used UTC-8. The ... +# 14 January 1949 ... change [to UTC-8] only occurred in Baja California. +# https://www.dof.gob.mx/nota_to_imagen_fs.php?codnota=4515613&fecha=13/01/1949&cod_diario=192309 +# +# In 1945, the decree changing Baja California to UTC-8 specified that it +# would take effect on the third day from its publication. +# It was published on 12 November, so it would take effect on 15 November.... +# https://www.dof.gob.mx/nota_to_imagen_fs.php?codnota=4555049&fecha=12/11/1945&cod_diario=194763 +# +# In 1948, the decree changing Baja California to UTC-7 specified that it +# would take effect on "this date". The decree was made on 13 March, +# but published on 5 April, so it's unclear when the change actually occurred. +# The database currently shows 5 April 1948. +# https://www.dof.gob.mx/nota_to_imagen_fs.php?cod_diario=188624&pagina=2&seccion=0 +# +# In 1949, the decree changing Baja California to UTC-8 was published on 13 +# January, but it said that it would apply from 1 January, so it's unclear when +# the change actually occurred. The database currently shows 14 January 1949. +# https://www.dof.gob.mx/nota_to_imagen_fs.php?codnota=4515613&fecha=13/01/1949&cod_diario=192309 +# +# Baja California also observed UTC-7 from 1 May to 24 September 1950, +# from 29 April to 30 September 1951 at 2:00, +# and from 27 April to 28 September 1952 at 2:00.... +# https://www.dof.gob.mx/nota_to_imagen_fs.php?codnota=4600403&fecha=29/04/1950&cod_diario=197505 +# https://www.dof.gob.mx/nota_to_imagen_fs.php?codnota=4623553&fecha=23/09/1950&cod_diario=198805 +# https://www.dof.gob.mx/nota_to_imagen_fs.php?codnota=4469444&fecha=27/04/1951&cod_diario=189317 +# https://www.dof.gob.mx/nota_to_imagen_fs.php?codnota=4533868&fecha=10/03/1952&cod_diario=193465 +# +# All changes in Baja California from 1948 to 1952 match those in California, +# on the same dates or with a difference of one day. +# So it may be easier to implement these changes as DST with rule CA +# during this whole period. +# +# From Paul Eggert (2024-08-18): +# For now, maintain the slightly-different history for Baja California, +# as we have no information on whether 1948/1952 clocks in Tijuana followed +# the decrees or followed San Diego. + # From Alan Perry (1996-02-15): # A guy from our Mexico subsidiary finally found the Presidential Decree # outlining the timezone changes in Mexico. @@ -2576,7 +2631,7 @@ Zone America/Dawson -9:17:40 - LMT 1900 Aug 20 # http://puentelibre.mx/noticia/ciudad_juarez_cambio_horario_noviembre_2022/ # Rule NAME FROM TO - IN ON AT SAVE LETTER/S -Rule Mexico 1931 only - May 1 23:00 1:00 D +Rule Mexico 1931 only - April 30 0:00 1:00 D Rule Mexico 1931 only - Oct 1 0:00 0 S Rule Mexico 1939 only - Feb 5 0:00 1:00 D Rule Mexico 1939 only - Jun 25 0:00 0 S @@ -2595,14 +2650,16 @@ Rule Mexico 2002 2022 - Oct lastSun 2:00 0 S # Zone NAME STDOFF RULES FORMAT [UNTIL] # Quintana Roo; represented by Cancún Zone America/Cancun -5:47:04 - LMT 1922 Jan 1 6:00u - -6:00 - CST 1981 Dec 23 + -6:00 - CST 1981 Dec 26 2:00 + -5:00 - EST 1983 Jan 4 0:00 + -6:00 Mexico C%sT 1997 Oct 26 2:00 -5:00 Mexico E%sT 1998 Aug 2 2:00 -6:00 Mexico C%sT 2015 Feb 1 2:00 -5:00 - EST # Campeche, Yucatán; represented by Mérida Zone America/Merida -5:58:28 - LMT 1922 Jan 1 6:00u - -6:00 - CST 1981 Dec 23 - -5:00 - EST 1982 Dec 2 + -6:00 - CST 1981 Dec 26 2:00 + -5:00 - EST 1982 Nov 2 2:00 -6:00 Mexico C%sT # Coahuila, Nuevo León, Tamaulipas (near US border) # This includes the following municipios: @@ -2619,12 +2676,15 @@ Zone America/Matamoros -6:30:00 - LMT 1922 Jan 1 6:00u -6:00 US C%sT # Durango; Coahuila, Nuevo León, Tamaulipas (away from US border) Zone America/Monterrey -6:41:16 - LMT 1922 Jan 1 6:00u + -7:00 - MST 1927 Jun 10 + -6:00 - CST 1930 Nov 15 + -7:00 Mexico M%sT 1932 Apr 1 -6:00 - CST 1988 -6:00 US C%sT 1989 -6:00 Mexico C%sT # Central Mexico Zone America/Mexico_City -6:36:36 - LMT 1922 Jan 1 7:00u - -7:00 - MST 1927 Jun 10 23:00 + -7:00 - MST 1927 Jun 10 -6:00 - CST 1930 Nov 15 -7:00 Mexico M%sT 1932 Apr 1 -6:00 Mexico C%sT 2001 Sep 30 2:00 @@ -2635,7 +2695,7 @@ Zone America/Mexico_City -6:36:36 - LMT 1922 Jan 1 7:00u # Práxedis G Guerrero. # http://gaceta.diputados.gob.mx/PDF/65/2a022/nov/20221124-VII.pdf Zone America/Ciudad_Juarez -7:05:56 - LMT 1922 Jan 1 7:00u - -7:00 - MST 1927 Jun 10 23:00 + -7:00 - MST 1927 Jun 10 -6:00 - CST 1930 Nov 15 -7:00 Mexico M%sT 1932 Apr 1 -6:00 - CST 1996 @@ -2650,7 +2710,7 @@ Zone America/Ciudad_Juarez -7:05:56 - LMT 1922 Jan 1 7:00u # Benavides. # http://gaceta.diputados.gob.mx/PDF/65/2a022/nov/20221124-VII.pdf Zone America/Ojinaga -6:57:40 - LMT 1922 Jan 1 7:00u - -7:00 - MST 1927 Jun 10 23:00 + -7:00 - MST 1927 Jun 10 -6:00 - CST 1930 Nov 15 -7:00 Mexico M%sT 1932 Apr 1 -6:00 - CST 1996 @@ -2662,7 +2722,7 @@ Zone America/Ojinaga -6:57:40 - LMT 1922 Jan 1 7:00u -6:00 US C%sT # Chihuahua (away from US border) Zone America/Chihuahua -7:04:20 - LMT 1922 Jan 1 7:00u - -7:00 - MST 1927 Jun 10 23:00 + -7:00 - MST 1927 Jun 10 -6:00 - CST 1930 Nov 15 -7:00 Mexico M%sT 1932 Apr 1 -6:00 - CST 1996 @@ -2672,23 +2732,21 @@ Zone America/Chihuahua -7:04:20 - LMT 1922 Jan 1 7:00u -6:00 - CST # Sonora Zone America/Hermosillo -7:23:52 - LMT 1922 Jan 1 7:00u - -7:00 - MST 1927 Jun 10 23:00 + -7:00 - MST 1927 Jun 10 -6:00 - CST 1930 Nov 15 -7:00 Mexico M%sT 1932 Apr 1 -6:00 - CST 1942 Apr 24 - -7:00 - MST 1949 Jan 14 - -8:00 - PST 1970 + -7:00 - MST 1996 -7:00 Mexico M%sT 1999 -7:00 - MST # Baja California Sur, Nayarit (except Bahía de Banderas), Sinaloa Zone America/Mazatlan -7:05:40 - LMT 1922 Jan 1 7:00u - -7:00 - MST 1927 Jun 10 23:00 + -7:00 - MST 1927 Jun 10 -6:00 - CST 1930 Nov 15 -7:00 Mexico M%sT 1932 Apr 1 -6:00 - CST 1942 Apr 24 - -7:00 - MST 1949 Jan 14 - -8:00 - PST 1970 + -7:00 - MST 1970 -7:00 Mexico M%sT # Bahía de Banderas @@ -2721,27 +2779,32 @@ Zone America/Mazatlan -7:05:40 - LMT 1922 Jan 1 7:00u # Use "Bahia_Banderas" to keep the name to fourteen characters. Zone America/Bahia_Banderas -7:01:00 - LMT 1922 Jan 1 7:00u - -7:00 - MST 1927 Jun 10 23:00 + -7:00 - MST 1927 Jun 10 -6:00 - CST 1930 Nov 15 -7:00 Mexico M%sT 1932 Apr 1 -6:00 - CST 1942 Apr 24 - -7:00 - MST 1949 Jan 14 - -8:00 - PST 1970 + -7:00 - MST 1970 -7:00 Mexico M%sT 2010 Apr 4 2:00 -6:00 Mexico C%sT # Baja California Zone America/Tijuana -7:48:04 - LMT 1922 Jan 1 7:00u -7:00 - MST 1924 - -8:00 - PST 1927 Jun 10 23:00 + -8:00 - PST 1927 Jun 10 -7:00 - MST 1930 Nov 15 -8:00 - PST 1931 Apr 1 -8:00 1:00 PDT 1931 Sep 30 -8:00 - PST 1942 Apr 24 -8:00 1:00 PWT 1945 Aug 14 23:00u - -8:00 1:00 PPT 1945 Nov 12 # Peace + -8:00 1:00 PPT 1945 Nov 15 # Peace -8:00 - PST 1948 Apr 5 -8:00 1:00 PDT 1949 Jan 14 + -8:00 - PST 1950 May 1 + -8:00 1:00 PDT 1950 Sep 24 + -8:00 - PST 1951 Apr 29 2:00 + -8:00 1:00 PDT 1951 Sep 30 2:00 + -8:00 - PST 1952 Apr 27 2:00 + -8:00 1:00 PDT 1952 Sep 28 2:00 -8:00 - PST 1954 -8:00 CA P%sT 1961 -8:00 - PST 1976 @@ -3550,8 +3613,8 @@ Zone America/Puerto_Rico -4:24:25 - LMT 1899 Mar 28 12:00 # San Juan # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone America/Miquelon -3:44:40 - LMT 1911 Jun 15 # St Pierre -4:00 - AST 1980 May - -3:00 - -03 1987 - -3:00 Canada -03/-02 + -3:00 - %z 1987 + -3:00 Canada %z # Turks and Caicos # diff --git a/southamerica b/southamerica index 344e67f38f4c..c8d9097aeb14 100644 --- a/southamerica +++ b/southamerica @@ -402,11 +402,11 @@ Rule Arg 2008 only - Oct Sun>=15 0:00 1:00 - Zone America/Argentina/Buenos_Aires -3:53:48 - LMT 1894 Oct 31 #STDOFF -4:16:48.25 -4:16:48 - CMT 1920 May # Córdoba Mean Time - -4:00 - -04 1930 Dec - -4:00 Arg -04/-03 1969 Oct 5 - -3:00 Arg -03/-02 1999 Oct 3 - -4:00 Arg -04/-03 2000 Mar 3 - -3:00 Arg -03/-02 + -4:00 - %z 1930 Dec + -4:00 Arg %z 1969 Oct 5 + -3:00 Arg %z 1999 Oct 3 + -4:00 Arg %z 2000 Mar 3 + -3:00 Arg %z # # Córdoba (CB), Santa Fe (SF), Entre Ríos (ER), Corrientes (CN), Misiones (MN), # Chaco (CC), Formosa (FM), Santiago del Estero (SE) @@ -421,120 +421,120 @@ Zone America/Argentina/Buenos_Aires -3:53:48 - LMT 1894 Oct 31 #STDOFF -4:16:48.25 Zone America/Argentina/Cordoba -4:16:48 - LMT 1894 Oct 31 -4:16:48 - CMT 1920 May - -4:00 - -04 1930 Dec - -4:00 Arg -04/-03 1969 Oct 5 - -3:00 Arg -03/-02 1991 Mar 3 - -4:00 - -04 1991 Oct 20 - -3:00 Arg -03/-02 1999 Oct 3 - -4:00 Arg -04/-03 2000 Mar 3 - -3:00 Arg -03/-02 + -4:00 - %z 1930 Dec + -4:00 Arg %z 1969 Oct 5 + -3:00 Arg %z 1991 Mar 3 + -4:00 - %z 1991 Oct 20 + -3:00 Arg %z 1999 Oct 3 + -4:00 Arg %z 2000 Mar 3 + -3:00 Arg %z # # Salta (SA), La Pampa (LP), Neuquén (NQ), Rio Negro (RN) Zone America/Argentina/Salta -4:21:40 - LMT 1894 Oct 31 #STDOFF -4:16:48.25 -4:16:48 - CMT 1920 May - -4:00 - -04 1930 Dec - -4:00 Arg -04/-03 1969 Oct 5 - -3:00 Arg -03/-02 1991 Mar 3 - -4:00 - -04 1991 Oct 20 - -3:00 Arg -03/-02 1999 Oct 3 - -4:00 Arg -04/-03 2000 Mar 3 - -3:00 Arg -03/-02 2008 Oct 18 - -3:00 - -03 + -4:00 - %z 1930 Dec + -4:00 Arg %z 1969 Oct 5 + -3:00 Arg %z 1991 Mar 3 + -4:00 - %z 1991 Oct 20 + -3:00 Arg %z 1999 Oct 3 + -4:00 Arg %z 2000 Mar 3 + -3:00 Arg %z 2008 Oct 18 + -3:00 - %z # # Tucumán (TM) Zone America/Argentina/Tucuman -4:20:52 - LMT 1894 Oct 31 #STDOFF -4:16:48.25 -4:16:48 - CMT 1920 May - -4:00 - -04 1930 Dec - -4:00 Arg -04/-03 1969 Oct 5 - -3:00 Arg -03/-02 1991 Mar 3 - -4:00 - -04 1991 Oct 20 - -3:00 Arg -03/-02 1999 Oct 3 - -4:00 Arg -04/-03 2000 Mar 3 - -3:00 - -03 2004 Jun 1 - -4:00 - -04 2004 Jun 13 - -3:00 Arg -03/-02 + -4:00 - %z 1930 Dec + -4:00 Arg %z 1969 Oct 5 + -3:00 Arg %z 1991 Mar 3 + -4:00 - %z 1991 Oct 20 + -3:00 Arg %z 1999 Oct 3 + -4:00 Arg %z 2000 Mar 3 + -3:00 - %z 2004 Jun 1 + -4:00 - %z 2004 Jun 13 + -3:00 Arg %z # # La Rioja (LR) Zone America/Argentina/La_Rioja -4:27:24 - LMT 1894 Oct 31 #STDOFF -4:16:48.25 -4:16:48 - CMT 1920 May - -4:00 - -04 1930 Dec - -4:00 Arg -04/-03 1969 Oct 5 - -3:00 Arg -03/-02 1991 Mar 1 - -4:00 - -04 1991 May 7 - -3:00 Arg -03/-02 1999 Oct 3 - -4:00 Arg -04/-03 2000 Mar 3 - -3:00 - -03 2004 Jun 1 - -4:00 - -04 2004 Jun 20 - -3:00 Arg -03/-02 2008 Oct 18 - -3:00 - -03 + -4:00 - %z 1930 Dec + -4:00 Arg %z 1969 Oct 5 + -3:00 Arg %z 1991 Mar 1 + -4:00 - %z 1991 May 7 + -3:00 Arg %z 1999 Oct 3 + -4:00 Arg %z 2000 Mar 3 + -3:00 - %z 2004 Jun 1 + -4:00 - %z 2004 Jun 20 + -3:00 Arg %z 2008 Oct 18 + -3:00 - %z # # San Juan (SJ) Zone America/Argentina/San_Juan -4:34:04 - LMT 1894 Oct 31 #STDOFF -4:16:48.25 -4:16:48 - CMT 1920 May - -4:00 - -04 1930 Dec - -4:00 Arg -04/-03 1969 Oct 5 - -3:00 Arg -03/-02 1991 Mar 1 - -4:00 - -04 1991 May 7 - -3:00 Arg -03/-02 1999 Oct 3 - -4:00 Arg -04/-03 2000 Mar 3 - -3:00 - -03 2004 May 31 - -4:00 - -04 2004 Jul 25 - -3:00 Arg -03/-02 2008 Oct 18 - -3:00 - -03 + -4:00 - %z 1930 Dec + -4:00 Arg %z 1969 Oct 5 + -3:00 Arg %z 1991 Mar 1 + -4:00 - %z 1991 May 7 + -3:00 Arg %z 1999 Oct 3 + -4:00 Arg %z 2000 Mar 3 + -3:00 - %z 2004 May 31 + -4:00 - %z 2004 Jul 25 + -3:00 Arg %z 2008 Oct 18 + -3:00 - %z # # Jujuy (JY) Zone America/Argentina/Jujuy -4:21:12 - LMT 1894 Oct 31 #STDOFF -4:16:48.25 -4:16:48 - CMT 1920 May - -4:00 - -04 1930 Dec - -4:00 Arg -04/-03 1969 Oct 5 - -3:00 Arg -03/-02 1990 Mar 4 - -4:00 - -04 1990 Oct 28 - -4:00 1:00 -03 1991 Mar 17 - -4:00 - -04 1991 Oct 6 - -3:00 1:00 -02 1992 - -3:00 Arg -03/-02 1999 Oct 3 - -4:00 Arg -04/-03 2000 Mar 3 - -3:00 Arg -03/-02 2008 Oct 18 - -3:00 - -03 + -4:00 - %z 1930 Dec + -4:00 Arg %z 1969 Oct 5 + -3:00 Arg %z 1990 Mar 4 + -4:00 - %z 1990 Oct 28 + -4:00 1:00 %z 1991 Mar 17 + -4:00 - %z 1991 Oct 6 + -3:00 1:00 %z 1992 + -3:00 Arg %z 1999 Oct 3 + -4:00 Arg %z 2000 Mar 3 + -3:00 Arg %z 2008 Oct 18 + -3:00 - %z # # Catamarca (CT), Chubut (CH) Zone America/Argentina/Catamarca -4:23:08 - LMT 1894 Oct 31 #STDOFF -4:16:48.25 -4:16:48 - CMT 1920 May - -4:00 - -04 1930 Dec - -4:00 Arg -04/-03 1969 Oct 5 - -3:00 Arg -03/-02 1991 Mar 3 - -4:00 - -04 1991 Oct 20 - -3:00 Arg -03/-02 1999 Oct 3 - -4:00 Arg -04/-03 2000 Mar 3 - -3:00 - -03 2004 Jun 1 - -4:00 - -04 2004 Jun 20 - -3:00 Arg -03/-02 2008 Oct 18 - -3:00 - -03 + -4:00 - %z 1930 Dec + -4:00 Arg %z 1969 Oct 5 + -3:00 Arg %z 1991 Mar 3 + -4:00 - %z 1991 Oct 20 + -3:00 Arg %z 1999 Oct 3 + -4:00 Arg %z 2000 Mar 3 + -3:00 - %z 2004 Jun 1 + -4:00 - %z 2004 Jun 20 + -3:00 Arg %z 2008 Oct 18 + -3:00 - %z # # Mendoza (MZ) Zone America/Argentina/Mendoza -4:35:16 - LMT 1894 Oct 31 #STDOFF -4:16:48.25 -4:16:48 - CMT 1920 May - -4:00 - -04 1930 Dec - -4:00 Arg -04/-03 1969 Oct 5 - -3:00 Arg -03/-02 1990 Mar 4 - -4:00 - -04 1990 Oct 15 - -4:00 1:00 -03 1991 Mar 1 - -4:00 - -04 1991 Oct 15 - -4:00 1:00 -03 1992 Mar 1 - -4:00 - -04 1992 Oct 18 - -3:00 Arg -03/-02 1999 Oct 3 - -4:00 Arg -04/-03 2000 Mar 3 - -3:00 - -03 2004 May 23 - -4:00 - -04 2004 Sep 26 - -3:00 Arg -03/-02 2008 Oct 18 - -3:00 - -03 + -4:00 - %z 1930 Dec + -4:00 Arg %z 1969 Oct 5 + -3:00 Arg %z 1990 Mar 4 + -4:00 - %z 1990 Oct 15 + -4:00 1:00 %z 1991 Mar 1 + -4:00 - %z 1991 Oct 15 + -4:00 1:00 %z 1992 Mar 1 + -4:00 - %z 1992 Oct 18 + -3:00 Arg %z 1999 Oct 3 + -4:00 Arg %z 2000 Mar 3 + -3:00 - %z 2004 May 23 + -4:00 - %z 2004 Sep 26 + -3:00 Arg %z 2008 Oct 18 + -3:00 - %z # # San Luis (SL) @@ -544,53 +544,53 @@ Rule SanLuis 2007 2008 - Oct Sun>=8 0:00 1:00 - Zone America/Argentina/San_Luis -4:25:24 - LMT 1894 Oct 31 #STDOFF -4:16:48.25 -4:16:48 - CMT 1920 May - -4:00 - -04 1930 Dec - -4:00 Arg -04/-03 1969 Oct 5 - -3:00 Arg -03/-02 1990 - -3:00 1:00 -02 1990 Mar 14 - -4:00 - -04 1990 Oct 15 - -4:00 1:00 -03 1991 Mar 1 - -4:00 - -04 1991 Jun 1 - -3:00 - -03 1999 Oct 3 - -4:00 1:00 -03 2000 Mar 3 - -3:00 - -03 2004 May 31 - -4:00 - -04 2004 Jul 25 - -3:00 Arg -03/-02 2008 Jan 21 - -4:00 SanLuis -04/-03 2009 Oct 11 - -3:00 - -03 + -4:00 - %z 1930 Dec + -4:00 Arg %z 1969 Oct 5 + -3:00 Arg %z 1990 + -3:00 1:00 %z 1990 Mar 14 + -4:00 - %z 1990 Oct 15 + -4:00 1:00 %z 1991 Mar 1 + -4:00 - %z 1991 Jun 1 + -3:00 - %z 1999 Oct 3 + -4:00 1:00 %z 2000 Mar 3 + -3:00 - %z 2004 May 31 + -4:00 - %z 2004 Jul 25 + -3:00 Arg %z 2008 Jan 21 + -4:00 SanLuis %z 2009 Oct 11 + -3:00 - %z # # Santa Cruz (SC) Zone America/Argentina/Rio_Gallegos -4:36:52 - LMT 1894 Oct 31 #STDOFF -4:16:48.25 -4:16:48 - CMT 1920 May - -4:00 - -04 1930 Dec - -4:00 Arg -04/-03 1969 Oct 5 - -3:00 Arg -03/-02 1999 Oct 3 - -4:00 Arg -04/-03 2000 Mar 3 - -3:00 - -03 2004 Jun 1 - -4:00 - -04 2004 Jun 20 - -3:00 Arg -03/-02 2008 Oct 18 - -3:00 - -03 + -4:00 - %z 1930 Dec + -4:00 Arg %z 1969 Oct 5 + -3:00 Arg %z 1999 Oct 3 + -4:00 Arg %z 2000 Mar 3 + -3:00 - %z 2004 Jun 1 + -4:00 - %z 2004 Jun 20 + -3:00 Arg %z 2008 Oct 18 + -3:00 - %z # # Tierra del Fuego, Antártida e Islas del Atlántico Sur (TF) Zone America/Argentina/Ushuaia -4:33:12 - LMT 1894 Oct 31 #STDOFF -4:16:48.25 -4:16:48 - CMT 1920 May - -4:00 - -04 1930 Dec - -4:00 Arg -04/-03 1969 Oct 5 - -3:00 Arg -03/-02 1999 Oct 3 - -4:00 Arg -04/-03 2000 Mar 3 - -3:00 - -03 2004 May 30 - -4:00 - -04 2004 Jun 20 - -3:00 Arg -03/-02 2008 Oct 18 - -3:00 - -03 + -4:00 - %z 1930 Dec + -4:00 Arg %z 1969 Oct 5 + -3:00 Arg %z 1999 Oct 3 + -4:00 Arg %z 2000 Mar 3 + -3:00 - %z 2004 May 30 + -4:00 - %z 2004 Jun 20 + -3:00 Arg %z 2008 Oct 18 + -3:00 - %z # Bolivia # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone America/La_Paz -4:32:36 - LMT 1890 -4:32:36 - CMT 1931 Oct 15 # Calamarca MT -4:32:36 1:00 BST 1932 Mar 21 # Bolivia ST - -4:00 - -04 + -4:00 - %z # Brazil @@ -961,12 +961,12 @@ Rule Brazil 2018 only - Nov Sun>=1 0:00 1:00 - # # Fernando de Noronha (administratively part of PE) Zone America/Noronha -2:09:40 - LMT 1914 - -2:00 Brazil -02/-01 1990 Sep 17 - -2:00 - -02 1999 Sep 30 - -2:00 Brazil -02/-01 2000 Oct 15 - -2:00 - -02 2001 Sep 13 - -2:00 Brazil -02/-01 2002 Oct 1 - -2:00 - -02 + -2:00 Brazil %z 1990 Sep 17 + -2:00 - %z 1999 Sep 30 + -2:00 Brazil %z 2000 Oct 15 + -2:00 - %z 2001 Sep 13 + -2:00 Brazil %z 2002 Oct 1 + -2:00 - %z # Other Atlantic islands have no permanent settlement. # These include Trindade and Martim Vaz (administratively part of ES), # Rocas Atoll (RN), and the St Peter and St Paul Archipelago (PE). @@ -979,119 +979,119 @@ Zone America/Noronha -2:09:40 - LMT 1914 # In the north a very small part from the river Javary (now Jari I guess, # the border with Amapá) to the Amazon, then to the Xingu. Zone America/Belem -3:13:56 - LMT 1914 - -3:00 Brazil -03/-02 1988 Sep 12 - -3:00 - -03 + -3:00 Brazil %z 1988 Sep 12 + -3:00 - %z # # west Pará (PA) # West Pará includes Altamira, Óbidos, Prainha, Oriximiná, and Santarém. Zone America/Santarem -3:38:48 - LMT 1914 - -4:00 Brazil -04/-03 1988 Sep 12 - -4:00 - -04 2008 Jun 24 0:00 - -3:00 - -03 + -4:00 Brazil %z 1988 Sep 12 + -4:00 - %z 2008 Jun 24 0:00 + -3:00 - %z # # Maranhão (MA), Piauí (PI), Ceará (CE), Rio Grande do Norte (RN), # Paraíba (PB) Zone America/Fortaleza -2:34:00 - LMT 1914 - -3:00 Brazil -03/-02 1990 Sep 17 - -3:00 - -03 1999 Sep 30 - -3:00 Brazil -03/-02 2000 Oct 22 - -3:00 - -03 2001 Sep 13 - -3:00 Brazil -03/-02 2002 Oct 1 - -3:00 - -03 + -3:00 Brazil %z 1990 Sep 17 + -3:00 - %z 1999 Sep 30 + -3:00 Brazil %z 2000 Oct 22 + -3:00 - %z 2001 Sep 13 + -3:00 Brazil %z 2002 Oct 1 + -3:00 - %z # # Pernambuco (PE) (except Atlantic islands) Zone America/Recife -2:19:36 - LMT 1914 - -3:00 Brazil -03/-02 1990 Sep 17 - -3:00 - -03 1999 Sep 30 - -3:00 Brazil -03/-02 2000 Oct 15 - -3:00 - -03 2001 Sep 13 - -3:00 Brazil -03/-02 2002 Oct 1 - -3:00 - -03 + -3:00 Brazil %z 1990 Sep 17 + -3:00 - %z 1999 Sep 30 + -3:00 Brazil %z 2000 Oct 15 + -3:00 - %z 2001 Sep 13 + -3:00 Brazil %z 2002 Oct 1 + -3:00 - %z # # Tocantins (TO) Zone America/Araguaina -3:12:48 - LMT 1914 - -3:00 Brazil -03/-02 1990 Sep 17 - -3:00 - -03 1995 Sep 14 - -3:00 Brazil -03/-02 2003 Sep 24 - -3:00 - -03 2012 Oct 21 - -3:00 Brazil -03/-02 2013 Sep - -3:00 - -03 + -3:00 Brazil %z 1990 Sep 17 + -3:00 - %z 1995 Sep 14 + -3:00 Brazil %z 2003 Sep 24 + -3:00 - %z 2012 Oct 21 + -3:00 Brazil %z 2013 Sep + -3:00 - %z # # Alagoas (AL), Sergipe (SE) Zone America/Maceio -2:22:52 - LMT 1914 - -3:00 Brazil -03/-02 1990 Sep 17 - -3:00 - -03 1995 Oct 13 - -3:00 Brazil -03/-02 1996 Sep 4 - -3:00 - -03 1999 Sep 30 - -3:00 Brazil -03/-02 2000 Oct 22 - -3:00 - -03 2001 Sep 13 - -3:00 Brazil -03/-02 2002 Oct 1 - -3:00 - -03 + -3:00 Brazil %z 1990 Sep 17 + -3:00 - %z 1995 Oct 13 + -3:00 Brazil %z 1996 Sep 4 + -3:00 - %z 1999 Sep 30 + -3:00 Brazil %z 2000 Oct 22 + -3:00 - %z 2001 Sep 13 + -3:00 Brazil %z 2002 Oct 1 + -3:00 - %z # # Bahia (BA) # There are too many Salvadors elsewhere, so use America/Bahia instead # of America/Salvador. Zone America/Bahia -2:34:04 - LMT 1914 - -3:00 Brazil -03/-02 2003 Sep 24 - -3:00 - -03 2011 Oct 16 - -3:00 Brazil -03/-02 2012 Oct 21 - -3:00 - -03 + -3:00 Brazil %z 2003 Sep 24 + -3:00 - %z 2011 Oct 16 + -3:00 Brazil %z 2012 Oct 21 + -3:00 - %z # # Goiás (GO), Distrito Federal (DF), Minas Gerais (MG), # Espírito Santo (ES), Rio de Janeiro (RJ), São Paulo (SP), Paraná (PR), # Santa Catarina (SC), Rio Grande do Sul (RS) Zone America/Sao_Paulo -3:06:28 - LMT 1914 - -3:00 Brazil -03/-02 1963 Oct 23 0:00 - -3:00 1:00 -02 1964 - -3:00 Brazil -03/-02 + -3:00 Brazil %z 1963 Oct 23 0:00 + -3:00 1:00 %z 1964 + -3:00 Brazil %z # # Mato Grosso do Sul (MS) Zone America/Campo_Grande -3:38:28 - LMT 1914 - -4:00 Brazil -04/-03 + -4:00 Brazil %z # # Mato Grosso (MT) Zone America/Cuiaba -3:44:20 - LMT 1914 - -4:00 Brazil -04/-03 2003 Sep 24 - -4:00 - -04 2004 Oct 1 - -4:00 Brazil -04/-03 + -4:00 Brazil %z 2003 Sep 24 + -4:00 - %z 2004 Oct 1 + -4:00 Brazil %z # # Rondônia (RO) Zone America/Porto_Velho -4:15:36 - LMT 1914 - -4:00 Brazil -04/-03 1988 Sep 12 - -4:00 - -04 + -4:00 Brazil %z 1988 Sep 12 + -4:00 - %z # # Roraima (RR) Zone America/Boa_Vista -4:02:40 - LMT 1914 - -4:00 Brazil -04/-03 1988 Sep 12 - -4:00 - -04 1999 Sep 30 - -4:00 Brazil -04/-03 2000 Oct 15 - -4:00 - -04 + -4:00 Brazil %z 1988 Sep 12 + -4:00 - %z 1999 Sep 30 + -4:00 Brazil %z 2000 Oct 15 + -4:00 - %z # # east Amazonas (AM): Boca do Acre, Jutaí, Manaus, Floriano Peixoto # The great circle line from Tabatinga to Porto Acre divides # east from west Amazonas. Zone America/Manaus -4:00:04 - LMT 1914 - -4:00 Brazil -04/-03 1988 Sep 12 - -4:00 - -04 1993 Sep 28 - -4:00 Brazil -04/-03 1994 Sep 22 - -4:00 - -04 + -4:00 Brazil %z 1988 Sep 12 + -4:00 - %z 1993 Sep 28 + -4:00 Brazil %z 1994 Sep 22 + -4:00 - %z # # west Amazonas (AM): Atalaia do Norte, Boca do Maoco, Benjamin Constant, # Eirunepé, Envira, Ipixuna Zone America/Eirunepe -4:39:28 - LMT 1914 - -5:00 Brazil -05/-04 1988 Sep 12 - -5:00 - -05 1993 Sep 28 - -5:00 Brazil -05/-04 1994 Sep 22 - -5:00 - -05 2008 Jun 24 0:00 - -4:00 - -04 2013 Nov 10 - -5:00 - -05 + -5:00 Brazil %z 1988 Sep 12 + -5:00 - %z 1993 Sep 28 + -5:00 Brazil %z 1994 Sep 22 + -5:00 - %z 2008 Jun 24 0:00 + -4:00 - %z 2013 Nov 10 + -5:00 - %z # # Acre (AC) Zone America/Rio_Branco -4:31:12 - LMT 1914 - -5:00 Brazil -05/-04 1988 Sep 12 - -5:00 - -05 2008 Jun 24 0:00 - -4:00 - -04 2013 Nov 10 - -5:00 - -05 + -5:00 Brazil %z 1988 Sep 12 + -5:00 - %z 2008 Jun 24 0:00 + -4:00 - %z 2013 Nov 10 + -5:00 - %z # Chile @@ -1359,36 +1359,36 @@ Rule Chile 2023 max - Sep Sun>=2 4:00u 1:00 - # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone America/Santiago -4:42:45 - LMT 1890 -4:42:45 - SMT 1910 Jan 10 # Santiago Mean Time - -5:00 - -05 1916 Jul 1 + -5:00 - %z 1916 Jul 1 -4:42:45 - SMT 1918 Sep 10 - -4:00 - -04 1919 Jul 1 + -4:00 - %z 1919 Jul 1 -4:42:45 - SMT 1927 Sep 1 - -5:00 Chile -05/-04 1932 Sep 1 - -4:00 - -04 1942 Jun 1 - -5:00 - -05 1942 Aug 1 - -4:00 - -04 1946 Jul 14 24:00 - -4:00 1:00 -03 1946 Aug 28 24:00 # central CL - -5:00 1:00 -04 1947 Mar 31 24:00 - -5:00 - -05 1947 May 21 23:00 - -4:00 Chile -04/-03 + -5:00 Chile %z 1932 Sep 1 + -4:00 - %z 1942 Jun 1 + -5:00 - %z 1942 Aug 1 + -4:00 - %z 1946 Jul 14 24:00 + -4:00 1:00 %z 1946 Aug 28 24:00 # central CL + -5:00 1:00 %z 1947 Mar 31 24:00 + -5:00 - %z 1947 May 21 23:00 + -4:00 Chile %z Zone America/Punta_Arenas -4:43:40 - LMT 1890 -4:42:45 - SMT 1910 Jan 10 - -5:00 - -05 1916 Jul 1 + -5:00 - %z 1916 Jul 1 -4:42:45 - SMT 1918 Sep 10 - -4:00 - -04 1919 Jul 1 + -4:00 - %z 1919 Jul 1 -4:42:45 - SMT 1927 Sep 1 - -5:00 Chile -05/-04 1932 Sep 1 - -4:00 - -04 1942 Jun 1 - -5:00 - -05 1942 Aug 1 - -4:00 - -04 1946 Aug 28 24:00 - -5:00 1:00 -04 1947 Mar 31 24:00 - -5:00 - -05 1947 May 21 23:00 - -4:00 Chile -04/-03 2016 Dec 4 - -3:00 - -03 + -5:00 Chile %z 1932 Sep 1 + -4:00 - %z 1942 Jun 1 + -5:00 - %z 1942 Aug 1 + -4:00 - %z 1946 Aug 28 24:00 + -5:00 1:00 %z 1947 Mar 31 24:00 + -5:00 - %z 1947 May 21 23:00 + -4:00 Chile %z 2016 Dec 4 + -3:00 - %z Zone Pacific/Easter -7:17:28 - LMT 1890 -7:17:28 - EMT 1932 Sep # Easter Mean Time - -7:00 Chile -07/-06 1982 Mar 14 3:00u # Easter Time - -6:00 Chile -06/-05 + -7:00 Chile %z 1982 Mar 14 3:00u # Easter Time + -6:00 Chile %z # # Salas y Gómez Island is uninhabited. # Other Chilean locations, including Juan Fernández Is, Desventuradas Is, @@ -1408,10 +1408,10 @@ Zone Pacific/Easter -7:17:28 - LMT 1890 # # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone Antarctica/Palmer 0 - -00 1965 - -4:00 Arg -04/-03 1969 Oct 5 - -3:00 Arg -03/-02 1982 May - -4:00 Chile -04/-03 2016 Dec 4 - -3:00 - -03 + -4:00 Arg %z 1969 Oct 5 + -3:00 Arg %z 1982 May + -4:00 Chile %z 2016 Dec 4 + -3:00 - %z # Colombia @@ -1430,7 +1430,7 @@ Rule CO 1993 only - Feb 6 24:00 0 - #STDOFF -4:56:16.4 Zone America/Bogota -4:56:16 - LMT 1884 Mar 13 -4:56:16 - BMT 1914 Nov 23 # Bogotá Mean Time - -5:00 CO -05/-04 + -5:00 CO %z # Malpelo, Providencia, San Andres # no information; probably like America/Bogota @@ -1461,10 +1461,10 @@ Rule Ecuador 1993 only - Feb 5 0:00 0 - # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone America/Guayaquil -5:19:20 - LMT 1890 -5:14:00 - QMT 1931 # Quito Mean Time - -5:00 Ecuador -05/-04 + -5:00 Ecuador %z Zone Pacific/Galapagos -5:58:24 - LMT 1931 # Puerto Baquerizo Moreno - -5:00 - -05 1986 - -6:00 Ecuador -06/-05 + -5:00 - %z 1986 + -6:00 Ecuador %z # Falklands @@ -1564,10 +1564,10 @@ Rule Falk 2001 2010 - Sep Sun>=1 2:00 1:00 - # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone Atlantic/Stanley -3:51:24 - LMT 1890 -3:51:24 - SMT 1912 Mar 12 # Stanley Mean Time - -4:00 Falk -04/-03 1983 May - -3:00 Falk -03/-02 1985 Sep 15 - -4:00 Falk -04/-03 2010 Sep 5 2:00 - -3:00 - -03 + -4:00 Falk %z 1983 May + -3:00 Falk %z 1985 Sep 15 + -4:00 Falk %z 2010 Sep 5 2:00 + -3:00 - %z # French Guiana # For the 1911/1912 establishment of standard time in French possessions, see: @@ -1575,8 +1575,8 @@ Zone Atlantic/Stanley -3:51:24 - LMT 1890 # page 752, 18b. # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone America/Cayenne -3:29:20 - LMT 1911 Jul 1 - -4:00 - -04 1967 Oct - -3:00 - -03 + -4:00 - %z 1967 Oct + -3:00 - %z # Guyana @@ -1610,10 +1610,10 @@ Zone America/Cayenne -3:29:20 - LMT 1911 Jul 1 # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone America/Guyana -3:52:39 - LMT 1911 Aug 1 # Georgetown - -4:00 - -04 1915 Mar 1 - -3:45 - -0345 1975 Aug 1 - -3:00 - -03 1992 Mar 29 1:00 - -4:00 - -04 + -4:00 - %z 1915 Mar 1 + -3:45 - %z 1975 Aug 1 + -3:00 - %z 1992 Mar 29 1:00 + -4:00 - %z # Paraguay # @@ -1711,9 +1711,9 @@ Rule Para 2013 max - Mar Sun>=22 0:00 0 - # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone America/Asuncion -3:50:40 - LMT 1890 -3:50:40 - AMT 1931 Oct 10 # Asunción Mean Time - -4:00 - -04 1972 Oct - -3:00 - -03 1974 Apr - -4:00 Para -04/-03 + -4:00 - %z 1972 Oct + -3:00 - %z 1974 Apr + -4:00 Para %z # Peru # @@ -1740,12 +1740,12 @@ Rule Peru 1994 only - Apr 1 0:00 0 - # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone America/Lima -5:08:12 - LMT 1890 -5:08:36 - LMT 1908 Jul 28 # Lima Mean Time? - -5:00 Peru -05/-04 + -5:00 Peru %z # South Georgia # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone Atlantic/South_Georgia -2:26:08 - LMT 1890 # Grytviken - -2:00 - -02 + -2:00 - %z # South Sandwich Is # uninhabited; scientific personnel have wintered @@ -1755,8 +1755,8 @@ Zone Atlantic/South_Georgia -2:26:08 - LMT 1890 # Grytviken Zone America/Paramaribo -3:40:40 - LMT 1911 -3:40:52 - PMT 1935 # Paramaribo Mean Time -3:40:36 - PMT 1945 Oct # The capital moved? - -3:30 - -0330 1984 Oct - -3:00 - -03 + -3:30 - %z 1984 Oct + -3:00 - %z # Uruguay # From Paul Eggert (1993-11-18): @@ -1971,15 +1971,15 @@ Rule Uruguay 2006 2014 - Oct Sun>=1 2:00 1:00 - # This Zone can be simplified once we assume zic %z. Zone America/Montevideo -3:44:51 - LMT 1908 Jun 10 -3:44:51 - MMT 1920 May 1 # Montevideo MT - -4:00 - -04 1923 Oct 1 - -3:30 Uruguay -0330/-03 1942 Dec 14 - -3:00 Uruguay -03/-0230 1960 - -3:00 Uruguay -03/-02 1968 - -3:00 Uruguay -03/-0230 1970 - -3:00 Uruguay -03/-02 1974 - -3:00 Uruguay -03/-0130 1974 Mar 10 - -3:00 Uruguay -03/-0230 1974 Dec 22 - -3:00 Uruguay -03/-02 + -4:00 - %z 1923 Oct 1 + -3:30 Uruguay %z 1942 Dec 14 + -3:00 Uruguay %z 1960 + -3:00 Uruguay %z 1968 + -3:00 Uruguay %z 1970 + -3:00 Uruguay %z 1974 + -3:00 Uruguay %z 1974 Mar 10 + -3:00 Uruguay %z 1974 Dec 22 + -3:00 Uruguay %z # Venezuela # @@ -2013,7 +2013,7 @@ Zone America/Montevideo -3:44:51 - LMT 1908 Jun 10 # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone America/Caracas -4:27:44 - LMT 1890 -4:27:40 - CMT 1912 Feb 12 # Caracas Mean Time? - -4:30 - -0430 1965 Jan 1 0:00 - -4:00 - -04 2007 Dec 9 3:00 - -4:30 - -0430 2016 May 1 2:30 - -4:00 - -04 + -4:30 - %z 1965 Jan 1 0:00 + -4:00 - %z 2007 Dec 9 3:00 + -4:30 - %z 2016 May 1 2:30 + -4:00 - %z diff --git a/theory.html b/theory.html index 516d2a525111..d3573ede0dfb 100644 --- a/theory.html +++ b/theory.html @@ -89,13 +89,15 @@

Scope of the tz database

href="https://en.wikipedia.org/wiki/POSIX">POSIX, an international standard for UNIX-like systems. -As of this writing, the current edition of POSIX is: The Open Group Base Specifications Issue 7, IEEE Std 1003.1-2017, 2018 -Edition. -Because the database's scope encompasses real-world changes to civil -timekeeping, its model for describing time is more complex than the -standard and daylight saving times supported by POSIX.1-2017. +Edition), POSIX.1-2024 requires support for the +tz database, which has a +model for describing civil time that is more complex than the +standard and daylight saving times required by POSIX.1-2017. A tz timezone corresponds to a ruleset that can have more than two changes per year, these changes need not merely flip back and forth between two alternatives, and the rules themselves @@ -159,7 +161,7 @@

Timezone identifiers

-Names normally have the form +Names normally have the format AREA/LOCATION, where AREA is a continent or ocean, and LOCATION is a specific location within the area. @@ -187,7 +189,7 @@

Timezone identifiers

href="https://en.wikipedia.org/wiki/ASCII">ASCII letters, '.', '-' and '_'. Do not use digits, as that might create an ambiguity with POSIX.1-2017 + href="https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html#tag_08_03">POSIX's proleptic TZ strings. A file name component must not exceed 14 characters or start with '-'. @@ -378,7 +380,8 @@

Timezone identifiers

and no great weight should be attached to whether a link is defined in backward or in some other file. The source file etcetera defines names that may be useful -on platforms that do not support POSIX.1-2017-style TZ strings; +on platforms that do not support proleptic TZ strings +like <+08>-8; no other source file other than backward contains links to its zones. One of etcetera's names is Etc/UTC, @@ -425,8 +428,8 @@

Time zone abbreviations

In other words, in the C locale the POSIX extended regular expression [-+[:alnum:]]{3,6} should match the abbreviation. - This guarantees that all abbreviations could have been specified by a - POSIX.1-2017 TZ string. + This guarantees that all abbreviations could have been specified + explicitly by a POSIX proleptic TZ string.

  • @@ -578,6 +581,11 @@

    Time zone abbreviations

    some sense undefined; this notation is derived from Internet RFC 3339. + (The abbreviation 'Z' that + Internet + RFC 9557 uses for this concept + would violate the POSIX requirement + of at least three characters in an abbreviation.)
  • @@ -775,7 +783,7 @@

    Accuracy of the tz database

    the Western 06:00 to be 12:00. These practices are largely outside the scope of the tz code and data, which provide only limited support for date and time localization - such as that required by POSIX.1-2017. + such as that required by POSIX. If DST is not used a different time zone can often do the trick; for example, in Kenya a TZ setting like <-03>3 or America/Cayenne starts @@ -866,29 +874,62 @@

    Time and date functions

    part of many platforms, where the primary use of this package is to update obsolete time-related files. To do this, you may need to compile the time zone compiler -'zic' supplied with this package instead of using the -system 'zic', since the format of zic's +zic supplied with this package instead of using the +system zic, since the format of zic's input is occasionally extended, and a platform may still be shipping an older zic.

    -

    POSIX.1-2017 properties and limitations

    +

    +In POSIX, time display in a process is controlled by the +environment variable TZ, which can have two forms: +

      +
    • + A proleptic TZ value + like CET-1CEST,M3.5.0,M10.5.0/3 uses a complex + notation that specifies a single standard time along with daylight + saving rules that apply to all years past, present, and future. +
    • +
    • + A geographical TZ value + like Europe/Berlin names a location that stands for + civil time near that location, which can have more than + one standard time and more than one set of daylight saving rules, + to record timekeeping practice more accurately. + These names are defined by the tz database. +
    • +
    + +

    POSIX.1-2017 properties and limitations

    +

    +Some platforms support only the features required by POSIX.1-2017, +and have not yet upgraded to POSIX.1-2024. +Code intended to be portable to these platforms must deal +with problems that were fixed in later POSIX editions. +

    + +
      +
    • + POSIX.1-2017 does not require support for geographical TZ, + and there is no convenient and efficient way to determine + the UT offset and time zone abbreviation of arbitrary + timestamps, particularly for timezones + that do not fit into the POSIX model. +
    • - In POSIX.1-2017, time display in a process is controlled by the - environment variable TZ. - Unfortunately, the POSIX.1-2017 - TZ string takes a form that is hard to describe and - is error-prone in practice. - Also, POSIX.1-2017 TZ strings cannot deal with daylight + The proleptic TZ string, + which is all that POSIX.1-2017 requires, + has a format that is hard to describe and is error-prone in practice. + Also, proleptic TZ strings cannot deal with daylight saving time rules not based on the Gregorian calendar (as in Morocco), or with situations where more than two time zone abbreviations or UT offsets are used in an area.

      - The POSIX.1-2017 TZ string takes the following form: + A proleptic TZ string has the following format:

      @@ -955,7 +996,7 @@

      POSIX.1-2017 properties and limitations

      - Here is an example POSIX.1-2017 TZ string for New + Here is an example proleptic TZ string for New Zealand after 2007. It says that standard time (NZST) is 12 hours ahead of UT, and that daylight saving time @@ -966,26 +1007,46 @@

      POSIX.1-2017 properties and limitations

      TZ='NZST-12NZDT,M9.5.0,M4.1.0/3'

      - This POSIX.1-2017 TZ string is hard to remember, and + This proleptic TZ string is hard to remember, and mishandles some timestamps before 2008. - With this package you can use this instead: + With this package you can use a geographical TZ instead:

      TZ='Pacific/Auckland'
    • +
    + +

    +POSIX.1-2017 also has the limitations of POSIX.1-2024, +discussed in the next section. +

    + +

    POSIX.1-2024 properties and limitations

    +

    +POSIX.1-2024 extends POSIX.1-2017 in the following significant ways: +

    +
    • - POSIX does not define the DST transitions - for TZ values like - "EST5EDT". - Traditionally the current US DST rules - were used to interpret such values, but this meant that the - US DST rules were compiled into each - time conversion package, and when - US time conversion rules changed (as in the United - States in 1987 and again in 2007), all packages that - interpreted TZ values had to be updated - to ensure proper results. + POSIX.1-2024 requires support for geographical TZ. + Earlier POSIX editions require support only for proleptic TZ. +
    • +
    • + POSIX.1-2024 requires struct tm + to have a UT offset member tm_gmtoff + and a time zone abbreviation member tm_zone. + Earlier POSIX editions lack this requirement. +
    • +
    • + DST transition times can range from −167:59:59 + to 167:59:59 instead of merely from 00:00:00 to 24:59:59. + This allows for proleptic TZ strings + like "<-02>2<-01>,M3.5.0/-1,M10.5.0/0" + where the transition time −1:00 means 23:00 the previous day.
    • +
    +

    +However POSIX.1-2024, like earlier POSIX editions, has some limitations: +

    • The TZ environment variable is process-global, which makes it hard to write efficient, thread-safe applications that @@ -1003,16 +1064,34 @@

      POSIX.1-2017 properties and limitations

      handling daylight saving time shifts – as might be required to limit phone calls to off-peak hours.
    • -
    • - POSIX.1-2017 provides no convenient and efficient way to determine - the UT offset and time zone abbreviation of arbitrary - timestamps, particularly for timezones - that do not fit into the POSIX model. -
    • POSIX requires that time_t clock counts exclude leap seconds.
    • +
    • + POSIX does not define the DST transitions + for TZ values like + "EST5EDT". + Traditionally the current US DST rules + were used to interpret such values, but this meant that the + US DST rules were compiled into each + time conversion package, and when + US time conversion rules changed (as in the United + States in 1987 and again in 2007), all packages that + interpreted TZ values had to be updated + to ensure proper results. +
    • +
    + +

    Extensions to POSIX in the +tz code

    +

    + The tz code defines some properties + left unspecified by POSIX, and attempts to support some + extensions to POSIX. +

    + +
    • The tz code attempts to support all the time_t implementations allowed by POSIX. @@ -1026,21 +1105,14 @@

      POSIX.1-2017 properties and limitations

      and 40-bit integers are also used occasionally. Although earlier POSIX versions allowed time_t to be a floating-point type, this was not supported by any practical system, - and POSIX.1-2013 and the tz code both + and POSIX.1-2013+ and the tz code both require time_t to be an integer type.
    • -
    - -

    Extensions to POSIX.1-2017 in the -tz code

    -
    • - The TZ environment variable is used in generating - the name of a file from which time-related information is read - (or is interpreted à la POSIX.1-2017); TZ is no longer - constrained to be a string containing abbreviations - and numeric data as described above. + If the TZ environment variable uses the geographical format, + it is used in generating + the name of a file from which time-related information is read. The file's format is TZif, a timezone information format that contains binary data; see Internet @@ -1053,10 +1125,11 @@

      Extensions to POSIX.1-2017 in the abbreviations are used.

      - It was recognized that allowing the TZ environment + When the tz code was developed in the 1980s, + it was recognized that allowing the TZ environment variable to take on values such as 'America/New_York' might cause "old" programs (that expect TZ to have a - certain form) to operate incorrectly; consideration was given to using + certain format) to operate incorrectly; consideration was given to using some other environment variable (for example, TIMEZONE) to hold the string used to generate the TZif file's name. In the end, however, it was decided to continue using @@ -1069,15 +1142,6 @@

      Extensions to POSIX.1-2017 in the assume pre-POSIX TZ values.

    • -
    • - The code supports platforms with a UT offset member - in struct tm, e.g., tm_gmtoff, - or with a time zone abbreviation member in - struct tm, e.g., tm_zone. As noted - in Austin - Group defect 1533, a future version of POSIX is planned to - require tm_gmtoff and tm_zone. -
    • Functions tzalloc, tzfree, localtime_rz, and mktime_z for @@ -1088,7 +1152,7 @@

      Extensions to POSIX.1-2017 in the and localtime_rz and mktime_z are like localtime_r and mktime with an extra timezone_t argument. - The functions were inspired by NetBSD. + The functions were inspired by NetBSD.

    • Negative time_t values are supported, on systems @@ -1116,6 +1180,7 @@

      POSIX features no longer needed

    • The POSIX tzname variable does not suffice and is no longer needed. + It is planned to be removed in a future edition of POSIX. To get a timestamp's time zone abbreviation, consult the tm_zone member if available; otherwise, use strftime's "%Z" conversion @@ -1124,6 +1189,7 @@

      POSIX features no longer needed

    • The POSIX daylight and timezone variables do not suffice and are no longer needed. + They are planned to be removed in a future edition of POSIX. To get a timestamp's UT offset, consult the tm_gmtoff member if available; otherwise, subtract values returned by localtime @@ -1278,13 +1344,13 @@

      Leap seconds

      Leap seconds were introduced in 1972 to accommodate the difference between atomic time and the less regular rotation of the earth. -Unfortunately they caused so many problems with civil -timekeeping that they -are planned -to be discontinued by 2035, with some as-yet-undetermined -mechanism replacing them, perhaps after the year 2135. -Despite their impending obsolescence, a record of leap seconds is still -needed to resolve timestamps from 1972 through 2035. +Unfortunately they have caused so many problems with civil +timekeeping that there are +plans +to discontinue them by 2035. +Even if these plans come to fruition, a record of leap seconds will still be +needed to resolve timestamps from 1972 through 2035, +and there may also be a need to record whatever mechanism replaces them.

      @@ -1374,6 +1440,12 @@

      Time and time zones off Earth

      the establishment of a reference timescale for the Moon, which has days roughly equivalent to 29.5 Earth days, and where relativistic effects cause clocks to tick slightly faster than on Earth. +Also, NASA +has been ordered +to consider the establishment of Coordinated Lunar Time (LTC). +It is not yet known whether the US and European efforts will result in +multiple timescales on the Moon.

      diff --git a/version b/version index 04fe6744432f..699e50d4d38e 100644 --- a/version +++ b/version @@ -1 +1 @@ -2024a +2024b diff --git a/ziguard.awk b/ziguard.awk index 7a3404fa4fcc..c0acb72a0380 100644 --- a/ziguard.awk +++ b/ziguard.awk @@ -5,14 +5,10 @@ # This is not a general-purpose converter; it is designed for current tzdata. # It just converts from current source to main, vanguard, and rearguard forms. # Although it might be nice for it to be idempotent, or to be useful -# for converting back and forth between vanguard and rearguard formats, +# for converting back and forth between formats, # it does not do these nonessential tasks now. # -# Although main and vanguard forms are currently equivalent, -# this need not always be the case. When the two forms differ, -# this script can convert either from main to vanguard form (needed then), -# or from vanguard to main form (this conversion would be needed later, -# after main became rearguard and vanguard became main). +# This script can convert from main to vanguard form and vice versa. # There is no need to convert rearguard to other forms. # # When converting to vanguard form, the output can use the line @@ -145,12 +141,12 @@ DATAFORM != "main" { } # If this line should differ due to Portugal benefiting from %z if supported, - # uncomment the desired version and comment out the undesired one. - if ($0 ~ /^#?[\t ]+-[12]:00[\t ]+Port[\t ]+[%+-]/) { - if (($0 ~ /%z/) == (DATAFORM == "vanguard")) { - uncomment = in_comment - } else { + # comment out the undesired version and uncomment the desired one. + if ($0 ~ /^#?[\t ]+-[12]:00[\t ]+((Port|W-Eur)[\t ]+[%+-]|-[\t ]+(%z|-01)[\t ]+1982 Mar 28)/) { + if (($0 ~ /%z/) == (DATAFORM == "rearguard")) { comment_out = !in_comment + } else { + uncomment = in_comment } } @@ -172,13 +168,8 @@ DATAFORM != "main" { sub(/^/, "#") } - # Prefer %z in vanguard form, explicit abbreviations otherwise. - if (DATAFORM == "vanguard") { - sub(/^(Zone[\t ]+[^\t ]+)?[\t ]+[^\t ]+[\t ]+[^\t ]+[\t ]+[-+][^\t ]+/, \ - "&CHANGE-TO-%z") - sub(/-00CHANGE-TO-%z/, "-00") - sub(/[-+][^\t ]+CHANGE-TO-/, "") - } else { + # Prefer explicit abbreviations in rearguard form, %z otherwise. + if (DATAFORM == "rearguard") { if ($0 ~ /^[^#]*%z/) { stdoff_column = 2 * ($0 ~ /^Zone/) + 1 rules_column = stdoff_column + 1 @@ -216,6 +207,11 @@ DATAFORM != "main" { } sub(/%z/, abbr) } + } else { + sub(/^(Zone[\t ]+[^\t ]+)?[\t ]+[^\t ]+[\t ]+[^\t ]+[\t ]+[-+][^\t ]+/, \ + "&CHANGE-TO-%z") + sub(/-00CHANGE-TO-%z/, "-00") + sub(/[-+][^\t ]+CHANGE-TO-/, "") } # Normally, prefer whole seconds. However, prefer subseconds diff --git a/zone.tab b/zone.tab index 3fa9306afbad..bfc0b5933044 100644 --- a/zone.tab +++ b/zone.tab @@ -264,8 +264,7 @@ MK +4159+02126 Europe/Skopje ML +1239-00800 Africa/Bamako MM +1647+09610 Asia/Yangon MN +4755+10653 Asia/Ulaanbaatar most of Mongolia -MN +4801+09139 Asia/Hovd Bayan-Olgiy, Govi-Altai, Hovd, Uvs, Zavkhan -MN +4804+11430 Asia/Choibalsan Dornod, Sukhbaatar +MN +4801+09139 Asia/Hovd Bayan-Olgii, Hovd, Uvs MO +221150+1133230 Asia/Macau MP +1512+14545 Pacific/Saipan MQ +1436-06105 America/Martinique diff --git a/zone1970.tab b/zone1970.tab index abd9489753f1..7726f39a0922 100644 --- a/zone1970.tab +++ b/zone1970.tab @@ -209,8 +209,7 @@ MD +4700+02850 Europe/Chisinau MH +0905+16720 Pacific/Kwajalein Kwajalein MM,CC +1647+09610 Asia/Yangon MN +4755+10653 Asia/Ulaanbaatar most of Mongolia -MN +4801+09139 Asia/Hovd Bayan-Ölgii, Govi-Altai, Hovd, Uvs, Zavkhan -MN +4804+11430 Asia/Choibalsan Dornod, Sükhbaatar +MN +4801+09139 Asia/Hovd Bayan-Ölgii, Hovd, Uvs MO +221150+1133230 Asia/Macau MQ +1436-06105 America/Martinique MT +3554+01431 Europe/Malta diff --git a/zonenow.tab b/zonenow.tab index b6f2910956fb..01f536b3ba38 100644 --- a/zonenow.tab +++ b/zonenow.tab @@ -5,7 +5,7 @@ # From Paul Eggert (2023-12-18): # This file contains a table where each row stands for a timezone # where civil timestamps are predicted to agree from now on. -# This file is like zone1970.tab (see zone1970.tab's coments), +# This file is like zone1970.tab (see zone1970.tab's comments), # but with the following changes: # # 1. Each timezone corresponds to a set of clocks that are planned @@ -123,8 +123,6 @@ XX +1455-02331 Atlantic/Cape_Verde Cape Verde # # -01/+00 (EU DST) XX +3744-02540 Atlantic/Azores Azores -# -01/+00 (EU DST) until 2024-03-31; then -02/-01 (EU DST) -XX +7029-02158 America/Scoresbysund Ittoqqortoormiit # # +00 - GMT XX +0519-00402 Africa/Abidjan far western Africa; Iceland ("GMT") @@ -199,7 +197,7 @@ XX +2518+05518 Asia/Dubai Russia; Caucasus; Persian Gulf; Seychelles; Réunion XX +3431+06912 Asia/Kabul Afghanistan # # +05 -XX +4120+06918 Asia/Tashkent Russia; west Kazakhstan; Tajikistan; Turkmenistan; Uzbekistan; Maldives +XX +4120+06918 Asia/Tashkent Russia; Kazakhstan; Tajikistan; Turkmenistan; Uzbekistan; Maldives # # +05 - PKT XX +2452+06703 Asia/Karachi Pakistan ("PKT") @@ -215,8 +213,6 @@ XX +2743+08519 Asia/Kathmandu Nepal # # +06 XX +2343+09025 Asia/Dhaka Russia; Kyrgyzstan; Bhutan; Bangladesh; Chagos -# +06 until 2024-03-01; then +05 -XX +4315+07657 Asia/Almaty Kazakhstan (except western areas) # # +06:30 XX +1647+09610 Asia/Yangon Myanmar; Cocos From 674cbf38f6d0a0b307e52c4265da9f077606b035 Mon Sep 17 00:00:00 2001 From: Navdeep Parhar Date: Thu, 5 Sep 2024 23:21:59 -0700 Subject: [PATCH 173/213] cxgbe/t4_tom: Add synq entry to the list before calling send_synack. This fixes a panic where the peer's ack to the synack arrives on a different queue and do_pass_establish tries to remove the synqe from synqe_list before it has been added by do_pass_accept_req. Reported by: Sony Arpita Das @ Chelsio Fixes: 283333c0e329 cxgbe/t4_tom: Track all synq entries in a per-adapter list. MFC after: 1 week Sponsored by: Chelsio Communications --- sys/dev/cxgbe/tom/t4_listen.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/sys/dev/cxgbe/tom/t4_listen.c b/sys/dev/cxgbe/tom/t4_listen.c index f91d193c0fed..8a39218a55ba 100644 --- a/sys/dev/cxgbe/tom/t4_listen.c +++ b/sys/dev/cxgbe/tom/t4_listen.c @@ -1494,18 +1494,20 @@ do_pass_accept_req(struct sge_iq *iq, const struct rss_header *rss, synqe->tid = tid; synqe->syn = m; m = NULL; + mtx_lock(&td->toep_list_lock); + TAILQ_INSERT_TAIL(&td->synqe_list, synqe, link); + mtx_unlock(&td->toep_list_lock); if (send_synack(sc, synqe, opt0, opt2, tid) != 0) { remove_tid(sc, tid, ntids); m = synqe->syn; synqe->syn = NULL; + mtx_lock(&td->toep_list_lock); + TAILQ_REMOVE(&td->synqe_list, synqe, link); + mtx_unlock(&td->toep_list_lock); NET_EPOCH_EXIT(et); REJECT_PASS_ACCEPT_REQ(true); } - - mtx_lock(&td->toep_list_lock); - TAILQ_INSERT_TAIL(&td->synqe_list, synqe, link); - mtx_unlock(&td->toep_list_lock); CTR6(KTR_CXGBE, "%s: stid %u, tid %u, synqe %p, opt0 %#016lx, opt2 %#08x", __func__, stid, tid, synqe, be64toh(opt0), be32toh(opt2)); From 390dc369efaaeca2802baf168ddbd7a40e3afcc8 Mon Sep 17 00:00:00 2001 From: Tom Jones Date: Fri, 6 Sep 2024 12:59:09 +0100 Subject: [PATCH 174/213] pf: Add support for endpoint independent NAT bindings for UDP With Endpoint Independent NAT bindings for UDP flows from a NATed source address are always mapped to the same ip:port pair on the NAT router. This allows a client to connect to multiple external servers while appearing as the same host and enables NAT traversal without requiring the client to use a middlebox traversal protocol such as STUN or TURN. Introduce the 'endpoint-independent' option to NAT rules to allow configuration of endpoint independent without effecting existing deployments. This change satisfies REQ 1 and 3 of RFC 4787 also known as 'full cone' NAT. Using Endpoint Independent NAT changes NAT exhaustion behaviour it does not introduce any additional security considerations compared to other forms of NAT. PR: 219803 Co-authored-by: Damjan Jovanovic Co-authored-by: Naman Sood Reviewed-by: kp Sponsored-by: Tailscale Sponsored-by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D11137 --- sbin/pfctl/parse.y | 12 +- sbin/pfctl/pfctl_parser.c | 2 + sbin/pfctl/tests/files/pf1021.in | 1 + sbin/pfctl/tests/files/pf1021.ok | 1 + share/man/man4/pf.4 | 6 +- share/man/man5/pf.conf.5 | 12 +- sys/net/pfvar.h | 49 +++++++- sys/netpfil/pf/pf.c | 195 ++++++++++++++++++++++++++++++- sys/netpfil/pf/pf.h | 1 + sys/netpfil/pf/pf_lb.c | 104 ++++++++++++++--- tests/sys/netpfil/pf/nat.sh | 134 +++++++++++++++++++++ 11 files changed, 489 insertions(+), 28 deletions(-) create mode 100644 sbin/pfctl/tests/files/pf1021.in create mode 100644 sbin/pfctl/tests/files/pf1021.ok diff --git a/sbin/pfctl/parse.y b/sbin/pfctl/parse.y index 724ffefcd7d9..f54f24a14a7c 100644 --- a/sbin/pfctl/parse.y +++ b/sbin/pfctl/parse.y @@ -326,6 +326,7 @@ static struct pool_opts { int marker; #define POM_TYPE 0x01 #define POM_STICKYADDRESS 0x02 +#define POM_ENDPI 0x04 u_int8_t opts; int type; int staticport; @@ -512,7 +513,7 @@ int parseport(char *, struct range *r, int); %token UPPERLIMIT QUEUE PRIORITY QLIMIT HOGS BUCKETS RTABLE TARGET INTERVAL %token DNPIPE DNQUEUE RIDENTIFIER %token LOAD RULESET_OPTIMIZATION PRIO -%token STICKYADDRESS MAXSRCSTATES MAXSRCNODES SOURCETRACK GLOBAL RULE +%token STICKYADDRESS ENDPI MAXSRCSTATES MAXSRCNODES SOURCETRACK GLOBAL RULE %token MAXSRCCONN MAXSRCCONNRATE OVERLOAD FLUSH SLOPPY PFLOW %token TAGGED TAG IFBOUND FLOATING STATEPOLICY STATEDEFAULTS ROUTE SETTOS %token DIVERTTO DIVERTREPLY BRIDGE_TO @@ -4593,6 +4594,14 @@ pool_opt : BITMASK { pool_opts.marker |= POM_STICKYADDRESS; pool_opts.opts |= PF_POOL_STICKYADDR; } + | ENDPI { + if (pool_opts.marker & POM_ENDPI) { + yyerror("endpoint-independent cannot be redefined"); + YYERROR; + } + pool_opts.marker |= POM_ENDPI; + pool_opts.opts |= PF_POOL_ENDPI; + } | MAPEPORTSET number '/' number '/' number { if (pool_opts.mape.offset) { yyerror("map-e-portset cannot be redefined"); @@ -6299,6 +6308,7 @@ lookup(char *s) { "dnqueue", DNQUEUE}, { "drop", DROP}, { "dup-to", DUPTO}, + { "endpoint-independent", ENDPI}, { "ether", ETHER}, { "fail-policy", FAILPOLICY}, { "fairq", FAIRQ}, diff --git a/sbin/pfctl/pfctl_parser.c b/sbin/pfctl/pfctl_parser.c index e71b7b160495..a9416534626b 100644 --- a/sbin/pfctl/pfctl_parser.c +++ b/sbin/pfctl/pfctl_parser.c @@ -488,6 +488,8 @@ print_pool(struct pfctl_pool *pool, u_int16_t p1, u_int16_t p2, } if (pool->opts & PF_POOL_STICKYADDR) printf(" sticky-address"); + if (pool->opts & PF_POOL_ENDPI) + printf(" endpoint-independent"); if (id == PF_NAT && p1 == 0 && p2 == 0) printf(" static-port"); if (pool->mape.offset > 0) diff --git a/sbin/pfctl/tests/files/pf1021.in b/sbin/pfctl/tests/files/pf1021.in new file mode 100644 index 000000000000..841b024157c6 --- /dev/null +++ b/sbin/pfctl/tests/files/pf1021.in @@ -0,0 +1 @@ +nat on vtnet1 inet from ! (vtnet1) to any -> (vtnet1) endpoint-independent diff --git a/sbin/pfctl/tests/files/pf1021.ok b/sbin/pfctl/tests/files/pf1021.ok new file mode 100644 index 000000000000..3b5b84e2e11b --- /dev/null +++ b/sbin/pfctl/tests/files/pf1021.ok @@ -0,0 +1 @@ +nat on vtnet1 inet from ! (vtnet1) to any -> (vtnet1) round-robin endpoint-independent diff --git a/share/man/man4/pf.4 b/share/man/man4/pf.4 index 9bfc75cb490d..3855d07faead 100644 --- a/share/man/man4/pf.4 +++ b/share/man/man4/pf.4 @@ -26,7 +26,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd September 2, 2024 +.Dd September 6, 2024 .Dt PF 4 .Os .Sh NAME @@ -89,6 +89,10 @@ Should be power of 2. Default value is 32768. .It Va net.pf.rule_tag_hashsize Size of the hash table that stores tags. +.It Va net.pf.udpendpoint_hashsize +Size of hash table that store UDP endpoint mappings. +Should be power of 2. +Default value is 32768. .It Va net.pf.default_to_drop This value overrides .Cd "options PF_DEFAULT_TO_DROP" diff --git a/share/man/man5/pf.conf.5 b/share/man/man5/pf.conf.5 index f04b0799741e..5aa936d509ed 100644 --- a/share/man/man5/pf.conf.5 +++ b/share/man/man5/pf.conf.5 @@ -27,7 +27,7 @@ .\" ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.Dd June 24, 2024 +.Dd September 4, 2024 .Dt PF.CONF 5 .Os .Sh NAME @@ -2278,6 +2278,16 @@ from modifying the source port on TCP and UDP packets. With .Ar nat rules, the +.It Ar endpoint-independent +With +.Ar nat +rules, the +.Ar endpoint-independent +option caues +.Xr pf 4 +to always map connections from a UDP source address and port to the same +NAT address and port. +This feature implements "full-cone" NAT behavior. .Ar map-e-portset option enables the source port translation of MAP-E (RFC 7597) Customer Edge. In order to make the host act as a MAP-E Customer Edge, setting up a tunneling diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h index 7b3c1c49696a..c123da37d2cb 100644 --- a/sys/net/pfvar.h +++ b/sys/net/pfvar.h @@ -940,6 +940,29 @@ struct pf_state_peer { u_int8_t pad[1]; }; +/* Keep synced with struct pf_udp_endpoint. */ +struct pf_udp_endpoint_cmp { + struct pf_addr addr; + uint16_t port; + sa_family_t af; + uint8_t pad[1]; +}; + +struct pf_udp_endpoint { + struct pf_addr addr; + uint16_t port; + sa_family_t af; + uint8_t pad[1]; + + struct pf_udp_mapping *mapping; + LIST_ENTRY(pf_udp_endpoint) entry; +}; + +struct pf_udp_mapping { + struct pf_udp_endpoint endpoints[2]; + u_int refs; +}; + /* Keep synced with struct pf_state_key. */ struct pf_state_key_cmp { struct pf_addr addr[2]; @@ -1069,6 +1092,7 @@ struct pf_kstate { union pf_krule_ptr nat_rule; struct pf_addr rt_addr; struct pf_state_key *key[2]; /* addresses stack and wire */ + struct pf_udp_mapping *udp_mapping; struct pfi_kkif *kif; struct pfi_kkif *orig_kif; /* The real kif, even if we're a floating state (i.e. if == V_pfi_all). */ struct pfi_kkif *rt_kif; @@ -2124,17 +2148,28 @@ struct pf_idhash { struct mtx lock; }; +struct pf_udpendpointhash { + LIST_HEAD(, pf_udp_endpoint) endpoints; + /* refcont is synchronized on the source endpoint's row lock */ + struct mtx lock; +}; + extern u_long pf_ioctl_maxcount; VNET_DECLARE(u_long, pf_hashmask); #define V_pf_hashmask VNET(pf_hashmask) VNET_DECLARE(u_long, pf_srchashmask); #define V_pf_srchashmask VNET(pf_srchashmask) +VNET_DECLARE(u_long, pf_udpendpointhashmask); +#define V_pf_udpendpointhashmask VNET(pf_udpendpointhashmask) #define PF_HASHSIZ (131072) #define PF_SRCHASHSIZ (PF_HASHSIZ/4) +#define PF_UDPENDHASHSIZ (PF_HASHSIZ/4) VNET_DECLARE(struct pf_keyhash *, pf_keyhash); VNET_DECLARE(struct pf_idhash *, pf_idhash); +VNET_DECLARE(struct pf_udpendpointhash *, pf_udpendpointhash); #define V_pf_keyhash VNET(pf_keyhash) #define V_pf_idhash VNET(pf_idhash) +#define V_pf_udpendpointhash VNET(pf_udpendpointhash) VNET_DECLARE(struct pf_srchash *, pf_srchash); #define V_pf_srchash VNET(pf_srchash) @@ -2209,6 +2244,8 @@ VNET_DECLARE(uma_zone_t, pf_state_z); #define V_pf_state_z VNET(pf_state_z) VNET_DECLARE(uma_zone_t, pf_state_key_z); #define V_pf_state_key_z VNET(pf_state_key_z) +VNET_DECLARE(uma_zone_t, pf_udp_mapping_z); +#define V_pf_udp_mapping_z VNET(pf_udp_mapping_z) VNET_DECLARE(uma_zone_t, pf_state_scrub_z); #define V_pf_state_scrub_z VNET(pf_state_scrub_z) @@ -2281,6 +2318,15 @@ extern struct pf_kstate *pf_find_state_all( extern bool pf_find_state_all_exists( const struct pf_state_key_cmp *, u_int); +extern struct pf_udp_mapping *pf_udp_mapping_find(struct pf_udp_endpoint_cmp + *endpoint); +extern struct pf_udp_mapping *pf_udp_mapping_create(sa_family_t af, + struct pf_addr *src_addr, uint16_t src_port, + struct pf_addr *nat_addr, uint16_t nat_port); +extern int pf_udp_mapping_insert(struct pf_udp_mapping + *mapping); +extern void pf_udp_mapping_release(struct pf_udp_mapping + *mapping); extern struct pf_ksrc_node *pf_find_src_node(struct pf_addr *, struct pf_krule *, sa_family_t, struct pf_srchash **, bool); @@ -2574,7 +2620,8 @@ u_short pf_get_translation(struct pf_pdesc *, struct mbuf *, struct pf_state_key **, struct pf_state_key **, struct pf_addr *, struct pf_addr *, uint16_t, uint16_t, struct pf_kanchor_stackframe *, - struct pf_krule **); + struct pf_krule **, + struct pf_udp_mapping **udp_mapping); struct pf_state_key *pf_state_key_setup(struct pf_pdesc *, struct mbuf *, int, struct pf_addr *, struct pf_addr *, u_int16_t, u_int16_t); diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c index f7fe75184efd..70220dda935e 100644 --- a/sys/netpfil/pf/pf.c +++ b/sys/netpfil/pf/pf.c @@ -283,6 +283,7 @@ VNET_DEFINE_STATIC(uma_zone_t, pf_sources_z); uma_zone_t pf_mtag_z; VNET_DEFINE(uma_zone_t, pf_state_z); VNET_DEFINE(uma_zone_t, pf_state_key_z); +VNET_DEFINE(uma_zone_t, pf_udp_mapping_z); VNET_DEFINE(struct unrhdr64, pf_stateid); @@ -330,7 +331,7 @@ static int pf_create_state(struct pf_krule *, struct pf_krule *, struct pf_state_key *, struct mbuf *, int, u_int16_t, u_int16_t, int *, struct pfi_kkif *, struct pf_kstate **, int, u_int16_t, u_int16_t, - int, struct pf_krule_slist *); + int, struct pf_krule_slist *, struct pf_udp_mapping *); static int pf_state_key_addr_setup(struct pf_pdesc *, struct mbuf *, int, struct pf_state_key_cmp *, int, struct pf_addr *, int, struct pf_addr *, int); @@ -493,22 +494,29 @@ MALLOC_DEFINE(M_PF_RULE_ITEM, "pf_krule_item", "pf(4) rule items"); VNET_DEFINE(struct pf_keyhash *, pf_keyhash); VNET_DEFINE(struct pf_idhash *, pf_idhash); VNET_DEFINE(struct pf_srchash *, pf_srchash); +VNET_DEFINE(struct pf_udpendpointhash *, pf_udpendpointhash); +VNET_DEFINE(struct pf_udpendpointmapping *, pf_udpendpointmapping); SYSCTL_NODE(_net, OID_AUTO, pf, CTLFLAG_RW | CTLFLAG_MPSAFE, 0, "pf(4)"); VNET_DEFINE(u_long, pf_hashmask); VNET_DEFINE(u_long, pf_srchashmask); +VNET_DEFINE(u_long, pf_udpendpointhashmask); VNET_DEFINE_STATIC(u_long, pf_hashsize); #define V_pf_hashsize VNET(pf_hashsize) VNET_DEFINE_STATIC(u_long, pf_srchashsize); #define V_pf_srchashsize VNET(pf_srchashsize) +VNET_DEFINE_STATIC(u_long, pf_udpendpointhashsize); +#define V_pf_udpendpointhashsize VNET(pf_udpendpointhashsize) u_long pf_ioctl_maxcount = 65535; SYSCTL_ULONG(_net_pf, OID_AUTO, states_hashsize, CTLFLAG_VNET | CTLFLAG_RDTUN, &VNET_NAME(pf_hashsize), 0, "Size of pf(4) states hashtable"); SYSCTL_ULONG(_net_pf, OID_AUTO, source_nodes_hashsize, CTLFLAG_VNET | CTLFLAG_RDTUN, &VNET_NAME(pf_srchashsize), 0, "Size of pf(4) source nodes hashtable"); +SYSCTL_ULONG(_net_pf, OID_AUTO, udpendpoint_hashsize, CTLFLAG_VNET | CTLFLAG_RDTUN, + &VNET_NAME(pf_udpendpointhashsize), 0, "Size of pf(4) endpoint hashtable"); SYSCTL_ULONG(_net_pf, OID_AUTO, request_maxcount, CTLFLAG_RWTUN, &pf_ioctl_maxcount, 0, "Maximum number of tables, addresses, ... in a single ioctl() call"); @@ -699,6 +707,17 @@ pf_hashsrc(struct pf_addr *addr, sa_family_t af) return (h & V_pf_srchashmask); } +static inline uint32_t +pf_hashudpendpoint(struct pf_udp_endpoint *endpoint) +{ + uint32_t h; + + h = murmur3_32_hash32((uint32_t *)endpoint, + sizeof(struct pf_udp_endpoint_cmp)/sizeof(uint32_t), + V_pf_hashseed); + return (h & V_pf_udpendpointhashmask); +} + #ifdef ALTQ static int pf_state_hash(struct pf_kstate *s) @@ -1086,12 +1105,15 @@ pf_initialize(void) struct pf_keyhash *kh; struct pf_idhash *ih; struct pf_srchash *sh; + struct pf_udpendpointhash *uh; u_int i; if (V_pf_hashsize == 0 || !powerof2(V_pf_hashsize)) V_pf_hashsize = PF_HASHSIZ; if (V_pf_srchashsize == 0 || !powerof2(V_pf_srchashsize)) V_pf_srchashsize = PF_SRCHASHSIZ; + if (V_pf_udpendpointhashsize == 0 || !powerof2(V_pf_udpendpointhashsize)) + V_pf_udpendpointhashsize = PF_UDPENDHASHSIZ; V_pf_hashseed = arc4random(); @@ -1154,6 +1176,30 @@ pf_initialize(void) for (i = 0, sh = V_pf_srchash; i <= V_pf_srchashmask; i++, sh++) mtx_init(&sh->lock, "pf_srchash", NULL, MTX_DEF); + + /* UDP endpoint mappings. */ + V_pf_udp_mapping_z = uma_zcreate("pf UDP mappings", + sizeof(struct pf_udp_mapping), NULL, NULL, NULL, NULL, + UMA_ALIGN_PTR, 0); + V_pf_udpendpointhash = mallocarray(V_pf_udpendpointhashsize, + sizeof(struct pf_udpendpointhash), M_PFHASH, M_NOWAIT | M_ZERO); + if (V_pf_udpendpointhash == NULL) { + printf("pf: Unable to allocate memory for " + "udpendpoint_hashsize %lu.\n", V_pf_udpendpointhashsize); + + V_pf_udpendpointhashsize = PF_UDPENDHASHSIZ; + V_pf_udpendpointhash = mallocarray(V_pf_udpendpointhashsize, + sizeof(struct pf_udpendpointhash), M_PFHASH, M_WAITOK | M_ZERO); + } + + V_pf_udpendpointhashmask = V_pf_udpendpointhashsize - 1; + for (i = 0, uh = V_pf_udpendpointhash; + i <= V_pf_udpendpointhashmask; + i++, uh++) { + mtx_init(&uh->lock, "pf_udpendpointhash", NULL, + MTX_DEF | MTX_DUPOK); + } + /* ALTQ */ TAILQ_INIT(&V_pf_altqs[0]); TAILQ_INIT(&V_pf_altqs[1]); @@ -1187,10 +1233,12 @@ pf_cleanup(void) struct pf_keyhash *kh; struct pf_idhash *ih; struct pf_srchash *sh; + struct pf_udpendpointhash *uh; struct pf_send_entry *pfse, *next; u_int i; - for (i = 0, kh = V_pf_keyhash, ih = V_pf_idhash; i <= V_pf_hashmask; + for (i = 0, kh = V_pf_keyhash, ih = V_pf_idhash; + i <= V_pf_hashmask; i++, kh++, ih++) { KASSERT(LIST_EMPTY(&kh->keys), ("%s: key hash not empty", __func__)); @@ -1209,6 +1257,15 @@ pf_cleanup(void) } free(V_pf_srchash, M_PFHASH); + for (i = 0, uh = V_pf_udpendpointhash; + i <= V_pf_udpendpointhashmask; + i++, uh++) { + KASSERT(LIST_EMPTY(&uh->endpoints), + ("%s: udp endpoint hash not empty", __func__)); + mtx_destroy(&uh->lock); + } + free(V_pf_udpendpointhash, M_PFHASH); + STAILQ_FOREACH_SAFE(pfse, &V_pf_sendqueue, pfse_next, next) { m_freem(pfse->pfse_m); free(pfse, M_PFTEMP); @@ -1218,6 +1275,7 @@ pf_cleanup(void) uma_zdestroy(V_pf_sources_z); uma_zdestroy(V_pf_state_z); uma_zdestroy(V_pf_state_key_z); + uma_zdestroy(V_pf_udp_mapping_z); } static int @@ -1807,6 +1865,123 @@ pf_find_state_all_exists(const struct pf_state_key_cmp *key, u_int dir) return (false); } +struct pf_udp_mapping * +pf_udp_mapping_create(sa_family_t af, struct pf_addr *src_addr, uint16_t src_port, + struct pf_addr *nat_addr, uint16_t nat_port) +{ + struct pf_udp_mapping *mapping; + + mapping = uma_zalloc(V_pf_udp_mapping_z, M_NOWAIT | M_ZERO); + if (mapping == NULL) + return (NULL); + PF_ACPY(&mapping->endpoints[0].addr, src_addr, af); + mapping->endpoints[0].port = src_port; + mapping->endpoints[0].af = af; + mapping->endpoints[0].mapping = mapping; + PF_ACPY(&mapping->endpoints[1].addr, nat_addr, af); + mapping->endpoints[1].port = nat_port; + mapping->endpoints[1].af = af; + mapping->endpoints[1].mapping = mapping; + refcount_init(&mapping->refs, 1); + return (mapping); +} + +int +pf_udp_mapping_insert(struct pf_udp_mapping *mapping) +{ + struct pf_udpendpointhash *h0, *h1; + struct pf_udp_endpoint *endpoint; + int ret = EEXIST; + + h0 = &V_pf_udpendpointhash[pf_hashudpendpoint(&mapping->endpoints[0])]; + h1 = &V_pf_udpendpointhash[pf_hashudpendpoint(&mapping->endpoints[1])]; + if (h0 == h1) { + PF_HASHROW_LOCK(h0); + } else if (h0 < h1) { + PF_HASHROW_LOCK(h0); + PF_HASHROW_LOCK(h1); + } else { + PF_HASHROW_LOCK(h1); + PF_HASHROW_LOCK(h0); + } + + LIST_FOREACH(endpoint, &h0->endpoints, entry) { + if (bcmp(endpoint, &mapping->endpoints[0], + sizeof(struct pf_udp_endpoint_cmp)) == 0) + break; + } + if (endpoint != NULL) + goto cleanup; + LIST_FOREACH(endpoint, &h1->endpoints, entry) { + if (bcmp(endpoint, &mapping->endpoints[1], + sizeof(struct pf_udp_endpoint_cmp)) == 0) + break; + } + if (endpoint != NULL) + goto cleanup; + LIST_INSERT_HEAD(&h0->endpoints, &mapping->endpoints[0], entry); + LIST_INSERT_HEAD(&h1->endpoints, &mapping->endpoints[1], entry); + ret = 0; + +cleanup: + if (h0 != h1) { + PF_HASHROW_UNLOCK(h0); + PF_HASHROW_UNLOCK(h1); + } else { + PF_HASHROW_UNLOCK(h0); + } + return (ret); +} + +void +pf_udp_mapping_release(struct pf_udp_mapping *mapping) +{ + /* refcount is synchronized on the source endpoint's row lock */ + struct pf_udpendpointhash *h0, *h1; + + if (mapping == NULL) + return; + + h0 = &V_pf_udpendpointhash[pf_hashudpendpoint(&mapping->endpoints[0])]; + PF_HASHROW_LOCK(h0); + if (refcount_release(&mapping->refs)) { + LIST_REMOVE(&mapping->endpoints[0], entry); + PF_HASHROW_UNLOCK(h0); + h1 = &V_pf_udpendpointhash[pf_hashudpendpoint(&mapping->endpoints[1])]; + PF_HASHROW_LOCK(h1); + LIST_REMOVE(&mapping->endpoints[1], entry); + PF_HASHROW_UNLOCK(h1); + + uma_zfree(V_pf_udp_mapping_z, mapping); + } else { + PF_HASHROW_UNLOCK(h0); + } +} + + +struct pf_udp_mapping * +pf_udp_mapping_find(struct pf_udp_endpoint_cmp *key) +{ + struct pf_udpendpointhash *uh; + struct pf_udp_endpoint *endpoint; + + uh = &V_pf_udpendpointhash[pf_hashudpendpoint((struct pf_udp_endpoint*)key)]; + + PF_HASHROW_LOCK(uh); + LIST_FOREACH(endpoint, &uh->endpoints, entry) { + if (bcmp(endpoint, key, sizeof(struct pf_udp_endpoint_cmp)) == 0 && + bcmp(endpoint, &endpoint->mapping->endpoints[0], + sizeof(struct pf_udp_endpoint_cmp)) == 0) + break; + } + if (endpoint == NULL) { + PF_HASHROW_UNLOCK(uh); + return (NULL); + } + refcount_acquire(&endpoint->mapping->refs); + PF_HASHROW_UNLOCK(uh); + return (endpoint->mapping); +} /* END state table stuff */ static void @@ -2423,6 +2598,9 @@ pf_unlink_state(struct pf_kstate *s) PF_HASHROW_UNLOCK(ih); pf_detach_state(s); + + pf_udp_mapping_release(s->udp_mapping); + /* pf_state_insert() initialises refs to 2 */ return (pf_release_staten(s, 2)); } @@ -4686,6 +4864,7 @@ pf_test_rule(struct pf_krule **rm, struct pf_kstate **sm, struct pfi_kkif *kif, u_int16_t bproto_sum = 0, bip_sum = 0; u_int8_t icmptype = 0, icmpcode = 0; struct pf_kanchor_stackframe anchor_stack[PF_ANCHOR_STACKSIZE]; + struct pf_udp_mapping *udp_mapping = NULL; PF_RULES_RASSERT(); @@ -4760,7 +4939,7 @@ pf_test_rule(struct pf_krule **rm, struct pf_kstate **sm, struct pfi_kkif *kif, /* check packet for BINAT/NAT/RDR */ transerror = pf_get_translation(pd, m, off, kif, &nsn, &sk, - &nk, saddr, daddr, sport, dport, anchor_stack, &nr); + &nk, saddr, daddr, sport, dport, anchor_stack, &nr, &udp_mapping); switch (transerror) { default: /* A translation error occurred. */ @@ -5058,8 +5237,9 @@ pf_test_rule(struct pf_krule **rm, struct pf_kstate **sm, struct pfi_kkif *kif, int action; action = pf_create_state(r, nr, a, pd, nsn, nk, sk, m, off, sport, dport, &rewrite, kif, sm, tag, bproto_sum, bip_sum, - hdrlen, &match_rules); + hdrlen, &match_rules, udp_mapping); if (action != PF_PASS) { + pf_udp_mapping_release(udp_mapping); if (action == PF_DROP && (r->rule_flag & PFRULE_RETURN)) pf_return(r, nr, pd, sk, off, m, th, kif, @@ -5075,6 +5255,7 @@ pf_test_rule(struct pf_krule **rm, struct pf_kstate **sm, struct pfi_kkif *kif, uma_zfree(V_pf_state_key_z, sk); uma_zfree(V_pf_state_key_z, nk); + pf_udp_mapping_release(udp_mapping); } /* copy back packet headers if we performed NAT operations */ @@ -5102,6 +5283,8 @@ pf_test_rule(struct pf_krule **rm, struct pf_kstate **sm, struct pfi_kkif *kif, uma_zfree(V_pf_state_key_z, sk); uma_zfree(V_pf_state_key_z, nk); + pf_udp_mapping_release(udp_mapping); + return (PF_DROP); } @@ -5111,7 +5294,7 @@ pf_create_state(struct pf_krule *r, struct pf_krule *nr, struct pf_krule *a, struct pf_state_key *sk, struct mbuf *m, int off, u_int16_t sport, u_int16_t dport, int *rewrite, struct pfi_kkif *kif, struct pf_kstate **sm, int tag, u_int16_t bproto_sum, u_int16_t bip_sum, int hdrlen, - struct pf_krule_slist *match_rules) + struct pf_krule_slist *match_rules, struct pf_udp_mapping *udp_mapping) { struct pf_kstate *s = NULL; struct pf_ksrc_node *sn = NULL; @@ -5328,6 +5511,8 @@ pf_create_state(struct pf_krule *r, struct pf_krule *nr, struct pf_krule *a, return (PF_SYNPROXY_DROP); } + s->udp_mapping = udp_mapping; + return (PF_PASS); csfailed: diff --git a/sys/netpfil/pf/pf.h b/sys/netpfil/pf/pf.h index d5ab4f03a96d..6370164cb291 100644 --- a/sys/netpfil/pf/pf.h +++ b/sys/netpfil/pf/pf.h @@ -129,6 +129,7 @@ enum { PF_ADDR_ADDRMASK, PF_ADDR_NOROUTE, PF_ADDR_DYNIFTL, PF_ADDR_RANGE }; #define PF_POOL_TYPEMASK 0x0f #define PF_POOL_STICKYADDR 0x20 +#define PF_POOL_ENDPI 0x40 #define PF_WSCALE_FLAG 0x80 #define PF_WSCALE_MASK 0x0f diff --git a/sys/netpfil/pf/pf_lb.c b/sys/netpfil/pf/pf_lb.c index 6b0b95e9ce01..cdd68aaf5dab 100644 --- a/sys/netpfil/pf/pf_lb.c +++ b/sys/netpfil/pf/pf_lb.c @@ -62,7 +62,8 @@ static struct pf_krule *pf_match_translation(struct pf_pdesc *, struct mbuf *, uint16_t, int, struct pf_kanchor_stackframe *); static int pf_get_sport(sa_family_t, uint8_t, struct pf_krule *, struct pf_addr *, uint16_t, struct pf_addr *, uint16_t, struct pf_addr *, - uint16_t *, uint16_t, uint16_t, struct pf_ksrc_node **); + uint16_t *, uint16_t, uint16_t, struct pf_ksrc_node **, + struct pf_udp_mapping **); #define mix(a,b,c) \ do { \ @@ -216,14 +217,47 @@ static int pf_get_sport(sa_family_t af, u_int8_t proto, struct pf_krule *r, struct pf_addr *saddr, uint16_t sport, struct pf_addr *daddr, uint16_t dport, struct pf_addr *naddr, uint16_t *nport, uint16_t low, - uint16_t high, struct pf_ksrc_node **sn) + uint16_t high, struct pf_ksrc_node **sn, + struct pf_udp_mapping **udp_mapping) { struct pf_state_key_cmp key; struct pf_addr init_addr; + struct pf_srchash *sh = NULL; bzero(&init_addr, sizeof(init_addr)); + + MPASS(*udp_mapping == NULL); + + /* + * If we are UDP and have an existing mapping we can get source port + * from the mapping. In this case we have to look up the src_node as + * pf_map_addr would. + */ + if (proto == IPPROTO_UDP && (r->rpool.opts & PF_POOL_ENDPI)) { + struct pf_udp_endpoint_cmp udp_source; + + bzero(&udp_source, sizeof(udp_source)); + udp_source.af = af; + PF_ACPY(&udp_source.addr, saddr, af); + udp_source.port = sport; + *udp_mapping = pf_udp_mapping_find(&udp_source); + if (*udp_mapping) { + PF_ACPY(naddr, &(*udp_mapping)->endpoints[1].addr, af); + *nport = (*udp_mapping)->endpoints[1].port; + /* Try to find a src_node as per pf_map_addr(). */ + if (*sn == NULL && r->rpool.opts & PF_POOL_STICKYADDR && + (r->rpool.opts & PF_POOL_TYPEMASK) != PF_POOL_NONE) + *sn = pf_find_src_node(saddr, r, af, &sh, 0); + return (0); + } else { + *udp_mapping = pf_udp_mapping_create(af, saddr, sport, &init_addr, 0); + if (*udp_mapping == NULL) + return (1); + } + } + if (pf_map_addr(af, r, saddr, naddr, NULL, &init_addr, sn)) - return (1); + goto failed; if (proto == IPPROTO_ICMP) { if (*nport == htons(ICMP_ECHO)) { @@ -250,6 +284,8 @@ pf_get_sport(sa_family_t af, u_int8_t proto, struct pf_krule *r, do { PF_ACPY(&key.addr[1], naddr, key.af); + if (*udp_mapping) + PF_ACPY(&(*udp_mapping)->endpoints[1].addr, naddr, af); /* * port search; start random, step; @@ -277,8 +313,16 @@ pf_get_sport(sa_family_t af, u_int8_t proto, struct pf_krule *r, } else if (low == high) { key.port[1] = htons(low); if (!pf_find_state_all_exists(&key, PF_IN)) { - *nport = htons(low); - return (0); + if (*udp_mapping != NULL) { + (*udp_mapping)->endpoints[1].port = htons(low); + if (pf_udp_mapping_insert(*udp_mapping) == 0) { + *nport = htons(low); + return (0); + } + } else { + *nport = htons(low); + return (0); + } } } else { uint32_t tmp; @@ -293,18 +337,35 @@ pf_get_sport(sa_family_t af, u_int8_t proto, struct pf_krule *r, cut = arc4random() % (1 + high - low) + low; /* low <= cut <= high */ for (tmp = cut; tmp <= high && tmp <= 0xffff; ++tmp) { - key.port[1] = htons(tmp); - if (!pf_find_state_all_exists(&key, PF_IN)) { - *nport = htons(tmp); - return (0); + if (*udp_mapping != NULL) { + (*udp_mapping)->endpoints[1].port = htons(tmp); + if (pf_udp_mapping_insert(*udp_mapping) == 0) { + *nport = htons(tmp); + return (0); + } + } else { + key.port[1] = htons(tmp); + if (!pf_find_state_all_exists(&key, PF_IN)) { + *nport = htons(tmp); + return (0); + } } } tmp = cut; for (tmp -= 1; tmp >= low && tmp <= 0xffff; --tmp) { - key.port[1] = htons(tmp); - if (!pf_find_state_all_exists(&key, PF_IN)) { - *nport = htons(tmp); - return (0); + if (proto == IPPROTO_UDP && + (r->rpool.opts & PF_POOL_ENDPI)) { + (*udp_mapping)->endpoints[1].port = htons(tmp); + if (pf_udp_mapping_insert(*udp_mapping) == 0) { + *nport = htons(tmp); + return (0); + } + } else { + key.port[1] = htons(tmp); + if (!pf_find_state_all_exists(&key, PF_IN)) { + *nport = htons(tmp); + return (0); + } } } } @@ -326,6 +387,10 @@ pf_get_sport(sa_family_t af, u_int8_t proto, struct pf_krule *r, return (1); } } while (! PF_AEQ(&init_addr, naddr, af) ); + +failed: + uma_zfree(V_pf_udp_mapping_z, *udp_mapping); + *udp_mapping = NULL; return (1); /* none available */ } @@ -333,7 +398,7 @@ static int pf_get_mape_sport(sa_family_t af, u_int8_t proto, struct pf_krule *r, struct pf_addr *saddr, uint16_t sport, struct pf_addr *daddr, uint16_t dport, struct pf_addr *naddr, uint16_t *nport, - struct pf_ksrc_node **sn) + struct pf_ksrc_node **sn, struct pf_udp_mapping **udp_mapping) { uint16_t psmask, low, highmask; uint16_t i, ahigh, cut; @@ -353,13 +418,13 @@ pf_get_mape_sport(sa_family_t af, u_int8_t proto, struct pf_krule *r, for (i = cut; i <= ahigh; i++) { low = (i << ashift) | psmask; if (!pf_get_sport(af, proto, r, saddr, sport, daddr, dport, - naddr, nport, low, low | highmask, sn)) + naddr, nport, low, low | highmask, sn, udp_mapping)) return (0); } for (i = cut - 1; i > 0; i--) { low = (i << ashift) | psmask; if (!pf_get_sport(af, proto, r, saddr, sport, daddr, dport, - naddr, nport, low, low | highmask, sn)) + naddr, nport, low, low | highmask, sn, udp_mapping)) return (0); } return (1); @@ -597,7 +662,8 @@ pf_get_translation(struct pf_pdesc *pd, struct mbuf *m, int off, struct pf_state_key **skp, struct pf_state_key **nkp, struct pf_addr *saddr, struct pf_addr *daddr, uint16_t sport, uint16_t dport, struct pf_kanchor_stackframe *anchor_stack, - struct pf_krule **rp) + struct pf_krule **rp, + struct pf_udp_mapping **udp_mapping) { struct pf_krule *r = NULL; struct pf_addr *naddr; @@ -661,7 +727,7 @@ pf_get_translation(struct pf_pdesc *pd, struct mbuf *m, int off, } if (r->rpool.mape.offset > 0) { if (pf_get_mape_sport(pd->af, pd->proto, r, saddr, - sport, daddr, dport, naddr, nportp, sn)) { + sport, daddr, dport, naddr, nportp, sn, udp_mapping)) { DPFPRINTF(PF_DEBUG_MISC, ("pf: MAP-E port allocation (%u/%u/%u)" " failed\n", @@ -672,7 +738,7 @@ pf_get_translation(struct pf_pdesc *pd, struct mbuf *m, int off, goto notrans; } } else if (pf_get_sport(pd->af, pd->proto, r, saddr, sport, - daddr, dport, naddr, nportp, low, high, sn)) { + daddr, dport, naddr, nportp, low, high, sn, udp_mapping)) { DPFPRINTF(PF_DEBUG_MISC, ("pf: NAT proxy port allocation (%u-%u) failed\n", r->rpool.proxy_port[0], r->rpool.proxy_port[1])); diff --git a/tests/sys/netpfil/pf/nat.sh b/tests/sys/netpfil/pf/nat.sh index 513abfa5e040..aaa49805c772 100644 --- a/tests/sys/netpfil/pf/nat.sh +++ b/tests/sys/netpfil/pf/nat.sh @@ -112,6 +112,139 @@ nested_anchor_body() } +atf_test_case "endpoint_independent" "cleanup" +endpoint_independent_head() +{ + atf_set descr 'Test that a client behind NAT gets the same external IP:port for different servers' + atf_set require.user root +} + +endpoint_independent_body() +{ + pft_init + filter="udp and dst port 1234" # only capture udp pings + + epair_client=$(vnet_mkepair) + epair_nat=$(vnet_mkepair) + epair_server1=$(vnet_mkepair) + epair_server2=$(vnet_mkepair) + bridge=$(vnet_mkbridge) + + vnet_mkjail nat ${epair_client}b ${epair_nat}a + vnet_mkjail client ${epair_client}a + vnet_mkjail server1 ${epair_server1}a + vnet_mkjail server2 ${epair_server2}a + + ifconfig ${epair_server1}b up + ifconfig ${epair_server2}b up + ifconfig ${epair_nat}b up + ifconfig ${bridge} \ + addm ${epair_server1}b \ + addm ${epair_server2}b \ + addm ${epair_nat}b \ + up + + jexec nat ifconfig ${epair_client}b 192.0.2.1/24 up + jexec nat ifconfig ${epair_nat}a 198.51.100.42/24 up + jexec nat sysctl net.inet.ip.forwarding=1 + + jexec client ifconfig ${epair_client}a 192.0.2.2/24 up + jexec client route add default 192.0.2.1 + + jexec server1 ifconfig ${epair_server1}a 198.51.100.32/24 up + jexec server2 ifconfig ${epair_server2}a 198.51.100.22/24 up + + # Enable pf! + jexec nat pfctl -e + + # validate non-endpoint independent nat rule behaviour + pft_set_rules nat \ + "nat on ${epair_nat}a inet from ! (${epair_nat}a) to any -> (${epair_nat}a)" + + jexec server1 tcpdump -i ${epair_server1}a -w ${PWD}/server1.pcap \ + --immediate-mode $filter & + server1tcppid="$!" + jexec server2 tcpdump -i ${epair_server2}a -w ${PWD}/server2.pcap \ + --immediate-mode $filter & + server2tcppid="$!" + + # send out multiple packets + for i in $(seq 1 10); do + echo "ping" | jexec client nc -u 198.51.100.32 1234 -p 4242 -w 0 + echo "ping" | jexec client nc -u 198.51.100.22 1234 -p 4242 -w 0 + done + + kill $server1tcppid + kill $server2tcppid + + tuple_server1=$(tcpdump -r ${PWD}/server1.pcap | awk '{addr=$3} END {print addr}') + tuple_server2=$(tcpdump -r ${PWD}/server2.pcap | awk '{addr=$3} END {print addr}') + + if [ -z $tuple_server1 ] + then + atf_fail "server1 did not receive connection from client (default)" + fi + + if [ -z $tuple_server2 ] + then + atf_fail "server2 did not receive connection from client (default)" + fi + + if [ "$tuple_server1" = "$tuple_server2" ] + then + echo "server1 tcpdump: $tuple_server1" + echo "server2 tcpdump: $tuple_server2" + atf_fail "Received same IP:port on server1 and server2 (default)" + fi + + # validate endpoint independent nat rule behaviour + pft_set_rules nat \ + "nat on ${epair_nat}a inet from ! (${epair_nat}a) to any -> (${epair_nat}a) endpoint-independent" + + jexec server1 tcpdump -i ${epair_server1}a -w ${PWD}/server1.pcap \ + --immediate-mode $filter & + server1tcppid="$!" + jexec server2 tcpdump -i ${epair_server2}a -w ${PWD}/server2.pcap \ + --immediate-mode $filter & + server2tcppid="$!" + + # send out multiple packets, sometimes one fails to go through + for i in $(seq 1 10); do + echo "ping" | jexec client nc -u 198.51.100.32 1234 -p 4242 -w 0 + echo "ping" | jexec client nc -u 198.51.100.22 1234 -p 4242 -w 0 + done + + kill $server1tcppid + kill $server2tcppid + + tuple_server1=$(tcpdump -r ${PWD}/server1.pcap | awk '{addr=$3} END {print addr}') + tuple_server2=$(tcpdump -r ${PWD}/server2.pcap | awk '{addr=$3} END {print addr}') + + if [ -z $tuple_server1 ] + then + atf_fail "server1 did not receive connection from client (endpoint-independent)" + fi + + if [ -z $tuple_server2 ] + then + atf_fail "server2 did not receive connection from client (endpoint-independent)" + fi + + if [ ! "$tuple_server1" = "$tuple_server2" ] + then + echo "server1 tcpdump: $tuple_server1" + echo "server2 tcpdump: $tuple_server2" + atf_fail "Received different IP:port on server1 than server2 (endpoint-independent)" + fi +} + +endpoint_independent_cleanup() +{ + pft_cleanup + rm -f server1.out + rm -f server2.out +} + nested_anchor_cleanup() { pft_cleanup @@ -121,4 +254,5 @@ atf_init_test_cases() { atf_add_test_case "exhaust" atf_add_test_case "nested_anchor" + atf_add_test_case "endpoint_independent" } From e1b1984abb8b673d43082660a5ae740741f85df6 Mon Sep 17 00:00:00 2001 From: Tom Jones Date: Fri, 6 Sep 2024 14:06:57 +0100 Subject: [PATCH 175/213] pfctl: Add endpoint-independent test to the list of tests Reviewed by: kp Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D46563 --- sbin/pfctl/tests/pfctl_test_list.inc | 1 + 1 file changed, 1 insertion(+) diff --git a/sbin/pfctl/tests/pfctl_test_list.inc b/sbin/pfctl/tests/pfctl_test_list.inc index 5d1717200759..1fd31de6ccc4 100644 --- a/sbin/pfctl/tests/pfctl_test_list.inc +++ b/sbin/pfctl/tests/pfctl_test_list.inc @@ -129,3 +129,4 @@ PFCTL_TEST(1017, "Ethernet rule with ridentifier and several labels") PFCTL_TEST(1018, "Test dynamic address mask") PFCTL_TEST(1019, "Test pflow option") PFCTL_TEST(1020, "Test hashmark and semicolon comment") +PFCTL_TEST(1021, "Endpoint-independent") From bb2d016afb009920f4bb2400c15a86e557b2d55a Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Fri, 6 Sep 2024 17:13:08 +0200 Subject: [PATCH 176/213] flua: make the ucl module a dynamic module Reviewed by: markj Differential Revision: https://reviews.freebsd.org/D46569 --- lib/flua/Makefile | 1 + lib/flua/libucl/Makefile | 17 +++++++++++++++++ libexec/flua/Makefile | 8 +------- libexec/flua/linit_flua.c | 2 -- 4 files changed, 19 insertions(+), 9 deletions(-) create mode 100644 lib/flua/libucl/Makefile diff --git a/lib/flua/Makefile b/lib/flua/Makefile index 769736039f7e..168d05f54674 100644 --- a/lib/flua/Makefile +++ b/lib/flua/Makefile @@ -1,4 +1,5 @@ SUBDIR+= libhash SUBDIR+= libjail +SUBDIR+= libucl .include diff --git a/lib/flua/libucl/Makefile b/lib/flua/libucl/Makefile new file mode 100644 index 000000000000..7d2681b85fcb --- /dev/null +++ b/lib/flua/libucl/Makefile @@ -0,0 +1,17 @@ +SHLIB_NAME= ucl.so +SHLIBDIR= ${LIBDIR}/flua + +WARNS= 2 + +UCLSRC?= ${SRCTOP}/contrib/libucl +.PATH: ${UCLSRC}/lua +SRCS+= lua_ucl.c +CFLAGS+= \ + -I${SRCTOP}/contrib/lua/src \ + -I${SRCTOP}/lib/liblua \ + -I${UCLSRC}/include \ + -I${UCLSRC}/src \ + -I${UCLSRC}/uthash +LIBADD+= ucl + +.include diff --git a/libexec/flua/Makefile b/libexec/flua/Makefile index e324ca993711..c8206b94769d 100644 --- a/libexec/flua/Makefile +++ b/libexec/flua/Makefile @@ -4,7 +4,7 @@ LUASRC?= ${SRCTOP}/contrib/lua/src .PATH: ${LUASRC} PROG= flua -WARNS?= 2 +WARNS?= 3 MAN= # No manpage; this is internal. CWARNFLAGS.gcc+= -Wno-format-nonliteral @@ -31,10 +31,4 @@ LIBADD+= edit LDFLAGS+= -Wl,-E .endif -UCLSRC?= ${SRCTOP}/contrib/libucl -.PATH: ${UCLSRC}/lua -SRCS+= lua_ucl.c -CFLAGS+= -I${UCLSRC}/include -I${UCLSRC}/src -I${UCLSRC}/uthash -LIBADD+= ucl - .include diff --git a/libexec/flua/linit_flua.c b/libexec/flua/linit_flua.c index 1b7d83016cfe..4635970d1fd7 100644 --- a/libexec/flua/linit_flua.c +++ b/libexec/flua/linit_flua.c @@ -36,7 +36,6 @@ #include "lfs.h" #include "lposix.h" #include "lfbsd.h" -#include "lua_ucl.h" /* ** these libs are loaded by lua.c and are readily available to any Lua @@ -61,7 +60,6 @@ static const luaL_Reg loadedlibs[] = { {"posix.sys.stat", luaopen_posix_sys_stat}, {"posix.sys.utsname", luaopen_posix_sys_utsname}, {"posix.unistd", luaopen_posix_unistd}, - {"ucl", luaopen_ucl}, {"fbsd", luaopen_fbsd}, {NULL, NULL} }; From de1d7d7b87cfa31a1d6c7bcf1acd27de8139cab3 Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Fri, 6 Sep 2024 11:00:50 +0200 Subject: [PATCH 177/213] flua: add freebsd module implementing kldload/kldunload Reviewed by: markj, imp Approved by: imp Differential Revision: https://reviews.freebsd.org/D46558 --- etc/mtree/BSD.usr.dist | 4 + lib/flua/libfreebsd/Makefile | 3 + lib/flua/libfreebsd/sys/Makefile | 4 + lib/flua/libfreebsd/sys/linker/Makefile | 12 ++ .../sys/linker/freebsd.sys.linker.3lua | 67 +++++++++++ .../sys/linker/lua_freebsd_sys_linker.c | 104 ++++++++++++++++++ 6 files changed, 194 insertions(+) create mode 100644 lib/flua/libfreebsd/Makefile create mode 100644 lib/flua/libfreebsd/sys/Makefile create mode 100644 lib/flua/libfreebsd/sys/linker/Makefile create mode 100644 lib/flua/libfreebsd/sys/linker/freebsd.sys.linker.3lua create mode 100644 lib/flua/libfreebsd/sys/linker/lua_freebsd_sys_linker.c diff --git a/etc/mtree/BSD.usr.dist b/etc/mtree/BSD.usr.dist index 13541aac1dd4..60d458f5d336 100644 --- a/etc/mtree/BSD.usr.dist +++ b/etc/mtree/BSD.usr.dist @@ -74,6 +74,10 @@ engines-3 .. flua + freebsd + sys + .. + .. .. i18n .. diff --git a/lib/flua/libfreebsd/Makefile b/lib/flua/libfreebsd/Makefile new file mode 100644 index 000000000000..6ed0451055ff --- /dev/null +++ b/lib/flua/libfreebsd/Makefile @@ -0,0 +1,3 @@ +SUBDIR+= sys + +.include diff --git a/lib/flua/libfreebsd/sys/Makefile b/lib/flua/libfreebsd/sys/Makefile new file mode 100644 index 000000000000..9f38294536f2 --- /dev/null +++ b/lib/flua/libfreebsd/sys/Makefile @@ -0,0 +1,4 @@ +SUBDIR+= linker + +.include + diff --git a/lib/flua/libfreebsd/sys/linker/Makefile b/lib/flua/libfreebsd/sys/linker/Makefile new file mode 100644 index 000000000000..318cc5078b33 --- /dev/null +++ b/lib/flua/libfreebsd/sys/linker/Makefile @@ -0,0 +1,12 @@ +SHLIB_NAME= linker.so +SHLIBDIR= ${LIBDIR}/flua/freebsd/sys + +SRCS+= lua_freebsd_sys_linker.c + +CFLAGS+= \ + -I${SRCTOP}/contrib/lua/src \ + -I${SRCTOP}/lib/liblua \ + +MAN= freebsd.sys.linker.3lua + +.include diff --git a/lib/flua/libfreebsd/sys/linker/freebsd.sys.linker.3lua b/lib/flua/libfreebsd/sys/linker/freebsd.sys.linker.3lua new file mode 100644 index 000000000000..0ab8f185388a --- /dev/null +++ b/lib/flua/libfreebsd/sys/linker/freebsd.sys.linker.3lua @@ -0,0 +1,67 @@ +.\" +.\" SPDX-License-Identifier: BSD-2-Clause +.\" +.\" Copyright (c) 2024, Baptiste Daroussin +.\" +.\" 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. +.\" +.Dd September 6, 2024 +.Dt FREEBSD.SYS.LINKER 3lua +.Os +.Sh NAME +.Nm freebsd.sys.linker +.Nd Lua binding to +.Fx 's +Linker functions +.Sh SYNOPSIS +.Bd -literal +local linker = require('freebsd.sys.linker') +.Ed +.Pp +.Bl -tag -width XXXX -compact +.It Dv fileid, err, errno = linker.kldload(name) +.It Dv ok, err, errno = linker.kldunload(fileid|name) +.El +.Sh DESCRIPTION +The +.Nm +module is a binding to the +.Fx 's +linker functions. +List of functions: +.Bl -tag -width XXXX +.It Dv fileid, err = freebsd.sys.linker.kldload(name) +Load the kernel module named +.Fa name +and return the identifier +.Pq fileid +as an interger. +.It Dv ok, err, errno = freebsd.sys.linker.kldunload(fileid|name) +Unload the kernel module identifier either by +.Fa name +as a string, or +.Fa fileid +as an integer. +.El +.Sh SEE ALSO +.Xr kldload 2 , +.Xr kldunload 2 diff --git a/lib/flua/libfreebsd/sys/linker/lua_freebsd_sys_linker.c b/lib/flua/libfreebsd/sys/linker/lua_freebsd_sys_linker.c new file mode 100644 index 000000000000..a2dc3b487525 --- /dev/null +++ b/lib/flua/libfreebsd/sys/linker/lua_freebsd_sys_linker.c @@ -0,0 +1,104 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2024, Baptiste Daroussin + * + * 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 REGENTS 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 REGENTS 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 +#include + +#include +#include +#include + +#include +#include +#include + +int luaopen_freebsd_sys_linker(lua_State *L); + +static int +lua_kldload(lua_State *L) +{ + const char *name; + int ret; + + name = luaL_checkstring(L, 1); + ret = kldload(name); + if (ret == -1) { + lua_pushnil(L); + lua_pushstring(L, strerror(errno)); + lua_pushinteger(L, errno); + return (3); + } + lua_pushinteger(L, ret); + return (1); +} + +static int +lua_kldunload(lua_State *L) +{ + const char *name; + int ret, fileid; + + if (lua_isinteger(L, 1)) { + fileid = lua_tointeger(L, 1); + } else { + name = luaL_checkstring(L, 1); + fileid = kldfind(name); + } + if (fileid == -1) { + lua_pushnil(L); + lua_pushstring(L, strerror(errno)); + lua_pushinteger(L, errno); + return (3); + } + ret = kldunload(fileid); + lua_pushinteger(L, ret); + if (ret == -1) { + lua_pushnil(L); + lua_pushstring(L, strerror(errno)); + lua_pushinteger(L, errno); + return (3); + } + lua_pushinteger(L, 0); + return (1); +} + +#define REG_SIMPLE(n) { #n, lua_ ## n } +static const struct luaL_Reg freebsd_sys_linker[] = { + REG_SIMPLE(kldload), + REG_SIMPLE(kldunload), + { NULL, NULL }, +}; +#undef REG_SIMPLE + +int +luaopen_freebsd_sys_linker(lua_State *L) +{ + luaL_newlib(L, freebsd_sys_linker); + + return (1); +} From 705583b76f3fba9e8c3cf77142e8ac84de721ac1 Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Fri, 6 Sep 2024 17:35:28 +0200 Subject: [PATCH 178/213] freebsd.sys.linker: rename source file Suggested by: markj --- lib/flua/libfreebsd/sys/linker/Makefile | 2 +- .../sys/linker/{lua_freebsd_sys_linker.c => linker.c} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename lib/flua/libfreebsd/sys/linker/{lua_freebsd_sys_linker.c => linker.c} (100%) diff --git a/lib/flua/libfreebsd/sys/linker/Makefile b/lib/flua/libfreebsd/sys/linker/Makefile index 318cc5078b33..572b5949d2a1 100644 --- a/lib/flua/libfreebsd/sys/linker/Makefile +++ b/lib/flua/libfreebsd/sys/linker/Makefile @@ -1,7 +1,7 @@ SHLIB_NAME= linker.so SHLIBDIR= ${LIBDIR}/flua/freebsd/sys -SRCS+= lua_freebsd_sys_linker.c +SRCS+= linker.c CFLAGS+= \ -I${SRCTOP}/contrib/lua/src \ diff --git a/lib/flua/libfreebsd/sys/linker/lua_freebsd_sys_linker.c b/lib/flua/libfreebsd/sys/linker/linker.c similarity index 100% rename from lib/flua/libfreebsd/sys/linker/lua_freebsd_sys_linker.c rename to lib/flua/libfreebsd/sys/linker/linker.c From df1323e023a40dea43e65b2460ff35126b5c62e8 Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Fri, 6 Sep 2024 17:49:16 +0200 Subject: [PATCH 179/213] lua_ucl: make sure flua gets build after libucl --- lib/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Makefile b/lib/Makefile index ee5419ae0f93..8860bfeb1770 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -152,7 +152,7 @@ SUBDIR_DEPEND_nss_tacplus= libtacplus .if !defined(COMPAT_LIBCOMPAT) SUBDIR+= flua -SUBDIR_DEPEND_flua= libjail +SUBDIR_DEPEND_flua= libjail libucl .endif # NB: keep these sorted by MK_* knobs From 39667ed7adc055879fffb5107ab3ecf1b26ac1bc Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Fri, 6 Sep 2024 17:52:08 +0200 Subject: [PATCH 180/213] flua: hook libfreebsd to the build --- lib/flua/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/flua/Makefile b/lib/flua/Makefile index 168d05f54674..d88e76f61062 100644 --- a/lib/flua/Makefile +++ b/lib/flua/Makefile @@ -1,3 +1,4 @@ +SUBDIR+= libfreebsd SUBDIR+= libhash SUBDIR+= libjail SUBDIR+= libucl From 58f194223ab8578269772a6874a8444e5e03afaf Mon Sep 17 00:00:00 2001 From: Mark Johnston Date: Fri, 6 Sep 2024 16:55:42 +0000 Subject: [PATCH 181/213] ifnet: Add handling for toggling IFF_ALLMULTI in ifhwioctl() IFF_ALLMULTI has an associated activation counter and so needs special treatment, like IFF_PROMISC. Introduce IFF_PALLMULTI, akin to IFF_PPROMISC, which indicates that userspace requested allmulti mode, and handle it specially in ifhwioctl(). Reviewed by: zlei, glebius MFC after: 2 weeks Sponsored by: Klara, Inc. Differential Revision: https://reviews.freebsd.org/D46524 --- sys/net/if.c | 16 ++++++++++++++-- sys/net/if.h | 2 +- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/sys/net/if.c b/sys/net/if.c index 4458d710d826..ebad5c5d16e5 100644 --- a/sys/net/if.c +++ b/sys/net/if.c @@ -2611,7 +2611,12 @@ ifhwioctl(u_long cmd, struct ifnet *ifp, caddr_t data, struct thread *td) (ifp->if_flags & IFF_UP) == 0) { do_ifup = 1; } - /* See if permanently promiscuous mode bit is about to flip */ + + /* + * See if the promiscuous mode or allmulti bits are about to + * 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; @@ -2622,6 +2627,12 @@ ifhwioctl(u_long cmd, struct ifnet *ifp, caddr_t data, struct thread *td) ((new_flags & IFF_PPROMISC) ? "enabled" : "disabled")); } + if ((ifp->if_flags ^ new_flags) & IFF_PALLMULTI) { + if (new_flags & IFF_PALLMULTI) + ifp->if_flags |= IFF_ALLMULTI; + else if (ifp->if_amcount == 0) + ifp->if_flags &= ~IFF_ALLMULTI; + } ifp->if_flags = (ifp->if_flags & IFF_CANTCHANGE) | (new_flags &~ IFF_CANTCHANGE); if (ifp->if_ioctl) { @@ -3383,7 +3394,8 @@ int if_allmulti(struct ifnet *ifp, int onswitch) { - return (if_setflag(ifp, IFF_ALLMULTI, 0, &ifp->if_amcount, onswitch)); + return (if_setflag(ifp, IFF_ALLMULTI, IFF_PALLMULTI, &ifp->if_amcount, + onswitch)); } struct ifmultiaddr * diff --git a/sys/net/if.h b/sys/net/if.h index 5c4b0637b25a..d54190f6ccf8 100644 --- a/sys/net/if.h +++ b/sys/net/if.h @@ -160,7 +160,7 @@ struct if_data { #define IFF_STICKYARP 0x100000 /* (n) sticky ARP */ #define IFF_DYING 0x200000 /* (n) interface is winding down */ #define IFF_RENAMING 0x400000 /* (n) interface is being renamed */ -#define IFF_SPARE 0x800000 +#define IFF_PALLMULTI 0x800000 /* (n) user-requested allmulti mode */ #define IFF_NETLINK_1 0x1000000 /* (n) used by netlink */ /* From 00c9a6806c9cf3357b62f6708e5acd1ffd166613 Mon Sep 17 00:00:00 2001 From: Mark Johnston Date: Fri, 6 Sep 2024 16:56:58 +0000 Subject: [PATCH 182/213] ifconfig: Add an allmulti verb Similar to "promisc", this allows the IFF_ALLMULTI flag to be toggled from userspace if it happens to be useful to disable multicast packet filtering. One use-case is when implementing IPv6 neighbour discovery over netmap. Reviewed by: zlei, glebius MFC after: 2 weeks Sponsored by: Klara, Inc. Differential Revision: https://reviews.freebsd.org/D46525 --- sbin/ifconfig/ifconfig.8 | 4 ++++ sbin/ifconfig/ifconfig.c | 2 ++ sbin/ifconfig/ifconfig_netlink.c | 2 +- 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/sbin/ifconfig/ifconfig.8 b/sbin/ifconfig/ifconfig.8 index c9861ccc6481..dfea59dfd229 100644 --- a/sbin/ifconfig/ifconfig.8 +++ b/sbin/ifconfig/ifconfig.8 @@ -502,6 +502,10 @@ Enable driver dependent debugging code; usually, this turns on extra console error logging. .It Fl debug Disable driver dependent debugging code. +.It Cm allmulti +Enable promiscuous mode for multicast packets. +.It Fl allmulti +Disable promiscuous mode for multicast packets. .It Cm promisc Put interface into permanently promiscuous mode. .It Fl promisc diff --git a/sbin/ifconfig/ifconfig.c b/sbin/ifconfig/ifconfig.c index e6ed9015b34b..a0680d09e54c 100644 --- a/sbin/ifconfig/ifconfig.c +++ b/sbin/ifconfig/ifconfig.c @@ -2078,6 +2078,8 @@ static struct cmd basic_cmds[] = { DEF_CMD_ARG("descr", setifdescr), DEF_CMD("-description", 0, unsetifdescr), DEF_CMD("-descr", 0, unsetifdescr), + DEF_CMD("allmulti", IFF_PALLMULTI, setifflags), + DEF_CMD("-allmulti", IFF_PALLMULTI, clearifflags), DEF_CMD("promisc", IFF_PPROMISC, setifflags), DEF_CMD("-promisc", IFF_PPROMISC, clearifflags), DEF_CMD("add", IFF_UP, notealias), diff --git a/sbin/ifconfig/ifconfig_netlink.c b/sbin/ifconfig/ifconfig_netlink.c index 729d4ca56545..5a986e840d7f 100644 --- a/sbin/ifconfig/ifconfig_netlink.c +++ b/sbin/ifconfig/ifconfig_netlink.c @@ -77,7 +77,7 @@ static const char *IFFBITS[] = { "STICKYARP", /* 20:0x100000 IFF_STICKYARP*/ "DYING", /* 21:0x200000 IFF_DYING*/ "RENAMING", /* 22:0x400000 IFF_RENAMING*/ - "NOGROUP", /* 23:0x800000 IFF_NOGROUP*/ + "PALLMULTI", /* 23:0x800000 IFF_PALLMULTI*/ "LOWER_UP", /* 24:0x1000000 IFF_NETLINK_1*/ }; From f5a58c2da23930ee4870f2eb54788f4669b9aa33 Mon Sep 17 00:00:00 2001 From: Mikhail Pchelin Date: Fri, 6 Sep 2024 21:04:52 +0300 Subject: [PATCH 183/213] linux80211: fix default deflink.rx_nss Native Linux implementation sets this as a maximum between 1 and ht/vht/eht rx SS'es, FreeBSD does the same, but uses 0 as a minimum, which leads setting it to 0 if we're not in ht/vht case. This 0 was breaking rtw89 driver, when it was trying to determine SS number by subtracting 1 from rx_nss and passing the value to the hardware. After this patch rtw89 association and simple ping work reliably, but more work is needed to make the driver robust with heavy traffic (iperf3) and being long idle. Reviewed by: bz Approved by: bz Sponsored by: Future Crew LLC Differential Revision: https://reviews.freebsd.org/D46528 --- sys/compat/linuxkpi/common/src/linux_80211.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/compat/linuxkpi/common/src/linux_80211.c b/sys/compat/linuxkpi/common/src/linux_80211.c index a2791d20a727..ae765cda5781 100644 --- a/sys/compat/linuxkpi/common/src/linux_80211.c +++ b/sys/compat/linuxkpi/common/src/linux_80211.c @@ -347,7 +347,7 @@ lkpi_lsta_alloc(struct ieee80211vap *vap, const uint8_t mac[IEEE80211_ADDR_LEN], sta->deflink.smps_mode = IEEE80211_SMPS_OFF; sta->deflink.bandwidth = IEEE80211_STA_RX_BW_20; - sta->deflink.rx_nss = 0; + sta->deflink.rx_nss = 1; ht_rx_nss = 0; #if defined(LKPI_80211_HT) From 07d90ee0a62110e5161bb0b8a3a0b1b9d2beabad Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Fri, 14 Jun 2024 09:30:28 +0200 Subject: [PATCH 184/213] kvprintf(): Fix '+' conversion handling For example, printf("%+i", 1) prints "+1". However, kvprintf() did print just "1" for this example. According to PRINTF(3): A sign must always be placed before a number produced by a signed conversion. For "%+r" radix conversions, keep the "+" handling as it is, since this is a non-standard conversion. For "%+p" pointer conversions, continue to ignore the sign modifier to be in line with libc. This change allows to support the ' conversion modifier in the future. Reviewed by: imp Pull Request: https://github.com/freebsd/freebsd-src/pull/1310 --- sys/kern/subr_prf.c | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/sys/kern/subr_prf.c b/sys/kern/subr_prf.c index 4dc989e2d1f1..8ecabdec18d5 100644 --- a/sys/kern/subr_prf.c +++ b/sys/kern/subr_prf.c @@ -660,9 +660,9 @@ kvprintf(char const *fmt, void (*func)(int, void*), void *arg, int radix, va_lis char *d; const char *p, *percent, *q; u_char *up; - int ch, n; + int ch, n, sign; uintmax_t num; - int base, lflag, qflag, tmp, width, ladjust, sharpflag, neg, sign, dot; + int base, lflag, qflag, tmp, width, ladjust, sharpflag, dot; int cflag, hflag, jflag, tflag, zflag; int bconv, dwidth, upper; char padc; @@ -690,7 +690,7 @@ kvprintf(char const *fmt, void (*func)(int, void*), void *arg, int radix, va_lis PCHAR(ch); } percent = fmt - 1; - qflag = 0; lflag = 0; ladjust = 0; sharpflag = 0; neg = 0; + qflag = 0; lflag = 0; ladjust = 0; sharpflag = 0; sign = 0; dot = 0; bconv = 0; dwidth = 0; upper = 0; cflag = 0; hflag = 0; jflag = 0; tflag = 0; zflag = 0; reswitch: switch (ch = (u_char)*fmt++) { @@ -701,7 +701,7 @@ reswitch: switch (ch = (u_char)*fmt++) { sharpflag = 1; goto reswitch; case '+': - sign = 1; + sign = '+'; goto reswitch; case '-': ladjust = 1; @@ -771,7 +771,6 @@ reswitch: switch (ch = (u_char)*fmt++) { case 'd': case 'i': base = 10; - sign = 1; goto handle_sign; case 'h': if (hflag) { @@ -824,8 +823,10 @@ reswitch: switch (ch = (u_char)*fmt++) { goto reswitch; case 'r': base = radix; - if (sign) + if (sign) { + sign = 0; goto handle_sign; + } goto handle_nosign; case 's': p = va_arg(ap, char *); @@ -862,13 +863,11 @@ reswitch: switch (ch = (u_char)*fmt++) { goto handle_nosign; case 'y': base = 16; - sign = 1; goto handle_sign; case 'z': zflag = 1; goto reswitch; handle_nosign: - sign = 0; if (jflag) num = va_arg(ap, uintmax_t); else if (qflag) @@ -907,11 +906,11 @@ reswitch: switch (ch = (u_char)*fmt++) { num = (signed char)va_arg(ap, int); else num = va_arg(ap, int); -number: - if (sign && (intmax_t)num < 0) { - neg = 1; + if ((intmax_t)num < 0) { + sign = '-'; num = -(intmax_t)num; } +number: p = ksprintn(nbuf, num, base, &n, upper); tmp = 0; if (sharpflag && num != 0) { @@ -920,7 +919,7 @@ reswitch: switch (ch = (u_char)*fmt++) { else if (base == 16) tmp += 2; } - if (neg) + if (sign) tmp++; if (!ladjust && padc == '0') @@ -930,8 +929,8 @@ reswitch: switch (ch = (u_char)*fmt++) { if (!ladjust) while (width-- > 0) PCHAR(' '); - if (neg) - PCHAR('-'); + if (sign) + PCHAR(sign); if (sharpflag && num != 0) { if (base == 8) { PCHAR('0'); From e152944f1a16a4ff33b4e20b813ce4a54b884b90 Mon Sep 17 00:00:00 2001 From: Ahmad Khalifa Date: Tue, 16 Jul 2024 20:38:12 +0300 Subject: [PATCH 185/213] usb: increase USB_PORT_RESET_RECOVERY 10ms seems to be too strict for some configurations, so increase to 20ms. Reviewed by: imp Pull Request: https://github.com/freebsd/freebsd-src/pull/1327 --- sys/dev/usb/usb.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/dev/usb/usb.h b/sys/dev/usb/usb.h index 3d00cda27d18..a6c3c8030c73 100644 --- a/sys/dev/usb/usb.h +++ b/sys/dev/usb/usb.h @@ -114,7 +114,7 @@ MALLOC_DECLARE(M_USBDEV); /* Allow for marginal and non-conforming devices. */ #define USB_PORT_RESET_DELAY 50 /* ms */ #define USB_PORT_ROOT_RESET_DELAY 200 /* ms */ -#define USB_PORT_RESET_RECOVERY 10 /* ms */ +#define USB_PORT_RESET_RECOVERY 20 /* ms */ #define USB_PORT_POWERUP_DELAY 300 /* ms */ #define USB_PORT_RESUME_DELAY (20*2) /* ms */ #define USB_SET_ADDRESS_SETTLE 10 /* ms */ From 71978fa41f2be0ecce7cb10d30242d29d4ccd844 Mon Sep 17 00:00:00 2001 From: Bram Date: Wed, 24 Jul 2024 22:01:56 +0200 Subject: [PATCH 186/213] du: Add version information to libxo output Add version information to libxo output so that libxo content consumers can track changes. Reviewed by: imp, markj Pull Request: https://github.com/freebsd/freebsd-src/pull/1350 --- usr.bin/du/du.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/usr.bin/du/du.c b/usr.bin/du/du.c index 96ad7c037dfd..185a5cbe4465 100644 --- a/usr.bin/du/du.c +++ b/usr.bin/du/du.c @@ -55,6 +55,8 @@ #define UNITS_2 1 #define UNITS_SI 2 +#define DU_XO_VERSION "1" + static SLIST_HEAD(ignhead, ignentry) ignores; struct ignentry { char *mask; @@ -259,6 +261,8 @@ main(int argc, char *argv[]) if ((fts = fts_open(argv, ftsoptions, NULL)) == NULL) err(1, "fts_open"); + + xo_set_version(DU_XO_VERSION); xo_open_container("disk-usage-information"); xo_open_list("paths"); while (errno = 0, (p = fts_read(fts)) != NULL) { From a0d6f89e692a683fc7f558e9eb8a27d30069e949 Mon Sep 17 00:00:00 2001 From: Bram Date: Fri, 26 Jul 2024 21:34:08 +0200 Subject: [PATCH 187/213] lastlogin: Add version information to libxo output Add version information to libxo output so that libxo content consumers can track changes. Reviewed by: imp, markj Pull Request: https://github.com/freebsd/freebsd-src/pull/1350 --- usr.sbin/lastlogin/lastlogin.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/usr.sbin/lastlogin/lastlogin.c b/usr.sbin/lastlogin/lastlogin.c index a1dcde3f60bf..3a71693f7576 100644 --- a/usr.sbin/lastlogin/lastlogin.c +++ b/usr.sbin/lastlogin/lastlogin.c @@ -48,6 +48,8 @@ __RCSID("$NetBSD: lastlogin.c,v 1.4 1998/02/03 04:45:35 perry Exp $"); #include +#define LASTLOGIN_XO_VERSION "1" + int main(int, char **); static void output(struct utmpx *); static void usage(void); @@ -103,6 +105,7 @@ main(int argc, char *argv[]) argc -= optind; argv += optind; + xo_set_version(LASTLOGIN_XO_VERSION); xo_open_container("lastlogin-information"); xo_open_list("lastlogin"); From 31ac8806885f22d6b3a3948a8f660ba0cf24e9cf Mon Sep 17 00:00:00 2001 From: Bram Date: Fri, 26 Jul 2024 21:35:06 +0200 Subject: [PATCH 188/213] iscsictl: Add version information to libxo output Add version information to libxo output so that libxo content consumers can track changes. Reviewed by: imp, markj Pull Request: https://github.com/freebsd/freebsd-src/pull/1350 --- usr.bin/iscsictl/iscsictl.c | 1 + usr.bin/iscsictl/iscsictl.h | 2 ++ 2 files changed, 3 insertions(+) diff --git a/usr.bin/iscsictl/iscsictl.c b/usr.bin/iscsictl/iscsictl.c index d95cb9a1c096..b75ff889a9a6 100644 --- a/usr.bin/iscsictl/iscsictl.c +++ b/usr.bin/iscsictl/iscsictl.c @@ -746,6 +746,7 @@ main(int argc, char **argv) if (argc < 0) exit(1); + xo_set_version(ISCSICTL_XO_VERSION); xo_open_container("iscsictl"); while ((ch = getopt(argc, argv, "AMRLac:d:e:i:n:p:rt:u:s:vw:")) != -1) { diff --git a/usr.bin/iscsictl/iscsictl.h b/usr.bin/iscsictl/iscsictl.h index 2ac17890bb57..3bc69e4877a9 100644 --- a/usr.bin/iscsictl/iscsictl.h +++ b/usr.bin/iscsictl/iscsictl.h @@ -38,6 +38,8 @@ #define DEFAULT_CONFIG_PATH "/etc/iscsi.conf" #define DEFAULT_IQN "iqn.1994-09.org.freebsd:" +#define ISCSICTL_XO_VERSION "1" + #define MAX_NAME_LEN 223 #define AUTH_METHOD_UNSPECIFIED 0 From 5321a3547912acbeea7eaea8ec3ed85f07537469 Mon Sep 17 00:00:00 2001 From: Bram Date: Fri, 26 Jul 2024 21:35:57 +0200 Subject: [PATCH 189/213] w: Add version information to libxo output Add version information to libxo output so that libxo content consumers can track changes. Reviewed by: imp, markj Pull Request: https://github.com/freebsd/freebsd-src/pull/1350 --- usr.bin/w/w.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/usr.bin/w/w.c b/usr.bin/w/w.c index 8bce6d8427e6..47899d0b38e0 100644 --- a/usr.bin/w/w.c +++ b/usr.bin/w/w.c @@ -108,6 +108,8 @@ static struct entry { #define debugproc(p) *(&((struct kinfo_proc *)p)->ki_udata) +#define W_XO_VERSION "1" + #define W_DISPUSERSIZE 10 #define W_DISPLINESIZE 8 #define W_MAXHOSTSIZE 40 @@ -317,6 +319,7 @@ main(int argc, char *argv[]) if (fromwidth > W_MAXHOSTSIZE) fromwidth = W_MAXHOSTSIZE; + xo_set_version(W_XO_VERSION); xo_open_container("uptime-information"); if (header || wcmd == 0) { From 6e6da538988a5edb5cc7437f8a8647a350800724 Mon Sep 17 00:00:00 2001 From: Bram Date: Fri, 26 Jul 2024 21:36:18 +0200 Subject: [PATCH 190/213] wc: Add version information to libxo output Add version information to libxo output so that libxo content consumers can track changes. Reviewed by: imp, markj Pull Request: https://github.com/freebsd/freebsd-src/pull/1350 --- usr.bin/wc/wc.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/usr.bin/wc/wc.c b/usr.bin/wc/wc.c index 4e8a2d8a8b59..7b83412f3c42 100644 --- a/usr.bin/wc/wc.c +++ b/usr.bin/wc/wc.c @@ -51,6 +51,8 @@ #include #include +#define WC_XO_VERSION "1" + static const char *stdin_filename = "stdin"; static fileargs_t *fa; @@ -132,6 +134,8 @@ main(int argc, char *argv[]) doline = doword = dochar = true; stderr_handle = xo_create_to_file(stderr, XO_STYLE_TEXT, 0); + + xo_set_version(WC_XO_VERSION); xo_open_container("wc"); xo_open_list("file"); From 5c4f64bded0eb9453dc84bcce9a74f64adf57739 Mon Sep 17 00:00:00 2001 From: Bram Date: Tue, 27 Aug 2024 08:17:33 +0200 Subject: [PATCH 191/213] netstat: Add version information to libxo output Add version information to libxo output so that libxo content consumers can track changes. Reviewed by: imp, markj Pull Request: https://github.com/freebsd/freebsd-src/pull/1350 --- usr.bin/netstat/main.c | 7 +++++++ usr.bin/netstat/netstat.h | 2 ++ 2 files changed, 9 insertions(+) diff --git a/usr.bin/netstat/main.c b/usr.bin/netstat/main.c index 2ed6eca4626e..6d19851b61fc 100644 --- a/usr.bin/netstat/main.c +++ b/usr.bin/netstat/main.c @@ -510,6 +510,7 @@ main(int argc, char *argv[]) #endif if (iflag && !sflag) { xo_open_container("statistics"); + xo_set_version(NETSTAT_XO_VERSION); intpr(NULL, af); xo_close_container("statistics"); xo_finish(); @@ -517,6 +518,7 @@ main(int argc, char *argv[]) } if (rflag) { xo_open_container("statistics"); + xo_set_version(NETSTAT_XO_VERSION); if (sflag) { if (live) { kresolve_list(nl); @@ -530,6 +532,7 @@ main(int argc, char *argv[]) } if (oflag) { xo_open_container("statistics"); + xo_set_version(NETSTAT_XO_VERSION); nhops_print(fib, af); xo_close_container("statistics"); xo_finish(); @@ -537,6 +540,7 @@ main(int argc, char *argv[]) } if (Oflag) { xo_open_container("statistics"); + xo_set_version(NETSTAT_XO_VERSION); nhgrp_print(fib, af); xo_close_container("statistics"); xo_finish(); @@ -547,6 +551,7 @@ main(int argc, char *argv[]) if (gflag) { xo_open_container("statistics"); + xo_set_version(NETSTAT_XO_VERSION); if (sflag) { if (af == AF_INET || af == AF_UNSPEC) mrt_stats(); @@ -569,6 +574,7 @@ main(int argc, char *argv[]) if (tp) { xo_open_container("statistics"); + xo_set_version(NETSTAT_XO_VERSION); printproto(tp, tp->pr_name, &first); if (!first) xo_close_list("socket"); @@ -578,6 +584,7 @@ main(int argc, char *argv[]) } xo_open_container("statistics"); + xo_set_version(NETSTAT_XO_VERSION); if (af == AF_INET || af == AF_UNSPEC) for (tp = protox; tp->pr_name; tp++) printproto(tp, tp->pr_name, &first); diff --git a/usr.bin/netstat/netstat.h b/usr.bin/netstat/netstat.h index c41862d9fbdd..7ebfc5180f44 100644 --- a/usr.bin/netstat/netstat.h +++ b/usr.bin/netstat/netstat.h @@ -31,6 +31,8 @@ #include +#define NETSTAT_XO_VERSION "1" + #define satosin(sa) ((struct sockaddr_in *)(sa)) #define satosin6(sa) ((struct sockaddr_in6 *)(sa)) #define sin6tosa(sin6) ((struct sockaddr *)(sin6)) From 1f882a5834836b43d4689efeefbc3109fc169363 Mon Sep 17 00:00:00 2001 From: Alexander Ziaee Date: Thu, 1 Aug 2024 08:33:22 -0400 Subject: [PATCH 192/213] adduser.8: update log location + spdx Closes: 280538 Fixes: cf8a18 (back out logging to /var/log/adduser) MFC after: 3 days Reported by: Herbert Baerschneider Reviewed by: imp Pull Request: https://github.com/freebsd/freebsd-src/pull/1354 --- usr.sbin/adduser/adduser.8 | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/usr.sbin/adduser/adduser.8 b/usr.sbin/adduser/adduser.8 index ed67e21f9430..8ba623fedd9d 100644 --- a/usr.sbin/adduser/adduser.8 +++ b/usr.sbin/adduser/adduser.8 @@ -1,3 +1,6 @@ +.\"- +.\" SPDX-License-Identifier: BSD-2-Clause +.\" .\" Copyright (c) 1995-1996 Wolfram Schneider . Berlin. .\" All rights reserved. .\" Copyright (c) 2002-2004 Michael Telahun Makonnen @@ -427,7 +430,7 @@ message file for .Nm .It Pa /usr/share/skel skeletal login directory -.It Pa /var/log/adduser +.It Pa /var/log/userlog logfile for .Nm .El From 5d889e60c15ce7856cb9a9bc258dab8aaeb94efe Mon Sep 17 00:00:00 2001 From: Wuyang Chung Date: Fri, 2 Aug 2024 14:44:38 +0800 Subject: [PATCH 193/213] amd64: move the right parenthesis to the right place Reviewed by: imp, emaste Pull Request: https://github.com/freebsd/freebsd-src/pull/1356 --- sys/amd64/amd64/machdep.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/amd64/amd64/machdep.c b/sys/amd64/amd64/machdep.c index 025c3c365de5..f4b3b9702e00 100644 --- a/sys/amd64/amd64/machdep.c +++ b/sys/amd64/amd64/machdep.c @@ -1382,7 +1382,7 @@ hammer_time(u_int64_t modulep, u_int64_t physfree) */ for (x = 0; x < NGDT; x++) { if (x != GPROC0_SEL && x != (GPROC0_SEL + 1) && - x != GUSERLDT_SEL && x != (GUSERLDT_SEL) + 1) + x != GUSERLDT_SEL && x != (GUSERLDT_SEL + 1)) ssdtosd(&gdt_segs[x], &gdt[x]); } gdt_segs[GPROC0_SEL].ssd_base = (uintptr_t)&pc->pc_common_tss; From 7b984d5043f2cab8ba05082366e48116e0d495a2 Mon Sep 17 00:00:00 2001 From: Joshua Rogers Date: Mon, 27 May 2024 17:46:29 +0200 Subject: [PATCH 194/213] wsp: Allow the trackpad to be used after a partially unreleased click. This provides functionality for a click which is partially unreleased and then allows the user to continue moving the mousepad as if were not invoked as a full click Signed-off-by: Joshua Rogers Reviewed by: imp, wulf Pull Request: https://github.com/freebsd/freebsd-src/pull/1365 --- share/man/man4/wsp.4 | 5 +++++ sys/dev/usb/input/wsp.c | 10 ++++++++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/share/man/man4/wsp.4 b/share/man/man4/wsp.4 index 39660a53ee9a..bcbbc1b8bb5d 100644 --- a/share/man/man4/wsp.4 +++ b/share/man/man4/wsp.4 @@ -65,6 +65,11 @@ Pointer sensitivity can be controlled using the sysctl tunable Tap to left-click can be controlled using the sysctl tunable .Nm hw.usb.wsp.enable_single_tap_clicks , set to 0 to disable single tap clicks or 1 to enable them (default). +Movement on the trackpad following a partially-released click can be +controlled using the sysctl tunable +.Nm hw.usb.wsp.enable_single_tap_movement , +set to 0 to disable the movement on the trackpad until a full release +or 1 to allow the continued movement (default). Z-Axis sensitivity can be controlled using the sysctl tunable .Nm hw.usb.wsp.z_factor . Z-Axis inversion can be controlled using the sysctl tunable diff --git a/sys/dev/usb/input/wsp.c b/sys/dev/usb/input/wsp.c index f1931c9e03c0..4527278295ca 100644 --- a/sys/dev/usb/input/wsp.c +++ b/sys/dev/usb/input/wsp.c @@ -99,6 +99,7 @@ static struct wsp_tuning { int pressure_tap_threshold; int scr_hor_threshold; int enable_single_tap_clicks; + int enable_single_tap_movement; } wsp_tuning = { @@ -110,6 +111,7 @@ static struct wsp_tuning { .pressure_tap_threshold = 120, .scr_hor_threshold = 20, .enable_single_tap_clicks = 1, + .enable_single_tap_movement = 1, }; static void @@ -123,6 +125,7 @@ wsp_runing_rangecheck(struct wsp_tuning *ptun) WSP_CLAMP(ptun->pressure_tap_threshold, 1, 255); WSP_CLAMP(ptun->scr_hor_threshold, 1, 255); WSP_CLAMP(ptun->enable_single_tap_clicks, 0, 1); + WSP_CLAMP(ptun->enable_single_tap_movement, 0, 1); } SYSCTL_INT(_hw_usb_wsp, OID_AUTO, scale_factor, CTLFLAG_RWTUN, @@ -141,6 +144,9 @@ SYSCTL_INT(_hw_usb_wsp, OID_AUTO, scr_hor_threshold, CTLFLAG_RWTUN, &wsp_tuning.scr_hor_threshold, 0, "horizontal scrolling threshold"); SYSCTL_INT(_hw_usb_wsp, OID_AUTO, enable_single_tap_clicks, CTLFLAG_RWTUN, &wsp_tuning.enable_single_tap_clicks, 0, "enable single tap clicks"); +SYSCTL_INT(_hw_usb_wsp, OID_AUTO, enable_single_tap_movement, CTLFLAG_RWTUN, + &wsp_tuning.enable_single_tap_movement, 0, "enable single tap movement"); + /* * Some tables, structures, definitions and constant values for the @@ -1149,8 +1155,8 @@ wsp_intr_callback(struct usb_xfer *xfer, usb_error_t error) dx = sc->pos_x[0] - sc->pre_pos_x; dy = sc->pos_y[0] - sc->pre_pos_y; - /* Ignore movement during button is releasing */ - if (sc->ibtn != 0 && sc->sc_status.button == 0) + /* Optionally ignore movement during button is releasing */ + if (tun.enable_single_tap_movement != 1 && sc->ibtn != 0 && sc->sc_status.button == 0) dx = dy = 0; /* Ignore movement if ntouch changed */ From 62cf43dda897f33bb80a20630f34bfe204cb97ee Mon Sep 17 00:00:00 2001 From: Joshua Rogers Date: Tue, 28 May 2024 02:20:19 +0200 Subject: [PATCH 195/213] wsp: Improve multi-finger touchpad usage and allow more configurations This patch allows scrolling with multiple fingers simultaneously, in line with how wsp trackpads function on MacOS. Two new tunables are added: hw.usb.wsp.max_finger_area and hw.usb.wsp.max_double_tap_distance. max_finger_area defines the maximum size which the driver registered an object on trackpad as a finger. Previously, this value was hardcoded as 1200, which was too low to register thumb-clicks. max_double_tap_distance defines the maximum distance between two fingers which will register as a double-click. Signed-off-by: Joshua Rogers Reviewed by: imp, wulf Pull Request: https://github.com/freebsd/freebsd-src/pull/1365 --- share/man/man4/wsp.4 | 6 +++ sys/dev/usb/input/wsp.c | 85 +++++++++++++++++++++++++++-------------- 2 files changed, 62 insertions(+), 29 deletions(-) diff --git a/share/man/man4/wsp.4 b/share/man/man4/wsp.4 index bcbbc1b8bb5d..83a4421fa2ff 100644 --- a/share/man/man4/wsp.4 +++ b/share/man/man4/wsp.4 @@ -70,6 +70,12 @@ controlled using the sysctl tunable .Nm hw.usb.wsp.enable_single_tap_movement , set to 0 to disable the movement on the trackpad until a full release or 1 to allow the continued movement (default). +.Nm hw.usb.wsp.max_finger_area +defines the maximum area on the trackpad which is registered as a +finger (lower for greater palm detection). +.Nm hw.usb.wsp.max_double_tap_distance +defines the maximum distance between two finger clicks or taps which may +register as a double-click. Z-Axis sensitivity can be controlled using the sysctl tunable .Nm hw.usb.wsp.z_factor . Z-Axis inversion can be controlled using the sysctl tunable diff --git a/sys/dev/usb/input/wsp.c b/sys/dev/usb/input/wsp.c index 4527278295ca..708a26498361 100644 --- a/sys/dev/usb/input/wsp.c +++ b/sys/dev/usb/input/wsp.c @@ -98,6 +98,8 @@ static struct wsp_tuning { int pressure_untouch_threshold; int pressure_tap_threshold; int scr_hor_threshold; + int max_finger_area; + int max_double_tap_distance; int enable_single_tap_clicks; int enable_single_tap_movement; } @@ -110,6 +112,8 @@ static struct wsp_tuning { .pressure_untouch_threshold = 10, .pressure_tap_threshold = 120, .scr_hor_threshold = 20, + .max_finger_area = 1900, + .max_double_tap_distance = 2500, .enable_single_tap_clicks = 1, .enable_single_tap_movement = 1, }; @@ -123,6 +127,8 @@ wsp_runing_rangecheck(struct wsp_tuning *ptun) WSP_CLAMP(ptun->pressure_touch_threshold, 1, 255); WSP_CLAMP(ptun->pressure_untouch_threshold, 1, 255); WSP_CLAMP(ptun->pressure_tap_threshold, 1, 255); + WSP_CLAMP(ptun->max_finger_area, 1, 2400); + WSP_CLAMP(ptun->max_double_tap_distance, 1, 16384); WSP_CLAMP(ptun->scr_hor_threshold, 1, 255); WSP_CLAMP(ptun->enable_single_tap_clicks, 0, 1); WSP_CLAMP(ptun->enable_single_tap_movement, 0, 1); @@ -140,6 +146,10 @@ SYSCTL_INT(_hw_usb_wsp, OID_AUTO, pressure_untouch_threshold, CTLFLAG_RWTUN, &wsp_tuning.pressure_untouch_threshold, 0, "untouch pressure threshold"); SYSCTL_INT(_hw_usb_wsp, OID_AUTO, pressure_tap_threshold, CTLFLAG_RWTUN, &wsp_tuning.pressure_tap_threshold, 0, "tap pressure threshold"); +SYSCTL_INT(_hw_usb_wsp, OID_AUTO, max_finger_area, CTLFLAG_RWTUN, + &wsp_tuning.max_finger_area, 0, "maximum finger area"); +SYSCTL_INT(_hw_usb_wsp, OID_AUTO, max_double_tap_distance, CTLFLAG_RWTUN, + &wsp_tuning.max_double_tap_distance, 0, "maximum double-finger click distance"); SYSCTL_INT(_hw_usb_wsp, OID_AUTO, scr_hor_threshold, CTLFLAG_RWTUN, &wsp_tuning.scr_hor_threshold, 0, "horizontal scrolling threshold"); SYSCTL_INT(_hw_usb_wsp, OID_AUTO, enable_single_tap_clicks, CTLFLAG_RWTUN, @@ -573,13 +583,13 @@ struct wsp_softc { struct tp_finger *index[MAX_FINGERS]; /* finger index data */ int16_t pos_x[MAX_FINGERS]; /* position array */ int16_t pos_y[MAX_FINGERS]; /* position array */ + int16_t pre_pos_x[MAX_FINGERS]; /* previous position array */ + int16_t pre_pos_y[MAX_FINGERS]; /* previous position array */ u_int sc_touch; /* touch status */ #define WSP_UNTOUCH 0x00 #define WSP_FIRST_TOUCH 0x01 #define WSP_SECOND_TOUCH 0x02 #define WSP_TOUCHING 0x04 - int16_t pre_pos_x; /* previous position array */ - int16_t pre_pos_y; /* previous position array */ int dx_sum; /* x axis cumulative movement */ int dy_sum; /* y axis cumulative movement */ int dz_sum; /* z axis cumulative movement */ @@ -596,7 +606,6 @@ struct wsp_softc { #define WSP_TAP_THRESHOLD 3 #define WSP_TAP_MAX_COUNT 20 int distance; /* the distance of 2 fingers */ -#define MAX_DISTANCE 2500 /* the max allowed distance */ uint8_t ibtn; /* button status in tapping */ uint8_t ntaps; /* finger status in tapping */ uint8_t scr_mode; /* scroll status in movement */ @@ -1040,13 +1049,35 @@ wsp_intr_callback(struct usb_xfer *xfer, usb_error_t error) sc->sc_status.obutton = sc->sc_status.button; sc->sc_status.button = 0; + if (ntouch == 2) { + sc->distance = max(sc->distance, max( + abs(sc->pos_x[0] - sc->pos_x[1]), + abs(sc->pos_y[0] - sc->pos_y[1]))); + } + if (ibt != 0) { - if ((params->tp->caps & HAS_INTEGRATED_BUTTON) && ntouch == 2) - sc->sc_status.button |= MOUSE_BUTTON3DOWN; - else if ((params->tp->caps & HAS_INTEGRATED_BUTTON) && ntouch == 3) - sc->sc_status.button |= MOUSE_BUTTON2DOWN; - else + if (params->tp->caps & HAS_INTEGRATED_BUTTON) { + switch (ntouch) { + case 1: + sc->sc_status.button |= MOUSE_BUTTON1DOWN; + break; + case 2: + if (sc->distance < tun.max_double_tap_distance && abs(sc->dx_sum) < 5 && + abs(sc->dy_sum) < 5) + sc->sc_status.button |= MOUSE_BUTTON3DOWN; + else + sc->sc_status.button |= MOUSE_BUTTON1DOWN; + break; + case 3: + sc->sc_status.button |= MOUSE_BUTTON2DOWN; + break; + default: + break; + } + } else { sc->sc_status.button |= MOUSE_BUTTON1DOWN; + } + sc->ibtn = 1; } sc->intr_count++; @@ -1055,7 +1086,7 @@ wsp_intr_callback(struct usb_xfer *xfer, usb_error_t error) switch (ntouch) { case 1: if (sc->index[0]->touch_major > tun.pressure_tap_threshold && - sc->index[0]->tool_major <= 1200) + sc->index[0]->tool_major <= tun.max_finger_area) sc->ntaps = 1; break; case 2: @@ -1073,11 +1104,7 @@ wsp_intr_callback(struct usb_xfer *xfer, usb_error_t error) break; } } - if (ntouch == 2) { - sc->distance = max(sc->distance, max( - abs(sc->pos_x[0] - sc->pos_x[1]), - abs(sc->pos_y[0] - sc->pos_y[1]))); - } + if (sc->index[0]->touch_major < tun.pressure_untouch_threshold && sc->sc_status.button == 0) { sc->sc_touch = WSP_UNTOUCH; @@ -1098,7 +1125,7 @@ wsp_intr_callback(struct usb_xfer *xfer, usb_error_t error) case 2: DPRINTFN(WSP_LLEVEL_INFO, "sum_x=%5d, sum_y=%5d\n", sc->dx_sum, sc->dy_sum); - if (sc->distance < MAX_DISTANCE && abs(sc->dx_sum) < 5 && + if (sc->distance < tun.max_double_tap_distance && abs(sc->dx_sum) < 5 && abs(sc->dy_sum) < 5) { wsp_add_to_queue(sc, 0, 0, 0, MOUSE_BUTTON3DOWN); DPRINTFN(WSP_LLEVEL_INFO, "RIGHT CLICK!\n"); @@ -1144,16 +1171,16 @@ wsp_intr_callback(struct usb_xfer *xfer, usb_error_t error) } else if (sc->index[0]->touch_major >= tun.pressure_touch_threshold && sc->sc_touch == WSP_FIRST_TOUCH) { /* ignore second touch */ sc->sc_touch = WSP_SECOND_TOUCH; - DPRINTFN(WSP_LLEVEL_INFO, "Fist pre_x=%5d, pre_y=%5d\n", - sc->pre_pos_x, sc->pre_pos_y); + DPRINTFN(WSP_LLEVEL_INFO, "First pre_x[0]=%5d, pre_y[0]=%5d\n", + sc->pre_pos_x[0], sc->pre_pos_y[0]); } else { if (sc->sc_touch == WSP_SECOND_TOUCH) sc->sc_touch = WSP_TOUCHING; if (ntouch != 0 && sc->index[0]->touch_major >= tun.pressure_touch_threshold) { - dx = sc->pos_x[0] - sc->pre_pos_x; - dy = sc->pos_y[0] - sc->pre_pos_y; + dx = sc->pos_x[0] - sc->pre_pos_x[0]; + dy = sc->pos_y[0] - sc->pre_pos_y[0]; /* Optionally ignore movement during button is releasing */ if (tun.enable_single_tap_movement != 1 && sc->ibtn != 0 && sc->sc_status.button == 0) @@ -1163,8 +1190,8 @@ wsp_intr_callback(struct usb_xfer *xfer, usb_error_t error) if (sc->o_ntouch != ntouch) dx = dy = 0; - /* Ignore unexpeted movement when typing */ - if (ntouch == 1 && sc->index[0]->tool_major > 1200) + /* Ignore unexpected movement when typing (palm detection) */ + if (ntouch == 1 && sc->index[0]->tool_major > tun.max_finger_area) dx = dy = 0; if (sc->ibtn != 0 && ntouch == 1 && @@ -1173,8 +1200,8 @@ wsp_intr_callback(struct usb_xfer *xfer, usb_error_t error) dx = dy = 0; if (ntouch == 2 && sc->sc_status.button != 0) { - dx = sc->pos_x[sc->finger] - sc->pre_pos_x; - dy = sc->pos_y[sc->finger] - sc->pre_pos_y; + dx = sc->pos_x[sc->finger] - sc->pre_pos_x[sc->finger]; + dy = sc->pos_y[sc->finger] - sc->pre_pos_y[sc->finger]; /* * Ignore movement of switch finger or @@ -1237,8 +1264,8 @@ wsp_intr_callback(struct usb_xfer *xfer, usb_error_t error) if (sc->dz_count == 0) dz = (sc->dz_sum / tun.z_factor) * (tun.z_invert ? -1 : 1); if (sc->scr_mode == WSP_SCR_HOR || - abs(sc->pos_x[0] - sc->pos_x[1]) > MAX_DISTANCE || - abs(sc->pos_y[0] - sc->pos_y[1]) > MAX_DISTANCE) + abs(sc->pos_x[0] - sc->pos_x[1]) > tun.max_finger_area || + abs(sc->pos_y[0] - sc->pos_y[1]) > tun.max_finger_area) dz = 0; } if (ntouch == 3) @@ -1262,12 +1289,12 @@ wsp_intr_callback(struct usb_xfer *xfer, usb_error_t error) sc->rdz = 0; } } - sc->pre_pos_x = sc->pos_x[0]; - sc->pre_pos_y = sc->pos_y[0]; + sc->pre_pos_x[0] = sc->pos_x[0]; + sc->pre_pos_y[0] = sc->pos_y[0]; if (ntouch == 2 && sc->sc_status.button != 0) { - sc->pre_pos_x = sc->pos_x[sc->finger]; - sc->pre_pos_y = sc->pos_y[sc->finger]; + sc->pre_pos_x[sc->finger] = sc->pos_x[sc->finger]; + sc->pre_pos_y[sc->finger] = sc->pos_y[sc->finger]; } sc->o_ntouch = ntouch; From 8aef1cd698f177986ee4f51ff6f63ea7b0b35098 Mon Sep 17 00:00:00 2001 From: Joshua Rogers Date: Mon, 10 Jun 2024 21:03:24 +0200 Subject: [PATCH 196/213] wsp: Use already-calculated distance of fingers for comparison. Also correctly use tun.max_double_tap_distance for maximum distance of fingers for vertical scrolling. Signed-off-by: Joshua Rogers Reviewed by: imp, wulf Pull Request: https://github.com/freebsd/freebsd-src/pull/1365 --- sys/dev/usb/input/wsp.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/sys/dev/usb/input/wsp.c b/sys/dev/usb/input/wsp.c index 708a26498361..a8d6c14c7421 100644 --- a/sys/dev/usb/input/wsp.c +++ b/sys/dev/usb/input/wsp.c @@ -1263,9 +1263,7 @@ wsp_intr_callback(struct usb_xfer *xfer, usb_error_t error) dx = dy = 0; if (sc->dz_count == 0) dz = (sc->dz_sum / tun.z_factor) * (tun.z_invert ? -1 : 1); - if (sc->scr_mode == WSP_SCR_HOR || - abs(sc->pos_x[0] - sc->pos_x[1]) > tun.max_finger_area || - abs(sc->pos_y[0] - sc->pos_y[1]) > tun.max_finger_area) + if (sc->scr_mode == WSP_SCR_HOR || sc->distance > tun.max_double_tap_distance) dz = 0; } if (ntouch == 3) From 66145c3829c1753f3b5fa303c4e36bba172be553 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Fri, 9 Aug 2024 04:57:47 +0200 Subject: [PATCH 197/213] ntptime: Use time_t for tv_sec related variables The struct timespec tv_sec member is of type time_t. Make sure that all variables related to this member are of the type time_t. This is important for targets where long is a 32-bit type and time_t a 64-bit type. Reviewed by: imp Pull Request: https://github.com/freebsd/freebsd-src/pull/1373 --- sys/kern/kern_ntptime.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sys/kern/kern_ntptime.c b/sys/kern/kern_ntptime.c index d2a2761ed683..65746021028b 100644 --- a/sys/kern/kern_ntptime.c +++ b/sys/kern/kern_ntptime.c @@ -193,7 +193,7 @@ static l_fp pps_freq; /* scaled frequency offset (ns/s) */ static long pps_fcount; /* frequency accumulator */ static long pps_jitter; /* nominal jitter (ns) */ static long pps_stabil; /* nominal stability (scaled ns/s) */ -static long pps_lastsec; /* time at last calibration (s) */ +static time_t pps_lastsec; /* time at last calibration (s) */ static int pps_valid; /* signal watchdog counter */ static int pps_shift = PPS_FAVG; /* interval duration (s) (shift) */ static int pps_shiftmax = PPS_FAVGDEF; /* max interval duration (s) (shift) */ @@ -742,7 +742,8 @@ hardupdate(long offset /* clock offset (ns) */) void hardpps(struct timespec *tsp, long delta_nsec) { - long u_sec, u_nsec, v_nsec; /* temps */ + long u_nsec, v_nsec; /* temps */ + time_t u_sec; l_fp ftemp; NTP_LOCK(); From 3272054073720172ebae9c2c5c75e656f72a6df1 Mon Sep 17 00:00:00 2001 From: Jose Luis Duran Date: Sat, 10 Aug 2024 17:46:23 +0000 Subject: [PATCH 198/213] ip6addrctl.8: Reference RFC 6724 instead Commit e695500d3cb945e62b4591cb68792601ed5c4b46 updated the policy table to match RFC 6724, which obsoletes RFC 3484. Add a reference to RFC 6724, and mark it up as a technical report (%R). MFC after: 3 days Signed-off-by: Jose Luis Duran Reviewed by: imp, glebius Pull Request: https://github.com/freebsd/freebsd-src/pull/1375 --- usr.sbin/ip6addrctl/ip6addrctl.8 | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/usr.sbin/ip6addrctl/ip6addrctl.8 b/usr.sbin/ip6addrctl/ip6addrctl.8 index f50da59aa2bb..cf8f1db4a8bd 100644 --- a/usr.sbin/ip6addrctl/ip6addrctl.8 +++ b/usr.sbin/ip6addrctl/ip6addrctl.8 @@ -27,7 +27,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd September 25, 2001 +.Dd August 10, 2024 .Dt IP6ADDRCTL 8 .Os .\" @@ -107,9 +107,12 @@ comments and are ignored. .\" .Sh SEE ALSO .Rs +.%A "Dave Thaler" .%A "Richard Draves" -.%T "Default Address Selection for IPv6" -.%N RFC 3484 +.%A "Arifumi Matsumoto" +.%A "Tim Chown" +.%T "Default Address Selection for Internet Protocol Version 6 (IPv6)" +.%R RFC 6724 .Re .\" .Sh HISTORY From 6bfbfc8f4fdc6ccd200541ef738a90d1be3c1ab7 Mon Sep 17 00:00:00 2001 From: Jose Luis Duran Date: Sun, 11 Aug 2024 03:06:12 +0000 Subject: [PATCH 199/213] ip6addrctl: Update the sample configuration file Update the sample ip6addrctl.conf.sample file to match the default policy, currently based on RFC 6724. MFC after: 3 days Signed-off-by: Jose Luis Duran Reviewed by: imp, glebius Pull Request: https://github.com/freebsd/freebsd-src/pull/1375 --- usr.sbin/ip6addrctl/ip6addrctl.conf.sample | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/usr.sbin/ip6addrctl/ip6addrctl.conf.sample b/usr.sbin/ip6addrctl/ip6addrctl.conf.sample index edcf77553f14..59c1f3db47e0 100644 --- a/usr.sbin/ip6addrctl/ip6addrctl.conf.sample +++ b/usr.sbin/ip6addrctl/ip6addrctl.conf.sample @@ -1,11 +1,15 @@ -# default policy table based on RFC 3484. +# default policy table based on RFC 6724. # usage: ip6addrctl install path_to_this_file # # #Format: #Prefix Precedence Label -::1/128 50 0 -::/0 40 1 -2002::/16 30 2 -::/96 20 3 -::ffff:0:0/96 10 4 +::1/128 50 0 +::/0 40 1 +::ffff:0:0/96 35 4 +2002::/16 30 2 +2001::/32 5 5 +fc00::/7 3 13 +::/96 1 3 +fec0::/10 1 11 +3ffe::/16 1 12 From 9cb98ab7ceeb97b70a4891a4a3a21372158ccf24 Mon Sep 17 00:00:00 2001 From: Jose Luis Duran Date: Thu, 22 Aug 2024 14:19:44 +0000 Subject: [PATCH 200/213] getaddrinfo.{1,3}: Cross-reference ip6addrctl(8) Reviewed by: imp, glebius Pull Request: https://github.com/freebsd/freebsd-src/pull/1375 --- lib/libc/net/getaddrinfo.3 | 3 ++- usr.bin/getaddrinfo/getaddrinfo.1 | 3 ++- usr.sbin/ip6addrctl/ip6addrctl.8 | 2 ++ 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/libc/net/getaddrinfo.3 b/lib/libc/net/getaddrinfo.3 index 271ef8a0102b..634786a8bd12 100644 --- a/lib/libc/net/getaddrinfo.3 +++ b/lib/libc/net/getaddrinfo.3 @@ -480,7 +480,8 @@ freeaddrinfo(res0); .Xr hosts 5 , .Xr resolv.conf 5 , .Xr services 5 , -.Xr hostname 7 +.Xr hostname 7 , +.Xr ip6addrctl 8 .Rs .%A R. Gilligan .%A S. Thomson diff --git a/usr.bin/getaddrinfo/getaddrinfo.1 b/usr.bin/getaddrinfo/getaddrinfo.1 index ff99cd1ea1ee..fa9e8adce6a2 100644 --- a/usr.bin/getaddrinfo/getaddrinfo.1 +++ b/usr.bin/getaddrinfo/getaddrinfo.1 @@ -171,7 +171,8 @@ stream inet tcp 199.233.217.249 80 .Xr nsswitch.conf 5 , .Xr protocols 5 , .Xr resolv.conf 5 , -.Xr services 5 +.Xr services 5 , +.Xr ip6addrctl 8 .Sh HISTORY The .Nm diff --git a/usr.sbin/ip6addrctl/ip6addrctl.8 b/usr.sbin/ip6addrctl/ip6addrctl.8 index cf8f1db4a8bd..50245cef91ea 100644 --- a/usr.sbin/ip6addrctl/ip6addrctl.8 +++ b/usr.sbin/ip6addrctl/ip6addrctl.8 @@ -106,6 +106,8 @@ comments and are ignored. .Ex -std .\" .Sh SEE ALSO +.Xr getaddrinfo 1 , +.Xr getaddrinfo 3 .Rs .%A "Dave Thaler" .%A "Richard Draves" From 7b9c9f8004b17cda071537c9b2fdd259eec27d2a Mon Sep 17 00:00:00 2001 From: Val Packett Date: Sat, 10 Aug 2024 23:11:25 -0300 Subject: [PATCH 201/213] cross-build: fix fake_sysctl/tzsetup The error was always returned, even after handling the sysctl, breaking installworld under Linux. Sponsored by: https://www.patreon.com/valpackett Reviewed by: imp Pull Request: https://github.com/freebsd/freebsd-src/pull/1376 --- tools/build/cross-build/fake_sysctl.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/build/cross-build/fake_sysctl.c b/tools/build/cross-build/fake_sysctl.c index 4f1b271f3858..c4e40ebb9e72 100644 --- a/tools/build/cross-build/fake_sysctl.c +++ b/tools/build/cross-build/fake_sysctl.c @@ -53,6 +53,7 @@ __freebsd_sysctlbyname(const char *name, void *oldp, size_t *oldlenp, errx(EX_USAGE, "kern.vm_guest is read-only"); strlcpy(oldp, "none", *oldlenp); *oldlenp = strlen("none"); + return (0); } errx(EX_USAGE, "fatal: unknown sysctl %s\n", name); } From 7e3b6b249f54f5b22eae14dfa48ef7891bc4eac1 Mon Sep 17 00:00:00 2001 From: Alexander Ziaee Date: Sun, 11 Aug 2024 23:07:42 -0400 Subject: [PATCH 202/213] diskless.8: show in `apropos pxe` + tag SPDX MFC after: 3 days Reviewed by: imp Pull Request: https://github.com/freebsd/freebsd-src/pull/1378 --- share/man/man8/diskless.8 | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/share/man/man8/diskless.8 b/share/man/man8/diskless.8 index 8839e27e11ba..cc49854ae850 100644 --- a/share/man/man8/diskless.8 +++ b/share/man/man8/diskless.8 @@ -1,3 +1,6 @@ +.\"- +.\" SPDX-License-Identifier: BSD-3-Clause +.\" .\" Copyright (c) 1994 Gordon W. Ross, Theo de Raadt .\" Updated by Luigi Rizzo, Robert Watson .\" All rights reserved. @@ -24,12 +27,12 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd May 3, 2020 +.Dd August 11, 2024 .Dt DISKLESS 8 .Os .Sh NAME .Nm diskless -.Nd booting a system over the network +.Nd booting a system over the network with PXE .Sh DESCRIPTION The ability to boot a machine over the network is useful for .Em diskless From 0d8effbd6e45643154c90942f210b7f7a6ecc61d Mon Sep 17 00:00:00 2001 From: Alexander Ziaee Date: Mon, 12 Aug 2024 05:39:03 -0400 Subject: [PATCH 203/213] growfs.8: align and alphabetize options MFC after: 3 days Reviewed by: imp Pull Request: https://github.com/freebsd/freebsd-src/pull/1379 --- sbin/growfs/growfs.8 | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/sbin/growfs/growfs.8 b/sbin/growfs/growfs.8 index 9a6076017c74..9b619613f30e 100644 --- a/sbin/growfs/growfs.8 +++ b/sbin/growfs/growfs.8 @@ -61,16 +61,11 @@ The .Nm utility extends the size of the file system on the specified special file. The following options are available: -.Bl -tag -width indent +.Bl -tag -width "-s size" .It Fl N .Dq Test mode . Causes the new file system parameters to be printed out without actually enlarging the file system. -.It Fl y -Causes -.Nm -to assume yes -as the answer to all operator questions. .It Fl s Ar size Determines the .Ar size @@ -87,6 +82,11 @@ This value defaults to the size of the raw partition specified in (in other words, .Nm will enlarge the file system to the size of the entire partition). +.It Fl y +Causes +.Nm +to assume yes +as the answer to all operator questions. .El .Sh EXIT STATUS Exit status is 0 on success, and >= 1 on errors. From a5770eb54f7d13717098b5c34cc2dd51d2772021 Mon Sep 17 00:00:00 2001 From: Alexander Ziaee Date: Mon, 12 Aug 2024 05:59:21 -0400 Subject: [PATCH 204/213] geom.8: minor cleanup (markup, spdx, gsched) Fixes: 86c06f (Remove GEOM_SCHED class and gsched) MFC after: 3 days Reviewed by: imp Pull Request: https://github.com/freebsd/freebsd-src/pull/1380 --- sbin/geom/core/geom.8 | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/sbin/geom/core/geom.8 b/sbin/geom/core/geom.8 index 124ea0f2be11..7f0f0b2911b3 100644 --- a/sbin/geom/core/geom.8 +++ b/sbin/geom/core/geom.8 @@ -1,3 +1,6 @@ +.\"- +.\" SPDX-License-Identifier: BSD-2-Clause +.\" .\" Copyright (c) 2004-2005 Pawel Jakub Dawidek .\" All rights reserved. .\" @@ -27,7 +30,7 @@ .Os .Sh NAME .Nm geom -.Nd "universal control utility for GEOM classes" +.Nd universal control utility for GEOM classes .Sh SYNOPSIS .Nm .Ar class @@ -66,7 +69,7 @@ which can be used for existing .Nm unaware classes. Here is the list of standard commands: -.Bl -tag -width ".Cm status" +.Bl -tag -width indent .It Cm help List all available commands for the given class. .It Cm list @@ -74,7 +77,7 @@ Print detailed information (within the given class) about all geoms (if no additional arguments were specified) or the given geoms. This command is only available if the given class exists in the kernel. Additional options include: -.Bl -tag -width ".Fl a" +.Bl -tag -width "-a" .It Fl a Print information for geoms without providers. .El @@ -84,9 +87,11 @@ Print general information (within the given class) about all geoms This command is only available if the given class exists in the kernel. .Pp Additional options include: -.Bl -tag -width ".Fl s" +.Bl -tag -width "-s" .It Fl a -When used with -g, print status for geoms without providers. +When used with +.Fl g , +print status for geoms without providers. .It Fl g Report statuses for geoms instead of providers. .It Fl s @@ -107,7 +112,7 @@ kernel module. .El .Pp Additional options include: -.Bl -tag -width ".Cm status" +.Bl -tag -width indent .It Fl p Ar provider-name Print detailed information about the geom which provides .Ar provider-name . @@ -170,7 +175,7 @@ VIRSTOR .Sh ENVIRONMENT The following environment variables affect the execution of .Nm : -.Bl -tag -width ".Ev GEOM_LIBRARY_PATH" +.Bl -tag -width "GEOM_LIBRARY_PATH" .It Ev GEOM_LIBRARY_PATH Specifies the path where shared libraries are stored instead of .Pa /lib/geom/ . @@ -213,7 +218,6 @@ geom md unload .Xr gnop 8 , .Xr gpart 8 , .Xr graid3 8 , -.Xr gsched 8 , .Xr gshsec 8 , .Xr gstripe 8 , .Xr gunion 8 , From fe830c3bdbb80545711d49b5bd6fd4ec28ed9f8e Mon Sep 17 00:00:00 2001 From: Alexander Ziaee Date: Tue, 13 Aug 2024 21:33:07 -0400 Subject: [PATCH 205/213] UPDATING: increase visibility of footnotes MFC after: 3 days Reviewed by: imp Pull Request: https://github.com/freebsd/freebsd-src/pull/1382 --- UPDATING | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/UPDATING b/UPDATING index 1aae85df0a70..01fbf9a30946 100644 --- a/UPDATING +++ b/UPDATING @@ -2022,6 +2022,8 @@ COMMON ITEMS: make -DALWAYS_CHECK_MAKE buildkernel KERNCONF=YOUR_KERNEL_HERE make -DALWAYS_CHECK_MAKE installkernel KERNCONF=YOUR_KERNEL_HERE + If you are running kernel modules from ports, see FOOTNOTE [1]. + To test a kernel once --------------------- If you just want to boot a kernel once (because you are not sure @@ -2038,8 +2040,7 @@ COMMON ITEMS: make buildworld make buildkernel KERNCONF=YOUR_KERNEL_HERE - make installkernel KERNCONF=YOUR_KERNEL_HERE - [1] + make installkernel KERNCONF=YOUR_KERNEL_HERE [1] [3] etcupdate -p [5] make installworld @@ -2057,7 +2058,7 @@ COMMON ITEMS: make buildworld - make buildkernel KERNCONF=YOUR_KERNEL_HERE + make buildkernel KERNCONF=YOUR_KERNEL_HERE [1] make installworld DESTDIR=${CURRENT_ROOT} -DDB_FROM_SRC @@ -2076,8 +2077,7 @@ COMMON ITEMS: make buildworld [9] make buildkernel KERNCONF=YOUR_KERNEL_HERE [8] - make installkernel KERNCONF=YOUR_KERNEL_HERE - [1] + make installkernel KERNCONF=YOUR_KERNEL_HERE [1] [3] etcupdate -p [5] make installworld @@ -2097,8 +2097,10 @@ COMMON ITEMS: messages there. If in doubt, please track -stable which has much fewer pitfalls. - [1] If you have third party modules, such as vmware, you should disable - them at this point so they don't crash your system on +FOOTNOTES: + + [1] If you have third party modules, such as drm-kmod or vmware, you + should disable them at this point so they don't crash your system on reboot. Alternatively, you should rebuild all the modules you have in your system and install them as well. If you are running -current, you should seriously consider placing all sources to all the modules for From 4c72525953fdf618a3fc0a45f3ef3f071dcc0c52 Mon Sep 17 00:00:00 2001 From: Alexander Ziaee Date: Wed, 14 Aug 2024 02:50:18 -0400 Subject: [PATCH 206/213] ure.4: description consistencies + tag spdx + consistent document description languague with other USB-BaseT drivers + mention newly added adapters from 6ea4d9 + attempt to mention rgephy(4) phys feed into ure interfaces Fixes: 6ea4d9 (Move RTL8156 from cdce(4) to ure(4)) MFC after: 3 days Reviewed by: imp Pull Request: https://github.com/freebsd/freebsd-src/pull/1384 --- share/man/man4/ure.4 | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/share/man/man4/ure.4 b/share/man/man4/ure.4 index 942764109dd8..f5452fa8463b 100644 --- a/share/man/man4/ure.4 +++ b/share/man/man4/ure.4 @@ -1,3 +1,5 @@ +.\"- +.\" SPDX-License-Identifier: BSD-2-Clause .\" .\" Copyright (c) 2015-2016 Kevin Lo .\" All rights reserved. @@ -23,12 +25,12 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd May 3, 2024 +.Dd September 3, 2024 .Dt URE 4 .Os .Sh NAME .Nm ure -.Nd "RealTek RTL8152/RTL8153/RTL8153B/RTL8156/RTL8156B USB to Ethernet controller driver" +.Nd RealTek RTL8152/RTL8153/RTL8156 USB Ethernet driver .Sh SYNOPSIS To compile this driver into the kernel, place the following lines in your @@ -52,15 +54,20 @@ if_ure_load="YES" The .Nm driver provides support for USB Ethernet adapters based on the RealTek -RealTek RTL8152 and RTL8153 USB Ethernet controllers. +RTL8152, RTL8153/RTL8153B, and RTL8156/RTL8156B USB Ethernet controllers, +as well as USB Ethernet PHYs provided by +.Xr rgephy 4 . .Pp -NICs based on the RTL8152 are capable of 10 and 100Mbps speeds. -NICs based on the RTL8153 are capable of 10, 100 and 1000Mbps operation. +NICs based on the RTL8152 are capable of 10 and 100Mbps. +NICs based on the RTL8153 or provided by +.Xr rgephy 4 +are capable of 10, 100, and 1000Mbps. +NICs based on the RTL8156 are capable of 10, 100, 1000, and 2500Mbps operation. .Pp The .Nm driver supports the following media types: -.Bl -tag -width ".Cm 10baseT/UTP" +.Bl -tag -width "10baseT/UTP" .It Cm autoselect Enable auto selection of the media type and options. The user can manually override @@ -86,7 +93,7 @@ or .Cm half-duplex modes. .It Cm 1000baseTX -Set 1000baseTX operation over twisted pair. +Set 1000baseTX (Gigabit Ethernet) operation over twisted pair. The RealTek gigE chips support 1000Mbps in .Cm full-duplex mode only. @@ -99,12 +106,12 @@ mode only. .Pp The .Nm -driver supports the following media options: -.Bl -tag -width ".Cm full-duplex" +driver supports the following media options for 10/100 operation: +.Bl -tag -width "full-duplex" .It Cm full-duplex -Force full duplex operation. +Force full-duplex operation. .It Cm half-duplex -Force half duplex operation. +Force half-duplex operation. .El .Pp For more information on configuring this device, see From 5e6bef460d9dc3a1ef567f9602b04a252b554b67 Mon Sep 17 00:00:00 2001 From: Tom Hukins Date: Sat, 17 Aug 2024 21:15:50 +0100 Subject: [PATCH 207/213] Fix "version introduced" in two manual pages Signed-off-by: Tom Hukins Reviewed by: imp Pull Request: https://github.com/freebsd/freebsd-src/pull/1385 --- share/man/man4/acpi_ged.4 | 2 +- share/man/man4/gve.4 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/share/man/man4/acpi_ged.4 b/share/man/man4/acpi_ged.4 index c87c7b3e97c9..98baabdde796 100644 --- a/share/man/man4/acpi_ged.4 +++ b/share/man/man4/acpi_ged.4 @@ -53,7 +53,7 @@ This may generate optionally ACPI notify for another device. The .Nm device driver first appeared in -.Fx 14.0 . +.Fx 13.3 . .Sh AUTHORS .An -nosplit The diff --git a/share/man/man4/gve.4 b/share/man/man4/gve.4 index 54e59b86108b..95c125507bd5 100644 --- a/share/man/man4/gve.4 +++ b/share/man/man4/gve.4 @@ -208,7 +208,7 @@ Please email gvnic-drivers@google.com with the specifics of the issue encountere The .Nm device driver first appeared in -.Fx 14.0 . +.Fx 13.3 . .Sh AUTHORS The .Nm From 3f0efe05432b1633991114ca4ca330102a561959 Mon Sep 17 00:00:00 2001 From: Jose Luis Duran Date: Tue, 20 Aug 2024 11:58:00 +0000 Subject: [PATCH 208/213] libefivar: Fix AcpiEx print logic Add logic that checks if the code doesn't overflow ACPI_EXTENDED_HID_DEVICE_PATH node when searching for optional strings. If the string is not provided in the device path node default value of "\0" is used. Upstream PR: https://bugzilla.tianocore.org/show_bug.cgi?id=4555 Obtained from: https://github.com/tianocore/edk2/commit/96ed60dfd7d4818a532216d64ee87b13fae5c726 Reviewed by: imp Pull Request: https://github.com/freebsd/freebsd-src/pull/1388 --- lib/libefivar/efivar-dp-format.c | 72 ++++++++++++++++++++------------ 1 file changed, 45 insertions(+), 27 deletions(-) diff --git a/lib/libefivar/efivar-dp-format.c b/lib/libefivar/efivar-dp-format.c index d97603c41dcb..72e024470a11 100644 --- a/lib/libefivar/efivar-dp-format.c +++ b/lib/libefivar/efivar-dp-format.c @@ -478,23 +478,41 @@ DevPathToTextAcpiEx ( ) { ACPI_EXTENDED_HID_DEVICE_PATH *AcpiEx; - CHAR8 *HIDStr; - CHAR8 *UIDStr; - CHAR8 *CIDStr; char HIDText[11]; char CIDText[11]; - - AcpiEx = DevPath; - HIDStr = (CHAR8 *)(((UINT8 *)AcpiEx) + sizeof (ACPI_EXTENDED_HID_DEVICE_PATH)); - UIDStr = HIDStr + AsciiStrLen (HIDStr) + 1; - CIDStr = UIDStr + AsciiStrLen (UIDStr) + 1; + UINTN CurrentLength; + CHAR8 *CurrentPos; + UINTN NextStringOffset; + CHAR8 *Strings[3]; + UINT8 HidStrIndex; + UINT8 UidStrIndex; + UINT8 CidStrIndex; + UINT8 StrIndex; + + HidStrIndex = 0; + UidStrIndex = 1; + CidStrIndex = 2; + AcpiEx = DevPath; + Strings[HidStrIndex] = NULL; + Strings[UidStrIndex] = NULL; + Strings[CidStrIndex] = NULL; + CurrentLength = sizeof (ACPI_EXTENDED_HID_DEVICE_PATH); + CurrentPos = (CHAR8 *)(((UINT8 *)AcpiEx) + sizeof (ACPI_EXTENDED_HID_DEVICE_PATH)); + StrIndex = 0; + while (CurrentLength < AcpiEx->Header.Length[0] && StrIndex < ARRAY_SIZE (Strings)) { + Strings[StrIndex] = CurrentPos; + NextStringOffset = AsciiStrLen (CurrentPos) + 1; + CurrentLength += NextStringOffset; + CurrentPos += NextStringOffset; + StrIndex++; + } if (DisplayOnly) { if ((EISA_ID_TO_NUM (AcpiEx->HID) == 0x0A03) || ((EISA_ID_TO_NUM (AcpiEx->CID) == 0x0A03) && (EISA_ID_TO_NUM (AcpiEx->HID) != 0x0A08))) { - if (AcpiEx->UID == 0) { - UefiDevicePathLibCatPrint (Str, "PciRoot(%s)", UIDStr); + if (Strings[UidStrIndex] != NULL) { + UefiDevicePathLibCatPrint (Str, "PciRoot(%s)", Strings[UidStrIndex]); } else { UefiDevicePathLibCatPrint (Str, "PciRoot(0x%x)", AcpiEx->UID); } @@ -503,8 +521,8 @@ DevPathToTextAcpiEx ( } if ((EISA_ID_TO_NUM (AcpiEx->HID) == 0x0A08) || (EISA_ID_TO_NUM (AcpiEx->CID) == 0x0A08)) { - if (AcpiEx->UID == 0) { - UefiDevicePathLibCatPrint (Str, "PcieRoot(%s)", UIDStr); + if (Strings[UidStrIndex] != NULL) { + UefiDevicePathLibCatPrint (Str, "PcieRoot(%s)", Strings[UidStrIndex]); } else { UefiDevicePathLibCatPrint (Str, "PcieRoot(0x%x)", AcpiEx->UID); } @@ -535,7 +553,10 @@ DevPathToTextAcpiEx ( (AcpiEx->CID >> 16) & 0xFFFF ); - if ((*HIDStr == '\0') && (*CIDStr == '\0') && (*UIDStr != '\0')) { + if (((Strings[HidStrIndex] != NULL) && (*Strings[HidStrIndex] == '\0')) && + ((Strings[CidStrIndex] != NULL) && (*Strings[CidStrIndex] == '\0')) && + ((Strings[UidStrIndex] != NULL) && (*Strings[UidStrIndex] != '\0'))) + { // // use AcpiExp() // @@ -544,7 +565,7 @@ DevPathToTextAcpiEx ( Str, "AcpiExp(%s,0,%s)", HIDText, - UIDStr + Strings[UidStrIndex] ); } else { UefiDevicePathLibCatPrint ( @@ -552,28 +573,25 @@ DevPathToTextAcpiEx ( "AcpiExp(%s,%s,%s)", HIDText, CIDText, - UIDStr + Strings[UidStrIndex] ); } } else { if (DisplayOnly) { - // - // display only - // - if (AcpiEx->HID == 0) { - UefiDevicePathLibCatPrint (Str, "AcpiEx(%s,", HIDStr); + if (Strings[HidStrIndex] != NULL) { + UefiDevicePathLibCatPrint (Str, "AcpiEx(%s,", Strings[HidStrIndex]); } else { UefiDevicePathLibCatPrint (Str, "AcpiEx(%s,", HIDText); } - if (AcpiEx->CID == 0) { - UefiDevicePathLibCatPrint (Str, "%s,", CIDStr); + if (Strings[CidStrIndex] != NULL) { + UefiDevicePathLibCatPrint (Str, "%s,", Strings[CidStrIndex]); } else { UefiDevicePathLibCatPrint (Str, "%s,", CIDText); } - if (AcpiEx->UID == 0) { - UefiDevicePathLibCatPrint (Str, "%s)", UIDStr); + if (Strings[UidStrIndex] != NULL) { + UefiDevicePathLibCatPrint (Str, "%s)", Strings[UidStrIndex]); } else { UefiDevicePathLibCatPrint (Str, "0x%x)", AcpiEx->UID); } @@ -584,9 +602,9 @@ DevPathToTextAcpiEx ( HIDText, CIDText, AcpiEx->UID, - HIDStr, - CIDStr, - UIDStr + Strings[HidStrIndex] != NULL ? Strings[HidStrIndex] : '\0', + Strings[CidStrIndex] != NULL ? Strings[CidStrIndex] : '\0', + Strings[UidStrIndex] != NULL ? Strings[UidStrIndex] : '\0' ); } } From 2b7f2890a812eb09dccaa8069483566a3b292338 Mon Sep 17 00:00:00 2001 From: Franco Fichtner Date: Mon, 29 Jul 2024 16:38:00 +0200 Subject: [PATCH 209/213] dummynet: fix pie Since 26b9e1f07fa codel was fixed but traffic was not flowing for pie too. Apply the same fix. MFC after: 1 week Sponsored by: OPNsense Differential Revision: https://reviews.freebsd.org/D46182 Also see: https://redmine.pfsense.org/issues/13996 Also see: https://forum.opnsense.org/index.php?topic=41827.0 Reviewed by: imp, markj Pull Request: https://github.com/freebsd/freebsd-src/pull/1390 --- sys/netpfil/ipfw/dn_sched_fq_pie.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sys/netpfil/ipfw/dn_sched_fq_pie.c b/sys/netpfil/ipfw/dn_sched_fq_pie.c index 632bfd4b7152..06700b0f93af 100644 --- a/sys/netpfil/ipfw/dn_sched_fq_pie.c +++ b/sys/netpfil/ipfw/dn_sched_fq_pie.c @@ -744,6 +744,9 @@ pie_enqueue(struct fq_pie_flow *q, struct mbuf* m, struct fq_pie_si *si) } if (t != DROP) { + if (m->m_pkthdr.rcvif != NULL) + m_rcvif_serialize(m); + mq_append(&q->mq, m); fq_update_stats(q, si, len, 0); return 0; From 3df987c99d1194a0e43a84853e934aa0c0ab09db Mon Sep 17 00:00:00 2001 From: Rick Macklem Date: Fri, 6 Sep 2024 16:41:12 -0700 Subject: [PATCH 210/213] mountd: Add check for "=" after exports(5) options Some exports(5) options take a "=arg" component that provides an argument value for the option. Others do not. Without this patch, if "=arg" was provided for an option that did not take an argument value, the "=arg" was simply ignored. This could result in confusion w.r.t. what was being exported, as noted by the Problem Report. This patch adds a check for "=arg" for the options that do not take an argument value and fails the exports line if one is found. PR: 281003 MFC after: 2 weeks --- usr.sbin/mountd/mountd.c | 44 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 40 insertions(+), 4 deletions(-) diff --git a/usr.sbin/mountd/mountd.c b/usr.sbin/mountd/mountd.c index 00293909614e..00309ed58136 100644 --- a/usr.sbin/mountd/mountd.c +++ b/usr.sbin/mountd/mountd.c @@ -2825,7 +2825,7 @@ do_opt(char **cpp, char **endcpp, struct exportlist *ep, struct grouplist *grp, { char *cpoptarg, *cpoptend; char *cp, *endcp, *cpopt, savedc, savedc2; - int allflag, usedarg; + int allflag, usedarg, fnd_equal; savedc2 = '\0'; cpopt = *cpp; @@ -2836,14 +2836,18 @@ do_opt(char **cpp, char **endcpp, struct exportlist *ep, struct grouplist *grp, while (cpopt && *cpopt) { allflag = 1; usedarg = -2; + fnd_equal = 0; if ((cpoptend = strchr(cpopt, ','))) { *cpoptend++ = '\0'; - if ((cpoptarg = strchr(cpopt, '='))) + if ((cpoptarg = strchr(cpopt, '='))) { *cpoptarg++ = '\0'; + fnd_equal = 1; + } } else { - if ((cpoptarg = strchr(cpopt, '='))) + if ((cpoptarg = strchr(cpopt, '='))) { *cpoptarg++ = '\0'; - else { + fnd_equal = 1; + } else { *cp = savedc; nextfield(&cp, &endcp); **endcpp = '\0'; @@ -2856,6 +2860,10 @@ do_opt(char **cpp, char **endcpp, struct exportlist *ep, struct grouplist *grp, } } if (!strcmp(cpopt, "ro") || !strcmp(cpopt, "o")) { + if (fnd_equal == 1) { + syslog(LOG_ERR, "= after op: %s", cpopt); + return (1); + } *exflagsp |= MNT_EXRDONLY; } else if (cpoptarg && (!strcmp(cpopt, "maproot") || !(allflag = strcmp(cpopt, "mapall")) || @@ -2894,15 +2902,31 @@ do_opt(char **cpp, char **endcpp, struct exportlist *ep, struct grouplist *grp, usedarg++; opt_flags |= OP_NET; } else if (!strcmp(cpopt, "alldirs")) { + if (fnd_equal == 1) { + syslog(LOG_ERR, "= after op: %s", cpopt); + return (1); + } opt_flags |= OP_ALLDIRS; } else if (!strcmp(cpopt, "public")) { + if (fnd_equal == 1) { + syslog(LOG_ERR, "= after op: %s", cpopt); + return (1); + } *exflagsp |= MNT_EXPUBLIC; } else if (!strcmp(cpopt, "webnfs")) { + if (fnd_equal == 1) { + syslog(LOG_ERR, "= after op: %s", cpopt); + return (1); + } *exflagsp |= (MNT_EXPUBLIC|MNT_EXRDONLY|MNT_EXPORTANON); opt_flags |= OP_MAPALL; } else if (cpoptarg && !strcmp(cpopt, "index")) { ep->ex_indexfile = strdup(cpoptarg); } else if (!strcmp(cpopt, "quiet")) { + if (fnd_equal == 1) { + syslog(LOG_ERR, "= after op: %s", cpopt); + return (1); + } opt_flags |= OP_QUIET; } else if (cpoptarg && !strcmp(cpopt, "sec")) { if (parsesec(cpoptarg, ep)) @@ -2910,10 +2934,22 @@ do_opt(char **cpp, char **endcpp, struct exportlist *ep, struct grouplist *grp, opt_flags |= OP_SEC; usedarg++; } else if (!strcmp(cpopt, "tls")) { + if (fnd_equal == 1) { + syslog(LOG_ERR, "= after op: %s", cpopt); + return (1); + } *exflagsp |= MNT_EXTLS; } else if (!strcmp(cpopt, "tlscert")) { + if (fnd_equal == 1) { + syslog(LOG_ERR, "= after op: %s", cpopt); + return (1); + } *exflagsp |= (MNT_EXTLS | MNT_EXTLSCERT); } else if (!strcmp(cpopt, "tlscertuser")) { + if (fnd_equal == 1) { + syslog(LOG_ERR, "= after op: %s", cpopt); + return (1); + } *exflagsp |= (MNT_EXTLS | MNT_EXTLSCERT | MNT_EXTLSCERTUSER); } else { From 7a6309fdc79427b0a7a5c3876daba150d946ae22 Mon Sep 17 00:00:00 2001 From: Eugene Grosbein Date: Sat, 7 Sep 2024 09:14:23 +0700 Subject: [PATCH 211/213] fetch(1): suppress "Not Modified" in quiet mode "fetch -qi" should skip printing "Not Modified" for successful http(s) request. Still print it by default (v_level == 1). MFC after: 1 week --- usr.bin/fetch/fetch.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/usr.bin/fetch/fetch.c b/usr.bin/fetch/fetch.c index 05c0211ead49..8b3ccbd3ab98 100644 --- a/usr.bin/fetch/fetch.c +++ b/usr.bin/fetch/fetch.c @@ -582,16 +582,17 @@ fetch(char *URL, const char *path, int *is_http) if (sigalrm || sigint) goto signal; if (f == NULL) { - warnx("%s: %s", URL, fetchLastErrString); - if (i_flag && (strcmp(url->scheme, SCHEME_HTTP) == 0 || - strcmp(url->scheme, SCHEME_HTTPS) == 0) && - fetchLastErrCode == FETCH_OK && + if (i_flag && *is_http && fetchLastErrCode == FETCH_OK && strcmp(fetchLastErrString, "Not Modified") == 0) { /* HTTP Not Modified Response, return OK. */ + if (v_level > 0) + warnx("%s: %s", URL, fetchLastErrString); r = 0; goto done; - } else + } else { + warnx("%s: %s", URL, fetchLastErrString); goto failure; + } } if (sigint) goto signal; From 5daafa2c2301ad6d5ee0ade9a31ac2c463694a21 Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Sat, 7 Sep 2024 13:25:43 +0200 Subject: [PATCH 212/213] flua: fix buildworld from a clean room now that the flua ucl module is built the lib directory, it is being build at a moment where it cannot link yet to libucl, push libucl in the _prebuild_libs to ensure it is present in a path to be linked against at the time the lua ucl module is being built. While here, remove libucl from boostrap as a dependence of flua as it is not needed anymore now that flua ucl module is dynamically loadable. --- Makefile.inc1 | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Makefile.inc1 b/Makefile.inc1 index a4e2889004b7..edff60cc17ac 100644 --- a/Makefile.inc1 +++ b/Makefile.inc1 @@ -2513,8 +2513,8 @@ ${_bt}-usr.sbin/kldxref: ${_bt_libelf_depend} # 13.0-CURRENT cycle, thus needs to be built on -older releases and stable # branches. .if ${BOOTSTRAPPING} < 1300059 -${_bt}-libexec/flua: ${_bt}-lib/liblua ${_bt}-lib/libucl -_flua= lib/liblua lib/libucl libexec/flua +${_bt}-libexec/flua: ${_bt}-lib/liblua +_flua= lib/liblua libexec/flua .endif # r245440 mtree -N support added @@ -3236,7 +3236,8 @@ _prebuild_libs= ${_kerberos5_lib_libasn1} \ lib/libutil lib/libpjdlog ${_lib_libypclnt} lib/libz lib/msun \ lib/libxo \ ${_secure_lib_libcrypto} ${_secure_lib_libssl} \ - ${_lib_libldns} ${_secure_lib_libssh} + ${_lib_libldns} ${_secure_lib_libssh} \ + lib/libucl .if ${MK_DIALOG} != "no" _prebuild_libs+= gnu/lib/libdialog From 9f0f4e23a584b5aa965aae774bb2dc1e5892d24a Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Sat, 7 Sep 2024 14:19:33 +0200 Subject: [PATCH 213/213] prebuild_libs: register libucl dependency on libm Reported by: Rainer Hurling --- Makefile.inc1 | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile.inc1 b/Makefile.inc1 index edff60cc17ac..ec1db75234b2 100644 --- a/Makefile.inc1 +++ b/Makefile.inc1 @@ -3292,6 +3292,7 @@ _generic_libs+= ${_DIR} lib/libtacplus__L: lib/libmd__L lib/libpam/libpam__L lib/libxo__L: lib/libutil__L +lib/libucl__L: lib/msun__L .if ${MK_CDDL} != "no" _cddl_lib_libumem= cddl/lib/libumem