Thank you for the quick patch, awesome work! One more thing: would it make sense to mention this in the man page for arc4random and getentropy? For context, I’m implementing random number generation in the Rust standard library (see https://github.com/rust-lang/rust/pull/129201), and the library team would quite like to make sure that the system sources we use protect against VM forks (https://github.com/rust-lang/rust/pull/129201#issuecomment-2302563968), so having this as an explicit guarantee on NetBSD would ease some concerns.
|
# HG changeset patch # User Taylor R Campbell <riastradh%NetBSD.org@localhost> # Date 1724594231 0 # Sun Aug 25 13:57:11 2024 +0000 # Branch trunk # Node ID 5be00488683c99f21ab86a2ae2106bacf7f3888a # Parent cf7a8f9687ea781207542c43a006460dc134ea3b # EXP-Topic riastradh-pr58632-vmgenid acpivmgenid(4): New driver for virtual machine generation ID. Added to amd64/ALL and i386/ALL kernel configurations, and made available as a loadable module acpivmgenid.kmod on x86, for now. TBD: Add to all ACPI-supporting GENERIC kernels. PR kern/58632: getentropy(2) and arc4random(3) do not reseed on VM fork diff -r cf7a8f9687ea -r 5be00488683c distrib/sets/lists/man/mi --- a/distrib/sets/lists/man/mi Sat Aug 24 07:24:34 2024 +0000 +++ b/distrib/sets/lists/man/mi Sun Aug 25 13:57:11 2024 +0000 @@ -834,6 +834,7 @@ ./usr/share/man/cat4/acpismbus.0 man-sys-catman .cat ./usr/share/man/cat4/acpitz.0 man-sys-catman .cat ./usr/share/man/cat4/acpivga.0 man-sys-catman .cat +./usr/share/man/cat4/acpivmgenid.0 man-sys-catman .cat ./usr/share/man/cat4/acpiwdrt.0 man-sys-catman .cat ./usr/share/man/cat4/acpiwmi.0 man-sys-catman .cat ./usr/share/man/cat4/adb.0 man-sys-catman .cat @@ -4391,6 +4392,7 @@ ./usr/share/man/man4/acpismbus.4 man-sys-man .man ./usr/share/man/man4/acpitz.4 man-sys-man .man ./usr/share/man/man4/acpivga.4 man-sys-man .man +./usr/share/man/man4/acpivmgenid.4 man-sys-man .man ./usr/share/man/man4/acpiwdrt.4 man-sys-man .man ./usr/share/man/man4/acpiwmi.4 man-sys-man .man ./usr/share/man/man4/adb.4 man-sys-man .man diff -r cf7a8f9687ea -r 5be00488683c distrib/sets/lists/manhtml/mi --- a/distrib/sets/lists/manhtml/mi Sat Aug 24 07:24:34 2024 +0000 +++ b/distrib/sets/lists/manhtml/mi Sun Aug 25 13:57:11 2024 +0000 @@ -755,6 +755,7 @@ ./usr/share/man/html4/acpismbus.html man-sys-htmlman html ./usr/share/man/html4/acpitz.html man-sys-htmlman html ./usr/share/man/html4/acpivga.html man-sys-htmlman html +./usr/share/man/html4/acpivmgenid.html man-sys-htmlman html ./usr/share/man/html4/acpiwdrt.html man-sys-htmlman html ./usr/share/man/html4/acpiwmi.html man-sys-htmlman html ./usr/share/man/html4/adb.html man-sys-htmlman html diff -r cf7a8f9687ea -r 5be00488683c distrib/sets/lists/modules/md.amd64 --- a/distrib/sets/lists/modules/md.amd64 Sat Aug 24 07:24:34 2024 +0000 +++ b/distrib/sets/lists/modules/md.amd64 Sun Aug 25 13:57:11 2024 +0000 @@ -24,6 +24,8 @@ ./@MODULEDIR@/acpiverbose/acpiverbose.kmod modules-base-kernel kmod ./@MODULEDIR@/acpivga modules-base-kernel kmod ./@MODULEDIR@/acpivga/acpivga.kmod modules-base-kernel kmod +./@MODULEDIR@/acpivmgenid modules-base-kernel kmod +./@MODULEDIR@/acpivmgenid/acpivmgenid.kmod modules-base-kernel kmod ./@MODULEDIR@/acpiwdrt modules-base-kernel kmod ./@MODULEDIR@/acpiwdrt/acpiwdrt.kmod modules-base-kernel kmod ./@MODULEDIR@/acpiwmi modules-base-kernel kmod diff -r cf7a8f9687ea -r 5be00488683c distrib/sets/lists/modules/md.i386 --- a/distrib/sets/lists/modules/md.i386 Sat Aug 24 07:24:34 2024 +0000 +++ b/distrib/sets/lists/modules/md.i386 Sun Aug 25 13:57:11 2024 +0000 @@ -24,6 +24,8 @@ ./@MODULEDIR@/acpiverbose/acpiverbose.kmod modules-base-kernel kmod ./@MODULEDIR@/acpivga modules-base-kernel kmod ./@MODULEDIR@/acpivga/acpivga.kmod modules-base-kernel kmod +./@MODULEDIR@/acpivmgenid modules-base-kernel kmod +./@MODULEDIR@/acpivmgenid/acpivmgenid.kmod modules-base-kernel kmod ./@MODULEDIR@/acpiwdrt modules-base-kernel kmod ./@MODULEDIR@/acpiwdrt/acpiwdrt.kmod modules-base-kernel kmod ./@MODULEDIR@/acpiwmi modules-base-kernel kmod diff -r cf7a8f9687ea -r 5be00488683c share/man/man4/Makefile --- a/share/man/man4/Makefile Sat Aug 24 07:24:34 2024 +0000 +++ b/share/man/man4/Makefile Sun Aug 25 13:57:11 2024 +0000 @@ -100,7 +100,8 @@ MAN+= irframe.4 cir.4 irframetty.4 oboe. # ACPI devices MAN+= acpi.4 acpiacad.4 acpibat.4 acpibut.4 acpicpu.4 \ acpidalb.4 acpiec.4 acpifan.4 acpihed.4 acpilid.4 \ - acpipmtr.4 acpismbus.4 acpitz.4 acpivga.4 acpiwdrt.4 acpiwmi.4 + acpipmtr.4 acpismbus.4 acpitz.4 acpivga.4 acpivmgenid.4 \ + acpiwdrt.4 acpiwmi.4 MAN+= apei.4 # Radio devices diff -r cf7a8f9687ea -r 5be00488683c share/man/man4/acpivmgenid.4 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/share/man/man4/acpivmgenid.4 Sun Aug 25 13:57:11 2024 +0000 @@ -0,0 +1,112 @@ +.\" $NetBSD$ +.\" +.\" Copyright (c) 2024 The NetBSD Foundation, Inc. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 August 25, 2024 +.Dt ACPIVMGENID 4 +.Os +.\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +.Sh NAME +.Nm acpivmgenid +.Nd ACPI Virtual Machine Generation ID +.\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +.Sh SYNOPSIS +.Cd "acpivmgenid* at acpi?" +.\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +.Sh DESCRIPTION +.Nm +provides a generation ID for virtual machines. +.Pp +When starting two otherwise identical virtual machines, whether from +the same clean image or by cloning snapshots or any other mechanism, +the VM host may choose a different generation ID. +Although this generation ID is not secret, it is incorporated into the +.Xr entropy 7 +pool (with a measure of zero entropy) so that the two virtual machines +will produce independent random output. +.Pp +If a live VM is cloned, the VM host may change the generation ID in one +or both of the clones and notify them through the +.Nm +device. +When this happens, +.Nx +will reseed system random number generators, so that output of +.Pa /dev/urandom +and +.Xr getentropy 3 +will be independent in the two clones. +.\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +.Sh SYSCTLS +The following +.Xr sysctl 7 +nodes are available: +.Bl -tag -width Li +.It Li "hw.acpivmgenid" Ns Va N Ns Li ".id" +The current 16-byte VM generation ID. +.It Li "hw.acpivmgenid" Ns Va N Ns Li ".paddr" +The physical address of the VM generation ID provided by the host. +.El +.\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +.Sh SEE ALSO +.Xr arc4random 3 , +.Xr getentropy 3 , +.Xr rnd 4 , +.Xr entropy 7 +.Rs +.%T Virtual Machine Generation ID +.%Q Microsoft +.%D 2018-08-01 +.%U http://go.microsoft.com/fwlink/?LinkId=260709 +.Re +.Rs +.%T Virtual Machine Generation ID Device +.%Q The QEMU Project Developers +.%U https://www.qemu.org/docs/master/specs/vmgenid.html +.Re +.\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +.Sh HISTORY +The +.Nm +driver first appeared in +.Nx 11.0 . +.\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +.Sh BUGS +Currently +.Nx +does not request fresh samples from all on-demand entropy sources when +the VM generation ID changes, so although the outputs of the system +entropy pool appear independent to an outside observer, disclosing the +kernel memory of one VM clone to an adversary may allow the adversary +to predict another VM clone's +.Pa /dev/urandom +outputs. +.Pp +Currently +.Xr arc4random 3 +is not reseeded when the VM generation ID changes. +.Pp +Currently there is no cheaper way to detect VM generation ID changes +than to query sysctl. diff -r cf7a8f9687ea -r 5be00488683c sys/arch/amd64/conf/ALL --- a/sys/arch/amd64/conf/ALL Sat Aug 24 07:24:34 2024 +0000 +++ b/sys/arch/amd64/conf/ALL Sun Aug 25 13:57:11 2024 +0000 @@ -381,6 +381,7 @@ acpismbus* at acpi? # ACPI SMBus CMI (e acpitz* at acpi? # ACPI Thermal Zone acpivga* at acpi? # ACPI Display Adapter acpiout* at acpivga? # ACPI Display Output Device +acpivmgenid* at acpi? # ACPI Virtual Machine Generation ID acpiwdrt* at acpi? # ACPI Watchdog Resource Table acpiwmi* at acpi? # ACPI WMI Mapper apei* at apeibus? # ACPI Platform Error Interfaces diff -r cf7a8f9687ea -r 5be00488683c sys/arch/i386/conf/ALL --- a/sys/arch/i386/conf/ALL Sat Aug 24 07:24:34 2024 +0000 +++ b/sys/arch/i386/conf/ALL Sun Aug 25 13:57:11 2024 +0000 @@ -368,6 +368,7 @@ acpismbus* at acpi? # ACPI SMBus CMI (e acpitz* at acpi? # ACPI Thermal Zone acpivga* at acpi? # ACPI Display Adapter acpiout* at acpivga? # ACPI Display Output Device +acpivmgenid* at acpi? # ACPI Virtual Machine Generation ID acpiwdrt* at acpi? # ACPI Watchdog Resource Table acpiwmi* at acpi? # ACPI WMI Mapper apei* at apeibus? # ACPI Platform Error Interfaces diff -r cf7a8f9687ea -r 5be00488683c sys/dev/acpi/acpi_vmgenid.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sys/dev/acpi/acpi_vmgenid.c Sun Aug 25 13:57:11 2024 +0000 @@ -0,0 +1,346 @@ +/* $NetBSD$ */ + +/*- + * Copyright (c) 2024 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + */ + +/* + * Virtual Machine Generation ID + * + * The VMGENID is an 8-byte cookie shared between a VM host and VM + * guest. Whenever the host clones a VM, it changes the VMGENID + * and sends an ACPI notification to the guest. + * + * References: + * + * `Virtual Machine Generation ID', Microsoft, 2012-08-01. + * http://go.microsoft.com/fwlink/?LinkId=260709 + * + * `Virtual Machine Generation ID Device', The QEMU Project + * Developers. + * https://www.qemu.org/docs/master/specs/vmgenid.html + */ + +#include <sys/cdefs.h> +__KERNEL_RCSID(0, "$NetBSD$"); + +#include <sys/device.h> +#include <sys/entropy.h> +#include <sys/module.h> +#include <sys/rndsource.h> +#include <sys/sysctl.h> + +#include <dev/acpi/acpireg.h> +#include <dev/acpi/acpivar.h> + +#define _COMPONENT ACPI_RESOURCE_COMPONENT +ACPI_MODULE_NAME ("acpi_vmgenid") + +struct acpivmgenid { + uint8_t id[16]; +} __aligned(8); + +struct acpivmgenid_softc { + device_t sc_dev; + struct acpi_devnode *sc_node; + uint64_t sc_paddr; + struct acpivmgenid *sc_vaddr; + struct acpivmgenid sc_cur; + struct krndsource sc_rndsource; + struct sysctllog *sc_sysctllog; + const struct sysctlnode *sc_sysctlroot; +}; + +static int acpivmgenid_match(device_t, cfdata_t, void *); +static void acpivmgenid_attach(device_t, device_t, void *); +static int acpivmgenid_detach(device_t, int); +static void acpivmgenid_set(struct acpivmgenid_softc *, const char *); +static void acpivmgenid_notify(ACPI_HANDLE, uint32_t, void *); +static void acpivmgenid_reset(void *); +static int acpivmgenid_sysctl(SYSCTLFN_ARGS); + +static const struct device_compatible_entry compat_data[] = { + { .compat = "VM_Gen_Counter" }, /* from the Microsoft spec */ + { .compat = "VM_GEN_COUNTER" }, /* used by qemu */ + { .compat = "VMGENCTR" }, /* recognized by Linux */ + DEVICE_COMPAT_EOL +}; + +CFATTACH_DECL_NEW(acpivmgenid, sizeof(struct acpivmgenid_softc), + acpivmgenid_match, acpivmgenid_attach, acpivmgenid_detach, NULL); + +static int +acpivmgenid_match(device_t parent, cfdata_t match, void *aux) +{ + const struct acpi_attach_args *const aa = aux; + + return acpi_compatible_match(aa, compat_data); +} + +static void +acpivmgenid_attach(device_t parent, device_t self, void *aux) +{ + struct acpivmgenid_softc *const sc = device_private(self); + const struct acpi_attach_args *const aa = aux; + ACPI_BUFFER addrbuf = { + .Pointer = NULL, + .Length = ACPI_ALLOCATE_BUFFER, + }; + ACPI_OBJECT *addrobj, *addrarr; + ACPI_STATUS rv; + int error; + + aprint_naive(": ACPI VM Generation ID\n"); + aprint_normal(": ACPI VM Generation ID\n"); + + sc->sc_dev = self; + sc->sc_node = aa->aa_node; + + /* + * Get the address from the ADDR object, which is a package of + * two 32-bit integers representing the low and high halves of + * a 64-bit physical address. + */ + rv = AcpiEvaluateObjectTyped(sc->sc_node->ad_handle, "ADDR", NULL, + &addrbuf, ACPI_TYPE_PACKAGE); + if (ACPI_FAILURE(rv)) { + aprint_error_dev(self, "failed to get ADDR: %s\n", + AcpiFormatException(rv)); + goto out; + } + addrobj = addrbuf.Pointer; + if (addrobj->Type != ACPI_TYPE_PACKAGE || + addrobj->Package.Count != 2) { + aprint_error_dev(self, "invalid ADDR\n"); + goto out; + } + addrarr = addrobj->Package.Elements; + if (addrarr[0].Type != ACPI_TYPE_INTEGER || + addrarr[1].Type != ACPI_TYPE_INTEGER || + addrarr[0].Integer.Value > UINT32_MAX || + addrarr[1].Integer.Value > UINT32_MAX) { + aprint_error_dev(self, "invalid ADDR\n"); + goto out; + } + sc->sc_paddr = (ACPI_PHYSICAL_ADDRESS)addrarr[0].Integer.Value; + sc->sc_paddr |= (ACPI_PHYSICAL_ADDRESS)addrarr[1].Integer.Value << 32; + aprint_normal_dev(self, "paddr=0x%"PRIx64"\n", (uint64_t)sc->sc_paddr); + + /* + * Map the physical address into virtual address space. + */ + sc->sc_vaddr = AcpiOsMapMemory(sc->sc_paddr, sizeof(*sc->sc_vaddr)); + if (sc->sc_vaddr == NULL) { + aprint_error_dev(self, "failed to map address\n"); + goto out; + } + + /* + * Register a random source so we can attribute samples. + */ + rnd_attach_source(&sc->sc_rndsource, device_xname(self), + RND_TYPE_UNKNOWN, RND_FLAG_COLLECT_TIME|RND_FLAG_COLLECT_VALUE); + + /* + * Register an ACPI notifier so that we can detect changes. + */ + (void)acpi_register_notify(sc->sc_node, acpivmgenid_notify); + + /* + * Now that we have registered a random source and a notifier, + * read out the first value. + */ + acpivmgenid_set(sc, "initial"); + + /* + * Attach a sysctl tree, rooted at hw.acpivmgenidN. + */ + error = sysctl_createv(&sc->sc_sysctllog, 0, NULL, &sc->sc_sysctlroot, + CTLFLAG_PERMANENT, CTLTYPE_NODE, device_xname(self), + SYSCTL_DESCR("Virtual Machine Generation ID device"), + NULL, 0, NULL, 0, + CTL_HW, CTL_CREATE, CTL_EOL); + if (error) { + aprint_error_dev(self, "failed to create sysctl hw.%s: %d\n", + device_xname(self), error); + goto out; + } + + /* + * hw.acpivmgenidN.id (`struct', 16-byte array) + */ + error = sysctl_createv(&sc->sc_sysctllog, 0, &sc->sc_sysctlroot, NULL, + CTLFLAG_PERMANENT|CTLFLAG_READONLY|CTLFLAG_PRIVATE, CTLTYPE_STRUCT, + "id", SYSCTL_DESCR("Virtual Machine Generation ID device"), + &acpivmgenid_sysctl, 0, sc, sizeof(struct acpivmgenid), + CTL_CREATE, CTL_EOL); + if (error) { + aprint_error_dev(self, + "failed to create sysctl hw.%s.id: %d\n", + device_xname(self), error); + goto out; + } + + /* + * hw.acpivmgenidN.paddr (64-bit integer) + */ + __CTASSERT(sizeof(ACPI_PHYSICAL_ADDRESS) == sizeof(long)); + error = sysctl_createv(&sc->sc_sysctllog, 0, &sc->sc_sysctlroot, NULL, + CTLFLAG_PERMANENT|CTLFLAG_READONLY|CTLFLAG_PRIVATE, CTLTYPE_LONG, + "paddr", SYSCTL_DESCR("Virtual Machine Generation ID device"), + NULL, 0, &sc->sc_paddr, sizeof(sc->sc_paddr), + CTL_CREATE, CTL_EOL); + if (error) { + aprint_error_dev(self, + "failed to create sysctl hw.%s.paddr: %d\n", + device_xname(self), error); + goto out; + } + +out: ACPI_FREE(addrbuf.Pointer); +} + +static int +acpivmgenid_detach(device_t self, int flags) +{ + struct acpivmgenid_softc *const sc = device_private(self); + int error; + + error = config_detach_children(self, flags); + if (error) + return error; + + sysctl_teardown(&sc->sc_sysctllog); + acpi_deregister_notify(sc->sc_node); + rnd_detach_source(&sc->sc_rndsource); + if (sc->sc_vaddr) { + AcpiOsUnmapMemory(sc->sc_vaddr, sizeof(*sc->sc_vaddr)); + sc->sc_vaddr = NULL; /* paranoia */ + } + sc->sc_paddr = 0; /* paranoia */ + + return 0; +} + +static void +acpivmgenid_set(struct acpivmgenid_softc *sc, const char *prefix) +{ + struct acpivmgenid vmgenid; + char vmgenidstr[2*__arraycount(vmgenid.id) + 1]; + unsigned i; + + /* + * Grab the current VM generation ID. No obvious way to make + * this atomic, so let's hope if it changes in the middle we'll + * get another notification. + */ + memcpy(&vmgenid, sc->sc_vaddr, sizeof(vmgenid)); + + /* + * Print the VM generation ID to the console for posterity. + */ + for (i = 0; i < __arraycount(vmgenid.id); i++) { + vmgenidstr[2*i] = "0123456789abcdef"[vmgenid.id[i] >> 4]; + vmgenidstr[2*i + 1] = "0123456789abcdef"[vmgenid.id[i] & 0xf]; + } + vmgenidstr[2*sizeof(vmgenid)] = '\0'; + aprint_verbose_dev(sc->sc_dev, "%s: %s\n", prefix, vmgenidstr); + + /* + * Enter the new VM generation ID into the entropy pool. + */ + rnd_add_data(&sc->sc_rndsource, &vmgenid, sizeof(vmgenid), 0); +} + +static void +acpivmgenid_notify(ACPI_HANDLE hdl, uint32_t notify, void *opaque) +{ + const device_t self = opaque; + struct acpivmgenid_softc *const sc = device_private(self); + + if (notify != 0x80) { + aprint_debug_dev(self, "unknown notify 0x%02x\n", notify); + return; + } + + (void)AcpiOsExecute(OSL_NOTIFY_HANDLER, &acpivmgenid_reset, sc); +} + +static void +acpivmgenid_reset(void *cookie) +{ + struct acpivmgenid_softc *const sc = cookie; + + /* + * Grab the current VM generation ID to put it into the entropy + * pool; then force consolidation so it affects all subsequent + * draws from the entropy pool and the entropy epoch advances. + * + * XXX This should also reset the entropy count and request new + * samples from all sources, but there currently isn't a good + * way to do that after boot. + */ + acpivmgenid_set(sc, "cloned"); + entropy_consolidate(); +} + +static int +acpivmgenid_sysctl(SYSCTLFN_ARGS) +{ + struct sysctlnode node = *rnode; + struct acpivmgenid_softc *const sc = node.sysctl_data; + + node.sysctl_data = sc->sc_vaddr; + return sysctl_lookup(SYSCTLFN_CALL(&node)); +} + +MODULE(MODULE_CLASS_DRIVER, acpivmgenid, NULL); + +#ifdef _MODULE +#include "ioconf.c" +#endif + +static int +acpivmgenid_modcmd(modcmd_t cmd, void *opaque) +{ + int error = 0; + + switch (cmd) { + case MODULE_CMD_INIT: +#ifdef _MODULE + error = config_init_component(cfdriver_ioconf_acpivmgenid, + cfattach_ioconf_acpivmgenid, cfdata_ioconf_acpivmgenid); +#endif + return error; + case MODULE_CMD_FINI: +#ifdef _MODULE + error = config_fini_component(cfdriver_ioconf_acpivmgenid, + cfattach_ioconf_acpivmgenid, cfdata_ioconf_acpivmgenid); +#endif + return error; + default: + return ENOTTY; + } +} diff -r cf7a8f9687ea -r 5be00488683c sys/dev/acpi/files.acpi --- a/sys/dev/acpi/files.acpi Sat Aug 24 07:24:34 2024 +0000 +++ b/sys/dev/acpi/files.acpi Sun Aug 25 13:57:11 2024 +0000 @@ -116,6 +116,11 @@ device acpicppc: acpipcc attach acpicppc at acpinodebus file dev/acpi/acpi_cppc.c acpicppc +# ACPI Virtual Machine Generation ID +device acpivmgenid +attach acpivmgenid at acpinodebus +file dev/acpi/acpi_vmgenid.c acpivmgenid + # ACPI Platform Error Interface device apei attach apei at apeibus diff -r cf7a8f9687ea -r 5be00488683c sys/modules/Makefile --- a/sys/modules/Makefile Sat Aug 24 07:24:34 2024 +0000 +++ b/sys/modules/Makefile Sun Aug 25 13:57:11 2024 +0000 @@ -298,6 +298,7 @@ SUBDIR+= acpilid SUBDIR+= acpipmtr SUBDIR+= acpitz SUBDIR+= acpivga +SUBDIR+= acpivmgenid SUBDIR+= acpiwdrt SUBDIR+= acpiwmi SUBDIR+= aibs diff -r cf7a8f9687ea -r 5be00488683c sys/modules/acpivmgenid/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sys/modules/acpivmgenid/Makefile Sun Aug 25 13:57:11 2024 +0000 @@ -0,0 +1,11 @@ +# $NetBSD$ + +.include "../Makefile.inc" + +.PATH: ${S}/dev/acpi + +KMOD= acpivmgenid +IOCONF= acpivmgenid.ioconf +SRCS= acpi_vmgenid.c + +.include <bsd.kmodule.mk> diff -r cf7a8f9687ea -r 5be00488683c sys/modules/acpivmgenid/acpivmgenid.ioconf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sys/modules/acpivmgenid/acpivmgenid.ioconf Sun Aug 25 13:57:11 2024 +0000 @@ -0,0 +1,10 @@ +# $NetBSD$ + +ioconf acpivmgenid + +include "conf/files" +include "dev/acpi/files.acpi" + +pseudo-root acpi* + +acpivmgenid* at acpi? # HG changeset patch # User Taylor R Campbell <riastradh%NetBSD.org@localhost> # Date 1724594459 0 # Sun Aug 25 14:00:59 2024 +0000 # Branch trunk # Node ID 1209429d9c2f1be453574307f2a1b7021ff1bfbd # Parent 5be00488683c99f21ab86a2ae2106bacf7f3888a # EXP-Topic riastradh-pr58632-vmgenid amd64, evbarm, i386: Add acpivmgenid(4) to GENERIC. PR kern/58632: getentropy(2) and arc4random(3) do not reseed on VM fork diff -r 5be00488683c -r 1209429d9c2f sys/arch/amd64/conf/GENERIC --- a/sys/arch/amd64/conf/GENERIC Sun Aug 25 13:57:11 2024 +0000 +++ b/sys/arch/amd64/conf/GENERIC Sun Aug 25 14:00:59 2024 +0000 @@ -341,6 +341,7 @@ acpilid* at acpi? # ACPI Lid Switch acpitz* at acpi? # ACPI Thermal Zone acpivga* at acpi? # ACPI Display Adapter acpiout* at acpivga? # ACPI Display Output Device +acpivmgenid* at acpi? # ACPI Virtual Machine Generation ID acpiwdrt* at acpi? # ACPI Watchdog Resource Table acpiwmi* at acpi? # ACPI WMI Mapper apei* at apeibus? # ACPI Platform Error Interfaces diff -r 5be00488683c -r 1209429d9c2f sys/arch/evbarm/conf/GENERIC64 --- a/sys/arch/evbarm/conf/GENERIC64 Sun Aug 25 13:57:11 2024 +0000 +++ b/sys/arch/evbarm/conf/GENERIC64 Sun Aug 25 14:00:59 2024 +0000 @@ -127,6 +127,7 @@ acpifan* at acpi? acpiged* at acpi? acpilid* at acpi? acpitz* at acpi? +acpivmgenid* at acpi? # CPUs cpus* at fdt? pass 0 diff -r 5be00488683c -r 1209429d9c2f sys/arch/i386/conf/GENERIC --- a/sys/arch/i386/conf/GENERIC Sun Aug 25 13:57:11 2024 +0000 +++ b/sys/arch/i386/conf/GENERIC Sun Aug 25 14:00:59 2024 +0000 @@ -324,6 +324,7 @@ acpilid* at acpi? # ACPI Lid Switch acpitz* at acpi? # ACPI Thermal Zone acpivga* at acpi? # ACPI Display Adapter acpiout* at acpivga? # ACPI Display Output Device +acpivmgenid* at acpi? # ACPI Virtual Machine Generation ID acpiwdrt* at acpi? # ACPI Watchdog Resource Table acpiwmi* at acpi? # ACPI WMI Mapper apei* at apeibus? # ACPI Platform Error Interfaces