diff --git a/src/dragonball/src/api/v1/vmm_action.rs b/src/dragonball/src/api/v1/vmm_action.rs index 586b998cb..e687bc1df 100644 --- a/src/dragonball/src/api/v1/vmm_action.rs +++ b/src/dragonball/src/api/v1/vmm_action.rs @@ -281,6 +281,8 @@ pub enum VmmData { MachineConfiguration(Box), /// Prometheus Metrics represented by String. HypervisorMetrics(String), + /// Return vfio device's slot number in guest. + VfioDeviceData(Option), /// Sync Hotplug SyncHotplug((Sender>, Receiver>)), } @@ -398,7 +400,9 @@ impl VmmService { self.add_balloon_device(vmm, event_mgr, balloon_cfg) } #[cfg(feature = "host-device")] - VmmAction::InsertHostDevice(hostdev_cfg) => self.add_vfio_device(vmm, hostdev_cfg), + VmmAction::InsertHostDevice(mut hostdev_cfg) => { + self.add_vfio_device(vmm, &mut hostdev_cfg) + } #[cfg(feature = "host-device")] VmmAction::PrepareRemoveHostDevice(hostdev_id) => { self.prepare_remove_vfio_device(vmm, &hostdev_id) @@ -850,7 +854,7 @@ impl VmmService { } #[cfg(feature = "host-device")] - fn add_vfio_device(&self, vmm: &mut Vmm, config: HostDeviceConfig) -> VmmRequestResult { + fn add_vfio_device(&self, vmm: &mut Vmm, config: &mut HostDeviceConfig) -> VmmRequestResult { let vm = vmm.get_vm_mut().ok_or(VmmActionError::HostDeviceConfig( VfioDeviceError::InvalidVMID, ))?; @@ -873,7 +877,8 @@ impl VmmService { .unwrap() .insert_device(&mut ctx, config) .map_err(VmmActionError::HostDeviceConfig)?; - Ok(VmmData::Empty) + + Ok(VmmData::VfioDeviceData(config.dev_config.guest_dev_id)) } // using upcall to unplug the pci device in the guest diff --git a/src/dragonball/src/device_manager/mod.rs b/src/dragonball/src/device_manager/mod.rs index 169e8cb14..c8ebeb3b2 100644 --- a/src/dragonball/src/device_manager/mod.rs +++ b/src/dragonball/src/device_manager/mod.rs @@ -553,7 +553,7 @@ impl DeviceOpContext { &self, dev: &Arc, callback: Option>, - ) -> Result<()> { + ) -> Result { if !self.is_hotplug || !self.pci_hotplug_enabled { return Err(DeviceMgrError::InvalidOperation); } @@ -561,7 +561,12 @@ impl DeviceOpContext { let (busno, devfn) = DeviceManager::get_pci_device_info(dev)?; let req = DevMgrRequest::AddPciDev(PciDevRequest { busno, devfn }); - self.call_hotplug_device(req, callback) + self.call_hotplug_device(req, callback)?; + + // Extract the slot number from devfn + // Right shift by 3 to remove function bits (2:0) and + // align slot bits (7:3) to the least significant position + Ok(devfn >> 3) } #[cfg(feature = "host-device")] diff --git a/src/dragonball/src/device_manager/vfio_dev_mgr/mod.rs b/src/dragonball/src/device_manager/vfio_dev_mgr/mod.rs index c3c3b6bac..d70106e27 100644 --- a/src/dragonball/src/device_manager/vfio_dev_mgr/mod.rs +++ b/src/dragonball/src/device_manager/vfio_dev_mgr/mod.rs @@ -255,7 +255,7 @@ impl VfioDeviceMgr { pub fn insert_device( &mut self, ctx: &mut DeviceOpContext, - config: HostDeviceConfig, + config: &mut HostDeviceConfig, ) -> Result<()> { if !cfg!(feature = "hotplug") && ctx.is_hotplug { return Err(VfioDeviceError::UpdateNotAllowedPostBoot); @@ -267,7 +267,7 @@ impl VfioDeviceMgr { "hostdev_id" => &config.hostdev_id, "bdf" => &config.dev_config.bus_slot_func, ); - let device_index = self.info_list.insert_or_update(&config)?; + let device_index = self.info_list.insert_or_update(config)?; // Handle device hotplug case if ctx.is_hotplug { slog::info!( @@ -277,7 +277,7 @@ impl VfioDeviceMgr { "hostdev_id" => &config.hostdev_id, "bdf" => &config.dev_config.bus_slot_func, ); - self.add_device(ctx, &config, device_index)?; + self.add_device(ctx, config, device_index)?; } Ok(()) @@ -438,7 +438,7 @@ impl VfioDeviceMgr { fn add_device( &mut self, ctx: &mut DeviceOpContext, - cfg: &HostDeviceConfig, + cfg: &mut HostDeviceConfig, idx: usize, ) -> Result<()> { let dev = self.create_device(cfg, ctx, idx)?; @@ -450,8 +450,13 @@ impl VfioDeviceMgr { self.register_memory(vm_memory.deref())?; } - ctx.insert_hotplug_pci_device(&dev, None) - .map_err(VfioDeviceError::VfioDeviceMgr) + let slot = ctx + .insert_hotplug_pci_device(&dev, None) + .map_err(VfioDeviceError::VfioDeviceMgr)?; + + cfg.dev_config.guest_dev_id = Some(slot); + + Ok(()) } /// Gets the index of the device with the specified `hostdev_id` if it exists in the list.