Commit Graph

10048 Commits

Author SHA1 Message Date
Rob Bradford
d449983495 vmm: Be consistent with PCI bus reservation nomenclature
Our bus slots are now Reserved/Allocated/Free so change the method to
free it to free_device_id() and update error.

Also update to take u8 to match the other methods.

Signed-off-by: Rob Bradford <rbradford@meta.com>
2026-04-17 07:45:22 +00:00
Pascal Scholz
18873d88d7 tests: Add an integration test for PCI device ID allocation errors
Adds a test that checks the correct error is returned on allocation of
an invalid device ID (one that is not in the range 0-31) and when trying
to allocate a reserved ID (such as that of the root bridge).

Signed-off-by: Pascal Scholz <pascal.scholz@cyberus-technology.de>
On-behalf-of: SAP pascal.scholz@sap.com
Signed-off-by: Rob Bradford <rbradford@meta.com>
2026-04-17 07:45:22 +00:00
Pascal Scholz
f81faad0a1 tests: Add an integration test to check duplicate PCI device IDs
This integration test verifies that the same device ID cannot be
allocated twice. Moreover, we check that the returned error matches our
expectations.

Signed-off-by: Pascal Scholz <pascal.scholz@cyberus-technology.de>
On-behalf-of: SAP pascal.scholz@sap.com
Signed-off-by: Rob Bradford <rbradford@meta.com>
2026-04-17 07:45:22 +00:00
Pascal Scholz
f82eebc0b0 tests: Add an integration test to verify PCI device allocations
This commit adds an integration test to verify that the guest sees the
correct BDF. Moreover, we check that we can allocate a random free BDF
and that freeing BDFs works.

Signed-off-by: Pascal Scholz <pascal.scholz@cyberus-technology.de>
On-behalf-of: SAP pascal.scholz@sap.com
Signed-off-by: Rob Bradford <rbradford@meta.com>
2026-04-17 07:45:22 +00:00
Pascal Scholz
8259f92909 tests: Return stderr when executing commands
If we want to test for error cases, it can be useful to inspect the
`stderr` of a `Command` to analyze the errors. For example, this allows
us to ensure that a `Command` returns an `IoError` by parsing the
error trace, if an `IoError` is expected.

This commit prepares the implementation of negative integration tests
for the configurable BDFs.

Signed-off-by: Pascal Scholz <pascal.scholz@cyberus-technology.de>
On-behalf-of: SAP pascal.scholz@sap.com
2026-04-17 07:45:22 +00:00
Rob Bradford
b4723999f8 docs: Update the relevant documentation
Some of the documentation references PCI segment ID. For those documents
add a mention of the new PCI device ID.

Signed-off-by: Rob Bradford <rbradford@meta.com>
2026-04-17 07:45:22 +00:00
Rob Bradford
5aa3692c6d vmm: device_manager: Reserve explicitly used PCI device IDs
Use two passes to first reserve PCI device IDs and then allocate them
when adding the devices to the bus. This prevents a situation where an
anonymous PCI device allocation clashes with an explicitly allocated PCI
device ID.

Signed-off-by: Rob Bradford <rbradford@meta.com>
2026-04-17 07:45:22 +00:00
Pascal Scholz
aace90f270 vmm: Propagate PCI device ID from the config
We pass the device ID from the config to the allocation routine, where
it is then used as the preferred device ID alongside the existing PCI
segment ID.

Signed-off-by: Pascal Scholz <pascal.scholz@cyberus-technology.de>
On-behalf-of: SAP pascal.scholz@sap.com
Signed-off-by: Rob Bradford <rbradford@meta.com>
2026-04-17 07:45:22 +00:00
Pascal Scholz
7315a38a02 vmm: Validate PCI device ID
Validate the PCI device ID are within range and not using the reserved
value. We need this option to ensure that invalid device IDs received
via an API call result in an error as soon as possible. In this case,
this would be after deserialization. On this code path, validation via
`parse` is skipped and must be invoked by calling `validate`.

Signed-off-by: Pascal Scholz <pascal.scholz@cyberus-technology.de>
On-behalf-of: SAP pascal.scholz@sap.com
Signed-off-by: Rob Bradford <rbradford@meta.com>
2026-04-17 07:45:22 +00:00
Rob Bradford
4e247cf91d vmm: config: Add pci_device_id to SYNTAX for supported devices
For those devices types that have the the ability to support specifying
the PCI device ID add it to their help syntax.

Signed-off-by: Rob Bradford <rbradford@meta.com>
2026-04-17 07:45:22 +00:00
Rob Bradford
e5d73159f6 vmm: openapi: Add pci_device_id to the required device entries
Also add pci_segment that was missing from vfio-user devices.

Signed-off-by: Rob Bradford <rbradford@meta.com>
2026-04-17 07:45:22 +00:00
Rob Bradford
c3ec804a44 vmm: config: Add pci_device_id to PciDeviceCommonConfig
This adds it to all device types that use the common PCI device
configuration.

Signed-off-by: Rob Bradford <rbradford@meta.com>
2026-04-17 07:45:22 +00:00
Rob Bradford
51a729a874 pci: Add support for reserving but not allocating slots
This can be used in a two pass approach where all configs that can hold
PCI devices are evaluated to reserve any specific PCI device IDs they
may need. Those device IDs will later be allocated when the devices are
added to the bus. The tri-state Free, Reserved, Allocated also catches
the problem of hotplugging a device with a specific, already used,
device ID.

Signed-off-by: Rob Bradford <rbradford@meta.com>
2026-04-17 07:45:22 +00:00
Rob Bradford
3a5fad22b9 vmm: Fix segment log message formatting
Signed-off-by: Rob Bradford <rbradford@meta.com>
2026-04-17 07:45:22 +00:00
Pascal Scholz
93c17cb291 vmm: Add tests for allocate_device_id in PciSegment
Next to tests for `allocate_device_id`, we introduce a new constructor
`new_without_address_manager`, only available in the test build. As
there is no way to instantiate an `AddressManager` in the tests, we use
this constructor to work around this.

Signed-off-by: Pascal Scholz <pascal.scholz@cyberus-technology.de>
On-behalf-of: SAP pascal.scholz@sap.com
Signed-off-by: Rob Bradford <rbradford@meta.com>
2026-04-17 07:45:22 +00:00
Pascal Scholz
34f08002e1 vmm: Allow for device ID allocation on a segment
Allocating a device ID is crucial for assigning a specific ID to a
device. We need this to implement configurable PCI device ID.

Signed-off-by: Pascal Scholz <pascal.scholz@cyberus-technology.de>
On-behalf-of: SAP pascal.scholz@sap.com
Signed-off-by: Rob Bradford <rbradford@meta.com>
2026-04-17 07:45:22 +00:00
Pascal Scholz
afd155d578 pci: Refactor bus.rs to better fit a PCI bus's semantics
This commit refactors the PCI bus struct. It has two major focuses.
First, we change the type of `device_ids` in `PciBus` to an array. A
fixed-size array better reflects real PCI bus constraints, especially
its limited number of PCI devices. Moreover, it can't be grown
accidentally.

The second focus is changing the type of the key of `devices` in
`PciBus` to `u8`, since device IDs are not allowed to exceed 31. We
furthermore replace magic numbers with constants and make them publicly
available so we can use them in a follow-up change when parsing user
input.

Signed-off-by: Pascal Scholz <pascal.scholz@cyberus-technology.de>
On-behalf-of: SAP pascal.scholz@sap.com
2026-04-17 07:45:22 +00:00
Rob Bradford
43b5a474f9 tests: Remove explicit sleep from test_api_dbus_and_http_interleaved
Instead wait for the guest to stop responding on the SSH port.

Signed-off-by: Rob Bradford <rbradford@meta.com>
2026-04-16 22:50:47 +00:00
Rob Bradford
1269475c2a tests: Remove explicit sleeps from pvpanic test
Instead wait for the event to be delivered that it has panicked.

Signed-off-by: Rob Bradford <rbradford@meta.com>
2026-04-16 22:50:47 +00:00
Rob Bradford
0107675eb1 tests: Remove explicit sleeps from net tests
Use `wait_until()` with the SSH command for detecting if the net device
is present/absent as part of hotplugging/unplugging.

Signed-off-by: Rob Bradford <rbradford@meta.com>
2026-04-16 22:50:47 +00:00
Rob Bradford
9ca6d4ca41 tests: Remove explicit sleeps from block tests
Use `wait_until()` with the SSH command for detecting if the block
device is present/absent as part of hotplugging/unplugging.

Signed-off-by: Rob Bradford <rbradford@meta.com>
2026-04-16 22:50:47 +00:00
Rob Bradford
78224baac6 tests: Remove explicit sleeps from virtio-fs tests
Instead use `wait_until()` for mounting of the filesystem.

Signed-off-by: Rob Bradford <rbradford@meta.com>
2026-04-16 22:50:47 +00:00
Rob Bradford
01decd964f tests: Remove explicit sleep from tests_simple_launch tests
On the shutdown path remove the explicit sleep and instead wait for
the event to be delivered.

Signed-off-by: Rob Bradford <rbradford@meta.com>
2026-04-16 22:50:47 +00:00
Rob Bradford
f55a90c170 tests: Remove explicit sleeps from "liveness" checks
The vhost-user tests uses SSH and checking the RAM to test for the
liveness of the VM - replace the explicit sleep before them with
`wait_until()` allowing them to potentially finish earlier.

Signed-off-by: Rob Bradford <rbradford@meta.com>
2026-04-16 22:50:47 +00:00
Rob Bradford
a1cfbd6f5c tests: Use wait_until() to check for vhost-user socket
Rather than use a fixed time to wait for the socket to be opened instead
test for its existence using `wait_until()`.

Signed-off-by: Rob Bradford <rbradford@meta.com>
2026-04-16 22:50:47 +00:00
Rob Bradford
52c24136b5 tests: Remove explicit sleeps before killing vhost-user daemons
If we're about to kill the daemons we don't need to spin waiting for
them.

Signed-off-by: Rob Bradford <rbradford@meta.com>
2026-04-16 22:50:47 +00:00
Rob Bradford
2eafee69be tests: Remove explicit sleeps from balloon tests
Use the new `wait_until()` to test the balloon size.

Signed-off-by: Rob Bradford <rbradford@meta.com>
2026-04-16 22:50:47 +00:00
Rob Bradford
030e63476e tests: Reduce explicit sleep time in _test_api_* tests
Use new `wait_until()` and existing boot response mechanisms to remove
explicit sleeps from these tests.

Signed-off-by: Rob Bradford <rbradford@meta.com>
2026-04-16 22:50:47 +00:00
Max Makarov
cdfedfaab2 vmm: device_manager: reject duplicate socket in add_user_device
Calling vm.add-user-device a second time with a socket path already
in use makes the VMM thread block indefinitely inside
vfio_user::Client::new(). libvfio-user servers (SPDK, the reference
libvfio-user daemon) accept a single active client per socket, so
the second connect(2) succeeds at the OS level but the handshake
recvmsg(2) waits for a response that never arrives.

All subsequent API requests queue behind the stuck VMM event loop
and also hang (vm.info, vmm.ping, vm.remove-device). The VM itself
keeps running on vcpu threads, making the symptom confusing: the
guest looks healthy, only the API is unreachable.

This is easy to hit from management software that uses an idempotent
reconcile / ensure pattern for user devices.

Reject the call up-front when another user_device already has the
same socket path, returning an HTTP 500 with a descriptive
UserDeviceSocketInUse error in milliseconds instead of hanging.

Signed-off-by: Max Makarov <maxpain@linux.com>
2026-04-16 22:04:38 +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
Anatol Belski
1ab877882d performance-metrics: Add QCOW2 batch write micro benchmark
Add micro_bench_qcow_batch_write which builds a batch of num_ops
write requests and submits them all at once through
submit_batch_requests. Writes in QcowAsync are synchronous (COW
path), so this measures whether batching reduces per-request
overhead compared to individual write_vectored calls.

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2026-04-16 17:27:38 +00:00
Anatol Belski
8052c5a66b performance-metrics: Add QCOW2 async L2 cache miss micro benchmark
Add micro_bench_qcow_async_l2_cache_miss which reads one cluster
from each of num_ops distinct L2 tables through the QcowAsync
io_uring path, forcing L2 cache eviction on nearly every read.

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2026-04-16 17:27:38 +00:00
Anatol Belski
3804968eef performance-metrics: Add sparse async QCOW2 tempfile helper
Add sparse_qcow_async_tempfile which creates a sparse QCOW2 image
with one cluster per L2 table and opens it via QcowDiskAsync.
Mirrors the existing sparse_qcow_tempfile for io_uring benchmarks.

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2026-04-16 17:27:38 +00:00
Anatol Belski
1d5d13eb7b performance-metrics: Add QCOW2 async write micro benchmark
Add micro_bench_qcow_async_write which writes clusters into an
empty QCOW2 image through the QcowAsync io_uring path. Writes
in QcowAsync are synchronous due to COW metadata allocation, so
this measures the write path overhead through the async code path.

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2026-04-16 17:27:38 +00:00
Anatol Belski
1069505151 performance-metrics: Add empty async QCOW2 tempfile helper
Add empty_qcow_async_tempfile which creates an empty QCOW2 image
and opens it via QcowDiskAsync. Mirrors the existing
empty_qcow_tempfile for io_uring write benchmarks.

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2026-04-16 17:27:38 +00:00
Anatol Belski
fca6429e9b performance-metrics: Add QCOW2 async compressed read micro benchmark
Add micro_bench_qcow_async_compressed_read which reads from a
zlib compressed QCOW2 image through the QcowAsync io_uring path.
Compressed clusters take the sync fallback since they require
decompression.

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2026-04-16 17:27:38 +00:00
Anatol Belski
4bf3672fad performance-metrics: Add compressed async QCOW2 tempfile helper
Add compressed_qcow_async_tempfile which creates a zlib compressed
QCOW2 image via qemu-img and opens it via QcowDiskAsync. Mirrors
the existing compressed_qcow_tempfile for io_uring benchmarks.

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2026-04-16 17:27:38 +00:00
Anatol Belski
324f16861d performance-metrics: Add QCOW2 async backing file read micro benchmark
Add micro_bench_qcow_async_backing_read which reads clusters from
a QCOW2 overlay through the QcowAsync io_uring path. All reads
fall through to the backing file, exercising the sync fallback
path in QcowAsync.

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2026-04-16 17:27:38 +00:00
Anatol Belski
c8fee5953f performance-metrics: Add async QCOW2 overlay tempfile helper
Add qcow_async_overlay_tempfile which creates a QCOW2 overlay
backed by a RAW file and opens it via QcowDiskAsync. Mirrors
the existing qcow_overlay_tempfile for io_uring benchmarks.

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2026-04-16 17:27:38 +00:00
Anatol Belski
2041ba5a91 performance-metrics: Add QCOW2 async multicluster read micro benchmark
Add micro_bench_qcow_async_multi_cluster_read which reads 8
contiguous clusters (512 KiB) per request through the QcowAsync
io_uring path. With coalesced mappings this can hit the io_uring
fast path for a single Readv SQE.

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2026-04-16 17:27:38 +00:00
Anatol Belski
377c260196 performance-metrics: Add QCOW2 async random read micro benchmark
Add micro_bench_qcow_async_random_read which reads clusters in
random order through the QcowAsync io_uring path. This mirrors
the existing sync random read benchmark and measures io_uring
completion handling under random access patterns.

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2026-04-16 17:27:38 +00:00
Anatol Belski
e9d1ffd24f performance-metrics: Add QCOW2 batch read micro benchmark
Add micro_bench_qcow_batch_read which builds a batch of num_ops
read requests and submits them all at once through
submit_batch_requests. This exercises the io_uring batch
submission path added in qcow_async, where multiple SQEs are
packed into a single io_uring_enter call.

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2026-04-16 17:27:38 +00:00
Anatol Belski
f8dbec0abb performance-metrics: Add QCOW2 async read micro benchmark
Add micro_bench_qcow_async_read which reads clusters through the
QcowDiskAsync io_uring backend. Single allocated cluster reads go
through io_uring for true asynchronous completion, unlike the sync
benchmarks which use QcowDiskSync with blocking I/O.

Workloads: 128 and 256 clusters.
Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2026-04-16 17:27:38 +00:00
Anatol Belski
3cb116fcfc performance-metrics: Add async drain completions helper
Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2026-04-16 17:27:38 +00:00
Anatol Belski
faf6f7b635 performance-metrics: Add QCOW2 L2 cache cold miss micro benchmark
Add micro_bench_qcow_l2_cache_miss which reads one cluster from each
of num_ops distinct L2 tables in a sparsely allocated image.  Clusters
are spaced L2_ENTRIES_PER_TABLE apart so every read touches a different
L2 table, forcing eviction when num_ops exceeds the cache capacity.

Workloads: 128 and 256 L2 tables.
Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2026-04-16 17:27:38 +00:00
Anatol Belski
73d99c044c performance-metrics: Add sparse QCOW2 tempfile helper
Add sparse_qcow_tempfile() which creates a QCOW2 image with one
allocated cluster per L2 table, spread across num_l2_tables distinct
L2 tables.  Reading these clusters in sequence forces L2 cache misses
when the count exceeds the cache capacity.

Also add the L2_ENTRIES_PER_TABLE constant, 8192 for 64 KiB clusters.

To be used by the L2 cache cold miss benchmark.

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2026-04-16 17:27:38 +00:00
Anatol Belski
94f78edcf0 performance-metrics: Add QCOW2 multi-cluster read micro benchmark
Add micro_bench_qcow_multi_cluster_read which issues large reads
spanning 8 contiguous clusters (512 KiB) per read_vectored call.
This exercises the mapping coalesce path where multiple L2 entries
are merged into fewer host I/O operations.

Workloads: 128 and 256 total clusters (16 and 32 reads).
Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2026-04-16 17:27:38 +00:00
Anatol Belski
7dd1978fce performance-metrics: Add QCOW2 compressed read micro benchmark
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>
2026-04-16 17:27:38 +00:00
Anatol Belski
aca64ced8f performance-metrics: Add compressed QCOW2 tempfile helper
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>
2026-04-16 17:27:38 +00:00
Anatol Belski
b2430d701b performance-metrics: Add QCOW2 copy-on-write write micro benchmark
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>
2026-04-16 17:27:38 +00:00