Commit Graph

749 Commits

Author SHA1 Message Date
Julian Schindel
4b5e2ef3a0 vmm: Lock disks after validating state change
On `VM::boot` call, lock disks only after the state change has been
checked for validity. Otherwise, on invalid state change, boot is
aborted, but file locks aren't rolled back.

On-behalf-of: SAP julian.schindel@sap.com
Signed-off-by: Julian Schindel <julian.schindel@cyberus-technology.de>
2026-07-23 15:27:30 +00:00
Rob Bradford
ab6afc21ec vmm: Generate common cpuid as part of CpuManager::new()
This removes a need to expose a method from the CpuManager back out to
the Vm which is called immediately after creating the CpuManager.

Signed-off-by: Rob Bradford <rbradford@meta.com>
2026-07-22 17:47:28 +01:00
Isaku Yamahata
9d3451a56a vmm: Fix aarch64 vmm::vm::unit_tests::test_create_fdt_with_devices()
test_create_fdt_with_devices() fails with a divide by zero.  The caller
passes Some((0, 0, 0, 0)) for CPU topology as (threads_per_core,
cores_per_die, dies_per_package, packages).  The valid default is
(1, 1, 1, 1), not all zero. Pass None because the eventual callee,
create_cpu_nodes(), checks None to get the right default value.

This affects the unit test only.  A real VM never hits it because
VmConfig::validate() rejects zero with an error.

Fixes: 7fb980f17 ("arch, vmm: Pass cpu topology configuation to FDT")
Assisted-by: Claude:Opus-4.8 (1M context)
Signed-off-by: Isaku Yamahata <iyamahata@crusoe.ai>
2026-07-22 08:53:04 +00:00
Alyssa Ross
cd2089eb69 build: Bump vm-memory and dependents
vm-memory 0.18 has renamed GuestMemory to GuestMemoryBackend, and made
GuestMemory refer to something less specific.  For simplicity, we keep
using GuestMemoryBackend (formerly GuestMemory) everywhere for now.  We
can adjust bounds to be less specific later if we find ourselves needing
the newly enabled flexibility.

Signed-off-by: Alyssa Ross <hi@alyssa.is>
Signed-off-by: Rob Bradford <rbradford@meta.com>
2026-07-20 17:51:23 +00:00
Pascal Scholz
ad3790a0ea vmm: Update memory zones
We consume `zone_updates` from `VmReceiveMigrationData` and
`RestoreConfig` to remap already existing `MemoryZone`s to different
host NUMA nodes. For now, we do not support further changes, such as
altering the size of the respective `MemoryZone`s.

These changes allow to migrate a VM to a host that has the capacity to
host the same `MemoryZone`s on a different NUMA layout.

Signed-off-by: Pascal Scholz <pascal.scholz@cyberus-technology.de>
On-behalf-of: SAP pascal.scholz@sap.com
2026-07-20 16:06:55 +00:00
Sebastien Boeuf
1ad1de1398 vmm: Perform sparse initial memory transfer for live migration
Add sparse region support to remote live migration as it will save some
of the network bandwidth and therefore speed up the migration to the
destination VM.

Instead of sending the entire guest RAM over the network, only send
ranges which have been populated during the first iteration. Pages full
of holes are simply skipped.

Signed-off-by: Sebastien Boeuf <sboeuf@meta.com>
Assisted-by: Claude:claude-opus-4-8
2026-07-17 12:39:03 +00:00
Rob Bradford
5b53f4202d vmm: Reject removal of already removed devices
A hot-unplug leaves the PCI node in the device tree until the guest
acknowledges the ejection, but VmConfig drops the device entry
immediately.

Move the config removal into DeviceManager::remove_device() and fail
when it returns false, so a second remove-device request cannot reuse
the stale device-tree node.

Assisted-by: OpenAI:Codex-GPT-5
Signed-off-by: Rob Bradford <rbradford@meta.com>
2026-07-08 21:42:49 +00:00
Rob Bradford
6de90bdec6 vmm: Error out on migration & snapshot if on-demand restoring
If there is an active on-demand restoration then reject any requests to
migrate or snapshot this VM as the memory will not be available for the
snapshot.

Signed-off-by: Rob Bradford <rbradford@meta.com>
2026-07-08 17:30:26 +00:00
Henry Hrvoje Tonkovac
ae7c0dd9f1 build: exempt arch from clippy::absolute_paths, use full paths
Suggested by phip1611 on #8446.

This adds the repo's first clippy.toml, carving arch out of the
absolute_paths deny from #7670. Glob imports and trait imports that
must be in scope for method-call resolution (e.g. DeviceInfoForFdt for
.irq()) are left as-is.

Signed-off-by: Henry Hrvoje Tonkovac <htonkovac@gmail.com>
Assisted-by: Claude:Opus-4.8
2026-07-01 16:27:46 +00:00
Philipp Schuster
013981b649 vm-migration: improve debuggability on receiver for failed migrations
We cannot reliably send Request::abandon() on every kind of failure on
the sender side, as we might be in the middle of a memory transmission.
The receiver would not reliably know what to do with that. So instead,
when the receiver cannot read from the socket, we log that the migration
sender failed, which is the only likely cause of that failure.

On-behalf-of: SAP philipp.schuster@sap.com
Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
2026-06-30 16:59:20 +00:00
Sebastian Eydam
969d2f855d vm-migration: stop sending abandon after error response
When the receiver of a live migration encounters an error, it sends an
error response. The sender of the migration would then send an abandon
request and wait for a response. This abandon request is not necessary,
because the receiver already abandoned the migration due to the error it
encountered.

From now on this function will not send an abandon request to the
receiver anymore, thus it was renamed to "ok_or_error".

Also, this case was always broken, because after sending the error
response, the receiver just exits without waiting for the additional
abandon request.

On-behalf-of: SAP sebastian.eydam@sap.com
Signed-off-by: Sebastian Eydam <sebastian.eydam@cyberus-technology.de>
2026-06-30 16:59:20 +00:00
Philipp Schuster
4d727c4899 vmm: keep virtio activation alive in migration
Live migration can deadlock if the guest triggers a virtio device
activation while the migration worker owns the VM.

The failure shows up when starting live migrations during boot and
firmware startup, where the guest can reset and reinitialize virtio
devices while precopy is running. In the failing case, the source log
shows a pending virtio activation that never completes:

    8.115833s _virtio-pci-net_0: Needs activation; returning barrier
    8.115854s vmm/src/vm.rs:464 -- Waiting for barrier
    24.875452s Entering downtime phase
    24.875481s stopping vcpu throttling thread
    ...
    vCPU thread did not respond in 10ms to signal - retrying
    vCPU thread did not respond in 20ms to signal - retrying
    ...
    thread 'throttle-vcpu' (1029) panicked
    ...
    Pause(Error signalling vCPUs: Timeout when waiting for signal
        to be acknowledged)

The vCPU blocks on the activation barrier and never reaches the normal
pause checkpoint. Later, migration enters downtime and stops the vCPU
throttle thread. In the failing case, that thread is still inside a
CpuManager::pause() call, which waits for every vCPU to acknowledge
the signal. The blocked vCPU never does, so the pause times out.

Fix this by storing the DeviceManager inside VmOwnership::Migration.
This keeps just enough state on the VMM thread to drain pending virtio
activations while the migration worker owns the Vm. The barrier logic
stays unchanged. The VMM now releases the same activation barrier during
migration that it already released before migration started.

This keeps the guest from getting stuck in the activation wait and
lets the later pause succeed.

Co-authored-by: Leander Kohler <leander.kohler@cyberus-technology.de>
On-behalf-of: SAP leander.kohler@sap.com
Signed-off-by: Leander Kohler <leander.kohler@cyberus-technology.de>

On-behalf-of: SAP philipp.schuster@sap.com
Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
2026-06-26 16:42:37 +00:00
Philipp Schuster
8c71a0d821 vmm: make migration errors more helpful
Keep the original error sources while adding operation context to the
straightforward migration send and receive paths. This keeps up a
chain of errors that can be printed nicely and in a helpful way.

This commit does that for all MigratableError-occurences where this
change is easily applicable.

Co-authored-by: Sebastian Eydam <sebastian.eydam@cyberus-technology.de>

On-behalf-of: SAP philipp.schuster@sap.com
Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
2026-06-25 19:12:15 +00:00
Henry Hrvoje Tonkovac
f720e619c1 misc: use prelude size_of
size_of is part of std::prelude as of Rust 1.80 (with size_of_val,
align_of, align_of_val), and the workspace MSRV is 1.89, so qualifying
it (mem::size_of, std::mem::size_of, core::mem::size_of) is unnecessary.

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

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

Signed-off-by: Henry Hrvoje Tonkovac <htonkovac@gmail.com>
Assisted-by: Claude:Opus-4.8
2026-06-25 16:54:35 +00:00
Henry Hrvoje Tonkovac
025e782e50 vmm: 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

Signed-off-by: Henry Hrvoje Tonkovac <htonkovac@gmail.com>
Assisted-by: Claude:Opus-4.8
2026-06-24 15:12:32 +00:00
Philipp Schuster
796fc055bd vmm: migration: handle in dedicated thread (make async)
This puts the send-migration action into a dedicated thread, laying the
groundwork for many follow-ups towards first-class live-migration in
CH.

This means:

1. The send-migration call will exit sooner (just trigger the
   migration - dispatch semantics)
2. Other API calls can be triggered while a migration is ongoing but
   will not be able to alter the VM as the VM's ownership is transferred
   from the VMM to the migration thread. Example: hotplugging won't work
   (which is good).
3. This is the basis for migration statistics via a dedicated endpoint
   (future work).

The whole change was done with a special focus on graceful recover and
cleanup: even if anything on the migration paths go wrong, the proper
cleanups are already executed and the VMM can take back the ownership
of the VM.

The receive-migration API call remains blocking. To observe any status
changes about the migration on the sender side, one can observe the
event-monitor output and look for `vm.migration-{failed,finished}`.

These changes are inspired by [0] but differ significantly in details.

[0] https://github.com/cloud-hypervisor/cloud-hypervisor/pull/7038

On-behalf-of: SAP philipp.schuster@sap.com
Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
2026-06-22 19:11:42 +00:00
Rob Bradford
6fee484715 vmm: Reject resizing below the boot size with an error
This was already handled with user memory zones but not with the default
memory. Make a small refactoring to move the boot RAM check into
MemoryManager rather than split across Vm and MemoryManager.

Signed-off-by: Rob Bradford <rbradford@meta.com>
2026-06-19 08:11:16 +00:00
Atish Patra
25271c9d0c hypervisor: aarch64: advance the guest counter on restore and migration
Currently, Cloud Hypervisor round-trips CNTVCT_EL0 through
KVM_GET_REG_LIST/SET_ONE_REG, which leaves a cold-restored or migrated
guest behind real UTC by the downtime. Same-host pause/resume
self-corrects (the physical counter keeps running across the pause), so
only restore and migration cases required the clock to catch up to wall
clock time.

Since ARM has no kernel helper, compute the difference in wall clock
time and compute the ticks so that it can advance the CNTVCT correctly.
It is set via vcpu0 only as it affects a single VM wide value after
Linux 6.4. For older kernels, it was a truly vcpu value which needs to
be invoked for every vcpu.

Gated on all(target_arch = "aarch64", feature = "kvm"); x86 is
unchanged.

Basic manual test case (aarch64 + KVM) verified both in intra host and
inter host snapshot save/restore:

1. Boot a Linux guest; in the guest, `date -u` tracks the host's UTC.
2. Pause and snapshot the VM (ch-remote pause; ch-remote snapshot
   file:///<dir>).
3. Leave it down for several minutes (the off-host interval).
4. Restore and resume into a fresh VMM (ch-remote restore
   source_url=file:///<dir>,resume=true).
5. In the guest, run `date -u` again and compare to the host: the guest
   now tracks current UTC, having advanced by ~the time it spent down.

Before this change the restored guest reads behind real UTC by the
downtime; after it, the guest clock is back in sync (to within the
snapshot-to-restore sampling slop).

Signed-off-by: Atish Patra <atishp@meta.com>
2026-06-18 22:59:37 +00:00
Atish Patra
69637dde69 hypervisor: aarch64: capture the guest counter for snapshot/restore
Unlike x86, ARM64 has no kvmclock support to sync guest time upon
required. However, the guest reads the architected virtual timer
(CNTVCT_EL0) directly which can be modified by the VMM to update the
time after snapshot restore. Since the CNTVCT is in ticks, we also need
to read CNTFRQ (via mrs due to lack of ONEREG interface) to compute the
ticks from wall clock difference.

Because the counter is a vCPU register, the capture must run with the
vCPUs quiesced, so the VMM now captures the clock just after
cpu_manager.pause() through the boot vCPU. This is behaviorally
identical for x86, whose clock is VM-wide. There is no restore/advance
yet, so aarch64 guests still resume behind real time until the following
commit.

Signed-off-by: Atish Patra <atishp@meta.com>
2026-06-18 22:59:37 +00:00
Atish Patra
ad909a3d71 vmm: drive guest clock save/restore through the vm abstraction
Currently, VM pause/resume/snapshot paths invoke architecture specific
bits for guest clock udpates which ideally belongs to hypervisor layer.

Route it through the snapshot_clock()/restore_clock() pair added in the
previous commit instead, so the VMM no longer depends on an architecture
specific clock API and the upcoming aarch64 backend can hook the same
path without a parallel branch in vm.rs.

Signed-off-by: Atish Patra <atishp@meta.com>
2026-06-18 22:59:37 +00:00
Meng Zhuo
14aa30cd2e vmm: retrieve timebase-frequency from KVM instead of hardcoding
The RISC-V device tree's timebase-frequency was hardcoded to 10 MHz
(0x989680). Actual hardware uses different frequencies.

Read the timebase frequency from KVM_GET_ONE_REG via
KVM_REG_RISCV_TIMER (offset 0, kvm_riscv_timer.frequency),
thread it through the VMM to arch to FDT layers, and fall back to
the 10 MHz default when KVM returns no value.

Signed-off-by: Meng Zhuo <mengzhuo@iscas.ac.cn>
2026-06-17 16:05:53 +01:00
Rob Bradford
3b9229e434 build: Consolidate sev_snp feature usage
Since igvm is a required feature of sev_snp and also sev_snp is x86-64
only the cfg attributes at build time can be consolidated & simplified.

Signed-off-by: Rob Bradford <rbradford@meta.com>
2026-06-12 22:29:26 +00:00
Tushar Khatri
b059475dfb vmm: reevaluate #[allow] attributes
Remove stale #[allow]s whose lints no longer fire, convert the
unconditionally-firing ones to #[expect], and keep the
arch/feature-conditional ones as #[allow]. Verified across kvm/mshv,
x86_64/aarch64, and --all-features.

Part of #8326.

Signed-off-by: Tushar Khatri <hello@tusharkhatri.in>
2026-06-11 19:06:49 +00:00
Ruben Hakobyan
e9b47ebacd vmm: Make sev_snp depend on igvm
Currently both kvm and mshv require an IGVM file to boot a SEV-SNP VM.
This is already configured in the top-level cloud-hypervisor
Cargo.toml where sev_snp depends on igvm.

Add a similar dependency in the vmm crate which helps simplify some of
the in-code cfg blocks by removing the ones that are within a sev_snp
cfg block.

Signed-off-by: Ruben Hakobyan <hruben@meta.com>
2026-06-10 21:29:40 +00:00
Daniel Verkamp
56e891a405 hypervisor: kvm: preserve kvmclock realtime and fill if needed
If `KVM_GET_CLOCK` already filled out the `realtime` field, it sets the
`KVM_CLOCK_REALTIME` flag, but if we instead preserve this flag, the
kernel will automatically adjust the kvmclock clock when calling
`KVM_SET_CLOCK` based on the elapsed wall-clock time between pause and
resume. This just requires removing the `reset_flags()` function, which
allows the `KVM_CLOCK_REALTIME` flag to persist in the serialized clock
state.

However, the kernel does not always fill the `realtime` field, depending
on clock source; in this case, fill `realtime` during pause based on the
system time. This is not as precise as the automatic `KVM_GET_CLOCK`
version, since we query the time slightly after the vCPU was paused, but
it allows the clock to be resumed mostly in sync instead of being wildly
off. In this case, we also set the `KVM_CLOCK_REALTIME` flag in the
saved `struct kvmclock` so `KVM_SET_CLOCK` will adjust the clock on
resume.

Basic test case:

1. Run a VM with a Linux guest.
2. Pause the guest via `vm.pause` API.
3. Wait several minutes.
4. Resume the guest via `vm.resume` API.
5. Verify the guest time (e.g. via `date` command) is valid.
6. Verify guest is still using `kvm-clock` timesource:

   cat /sys/devices/system/clocksource/clocksource0/current_clocksource

Before applying the patch, the guest clock would be off by the delta
time between pause and resume; after the patch, the clock is (more or
less) in sync with the correct wall-clock time.

Old snapshots will not have the `KVM_CLOCK_REALTIME` flag populated, so
they will not be affected by the new behavior.

Signed-off-by: Daniel Verkamp <drv@meta.com>
2026-06-03 20:32:58 +00:00
Leander Kohler
e097d7d495 vmm: plumb legacy SMBIOS config
Add a small SMBIOS config that carries serial_number, uuid,
and OEM strings, and pass it from platform config into
x86_64 setup.

On-behalf-of: SAP leander.kohler@sap.com
Signed-off-by: Leander Kohler <leander.kohler@cyberus-technology.de>
2026-05-28 16:32:41 +00:00
Leander Kohler
0141635a5c arch: x86_64: refactor SMBIOS helpers
Split the System Information write into helper functions and
reuse the string writer so the table layout and inputs are
unchanged.

On-behalf-of: SAP leander.kohler@sap.com
Signed-off-by: Leander Kohler <leander.kohler@cyberus-technology.de>
2026-05-28 16:32:41 +00:00
Oliver Anderson
549f3d6c04 misc: Make CPU profile part of various configs
We integrate the CPU profile into the various configs that
ultimately get set by the user.

This quickly ends up involving multiple files, luckily Rust
helps us find which ones via compilation errors.

Signed-off-by: Oliver Anderson <oliver.anderson@cyberus-technology.de>
On-behalf-of: SAP oliver.anderson@sap.com
2026-05-28 15:19:15 +00:00
Rob Bradford
4d27640d08 vmm: Fix clippy: uninlined_format_args
Inline the format argument rather than provide it as a parameter.

Signed-off-by: Rob Bradford <rbradford@meta.com>
2026-05-27 16:50:41 +00:00
Rob Bradford
7a386eca4a vmm: Fix clippy: useless_borrows_in_formatting
Replace & in formatting arguments where it is already a reference
(avoiding &&).

Signed-off-by: Rob Bradford <rbradford@meta.com>
2026-05-27 16:50:41 +00:00
Rob Bradford
44ed81e66f vmm: Don't store the snapshot on the DeviceManager
Storing the snapshot causes issues when needing to do a subsequent
hotplug instead just pass it through on all the methods that need it
making the lifecycle cleaner.

Assisted-by: Claude:Opus-4.6
Signed-off-by: Rob Bradford <rbradford@meta.com>
2026-05-20 11:10:39 +00:00
Chris Webb
7b29691932 vmm: return all-ones for unregistered PIO reads
When reading from an unregistered PIO address, pio_read() wasn't
initialising the buffer, so guests were reading stale bytes from the
previous PIO transaction rather than all 0xff bytes like master abort
on real hardware.

Fill data with 0xff on invalid reads.

Correct 'read to unregistered address' info message to 'read from
unregistered address' while we're touching this block.

Signed-off-by: Chris Webb <chris@arachsys.com>
2026-05-16 15:40:55 +00:00
Chris Webb
4091e965b8 vmm: return all-ones for unregistered MMIO reads
When reading from an unregistered MMIO address, mmio_read() wasn't
initialising the buffer, so guests were reading stale bytes from the
previous MMIO transaction rather than all 0xff bytes like master abort
on real hardware.

Fill data with 0xff on invalid reads.

Correct 'read to unregistered address' info message to 'read from
unregistered address' while we're touching this block.

Signed-off-by: Chris Webb <chris@arachsys.com>
2026-05-16 15:40:55 +00:00
Julian Schindel
8b101fb890 vmm: replace as <pointer> casts with safer alternatives
`as` casts can change mutability, which quickly leads to undefined
behavior.

Signed-off-by: Julian Schindel <mail@arctic-alpaca.de>
2026-05-03 08:38:31 +00:00
Ruben Hakobyan
bfab43e252 vmm: Parse guest policy from IGVM initialization headers
Extract the SNP guest policy from IGVM initialization headers when
available, falling back to the default policy. This matches QEMU's
behaviour where only a non-zero IGVM policy overrides the default.

Signed-off-by: Ruben Hakobyan <hruben@meta.com>
2026-05-01 20:28:55 +00:00
Kevin Hui
70388fb1bb vmm: Introduce kernel hashes measured boot
This introduces the kernel hashes measured boot table into
cloud hypervisor if a cmdline and kernel is passed into an
SEV-SNP CVM, incorporating a kernel/cmdline/optional initrd
into a memory page that is measured into the launch digest
of a SEV-SNP CVM. If both --kernel and --cmdline are not
provided, we do not insert this data page

Signed-off-by: Kevin Hui <kevinhui@meta.com>
2026-05-01 20:28:55 +00:00
Ruben Hakobyan
9f1247fe60 devices: fw_cfg: Don't modify kernel header for KVM SEV-SNP guests
For KVM SEV-SNP guests, the VMM should not modify the kernel
boot header before sending it via fw_cfg. The guest firmware is expected
to set fields like type_of_loader itself.

For upcoming measured boot logic for SEV-SNP, modifying `type_of_loader`
causes the kernel hash computed by the VMM to diverge from the hash that
`sev-snp-measure` (and the guest firmware) compute, resulting in a
launch measurement mismatch.

This matches QEMU's behavior, which skips kernel header modifications
for confidential guests so the data sent via fw_cfg matches the
original kernel file provided by the user.

Signed-off-by: Ruben Hakobyan <hruben@meta.com>
2026-05-01 20:28:55 +00:00
Muminul Islam
f6ed896f68 vmm: gate reserve_bootloader_regions on KVM hypervisor type
The reserve_bootloader_regions() call allocates RAM regions at
KVM-specific addresses (0xffc00000 for stage0, 0xfffffffff000
for VMSA) that are only needed by the KVM SEV-SNP boot path.

The existing #[cfg(all(feature = "kvm", feature = "sev_snp"))]
compile-time guard is insufficient when both 'mshv' and 'kvm'
features are enabled in the same binary. The runtime check only
verified sev_snp_enabled() but not the hypervisor type, causing
these KVM-specific memory regions to be allocated on MSHV.

On MSHV, these spurious RAM mappings at high addresses interfere
with the hypervisor's address space layout. When the guest kernel
subsequently accesses MMIO regions (e.g., IOAPIC at 0xFEC00000),
MSHV incorrectly reports HVMSG_UNACCEPTED_GPA instead of routing
the access through MMIO emulation, crashing the guest.

Add a runtime hypervisor type check to ensure these regions are
only reserved when running on KVM.

Assisted-by: Claude:Opus-4.6

Signed-off-by: Muminul Islam <muislam@microsoft.com>
2026-04-30 10:39:28 +00:00
Muminul Islam
8598b45a95 vmm: skip configure_system when rsdp_addr is None
For SEV-SNP guests using IGVM, the ACPI tables and system
configuration (MP tables, EBDA, SMBIOS, PVH start info, e820)
are provided by the IGVM file. The rsdp_addr is set to None
for these guests to indicate ACPI table creation was skipped.

Commit 7d65187350 ("vmm: make RSDP address optional in
configure_system") removed the guard that prevented calling
configure_system when rsdp_addr is None. This caused MSHV
SEV-SNP guests to crash because configure_system writes to
guest memory locations that conflict with the IGVM-provided
layout.

Restore the guard by only calling configure_system when
rsdp_addr is Some, which preserves the intended behavior
for CVM guests while still allowing the Option<GuestAddress>
refactoring.

Assisted-by: Claude:Opus-4.6

Signed-off-by: Muminul Islam <muislam@microsoft.com>
2026-04-30 10:39:28 +00:00
Keith Adler
926dd1e141 vmm, devices: Add fw_cfg string item support
QEMU supports passing inline string values to the guest via fw_cfg
(-fw_cfg name=...,string=...). Cloud Hypervisor previously only
supported file-backed fw_cfg items. This adds the 'string' option
so users can pass values like OVMF's X-PciMmio64Mb without creating
a temporary file on the host.

Each fw_cfg item now accepts exactly one of 'file' or 'string'.
The FwCfgInvalidItem invariant is validated in PayloadConfig::validate()
(via FwCfgConfig::validate()), covering both CLI and JSON API paths.
The populate_fw_cfg match arm uses unreachable!() since validation
guarantees the invariant holds at that point.

CLI syntax:
  --fw-cfg-config items=[name=opt/ovmf/X-PciMmio64Mb,string=262144]

Signed-off-by: Keith Adler <kadler@cloudflare.com>
2026-04-20 09:39:56 +00:00
Ruben Hakobyan
883ca3feb2 vmm: reserve memory regions for stage0 and VMSA on KVM SEV-SNP
A bootloader/firmware (e.g. stage0) and the VMSA page require dedicated
memory regions at fixed GPAs.

Add reserve_region_for_stage0() to allocate these regions before IGVM
loading begins:
- Stage0 at GPA 0xffc0_0000 (4 MB)
- VMSA page at GPA 0xffff_ffff_f000 (4 KB)

These reservations are KVM-only; MSHV handles stage0/VMSA placement
through its own isolated import path.

Also add fw_cfg device creation and SYS_statx to the vCPU seccomp
allowlist (needed by stage0's file access pattern).

Co-authored-by: Keith Adler <kadler@cloudflare.com>
Signed-off-by: Keith Adler <kadler@cloudflare.com>
Co-authored-by: Alex Orozco <aorozco@google.com>
Signed-off-by: Alex Orozco <aorozco@google.com>
Signed-off-by: Ruben Hakobyan <hruben@meta.com>
2026-04-17 12:28:55 +00:00
Ruben Hakobyan
2e004521e0 hypervisor, vmm: Add KVM SEV_{INIT2, SNP_LAUNCH_START} support
Introduce the SevFd abstraction that wraps /dev/sev and implements the
KVM_SEV_INIT2 and KVM_SEV_SNP_LAUNCH_START ioctls for SEV-SNP VM
initialization on KVM.

Key changes:
- Add sev.rs with KvmSevInit and KvmSevSnpLaunchStart ioctl structs
  matching the kernel layout (linux/arch/x86/include/uapi/asm/kvm.h)
- Implement KVM_SEV_INIT2 and KVM_SEV_SNP_LAUNCH_START ioctls
- Set KVM_MEMORY_ATTRIBUTE_PRIVATE on newly created memory regions
  when guest_memfd is supported
- Widen SevSnpPageAccessProxy cfg gates from mshv-only to all
  sev_snp-enabled builds
- Make sev_snp_init a required trait method (remove default impl)
- Include KVM_SEV_SNP_LAUNCH_START in the seccomp allowlist
- Parse VMSA SEV features from IGVM and include them in the
  KVM_SEV_INIT2 ioctl

Co-authored-by: Keith Adler <kadler@cloudflare.com>
Signed-off-by: Keith Adler <kadler@cloudflare.com>
Co-authored-by: Alex Orozco <aorozco@google.com>
Signed-off-by: Alex Orozco <aorozco@google.com>
Co-authored-by: Rob Bradford <rbradford@meta.com>
Signed-off-by: Rob Bradford <rbradford@meta.com>
Signed-off-by: Ruben Hakobyan <hruben@meta.com>
2026-04-17 12:28:55 +00:00
Ruben Hakobyan
425609a8b5 vmm: parse IGVM file early and thread it through VM setup
Move IGVM file parsing from load_igvm() into a dedicated parse_igvm()
helper in igvm/mod.rs, and parse the file upfront in Vm::new() so the
resulting IgvmFile struct is available throughout VM initialization.

This is a prerequisite for extracting VMSA SEV features from the parsed
IGVM before issuing KVM_SEV_INIT2, which needs sev_features.

Signed-off-by: Ruben Hakobyan <hruben@meta.com>
2026-04-17 12:28:55 +00:00
Ruben Hakobyan
4f1119a788 vmm: remove sev_snp_enabled parameter from payload loading
The load_payload and load_payload_async functions previously received a
sev_snp_enabled flag to decide whether to call load_igvm with or
without the host_data parameter. Replace this with a single code path
that always passes host_data behind a cfg(feature = "sev_snp") gate,
removing the runtime branch and the extra parameter threaded through
three call sites.

Co-authored-by: Keith Adler <kadler@cloudflare.com>
Signed-off-by: Keith Adler <kadler@cloudflare.com>
Co-authored-by: Alex Orozco <aorozco@google.com>
Signed-off-by: Alex Orozco <aorozco@google.com>
Signed-off-by: Ruben Hakobyan <hruben@meta.com>
2026-04-17 12:28:55 +00:00
Ruben Hakobyan
7d65187350 vmm: make RSDP address optional in configure_system
Change configure_system to take an Option<GuestAddress>
since rsdp is wrapped into an option anyways (we use configure
system to setup the mptables).

Co-authored-by: Keith Adler <kadler@cloudflare.com>
Signed-off-by: Keith Adler <kadler@cloudflare.com>
Co-authored-by: Alex Orozco <aorozco@google.com>
Signed-off-by: Alex Orozco <aorozco@google.com>
Signed-off-by: Ruben Hakobyan <hruben@meta.com>
2026-04-17 12:28:55 +00:00
Ruben Hakobyan
b545b2fc4e hypervisor, vmm: pass SNP guest policy to sev_snp_init
The SNP guest policy (AMD SEV-SNP ABI bits controlling SMT, migration,
debug, etc.) was previously hardcoded inside the MSHV implementation.
Widen Vm::sev_snp_init() to accept an SnpPolicy parameter so each
hypervisor backend receives the policy at init time.

Add get_default_sev_snp_guest_policy() in the VMM to construct the
default policy.

Co-authored-by: Keith Adler <kadler@cloudflare.com>
Signed-off-by: Keith Adler <kadler@cloudflare.com>
Co-authored-by: Alex Orozco <aorozco@google.com>
Signed-off-by: Alex Orozco <aorozco@google.com>
Signed-off-by: Ruben Hakobyan <hruben@meta.com>
2026-04-17 12:28:55 +00:00
Ruben Hakobyan
8ee0a07ab1 arch, hypervisor, vmm: skip vcpu setup when using igvm and kvm
When we use igvm + kvm, we setup the regs and sregs using the cpuid
page. We still need to setup the fpu in configure_vcpu.

Co-authored-by: Keith Adler <kadler@cloudflare.com>
Signed-off-by: Keith Adler <kadler@cloudflare.com>
Co-authored-by: Alex Orozco <aorozco@google.com>
Signed-off-by: Alex Orozco <aorozco@google.com>
Signed-off-by: Ruben Hakobyan <hruben@meta.com>
2026-04-17 12:28:55 +00:00
Rob Bradford
5bd6fdc17d vmm: Rename force_iommu to force_access_platform
This a clearer name for it's purpose and now matches more closely what
is used for the virtio devices themselves.

Signed-off-by: Rob Bradford <rbradford@meta.com>
2026-04-17 10:54:51 +00:00
Keith Adler
e2c51042d3 vmm: preserve underlying errors in vm.rs instead of dropping them
Several error mappings in vm.rs dropped the underlying error with
map_err(|_| ...), making failures harder to diagnose. Preserve the
source error by adding #[source] fields to InitramfsLoad and ErrorNmi.

- InitramfsLoad: now wraps std::io::Error from seek/rewind operations
- ErrorNmi: now wraps cpu::Error from the CPU manager nmi() call

Partially addresses #7563

Signed-off-by: Keith Adler <kadler@cloudflare.com>
2026-04-16 20:48:19 +00:00
Leander Kohler
c698075157 vmm: add guest exit event path
Introduce a dedicated guest_exit_evt and a matching epoll dispatch
path for guest-triggered shutdowns.

This series is needed because managment software such as libvirt may
still need the Cloud Hypervisor process to stay alive after the guest
has shut down.
Today a guest-triggered shutdown can make the VMM disappear immediately,
which means the managment software can lose track of the VM run-state.

This must only apply to guest-triggered shutdowns. Fatal error paths
and other internal exit paths must keep using the existing VMM exit
handling.

For now GuestExit still calls vmm_shutdown(), so this commit only adds
the separate plumbing and keeps the current behavior unchanged.

On-behalf-of: SAP leander.kohler@sap.com
Signed-off-by: Leander Kohler <leander.kohler@cyberus-technology.de>
2026-04-15 17:58:56 +00:00