pci, vmm: Cleanup the naming and references to VFIO container

Following the `VfioContainer` to `VfioOps` trait switch, update the
remaining field names, method names, comments, and log messages to use
`vfio_ops` and "host IOMMU address space" consistently.

No fucntional changes.

Signed-off-by: Bo Chen <bchen@crusoe.ai>
This commit is contained in:
Bo Chen
2026-03-26 22:38:01 +00:00
parent 7360bfe33a
commit 1bc49758a0
2 changed files with 64 additions and 61 deletions

View File

@@ -1466,7 +1466,7 @@ pub struct VfioPciDevice {
id: String,
vm: Arc<dyn hypervisor::Vm>,
device: Arc<VfioDevice>,
container: Arc<dyn VfioOps>,
vfio_ops: Arc<dyn VfioOps>,
common: VfioCommon,
iommu_attached: bool,
memory_slot_allocator: MemorySlotAllocator,
@@ -1481,7 +1481,7 @@ impl VfioPciDevice {
id: String,
vm: Arc<dyn hypervisor::Vm>,
device: VfioDevice,
container: Arc<dyn VfioOps>,
vfio_ops: Arc<dyn VfioOps>,
msi_interrupt_manager: Arc<dyn InterruptManager<GroupConfig = MsiIrqGroupConfig>>,
legacy_interrupt_group: Option<Arc<dyn InterruptSourceGroup>>,
iommu_attached: bool,
@@ -1510,7 +1510,7 @@ impl VfioPciDevice {
id,
vm,
device,
container,
vfio_ops,
common,
iommu_attached,
memory_slot_allocator,
@@ -1705,7 +1705,7 @@ impl VfioPciDevice {
// user_memory_region.mapping.len() bytes of
// valid memory that will only be unmapped with munmap().
unsafe {
self.container.vfio_dma_map(
self.vfio_ops.vfio_dma_map(
user_memory_region.start,
user_memory_region.mapping.len(),
user_memory_region.mapping.addr(),
@@ -1726,15 +1726,15 @@ impl VfioPciDevice {
for user_memory_region in region.user_memory_regions.drain(..) {
let len = user_memory_region.mapping.len();
let host_addr = user_memory_region.mapping.addr();
// Unmap from vfio container
// Unmap MMIO region from the host IOMMU address space via VfioOps
if !self.iommu_attached
&& let Err(e) = self
.container
.vfio_ops
.vfio_dma_unmap(user_memory_region.start, len)
.map_err(|e| VfioPciError::DmaUnmap(e, self.device_path.clone(), self.bdf))
{
error!(
"Could not unmap mmio region from vfio container: \
"Could not unmap MMIO region from the host IOMMU address space: \
iova 0x{:x}, size 0x{:x}: {}, ",
user_memory_region.start, len, e
);
@@ -1884,17 +1884,17 @@ impl PciDevice for VfioPciDevice {
for user_memory_region in region.user_memory_regions.iter_mut() {
let len = user_memory_region.mapping.len();
let host_addr = user_memory_region.mapping.addr();
// Unmap the old MMIO region from vfio container
// Unmap the old MMIO region from the host IOMMU address space via VfioOps
if !self.iommu_attached
&& let Err(e) = self
.container
.vfio_ops
.vfio_dma_unmap(user_memory_region.start, len)
.map_err(|e| {
VfioPciError::DmaUnmap(e, self.device_path.clone(), self.bdf)
})
{
error!(
"Could not unmap mmio region from vfio container: \
"Could not unmap MMIO region from the host IOMMU address space: \
iova 0x{:x}, size 0x{:x}: {}, ",
user_memory_region.start, len, e
);
@@ -1938,7 +1938,7 @@ iova 0x{:x}, size 0x{:x}: {}, ",
}
.map_err(io::Error::other)?;
// Map the moved mmio region to vfio container
// Map the moved MMIO region into the host IOMMU address space via VfioOps
if !self.iommu_attached {
// vfio_dma_map is unsound and ought to be marked as unsafe
#[allow(unused_unsafe)]
@@ -1946,13 +1946,13 @@ iova 0x{:x}, size 0x{:x}: {}, ",
// host_addr points to len bytes of
// valid memory that will only be unmapped with munmap().
unsafe {
self.container
self.vfio_ops
.vfio_dma_map(user_memory_region.start, len, host_addr)
}
.map_err(|e| VfioPciError::DmaMap(e, self.device_path.clone(), self.bdf))
.map_err(|e| {
io::Error::other(format!(
"Could not map mmio region to vfio container: \
"Could not map MMIO region into the host IOMMU address space: \
iova 0x{:x}, size 0x{:x}: {}, ",
user_memory_region.start, len, e
))
@@ -1996,9 +1996,9 @@ impl Migratable for VfioPciDevice {}
/// This structure implements the ExternalDmaMapping trait. It is meant to
/// be used when the caller tries to provide a way to update the mappings
/// associated with a specific VFIO container.
/// associated with a specific VfioOps instance.
pub struct VfioDmaMapping<M: GuestAddressSpace> {
container: Arc<dyn VfioOps>,
vfio_ops: Arc<dyn VfioOps>,
memory: Arc<M>,
mmio_regions: Arc<Mutex<Vec<MmioRegion>>>,
}
@@ -2006,16 +2006,16 @@ pub struct VfioDmaMapping<M: GuestAddressSpace> {
impl<M: GuestAddressSpace> VfioDmaMapping<M> {
/// Create a DmaMapping object.
/// # Parameters
/// * `container`: VFIO container object.
/// * `vfio_ops`: VfioOps instance.
/// * `memory`: guest memory to mmap.
/// * `mmio_regions`: mmio_regions to mmap.
pub fn new(
container: Arc<dyn VfioOps>,
vfio_ops: Arc<dyn VfioOps>,
memory: Arc<M>,
mmio_regions: Arc<Mutex<Vec<MmioRegion>>>,
) -> Self {
VfioDmaMapping {
container,
vfio_ops,
memory,
mmio_regions,
}
@@ -2062,20 +2062,20 @@ impl<M: GuestAddressSpace + Sync + Send> ExternalDmaMapping for VfioDmaMapping<M
// SAFETY: find_user_address and GuestMemory::get_slice() guarantee that
// the returned pointer is valid for up to `usize_size` bytes.
// `usize_size` is always equal to `size` due to the above `try_into()` call.
unsafe { self.container.vfio_dma_map(iova, size as usize, user_addr) }.map_err(|e| {
unsafe { self.vfio_ops.vfio_dma_map(iova, size as usize, user_addr) }.map_err(|e| {
io::Error::other(format!(
"failed to map memory for VFIO container, \
"failed to map memory into the host IOMMU address space, \
iova 0x{iova:x}, gpa 0x{gpa:x}, size 0x{size:x}: {e:?}"
))
})
}
fn unmap(&self, iova: u64, size: u64) -> std::result::Result<(), io::Error> {
self.container
self.vfio_ops
.vfio_dma_unmap(iova, size as usize)
.map_err(|e| {
io::Error::other(format!(
"failed to unmap memory for VFIO container, \
"failed to unmap memory from the host IOMMU address space, \
iova 0x{iova:x}, size 0x{size:x}: {e:?}"
))
})

View File

@@ -1029,10 +1029,10 @@ pub struct DeviceManager {
// Passthrough device handle
passthrough_device: Option<VfioDeviceFd>,
// VFIO container
// Only one container can be created, therefore it is stored as part of the
// VFIO operation instance
// Only one can be created, therefore it is stored as part of the
// DeviceManager to be reused.
vfio_container: Option<Arc<dyn VfioOps>>,
vfio_ops: Option<Arc<dyn VfioOps>>,
// Paravirtualized IOMMU
iommu_device: Option<Arc<Mutex<virtio_devices::Iommu>>>,
@@ -1350,7 +1350,7 @@ impl DeviceManager {
msi_interrupt_manager,
legacy_interrupt_manager: None,
passthrough_device: None,
vfio_container: None,
vfio_ops: None,
iommu_device: None,
iommu_mapping: None,
iommu_attached_devices: None,
@@ -3798,7 +3798,7 @@ impl DeviceManager {
self.add_vfio_device(device_cfg)
}
fn create_vfio_container(&self) -> DeviceManagerResult<Arc<dyn VfioOps>> {
fn create_vfio_ops(&self) -> DeviceManagerResult<Arc<dyn VfioOps>> {
let passthrough_device = self
.passthrough_device
.as_ref()
@@ -3830,19 +3830,24 @@ impl DeviceManager {
let mut needs_dma_mapping = false;
// Here we create a new VFIO container for two reasons. Either this is
// the first VFIO device, meaning we need a new VFIO container, which
// will be shared with other VFIO devices. Or the new VFIO device is
// attached to a vIOMMU, meaning we must create a dedicated VFIO
// container. In the vIOMMU use case, we can't let all devices under
// the same VFIO container since we couldn't map/unmap memory for each
// device. That's simply because the map/unmap operations happen at the
// VFIO container level.
let vfio_container = if device_cfg.iommu {
let vfio_container = self.create_vfio_container()?;
// Here we create a new VfioOps for two reasons:
// 1) This is the first VFIO device, meaning we need a new VfioOps
// which will be shared with other VFIO devices.
// 2) The new VFIO device is attached to a vIOMMU, meaning we must
// create a dedicated VfioOps. In the vIOMMU use case, we can't
// let all devices share the same VfioOps since we couldn't
// map/unmap memory for each device independently. That's simply
// because the map/unmap operations happen at the VfioOps level.
//
// Note: this is a limitation of the legacy VFIO interface using
// container/group. The VFIO cdev and iommufd do not have such a
// limitation, and this will be revised once we have VFIO cdev and
// iommufd support.
let vfio_ops = if device_cfg.iommu {
let vfio_ops = self.create_vfio_ops()?;
let vfio_mapping = Arc::new(VfioDmaMapping::new(
Arc::clone(&vfio_container),
Arc::clone(&vfio_ops),
Arc::new(self.memory_manager.lock().unwrap().guest_memory()),
Arc::clone(&self.mmio_regions),
));
@@ -3856,22 +3861,20 @@ impl DeviceManager {
return Err(DeviceManagerError::MissingVirtualIommu);
}
vfio_container
} else if let Some(vfio_container) = &self.vfio_container {
Arc::clone(vfio_container)
vfio_ops
} else if let Some(vfio_ops) = &self.vfio_ops {
Arc::clone(vfio_ops)
} else {
let vfio_container = self.create_vfio_container()?;
let vfio_ops = self.create_vfio_ops()?;
needs_dma_mapping = true;
self.vfio_container = Some(Arc::clone(&vfio_container));
self.vfio_ops = Some(Arc::clone(&vfio_ops));
vfio_container
vfio_ops
};
let vfio_device = VfioDevice::new(
&device_cfg.path,
Arc::clone(&vfio_container) as Arc<dyn VfioOps>,
)
.map_err(DeviceManagerError::VfioCreate)?;
let vfio_device =
VfioDevice::new(&device_cfg.path, Arc::clone(&vfio_ops) as Arc<dyn VfioOps>)
.map_err(DeviceManagerError::VfioCreate)?;
if needs_dma_mapping {
// Register DMA mapping in IOMMU.
@@ -3885,7 +3888,7 @@ impl DeviceManager {
// to len bytes of valid memory starting at as_ptr()
// that will only be freed with munmap().
unsafe {
vfio_container.vfio_dma_map(
vfio_ops.vfio_dma_map(
region.start_addr().raw_value(),
region.len() as usize,
region.as_ptr(),
@@ -3896,7 +3899,7 @@ impl DeviceManager {
}
let vfio_mapping = Arc::new(VfioDmaMapping::new(
Arc::clone(&vfio_container),
Arc::clone(&vfio_ops),
Arc::new(self.memory_manager.lock().unwrap().guest_memory()),
Arc::clone(&self.mmio_regions),
));
@@ -3934,7 +3937,7 @@ impl DeviceManager {
vfio_name.clone(),
self.address_manager.vm.clone(),
vfio_device,
vfio_container,
vfio_ops,
self.msi_interrupt_manager.clone(),
legacy_interrupt_group,
device_cfg.iommu,
@@ -4513,14 +4516,14 @@ impl DeviceManager {
}
// Take care of updating the memory for VFIO PCI devices.
if let Some(vfio_container) = &self.vfio_container {
if let Some(vfio_ops) = &self.vfio_ops {
// vfio_dma_map is unsound and ought to be marked as unsafe
#[allow(unused_unsafe)]
// SAFETY: GuestMemoryMmap guarantees that region points
// to len bytes of valid memory starting at as_ptr()
// that will only be freed with munmap().
unsafe {
vfio_container.vfio_dma_map(
vfio_ops.vfio_dma_map(
new_region.start_addr().raw_value(),
new_region.len() as usize,
new_region.as_ptr(),
@@ -4764,7 +4767,7 @@ impl DeviceManager {
let (pci_device, bus_device, virtio_device, remove_dma_handler) = match pci_device_handle {
// VirtioMemMappingSource::Container cleanup is handled by
// cleanup_vfio_container when the last VFIO device is removed.
// cleanup_vfio_ops when the last VFIO device is removed.
PciDeviceHandle::Vfio(vfio_pci_device) => {
// Remove this device's MMIO regions from the DeviceManager's
// mmio_regions list. We match on UserMemoryRegion slot numbers
@@ -5154,11 +5157,11 @@ impl DeviceManager {
&self.acpi_platform_addresses
}
fn cleanup_vfio_container(&mut self) {
// Drop the 'vfio container' instance when "Self" is the only reference
if let Some(1) = self.vfio_container.as_ref().map(Arc::strong_count) {
debug!("Drop 'vfio container' given no active 'vfio devices'.");
self.vfio_container = None;
fn cleanup_vfio_ops(&mut self) {
// Drop the VfioOps instance when "Self" is the only reference
if let Some(1) = self.vfio_ops.as_ref().map(Arc::strong_count) {
debug!("Drop VfioOps given no active VFIO devices.");
self.vfio_ops = None;
}
}
}
@@ -5644,7 +5647,7 @@ impl BusDevice for DeviceManager {
if let Err(e) = self.eject_device(self.selected_segment as u16, slot_id as u8) {
error!("Failed ejecting device {slot_id}: {e:?}");
}
self.cleanup_vfio_container();
self.cleanup_vfio_ops();
slot_bitmap &= !(1 << slot_id);
}
}