Commit Graph

1153 Commits

Author SHA1 Message Date
Rob Bradford
660b18eaac vmm: Clean up seccomp handling for glibc overcommit sysctl
Unfortunately glibc can read the overcommit sysctl from any thread. This
has lead to us adding a patchwork of openat/read syscalls to our allow
list when those threads don't necessarily need openat for their actual
uses.

Only the VMM and migration worker thread have a strict requirement for
the openat syscall. The syscall was added to the other threads to deal
with this glibc behaviour.

As read() is itself harmless move it to the common syscalls, strip
full openat() from all but the threads that need it and add limited,
read only, openat to all threads.

Signed-off-by: Rob Bradford <rbradford@meta.com>
2026-07-29 10:25:42 +00:00
Lily Goscha
8bd96078a9 virtio-devices: Release vsock local ports only to their owner
The vsock muxer tracked host-allocated local ports in a set, and
`remove_connection()` released `key.local_port` from it for every
connection it removed. Only host-initiated connections take their local
port from `allocate_local_port()`, though: guest-initiated ones use the
guest-chosen `dst_port` verbatim, and never hold an allocation.

Removal was therefore able to release a port its connection did not own.
A guest-initiated connection whose destination port collides with a
host-allocated ephemeral port dropped that port from the allocator's
free list on teardown, while the host-initiated connection that owned it
was still live and using it. The allocator could then hand the same port
out twice.

Track the owning peer (guest) port alongside each allocation, and
release an allocation only when the connection being removed matches the
recorded owner. Guest-initiated connections never match, so they can no
longer disturb host-side port accounting.

Reaching this from the guest additionally requires a host process
listening on the AF_UNIX path for a port in the host ephemeral range,
which is not how host services are normally deployed. Hitting the
duplicate allocation would further require the allocator to wrap its
~2^30 port range. This is a correctness fix rather than a fix for a
practically exploitable issue.

Add a regression test that drives the muxer through the colliding-port
sequence and checks the host connection keeps its allocation.

Signed-off-by: Lily Goscha <lilygoscha@gmail.com>
2026-07-24 23:02:06 +00:00
Sebastien Boeuf
b47c26fa56 virtio-devices: Resume vhost-user devices after snapshot
For vhost-user devices, a snapshot involved the vrings to be stopped,
but they couldn't be resumed. This commit aims at fixing this by saving
the vrings base so that it can be safely reset after the snapshot has
succeeded.

This will allow VMs where snapshots are taken from internal CH
implementation and from an offload daemon to be resumed once the
snapshot is complete.

Signed-off-by: Sebastien Boeuf <sboeuf@meta.com>
Assisted-by: Claude:claude-opus-4-8
2026-07-24 16:40:39 +00:00
Yi Wang
e0f2d99d6f virtio-devices: Test sparse queue indices on resume
Filtered activation queues can hide regressions where resume treats
their positions as transport queue indices. Such regressions route
interrupts to unrelated MSI-X vectors while eventfd notifications still
reach the correct workers.

Add a VirtioCommon regression test with queue indices one and three.
Verify resume signals both queue eventfds and records interrupts for the
original sparse indices.

Assisted-by: OpenAI:GPT-5.6-Sol
Signed-off-by: Yi Wang <foxywang@tencent.com>
2026-07-23 12:00:11 +00:00
Yi Wang
e4f0744521 virtio-devices: Preserve queue indices across resume
VirtioCommon stores only activated queue eventfds, so filtered queues
are renumbered when resume injects interrupts. A sparse queue set can
therefore wake the wrong MSI-X vectors and leave completed requests
stalled after restore.

Retain each queue index alongside its eventfd during activate(). Use
the saved index for resume interrupts so each notification reaches the
queue's original vector.

Assisted-by: OpenAI:GPT-5.6-Sol
Signed-off-by: Yi Wang <foxywang@tencent.com>
2026-07-23 12:00:11 +00:00
Peter Delevoryas
d3d83dcbd8 virtio-devices: Retry complete vhost-user reconnect
A Unix stream connection can succeed while the process owning the
listener is exiting. The resulting connection can then fail during
SET_OWNER, GET_FEATURES, or later reinitialization.

Retry the complete connect and reinitialization transaction when it
returns a transport failure within a 60-second retry window. Each retry
uses a fresh frontend. Connection errors retain their existing handling,
non-transport errors fail immediately, and waits remain interruptible by
the worker kill event.

Signed-off-by: Peter Delevoryas <pdel@meta.com>
Assisted-by: Codex:GPT-5
2026-07-23 07:11:33 +00:00
Rob Bradford
eaabb0e1ec virtio-devices: balloon: Fix use of usize for virtio queue index
This should be a u16 for consistency (as the number of queues is limited
to u16).

Signed-off-by: Rob Bradford <rbradford@meta.com>
2026-07-22 19:11:11 +00:00
Rob Bradford
5f86e58775 virtio-devices: Use u16 for the queue index
The number of queues is limited to a u16 so this most consistent. The
vm-virtio crate API unfortunately uses usize but its safe to convert up
from u16 to usize.

Signed-off-by: Rob Bradford <rbradford@meta.com>
2026-07-22 19:11:11 +00:00
Alyssa Ross
cd2089eb69 build: Bump vm-memory and dependents
vm-memory 0.18 has renamed GuestMemory to GuestMemoryBackend, and made
GuestMemory refer to something less specific.  For simplicity, we keep
using GuestMemoryBackend (formerly GuestMemory) everywhere for now.  We
can adjust bounds to be less specific later if we find ourselves needing
the newly enabled flexibility.

Signed-off-by: Alyssa Ross <hi@alyssa.is>
Signed-off-by: Rob Bradford <rbradford@meta.com>
2026-07-20 17:51:23 +00:00
CMGS
b68e7f3d91 block: flush cached qcow2 metadata on device pause
The qcow2 backend caches L2 table and refcount updates in memory and
only writes them back on a guest-initiated flush, clean shutdown or
drop. A paused VM therefore leaves the on-disk image without the
mappings for any cluster allocated since the last guest flush: the
data clusters are present in the file, but nothing references them.

Anything that reads the image while the VM is paused sees those
writes as missing. Copying the disk alongside vm.snapshot (the
documented snapshot workflow) captures a stale image, and live
migration releases the disk locks after pausing so the destination
reopens the file with the same stale metadata. In both cases writes
the guest has completed, and may later read back, silently disappear.

Add a MetadataSync capability trait with a no-op default, fold it
into FullDiskFile, implement it for the qcow2 backend as a metadata
cache flush, and call it from the virtio-block pause path after
in-flight requests have drained. Pause is the quiesce point both
flows rely on, and it is a cold path, so the extra flush does not
affect runtime I/O.

Reproduced by writing to a qcow2 disk from the guest with O_DIRECT
and no explicit flush, pausing the VM and copying the image: qemu-img
map on the copy shows no mapped clusters and reads return zeros. With
this change the copy contains every completed write. A unit test
covers the same sequence at the format level: a completed write is
invisible to a fresh reader until sync_metadata, and visible after.

Signed-off-by: CMGS <ilskdw@gmail.com>
2026-07-19 18:26:37 +00:00
Peter Delevoryas
5b68d7694d virtio-devices: Replay in-order vhost-user queues after reconnect
When reconnecting to a vhost-user backend, Cloud Hypervisor keeps the
same queues and currently restarts them from avail_idx.

That can skip descriptors that were made available by the guest but not
completed before the old backend crashed. For queues where
VIRTIO_F_IN_ORDER was negotiated, used_idx is a safe completion
boundary, so reconnect can resume from used_idx and kick the queue if
work remains.

Do not do this when inflight tracking is active, because the backend
inflight state is the more precise recovery mechanism. Also leave queues
without VIRTIO_F_IN_ORDER on the existing avail_idx path, since used_idx
does not identify which descriptors completed for out-of-order devices.

Signed-off-by: Peter Delevoryas <pdel@meta.com>
2026-07-18 19:18:40 +00:00
Chinmoy
c070d5dfa4 virtio-devices: Abort vhost-user client connect on kill_evt
Client connect retried for a full minute on every failure and did not
watch kill_evt for early exit, unlike reconnect, so teardown and
permanent connect errors both stalled for CONNECT_TIMEOUT.

Update the client path to watch kill_evt for early abort, fail
non-retryable errors immediately, and surface timeout with a dedicated
error.

Partially Fixes #8052

Signed-off-by: Chinmoy <daschinmoyy21@gmail.com>
Assisted-by: GLM 5.2
2026-07-18 18:52:28 +00:00
Sebastien Boeuf
e37f63282c net_util: Only set host MAC address from user input
In case the host MAC address associated with a TAP device wasn't
explicitly provided by the user, Cloud Hypervisor would get the host MAC
associated by default with this TAP device and store it through the
network config. Problem is, in the context of a snapshot/restore, that
meant the network config provided by the user was different on the
destination host compared to the source host. This was causing an issue
when Cloud Hypervisor wasn't started with CAP_NET_ADMIN permissions as
it couldn't set the host MAC address on the destination, while the
source never needed these permissions since the MAC was automatically
allocated by the kernel.

We're fixing this issue by setting the host MAC address when it's
explicitly requested by the user through the network config, and making
the host MAC immutable so that it can't be changed at runtime.

Signed-off-by: Sebastien Boeuf <sboeuf@meta.com>
2026-07-18 09:42:40 +00:00
Rob Bradford
58306b6f28 vmm: Support setting seccomp to errno
This will generate -EPERM on seccomp violations as opposed to causing
the VMM to exit with SIGSYS.

Signed-off-by: Rob Bradford <rbradford@meta.com>
2026-07-10 21:12:26 +00:00
Wei Liu
85c0725f5c virtio-devices: signal queue eventfd for PCI_CFG doorbells
A virtqueue notification (doorbell) is normally delivered to the device
through an ioeventfd registered on the notify address, so a plain MMIO
write to the notify register is consumed by the hypervisor and never
reaches write_bar().

It does reach write_bar() when the driver rings the doorbell through the
VIRTIO_PCI_CAP_PCI_CFG window (write_cap_pci_cfg -> write_bar) instead
of a mapped BAR, or on backends that deliver the write to the VMM such
as SEV-SNP.

The notification arm of write_bar() only re-signalled the matching
queue eventfd under the sev_snp feature and logged an error
otherwise, so a doorbell delivered through the PCI_CFG window was
silently dropped on standard builds and the queue was never
processed.

The virtio spec allows driving the device purely through the PCI_CFG
window, so signal the matching queue eventfd for any doorbell that
reaches write_bar() on every build.

Add unit tests that ring a queue's doorbell via write_bar() and
assert only the addressed queue's eventfd is signalled.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
Assisted-by: Copilot:Opus-4.8
2026-07-09 21:06:20 +00:00
Rob Bradford
ad3dbcd130 virtio-devices: Use SmallVec for descriptor chains
Rather than instantiating a vector for parsing the descriptor chain in
advance instead use a SmallVec bounded by the expected length of the
descriptor chain. This removes vector allocations from those paths.

As smallvec was already a block dependency move it to a workspace
dependency and use it from there.

Fixes: #5079

Signed-off-by: Rob Bradford <rbradford@meta.com>
2026-07-08 02:15:19 +00:00
Henry Hrvoje Tonkovac
ba3cfd7d9d virtio-devices: restrict vhost/vsock worker socket() to AF_UNIX
The vhost-user (fs, net, block, generic) and vsock worker threads allow
socket() unconditionally in their seccomp rules. These threads only ever
open AF_UNIX sockets: the vhost-user transport connects/binds a Unix
socket (via the vhost crate's Endpoint/Listener), and the vsock device's
host side is a Unix socket. None of them open AF_INET/AF_INET6 sockets.

Restrict their socket() rule to AF_UNIX. Because these threads are
spawned by the VMM thread and inherit its filter, socket() was already
limited to the VMM's set (AF_UNIX/AF_INET/AF_INET6); this narrows it
further to just AF_UNIX, so each worker is confined to what it actually
uses rather than the broader inherited set.

Related to #8490 (giving each thread a more restrictive filter than the
VMM thread).

Signed-off-by: Henry Hrvoje Tonkovac <htonkovac@gmail.com>
Assisted-by: Claude:Opus-4.8
2026-07-07 19:09:15 +00:00
Rob Bradford
4b120c3702 virtio-devices: Gate VIRTIO_NET_S_ANNOUNCE on feature acked
Only set the VIRTIO_NET_S_ANNOUNCE status bit if the feature
VIRTIO_NET_F_GUEST_ANNOUNCE was acknowledged.

Signed-off-by: Rob Bradford <rbradford@meta.com>
2026-07-06 18:46:56 +00:00
Rob Bradford
9161b18f9b virtio-devices: iommu: Translate buffers spanning adjacent mappings
The virtio-iommu translation required the whole [addr, addr+size) span
to be covered by a single mapping. A guest is free to describe one
contiguous buffer with several adjacent mappings: the specification lets
the driver map at page granularity and the Linux IOMMU core splits a
single mapping request at page size boundaries. A descriptor buffer
backed this way was rejected as an invalid translation even though every
page was mapped, wedging the device.

Walk consecutive mappings when no single one covers the span, accepting
the translation once the mappings are adjacent in IOVA space and
contiguous in guest-physical space. A non-contiguous span cannot be
represented by the single returned address and is still rejected.

Assisted-by: Claude:Opus-4.8
Signed-off-by: Rob Bradford <rbradford@meta.com>
2026-07-06 18:35:11 +00:00
Sebastian Eydam
4ac2340c1f virtio-devices: net: offer VIRTIO_NET_F_GUEST_ANNOUNCE to guests
The virtio-net guest announce feature bit was accidentally dropped
during upstreaming, so the device never advertised it to guests. Restore
the feature offer for virtio-net.

On-behalf-of: SAP sebastian.eydam@sap.com
Signed-off-by: Sebastian Eydam <sebastian.eydam@cyberus-technology.de>
2026-07-03 13:47:11 +00:00
Sebastian Eydam
53a00c0514 virtio-devices: net: add guest-announce plumbing
Advertise `VIRTIO_NET_F_GUEST_ANNOUNCE` on virtio-net devices, surface
`VIRTIO_NET_S_ANNOUNCE` through config status, and handle
`VIRTIO_NET_CTRL_ANNOUNCE_ACK` on the control queue.

This adds the guest-visible state needed for post-migration or
post-restore announce requests; the VMM side triggering is added in
follow-up commits.

The motivation is to reduce post-migration and post-restore
connectivity gap. After a live migration or after restoring, it can
take the guest several seconds to be reachable again over the network.
With these announcements, the network path should be refreshed within a
few milliseconds.

On-behalf-of: SAP sebastian.eydam@sap.com
Signed-off-by: Sebastian Eydam <sebastian.eydam@cyberus-technology.de>
2026-07-02 15:17:40 +00:00
Sebastian Eydam
e17c0be127 virtio-devices: net: report link up in config status
Expose `VIRTIO_NET_S_LINK_UP` through the virtio-net config status field
when `VIRTIO_NET_F_STATUS` was negotiated.

This makes the guest-visible status bits reflect the device runtime
state and prepares the config status path used by later post-migration
announce handling.

On-behalf-of: SAP sebastian.eydam@sap.com
Signed-off-by: Sebastian Eydam <sebastian.eydam@cyberus-technology.de>
2026-07-02 15:17:40 +00:00
Anatol Belski
ab593accb3 virtio-devices: Test device config capability presence
Add unit tests for add_pci_capabilities covering the configless
device path. The device config capability is present when the
config region is sized and absent when the size is zero.

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2026-06-29 23:09:52 +00:00
Anatol Belski
3c90f91491 virtio-devices: Report no config space for configless devices
The watchdog, rng, and rtc devices expose no device specific
configuration fields. Each now reports a config size of zero so the
transport omits the device configuration capability instead of
advertising an unbacked region that the device cannot service.

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2026-06-29 23:09:52 +00:00
Anatol Belski
d1dd6b13d5 virtio-devices: Size the device config capability per device
Add a config_size method to VirtioDevice and use it when building the
PCI device configuration capability. The transport advertises the size
reported by the device and omits the capability entirely when the size
is zero, because the virtio driver rejects a zero length capability.

The method defaults to None, so every device keeps its current
capability size.

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2026-06-29 23:09:52 +00:00
Henry Hrvoje Tonkovac
f720e619c1 misc: use prelude size_of
size_of is part of std::prelude as of Rust 1.80 (with size_of_val,
align_of, align_of_val), and the workspace MSRV is 1.89, so qualifying
it (mem::size_of, std::mem::size_of, core::mem::size_of) is unnecessary.

Convert every qualified size_of call-site to the bare prelude form and
drop the now-redundant `use std::mem::size_of;` imports, keeping
`use std::mem;` where it still serves non-prelude items (transmute,
swap, replace, take, zeroed, MaybeUninit, offset_of). size_of is the
only one of the four currently used in the tree.

Pure refactor, no behavioural change. Follow-up to the
clippy::absolute_paths cleanup (#7670), as discussed in #8444.

Signed-off-by: Henry Hrvoje Tonkovac <htonkovac@gmail.com>
Assisted-by: Claude:Opus-4.8
2026-06-25 16:54:35 +00:00
Philipp Schuster
dcaccf21ea virtio-devices: silence some info! messages
We have larger cloud deployments and analyzed the logs. Let's silence
some messages that generally provide little value on the `info!` level.

On-behalf-of: SAP philipp.schuster@sap.com
Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
2026-06-24 13:58:46 +00:00
Anatol Belski
1db8858fac virtio-devices: block: Reuse descriptor chain's memory for queue enable
The two synchronous completion paths add the head to the used ring with
desc_chain.memory() but reload self.mem.memory() to enable
notifications. Keep both on the snapshot the chain was parsed from so
the used ring update and the notification enable always act on one
guest memory view rather than two independent atomic loads.

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2026-06-21 19:46:46 +00:00
Henry Hrvoje Tonkovac
74a749b960 virtio-devices: trim qualified paths
Import the modules used in the crate instead of spelling the full paths
at every use site, and drop the now-unnecessary crate-level
#![expect(clippy::absolute_paths)].

Signed-off-by: Henry Hrvoje Tonkovac <htonkovac@gmail.com>
Assisted-by: Claude:Opus-4.8
2026-06-18 15:55:15 +00:00
Rob Bradford
2bc968ba1d build: Deny clippy::absolute_paths
Removal of absolute paths is currently in progress. To avoid regressing
those changes add a clippy deny at the workspace level and at the crate
level override with #[expect(clippy::absolute_paths)]

See: #7670

Signed-off-by: Rob Bradford <rbradford@meta.com>
2026-06-17 14:38:25 +01:00
Anatol Belski
fd4a923c37 virtio-devices: block: Test parse failure head reclamation
Submit a head only virtio-blk chain, confirm Request::parse rejects
it, and verify that add_used with len 0 returns the head to the
guest by advancing the used ring index.

Assisted-by: Claude:Opus-4.7
Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2026-06-16 22:02:46 +00:00
Anatol Belski
e1a63b41ff virtio-devices: block: Reclaim head on malformed descriptor chain
When Request::parse failed, for example for a chain containing only
the head descriptor, process_queue_submit returned the error via
`?`. The caller process_queue_submit_and_signal swallowed
Error::RequestParsing with a warn! and returned Ok(()), but
queue.iter().next() had already consumed the head from the avail
ring. The head was never written to the used ring, so the descriptor
slot leaked and the queue could be stalled by a guest that keeps
submitting malformed chains.

Handle the parse error in line. Log a warning, add the head to the
used ring with len 0, reenable notifications, and continue draining
the queue. A VIRTIO_BLK_S_IOERR status cannot be written because the
status descriptor address is exactly what failed to parse.

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2026-06-16 22:02:46 +00:00
Rob Bradford
80a0393edd block: qcow: Port RawFile to AlignedFile
Reuse the functionality in the AlignedFile wrapper for the QCOW RawFile
wrapper. This makes alignment handling more transparent.

Assisted-by: Claude:Opus-4.8
Signed-off-by: Rob Bradford <rbradford@meta.com>
2026-06-16 14:43:11 +00:00
Dylan Reid
50f2fd369f virtio-devices: block: drain async I/O before pausing
During pause the block backend's async I/O path can have unfinished I/O
requests. A snapshot or migration RAM copy taken after pause returns can
then race with kernel writes and capture torn pages.

Since vCPUs are already paused, the VMM thread can stop new block
submissions and wait for the worker to drain before parking the worker
threads.

Assisted-by: Codex:GPT-5
Signed-off-by: Dylan Reid <dgreid@fb.com>
2026-06-13 18:13:37 +00:00
Rob Bradford
01593ad181 virtio-devices: vsock: Handle host half-close
When the host half-closed the socket this was wrongly interpreted as a
full shutdown preventing the guest from sending any more data. Instead
propagate the half-close by setting just `VSOCK_FLAGS_SHUTDOWN_SEND`,
leaving the connection alive so that guest-to-host writes are still
forwarded. The connection is only torn down once the guest also shuts
down its send side or a host write fails.

Fixes: #8300

Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Rob Bradford <rbradford@meta.com>
2026-06-12 08:20:00 +00:00
Rob Bradford
5eb539b6ef virtio-devices: vsock: Handle guest half-close
When the guest did a half-close (shutting down only its send side) the
connection state was updated but the write half of the host Unix socket
was never closed so the host peer never saw an EOF. This caused issues
with newer systemd (v256+) as it now half closes its socket and waits
for the host side to react and fully close the connection.

Propagate the guest's half-close to the host by shutting down the write
half of the backing stream. This is deferred until any buffered guest
data has been flushed so that no data is lost, and the connection is
left open so that host-to-guest data keeps flowing.

Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Rob Bradford <rbradford@meta.com>
2026-06-12 08:20:00 +00:00
Tushar Khatri
4f68b687aa virtio-devices: reevaluate #[allow] attributes
Convert the still-needed #[allow]s to #[expect] so they warn if the
lints stop firing.

Part of #8326.

Signed-off-by: Tushar Khatri <hello@tusharkhatri.in>
2026-06-11 19:06:49 +00:00
Dylan Reid
0487035512 vmm: release vIOMMU VFIO container on device eject
Currently ejecting a device leaks its mapping keeping the container fd
open. Remove the mapping so the fd can be closed.

Assisted-by: Claude:Opus-4.8
Signed-off-by: Dylan Reid <dgreid@fb.com>
2026-06-11 15:15:38 +00:00
Rob Bradford
c194f63cf4 virtio-devices: vhost_user: Save the dirty log before shutdown
Query and save the dirty log before shutting down the vhost-user device.
This allows any final dirty memory ranges to be recorded before it
becomes impossible to do that as the vhost-user handle has been closed.
This is required to ensure that all memory writes have been correctly
recorded that may be triggered by inflight I/O drains from vhost-user
device state capture.

One small implementation wrinkle: with local migrations there is no
dirty logging (since we just pass the memory FD over the socket) so
calling dirty_log() would generate an error. As there is no clean way to
query if dirty logging has been started add a boolean to track if its
active.

Signed-off-by: Rob Bradford <rbradford@meta.com>
2026-06-11 08:00:50 +00:00
Rob Bradford
47e61f3b2a virtio-devices: Move guest_memory to VhostUserCommon
Rather than each device implementation holding a reference to the guest
memory move this to VhostUserCommon. This refactoring simplifies the
function signatures but also allows for methods that act on
VhostUserCommon that don't have the memory available to them.

Signed-off-by: Rob Bradford <rbradford@meta.com>
2026-06-11 08:00:50 +00:00
Ruben Hakobyan
9e6c817192 virtio-devices: add VIRTIO_F_ACCESS_PLATFORM to watchdog and iommu
A confidential guest (e.g. SEV-SNP) requires every virtio device to
advertise VIRTIO_F_ACCESS_PLATFORM so the guest driver routes DMA
through the platform's bounce-buffer path; the driver refuses a device
that does not offer it.

Add VIRTIO_F_ACCESS_PLATFORM support to virtio-{watchdog,iommu} which
are exercised as part of the CVM integration tests.

Assisted-by: Claude:Opus-4.8
Signed-off-by: Ruben Hakobyan <hruben@meta.com>
2026-06-09 15:49:42 +00:00
Dylan Reid
dd3a2f2649 virtio-devices: block: make shutdown join the worker
eject_device calls shutdown, but Block doesn't implement it, so the
worker thread was never joined. Drop for Block does not help either,
VirtioPciDevice keeps an Arc<Mutex<Block>> past eject, so Drop never
runs. The async worker keeps completing in-flight I/O into the guest RAM
that backed it when issued.

Implement shutdown() to call wait_for_epoll_threads(), which drops the
WorkerThreads handle and ensures that worker's io completes.

Signed-off-by: Dylan Reid <dgreid@fb.com>
2026-06-05 08:00:10 +00:00
Philipp Schuster
13e727efed virtio-devices: vmm: replace #[allow(unnused)] with expect()
On-behalf-of: SAP philipp.schuster@sap.com
Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
2026-06-03 13:56:31 +00:00
Philipp Schuster
619f964747 virtio-devices: replace #[allow(dead_code)] with expect()
On-behalf-of: SAP philipp.schuster@sap.com
Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
2026-06-03 13:56:31 +00:00
Philipp Schuster
6745ff87ef virtio-devices: remove unneeded #[allow(dead_code)]
On-behalf-of: SAP philipp.schuster@sap.com
Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
2026-06-03 13:56:31 +00:00
Anatol Belski
a89600aeba virtio-devices: Test activator success path
Feed Ok into VirtioPciDeviceActivator and assert that activate returns
Ok, device_activated becomes true, DEVICE_NEEDS_RESET is not set,
status is otherwise unchanged, no Config interrupt is delivered, and
the barrier waiter unblocks normally.

Assisted-by: Claude:Opus-4.7
Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2026-06-02 14:49:32 +01:00
Anatol Belski
64c552cc96 virtio-devices: Test activator failure releases barrier
Feed BadActivate into VirtioPciDeviceActivator and assert that the
error propagates, device_activated stays false, DEVICE_NEEDS_RESET is
set in status, a single Config interrupt is delivered, and a thread
waiting on the activation barrier unblocks. The barrier release is
the deadlock fixed by the NEEDS_RESET on activation failure change.

Assisted-by: Claude:Opus-4.7
Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2026-06-02 14:49:32 +01:00
Anatol Belski
7cdb724346 virtio-devices: Add activator unit test scaffolding
Add TestVirtioDevice with a controllable ActivateResult,
TestVirtioInterrupt that records delivered interrupt types, and a
make_activator helper that builds a complete VirtioPciDeviceActivator
with observable status, activated flag, interrupt log, and barrier.

Assisted-by: Claude:Opus-4.7
Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2026-06-02 14:49:32 +01:00
Anatol Belski
2d2931a76e virtio-devices: vmm: Signal NEEDS_RESET on activation failure
When the guest writes DRIVER_OK and the device fails to activate, the
VMM previously bubbled the error up via VirtioActivate and never
released the activation barrier, leaving the vCPU that wrote DRIVER_OK
blocked on the barrier and effectively deadlocking the guest.

Per virtio 1.3 section 2.1.2, a device that has experienced an error
it cannot recover from should set DEVICE_NEEDS_RESET in its status and
notify the driver via a configuration change interrupt. Do that on
activation failure through the existing mark_device_needs_reset
helper, then release the activation barrier so the vCPU can resume.

DeviceManager::activate_virtio_devices now logs and continues instead
of aborting the whole pending list, so one failing device does not
take down the VMM or block pause and migration. The activator has
already reported the failure with the device id.

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2026-06-02 14:49:32 +01:00
Philipp Schuster
727b704606 virtio-devices: vsock: improve error handling
On-behalf-of: SAP philipp.schuster@sap.com
Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
2026-06-02 09:17:12 +00:00