Commit Graph

804 Commits

Author SHA1 Message Date
Philipp Schuster
5ff4696cea vmm: introduce ACPI CPU hotplug controller (fix deadlock)
Extract AcpiCpuHotplugController from CpuManager and move the BusDevice
implementation to the new type. This separates VMM-internal vCPU
management from the guest-visible ACPI CPU hotplug MMIO interface.

Besides clarifying responsibilities and reducing technical debt, this
fixes a rare deadlock involving pause handling and MMIO access.

New responsibilities:
- CpuManager manages VMM-internal vCPU lifecycle and coordination
- AcpiCpuHotplugController implements the guest-visible ACPI CPU hotplug
  MMIO interface

A vCPU thread may exit KVM_RUN to perform an MMIO access previously
handled by CpuManager. If the VMM thread begins processing a `pause`
event before that MMIO operation acquires access to CpuManager,
CpuManager::pause() will block waiting for the vCPU thread to ACK
the pause, while the vCPU thread is blocked waiting to complete the MMIO
operation through the same CpuManager - which it can never lock - the
VMM is deadlocked.

This can occur during early boot or CPU hotplug when pause events race
with MMIO accesses. The issue is rare and timing-dependent, but real.
For reproducing: run `ch-remote pause|resume` in a loop while booting
a Linux VM (via direct kernel boot).

With the new design, these MMIO operations no longer depend on
CpuManager, which removes the deadlock path entirely.

On-behalf-of: SAP philipp.schuster@sap.com
Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
2026-04-15 11:57:23 +00:00
Anatol Belski
3d5a40dfa6 vmm: device_manager: Wire up QcowDiskAsync with io_uring
When io_uring is available and not disabled, open QCOW2 images
with QcowDiskAsync for asynchronous reads. Falls back to
QcowDiskSync otherwise.

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2026-04-14 22:11:26 +00:00
Rob Bradford
cc7e56fa07 vmm: device_manager: Use more idiomatic Rust for ID assignment
Use a more idiomatic Rust approach when establishing an autogenerated ID
when none is set.

Signed-off-by: Rob Bradford <rbradford@meta.com>
2026-04-14 14:19:34 +00:00
Rob Bradford
7ac877cc26 vmm: device_manager: Reuse PciDeviceCommonConfig in MetaVirtioDevice
This struct has the same members and it can be reused to reduce
complexity now and if other common PCI related fields need to be
added in the future.

Signed-off-by: Rob Bradford <rbradford@meta.com>
2026-04-14 14:19:34 +00:00
Rob Bradford
37b1ed1b84 vmm: config: Switch VsockConfig to use PciDeviceCommonConfig
Switch VsockConfig over to using the newly extracted struct members as
used by all PCI based devices. The use of #[serde(flatten)] means that
this change has no impact on the JSON format that the data is stored as.

Signed-off-by: Rob Bradford <rbradford@meta.com>
2026-04-14 14:19:34 +00:00
Rob Bradford
ece77c3c52 vmm: config: Switch VdpaConfig to use PciDeviceCommonConfig
Switch VdpaConfig over to using the newly extracted struct members as
used by all PCI based devices. The use of #[serde(flatten)] means that
this change has no impact on the JSON format that the data is stored as.

Signed-off-by: Rob Bradford <rbradford@meta.com>
2026-04-14 14:19:34 +00:00
Rob Bradford
2c50be4753 vmm: config: Switch UserDeviceConfig to use PciDeviceCommonConfig
Switch UserDeviceConfig over to using the newly extracted struct members
as used by all PCI based devices. The use of #[serde(flatten)] means
that this change has no impact on the JSON format that the data is
stored as.

As VFIO user devices do not support being placed behind an IOMMU an
error is now raised if iommu is set. This can't happen via the CLI but
could via the JSON/API.

Signed-off-by: Rob Bradford <rbradford@meta.com>
2026-04-14 14:19:34 +00:00
Rob Bradford
47182201f9 vmm: config: Switch DeviceConfig to use PciDeviceCommonConfig
Switch DeviceConfig over to using the newly extracted struct members as
used by all PCI based devices. The use of #[serde(flatten)] means that
this change has no impact on the JSON format that the data is stored as.

Signed-off-by: Rob Bradford <rbradford@meta.com>
2026-04-14 14:19:34 +00:00
Rob Bradford
c9082570b0 vmm: config: Switch PmemConfig to use PciDeviceCommonConfig
Switch PmemConfig over to using the newly extracted struct members as
used by all PCI based devices. The use of #[serde(flatten)] means that
this change has no impact on the JSON format that the data is stored as.

Signed-off-by: Rob Bradford <rbradford@meta.com>
2026-04-14 14:19:34 +00:00
Rob Bradford
0d3080e036 vmm: config: Switch GenericVhostUserConfig to use PciDeviceCommonConfig
Switch GenericVhostUserConfig over to using the newly extracted struct
members as used by all PCI based devices. The use of #[serde(flatten)]
means that this change has no impact on the JSON format that the data is
stored as.

As generic vhost-user devices do not support being placed behind an
IOMMU an error is now raised if iommu is set. This can't happen via the
CLI but could via the JSON/API.

Signed-off-by: Rob Bradford <rbradford@meta.com>
2026-04-14 14:19:34 +00:00
Rob Bradford
40150dd72d vmm: config: Switch FsConfig to use PciDeviceCommonConfig
Switch FsConfig over to using the newly extracted struct members as used
by all PCI based devices. The use of #[serde(flatten)] means that this
change has no impact on the JSON format that the data is stored as.

As virtio-fs does not support being placed behind an IOMMU an error is
now raised if iommu is set. This option is not exposed via the CLI but
could happen with a miscontructed JSON/API call.

Signed-off-by: Rob Bradford <rbradford@meta.com>
2026-04-14 14:19:34 +00:00
Rob Bradford
92c2cf0103 vmm: config: Switch NetConfig to use PciDeviceCommonConfig
Switch NetConfig over to using the newly extracted struct members as
used by all PCI based devices. The use of #[serde(flatten)] means that
this change has no impact on the JSON format that the data is stored as.

Signed-off-by: Rob Bradford <rbradford@meta.com>
2026-04-14 14:19:34 +00:00
Rob Bradford
d2ce7667bc vmm: config: Switch DiskConfig to use PciDeviceCommonConfig
Switch DiskConfig over to using the newly extracted struct members as
used by all PCI based devices. The use of #[serde(flatten)] means that
this change has no impact on the JSON format that the data is stored as.

Signed-off-by: Rob Bradford <rbradford@meta.com>
2026-04-14 14:19:34 +00:00
CMGS
0a4be0c1c7 vmm: extend last MMIO64 allocator to cover full range
The MMIO64 allocator size is computed with alignment truncation:
  size = (range / alignment) * alignment
This loses up to one alignment unit (4 GiB) at the top of the
address space. When a guest (Windows with virtio-win 0.1.285)
programs a BAR near the top of the physical address space, the
allocation fails because the address falls in the truncated gap.

Give the last PCI segment allocator all remaining space up to
the end of the device area, so no addresses are lost.

The `end` parameter of create_mmio_allocators() is an inclusive
address (the last valid byte). Fix the 32-bit caller and tests
to pass inclusive values, consistent with the 64-bit caller
which already uses the inclusive end_of_device_area().

Signed-off-by: CMGS <ilskdw@gmail.com>
2026-04-13 10:25:18 +00:00
Bo Chen
87992c77c1 vmm: Introduce option --platform vfio_p2p_dma=on|off
Add a user-configurable option to control whether VFIO device MMIO BAR
regions are DMA-mapped into the host IOMMU address space.

This mapping is required for peer-to-peer DMA between devices (e.g.
NVLink, RDMA NIC accessing GPU VRAM). However, iommufd on upstream
kernels does not support mapping device MMIO pages (VM_PFNMAP), causing
IOMMU_IOAS_MAP to fail with -EFAULT. Kernels with the NVIDIA PFNMAP
workaround or future kernels with DMABUF-based mapping
(IOMMU_IOAS_MAP_FILE) handle this correctly.

The option defaults to `on` to preserve existing behavior. Users on
vanilla kernels using iommufd should set `vfio_p2p_dma=off` to skip
MMIO BAR DMA mapping.

A validation check ensures that `x_nv_gpudirect_clique` (which depends
on P2P DMA) cannot be used when `vfio_p2p_dma=off`.

Signed-off-by: Bo Chen <bchen@crusoe.ai>
2026-04-10 22:55:38 +00:00
Bo Chen
fe5f991c37 vmm: Support device passthrough with vfio cdev and iommufd
When `--platform iommufd=on` is set, use the vfio cdev interface backed
by iommufd instead of the legacy vfio container/group interface for
device passthrough.

The cdev path opens '/dev/iommu' via IommuFd, allocates an IOAS, and
binds VFIO devices through VfioIommufd. The legacy container/group path
remains the default and is used when iommufd is not enabled.

Add iommufd-ioctls as a workspace dependency and enable the "vfio_cdev"
feature on vfio-ioctls for KVM builds.

Fixes: #6892

Signed-off-by: Bo Chen <bchen@crusoe.ai>
2026-04-10 22:55:38 +00:00
Chinmoy
d0b253472d pci, devices, virtio-devices, vmm: Refactor allocate_bars
Refactor PciDevice::allocate_bars trait and all implementations
to take &mut SystemAllocator instead of &Arc<Mutex<SystemAllocator>>,
removing double indirection.

The caller in device_manager.rs now acquires the lock before
calling allocate_bars.

Signed-off-by: Chinmoy <daschinmoyy21@gmail.com>
2026-04-02 11:52:04 +00:00
Chinmoy
ef9133a3ee vmm: acpi: Take &T instead of &Arc<Mutex<T>>
Refactor ACPI table creation functions to accept borrowed
references, removing double indirection and moving locking
to callers.

Signed-off-by: Chinmoy <daschinmoyy21@gmail.com>
2026-04-02 11:52:04 +00:00
Muminul Islam
783cc8bbd9 block: Remove legacy DiskFile impl from RawFileDiskAio
Remove the old async_io::DiskFile trait implementation from
RawFileDiskAio, now that the new disk_file trait hierarchy
is fully implemented.

Clean up unused imports: DiskFile and DiskFileResult from
crate::async_io.

Signed-off-by: Muminul Islam <muislam@microsoft.com>
2026-04-02 01:18:30 +00:00
Anatol Belski
c90f5a9e47 vmm: Switch fixed VHD sync to DiskBackend::Next
Wire FixedVhdDiskSync through the new composable trait system.

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2026-03-30 22:18:09 +00:00
Anatol Belski
24e9049280 block: vhd: Switch FixedVhdDiskSync::new to BlockResult
Classify the io::Error as BlockErrorKind::Io with ErrorOp::Open.
Update vmm CreateFixedVhdDiskSync to take BlockError.

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2026-03-30 22:18:09 +00:00
Anatol Belski
b703043f77 vmm: Switch VHDX to DiskBackend::Next
Wire VhdxDiskSync through DiskBackend::Next instead of Legacy.

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2026-03-30 22:17:01 +00:00
Anatol Belski
b8b32f5927 block: vhdx: Switch VhdxDiskSync::new to BlockResult
Wrap VhdxError via BlockError::new(Io, e).with_op(Open). Update VMM
CreateFixedVhdxDiskSync error variant from VhdxError to BlockError.

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2026-03-30 22:17:01 +00:00
Anatol Belski
b69bd219fa vmm: Switch fixed VHD async to DiskBackend::Next
Wire FixedVhdDiskAsync through the new composable trait system.

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2026-03-30 22:16:04 +00:00
Anatol Belski
15073edf08 block: vhd: Switch FixedVhdDiskAsync::new to BlockResult
Map FixedVhd::new io::Error to BlockError with ErrorOp::Open.
Update vmm CreateFixedVhdDiskAsync source type accordingly.

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2026-03-30 22:16:04 +00:00
Muminul Islam
4f44cd9ed3 vmm: Switch RawFileDiskSync to DiskBackend::Next
Update device_manager.rs to construct DiskBackend::Next
instead of DiskBackend::Legacy for the synchronous raw
backend.

Signed-off-by: Muminul Islam <muislam@microsoft.com>
2026-03-30 22:15:31 +00:00
Muminul Islam
573f3af77d vmm: Switch RawFileDisk to DiskBackend::Next
Update device_manager.rs to construct DiskBackend::Next
instead of DiskBackend::Legacy for the io_uring raw backend.

Signed-off-by: Muminul Islam <muislam@microsoft.com>
2026-03-30 22:14:42 +00:00
Bo Chen
1bc49758a0 pci, vmm: Cleanup the naming and references to VFIO container
Following the `VfioContainer` to `VfioOps` trait switch, update the
remaining field names, method names, comments, and log messages to use
`vfio_ops` and "host IOMMU address space" consistently.

No fucntional changes.

Signed-off-by: Bo Chen <bchen@crusoe.ai>
2026-03-27 04:22:05 +00:00
Bo Chen
7360bfe33a pci, vmm: Switch to use more generic VfioOps trait
Replace the concrete `VfioContainer` type with the `VfioOps` trait
object for device passthrough. This decouples the VFIO DMA mapping
interface from the legacy VFIO container/group implementation, allowing
it to be extended to support VFIO cdev and iommufd in the future.

Signed-off-by: Bo Chen <bchen@crusoe.ai>
2026-03-27 04:22:05 +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
Anatol Belski
b4dad66d35 virtio-devices: vmm: fuzz: Switch to DiskBackend
Change Block to hold DiskBackend instead of
Box<dyn async_io::DiskFile>. In device_manager, existing formats
(raw, vhd, vhdx) are wrapped in DiskBackend::Legacy while
QcowDiskSync uses DiskBackend::Next. The fuzz target is updated
accordingly.

The Error::DiskResize variant now carries BlockError instead of
DiskFileError, matching the BlockResult return type of
DiskBackend::resize().

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2026-03-19 22:29:27 +00:00
Demi Marie Obenour
d609410b8b pci: Support injecting interrupts from externally-provided irqfds
The virtio vhost-user device backend prefers to use externally-provided
eventfds as irqfds.  This allows the frontend VM to notify the backend
VM directly, without the need for a userspace proxy process.  Since the
frontend can provide irqfds at any time, the backend needs to register
and unregister irqfds dynamically.

This is tricky because the functions that access the irqfd table all
take `&self`, not `&mut self`.  The obvious solution to this problem is
to wrap the table in a mutex.  Most of these functions are not called on
hot paths, but `.notifier()` is called whenever Cloud Hypervisor needs
to inject an interrupt into a guest.  Most devices don't need to
register irqfds at runtime, and for them, slowing down interrupt
injection would be wasteful.

Instead, require devices to opt-in to irqfd registration.  The irqfd
table now comes in two forms: one that contains a mutex and one that
does not.  The one containing a mutex can be mutated freely, while
attempting to mutate the one that does not will panic.

Right now, no code registeres irqfds at runtime, but this will change in
subsequent commits.

Signed-off-by: Demi Marie Obenour <demiobenour@gmail.com>
2026-03-18 09:25:27 +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
4fea912d18 block: qcow: Add open_disk_image helper with path context
Add a small helper in the block crate that opens a disk image
file and wraps any failure in a BlockError carrying the file
path and operation context. Use it from the vmm device manager
so that a failed open now reports which path couldn't be opened.

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2026-03-12 14:18:45 +00:00
Anatol Belski
b1bc376c91 block: Make detect_image_type return BlockResult with context
Convert detect_image_type() from io::Result to BlockResult so
that I/O failures carry the operation name in the error context.
Update the corresponding vmm error variant to wrap BlockError.

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2026-03-12 14:18:45 +00:00
Anatol Belski
58bdfaee3a block: qcow: QcowDiskSync returns BlockResult with path context
Change QcowDiskSync::new() to return BlockResult instead of
qcow::Result, mapping format specific errors to the appropriate
BlockErrorKind at the crate boundary. The vmm caller attaches
the disk image path to the error so failures identify which
file was being opened.

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2026-03-12 14:18:45 +00:00
Victor Vieux
7c690ffec0 vmm: config: Expose disk lock granularity option
Add a per-disk lock_granularity parameter that lets users choose
between byte-range OFD locks and whole-file OFD locks:

  --disk path=/foo.img,lock_granularity=byte-range
  --disk path=/bar.img,lock_granularity=full

Byte-range is the default and matches QEMU behavior, working
best with storage backends where whole-file OFD locks are treated
as mandatory. The full option restores the original whole-file
locking for environments that depend on it.

The LockGranularityChoice enum and its FromStr impl live in the
block crate alongside the existing LockGranularity type. The
Block device converts the user-facing choice to the internal
LockGranularity at lock time, keeping device_manager.rs simple.

Closes: #7553

Signed-off-by: Victor Vieux <vieux@repl.it>
2026-03-08 10:07:03 +00:00
Rob Bradford
9d712a10a6 vmm: Improve naming of ConsoleInfo struct members
These aren't FDs and we don't need to know that they are the main ones.

Signed-off-by: Rob Bradford <rbradford@meta.com>
2026-03-06 21:04:14 +00:00
Rob Bradford
9cb49a244e vmm: device_manager: Be consistent with transport variable name
Signed-off-by: Rob Bradford <rbradford@meta.com>
2026-03-06 21:04:14 +00:00
Rob Bradford
48dcfc5fd0 vmm: Rename ConsoleOutput to ConsoleTransport
This is not just used for determine the output but also the input to the
console where this can be bidirectional.

Signed-off-by: Rob Bradford <rbradford@meta.com>
2026-03-06 21:04:14 +00:00
Anatol Belski
1f93fef66f vmm: Remove dead QcowDeviceCreate error variant
The variant has been unused since commit 12e20effd which
replaced direct QcowFile creation with QcowDiskSync.

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2026-03-06 00:05:33 +00:00
Pascal Scholz
15d1f1d7fd vmm: Refactor locking in AddressManager::move_bar
The current implementation performs multiple operations on allocators in
a row, with the single goal of updating the allocator. For each of these
operations, the `Mutex` guarding the respective allocator is locked anew
which introduces room for race conditions.

Instead of locking the mutex multiple times, we should lock it once to
perform the whole move.

Signed-off-by: Pascal Scholz <pascal.scholz@cyberus-technology.de>
On-behalf-of: SAP pascal.scholz@sap.com
2026-02-26 11:56:59 +00:00
Demi Marie Obenour
085a7a49fa vmm: generic vhost-user: add support
Add VMM support for generic vhost-user devices.

Signed-off-by: Demi Marie Obenour <demiobenour@gmail.com>
2026-02-24 07:53:53 +00:00
Rob Bradford
b3e8e2abc5 vmm, virtio-devices: Deny zero sector writes for autodetected raw images
If the disk image was autodetected to raw (not specified with image_type
= 0) then in the virtio-block subsystem generate errors for writes to
block 0 (treat as if read-only). This gives an immediate error vs using
the image implementations in the block subsystem.

Signed-off-by: Rob Bradford <rbradford@meta.com>
2026-02-19 22:43:15 +00:00
Rob Bradford
6f2357c14e vmm: Improve resiliency of image type handling
Add an image_type to DiskConfig to specify the image type. If none is
specified autodetect the image type but disable potentially unsafe
behaviour in the QCOW2 backend by disabling the backing file support.

If the image type is autodetected then fix it in the config so that it
will be persistant across reboots and migrations/snapshot & restores.
This also handles the case where the image type was not specified as
part of the disk configuration.

Signed-off-by: Rob Bradford <rbradford@meta.com>
2026-02-19 22:43:15 +00:00
Anatol Belski
49a30cbbaf block: raw: Implement disk preallocation for sparse=false
When sparse=false is configured, preallocate the entire raw disk file
at startup using fallocate(). This provides space reservation and
reduces fragmentation.

Only applies to raw disks. QCOW2/VHD/VHDX formats manage their own
allocation.

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2026-02-13 18:44:30 +00:00
Anatol Belski
0a287793df block: qcow: Thread sparse configuration to QCOW2 constructors
Add sparse parameter to QcowFile constructors and propagate it from
device_manager through QcowDiskSync. This makes the sparse configuration
available throughout the QCOW2 implementation for controlling allocation
and deallocation behavior.

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2026-02-13 18:44:30 +00:00
Anatol Belski
7dfcbff309 vmm: config: Add sparse flag to control disk space allocation
Add sparse boolean configuration option to DiskConfig with a default
value of true to control disk space allocation behavior.

When sparse is true, the disk uses sparse allocation where deallocated
blocks are returned to the filesystem, and the DISCARD feature is
advertised to the guest.

When sparse is false, disk space is kept fully allocated and DISCARD
is not advertised.

WRITE_ZEROES is always advertised when the backend supports it,
regardless of the sparse setting.

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2026-02-13 18:44:30 +00:00
Muminul Islam
41b23229a5 vmm: refactor VM initialization into modular helper methods
Decompose the monolithic `new_from_memory_manager` function into
smaller, focused helper methods to improve code readability,
maintainability, and testability.

Changes:
- Extract `should_force_iommu()` to determine IOMMU requirements for
  confidential computing (TDX/SEV-SNP)
- Extract `should_stop_on_boot()` to check debug pause configuration
- Extract `create_cpu_manager()` to encapsulate CPU manager creation
  and CPUID population
- Extract `init_tdx_if_enabled()` for TDX-specific VM initialization
- Extract `create_device_manager()` to encapsulate device manager setup
- Extract `hypervisor_specific_init()` to orchestrate initialization
  sequences for different hypervisors (KVM, MSHV, SEV-SNP)
- Extract `init_sev_snp()` for SEV-SNP confidential VM setup
- Extract `init_mshv()` for MSHV hypervisor initialization
- Extract `init_kvm()` for KVM hypervisor initialization
- Extract `create_fw_cfg_if_enabled()` for fw_cfg device creation

This refactoring replaces complex nested `cfg_if!` blocks with cleaner
conditional method calls, providing clear separation between hypervisor-
specific initialization paths while preserving existing functionality.

No functional changes intended.
Issue: https://github.com/cloud-hypervisor/cloud-hypervisor/issues/7598

Signed-off-by: Muminul Islam <muislam@microsoft.com>
2026-02-13 10:18:50 +00:00
Saravanan D
dc0c306dd9 vmm: Add ACPI Generic Initiator support
Support ACPI Generic Initiator Affinity to associate
PCI devices with NUMA proximity domains

Add GenericInitiatorAffinity struct

Add from_pci_bdf() to encode PCI Segment:Bus:Device.Function

Add from_acpi_device() for ACPI device handles (future use)

Generate SRAT Type 5 entries for nodes with device_id

Improve create_slit_table() to check distance symmetry when
forward distance is missing

Track device ID to BDF mappings in DeviceManager

Includes comprehensive unit tests

Signed-off-by: Saravanan D <saravanand@crusoe.ai>
2026-02-12 22:54:54 +00:00