Extract virtio net control queue test logic into a standalone
_test_virtio_net_ctrl_queue helper that accepts a Guest
reference. The helper boots a VM with MTU 3000, verifies
ethtool can disable rx-gro-hw, and asserts the guest interface
MTU is correctly set.
Replace hardcoded kernel and cmdline arguments with
default_kernel_cmdline(). Update the test call site in
common_parallel to use GuestFactory and delegate to the new
helper, enabling reuse with different guest types.
Signed-off-by: Muminul Islam <muislam@microsoft.com>
Add test_pci_msi to the common_cvm integration test module to
verify that PCI MSI interrupt functionality works correctly in
confidential guest environments.
The test creates an Ubuntu Jammy-based confidential VM using
GuestFactory and delegates to the existing _test_pci_msi helper
to validate MSI interrupts.
Signed-off-by: Muminul Islam <muislam@microsoft.com>
Extract PCI MSI interrupt test logic from test_pci_msi into a
standalone _test_pci_msi helper that accepts a Guest reference.
The helper boots a VM, waits for boot, and asserts that 12 MSI
interrupts are present in /proc/interrupts.
Replace hardcoded kernel and cmdline arguments with
default_kernel_cmdline(). Update the test call site in
common_parallel to use GuestFactory and delegate to the new
helper, enabling reuse with different guest types.
Signed-off-by: Muminul Islam <muislam@microsoft.com>
Add test_virtio_queue_affinity to the common_cvm integration
test module to verify that per-queue CPU pinning works correctly
in confidential guest environments.
The test creates a 4-vCPU Ubuntu Jammy-based confidential VM
using GuestFactory and delegates to the existing
_test_virtio_queue_affinity helper to validate queue-to-core
affinity settings.
Signed-off-by: Muminul Islam <muislam@microsoft.com>
Extract virtio queue affinity test logic into a standalone
_test_virtio_queue_affinity helper that accepts a Guest
reference. The helper verifies the host has at least 4 CPUs,
boots a VM with per-queue affinity on the cloud-init disk,
and asserts each disk queue thread is pinned to the expected
cores.
Replace hardcoded kernel and cmdline arguments with
default_cpus() and default_kernel_cmdline(). Update the
test call site in common_parallel to use GuestFactory and
delegate to the new helper, enabling reuse with different
guest types.
Signed-off-by: Muminul Islam <muislam@microsoft.com>
Add test_cpu_affinity to the common_cvm integration test module
to verify that CPU pinning works correctly in confidential
guest environments.
The test creates a 2-vCPU Ubuntu Jammy-based confidential VM
using GuestFactory and delegates to the existing
_test_cpu_affinity helper to validate vCPU-to-core affinity.
Signed-off-by: Muminul Islam <muislam@microsoft.com>
Extract CPU affinity test logic from test_cpu_affinity into a
standalone _test_cpu_affinity helper that accepts a Guest
reference. The helper verifies the host has at least 4 CPUs,
boots a VM with affinity settings, and asserts vcpu0 is pinned
to cores 0,2 and vcpu1 to cores 1,3.
Add default_cpus_with_affinity_string() to Guest and
default_cpus_with_affinity() to GuestCommand in test_infra
to generate CPU arguments with affinity configuration.
Update the test_cpu_affinity call site in common_parallel to
use GuestFactory and delegate to the new helper, enabling
reuse with different guest types.
Signed-off-by: Muminul Islam <muislam@microsoft.com>
Add test_multi_cpu to the common_cvm integration test module
to verify that multi-CPU functionality works correctly in
confidential guest environments.
The test creates an Ubuntu Jammy-based confidential VM using
GuestFactory and delegates to the existing _test_multi_cpu
helper to validate SMP boot with multiple vCPUs.
Signed-off-by: Muminul Islam <muislam@microsoft.com>
Extract the multi-CPU test logic from the test_multi_cpu test
into a standalone _test_multi_cpu helper that accepts a Guest
reference as a parameter.
Update the test_multi_cpu call site in common_parallel to
create the guest via GuestFactory::new_regular_guest_factory()
and delegate to the new helper. This enables reuse of the test
logic with different guest types such as confidential VMs.
Signed-off-by: Muminul Islam <muislam@microsoft.com>
Add test_virtio_vsock to the common_cvm integration test module
to verify that virtio vsock functionality works correctly in
confidential guest environments.
The test creates an Ubuntu Jammy-based confidential VM using
GuestFactory and delegates to the existing _test_virtio_vsock
helper with hotplug disabled.
Signed-off-by: Muminul Islam <muislam@microsoft.com>
Extract guest and kernel setup out of _test_virtio_vsock and
pass a Guest reference as a parameter instead. Replace explicit
kernel and cmdline arguments with default_kernel_cmdline().
Move guest creation to the test call sites using
GuestFactory::new_regular_guest_factory(), enabling reuse of
the helper with different guest types such as confidential VMs.
Signed-off-by: Muminul Islam <muislam@microsoft.com>
Add test_power_button to the common_cvm integration test module
to verify that power button functionality works correctly in
confidential guest environments.
The test creates an Ubuntu Jammy-based confidential VM using
GuestFactory and delegates to the existing _test_power_button
helper to validate the power button signal handling.
Signed-off-by: Muminul Islam <muislam@microsoft.com>
Remove the acpi bool parameter and internal guest and kernel
setup from _test_power_button. The function now accepts a Guest
reference and uses default_kernel_cmdline() instead of
hardcoded kernel paths.
Update test_power_button in common_parallel to create a regular
guest via GuestFactory. Update test_power_button_acpi in
aarch64_acpi to use with_kernel_path(edk2_path()) for ACPI
firmware support.
Add with_kernel_path() builder method on Guest in test_infra
to allow overriding the kernel path after guest creation.
Signed-off-by: Muminul Islam <muislam@microsoft.com>
Add an option that can be used when restoring to resume the VM. This is
particularly useful when restoring the VM via the direct VMM command
line, when you might not want/have an API socket configured.
Signed-off-by: Rob Bradford <rbradford@meta.com>
Add test_virtio_block_write_zeroes_unmap_raw to verify that the
VIRTIO_BLK_WRITE_ZEROES_FLAG_UNMAP code path works correctly with
raw disk images.
The test creates a 128M raw disk and writes 64M of random data,
then uses fallocate --punch-hole on the guest block device, which
the Linux virtio-blk driver translates to VIRTIO_BLK_T_WRITE_ZEROES
with VIRTIO_BLK_WRITE_ZEROES_FLAG_UNMAP set. It then verifies:
- the zeroed region reads back as zero from the guest
- the host file became sparse (punch_hole succeeded)
- FIEMAP confirms the file has holes
Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
The config space fix in the previous commit correctly populates
the discard and write zeroes fields, so the sparse=off
workaround is no longer needed for Windows guests.
Replace default_disks_sparse_off() with default_disks() in all
Windows test cases and remove the explicit sparse=off from the
multi queue test.
Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
warning: this argument is passed by value, but not consumed in the function body
--> cloud-hypervisor/tests/integration.rs:3785:51
|
3785 | fn run_multiqueue_qcow2_test<F>(image_config: QcowTestImageConfig, test_fn: F)
| ^^^^^^^^^^^^^^^^^^^
|
help: or consider marking this type as `Copy`
--> cloud-hypervisor/tests/integration.rs:3774:5
|
3774 | enum QcowTestImageConfig {
| ^^^^^^^^^^^^^^^^^^^^^^^^
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_pass_by_value
= note: requested on the command line with `-D clippy::needless-pass-by-value`
Signed-off-by: Rob Bradford <rbradford@meta.com>
error: the borrowed expression implements the required traits
--> cloud-hypervisor/tests/integration.rs:8510:32
|
8510 | disk_check_consistency(&test_disk_path, None);
| ^^^^^^^^^^^^^^^ help: change this to: `test_disk_path`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_borrows_for_generic_args
= note: `-D clippy::needless-borrows-for-generic-args` implied by `-D clippy::all`
= help: to override `-D clippy::all` add `#[allow(clippy::needless_borrows_for_generic_args)]`
error: could not compile `cloud-hypervisor` (test "integration") due to 7 previous errors
Signed-off-by: Rob Bradford <rbradford@meta.com>
error: you seem to use `.enumerate()` and immediately discard the index
--> cloud-hypervisor/tests/integration.rs:7675:72
|
7675 | for (_i, (offset, length)) in discard_operations.iter().enumerate() {
| ^^^^^^^^^^^^
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#unused_enumerate_index
= note: `-D clippy::unused-enumerate-index` implied by `-D clippy::all`
= help: to override `-D clippy::all` add `#[allow(clippy::unused_enumerate_index)]`
help: remove the `.enumerate()` call
|
7675 - for (_i, (offset, length)) in discard_operations.iter().enumerate() {
7675 + for (offset, length) in discard_operations.iter() {
|
Signed-off-by: Rob Bradford <rbradford@meta.com>
error: consider adding a `;` to the last statement for consistent formatting
--> cloud-hypervisor/tests/integration.rs:2516:9
|
2516 | _test_simple_launch(&guest)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: add a `;` here: `_test_simple_launch(&guest);`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#semicolon_if_nothing_returned
Signed-off-by: Rob Bradford <rbradford@meta.com>
error: variables can be used directly in the `format!` string
--> cloud-hypervisor/tests/integration.rs:12770:27
|
12770 | let driver_path = format!("{}/driver", NVIDIA_VFIO_DEVICE);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#uninlined_format_args
help: change this to
|
12770 - let driver_path = format!("{}/driver", NVIDIA_VFIO_DEVICE);
12770 + let driver_path = format!("{NVIDIA_VFIO_DEVICE}/driver");
Signed-off-by: Rob Bradford <rbradford@meta.com>
Add UFFD restore tests to common_sequential: basic anonymous RAM,
shared memory, and hugepage-backed zone memory. Each exercises the
full snapshot/restore cycle with memory_restore_mode=ondemand and
verifies CPU count, memory size, and device health after resume.
Signed-off-by: Shayon Mukherjee <shayonj@gmail.com>
The rate limiter tests create raw block images with dd but do not
specify image_type=raw. Without it the VMM autodetects the format
and enables sector 0 write protection for unknown image types,
causing I/O errors when fio writes to sector 0 and making the
test hang until timeout.
Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
Moves the MSRV requirement to the workspace and expands it to all
cloud-hypervisor dependencies and dev-dependencies.
This improves discoverability for new contributors working on crates
other than the cloud-hypervisor itself and creates consistency regarding
the MSRV of cloud-hypervisor dependencies.
Functionally, this doesn't change anything for dependencies of the
cloud-hypervisor crate as the MSRV requirement is already enforced by CI
when building the cloud-hypervisor with the MSRV versioned compiler.
On-behalf-of: SAP julian.schindel@sap.com
Signed-off-by: Julian Schindel <julian.schindel@cyberus-technology.de>
With `.num_args(1..)`, multiple values can be specified for a CLI
option, but the option cannot be specified more than once. In my
experience, it’s more common to specify flags with a single argument
multiple times to specify multiple arguments. One might thus expect to
call cloud-hypervisor with e.g. `--disk path=foo --disk path==bar`.
With this commit, both `--disk path=foo path=bar path=baz` and
`--disk path=foo -disk path=bar path=baz` (note: combinations as well)
are allowed.
Signed-off-by: Sebastian Walz <sebastian.walz@secunet.com>
The AIO block backend advertises VIRTIO_BLK_F_WRITE_ZEROES
and VIRTIO_BLK_F_DISCARD to guests because the filesystem
probe (supports_sparse_operations) returns true on ext4/XFS.
However, RawFileAsyncAio::write_zeroes() and punch_hole()
return errors because Linux AIO (io_submit) has no IOCB
command for fallocate.
When io_uring is unavailable (e.g. io_uring_disabled=2, a
common security hardening on enterprise Linux), Cloud
Hypervisor falls back to the AIO backend. The guest
negotiates the feature, issues WRITE_ZEROES requests, and
gets I/O errors.
Implement write_zeroes and punch_hole using synchronous
libc::fallocate() calls, matching the pattern used by the
sync backend (RawFileSync). A VecDeque-based completion
list signals results to the caller via the existing eventfd
mechanism.
Unit tests mirror the existing raw_sync.rs test suite.
Integration tests add AIO-specific variants of the discard
and fstrim tests using _disable_io_uring=on.
Signed-off-by: Emir Beganovic <beganovic.emir@gmail.com>
Since we run integration tests on Intel & AMD this should test the
behaviour of `--cpus nested={on|off}` correctly.
Signed-off-by: Rob Bradford <rbradford@meta.com>
Add test_api_http_shutdown and test_api_http_delete to the
common_cvm module using GuestFactory with 4 CPUs. Both tests
reuse existing _test_api_shutdown and _test_api_delete helpers
to extend API coverage to confidential VMs.
Signed-off-by: Muminul Islam <muislam@microsoft.com>
Replace manual Guest field assignments with
GuestFactory::new_confidential_guest_factory() in
test_focal_simple_launch for consistent CVM guest creation.
Signed-off-by: Muminul Islam <muislam@microsoft.com>
Add test_api_http_create_boot to the common_cvm module using
GuestFactory::new_confidential_guest_factory() with 4 CPUs.
This extends API create/boot coverage to confidential VMs.
Signed-off-by: Muminul Islam <muislam@microsoft.com>
Refactor api_create_body() to read cpu_count, kernel_path,
and kernel_cmdline from Guest fields instead of taking them
as parameters. This makes Guest the single source of truth
for VM configuration.
Update all call sites in HTTP and DBus API tests to use the
new parameterless signature. Switch guest creation to use
GuestFactory for consistent 4-CPU configuration.
Replace manual CPU and memory assertions with
validate_cpu_count() and validate_memory() helpers.
Replace thread::sleep with wait_vm_boot() in
_test_api_create_boot for proper boot synchronization.
Signed-off-by: Muminul Islam <muislam@microsoft.com>
Move test constants (MAX_NUM_PCI_SEGMENTS,
DIRECT_KERNEL_BOOT_CMDLINE, CONSOLE_TEST_STRING),
arch-specific image name modules (x86_64, aarch64),
and helper functions (direct_kernel_boot_path, edk2_path)
from integration.rs to test_infra/src/lib.rs.
This centralizes shared test definitions so they can be
reused across multiple test crates instead of being
confined to integration.rs.
Signed-off-by: Muminul Islam <muislam@microsoft.com>
Boot a VM with a 4k sector loop device passed with direct=on and
image_type=raw. Assert that the guest sees a 4096 byte logical
sector and that a DIO write/read roundtrip at 4096 byte alignment
succeeds.
Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
Verify that DiskTopology::probe() returns the correct DIO alignment
for a regular file on a 4k sector filesystem. The test creates a
loop device with --sector-size 4096, formats ext4, places a raw disk
image on it, and boots a VM with direct=on. Asserts that the guest
sees a 4096 byte logical sector and that a DIO write/read roundtrip
succeeds.
Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
Move LOOP_CTL_GET_FREE + open + LOOP_CONFIGURE into the retry loop
so each attempt requests a fresh free device number. Previously, a
parallel test could claim the same device between GET_FREE and
CONFIGURE, and retrying the same stale number would always fail with
EBUSY.
Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
Drop an unused vm_memory::GuestAddress import from common_cvm
in integration tests to keep the module clean.
Signed-off-by: Muminul Islam <muislam@microsoft.com>
Replace hard-coded --memory size=512M args with default_memory()
across integration tests to centralize default memory settings.
This reduces duplicated CLI fragments and keeps behavior consistent.
Signed-off-by: Muminul Islam <muislam@microsoft.com>
Replace hard-coded --cpus boot=<n> arguments in integration tests
with GuestCommand::default_cpus() for shared, centralized defaults.
This removes duplicated CLI fragments and keeps CPU setup consistent.
Signed-off-by: Muminul Islam <muislam@microsoft.com>
Replace the hard-coded memory threshold check in the simple launch
integration test with Guest::validate_memory(None).
Add Guest::get_expected_memory() to derive thresholds from mem_size_str
and vm_type, and reuse this through validate_memory().
Signed-off-by: Muminul Islam <muislam@microsoft.com>
Replace hard-coded --memory args in simple launch tests
with GuestCommand defaults driven by Guest state.
Add Guest.mem_size_str with a default of 512M and introduce
default_memory_string() and GuestCommand::default_memory().
Signed-off-by: Muminul Islam <muislam@microsoft.com>
Instead of validating number of CPU in the test case itself,
moving the checking of the CPU count to Guest struct with a
new function as The Guest already has the Default CPU number.
Signed-off-by: Muminul Islam <muislam@microsoft.com>
Replace the hard-coded .args(["--cpus", "boot=1"]) in the simple
launch integration test with a shared helper (default_cpus) from test
infrastructure.
Extend Guest with explicit CPU-related defaults (num_cpu, nested)
and add default_cpus_string() so CPU configuration is derived from
guest state instead of being duplicated at call sites.
This refactor improves consistency and makes CPU defaults easier to
maintain across integration tests.
Signed-off-by: Muminul Islam <muislam@microsoft.com>
Move MetaEvent from the integration test into shared test infrastructure
and expose it for reuse. Add a Guest helper that returns the expected
sequential events for simple launch, and update the integration test to
consume this helper instead of maintaining a local event list.
Adjust expected behavior for confidential VMs by omitting the disk reset
event, which is not guaranteed to be emitted in that mode. Preserve the
existing expected sequence for non-confidential VMs.
Signed-off-by: Muminul Islam <muislam@microsoft.com>
Add a core_scheduling option to --cpus with three modes of operation.
This feature takes advantage of a kernel feature that restricts
scheduling of processes on the SMT threads on the same core. This is
useful for mitigating certain classes of side-channel attacks and has
better performance that disabling SMT on the CPU.
- vm (default): All vCPU threads share one core scheduling cookie.
They may be co-scheduled on SMT siblings while host threads are
excluded - this has minimal performance impact and can even
potentially improve performance from co-location.
- vcpu: Each vCPU gets a unique cookie preventing any two vCPUs from
sharing SMT siblings. This has the strongest isolation but at some
compromise of performance.
- off: No core scheduling applied (old behaviour).
This isolation is done by the kernel maintaining a "cookie" - threads
with the same cookie can share the same core.
In vCPU mode each vCPU thread the cookie is created when the thread
starts and each gets a unique cookie. For VM mode the first vCPU thread
(the leader) will create the cookie. All other vCPU threads started (via
hotplug or during boot) will have that cookie shared to it.
EINVAL/ENODEV from prctl is silently ignored so this works transparently
on kernels older than 5.14 that lack PR_SCHED_CORE or when SMT disabled.
Full details of this kernel feature can be found at:
https://docs.kernel.org/admin-guide/hw-vuln/core-scheduling.html
This implementation was inspired by crosvm's implementation - in
particular the enable_core_scheduling() function.
This is challenging to test via integration testing but the logging of
the received cookie shows it working:
VM case:
cloud-hypervisor: 0.243102s: <vcpu1> INFO:vmm/src/cpu.rs:1247 -- vCPU 1: core scheduling cookie = 0x33e4c167
cloud-hypervisor: 0.243102s: <vcpu0> INFO:vmm/src/cpu.rs:1247 -- vCPU 0: core scheduling cookie = 0x33e4c167
vCPU case:
cloud-hypervisor: 0.089356s: <vcpu0> INFO:vmm/src/cpu.rs:1247 -- vCPU 0: core scheduling cookie = 0x13993ad6
cloud-hypervisor: 0.089380s: <vcpu1> INFO:vmm/src/cpu.rs:1247 -- vCPU 1: core scheduling cookie = 0xd48e86e
Signed-off-by: Rob Bradford <rbradford@meta.com>