Add an `iommufd` flag to existing VFIO integration tests. When false,
tests use the legacy vfio container/group backend (existing behavior).
When true, tests use vfio cdev with iommufd and vfio_p2p_dma=off.
vfio_p2p_dma=off is required because the VFIO test runner uses a stock
Ubuntu 24.04 kernel (v6.8) which does not support mapping device MMIO
pages (VM_PFNMAP) through iommufd, causing IOMMU_IOAS_MAP to fail with
-EFAULT on MMIO BAR regions.
Signed-off-by: Bo Chen <bchen@crusoe.ai>
Add a user-configurable option to control whether VFIO device MMIO BAR
regions are DMA-mapped into the host IOMMU address space.
This mapping is required for peer-to-peer DMA between devices (e.g.
NVLink, RDMA NIC accessing GPU VRAM). However, iommufd on upstream
kernels does not support mapping device MMIO pages (VM_PFNMAP), causing
IOMMU_IOAS_MAP to fail with -EFAULT. Kernels with the NVIDIA PFNMAP
workaround or future kernels with DMABUF-based mapping
(IOMMU_IOAS_MAP_FILE) handle this correctly.
The option defaults to `on` to preserve existing behavior. Users on
vanilla kernels using iommufd should set `vfio_p2p_dma=off` to skip
MMIO BAR DMA mapping.
A validation check ensures that `x_nv_gpudirect_clique` (which depends
on P2P DMA) cannot be used when `vfio_p2p_dma=off`.
Signed-off-by: Bo Chen <bchen@crusoe.ai>
When `--platform iommufd=on` is set, use the vfio cdev interface backed
by iommufd instead of the legacy vfio container/group interface for
device passthrough.
The cdev path opens '/dev/iommu' via IommuFd, allocates an IOAS, and
binds VFIO devices through VfioIommufd. The legacy container/group path
remains the default and is used when iommufd is not enabled.
Add iommufd-ioctls as a workspace dependency and enable the "vfio_cdev"
feature on vfio-ioctls for KVM builds.
Fixes: #6892
Signed-off-by: Bo Chen <bchen@crusoe.ai>
This option allows user to configure VFIO device pass-through with
iommufd (e.g. vfio cdev mode) or not (e.g. vfio legacy mode).
Signed-off-by: Bo Chen <bchen@crusoe.ai>
The `--platform` help string was hardcoded and did not reflect which
optional features (tdx, sev_snp) were actually enabled in. Build the
syntax string dynamically as `PlatformConfig::syntax()`, conditionally
appending feature-gated options so the CLI help stays accurate.
Signed-off-by: Bo Chen <bchen@crusoe.ai>
A 4M uefi_region is allocated unconditionally. When directly booting a
kernel, it goes unused. Avoid the allocation in this case by moving the
call to add_uefi_flash() to load_firmware().
Also extended add_uefi_flash() to riscv64 since it shares the
load_firmware() path. It looked like up to this point a firmware boot on
riscv64 would panic with an uninitialized uefi_flash.
Signed-off-by: JP Kobryn <inwardvessel@gmail.com>
The aarch64 dbus, fw_cfg & ivshmem tests don't build the mshv feature
causing them to fail when run on MSHV. Fix by building the mshv feature
too just like the x86 version of the script does.
Signed-off-by: Anirudh Rayabharam <anrayabh@microsoft.com>
It is desirable to be able to track the progress of memory hotplug.
Update the memory_actual_size field to query the current plugged size
from virtio-mem to enable this.
Signed-off-by: Jared White <git@jaredwhite.dev>
After a vDPA device reset, activate_vdpa() read avail_idx from guest
memory to pass as the vring base via VHOST_SET_VRING_BASE. However,
the guest memory still contained the stale avail_idx from the previous
session. For a 256-entry ring, this meant base=256, causing the
hardware to believe the entire RX ring was consumed with no available
buffers — RX silently stopped while TX continued to work.
QEMU handles this correctly by tracking last_avail_idx internally
(reset to 0 in virtio_reset()) and passing that value, rather than
reading from guest memory.
Fix by always passing base=0 to set_vring_base(). After a device
reset, both the guest driver and the vhost backend restart their rings
from index 0. For live migration, the correct base should come from
VHOST_GET_VRING_BASE (saved before the migration), not guest memory.
Tested with mlx5_vdpa (ConnectX-6 Dx) + Windows Server 2025 (netkvm).
Before: RX=0 after 3rd driver activation. After: full connectivity.
Signed-off-by: Max Makarov <maxpain@linux.com>
KVM_GET_MSR_INDEX_LIST does not consistently include all
guest-programmable MTRR MSRs.
During save/restore while booting, the VMM initially sets only
MSR_MTRRdefType, then guest firmware or other early boot code can
program additional MTRR state before the snapshot is taken. If those
MSRs are missing from the vCPU MSR buffer, snapshot omits part of the
guest's MTRR configuration and restore resumes with an incomplete
MTRR map.
Add the guest-programmable MTRR MSRs to the KVM MSR index list used
to build the vCPU MSR buffer so the existing snapshot/restore path
preserves the guest's MTRR state.
On-behalf-of: SAP leander.kohler@sap.com
Signed-off-by: Leander Kohler <leander.kohler@cyberus-technology.de>
Some guests update the MSI-X capability through a 32-bit write at
offset 0 instead of a 16-bit write at offset 2. Update the cached
Message Control state for that path as well so MSI-X enablement stays
in sync with the guest configuration.
Add a short comment documenting why the dword write path also updates
the cached MSI-X Message Control state.
This is important for passthrough GPUs, where MSI-X interrupts are used
during NVIDIA Fabric Manager registration. Without updating the cached
state on the dword write path, interrupt delivery can remain stale and
GPU initialization or fabric registration can fail.
Signed-off-by: Damian Barabonkov <dbctl@pm.me>
This gate behaves like a barrier, but it can be opened, meaning that
threads can be released before all threads arrived at the gate. This
lets us release waiting threads in case of an error, which will be
important for the sender side of a live migration with multiple
TCP connections.
On-behalf-of: SAP sebastian.eydam@sap.com
Signed-off-by: Sebastian Eydam <sebastian.eydam@cyberus-technology.de>
For sending memory over multiple connections, we need a way to split up
the work. With these changes, we can chop a memory table into same-sized
chunks for transmit
On-behalf-of: SAP sebastian.eydam@sap.com
Signed-off-by: Sebastian Eydam <sebastian.eydam@cyberus-technology.de>
Adds the functionality to accept multiple connections on the receiver
side of a live migration. A thread listens for incoming connections and
creates a worker for each new connection.
On-behalf-of: SAP sebastian.eydam@sap.com
Signed-off-by: Sebastian Eydam <sebastian.eydam@cyberus-technology.de>
With this, the receiver side of a migration can wait for incoming
connections, while also being able to abort the accept when the
migration is done.
On-behalf-of: SAP sebastian.eydam@sap.com
Signed-off-by: Sebastian Eydam <sebastian.eydam@cyberus-technology.de>
That way we avoid having to grab a lock when receiving a chunk of memory
over the migration socket. This is a necessary prerequisite for having
multiple memory receiving threads.
On-behalf-of: SAP sebastian.eydam@sap.com
Signed-off-by: Sebastian Eydam <sebastian.eydam@cyberus-technology.de>
The memory manager is guarded by a mutex, thus parallel accesses to it
and its members are not possible. But we have to execute this function
in parallel when we introduce multiple TCP connections. Otherwise, the
workers who receive the data and write it into guest memory will block
on each other, and thus slow down the migration.
Also rename the function to receive_memory_ranges for better naming
consistency.
On-behalf-of: SAP sebastian.eydam@sap.com
Signed-off-by: Sebastian Eydam <sebastian.eydam@cyberus-technology.de>
When doing a local migration using a UNIX socket, we removed the UNIX
socket file after accepting the connection. The VMM does not own this
socket file, which makes this an unsafe operation. Thus, we stop doing
that.
On-behalf-of: SAP sebastian.eydam@sap.com
Signed-off-by: Sebastian Eydam <sebastian.eydam@cyberus-technology.de>
Remove the local remote_command() function from
performance_tests.rs. The identical function is now
available from test_infra via the existing glob import.
Signed-off-by: Muminul Islam <muislam@microsoft.com>
Move remote_command() and remote_command_w_output() from
tests/common/utils.rs into test_infra/src/lib.rs to allow
reuse across crates.
The cloud-hypervisor integration tests already use
'use test_infra::*', so the functions are available
without any caller changes.
Signed-off-by: Muminul Islam <muislam@microsoft.com>
Remove the local x86_64 FOCAL_IMAGE_NAME constant from
performance_tests.rs. The identical public constant from
test_infra is already available via wildcard import.
The aarch64 definition is kept as it differs from test_infra:
performance-metrics uses a specific image with the
'-update-tool' suffix.
Signed-off-by: Muminul Islam <muislam@microsoft.com>
Remove the local DIRECT_KERNEL_BOOT_CMDLINE constant from
performance_tests.rs. The identical public constant from
test_infra is already available via wildcard import.
Signed-off-by: Muminul Islam <muislam@microsoft.com>
Remove the local direct_kernel_boot_path() function and unused
PathBuf import from performance_tests.rs. The identical public
function from test_infra is already available via wildcard
import.
Signed-off-by: Muminul Islam <muislam@microsoft.com>
Virtio v1.2 says that if CONFIG_WCE is negotiated
but FLUSH is not, the device must initialize writeback to 0.
It also says that if CONFIG_WCE was not negotiated but FLUSH
was, the driver should assume presence of a writeback cache.
Introduce a pure is_writeback_enabled helper and a
set_writeback_mode helper. This makes the two call flows
explicit:
* write_config resolves the guest requested mode against the
negotiated features before storing it back
* activate starts from the default writeback preference and then
resolves it against the negotiated features
* reset restores the initial writeback state
This keeps the config space value and the runtime writeback flag
in sync and makes the spec driven fallback easier to follow.
Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
Refactor PciDevice::allocate_bars trait and all implementations
to take &mut SystemAllocator instead of &Arc<Mutex<SystemAllocator>>,
removing double indirection.
The caller in device_manager.rs now acquires the lock before
calling allocate_bars.
Signed-off-by: Chinmoy <daschinmoyy21@gmail.com>