Commit Graph

118 Commits

Author SHA1 Message Date
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
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
Peter Oskolkov
f56c8392ea virtio-devices: vsock: RST vsocks on snapshot restore
Otherwise guest connections just hang.

Signed-off-by: Peter Oskolkov <posk@google.com>
2026-04-07 00:36:57 +00:00
Demi Marie Obenour
e1c40211ae virtio-devices: Add set_notifier() method to VirtioInterrupt
It is currently left as unimplemented!().

No functional change intended as there are no callers.

Signed-off-by: Demi Marie Obenour <demiobenour@gmail.com>
2026-03-18 09:25:27 +00:00
Peter Oskolkov
b5053ae4de virtio-devices: wire driver_status to EpollHandler
Signed-off-by: Peter Oskolkov <posk@google.com>
2026-03-14 00:21:02 +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
Anatol Belski
f1c33afc8e virtio-devices: vsock: Simplify discarded accept result
Do the necessary replacements to satisfy clippy::map_unwrap_or.

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2026-03-06 12:32:38 +00:00
Wei Liu
bf6f0f8352 virtio-devices: vsock: Accept multi-descriptor TX packets
Since kernel commit 6693731487a8 ("vsock/virtio: Allocate nonlinear SKBs
for handling large transmit buffers"), a large vsock packet can be split
into multiple descriptors.

If we encounter such TX packets, pull the content into an owned buffer.

Fixes: #7672
Signed-off-by: Wei Liu <liuwe@microsoft.com>
2026-02-10 22:00:27 +00:00
Thomas Leroy
929df76e1a virtio-devices: copy VSock header from guest
VsockPacket::hdr holds a raw pointer to the address of the VSock packet
header, which is in guest memory. It opens the door to double-fetch
(or TOCTOU) race conditions. Therefore, VSockPacket::hdr content can't
be trusted since it can be arbitrarily changed by the guest, at any
time.

To mitigate this, we can copy the header content to an array in VMM's
memory that the guest can't modify.

Signed-off-by: Thomas Leroy <thomas.leroy.mp@gmail.com>
2026-01-27 19:39:07 +00:00
Philipp Schuster
82e8002fa0 misc: clippy: remove some overrides
Closes #4986 [0].

[0]: https://github.com/cloud-hypervisor/cloud-hypervisor/issues/4986

Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
On-behalf-of: SAP philipp.schuster@sap.com
2025-12-14 17:05:49 +00:00
Philipp Schuster
265d21b0c4 misc: improve test idempotence (unrelated improvement)
Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
On-behalf-of: SAP philipp.schuster@sap.com
2025-12-09 16:13:10 +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
7cb73e9e56 misc: clippy: add unnecessary_semicolon
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
d1680b9ff9 tests: streamline module names to unit_tests
This better aligns with the rest of the code and makes it clearer
that these tests can run "as is" in a normal hosted environments
without the special test environment.

Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
On-behalf-of: SAP philipp.schuster@sap.com
2025-11-20 21:15:03 +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
Maximilian Güntner
d28d9eb34e virtio-devices: refactor VSOCK "connect" parsing
The function `read_local_stream_port` had no proper handling for
unexpected or incomplete input.
When the control socket of the VSOCK device was closed without sending
the expected `CONNECT <PORT>\n` statement completely, the thread
got stuck in an infinite loop as it attempted to read from a closed
socket over and over again which never returned any data.

This resulted in the thread responsible for `epoll` being completely
blocked. New VSOCK connections could not be established and existing
ones became defunct, effectively leading to a Denial of Service of
the entire VSOCK device.

The issue can be reproduced by opening a socket and immediately
closing it.

```
socat - UNIX-CONNECT:/socket.vsock
<Ctrl-C>
```

Instead of applying a quick fix by handling the `EPOLLHUP` event before
reading, the function is refactored to remove the error-prone `while`
loop and multiple `read`s.
Notably, we now check if the number of bytes read is zero, which occurs
when `event_set == EPOLLHUP | EPOLLIN`, indicating that the socket has
been closed by the client.

Additionally, the actual parsing code is now extracted into a dedicated
function that is tested.

Fixes: #6798
Signed-off-by: Maximilian Güntner <code@mguentner.de>
2025-09-17 17:10:12 +00:00
Philipp Schuster
c995b72384 build: treewide: clippy: collapse nested ifs, use let chains
This bumps the MSRV to 1.88 (also, Rust edition 2024 is mandatory).

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
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
Alyssa Ross
ec8fceb4a6 virtio-devices: stop corrupting vsock commands
The read_exact() call was introduced in 82ac114b8 ("virtio-devices:
vsock: handle short read in muxer") to solve a crash when a connection
disconnected without sending any data, but it introduced a problem of
its own: because the socket is non-blocking, read_exact() may read
some data, then return ErrorKind::WouldBlock.  In that case, the data
it read will be discarded.  So for example if it read "CONNECT ",
and then nothing else was available to read yet, "CONNECT " would be
discarded, and so the next time this function was called, when epoll
triggered again for the socket, only the following data would end up
in command.buf, causing an error due to just a port number being an
invalid command.

Contrary to that commit message, this code was actually designed to
handle short reads just fine — in the case of a short read, it stores
the data it has read in command, and returns
Error::UnixRead(ErrorKind::WouldBlock), which is ignored by the
caller, and the function gets called again when there is more data to
read, building up command potentially over the course of several
reads.  The only thing it didn't handle correctly, as far as I can
tell, was a 0-byte read, which happens when a client disconnects from
the socket without writing anything.  All that's needed to fix this is
to avoid an invalid subtraction in that case, so this change reverts
82ac114b8, fixing the issue with partial commands being discarded, and
instead handles the 0-byte read by using slice::get, and treating an
empty command as an incomplete command, which of course it is.

Fixes: 82ac114b8 ("virtio-devices: vsock: handle short read in muxer")
Signed-off-by: Alyssa Ross <hi@alyssa.is>
2025-07-14 18:07:07 +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
Jinank Jain
2bc8d51a60 misc: Fix missing lifetime syntax clippy warning
This was caught by the nightly compiler during cargo fuzz build.

error: lifetime flowing from input to output with different syntax can be confusing
   --> /home/runner/work/cloud-hypervisor/cloud-hypervisor/hypervisor/src/arch/x86/emulator/mod.rs:493:26
    |
493 |     pub fn new(platform: &mut dyn PlatformEmulator<CpuState = T>) -> Emulator<T> {
    |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^     ----------- the lifetime gets resolved as `'_`
    |                          |
    |                          this lifetime flows to the output
    |
    = note: `-D mismatched-lifetime-syntaxes` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(mismatched_lifetime_syntaxes)]`
help: one option is to remove the lifetime for references and use the anonymous lifetime for paths
    |
493 |     pub fn new(platform: &mut dyn PlatformEmulator<CpuState = T>) -> Emulator<'_, T> {

Signed-off-by: Jinank Jain <jinankjain@microsoft.com>
2025-06-09 11:19:11 +00:00
Philipp Schuster
a615c809eb misc: vsock: 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
Philipp Schuster
78b0f68b21 vmm: Error for MemoryManagerError
Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>

On-behalf-of: SAP <philipp.schuster@sap.com>
2025-05-16 11:42:01 +00:00
Philipp Schuster
b2993fb2fa vmm: Error for vsock::unix::Error
Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
On-behalf-of: SAP philipp.schuster@sap.com
2025-05-16 11:42:01 +00:00
Ruoqing He
c441bb2968 misc: Fix clippy - doc list item overindented
Reported by 1.86.0-beta.1 (f0cb41030 2025-02-17).

Signed-off-by: Ruoqing He <heruoqing@iscas.ac.cn>
2025-03-01 01:02:17 +00:00
Wei Liu
0cb2c86ff4 fuzz: introduce a virtio vsock fuzzer
Signed-off-by: Wei Liu <liuwe@microsoft.com>
2025-01-14 00:26:01 +00:00
Wei Liu
d359c8cdce virtio-devices: vsock: allow fuzzer to use TestBackend
Instead of reinventing this mock infrastructure in the upcoming fuzzer,
reuse the one that is already available.

However this change makes Clippy complain that TestBackend and
TestContext don't implement Default. This is just test code, we can
suppress Clippy in this case.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2025-01-14 00:26:01 +00:00
Rob Bradford
2624f17ffe virtio-devices: Automatically fix operator precedence clippy warning
Signed-off-by: Rob Bradford <rbradford@rivosinc.com>
2025-01-07 17:44:41 +00:00
Ruoqing He
0aab960bf1 misc: Elide needless lifetimes
As clippy of rust-toolchain version 1.83.0-beta.1 suggests, elide
needless lifetimes to `'_`.

Signed-off-by: Ruoqing He <heruoqing@iscas.ac.cn>
2024-10-18 17:46:39 +00:00
Ruoqing He
297236a7c0 misc: Eliminate use of assert!((...).is_ok())
Asserting on .is_ok()/.is_err() leads to hard to debug failures (as if
the test fails, it will only say "assertion failed: false". We replace
these with `.unwrap()`, which also prints the exact error variant that
was unexpectedly encountered (we can to this these days thanks to
efforts to implement Display and Debug for our error types). If the
assert!((...).is_ok()) was followed by an .unwrap() anyway, we just drop
the assert.

Inspired by and quoted from @roypat.

Signed-off-by: Ruoqing He <heruoqing@iscas.ac.cn>
2024-10-03 12:03:49 +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
Bo Chen
60c8a72e29 misc: Fix various warnings from clippy 0.1.82
An example warning output is:

error: first doc comment paragraph is too long
   --> virtio-devices/src/lib.rs:158:1
    |
158 | / /// Convert an absolute address into an address space (GuestMemory)
159 | | /// to a host pointer and verify that the provided size define a valid
160 | | /// range within a single memory region.
161 | | /// Return None if it is out of bounds or if addr+size overlaps a single region.
    | |_
    |
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#too_long_first_doc_paragraph
    = note: `-D clippy::too-long-first-doc-paragraph` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::too_long_first_doc_paragraph)]`

Signed-off-by: Bo Chen <chen.bo@intel.com>
2024-09-07 09:40:20 +00:00
Wei Liu
f5b2eb5c76 virtio-devices: vsock: drop a useless line
Signed-off-by: Wei Liu <liuwe@microsoft.com>
2024-07-31 16:36:10 +00:00
Wei Liu
82ac114b8a virtio-devices: vsock: handle short read in muxer
Use read_exact to make sure we really get the minimum number of bytes.

Fixes: #6621
Signed-off-by: Wei Liu <liuwe@microsoft.com>
2024-07-31 16:36:10 +00:00
Wei Liu
b3a73d6634 virtio-devices: fix documentation formatting
Signed-off-by: Wei Liu <liuwe@microsoft.com>
2024-06-12 16:59:20 +00:00
Josh Soref
42e9632c53 misc: Fix spelling issues
Misspellings were identified by:
  https://github.com/marketplace/actions/check-spelling

* Initial corrections based on forbidden patterns from the action
* Additional corrections by Google Chrome auto-suggest
* Some manual corrections
* Adding markdown bullets to readme credits section

Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com>
2024-06-08 16:31:30 +00:00
Wei Liu
862a056105 virtio-devices: vsock: fix two clippy warnings
The mem_size field is not needed in TestContext. Drop it.

Make sure guest_evvq is read once. Clippy cannot figured out that it was
used.

While at it, add an extra assert for the spurious rxvq event test, too.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2024-04-30 07:32:08 +00: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
Rob Bradford
fd81a23fcc virtio-devices: vsock: csm: Use thiserror to provide error messages
This resolves a nightly compiler check for unused enum inner value.

Signed-off-by: Rob Bradford <rbradford@rivosinc.com>
2024-03-25 04:32:28 +00:00
Rob Bradford
adb318f4cd misc: Remove redundant "use" imports
With the nightly toolchain (2024-02-18) cargo check will flag up
redundant imports either because they are pulled in by the prelude on
earlier match.

Remove those redundant imports.

Signed-off-by: Rob Bradford <rbradford@rivosinc.com>
2024-02-19 17:54:30 +00:00
Alyssa Ross
451d3fb2f0 vmm: limit VSOCK CIDs to 32 bits
The VIRTIO specification[1] says:

> The upper 32 bits of the CID are reserved and zeroed.

We should therefore not allow the user to supply a VSOCK CID with
those bits set.  To accomplish this, limit the public API of the
virtio-vsock device to only accept 32-bit CIDs, while still using
64-bit CIDs internally since that's how virtio-vsock works.

[1]: https://docs.oasis-open.org/virtio/virtio/v1.2/csd01/virtio-v1.2-csd01.html#x1-4400004

Signed-off-by: Alyssa Ross <hi@alyssa.is>
2024-01-10 17:28:56 +00:00
Alyssa Ross
48de800756 virtio-devices: fix reading vsock connect command
The socket is nonblocking, so it's not guaranteed that it will be
possible to read the whole connect command in a single iteration of
the event loop.  To reproduce:

	(echo -n 'CONNECT '; sleep 1; echo 1234; cat) | socat STDIO UNIX-CONNECT:vsock.sock

This would produce the error:

	cloud-hypervisor: 5.509209s: <_vsock4> INFO:virtio-devices/src/vsock/unix/muxer.rs:446 -- vsock: error adding local-init connection: UnixRead(Os { code: 11, kind: WouldBlock, message: "Resource temporarily unavailable" })

To fix this, if we only get a partial command, we need to save it for
future iterations of the event loop, and only proceed once we've read
a complete command.

Signed-off-by: Alyssa Ross <hi@alyssa.is>
2024-01-09 16:01:52 +00:00