Commit Graph

10270 Commits

Author SHA1 Message Date
Rob Bradford
4d6c7c95c0 virtio-devices: iommu: Reject UNMAP that partially overlaps a mapping
An UNMAP that would split an existing mapping must be rejected with
VIRTIO_IOMMU_S_RANGE without removing anything. The previous start-only
retain silently left mappings that started outside the unmap range but
overlapped it.

Walk bookkeeping under a read lock and reject before touching VFIO so a
rejection cannot leave VFIO and bookkeeping out of sync.

Signed-off-by: Rob Bradford <rbradford@meta.com>
Assisted-by: Claude:claude-opus-4-7
2026-05-06 08:58:03 +00:00
Rob Bradford
7989e46f8b virtio-devices: iommu: Pass size to translate_gva/translate_gpa
The DmaRemapping translate_gva and translate_gpa entry points discarded
the size argument that AccessPlatform's signature already carries and
only checked the base address. A buffer beginning inside a mapping but
extending past it was treated as fully translated, allowing reads or
writes outside the IOMMU-authorized window.

Add `size` to the trait, validate the full span fits in a single
mapping, and propagate it through AccessPlatformMapping.

Signed-off-by: Rob Bradford <rbradford@meta.com>
Assisted-by: Claude:claude-opus-4-7
2026-05-06 08:58:03 +00:00
Rob Bradford
f9abcb8d9c virtio-devices: iommu: Use checked add for reply length
The reply length was `hdr_len + size_of::<tail>()`, computed twice.
Make it explicit via checked_add and reuse the result.

Signed-off-by: Rob Bradford <rbradford@meta.com>
Assisted-by: Claude:claude-opus-4-7
2026-05-06 08:58:03 +00:00
Muminul Islam
d552320f4f docs: remove CI workflow in the testing doc
Remove CI workflow description section as the yaml
files change often and the docs become stale quickly.

Assisted-by: Claude:Opus-4.6
Signed-off-by: Muminul Islam <muislam@microsoft.com>
2026-05-05 21:24:59 +00:00
Demi Marie Obenour
fb9532f857 virtio-devices: PCI: Hard-code the settings BAR number
It will always be 0.

Signed-off-by: Demi Marie Obenour <demiobenour@gmail.com>
2026-05-05 11:45:44 +00:00
Demi Marie Obenour
8b86dd9fb5 pci: Reduce use of magic number 4
No functional change intended.

Signed-off-by: Demi Marie Obenour <demiobenour@gmail.com>
2026-05-05 11:45:44 +00:00
Dylan Reid
68ae56eb74 vmm: memory_manager: test: build sparse fixtures via PUNCH_HOLE
The unit tests added in bf3279f09 built sparse files by writing only
at one offset and assuming the surrounding pages stayed unallocated.
That breaks on shmem/tmpfs with huge=within_size: kernel 6.10+ added
large-folio support to shmem, and on first write the kernel allocates
one folio whose order is the largest power-of-two number of pages
that fits inside the file size (capped at PMD-size). For a 64 KiB
test file the very first pwrite anywhere allocates a 64 KiB folio
covering the whole file, so SEEK_HOLE never reports a hole and
written_pages_show_as_data_extents,
sparse_file_yields_extents_at_written_positions, and
single_extent_at_zero_offset all fail. memfd_create lives on shmem
too and inherits the same THP policy from
/sys/kernel/mm/transparent_hugepage/shmem_enabled, so the problem is
not /tmp-specific.

Fix the fixtures, not the production code: build each test file via
a new sparse_layout() helper that writes the requested data extents
and then fallocate(FALLOC_FL_PUNCH_HOLE)s every gap. PUNCH_HOLE is
the explicit "deallocate these pages" syscall and is honored by every
Linux filesystem we run tests on (tmpfs, ext4, xfs, btrfs); the
kernel splits any large folio overlapping the punched range. The
resulting SEEK_DATA/SEEK_HOLE map matches the spec exactly regardless
of folio/THP policy.

For single_extent_at_zero_offset the dst side still loses to the
folio allocator -- writing 8 KiB into a 64 KiB tmpfs file allocates
a 64 KiB folio whether we want it or not -- so the previous
meta.blocks()-based sparseness assertion (which tested the filesystem,
not our code) is replaced with a sentinel pre-fill: dst starts filled
with 0xFE and the post-condition is that bytes outside the
source-data extent are still 0xFE. That directly verifies
write_region_sparse only touched the data extent without depending on
dst-side hole reporting.

Side effect: extent_at_non_zero_src_offset,
two_regions_in_same_destination_file_at_dst_offset, and
round_trip_sparse_write_then_read previously passed by accident on
hosts with mTHP-on-shmem -- their src memfds reported the whole file
as data so write_region_sparse silently fell into a dense copy of
zeros + data. With sparse_layout() the sources are genuinely sparse
and those tests now exercise the sparse path on every host.

Tested on tmpfs (huge=within_size) and ext4 (TMPDIR=/var/tmp); all 9
tests pass on both with no skips.

Assisted-by: Claude:Opus-4.7
Signed-off-by: Dylan Reid <dgreid@fb.com>
2026-05-05 08:42:56 +00:00
Anatol Belski
6daa9e14e6 virtio-devices: Test config vector OOB does not panic
Verify that firing a config change interrupt with msix_config
vector beyond the table size returns Ok without panicking.

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2026-05-05 08:24:19 +00:00
Anatol Belski
6be080c083 virtio-devices: Test trigger with valid vector fires interrupt
Verify that a valid in bounds vector with MSI-X enabled
successfully triggers the interrupt source group.

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2026-05-05 08:24:19 +00:00
Anatol Belski
a682112851 virtio-devices: Test notifier with OOB vector returns None
Verify that requesting a notifier with an out-of-bounds MSI-X
vector returns None instead of panicking.

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2026-05-05 08:24:19 +00:00
Anatol Belski
088b1363e7 virtio-devices: Test trigger with NO_VECTOR returns Ok
Verify that triggering an interrupt when the vector is set to
VIRTQ_MSI_NO_VECTOR short-circuits and returns Ok.

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2026-05-05 08:24:19 +00:00
Anatol Belski
442e7f85fa virtio-devices: Test trigger with OOB MSI-X vector does not panic
Verify that firing an interrupt with a queue vector beyond the
MSI-X table size returns Ok without panicking.

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2026-05-05 08:24:19 +00:00
Anatol Belski
3b431afba4 virtio-devices: Check MSI-X vector bounds before table access
A malicious or buggy guest can write an out-of-bounds value to
queue_msix_vector or msix_config. When the device later triggers
an interrupt, it indexes into table_entries with the unchecked
vector, causing a panic.

Validate the vector against the MSI-X table size in both trigger()
and notifier() paths, logging a warning and returning early when
the vector exceeds the table bounds.

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2026-05-05 08:24:19 +00:00
Dylan Reid
376434a695 block: bounds-check the cumulative descriptor length
Request::execute and Request::execute_async checked each data descriptor
against `disk_nsectors` using the request's fixed start sector. With
sector = disk_nsectors-1 and N descriptors of 512 bytes each, every
descriptor passed (top = disk_nsectors) but the vectored I/O
collectively read/wrote N*512 bytes starting at the last sector — N-1
sectors past EOF.

For the io_uring/aio raw backends this lets the guest extend the host
disk image beyond its provisioned size, exhausting the host filesystem.
For fixed-VHD images (footer at end of file) the same chain overwrites
the footer with guest-controlled bytes, corrupting the disk image.

Replace the per-descriptor check with a chain-wide check_data_bounds().
Pre-validating the entire request before beginning the operation avoids
having to unroll a partial submit.

Signed-off-by: Dylan Reid <dgreid@fb.com>
2026-05-05 08:21:03 +00:00
Muminul Islam
3df0579866 performance-metrics: avoid double ref in test selection
Use into_iter() for test_list when building tests_to_run.

This keeps the collected type as Vec<&PerformanceTest>.

Signed-off-by: Muminul Islam <muislam@microsoft.com>
2026-05-04 21:36:25 +00:00
Rob Bradford
63d6beb170 virtio-devices: vsock: Adapt used handling to match other devices
Follow the same pattern as other virtio devices using a bool to check if
it needs notification and propagating its own Error enum.

Sadly this does still use `anyhow!()` but this does match with the
behaviour of the other devices in their implementations.

As a side effect we can now remove two errors from the top-level Error
enum in virtio-devices as these were only used by this module and those
errors had mangled descriptions.

Signed-off-by: Rob Bradford <rbradford@meta.com>
2026-05-04 21:28:54 +00:00
Rob Bradford
7d8986aad0 tests: Allow more time for firmware & O_DIRECT tests
Booting the VM on these tests takes longer so allow longer before
timing out the boot.

Signed-off-by: Rob Bradford <rbradford@meta.com>
2026-05-04 21:28:33 +00:00
Rob Bradford
a93dbe790f tests: Cleanup interfaces in test_vfio
If this test flakes is can then cause subsequent invocations to fail as
the test has left its special test interfaces alive.

Signed-off-by: Rob Bradford <rbradford@meta.com>
2026-05-04 21:28:33 +00:00
Rob Bradford
f09ab0898d vmm: config: Reject rate limiting with vhost_user
Rate limiting is implemented in the virtio device layer and does not
apply to vhost-user devices which delegate I/O handling to an external
process.

Add validation to reject configurations where vhost_user is enabled
along with rate limiting options (bw_size, ops_size, or
rate_limit_group) for both disk and network devices.

This prevents users from mistakenly configuring rate limiting that would
be silently ignored when using vhost-user backends.

Signed-off-by: Rob Bradford <rbradford@meta.com>
2026-05-04 17:43:25 +00:00
Anatol Belski
7fbc5a1354 pci: msix: Replace panic with graceful error on invalid table write
A malicious or buggy guest can issue an MSI-X table write with an
unexpected size (not 4 or 8 bytes), triggering an assert!() that
crashes the VMM process. Replace the assertion with an error log and
early return to maintain VMM stability under adversarial guest
behavior.

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2026-05-04 16:08:06 +01:00
Nguyen Dinh Phi
c5951252a5 tests: Adding integration tests for migration of paused VM
Adding a paused flag to live_migration() tests; when this
flag is set, the VM will be paused before migration is
performed.

Signed-off-by: Nguyen Dinh Phi <phind.uet@gmail.com>
2026-05-04 09:30:30 +00:00
Nguyen Dinh Phi
23fc9ca258 vmm: support migration of paused VMs
This extends migration to also support paused VMs, preserving the
paused state on the destination.

Changes:
- Add CompletePaused protocol command that finalizes migration without
 resuming the VM on the destination
- Skip the pause step during migration if the VM is already paused
- On migration failure, only restore the running state if
  the VM was originally running (not paused)

Signed-off-by: Nguyen Dinh Phi <phind.uet@gmail.com>
2026-05-04 09:30:30 +00:00
Dylan Reid
e2b9fa261b virtio-devices: get_host_address_range check fixes
`get_host_address_range` used `check_range(addr, size)` as a guard then
unwrapped `get_slice(addr, size)`. This allowed a span across two
regions to hit the unwrap (get_slice limits to one range).

If `size` were zero, then the checks were all skipped. Causing a panic
later on for an invalid address.

Make get_slice the sole authority and reject size==0 explicitly.
Callers already handle None.

Signed-off-by: Dylan Reid <dgreid@fb.com>
2026-05-04 09:08:43 +00:00
Dylan Reid
c565d4eb88 virtio-devices: block: don't kill worker on per-request errors
The guest can cause submit and completion failures with malformed chains
or invalid addresses. However, this shouldn't permanently stall the
device and terminate the worker.

Genuine reset-worthy failures set needs_reset and return `Ok` anyways
and will more cleanly reset the worker.

Signed-off-by: Dylan Reid <dgreid@fb.com>
2026-05-04 09:08:43 +00:00
Dylan Reid
fbcf2fd6b0 virtio-devices: block: cap submit-loop iterations to virtqueue size
process_queue_submit's drain loop builds a fresh queue.iter() per
iteration, which re-reads the guest avail index on every call and has
no per-call cap (the per-iter gap check in virtio-queue only protects
against avail_idx jumping more than queue_size between two reads).
In theory, a malicous or buggy guest could keep adding descriptors and
cause this loop to overflow the iouring submit queue.

Cap a single drain at queue_size. A spec-compliant driver never
produces more than queue_size outstanding entries simultaneously, so
the cap is invisible to well-behaved guests.

Signed-off-by: Dylan Reid <dgreid@fb.com>
2026-05-04 09:08:43 +00:00
Muminul Islam
48e671011c scripts: Add kernel option validation in prepare_linux
Add validation checks to prepare_linux() to catch invalid
kernel option combinations early:

- Error if --build-guest-kernel and CH_CUSTOM_KERNEL are
  both provided, as they are mutually exclusive.
- On x86_64, error if only one of CH_CUSTOM_KERNEL or
  CH_CUSTOM_BZIMAGE is set; both must be provided together.
- Fix kernel-already-present check: use per-architecture
  branches with correct bash syntax (elif instead of
  else-if, [[ ]] instead of [ && ]) so aarch64 and x86_64
  are each handled properly.

Signed-off-by: Muminul Islam <muislam@microsoft.com>
2026-05-04 08:26:15 +00:00
Muminul Islam
bb8bbb2961 docs: add testing documentation
Add docs/testing.md covering the dev_cli.sh interface, all
test types (unit, integration, VFIO, Windows, live migration,
rate limiter, CVM), custom kernel/firmware overrides via
environment variables, performance metrics, code coverage,
and the CI workflow matrix.

Assisted-by: GitHub Copilot:Claude-Opus-4.6

Signed-off-by: Muminul Islam <muislam@microsoft.com>
2026-05-04 08:26:15 +00:00
Muminul Islam
c5e90a37e6 scripts: skip downloads when workloads already exist
Add file-existence guards around firmware and OVMF download
calls in integration test scripts that were missing them.
Also guard prepare_linux() in test-util.sh so it returns
early when the kernel binary is already present.

This lets users pre-populate the workloads directory (e.g.
via CH_CUSTOM_KERNEL, CH_CUSTOM_FIRMWARE, CH_CUSTOM_OVMF)
and avoid redundant network fetches or source builds inside
the container.

Updated scripts:
- test-util.sh (prepare_linux early return)
- run_integration_tests_aarch64.sh
- run_integration_tests_vfio.sh
- run_integration_tests_windows_x86_64.sh
- run_integration_tests_windows_aarch64.sh

Assisted-by: GitHub Copilot:Claude-Opus-4.6

Signed-off-by: Muminul Islam <muislam@microsoft.com>
2026-05-04 08:26:15 +00:00
Muminul Islam
00bee62653 scripts: skip checksum for custom-provided workloads
Skip sha1sum verification for firmware files that were
provided via CH_CUSTOM_FIRMWARE or CH_CUSTOM_OVMF environment
variables.  Custom files will not match the expected checksums,
so we filter them out of the sha1sums list before running
sha1sum --check.

Updated scripts:
- run_integration_tests_x86_64.sh
- run_integration_tests_aarch64.sh

Assisted-by: GitHub Copilot:Claude-Opus-4.6

Signed-off-by: Muminul Islam <muislam@microsoft.com>
2026-05-04 08:26:15 +00:00
Muminul Islam
38bc97dd4d scripts: copy custom workloads before container launch
When CH_CUSTOM_KERNEL, CH_CUSTOM_FIRMWARE, or CH_CUSTOM_OVMF
environment variables are set, copy the referenced files into
the host workloads directory before starting Docker. The files
land at the default paths the test scripts expect
(vmlinux-x86_64, Image-arm64, hypervisor-fw, CLOUDHV.fd,
CLOUDHV_EFI.fd), so the existing download-if-missing guards
inside the container skip the network fetch.

Each variable is independent; users can override any
combination without affecting the others.

Assisted-by: GitHub Copilot:Claude-Opus-4.6

Signed-off-by: Muminul Islam <muislam@microsoft.com>
2026-05-04 08:26:15 +00:00
Muminul Islam
339d0a84f9 scripts: deduplicate container env args in dev_cli.sh
Extract a common_env_args bash array with the environment
variables shared by both unit and integration test containers
(BUILD_TARGET, RUSTFLAGS, TARGET_CC). The unit test block
uses common_env_args plus its own LLVM_PROFILE_FILE. After
the unit block, common_env_args is extended with the USER
and AUTH_DOWNLOAD_TOKEN variables used by all integration
test groups.

Assisted-by: GitHub Copilot:Claude-Opus-4.6

Signed-off-by: Muminul Islam <muislam@microsoft.com>
2026-05-04 08:26:15 +00:00
Muminul Islam
afeeeee494 scripts: deduplicate container runtime args in dev_cli.sh
Extract a common_args bash array with the runtime arguments
shared by both unit and integration test containers (name,
workdir, rm, seccomp, volumes). The unit test block uses
common_args plus its own device and cap-add flags. After
the unit block, common_args is extended with the privileged,
ipc, net, tmpfs, and workload-volume flags used by all
integration test groups.

Assisted-by: GitHub Copilot:Claude-Opus-4.6

Signed-off-by: Muminul Islam <muislam@microsoft.com>
2026-05-04 08:26:15 +00:00
Rob Bradford
80c56f728e vmm: config: Validate mergeable and shared are not both set
KSM will not attempt to merge pages that are mapped as MAP_SHARED, so
configuring memory with both mergeable and shared options is invalid.
Add validation to reject configurations where both options are enabled
for memory or memory zones.

Signed-off-by: Rob Bradford <rbradford@meta.com>
2026-05-04 08:24:26 +00:00
Julian Schindel
9a0fb1b06a vmm: fix UB in load_igvm(...)
With the `mshv` feature enabled, the immutable `data` `Vec` is mutated
via a pointer. This violates Rust aliasing rules. Fixed by cloning the
`Vec` to a mutable instance when the `mshv` feature is active.

Signed-off-by: Julian Schindel <mail@arctic-alpaca.de>
2026-05-04 08:22:29 +00:00
Julian Schindel
5f360abdc7 arch: 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
Julian Schindel
2b6e9df4e3 block: 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
Julian Schindel
7455ff1ea4 devices: 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
Julian Schindel
9b0d4b20ea hypervisor: 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
Julian Schindel
2a6b746f5e net_util: 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
Julian Schindel
6de472f1bb pci: 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
Julian Schindel
ae7113e1d4 virtio-devices: 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
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
Julian Schindel
cb09c37c55 vm-migration: 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
Julian Schindel
8abd9d7db5 tpm: 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
Julian Schindel
032f29da29 misc: 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
c97d635d40 hypervisor, vmm: Build and pass SNP ID block to launch finish
Add KvmSevSnpIdBlock and KvmSevSnpIdAuth structs matching the AMD
SEV-SNP Firmware ABI Spec (Rev 1.58), and build them from the IGVM
SNP ID block directive during launch finish. This properly populates
id_block_uaddr/id_auth_uaddr in KVM_SEV_SNP_LAUNCH_FINISH and derives
auth_key_en from the assembled author key, matching QEMU's behavior.

Thread the guest policy from sev_snp_init to launch_finish via an
atomic on KvmVm so the ID block gets the correct policy value.

Also track has_snp_id_block in IgvmLoadedInfo to enable the ID block
based on whether the IGVM file actually contains one, rather than
hardcoding it for KVM.

Signed-off-by: Ruben Hakobyan <hruben@meta.com>
2026-05-01 20:28:55 +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
4a91b4a608 vmm: Preserve SEV-SNP IGVM load ordering
Preserve the original IGVM import order for KVM SNP launch updates.
The launch digest is order-sensitive, so only coalesce adjacent pages
that already share the same page type and size. MSHV continues to
sort by GPA for hypercall batching.

Signed-off-by: Kevin Hui <kevinhui@meta.com>
2026-05-01 20:28:55 +00:00
Kevin Hui
982934fba0 vmm: Add SNP zero-page type for IGVM imports
Introduce the KVM_SNP_PAGE_TYPE_ZERO page type for ZERO
pages. AMD SEV SNP can accept ZERO pages as a page in which
the page memory is functionally just zeroes

Signed-off-by: Kevin Hui <kevinhui@meta.com>
2026-05-01 20:28:55 +00:00
Kevin Hui
e3e22d8e78 vmm: Add unit tests for generating hash blocks for SEV-SNP
Verify the SEV hash table layout, GUID placement, kernel/initrd/cmdline
digest values, and the setup_sects > boot_params size branch. These
guard against silent regressions in the launch digest computation.

Signed-off-by: Kevin Hui <kevinhui@meta.com>
2026-05-01 20:28:55 +00:00