diff --git a/src/runtime-rs/crates/hypervisor/src/dragonball/inner_device.rs b/src/runtime-rs/crates/hypervisor/src/dragonball/inner_device.rs index 6f7573d557..48df4247c8 100644 --- a/src/runtime-rs/crates/hypervisor/src/dragonball/inner_device.rs +++ b/src/runtime-rs/crates/hypervisor/src/dragonball/inner_device.rs @@ -13,13 +13,16 @@ use dragonball::api::v1::{ BlockDeviceConfigInfo, FsDeviceConfigInfo, FsMountConfigInfo, NetworkInterfaceConfig, VsockDeviceConfigInfo, }; -use dragonball::device_manager::blk_dev_mgr::BlockDeviceType; +use dragonball::device_manager::{ + blk_dev_mgr::BlockDeviceType, + vfio_dev_mgr::{HostDeviceConfig, VfioPciDeviceConfig}, +}; use super::{build_dragonball_network_config, DragonballInner}; use crate::VhostUserConfig; use crate::{ device::DeviceType, HybridVsockConfig, NetworkConfig, ShareFsConfig, ShareFsMountConfig, - ShareFsMountOperation, ShareFsMountType, VfioBusMode, VfioDevice, VmmState, JAILER_ROOT, + ShareFsMountOperation, ShareFsMountType, VfioDevice, VmmState, JAILER_ROOT, }; const MB_TO_B: u32 = 1024 * 1024; @@ -134,47 +137,52 @@ impl DragonballInner { 0 }; - let guest_dev_id = if let Some(pci_path) = primary_device.guest_pci_path { - // safe here, dragonball's pci device directly connects to root bus. - // usually, it has been assigned in vfio device manager. - pci_path.get_device_slot().unwrap().0 - } else { - 0 - }; + // It's safe to unwrap the guest_pci_path and get device slot, + // As it has been assigned in vfio device manager. + let pci_path = primary_device.guest_pci_path.unwrap(); + let guest_dev_id = pci_path.get_device_slot().unwrap().0; - let bus_mode = VfioBusMode::to_string(vfio_device.bus_mode); - - info!(sl!(), "Mock for dragonball insert host device."); info!( sl!(), - " Mock for dragonball insert host device. + "insert host device. host device id: {:?}, bus_slot_func: {:?}, - bus mod: {:?}, guest device id: {:?}, vendor/device id: {:?}", primary_device.hostdev_id, primary_device.bus_slot_func, - bus_mode, guest_dev_id, vendor_device_id, ); - // FIXME: - // interface implementation to be done when dragonball supports - // self.vmm_instance.insert_host_device(host_cfg)?; + let vfio_dev_config = VfioPciDeviceConfig { + bus_slot_func: primary_device.bus_slot_func, + vendor_device_id, + guest_dev_id: Some(guest_dev_id), + ..Default::default() + }; + let host_dev_config = HostDeviceConfig { + hostdev_id: primary_device.hostdev_id, + sysfs_path: primary_device.sysfs_path.clone(), + dev_config: vfio_dev_config, + }; + + self.vmm_instance + .insert_host_device(host_dev_config) + .context("insert host device failed")?; Ok(()) } fn remove_vfio_device(&mut self, hostdev_id: String) -> Result<()> { - info!( - sl!(), - "Mock for dragonball remove host_device with hostdev id {:?}", hostdev_id - ); - // FIXME: - // interface implementation to be done when dragonball supports - // self.vmm_instance.remove_host_device(hostdev_id)?; + info!(sl!(), "remove host_device with hostdev id {:?}", hostdev_id); + + self.vmm_instance + .prepare_remove_host_device(&hostdev_id) + .context("prepare to remove host device failed")?; + self.vmm_instance + .remove_host_device(&hostdev_id) + .context("remove host device failed")?; Ok(()) } diff --git a/src/runtime-rs/crates/hypervisor/src/dragonball/vmm_instance.rs b/src/runtime-rs/crates/hypervisor/src/dragonball/vmm_instance.rs index 899f4f258c..3973960d28 100644 --- a/src/runtime-rs/crates/hypervisor/src/dragonball/vmm_instance.rs +++ b/src/runtime-rs/crates/hypervisor/src/dragonball/vmm_instance.rs @@ -19,7 +19,10 @@ use dragonball::{ InstanceInfo, InstanceState, NetworkInterfaceConfig, VcpuResizeInfo, VmmAction, VmmActionError, VmmData, VmmRequest, VmmResponse, VmmService, VsockDeviceConfigInfo, }, - device_manager::{balloon_dev_mgr::BalloonDeviceConfigInfo, mem_dev_mgr::MemDeviceConfigInfo}, + device_manager::{ + balloon_dev_mgr::BalloonDeviceConfigInfo, mem_dev_mgr::MemDeviceConfigInfo, + vfio_dev_mgr::HostDeviceConfig, + }, vm::VmConfigInfo, Vmm, }; @@ -194,6 +197,30 @@ impl VmmInstance { Err(anyhow!("Failed to get machine info")) } + pub fn insert_host_device(&self, device_cfg: HostDeviceConfig) -> Result<()> { + self.handle_request_with_retry(Request::Sync(VmmAction::InsertHostDevice( + device_cfg.clone(), + ))) + .with_context(|| format!("Failed to insert host device {:?}", device_cfg))?; + Ok(()) + } + + pub fn prepare_remove_host_device(&self, id: &str) -> Result<()> { + info!(sl!(), "prepare to remove host device {}", id); + self.handle_request(Request::Sync(VmmAction::PrepareRemoveHostDevice( + id.to_string(), + ))) + .with_context(|| format!("Prepare to remove host device {:?} failed", id))?; + Ok(()) + } + + pub fn remove_host_device(&self, id: &str) -> Result<()> { + info!(sl!(), "remove host device {}", id); + self.handle_request(Request::Sync(VmmAction::RemoveHostDevice(id.to_string()))) + .with_context(|| format!("Failed to remove host device {:?}", id))?; + Ok(()) + } + pub fn insert_block_device(&self, device_cfg: BlockDeviceConfigInfo) -> Result<()> { self.handle_request_with_retry(Request::Sync(VmmAction::InsertBlockDevice( device_cfg.clone(),