Commit Graph

79 Commits

Author SHA1 Message Date
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
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
3a1cf6e740 virtio-devices: Remove panic when duplicating activate EventFds
Replace the (unlikely) panic when duplicating the EventFds with a
propagated error.

Signed-off-by: Rob Bradford <rbradford@meta.com>
2026-06-01 17:07:23 +01:00
Dylan Reid
2bcacbe19d virtio-devices: Introduce WorkerThreads handle
Take the recent thread refactor further. Bundle a device's worker
JoinHandles together with the kill event that stops them into a single
WorkerThreads value, owned by VirtioCommon. Its Drop signals the workers
to exit, unparks any parked for migration, and joins them.

This makes a detached/leaked worker unrepresentable. reset(),
wait_for_epoll_threads() and VhostUserCommon::shutdown() now happen when
dropping the WorkerThreads, and the unpark-before-join teardown now
lives in one place.

Assisted-by: Claude:Opus-4.8
Signed-off-by: Dylan Reid <dgreid@fb.com>
Signed-off-by: Rob Bradford <rbradford@meta.com>
2026-06-01 17:07:23 +01:00
Rob Bradford
b5f1632177 virtio-devices: Use VirtioCommon::spawn_worker()
Replace use of spawn_virtio_thread() helper with the new method on
VirtioCommon to handle thread management as well as spawning. As a
result this cleanly handles reset if it fails to spawn the thread.

Assisted-by: Claude:Opus-4.7
Signed-off-by: Rob Bradford <rbradford@meta.com>
2026-06-01 17:07:23 +01:00
Anatol Belski
45cba34101 virtio-devices: rng: Use checked descriptor iterator
Replace manual translate_gva call with checked_iter which validates
the descriptor buffer range against guest memory before I/O.

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2026-05-28 21:41:45 +00:00
Rob Bradford
5702e9751c virtio-devices: rng: Preserve byte count on mid-chain errors
When address translation or the entropy read fails mid-chain the
handler reset total_len to zero before breaking out of the loop.
If earlier descriptors in the same chain were already filled, the
used ring entry under-reports the bytes actually written to guest
memory. Drop the reset so the used length reflects reality.

Signed-off-by: Rob Bradford <rbradford@meta.com>
Assisted-by: Claude:claude-opus-4-6
2026-05-07 16:27:18 +00:00
Rob Bradford
aee4fd6010 virtio-devices: rng: Skip device-readable descriptors
A device-readable descriptor anywhere in the chain caused the handler
to reset the byte count to zero and abandon the rest of the chain.
This discards valid device-writable descriptors that follow and
misreports bytes already written to earlier descriptors.

Skip device-readable and zero-length descriptors individually so
the remaining device-writable buffers still get filled with entropy.

Signed-off-by: Rob Bradford <rbradford@meta.com>
Assisted-by: Claude:claude-opus-4-6
2026-05-07 16:27:18 +00:00
Anatol Belski
3402bc0762 virtio-devices: NEEDS_RESET on worker thread Err
Worker threads spawned through spawn_virtio_thread previously wrote to
exit_evt on any clean Err return, taking the whole VMM down on a single
failed device worker. A guest induced fault in any virtio device thus
propagated into a host wide failure.

Route the Err return through the shared mark_device_needs_reset helper
instead. The helper sets the DEVICE_NEEDS_RESET bit on device_status
and triggers a config change interrupt, so the device goes idle and
the guest is informed. The thread exits cleanly without killing the
rest of the VMM.

The panic and the seccomp filter apply paths keep writing to exit_evt.
A panicked worker may have left poisoned locks or partially mutated
state, so a hard exit remains the right policy there.

spawn_virtio_thread now takes the device_status and the interrupt
callback. Every native virtio and vhost-user call site is updated to
pass them in.

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2026-05-06 21:45:18 +01:00
Rob Bradford
e11ff541da virtio-devices: Simplify interrupt handling
Previously the interrupt was created in VirtioPciDevice, moved via the
Option::take() to the VirtioPciDeviceActivator and then moved to the
VirtioDevice upon activation. On reset it would be moved back ready for
reactivation.

Since this already an Arc type remove the wrapping Option and instead
refcount it such that the VirtioPciDevice can continue to hold onto it
for later activations.

This significantly simplifies the reset() logic as there is no need to
hand back the interrupt.

A few devices used whether the interrupt was Some to make triggering an
interrupt a no-op. However the MSI-X interrupt routing already drops the
interrupt if the driver hasn't yet configured the vector so it is safe
to trigger the interrupt before device activation (e.g. balloon resize
request before driver loaded).

VirtioCommon still retains an Option<..> for the interrupt as the
interrupt is not known until activation time (after this has been
created). A helper VirtioCommon::trigger_interrupt() has been added to
handle this.

Signed-off-by: Rob Bradford <rbradford@meta.com>
2026-04-27 07:15:37 +00:00
Rob Bradford
7b07c3a194 virtio-devices: rng: Fill the entire descriptor chain
The virtio spec allows a chain of writable descriptors however the rng
device was assuming just a single writable descriptor. Instead fill in
all writable descriptors. There is no status byte (unlike e.g. block)
and instead 0 bytes used is used to indicate error.

Signed-off-by: Rob Bradford <rbradford@meta.com>
2026-04-20 18:08:34 +00:00
Rob Bradford
0eca4d7c68 virtio-devices: Rename control parameter for VIRTIO_F_ACCESS_PLATFORM
Rename from iommu to access_platform_enabled. The original name was
iommu as this feature was exposed for devices behind an IOMMU however
this feature is also now used for confidential VMs so adopt a more
general name.

Signed-off-by: Rob Bradford <rbradford@meta.com>
2026-04-17 10:54:51 +00:00
Rob Bradford
128ee6d105 virtio-devices: Implement VirtioDevice::access_platform()
This forwards through to the VirtioCommon implementation and can be used
to simplify the virtio PCI access code.

Signed-off-by: Rob Bradford <rbradford@meta.com>
2026-04-17 10:54:51 +00:00
Rob Bradford
81ee260ac3 virtio-devices: Use new VirtioCommon::access_platform() accessor
Use the new virtio feature gated accessor when creating the handlers for
the virtio devices. This now means that the translations via the
accessor will only be applied if the feature is acked in accordance with
the spec.

Signed-off-by: Rob Bradford <rbradford@meta.com>
2026-04-17 10:54:51 +00:00
Dylan Reid
a6d3901f3e misc: return errors from IOMMU address translation instead of panicking
The address that is passed from the guest should be treated as
untrusted. Currently an invalid address will panic the VMM. This only
allows the guest to hurt itself, but we shouldn't have the VMM crashing.
Instead let's return an error if possible or invalidate the queue if it
happen during setup.

The data flow from guest to translate_gva/translate_gpa is:

  1. Guest writes a raw u64 address into a virtio descriptor in the
     shared descriptor table (guest memory).
  2. The virtio-queue crate reads this descriptor via read_obj() and
     returns the addr field as-is in a GuestAddress — no validation.
  3. Device code calls .translate_gva(access_platform, len) on the
     GuestAddress.
  4. With IOMMU (access_platform is Some): the address is an IOVA that
     must be translated to a GPA via the IOMMU mapping table. If the
     guest provides an unmapped IOVA, translation returns Err.
     Previously, .unwrap() here panicked the VMM.
  5. Without IOMMU (access_platform is None): translate_gva is a no-op
     (returns self). The raw address flows to GuestMemory::read_obj()
     which validates it — out-of-range addresses return
     Err(InvalidGuestAddress), so no host memory corruption is possible.

Signed-off-by: Dylan Reid <dgreid@fb.com>
2026-04-14 23:25:03 +00:00
Rob Bradford
e05065f509 build: Bump rust-vmm dependencies
Bump to the released versions that are compatible wherever possible but
for the vhost and vfio crates they are git hashes as no releases with
compatible versions have yet been made.

Signed-off-by: Rob Bradford <rbradford@meta.com>
2026-03-23 10:04:07 +00:00
Peter Oskolkov
f77c6ef78b virtio-devices: introduce ActivationContext for device activation
Signed-off-by: Peter Oskolkov <posk@google.com>
2026-03-14 00:21:02 +00:00
Anatol Belski
da0d0a2090 virtio-devices: Rename VIRTIO_F_IOMMU_PLATFORM
Rename the transport feature bit constant from
VIRTIO_F_IOMMU_PLATFORM to VIRTIO_F_ACCESS_PLATFORM across
the entire virtio-devices crate.

The virtio specification as of v1.1 carries bit 33 as
VIRTIO_F_ACCESS_PLATFORM. The Linux kernel UAPI header
<linux/virtio_config.h> carries VIRTIO_F_IOMMU_PLATFORM
only as a backward-compatible alias.

This is a pure rename with no functional or behavioral
change.

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2026-03-08 09:56:01 +00:00
Philipp Schuster
c53781bf5f misc: clippy: add needless_pass_by_value
This is a follow-up of [0].

# Advantages

- This saves dozens of unneeded clone()s across the whole code base
- Makes it much easier to reason about how parameters are used
  (often we passed owned Arc/Rc versions without actually needing
  ownership)

# Exceptions

For certain code paths, the alternatives would require awkward or overly
complex code, and in some cases the functions are the logical owners of
the values they take. In those cases, I've added
#[allow(clippy::needless_pass_by_value)].

This does not mean that one should not improve this in the future.

[0] 6a86c157af

Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
On-behalf-of: SAP philipp.schuster@sap.com
2025-11-27 17:11:14 +00:00
Philipp Schuster
2157f1a1f2 misc: virtio-devices: drop extern crate, use modern rust
This commit is part of a series of similar commits.

Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
On-behalf-of: SAP philipp.schuster@sap.com
2025-11-24 22:36:46 +00:00
Philipp Schuster
b4c62bf159 misc: clippy: add semicolon_if_nothing_returned
Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
On-behalf-of: SAP philipp.schuster@sap.com
2025-11-21 09:32:11 +00:00
Philipp Schuster
7536a95424 misc: cleanup &Arc<dyn T> -> &dyn T
Consuming `&Arc<T>` as argument is almost always an antipattern as it
hides whether the callee is going to take over (shared) ownership
(by .clone()) or not. Instead, it is better to consume `&dyn T` or
`Arc<dyn T>` to be more explicit. This commit cleans up the code.

The change is very mechanic and was very easy to implement across the
code base.

Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
On-behalf-of: SAP philipp.schuster@sap.com
2025-10-28 17:37:49 +00:00
Ruoqing He
f2dfa7f6e0 misc: Use variables directly in format! string
Fix clippy warning `uninlined_format_args` reported by rustc rustc
1.89.0 (29483883e 2025-08-04).

```console
warning: variables can be used directly in the `format!` string
   --> block/src/lib.rs:649:17
    |
649 |                 info!("{} failed to create io_uring instance: {}", error_msg, e);
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#uninlined_format_args
    = note: `#[warn(clippy::uninlined_format_args)]` on by default
help: change this to
    |
649 -                 info!("{} failed to create io_uring instance: {}", error_msg, e);
649 +                 info!("{error_msg} failed to create io_uring instance: {e}");
    |
```

Signed-off-by: Ruoqing He <heruoqing@iscas.ac.cn>
2025-09-24 02:28:12 +00:00
Philipp Schuster
363273111a build: treewide: fmt for edition 2024
`cargo +nightly fmt`

Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
On-behalf-of: SAP philipp.schuster@sap.com
2025-09-10 18:35:38 +00:00
Philipp Schuster
8e2973fe7c misc: virtio-devices: streamline error Display::fmt()
The changes were mostly automatically applied using the Python
script mentioned in the first commit of this series.

Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
On-behalf-of: SAP philipp.schuster@sap.com
2025-06-13 19:55:54 +00:00
Philipp Schuster
28e0a95450 misc: virtio-devices: streamline #[source] and Error
This streamlines the code base to follow best practices for
error handling in Rust: Each error struct implements
std::error::Error (most due via thiserror::Error derive macro)
and sets its source accordingly.

This allows future work that nicely prints the error chains,
for example.

So far, the convention is that each error prints its
sub error as part of its Display::fmt() impl.

Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
On-behalf-of: SAP philipp.schuster@sap.com
2025-05-21 09:09:30 +00:00
Ruoqing He
61e57e1cb1 misc: Further improve imports styling
By introducing `imports_granularity="Module"` format strategy,
effectively groups imports from the same module into one line or block,
improving maintainability and readability.

Signed-off-by: Ruoqing He <heruoqing@iscas.ac.cn>
2024-09-29 16:13:48 +00:00
Rob Bradford
88a9f79944 misc: Adapt consistent import style formatting
Historically the Cloud Hypervisor coding style has been to ensure that
all imports are ordered and placed in a single group. Unfortunately
cargo fmt has no support for ensuring that all imports are in a single
group so if whitespace lines were added as part of the import statements
then they would only be odered correctly in the group.

By adopting "group_imports="StdExternalCrate" we can enforce a style
where imports are placed in at most three groups for std, external
crates and the crate itself. Choosing a style enforceable by the tooling
reduces the reviewer burden.

Signed-off-by: Rob Bradford <rbradford@rivosinc.com>
2024-09-29 13:08:12 +01:00
Rob Bradford
10ab87d6a3 misc: Migrate away from versionize
Replace with serde instead.

Fixes: #6370

Signed-off-by: Rob Bradford <rbradford@rivosinc.com>
2024-04-22 17:10:55 +00:00
Ruslan Mstoi
5e9886bba4 build: add REUSE Compliance Check
In accordance with reuse requirements:
- Place each license file in the LICENSES/ directory
- Add missing SPDX-License-Identifier to files.
- Add .reuse/dep5 to bulk-license files

Fixes: #5887

Signed-off-by: Ruslan Mstoi <ruslan.mstoi@intel.com>
2024-04-19 17:35:45 +00:00
Bo Chen
d4892f41b3 misc: Stop using deprecated functions from vm-memory crate
See: https://github.com/rust-vmm/vm-memory/pull/247

Signed-off-by: Bo Chen <chen.bo@intel.com>
2023-11-14 09:17:42 +00:00
Philipp Schuster
ad6c0ee52b virtio-devices: properly join all threads on Drop
This change is important to do a proper resource cleanup. We decided
to do this repetitive approach as VirtioCommon can't implement Drop
without major changes to the corresponding code. Also, devices such as
Net can't easily use the epoll_threads-abstraction from VirtioCommon as
it has multiple threads with different semantics.

Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
2023-01-12 18:03:33 +00:00
Sebastien Boeuf
748018ace3 vm-migration: Don't store the id as part of Snapshot structure
The information about the identifier related to a Snapshot is only
relevant from the BTreeMap perspective, which is why we can get rid of
the duplicated identifier in every Snapshot structure.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-12-09 10:26:06 +01:00
Sebastien Boeuf
b62a40efae virtio-devices, vmm: Always restore virtio devices in paused state
Following the new restore design, it is not appropriate to set every
virtio device threads into a paused state after they've been started.

This is why we remove the line of code pausing the devices only after
they've been restored, and replace it with a small patch in every virtio
device implementation. When a virtio device is created as part of a
restored VM, the associated "paused" boolean is set to true. This
ensures the corresponding thread will be directly parked when being
started, avoiding the thread to be in a different state than the one it
was on the source VM during the snapshot.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-12-01 09:27:00 +01:00
Sebastien Boeuf
1f0e5eb66a vmm: virtio-devices: Restore every VirtioDevice upon creation
Following the new design proposal to improve the restore codepath when
migrating a VM, all virtio devices are supplied with an optional state
they can use to restore from. The restore() implementation every device
was providing has been removed in order to prevent from going through
the restoration twice.

Here is the list of devices now following the new restore design:

- Block (virtio-block)
- Net (virtio-net)
- Rng (virtio-rng)
- Fs (vhost-user-fs)
- Blk (vhost-user-block)
- Net (vhost-user-net)
- Pmem (virtio-pmem)
- Vsock (virtio-vsock)
- Mem (virtio-mem)
- Balloon (virtio-balloon)
- Watchdog (virtio-watchdog)
- Vdpa (vDPA)
- Console (virtio-console)
- Iommu (virtio-iommu)

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-10-24 14:17:08 +02:00
Rob Bradford
31ca22d4b6 virtio-devices: rng: Fix error message
The RNG device never reads from the guest memory it reads from a file
and writes to the guest memory.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-10-04 16:38:41 +01:00
Bo Chen
f0c55f5245 virtio-devices: rng: Error out of queue execution on invalid requests
With the virtio-rng device the descriptors that are provided by the
guest must be writable and of non-zero length. Also propagate an error
if writing to the guest memory fails.

Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-09-28 10:07:44 +01:00
Rob Bradford
194b59f44b fuzz: Don't overload meaning of reset()
This function is for really for the transport layer to trigger a device
reset. Instead name it appropriately for the fuzzing specific use case.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-09-22 11:01:41 -07:00
Bo Chen
1c1bff93a1 vitio-devices: rng: Avoid panic and propagate errors properly
Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-09-16 09:42:41 +02:00
Markus Napierkowski
b49f8b9248 virtio-devices: rng: correctly indicate number of bytes written
Reads from the random file may only be partial, e.g., if the random file is an ordinary text
file. When that happens, the device needs to signal to the driver that only parts of the buffer have
been overwritten.

Signed-off-by: Markus Napierkowski <markus.napierkowski@cyberus-technology.de>
2022-08-18 14:44:58 +01:00
Bo Chen
df5b803a63 virtio-devices: Shutdown VMM upon worker thread errors
Fixes: #4462

Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-08-16 11:45:44 +01:00
Bo Chen
b1752994d5 virtio-devices: Report errors from EpollHelperHandler::handle_event
Signed-off-by: Bo Chen <chen.bo@intel.com>
2022-08-16 11:45:44 +01:00
Sebastien Boeuf
a4859ffe85 virtio-devices: Optimize add_used() usage
Now that we rely on pop_descriptor_chain() rather than iter() to iterate
over a queue, there's no more borrow on the queue itself, meaning we can
invoke add_used() directly for the iteration loop. This simplifies the
processing of the queues for each virtio device, and bring some possible
performance improvement given we don't have to iterate twice over the
list of descriptors to invoke add_used().

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-07-29 17:41:32 +01:00
Sebastien Boeuf
87f57f7c1e virtio-devices: Improve queue handling with pop_descriptor_chain()
Using pop_descriptor_chain() is much more appropriate than iter() since
it recreates the iterator every time, avoiding the queue to be borrowed
and allowing the virtio-net implementation to match all the other ones.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-07-29 17:41:32 +01:00
Sebastien Boeuf
a423bf13ad virtio: Port codebase to the latest virtio-queue version
The new virtio-queue version introduced some breaking changes which need
to be addressed so that Cloud Hypervisor can still work with this
version.

The most important change is about removing a handle to the guest memory
from the Queue, meaning the caller has to provide the guest memory
handle for multiple methods from the QueueT trait.

One interesting aspect is that QueueT has been widely extended to
provide every getter and setter we need to access and update the Queue
structure without having direct access to its internal fields.

This patch ports all the virtio and vhost-user devices to this new crate
definition. It also updates both vhost-user-block and vhost-user-net
backends based on the updated vhost-user-backend crate. It also updates
the fuzz directory.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-07-29 17:41:32 +01:00
Sebastien Boeuf
3f62a172b2 virtio-devices: Pass a list of tuples for virtqueues
Instead of passing separately a list of Queues and the equivalent list
of EventFds, we consolidate these two through a tuple along with the
queue index.

The queue index can be very useful if looking for the actual index
related to the queue, no matter if other queues have been enabled or
not.

It's also convenient to have the EventFd associated with the Queue so
that we don't have to carry two lists with the same amount of items.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-07-21 14:28:41 +02:00
Sebastien Boeuf
059e787cb5 virtio-devices: Rename address translation function for more clarity
Renaming translate() to translate_gva() to clarify we want to translate
a GVA address into a GPA.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-04-05 00:09:52 +02:00
Sebastien Boeuf
77df4e6773 vm-virtio: Define and implement Translatable trait
This new trait simplifies the address translation of a GuestAddress by
having GuestAddress implementing it.

The three crates virtio-devices, block_util and net_util have been
updated accordingly to rely on this new trait, helping with code
readability and limiting the amount of duplicated code.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-01-27 10:00:20 +00:00
Sebastien Boeuf
8eed276d14 vm-virtio: Define AccessPlatform trait
Moving the whole codebase to rely on the AccessPlatform definition from
vm-virtio so that we can fully remove it from virtio-queue crate.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-01-27 10:00:20 +00:00
Sebastien Boeuf
09f5b82fd7 virtio-devices: rng: Handle descriptor address translation
Since we're trying to move away from the translation happening in the
virtio-queue crate, the device itself is performing the address
translation when needed.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
2022-01-27 10:00:20 +00:00