dragonball: make add vfio device return guest device id

Fixes #9813

Signed-off-by: Alex Lyn <alex.lyn@antgroup.com>
This commit is contained in:
Alex Lyn 2024-07-03 15:49:15 +08:00
parent e3e3873857
commit 27947cbb0b
3 changed files with 26 additions and 11 deletions

View File

@ -281,6 +281,8 @@ pub enum VmmData {
MachineConfiguration(Box<VmConfigInfo>), MachineConfiguration(Box<VmConfigInfo>),
/// Prometheus Metrics represented by String. /// Prometheus Metrics represented by String.
HypervisorMetrics(String), HypervisorMetrics(String),
/// Return vfio device's slot number in guest.
VfioDeviceData(Option<u8>),
/// Sync Hotplug /// Sync Hotplug
SyncHotplug((Sender<Option<i32>>, Receiver<Option<i32>>)), SyncHotplug((Sender<Option<i32>>, Receiver<Option<i32>>)),
} }
@ -398,7 +400,9 @@ impl VmmService {
self.add_balloon_device(vmm, event_mgr, balloon_cfg) self.add_balloon_device(vmm, event_mgr, balloon_cfg)
} }
#[cfg(feature = "host-device")] #[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")] #[cfg(feature = "host-device")]
VmmAction::PrepareRemoveHostDevice(hostdev_id) => { VmmAction::PrepareRemoveHostDevice(hostdev_id) => {
self.prepare_remove_vfio_device(vmm, &hostdev_id) self.prepare_remove_vfio_device(vmm, &hostdev_id)
@ -850,7 +854,7 @@ impl VmmService {
} }
#[cfg(feature = "host-device")] #[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( let vm = vmm.get_vm_mut().ok_or(VmmActionError::HostDeviceConfig(
VfioDeviceError::InvalidVMID, VfioDeviceError::InvalidVMID,
))?; ))?;
@ -873,7 +877,8 @@ impl VmmService {
.unwrap() .unwrap()
.insert_device(&mut ctx, config) .insert_device(&mut ctx, config)
.map_err(VmmActionError::HostDeviceConfig)?; .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 // using upcall to unplug the pci device in the guest

View File

@ -553,7 +553,7 @@ impl DeviceOpContext {
&self, &self,
dev: &Arc<dyn DeviceIo>, dev: &Arc<dyn DeviceIo>,
callback: Option<Box<dyn Fn(UpcallClientResponse) + Send>>, callback: Option<Box<dyn Fn(UpcallClientResponse) + Send>>,
) -> Result<()> { ) -> Result<u8> {
if !self.is_hotplug || !self.pci_hotplug_enabled { if !self.is_hotplug || !self.pci_hotplug_enabled {
return Err(DeviceMgrError::InvalidOperation); return Err(DeviceMgrError::InvalidOperation);
} }
@ -561,7 +561,12 @@ impl DeviceOpContext {
let (busno, devfn) = DeviceManager::get_pci_device_info(dev)?; let (busno, devfn) = DeviceManager::get_pci_device_info(dev)?;
let req = DevMgrRequest::AddPciDev(PciDevRequest { busno, devfn }); 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")] #[cfg(feature = "host-device")]

View File

@ -255,7 +255,7 @@ impl VfioDeviceMgr {
pub fn insert_device( pub fn insert_device(
&mut self, &mut self,
ctx: &mut DeviceOpContext, ctx: &mut DeviceOpContext,
config: HostDeviceConfig, config: &mut HostDeviceConfig,
) -> Result<()> { ) -> Result<()> {
if !cfg!(feature = "hotplug") && ctx.is_hotplug { if !cfg!(feature = "hotplug") && ctx.is_hotplug {
return Err(VfioDeviceError::UpdateNotAllowedPostBoot); return Err(VfioDeviceError::UpdateNotAllowedPostBoot);
@ -267,7 +267,7 @@ impl VfioDeviceMgr {
"hostdev_id" => &config.hostdev_id, "hostdev_id" => &config.hostdev_id,
"bdf" => &config.dev_config.bus_slot_func, "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 // Handle device hotplug case
if ctx.is_hotplug { if ctx.is_hotplug {
slog::info!( slog::info!(
@ -277,7 +277,7 @@ impl VfioDeviceMgr {
"hostdev_id" => &config.hostdev_id, "hostdev_id" => &config.hostdev_id,
"bdf" => &config.dev_config.bus_slot_func, "bdf" => &config.dev_config.bus_slot_func,
); );
self.add_device(ctx, &config, device_index)?; self.add_device(ctx, config, device_index)?;
} }
Ok(()) Ok(())
@ -438,7 +438,7 @@ impl VfioDeviceMgr {
fn add_device( fn add_device(
&mut self, &mut self,
ctx: &mut DeviceOpContext, ctx: &mut DeviceOpContext,
cfg: &HostDeviceConfig, cfg: &mut HostDeviceConfig,
idx: usize, idx: usize,
) -> Result<()> { ) -> Result<()> {
let dev = self.create_device(cfg, ctx, idx)?; let dev = self.create_device(cfg, ctx, idx)?;
@ -450,8 +450,13 @@ impl VfioDeviceMgr {
self.register_memory(vm_memory.deref())?; self.register_memory(vm_memory.deref())?;
} }
ctx.insert_hotplug_pci_device(&dev, None) let slot = ctx
.map_err(VfioDeviceError::VfioDeviceMgr) .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. /// Gets the index of the device with the specified `hostdev_id` if it exists in the list.