Add micro_bench_qcow_compressed_read which reads clusters from a
zlib compressed QCOW2 image. Every cluster triggers decompression,
isolating the decompression overhead from the normal allocated cluster
read path.
Workloads: 128 and 256 clusters.
Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
Add compressed_qcow_tempfile() which creates a zlib compressed QCOW2
image by populating a RAW tempfile with data and converting it via
qemu-img convert -c. Every cluster in the resulting image is stored
compressed so reads exercise the decompression path.
To be used by the compressed read benchmark.
Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
Add micro_bench_qcow_cow_write which writes clusters into a QCOW2
overlay backed by a raw file. Each write triggers copy-on-write:
cluster allocation, L2 and refcount table updates, then the data
write. This measures COW allocation overhead compared to writing
into a plain empty image.
Workloads: 128 and 256 clusters.
Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
Add micro_bench_qcow_backing_read which reads clusters from a QCOW2
overlay where all data lives in a raw backing file. Every read falls
through the L2 lookup to the backing file, exercising the backing
chain read path.
Workloads: 128 and 256 clusters.
Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
Add qcow_overlay_tempfile() which creates a raw backing file with
pre-populated data and a QCOW2 overlay on top with no allocated
clusters. The overlay is opened with backing file support via
QcowDiskSync so reads fall through to the backing file.
To be used by backing file read and copy-on-write write
benchmarks.
Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
Add micro_bench_qcow_random_read which reads clusters from a
prepopulated qcow2 image in a deterministic pseudo-random order.
Unlike the sequential read benchmark, this exercises L2 cache miss
and eviction behaviour under random access patterns.
Uses Fisher-Yates shuffle with DefaultHasher for reproducible
permutation across runs.
Two TEST_LIST entries: micro_block_qcow_random_read_128_us and
micro_block_qcow_random_read_256_us with 128 and 256 cluster
workloads.
Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
Add deterministic_permutation() which produces a reproducible
pseudo random permutation of [0, n) using a Fisher-Yates shuffle
seeded by DefaultHasher. This is used by the random read micro
benchmarks to generate a fixed access pattern that is identical
across runs.
Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
Add micro_bench_qcow_fsync which writes num_ops clusters into an
empty qcow2 image to dirty L2 and refcount metadata then times a
single fsync call that flushes all dirty tables to disk. This
isolates the metadata flush cost which scales with the number of
dirty L2 table entries and refcount blocks.
Two TEST_LIST entries: micro_block_qcow_fsync_64_us and
micro_block_qcow_fsync_256_us with 64 and 256 cluster workloads.
Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
Add micro_bench_qcow_punch_hole which times punch_hole calls through
QcowSync on a prepopulated qcow2 image. Each call deallocates one
cluster exercising deallocate_bytes with refcount decrement and
fallocate punch_hole on the host file.
Two TEST_LIST entries: micro_block_qcow_punch_hole_64_us and
micro_block_qcow_punch_hole_256_us with 64 and 256 cluster workloads.
Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
Add micro_bench_qcow_write which times write_vectored calls through
QcowSync on an empty QCOW2 image. Each write allocates a new cluster
exercising map_cluster_for_write with L2 entry allocation and refcount
updates followed by pwrite_all.
Two TEST_LIST entries: micro_block_qcow_write_128_us and
micro_block_qcow_write_256_us with 128 and 256 cluster workloads.
Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
Add empty_qcow_tempfile() which creates a QCOW2 v3 image with no
allocated clusters so every write triggers the full cluster allocation
path including L2 entry allocation and refcount updates.
Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
Add micro_bench_qcow_read which times read_vectored calls through
QcowSync on a prepopulated QCOW2 image. This exercises the hot
read path including L2 lookup, pread64 for allocated clusters and
iovec scatter.
Two TEST_LIST entries: micro_block_qcow_read_128_us and
micro_block_qcow_read_256_us with 128 and 256 cluster workloads.
Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
Add qcow_tempfile() which creates a QCOW2 v3 image with all clusters
allocated via QcowFile::new plus sequential writes, then reopens it
as QcowDiskSync. Add QCOW_CLUSTER_SIZE constant for the default
64 KiB cluster size.
Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
Enable the io_uring feature so that QcowDiskAsync and QcowAsync are
available for async path micro benchmarks.
Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
Make it easier to chase down which vhost user socket failed and why in
systems that have many vhost user devices.
Signed-off-by: Dylan Reid <dgreid@fb.com>
Remove the pinned cross-version commit hash from all
houseabsolute/actions-rust-cross usages. The pin was added as a
workaround for virtio-bindings build issues that have since been
resolved upstream.
Closes#7180
Signed-off-by: Keith Adler <kadler@cloudflare.com>
Drop the -f flag from the process termination command in
cleanup_stale_processes() so it matches by process name only, not the
full command line. This prevents terminating unrelated processes whose
arguments happen to contain target strings (e.g., the test runner
invoked with --report-file /cloud-hypervisor/report.json).
Use the truncated name 'cloud-hyperviso' because Linux limits process
names to 15 characters.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: Anirudh Rayabharam <anrayabh@microsoft.com>
Add a CLI-only --no-shutdown flag that keeps the VMM process alive
after a guest-triggered shutdown.
Management software may still need the Cloud Hypervisor process
after the guest has powered off. Exposing this separately lets
management software, for example libvirt, keep the VMM around in a
way that is closer to QEMU.
The flag only affects the GuestExit path. Fatal exits and other
existing VMM shutdown paths remain unchanged.
On-behalf-of: SAP leander.kohler@sap.com
Signed-off-by: Leander Kohler <leander.kohler@cyberus-technology.de>
Plumb ACPI S5 shutdown through guest_exit_evt instead of the shared
exit path.
This keeps guest-triggered shutdown separate from fatal VMM exit
handling. Management software, for example libvirt, expects that
distinction, and making it explicit aligns Cloud Hypervisor more
closely with QEMU.
Only the guest shutdown path is moved here. Reboot handling stays on
reset_evt and non-guest exit paths are left unchanged.
On-behalf-of: SAP leander.kohler@sap.com
Signed-off-by: Leander Kohler <leander.kohler@cyberus-technology.de>
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>
Verify that AlignedBuf rounds the allocation size up to the
requested alignment. Passes under miri.
Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
Test AlignedBuf with 512 and 4096 byte alignment. Verify pointer
alignment, zero initialization, and write/read round trip. Passes
under miri.
Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
Boot a Windows guest from a qcow2 overlay with direct=on. After
boot, write 5 randomly filled files from 4MB to 20MB, copy each
file, and compare SHA256 hashes to verify data integrity through
the aligned bounce buffer path.
Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
WindowsDiskConfig now creates a qcow2 overlay backed by the raw
Windows image during prepare_files(). The overlay is placed under
~/workloads alongside the raw image. Writes go into the overlay
so the backing raw image stays unmodified, matching the CoW
semantics already provided by the dm snapshot for raw tests.
Drop removes the qcow2 file.
The DiskConfig trait gains a qcow2_disk() default method returning
None. WindowsDiskConfig overrides it to expose the overlay path.
Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
Exercise both aligned_pread and aligned_pwrite with 4096 byte
alignment instead of 512. Verify written data and that surrounding
regions are preserved.
Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
Write at offset 100 with alignment 512 so the read modify write
path is exercised. Verify the written region and that surrounding
data is preserved.
Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
Write 4096 bytes via plain Vec<u8> whose address is not guaranteed
to be aligned. The bounce buffer path copies data into an aligned
allocation before the syscall. Read back with pread_exact to verify
data integrity.
Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
Write 4096 bytes of pattern data at offset 0 using AlignedBuf
and verify data integrity via plain pread_exact. All parameters
are naturally aligned to 512 so the fast path is exercised.
Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
Test that aligned_pread handles a non aligned offset by
rounding down, reading an aligned region, and returning the
correct slice from within the bounce buffer.
Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
Test that aligned_pread correctly uses a bounce buffer when
the caller buffer address is not aligned.
Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
Test that aligned_pread takes the fast path when buffer
address, length, and offset are all properly aligned.
Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
Exercise scatter/gather with multiple iovecs per operation,
covering both the standard and direct_io paths. Write uses
3 iovecs with distinct patterns, read uses 3 iovecs with
different sizes, then reassembles and compares.
Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
Add direct_io variants for suitable tests by extracting
test bodies into _impl(direct_io: bool) functions. Each
original test calls _impl(false) and a new _direct_io test
calls _impl(true).
When direct_io is true, RawFile probes alignment and QcowSync
exercises the AlignedBuf and bounce buffer paths in
read_vectored and write_vectored.
Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
Store the alignment from the data file in QcowAsync. Use
aligned_pread in scatter_read_sync and aligned_pwrite with
gather_from_iovecs_into in cow_write_sync, matching the
QcowSync approach.
Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
Store the alignment from the data file in QcowSync. Use AlignedBuf
directly in read_vectored and write_vectored as the intermediate
buffer so that aligned_pread/aligned_pwrite can skip the bounce
copy when offset and length are naturally aligned.
Use gather_from_iovecs_into to gather iovec data directly into the
aligned buffer.
Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
When the data file is opened with O_DIRECT, buffer address, length,
and file offset must satisfy the device alignment.
Add AlignedBuf RAII wrapper and aligned_pread/aligned_pwrite helpers
in qcow_common that use bounce buffers when alignment constraints
are not met. For writes with misaligned offset, a read modify write
is performed on the aligned region.
gather_from_iovecs_into gathers iovec data directly into a caller
provided buffer, avoiding an intermediate Vec allocation.
Fixes: #8007
Signed-off-by: CMGS <ilskdw@gmail.com>
Co-authored-by: Anatol Belski <anbelski@linux.microsoft.com>
Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
Add pub fn alignment() to RawFile so that callers can
query the O_DIRECT buffer alignment requirement probed
at file open time.
Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
The old name read as 'metadata for a QCOW2 backing file' rather
than what it actually is: a QCOW2 backing file reader. Rename to
Qcow2Backing to parallel RawBacking and clarify intent.
Suggested-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
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>
The address that is passed from the guest should be treated as
untrusted. Currently an invalid address will panic the VMM. This only
allows the guest to hurt itself, but we shouldn't have the VMM crashing.
Instead let's return an error if possible or invalidate the queue if it
happen during setup.
The data flow from guest to translate_gva/translate_gpa is:
1. Guest writes a raw u64 address into a virtio descriptor in the
shared descriptor table (guest memory).
2. The virtio-queue crate reads this descriptor via read_obj() and
returns the addr field as-is in a GuestAddress — no validation.
3. Device code calls .translate_gva(access_platform, len) on the
GuestAddress.
4. With IOMMU (access_platform is Some): the address is an IOVA that
must be translated to a GPA via the IOMMU mapping table. If the
guest provides an unmapped IOVA, translation returns Err.
Previously, .unwrap() here panicked the VMM.
5. Without IOMMU (access_platform is None): translate_gva is a no-op
(returns self). The raw address flows to GuestMemory::read_obj()
which validates it — out-of-range addresses return
Err(InvalidGuestAddress), so no host memory corruption is possible.
Signed-off-by: Dylan Reid <dgreid@fb.com>
The unit test container runs with Docker default seccomp
profile which blocks io_uring_setup, io_uring_enter and
io_uring_register. This causes all qcow_async unit tests to
fail with EPERM when creating an io_uring instance.
Add --security-opt seccomp=unconfined to the unit test docker
run invocation. The container already has --device access and
cap_net_admin, so this does not materially change the security
posture.
Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>