Commit Graph

2881 Commits

Author SHA1 Message Date
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
Rob Bradford
a96da9d4bc vmm: Introduce PciDeviceCommonConfig::validate()
Implement some common PCI segment validation. This can be used to reduce
duplication across the different validation methods.

Signed-off-by: Rob Bradford <rbradford@meta.com>
2026-04-14 14:19:34 +00:00
Rob Bradford
c66c2b8470 vmm: config: Implement PciDeviceCommonConfig::parse
This parses a subset of the device configuration options used for
devices that are PCI based.

Signed-off-by: Rob Bradford <rbradford@meta.com>
2026-04-14 14:19:34 +00:00
Rob Bradford
4f7ff8fe48 vmm: Introduce a PciDeviceCommonConfig struct
Introduce a common struct that can encompass all the config fields
used by devices that are PCI based. The use of `skip_serializing_if`
means that the iommu field will only be included if set (otherwise
falling back to default false). This neatly handles the devices that
don't support an iommu.

Signed-off-by: Rob Bradford <rbradford@meta.com>
2026-04-14 14:19:34 +00:00
Shayon Mukherjee
0a32a9ca91 vmm: add compile-time validation for userfaultfd ioctl constants
Cross-check each UFFDIO_* constant against the Linux _IOC(dir, type,
nr, size) encoding formula at compile time so that transposed direction
bits or struct sizes are caught immediately rather than silently
producing wrong ioctl numbers at runtime.

Signed-off-by: Shayon Mukherjee <shayonj@gmail.com>
2026-04-14 14:17:40 +00:00
Zhiheng Tao
df58e814eb vmm: fix UFFDIO_WAKE and UFFD_FEATURE_MISSING_HUGETLBFS
UFFDIO_WAKE was 0x4010_aa02 (_IOW) but should be 0x8010_aa02,
causing every wake call to silently fail with -EINVAL.

UFFD_FEATURE_MISSING_HUGETLBFS was (1<<6) but should be (1<<4),
colliding with UFFD_FEATURE_EVENT_UNMAP.

Signed-off-by: Zhiheng Tao <junchuan.tzh@antgroup.com>
2026-04-14 11:20:32 +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
Philipp Schuster
2515b06f19 vmm: incoming migration: log duration of state receive and VM resume
Instrument the two main downtime-phase operations on the destination
side - receiving state and resuming the VM - so their costs are visible
in logs and can be iterated on.

The new log messages may look like this:

```text
cloud-hypervisor:   7.283424s: <vmm> DEBUG:vmm/src/lib.rs:948 -- Migration (incoming): recv_snapshot:3ms restore:10ms
cloud-hypervisor:   7.284824s: <vmm> DEBUG:vmm/src/lib.rs:967 -- Migration (incoming): resume:1ms
cloud-hypervisor:   7.284842s: <vmm> DEBUG:vmm/src/lib.rs:977 -- Migration (incoming): Receiving final state and resuming the VM took 15ms
```

On-behalf-of: SAP philipp.schuster@sap.com
Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
2026-04-13 09:52:23 +00:00
Philipp Schuster
f15999823d vmm: outgoing migration: log effective downtime
Use OngoingMigrationContext to measure and log the effective VM downtime
(pause to remote resume) and the cost of each non-trivial step in the
downtime window: snapshotting, sending the snapshot, and awaiting
completion. This makes it straightforward to identify and reduce
downtime as live migration matures.

Example:

```
cloud-hypervisor:   7.703402s: <vmm> INFO:vmm/src/lib.rs:1494 -- Migration completed after 2.2s with a downtime of 298ms (goal was 300ms)
cloud-hypervisor:   7.703453s: <vmm> DEBUG:vmm/src/lib.rs:1500 -- Downtime breakdown: 298ms (final_iter:269ms state:7ms send_state:19ms complete:1ms)
```

Note: downtime is measured on the source only; cross-host clock skew
may cause unreliable results.

# Terminology

At first glance, the use of "state" and "[VM] snapshot" may seem
confusing. As discussed in [0], we use "state" consistently in the
migration code. On the VM side, "snapshotting" is merely the mechanism
used to obtain the VM state.

[0] https://github.com/cloud-hypervisor/cloud-hypervisor/pull/7979#discussion_r3061359899

On-behalf-of: SAP philipp.schuster@sap.com
Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
2026-04-13 09:52:23 +00:00
Philipp Schuster
f32506447f vmm: add helper to measure successful operation duration
Add a small helper that returns both the successful result of an
operation and the time it took to complete.

Subsequent migration instrumentation uses this to keep timing code
compact and consistent.

On-behalf-of: SAP philipp.schuster@sap.com
Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
2026-04-13 09:52:23 +00:00
Max Makarov
87ba83bb01 vmm: pci_segment: use segment id as ACPI _UID
The ACPI specification requires _UID to be unique across devices
sharing the same _HID (ACPI 6.5 section 6.1.12). Currently every
PciSegment emits _UID=0 for its PNP0A08 host bridge, which violates
the spec when num_pci_segments > 1.

Windows guests detect this during ACPI namespace enumeration and
abort boot with BSOD 0xA5 ACPI_BIOS_ERROR, pointing at the _UID
object of the second PNP0A08 node. Linux guests are lenient and
silently accept the collision, so the issue has gone unnoticed.

Use self.id as _UID, matching what _SEG does on the line above.
For single-segment VMs (id == 0) this is a no-op at runtime.

Signed-off-by: Max Makarov <maxpain@linux.com>
2026-04-13 09:39:55 +00:00
JP Kobryn
bdc7a6947d vmm: add per-zone mergeable option to --memory-zone
Add a `mergeable` field to `MemoryZoneConfig` so that KSM page merging
can be enabled selectively per memory zone rather than globally for all
guest RAM.

Previously, `MADV_MERGEABLE` was only controllable via the top-level
`--memory mergeable=on` flag, which applied uniformly to all regions.
With this change, users can leave boot memory unmerged while enabling
KSM only on hotplug zones:

  --memory size=0,hotplug_method=virtio-mem
  --memory-zone id=boot,size=512M,shared=on,mergeable=off
  --memory-zone id=hotplug,size=256M,hotplug_size=1G,shared=off,mergeable=on

The `MemoryZone` runtime struct now carries the `mergeable` flag so
that both `allocate_address_space` and `add_ram_region` can apply
per-zone `MADV_MERGEABLE` instead of the global `self.mergeable`.
The top-level `--memory mergeable=on` path continues to work unchanged:
the default zone is synthesised from `MemoryConfig` and inherits its
`mergeable` value.

AI/LLM disclosure: this patch was co-authored with
GitHub Copilot and Claude Code (Opus 4.6).

Signed-off-by: JP Kobryn <inwardvessel@gmail.com>
2026-04-11 09:01:57 +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
32c459c3dc virtio-devices, vmm: Add seccomp rules for iommufd and vfio cdev
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
Bo Chen
13972a0edf vmm: Introduce option --platform iommufd=on|off
This option allows user to configure VFIO device pass-through with
iommufd (e.g. vfio cdev mode) or not (e.g. vfio legacy mode).

Signed-off-by: Bo Chen <bchen@crusoe.ai>
2026-04-10 22:55:38 +00:00
Bo Chen
7f377eadd9 vmm: Fix --platform syntax with optional feature flags
The `--platform` help string was hardcoded and did not reflect which
optional features (tdx, sev_snp) were actually enabled in. Build the
syntax string dynamically as `PlatformConfig::syntax()`, conditionally
appending feature-gated options so the CLI help stays accurate.

Signed-off-by: Bo Chen <bchen@crusoe.ai>
2026-04-10 22:55:38 +00:00
JP Kobryn
474106a067 vmm: skip uefi allocation on direct boot
A 4M uefi_region is allocated unconditionally. When directly booting a
kernel, it goes unused. Avoid the allocation in this case by moving the
call to add_uefi_flash() to load_firmware().

Also extended add_uefi_flash() to riscv64 since it shares the
load_firmware() path. It looked like up to this point a firmware boot on
riscv64 would panic with an uninitialized uefi_flash.

Signed-off-by: JP Kobryn <inwardvessel@gmail.com>
2026-04-09 23:18:00 +00:00
Jared White
77ce3f6cbf vmm: memory_actual_size reflects hotplug state
It is desirable to be able to track the progress of memory hotplug.
Update the memory_actual_size field to query the current plugged size
from virtio-mem to enable this.

Signed-off-by: Jared White <git@jaredwhite.dev>
2026-04-07 01:37:37 +00:00
Sebastian Eydam
ecddc6f842 vmm: add upper limit for amount of parallel connections during migration
Check that the amount of parallel connections does not exceed 128 and
update documentation.

On-behalf-of: SAP sebastian.eydam@sap.com
Signed-off-by: Sebastian Eydam <sebastian.eydam@cyberus-technology.de>
2026-04-02 23:43:42 +00:00
Sebastian Eydam
a9a832f392 vmm: validate VmSendMigrationData
Validates that there are no conflicting options set, and that the
destination URL is valid.

On-behalf-of: SAP sebastian.eydam@sap.com
Signed-off-by: Sebastian Eydam <sebastian.eydam@cyberus-technology.de>
2026-04-02 23:43:42 +00:00
Sebastian Eydam
fb19881918 vm-migration: add connections field to API
And wire everything up. From now on the multiple connections feature can
be used.

This commit series is heavily based on Julian Stecklina's work, so kudos
to him!

Co-authored-by: Julian Stecklina <julian.stecklina@cyberus-technology.de>
On-behalf-of: SAP sebastian.eydam@sap.com
Signed-off-by: Sebastian Eydam <sebastian.eydam@cyberus-technology.de>
2026-04-02 23:43:42 +00:00
Sebastian Eydam
55e6971c47 vmm: funnel VM memory via additional connections abstraction
At this point, we are still only using a single connection.

On-behalf-of: SAP sebastian.eydam@sap.com
Signed-off-by: Sebastian Eydam <sebastian.eydam@cyberus-technology.de>
2026-04-02 23:43:42 +00:00
Sebastian Eydam
07484abd35 vmm: implement functionality to send via multiple connections
Implements the functionality to send VM memory via multiple connections
during a live migration.

On-behalf-of: SAP sebastian.eydam@sap.com
Signed-off-by: Sebastian Eydam <sebastian.eydam@cyberus-technology.de>
2026-04-02 23:43:42 +00:00
Sebastian Eydam
5a2dea8fa6 vmm: implement a gate
This gate behaves like a barrier, but it can be opened, meaning that
threads can be released before all threads arrived at the gate. This
lets us release waiting threads in case of an error, which will be
important for the sender side of a live migration with multiple
TCP connections.

On-behalf-of: SAP sebastian.eydam@sap.com
Signed-off-by: Sebastian Eydam <sebastian.eydam@cyberus-technology.de>
2026-04-02 23:43:42 +00:00
Sebastian Eydam
5c556880dd vmm: implement functionality to accept multiple connections
Adds the functionality to accept multiple connections on the receiver
side of a live migration. A thread listens for incoming connections and
creates a worker for each new connection.

On-behalf-of: SAP sebastian.eydam@sap.com
Signed-off-by: Sebastian Eydam <sebastian.eydam@cyberus-technology.de>
2026-04-02 23:43:42 +00:00
Sebastian Eydam
058954a8c1 vmm: make receive_memory_ranges take the requests directly
This just removes some unnecessary indirections.

On-behalf-of: SAP sebastian.eydam@sap.com
Signed-off-by: Sebastian Eydam <sebastian.eydam@cyberus-technology.de>
2026-04-02 23:43:42 +00:00
Sebastian Eydam
98ece1e347 vmm: add functionality for an abortable accept for sockets
With this, the receiver side of a migration can wait for incoming
connections, while also being able to abort the accept when the
migration is done.

On-behalf-of: SAP sebastian.eydam@sap.com
Signed-off-by: Sebastian Eydam <sebastian.eydam@cyberus-technology.de>
2026-04-02 23:43:42 +00:00
Sebastian Eydam
7311211b38 vmm: allow keeping the socket listener around
This allows accepting multiple connections in the migration receive
path.

On-behalf-of: SAP sebastian.eydam@sap.com
Signed-off-by: Sebastian Eydam <sebastian.eydam@cyberus-technology.de>
2026-04-02 23:43:42 +00:00
Sebastian Eydam
765311085f vmm: keep direct reference to guest memory around
That way we avoid having to grab a lock when receiving a chunk of memory
over the migration socket. This is a necessary prerequisite for having
multiple memory receiving threads.

On-behalf-of: SAP sebastian.eydam@sap.com
Signed-off-by: Sebastian Eydam <sebastian.eydam@cyberus-technology.de>
2026-04-02 23:43:42 +00:00
Sebastian Eydam
ec42ee8004 vmm: extract receive_memory_regions from memory manager
The memory manager is guarded by a mutex, thus parallel accesses to it
and its members are not possible. But we have to execute this function
in parallel when we introduce multiple TCP connections. Otherwise, the
workers who receive the data and write it into guest memory will block
on each other, and thus slow down the migration.

Also rename the function to receive_memory_ranges for better naming
consistency.

On-behalf-of: SAP sebastian.eydam@sap.com
Signed-off-by: Sebastian Eydam <sebastian.eydam@cyberus-technology.de>
2026-04-02 23:43:42 +00:00
Sebastian Eydam
e175ad64f2 vmm: move SocketStream into the migration_transport module
This is mainly to clean up the lib.rs a bit more.

On-behalf-of: SAP sebastian.eydam@sap.com
Signed-off-by: Sebastian Eydam <sebastian.eydam@cyberus-technology.de>
2026-04-02 23:43:42 +00:00
Sebastian Eydam
9248143e18 vmm: extract send_memory_regions from vm
And rename it for better naming consistency.

On-behalf-of: SAP sebastian.eydam@sap.com
Signed-off-by: Sebastian Eydam <sebastian.eydam@cyberus-technology.de>
2026-04-02 23:43:42 +00:00
Sebastian Eydam
e03c0f7708 vmm: move function to send dirty pages into transport module
On-behalf-of: SAP sebastian.eydam@sap.com
Signed-off-by: Sebastian Eydam <sebastian.eydam@cyberus-technology.de>
2026-04-02 23:43:42 +00:00
Sebastian Eydam
693cdccbb0 vmm: extract a helper to send the VM state
On-behalf-of: SAP sebastian.eydam@sap.com
Signed-off-by: Sebastian Eydam <sebastian.eydam@cyberus-technology.de>
2026-04-02 23:43:42 +00:00
Sebastian Eydam
196e48af30 vmm: extract a helper to send the VM config
This further decreases boilerplate code in lib.rs while keeping the
behavior.

On-behalf-of: SAP sebastian.eydam@sap.com
Signed-off-by: Sebastian Eydam <sebastian.eydam@cyberus-technology.de>
2026-04-02 23:43:42 +00:00
Sebastian Eydam
d4a8d55074 vmm: extract small request/response helpers to reduce boilerplate
On-behalf-of: SAP sebastian.eydam@sap.com
Signed-off-by: Sebastian Eydam <sebastian.eydam@cyberus-technology.de>
2026-04-02 23:43:42 +00:00
Sebastian Eydam
bb3e1b4073 vmm: stop removing the UNIX socket file
When doing a local migration using a UNIX socket, we removed the UNIX
socket file after accepting the connection. The VMM does not own this
socket file, which makes this an unsafe operation. Thus, we stop doing
that.

On-behalf-of: SAP sebastian.eydam@sap.com
Signed-off-by: Sebastian Eydam <sebastian.eydam@cyberus-technology.de>
2026-04-02 23:43:42 +00:00
Sebastian Eydam
d2f6476149 vmm: move migration socket helpers into transport module
On-behalf-of: SAP sebastian.eydam@sap.com
Signed-off-by: Sebastian Eydam <sebastian.eydam@cyberus-technology.de>
2026-04-02 23:43:42 +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
Bo Chen
0686045290 vmm: interrupt: Allocate GSIs for MSI/MSI-X interrupt vectors lazily
Previously, GSIs were eagerly allocated for all MSI-X vectors a device
advertises (i.e. the maximum the device can support). This can easily
exhaust KVM_MAX_IRQ_ROUTES (4096) with modern NVMe devices that support
up to 2048 MSI-X vectors.

Defer GSI allocation to the first time an interrupt vector is
unmasked. The EventFd is still created eagerly since external
components (e.g. VFIO) need it at device init time.

Signed-off-by: Bo Chen <bchen@crusoe.ai>
2026-04-01 01:25:44 +00:00
Bo Chen
820140930a vmm: interrupt: Reduce visibility of internal types and methods
Signed-off-by: Bo Chen <bchen@crusoe.ai>
2026-04-01 01:25:44 +00:00
CMGS
ca58685f4c vmm: call notify_guest_clock_paused for Hyper-V guests
Previously, KVM_KVMCLOCK_CTRL was skipped when kvm_hyperv=on because
Windows does not use pvclock directly. However, KVM internally uses
pvclock data structures as the basis for computing the Hyper-V
Reference TSC page parameters. Not calling KVM_KVMCLOCK_CTRL means
there is no mechanism to signal time discontinuity to Windows guests
after pause/resume, contributing to multi-minute hangs.

Remove the kvm_hyperv guard so all guests receive the clock-paused
notification.

Signed-off-by: CMGS <ilskdw@gmail.com>
2026-03-31 13:09:30 +00:00
CMGS
ff20f18364 vmm: restore KVM clock before resuming vCPUs
Reorder resume() to: set_clock, device_manager.resume,
cpu_manager.resume. This matches the inverse of pause()
which correctly saves the clock before pausing vCPUs.

Signed-off-by: CMGS <ilskdw@gmail.com>
2026-03-31 08:39:20 +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