The prior commit moved the order of initializing driver_data around. In
looking through the tree at what is normally done, it appears that
actually few drivers set or get driver_data directly, but instead go
through the dev_set/get_drvdata helpers, which are simple inline helpers
that amount to the same exact code. So, for the sake of consistency, use
the helpers.
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Both probe paths register their notification handler before assigning
driver_data, which the handler dereferences.
In the devicetree path, the notification IRQ can fire as soon as
devm_request_irq() registers the handler: the interrupt may already be
pending at probe time, for example when a VMM injects the
generation-changed notification while restoring a guest from a snapshot
that was taken before the driver had probed (Firecracker does exactly
this on snapshot restore). The IRQ is also requested with IRQF_SHARED,
so another device sharing the line can trigger the handler just as
early. The handler then calls vmgenid_notify(), which dereferences the
still-NULL driver_data and panics:
Unable to handle kernel NULL pointer dereference at virtual address 0000000000000010
CPU: 0 UID: 0 PID: 1 Comm: swapper/0 Not tainted 6.18.38+ #1 PREEMPT(none)
Hardware name: linux,dummy-virt (DT)
pc : vmgenid_notify.isra.0+0x24/0x8c
lr : vmgenid_of_irq_handler+0x14/0x34
Call trace:
vmgenid_notify.isra.0+0x24/0x8c (P)
vmgenid_of_irq_handler+0x14/0x34
__handle_irq_event_percpu+0x44/0x1bc
handle_irq_event+0x4c/0xb4
handle_fasteoi_irq+0xf8/0x1f8
The ACPI path has the same ordering problem: the handler is installed
with acpi_install_notify_handler() before driver_data is assigned.
ACPI notifications are dispatched asynchronously from a workqueue, so
the window is narrow, but a notification arriving between the two calls
hits the same NULL dereference.
Assign driver_data before registering the handlers. The state is fully
initialized at that point, so the handlers are safe to run. Should
registration fail, the probe error path leaves no dangling pointer
behind: the driver core clears driver_data in device_unbind_cleanup().
Fixes: 7b1bcd6b50 ("virt: vmgenid: add support for devicetree bindings")
Fixes: e07606713a ("virt: vmgenid: change implementation to use a platform driver")
Cc: stable@vger.kernel.org
Signed-off-by: Zhichen Wang <wangzhichen@manus.ai>
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
It was found that AWS SEV-SNP enabled instances are not able to boot with
commit 81256a50aa ("x86/mm: Make memremap(MEMREMAP_WB) map memory as
encrypted by default") applied and the reason seems to be the vmgenid
device which requires unencrypted writeable memory.
A similar problem was previously fixed in DRM with commit
7dfede7d7e ("drm/vmwgfx: Fix guests running with TDX/SEV").
Note, trusting vmgenid device in a Confidential VM is questionable: the
malicious host may intentionally avoid notifying the guest when a copy is
created.
Fixes: 81256a50aa ("x86/mm: Make memremap(MEMREMAP_WB) map memory as encrypted by default")
Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
Cc: stable@vger.kernel.org # 6.15+
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Extend the vmgenid platform driver to support devicetree bindings. With
this support, hypervisors can send vmgenid notifications to the virtual
machine without the need to enable ACPI. The bindings are located at:
Documentation/devicetree/bindings/rng/microsoft,vmgenid.yaml
Since this is no longer ACPI-dependent, remove the dependency from
Kconfig and protect the ACPI code with a single ifdef.
Signed-off-by: Sudan Landge <sudanl@amazon.com>
Reviewed-by: Alexander Graf <graf@amazon.com>
Tested-by: Babis Chalios <bchalios@amazon.es>
[Jason: - Small style cleanups and refactoring.
- Re-work ACPI conditionalization. ]
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Re-implement vmgenid as a platform driver in preparation for adding
devicetree bindings support in next commits.
Signed-off-by: Sudan Landge <sudanl@amazon.com>
Reviewed-by: Alexander Graf <graf@amazon.com>
Tested-by: Babis Chalios <bchalios@amazon.es>
[Jason: - Small style cleanups and refactoring.]
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
This reverts commit ad6bcdad2b. I had
nak'd it, and Greg said on the thread that it links that he wasn't going
to take it either, especially since it's not his code or his tree, but
then, seemingly accidentally, it got pushed up some months later, in
what looks like a mistake, with no further discussion in the linked
thread. So revert it, since it's clearly not intended.
Fixes: ad6bcdad2b ("vmgenid: emit uevent when VMGENID updates")
Cc: stable@vger.kernel.org
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Link: https://lore.kernel.org/r/20230531095119.11202-2-bchalios@amazon.es
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
We receive an ACPI notification every time the VM Generation ID changes
and use the new ID as fresh randomness added to the entropy pool. This
commits emits a uevent every time we receive the ACPI notification, as a
means to notify the user space that it now is in a new VM.
Signed-off-by: Babis Chalios <bchalios@amazon.es>
Reviewed-by: Alexander Graf <graf@amazon.com>
Reviewed-by: Lennart Poettering <mzxreary@0pointer.de>
Link: https://lore.kernel.org/r/20230531095119.11202-2-bchalios@amazon.es
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
In the Windows spec for VM Generation ID, the originally specified CID
is longer than allowed by the ACPI spec. Hyper-V has added "VMGENCTR" as
a second valid CID that is conformant, while retaining the original CID
for compatibility with Windows guests.
Add this new CID to the list recognized by the driver.
Signed-off-by: Michael Kelley <mikelley@microsoft.com>
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
VM Generation ID is a feature from Microsoft, described at
<https://go.microsoft.com/fwlink/?LinkId=260709>, and supported by
Hyper-V and QEMU. Its usage is described in Microsoft's RNG whitepaper,
<https://aka.ms/win10rng>, as:
If the OS is running in a VM, there is a problem that most
hypervisors can snapshot the state of the machine and later rewind
the VM state to the saved state. This results in the machine running
a second time with the exact same RNG state, which leads to serious
security problems. To reduce the window of vulnerability, Windows
10 on a Hyper-V VM will detect when the VM state is reset, retrieve
a unique (not random) value from the hypervisor, and reseed the root
RNG with that unique value. This does not eliminate the
vulnerability, but it greatly reduces the time during which the RNG
system will produce the same outputs as it did during a previous
instantiation of the same VM state.
Linux has the same issue, and given that vmgenid is supported already by
multiple hypervisors, we can implement more or less the same solution.
So this commit wires up the vmgenid ACPI notification to the RNG's newly
added add_vmfork_randomness() function.
It can be used from qemu via the `-device vmgenid,guid=auto` parameter.
After setting that, use `savevm` in the monitor to save the VM state,
then quit QEMU, start it again, and use `loadvm`. That will trigger this
driver's notify function, which hands the new UUID to the RNG. This is
described in <https://git.qemu.org/?p=qemu.git;a=blob;f=docs/specs/vmgenid.txt>.
And there are hooks for this in libvirt as well, described in
<https://libvirt.org/formatdomain.html#general-metadata>.
Note, however, that the treatment of this as a UUID is considered to be
an accidental QEMU nuance, per
<https://github.com/libguestfs/virt-v2v/blob/master/docs/vm-generation-id-across-hypervisors.txt>,
so this driver simply treats these bytes as an opaque 128-bit binary
blob, as per the spec. This doesn't really make a difference anyway,
considering that's how it ends up when handed to the RNG in the end.
Cc: Alexander Graf <graf@amazon.com>
Cc: Adrian Catangiu <adrian@parity.io>
Cc: Daniel P. Berrangé <berrange@redhat.com>
Cc: Dominik Brodowski <linux@dominikbrodowski.net>
Cc: Wei Yongjun <weiyongjun1@huawei.com>
Tested-by: Souradeep Chakrabarti <souradch.linux@gmail.com> # With Hyper-V's virtual hardware
Reviewed-by: Ard Biesheuvel <ardb@kernel.org>
Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>