Commit Graph

3072 Commits

Author SHA1 Message Date
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
Thomas Prescher
490a9a87af vmm: Emit complete ACPI S5 sleep package
OpenBSD expects the ACPI _S5_ object to provide both sleep type values.
The single-value package made acpi_init_states() parse an invalid object
and fault during early ACPI setup with:

```
...
acpi0 at bios0: ACPI 6.3
acpi0: sleep statesfatal protection fault in supervisor mode
trap type 4 code 0 rip ffffffff814af264 cs 8 rflags 10282 cr2 0 cpl e rsp ffffffff81a06a30
gsbase 0xffffffff81755ff0  kgsbase 0x0
panic: trap type 4, code=0, pc=ffffffff814af264
Starting stack trace...
panic(ffffffff81a06980,4,ffffffff81a06a58,ffffffff81756ae0,ffffffff81a06960,ffffffff81a068e0) at panic+0x12e
kerntrap(ffffffff81a06aa0,ffff800000232400,ffffffff81261681,ffffffff81a06970,ffffffff81a06980,4) at kerntrap+0xe1
alltraps_kern_meltdown(4,ef0d316e102be1f4,ffff800000232480,0,ffffffff81a06aa0,ffff800000232400) at alltraps_kern_meltdown+0x7b
aml_val2int(ef0d316e102be1f4,0,10,ffffffff81a06a30,10282,8) at aml_val2int+0x24
acpi_init_states(1,ffff800000232400,ffff800000232470,0,ef0d316e102be1f4,5f35535f) at acpi_init_states+0xd5
acpi_attach_common(ffff800000235300,ffffffff81a06cf0,ffffffff81762a00,ffff800000232400,ffff800000232424,ef0d316e102be1f4) at acpi_attach_common+0x311
config_attach(ffffffff81a06d30,ffff800000235300,50,118,ffff80003158c004,ffffffff813e3270) at config_attach+0x1d2
bios_attach(ffff800000235280,ffffffff81a06e28,ffffffff8175ca50,ffff800000235300,ffff800000235324,ef0d316e102be1f4) at bios_attach+0x898
config_attach(ffffffff81a06e28,ffff800000235280,ffffffff81757e68,ffff800000235280,ffff8000002352a4,ffffffff8128c510) at config_attach+0x1d2
mainbus_attach(0,0,ef0d316e102be1f4,ffffffff81a06e50,ffffffff81a06ec0,3000000010) at mainbus_attach+0x70
config_attach(8,1001000,805f50,1000000,ffffffff81a00008,0) at config_attach+0x1d2
cpu_configure(8,1001000,ffffffff814f3859,ffffffff81a06f20,8,1001000) at cpu_configure+0x29
main(1001000,ef0d316e102be1f4,ffffffff812e8b2f,ffffffff81a06f40,8,1001000) at main+0x3af
end trace frame: 0x0, count: 244
End of stack trace.
```

Advertise S5 as the conventional four-element package as described in
the ACPI spec [1]. Cover the generated AML bytes with a unit test.

In AML, the package now looks like this:

```
Name (_S5, Package () {
  0x05, 0x05, 0x00, 0x00
})
```

[1] https://uefi.org/htmlspecs/ACPI_Spec_6_4_html/07_Power_and_Performance_Mgmt/oem-supplied-system-level-control-methods.html#sx-system-states

On-behalf-of: SAP thomas.prescher@sap.com
Signed-off-by: Thomas Prescher <thomas.prescher@cyberus-technology.de>
2026-06-18 18:38:01 +00:00
Sebastien Boeuf
df5d2d6003 vmm: Extract sparse file-copy helpers into a reusable module
Move next_data_extent and write_region_sparse out of memory_manager.rs
into a new vmm::sparse module so the snapshot writer, the restore
reader, and the offload daemon can share one implementation.

No functional change intended.

Signed-off-by: Sebastien Boeuf <sboeuf@meta.com>
Assisted-by: Claude:claude-opus-4-7
2026-06-18 13:45:36 +00:00
Sebastien Boeuf
cca8e1cd52 vmm: Export VmMigrationConfig as public
Expose VmMigrationConfig as a public facing structure that can be used
by an offload daemon to act as if it was the VM to migrate to, or the VM
to migrate from.

Signed-off-by: Sebastien Boeuf <sboeuf@meta.com>
Assisted-by: Claude:claude-opus-4-7
2026-06-18 13:45:36 +00:00
yanjianqing
58c08ffcca vmm: seccomp: Add SYS_fsync to vcpu thread
Fix disk hot unplug failure caused by seccomp SIGSYS kill.

When performing disk hot unplug, the vcpu thread calls fsync()
on the block device file descriptor to flush pending I/O.
The seccomp filter previously blocked SYS_fsync, triggering SIGSYS
and terminating the vcpu thread, which makes the hot unplug
operation fail. This issue exists on both x86 and AArch64.

Strace log snippet captured during failure:
```
[pid 3118852] fsync(142) = 142
[pid 3118852] ---SIGSYS {si_signo=SIGSYS,si_code=SYS_SECCOMP,si_call_addr=0xffff9c931df8, si_syscall=__NR_fsync,si_arch=AUDIT_ARCH_AARCH64}
```
Add unrestricted SYS_fsync entry to vcpu thread syscall allowlist,
consistent with existing file I/O syscalls such as fcntl and fstat.

Signed-off-by: yanjianqing <yanjianqing@kylinos.cn>
2026-06-18 08:52:39 +00:00
Rob Bradford
7ca99204ed vmm: cpu: Reject mis-sized ACPI CPU hotplug register accesses
Reject without asserting that the ACPI CPU hotplug register accesses
match those that are specified by the ACPI definitions.

Signed-off-by: Rob Bradford <rbradford@meta.com>
Assisted-by: Claude:Opus-4.7
2026-06-17 18:06:21 +01:00
Rob Bradford
df09e80b89 vmm: device_manager: Reject mis-sized PCI hotplug register accesses
Reject without asserting that the ACPI PCI hotplug register request
matches what is defined in the ACPI definition.

Signed-off-by: Rob Bradford <rbradford@meta.com>
Assisted-by: Claude:Opus-4.7
2026-06-17 18:06:21 +01: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
2bc968ba1d build: Deny clippy::absolute_paths
Removal of absolute paths is currently in progress. To avoid regressing
those changes add a clippy deny at the workspace level and at the crate
level override with #[expect(clippy::absolute_paths)]

See: #7670

Signed-off-by: Rob Bradford <rbradford@meta.com>
2026-06-17 14:38:25 +01:00
Bo Chen
19fb12c28b vmm: device_manager: Use externally-supplied iommufd FD
Signed-off-by: Bo Chen <bchen@crusoe.ai>
Assisted-by: Claude:Opus-4.7
2026-06-17 08:39:43 +00:00
Bo Chen
867b5796a5 vmm: Accept an externally-opened iommufd FD
The CLI `--platform` option now accepts `iommufd_fd=<n>` alongside the
existing `iommufd=on|off`.

Signed-off-by: Bo Chen <bchen@crusoe.ai>
Assisted-by: Claude:Opus-4.7
2026-06-17 08:39:43 +00:00
Bo Chen
0419ab6f39 vmm: OpenAPI: Make DeviceConfig path optional
`path` is no longer required in the DeviceConfig, since a VFIO
device may also be supplied via a pre-opened cdev FD passed via
SCM_RIGHTS alongside the /vm.add-device request.

Signed-off-by: Bo Chen <bchen@crusoe.ai>
Assisted-by: Claude:Opus-4.7
2026-06-17 08:39:43 +00:00
Bo Chen
c315d5fd96 vmm: Enable FD-based VFIO devices
Signed-off-by: Bo Chen <bchen@crusoe.ai>
Assisted-by: Claude:Opus-4.7
2026-06-17 08:39:43 +00:00
Bo Chen
d9f89ef2ab vmm: http_api: Accept a VFIO device FD via SCM_RIGHTS
Signed-off-by: Bo Chen <bchen@crusoe.ai>
Assisted-by: Claude:Opus-4.7
2026-06-17 08:39:43 +00:00
Bo Chen
0e4b98ae8e vmm: DeviceConfig: Add fd field for an externally-opened vfio cdev
Add a new `fd: Option<i32>` field to DeviceConfig so a caller can
supply a pre-opened vfio cdev FD (e.g. /dev/vfio/devices/vfioN) in
addition to the existing sysfs path. The CLI `--device` option now
accepts `fd=<n>`, parsed alongside the existing options.

Signed-off-by: Bo Chen <bchen@crusoe.ai>
Assisted-by: Claude:Opus-4.7
2026-06-17 08:39:43 +00:00
Bo Chen
bc5363823a vmm: DeviceConfig: Store path as Option<PathBuf>
Relax DeviceConfig::path from PathBuf to Option<PathBuf> in preparation
to accept an externally-opened vfio cdev FD. The parser and OpenAPI spec
still enforces that `path` is set, so callers see no behavior change.

Signed-off-by: Bo Chen <bchen@crusoe.ai>
Assisted-by: Claude:Opus-4.7
2026-06-17 08:39:43 +00:00
Bo Chen
96ea24339d vmm: seccomp: Allow IOMMU_DESTORY ioctl
Update the seccomp filter for vmm and vcpu thread, because `Drop for
VfioIommufd` since vfio-ioctls v0.6.1 now issues IOMMU_DESTROY
to release the IOAS allocated for each VM boot.

Signed-off-by: Bo Chen <bchen@crusoe.ai>
2026-06-17 08:39:43 +00:00
Philipp Schuster
4491a3e412 vmm: improved error messages
Unrelated improvements that help to catch common pitfalls.

On-behalf-of: SAP philipp.schuster@sap.com
Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
2026-06-16 22:01:30 +00:00
Philipp Schuster
15cab7ee6a vmm: improve VM ownership handling
Introducing a new enum that models the various states of VM ownership
from the perspective of the VMM.

This is an important prerequisite for the asynchronization of the
migration, where the ownership of the Vm struct is transferred to the
migration thread. Specifically, this allows to introduces a new
"Migration(ThreadHandle)" variant and all existing match statements
can be easily extended to react accordingly.

On-behalf-of: SAP philipp.schuster@sap.com
Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
2026-06-16 22:01:30 +00: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
Rob Bradford
bf3bc325e2 vmm: Validate the PCI segment ID without platform configuration
Validate that the PCI segment specified is a valid PCI segment ID (less
than the number of segments specified) defaulting to default if no
segments are specified because no there is no platform configuration.

See: #8376

Signed-off-by: Rob Bradford <rbradford@meta.com>
2026-06-12 13:08:25 +00:00
Rob Bradford
e94bb6bce6 main: Fix test_vmm_vm_cold_add_user_device
This test has a copy and paste error where the PCI segment ID was being
set with no extra segments configured.

Signed-off-by: Rob Bradford <rbradford@meta.com>
2026-06-12 13:08:25 +00:00
Sebastian Eydam
cf28552085 vmm: encrypt migration data with TLS if configured
Wire in the code paths that activate the TLS encrypting if the necessary
API arguments are provided.

On-behalf-of: SAP sebastian.eydam@sap.com
Signed-off-by: Sebastian Eydam <sebastian.eydam@cyberus-technology.de>
2026-06-12 10:11:56 +00:00
Sebastian Eydam
320403a11e vmm: validate TLS related files
Validate that all files that are necessary for TLS encryption are in the
given folder. The knowledge which files are necessary is part of the TLS
module.

On-behalf-of: SAP sebastian.eydam@sap.com
Signed-off-by: Sebastian Eydam <sebastian.eydam@cyberus-technology.de>
2026-06-12 10:11:56 +00:00
Sebastian Eydam
58baee16ac vmm: add TLS API option to receive migration call
As we now have more than one parameter for the receive migration call,
this commit also adds parsing and validation for those parameters. We
maintain backwards compatibility by also correctly parsing the case
where the caller only provides a URL.

On-behalf-of: SAP sebastian.eydam@sap.com
Signed-off-by: Sebastian Eydam <sebastian.eydam@cyberus-technology.de>
2026-06-12 10:11:56 +00:00
Sebastian Eydam
c23edda98b vmm: add TLS API option to send migration call
To enable TLS, the caller has to provide a path to a directory that
contains the necessary files.

On-behalf-of: SAP sebastian.eydam@sap.com
Signed-off-by: Sebastian Eydam <sebastian.eydam@cyberus-technology.de>
2026-06-12 10:11:56 +00:00
Sebastian Eydam
001bdde75f vmm: tighten migration URL validation
For TLS we have to parse the hostname from the given migration URL. For
that we have to make a few assumptions about the URL (e.g. it always has
a port). To catch problems early, we tighten the URL validation.

On-behalf-of: SAP sebastian.eydam@sap.com
Signed-off-by: Sebastian Eydam <sebastian.eydam@cyberus-technology.de>
2026-06-12 10:11:56 +00:00
Sebastian Eydam
0ec2ae376b vmm: accept migration connections over TLS
Extend ReceiveListener with a TLS-backed listener variant for migration
receivers.

Store the TCP listener together with the server TLS configuration, wrap
accepted sockets in TlsStream::new_server(), and preserver the existing
listener cloning and fd polling behavior so receive-side migration code
can treat TLS listeners like the existing TCP and UNIX cases.

On-behalf-of: SAP sebastian.eydam@sap.com
Signed-off-by: Sebastian Eydam <sebastian.eydam@cyberus-technology.de>
2026-06-12 10:11:56 +00:00
Sebastian Eydam
f3623e6403 vmm: add TLS streams to migration transport
Teach the migration transport to handle TLS-backed streams alongside
plain TCP and UNIX sockets.

Introduce a Tls variant in SocketStream and implement the necessary
traits.

Also updates the local-migration error path to reject any non-UNIX
transport, which now includes TLS-wrapped TCP connections.

On-behalf-of: SAP sebastian.eydam@sap.com
Signed-off-by: Sebastian Eydam <sebastian.eydam@cyberus-technology.de>
2026-06-12 10:11:56 +00:00
Sebastian Eydam
6e501cc2dc vmm: remove redundant SocketStream overrides
ReadVolatile already provides a default read_volatile_exact()
implementation, and WriteVolatile a default write_volatile_exact()
implementation. Overriding these functions adds no behavioral value, but
duplicates logic and needs to be updated whenever SocketStream gains or
changes a variant.

On-behalf-of: SAP sebastian.eydam@sap.com
Signed-off-by: Sebastian Eydam <sebastian.eydam@cyberus-technology.de>
2026-06-12 10:11:56 +00:00
Sebastian Eydam
d181d2c2ac vmm: remove AsRawFd trait for SocketStream
The trait is not used and thus can be removed.

On-behalf-of: SAP sebastian.eydam@sap.com
Signed-off-by: Sebastian Eydam <sebastian.eydam@cyberus-technology.de>
2026-06-12 10:11:56 +00:00
wuxinyue
75b0fe5a21 vmm: defer PCI device visibility to fix hotplug race condition
Split `add_pci_device()` into two phases: `allocate_pci_bars()` which
only allocates BAR address space, and `commit_pci_device()` which
makes the device visible to the guest on the PCI bus.

All callers now follow the pattern: allocate BARs → perform device-
specific setup (ioeventfd, device_tree, mmio mapping) → commit device.
This eliminates a race window where the guest could discover a
partially-initialized device via `acpiphp_check_bridge()` during rapid
sequential hotplug, causing BAR reprogramming to fail because
ioeventfds and device_tree entries were not yet in place.

Signed-off-by: wuxinyue <wuxinyue.wxy@antgroup.com>
Assisted-by: Claude:Opus-4.6
2026-06-12 08:19:42 +00:00
wuxinyue
f787bd7a17 vmm: move BAR mapping registration from PciBus to DeviceManager
`PciBus::register_mapping()` operates on `mmio_bus` and `io_bus`
which are passed in as external parameters and have nothing to do
with PciBus internal state. Move this logic into
`DeviceManager::register_bar_mapping()` where it belongs, and move
the `PioInsert`/`MmioInsert` error variants from `PciRootError` to
`DeviceManagerError` accordingly.

Signed-off-by: wuxinyue <wuxinyue.wxy@antgroup.com>
Assisted-by: Claude:Opus-4.6
2026-06-12 08:19:42 +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
Dylan Reid
0487035512 vmm: release vIOMMU VFIO container on device eject
Currently ejecting a device leaks its mapping keeping the container fd
open. Remove the mapping so the fd can be closed.

Assisted-by: Claude:Opus-4.8
Signed-off-by: Dylan Reid <dgreid@fb.com>
2026-06-11 15:15:38 +00:00
Leander Kohler
51bd9d24f3 vmm, vm-migration: validate protocol version at start
Validate the sender's migration protocol version when
handling the initial Start request.

Read the version from the Start command header, accept only
the supported version window n-1..=n, and reject unsupported
versions with Error. A rejected Start moves the receiver to
the aborted state.

This keeps compatibility one-way, from older protocol
versions to newer ones, and leaves later version-based
branching on the receiver side.

Log the protocol version on both sender and receiver to make
the active migration path visible.

On-behalf-of: SAP leander.kohler@sap.com
Signed-off-by: Leander Kohler <leander.kohler@cyberus-technology.de>
2026-06-11 13:24:16 +00:00
Rob Bradford
7042922e83 vmm: Add a final memory pass after capturing snapshot
During migration send one final set of changed memory after capturing
the snapshot/state. This captures any memory changed as a side effect of
capturing that state. In particular with vhost-user capturing the device
state can lead to inflight requests being drained/flushed which could
change memory. As this is related to the snapshot account for this
memory transfer in the snapshot metrics.

No equivalent change is needed for snapshot as the memory is written
after the state is snapshotted.

Signed-off-by: Rob Bradford <rbradford@meta.com>
2026-06-11 08:00:50 +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
Ian Klemm
8d05407799 vmm: add memory reserve option to opt out of MAP_NORESERVE
Cloud Hypervisor maps guest RAM with MAP_NORESERVE, so the kernel never
reserves the backing pages at mmap time. On a host whose hugepage pool
cannot satisfy every guest, a VM is created successfully and then takes
a SIGBUS when the guest faults a page the pool can no longer back. This
is the failure mode reported in #5730 and #7387. As noted on #5730,
checking free pool headroom up front is not a reliable fix: another
process can consume pages between the check and the fault.

Add a reserve=on parameter to --memory and --memory-zone (default off,
preserving the current MAP_NORESERVE behaviour). When set, the region
is mapped without MAP_NORESERVE, so the kernel reserves the backing
pages (swap, or huge pages for hugepage-backed memory) at mmap time,
atomically with the mapping. An over-committed configuration then
fails cleanly at VM creation with an mmap ENOMEM instead of crashing
the guest later. Unlike prefault it does not fault the memory in, so
it does not slow down boot.

This mirrors QEMU's memory-backend reserve property, which has the same
name and meaning (reserve=off maps with MAP_NORESERVE). reserve is
threaded through the same mmap paths as the existing prefault option,
and is exposed in the OpenAPI schema, CLI help and docs. The top-level
--memory reserve=on path is unchanged: the default zone is synthesised
from MemoryConfig and inherits its reserve value.

Assisted-by: Claude Code (Opus 4.8)
Signed-off-by: Ian Klemm <hi@ianklemm.de>
2026-06-10 12:30:25 +00:00
Dylan Reid
38bee23d89 vmm: memory_manager: free memslot in remove_userspace_mapping
remove_userspace_mapping tears down the KVM mapping but never returns
the slot id to the allocator's free list. Call `free_memory_slot` to
avoid the leak.

Signed-off-by: Dylan Reid <dgreid@fb.com>
2026-06-10 10:15:46 +00:00
Ruben Hakobyan
b1d33ec9aa vmm: vm_config: apply serde defaults to FwCfgConfig
FwCfgConfig already has a Default impl (e820/kernel/cmdline/initramfs/
acpi_tables = true, items = None), but deserialization did not use it:
without serde default every field was mandatory, so any caller building
a payload config over the API had to spell out the whole object even to
flip a single flag.

Add a container-level #[serde(default)] so missing fields fall back to
FwCfgConfig::default(). The container form is required here because the
defaults are all true; a per-field #[serde(default)] would resolve bool
to false and contradict the Default impl.

This lets callers send only the fields that differ from the defaults.

Assisted-by: Claude:Opus-4.8
Signed-off-by: Ruben Hakobyan <hruben@meta.com>
2026-06-09 15:49:42 +00:00
Ruben Hakobyan
ec157d7eb9 seccomp: allow openat + read on the HTTP API thread under KVM SEV-SNP
The KVM SEV-SNP net-hotplug integration tests (supported added in
later commits) intermittently kill the VMM with SIGSYS on the
http-server thread. The thread is seen reading
/proc/sys/vm/overcommit_memory (openat + read).

Allow the syscalls there, gated on sev_snp+kvm. seccomp can't match
a path, so the open is restricted to O_RDONLY.

Assisted-by: Claude:Opus-4.8
Signed-off-by: Ruben Hakobyan <hruben@meta.com>
2026-06-09 15:49:42 +00:00
Ruben Hakobyan
dc6a56a0db vmm: vm_config: allow opening /dev/sev after landlock
On KVM, an SEV-SNP guest opens /dev/sev at VM creation and passes
its fd as kvm_sev_cmd.sev_fd. KVM uses it to issue the SNP_LAUNCH_*
commands. The open happens after the landlock ruleset is applied,
so grant rw access to /dev/sev when the sev_snp platform feature
is enabled.

Assisted-by: Claude:Opus-4.8
Signed-off-by: Ruben Hakobyan <hruben@meta.com>
2026-06-09 15:49:42 +00:00
Ruben Hakobyan
9e6c817192 virtio-devices: add VIRTIO_F_ACCESS_PLATFORM to watchdog and iommu
A confidential guest (e.g. SEV-SNP) requires every virtio device to
advertise VIRTIO_F_ACCESS_PLATFORM so the guest driver routes DMA
through the platform's bounce-buffer path; the driver refuses a device
that does not offer it.

Add VIRTIO_F_ACCESS_PLATFORM support to virtio-{watchdog,iommu} which
are exercised as part of the CVM integration tests.

Assisted-by: Claude:Opus-4.8
Signed-off-by: Ruben Hakobyan <hruben@meta.com>
2026-06-09 15:49:42 +00:00
Max Makarov
9889f6d403 vmm: buffer socket serial output for late-connecting clients
In Socket serial mode the device output sink was only installed once a
client connected, so output produced beforehand (kernel boot messages,
cloud-init) was dropped, and a client attaching after boot saw a blank
screen. Only PTY mode wrapped the sink in a SerialBuffer.

Install a persistent SerialBuffer as the Socket device's output sink at
SerialManager construction (discarding downstream via io::sink() until a
client connects), so output is captured into the 1 MiB ring even with no
client attached. On connect, retarget the buffer at the accepted client
and flush the backlog before live output resumes; on disconnect, keep
buffering so output produced while no client is attached is delivered to
the next one. The accepted socket is made non-blocking via
set_nonblocking() so a slow client cannot stall the vCPU thread
(SerialBuffer re-buffers on WouldBlock).

The serial-manager thread gains two syscalls under seccomp: sendto
(replaying the backlog is the first time it writes to the socket) and
ioctl restricted to FIONBIO, which is what set_nonblocking() issues.

Fixes: #7907

Signed-off-by: Max Makarov <maxpain@linux.com>
Assisted-by: Claude:claude-opus-4-8 [Claude Code]
2026-06-08 10:21:04 +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
Max Makarov
0a08f6551a vmm: clean up a stale API socket under a lock before bind
When Cloud Hypervisor crashed or was killed, the API socket file was
left on disk, so the next start failed with EADDRINUSE ("Address already
in use") and the VMM could not restart. This affects any environment
where the socket directory survives across restarts (systemd services,
Kubernetes emptyDir volumes, and so on).

Before binding the path-based API socket, take an exclusive lock on a
sidecar "<socket>.lock" file using the block crate's OFD-lock helper.
Holding it proves no other instance is bound to this path, so a stale
socket left by a crashed run can be removed safely and race-free. If
the lock is already held, fail with a clear "API socket is already in
use" error instead of clobbering the live instance. The lock is held
for the process lifetime and released by the kernel on exit or crash.
The fd-based (socket-activation) path is left unchanged.

This implements the lock-file approach suggested by @DemiMarie.

Fixes: #7784

Signed-off-by: Max Makarov <maxpain@linux.com>
Assisted-by: Claude:claude-opus-4-8 [Claude Code]
2026-06-03 19:42:35 +00:00
Dylan Reid
6219613bce vmm: allow madvise in the event-monitor seccomp filter
Fix racy seccomp kill on shutdown. When a VM shuts down the
event-monitor thread's recv() loop ends and the thread exits. glibc's
thread teardown then runs __malloc_arena_thread_freeres, which trims the
per-thread malloc arena with madvise(MADV_DONTNEED).

Add madvise to the allowed calls to match other threads. The crash is
intermittent because it only fires when that thread's arena accumulated
trimmable memory by shutdown.

Signed-off-by: Dylan Reid <dgreid@fb.com>
2026-06-03 19:05:46 +00:00
Philipp Schuster
360e155cac vmm: replace #[allow(dead_code)] with expect()
On-behalf-of: SAP philipp.schuster@sap.com
Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
2026-06-03 13:56:31 +00:00
Philipp Schuster
f1f02e7144 vmm: remove unneeded #[allow(dead_code)]
On-behalf-of: SAP philipp.schuster@sap.com
Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
2026-06-03 13:56:31 +00:00