mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2026-08-05 02:19:16 +00:00
pci: vfio: Probe migration v2 capabilities
Probe VFIO_DEVICE_FEATURE_MIGRATION during VfioCommon::new() and store the result in a new migration_flags field so later migration phases can gate state machine transitions. The probe runs on every instantiation, including snapshot restore, because migration capability is a property of the host kernel and its variant driver rather than of any saved VM state. migration_flags() is added to the internal Vfio trait with a default implementation that returns Ok(None), meaning not migratable. VfioDeviceWrapper overrides it to issue the kernel ioctl, while vfio-user devices keep the default and are always treated as non migratable. Allow the VFIO_DEVICE_FEATURE ioctl in the VMM seccomp filter. Signed-off-by: Saravanan D <saravanand@crusoe.ai>
This commit is contained in:
@@ -15,7 +15,7 @@ use anyhow::anyhow;
|
||||
use byteorder::{ByteOrder, LittleEndian};
|
||||
use hypervisor::HypervisorVmError;
|
||||
use libc::{_SC_PAGESIZE, sysconf};
|
||||
use log::{error, info};
|
||||
use log::{debug, error, info};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use thiserror::Error;
|
||||
use vfio_bindings::bindings::vfio::*;
|
||||
@@ -437,6 +437,10 @@ pub(crate) trait Vfio: Send + Sync {
|
||||
fn unmask_irq(&self, _irq_index: u32) -> Result<(), VfioError> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn migration_flags(&self) -> Result<Option<u64>, VfioError> {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
||||
struct VfioDeviceWrapper {
|
||||
@@ -479,6 +483,12 @@ impl Vfio for VfioDeviceWrapper {
|
||||
.unmask_irq(irq_index)
|
||||
.map_err(VfioError::KernelVfio)
|
||||
}
|
||||
|
||||
fn migration_flags(&self) -> Result<Option<u64>, VfioError> {
|
||||
self.device
|
||||
.query_migration_support()
|
||||
.map_err(VfioError::KernelVfio)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
@@ -503,6 +513,8 @@ pub(crate) struct VfioCommon {
|
||||
pub(crate) patches: HashMap<usize, ConfigPatch>,
|
||||
x_nv_gpudirect_clique: Option<u8>,
|
||||
x_exclude_mmap_bars: Vec<u8>,
|
||||
#[allow(dead_code)]
|
||||
pub(crate) migration_flags: Option<u64>,
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
@@ -542,6 +554,27 @@ impl VfioCommon {
|
||||
pci_configuration_state,
|
||||
);
|
||||
|
||||
let migration_flags = match vfio_wrapper.migration_flags() {
|
||||
Ok(Some(flags)) => {
|
||||
info!(
|
||||
"VFIO device {bdf} supports migration v2 (flags=0x{flags:x}, \
|
||||
STOP_COPY={}, P2P={}, PRE_COPY={})",
|
||||
flags & VFIO_MIGRATION_STOP_COPY as u64 != 0,
|
||||
flags & VFIO_MIGRATION_P2P as u64 != 0,
|
||||
flags & VFIO_MIGRATION_PRE_COPY as u64 != 0,
|
||||
);
|
||||
Some(flags)
|
||||
}
|
||||
Ok(None) => {
|
||||
debug!("VFIO device {bdf} does not support migration v2");
|
||||
None
|
||||
}
|
||||
Err(e) => {
|
||||
debug!("VFIO device {bdf} migration probe failed, treating as non-migratable: {e}");
|
||||
None
|
||||
}
|
||||
};
|
||||
|
||||
let mut vfio_common = VfioCommon {
|
||||
mmio_regions: Vec::new(),
|
||||
configuration,
|
||||
@@ -556,6 +589,7 @@ impl VfioCommon {
|
||||
patches: HashMap::new(),
|
||||
x_nv_gpudirect_clique: config.x_nv_gpudirect_clique,
|
||||
x_exclude_mmap_bars: config.x_exclude_mmap_bars,
|
||||
migration_flags,
|
||||
};
|
||||
|
||||
let state: Option<VfioCommonState> = snapshot
|
||||
|
||||
@@ -86,6 +86,7 @@ const VFIO_DEVICE_RESET: u64 = 0x3b6f;
|
||||
const VFIO_IOMMU_MAP_DMA: u64 = 0x3b71;
|
||||
const VFIO_IOMMU_UNMAP_DMA: u64 = 0x3b72;
|
||||
const VFIO_DEVICE_IOEVENTFD: u64 = 0x3b74;
|
||||
const VFIO_DEVICE_FEATURE: u64 = 0x3b75;
|
||||
|
||||
// See include/uapi/linux/kvm.h in the kernel code.
|
||||
#[cfg(feature = "kvm")]
|
||||
@@ -381,6 +382,7 @@ fn create_vmm_ioctl_seccomp_rule_common(
|
||||
and![Cond::new(1, ArgLen::Dword, Eq, VFIO_IOMMU_MAP_DMA)?],
|
||||
and![Cond::new(1, ArgLen::Dword, Eq, VFIO_IOMMU_UNMAP_DMA)?],
|
||||
and![Cond::new(1, ArgLen::Dword, Eq, VFIO_DEVICE_IOEVENTFD)?],
|
||||
and![Cond::new(1, ArgLen::Dword, Eq, VFIO_DEVICE_FEATURE)?],
|
||||
and![Cond::new(1, ArgLen::Dword, Eq, VHOST_GET_FEATURES())?],
|
||||
and![Cond::new(1, ArgLen::Dword, Eq, VHOST_SET_FEATURES())?],
|
||||
and![Cond::new(1, ArgLen::Dword, Eq, VHOST_SET_OWNER())?],
|
||||
|
||||
Reference in New Issue
Block a user