diff --git a/src/runtime-rs/crates/hypervisor/src/device/driver/vfio.rs b/src/runtime-rs/crates/hypervisor/src/device/driver/vfio.rs index 4c1f89e450..292d53b206 100644 --- a/src/runtime-rs/crates/hypervisor/src/device/driver/vfio.rs +++ b/src/runtime-rs/crates/hypervisor/src/device/driver/vfio.rs @@ -5,28 +5,24 @@ // use std::{ - collections::HashMap, fs, path::{Path, PathBuf}, process::Command, - sync::{ - atomic::{AtomicU8, Ordering}, - Arc, RwLock, - }, }; use anyhow::{anyhow, Context, Result}; use async_trait::async_trait; -use lazy_static::lazy_static; use path_clean::PathClean; use kata_sys_util::fs::get_base_name; -use crate::device::{ - hypervisor, - pci_path::{PciPath, PciSlot}, - topology::{do_add_pcie_endpoint, PCIeTopology}, - Device, DeviceType, PCIeDevice, +use crate::{ + device::{ + pci_path::PciPath, + topology::{do_add_pcie_endpoint, PCIeTopology}, + Device, DeviceType, PCIeDevice, + }, + register_pcie_device, unregister_pcie_device, update_pcie_device, Hypervisor as hypervisor, }; pub const SYS_BUS_PCI_DRIVER_PROBE: &str = "/sys/bus/pci/drivers_probe"; @@ -44,35 +40,6 @@ const INTEL_IOMMU_PREFIX: &str = "dmar"; const AMD_IOMMU_PREFIX: &str = "ivhd"; const ARM_IOMMU_PREFIX: &str = "smmu"; -lazy_static! { - static ref GUEST_DEVICE_ID: Arc = Arc::new(AtomicU8::new(0_u8)); - static ref HOST_GUEST_MAP: Arc>> = - Arc::new(RwLock::new(HashMap::new())); -} - -// map host/guest bdf and the mapping saved into `HOST_GUEST_MAP`, -// and return PciPath. -pub fn generate_guest_pci_path(bdf: String) -> Result { - let hg_map = HOST_GUEST_MAP.clone(); - let current_id = GUEST_DEVICE_ID.clone(); - - current_id.fetch_add(1, Ordering::SeqCst); - let slot = current_id.load(Ordering::SeqCst); - - // In some Hypervisors, dragonball, cloud-hypervisor or firecracker, - // the device is directly connected to the bus without intermediary bus. - // FIXME: Qemu's pci path needs to be implemented; - let host_bdf = normalize_device_bdf(bdf.as_str()); - let guest_bdf = format!("0000:00:{:02x}.0", slot); - - // safe, just do unwrap as `HOST_GUEST_MAP` is always valid. - hg_map.write().unwrap().insert(host_bdf, guest_bdf); - - Ok(PciPath { - slots: vec![PciSlot::new(slot)], - }) -} - pub fn do_check_iommu_on() -> Result { let element = std::fs::read_dir(SYS_CLASS_IOMMU)? .filter_map(|e| e.ok()) @@ -479,9 +446,11 @@ impl VfioDevice { impl Device for VfioDevice { async fn attach( &mut self, - _pcie_topo: &mut Option<&mut PCIeTopology>, + pcie_topo: &mut Option<&mut PCIeTopology>, h: &dyn hypervisor, ) -> Result<()> { + register_pcie_device!(self, pcie_topo)?; + if self .increase_attach_count() .await @@ -499,31 +468,13 @@ impl Device for VfioDevice { self.devices = vfio.devices; } - if self.bus_mode == VfioBusMode::PCI { - for hostdev in self.devices.iter_mut() { - if hostdev.guest_pci_path.is_none() { - // guest_pci_path may be empty for certain hypervisors such as - // dragonball - hostdev.guest_pci_path = Some( - generate_guest_pci_path(hostdev.bus_slot_func.clone()) - .map_err(|e| anyhow!("generate pci path failed: {:?}", e))?, - ); - } - - // Safe to call unwrap here because of previous assignment. - let pci_path = hostdev.guest_pci_path.clone().unwrap(); - self.device_options.push(format!( - "0000:{}={}", - hostdev.bus_slot_func.clone(), - pci_path.to_string() - )); - } - } + update_pcie_device!(self, pcie_topo)?; Ok(()) } Err(e) => { self.decrease_attach_count().await?; + unregister_pcie_device!(self, pcie_topo)?; return Err(e); } }