runtime-rs: Introduce qemu-rs vfio device hotplug handler

This commit note that the current implementation restriction where
'multifunction=on' is temporarily unsupported. While the feature
isn't available in the present version, we explicitly acknowledge
this limitation and commit to addressing it in future iterations
to enhance functional completeness.

Tracking issue #11292 has been created to monitor progress towards
full multifunction support.

Fixes #10361

Signed-off-by: alex.lyn <alex.lyn@antgroup.com>
This commit is contained in:
alex.lyn 2025-05-20 10:36:53 +08:00
parent f1796fe9ba
commit 533d07a2c3
2 changed files with 55 additions and 0 deletions

View File

@ -632,6 +632,25 @@ impl QemuInner {
return Ok(DeviceType::Block(block_device));
}
DeviceType::Vfio(mut vfiodev) => {
// FIXME: the first one might not the true device we want to passthrough.
// The `multifunction=on` is temporarily unsupported.
// Tracking issue #11292 has been created to monitor progress towards full multifunction support.
let primary_device = vfiodev.devices.first_mut().unwrap();
info!(
sl!(),
"qmp hotplug vfio primary_device {:?}", &primary_device
);
primary_device.guest_pci_path = qmp.hotplug_vfio_device(
&primary_device.hostdev_id,
&primary_device.bus_slot_func,
&vfiodev.driver_type,
&vfiodev.bus,
)?;
return Ok(DeviceType::Vfio(vfiodev));
}
_ => info!(sl!(), "hotplugging of {:#?} is unsupported", device),
}
Ok(device)

View File

@ -596,6 +596,42 @@ impl Qmp {
Ok(Some(pci_path))
}
pub fn hotplug_vfio_device(
&mut self,
hostdev_id: &str,
bus_slot_func: &str,
driver: &str,
bus: &str,
) -> Result<Option<PciPath>> {
let mut vfio_args = Dictionary::new();
let bdf = if !bus_slot_func.starts_with("0000") {
format!("0000:{}", bus_slot_func)
} else {
bus_slot_func.to_owned()
};
vfio_args.insert("addr".to_owned(), "0x0".into());
vfio_args.insert("host".to_owned(), bdf.into());
vfio_args.insert("multifunction".to_owned(), "off".into());
let vfio_device_add = qmp::device_add {
driver: driver.to_string(),
bus: Some(bus.to_string()),
id: Some(hostdev_id.to_string()),
arguments: vfio_args,
};
info!(sl!(), "vfio_device_add: {:?}", vfio_device_add.clone());
self.qmp
.execute(&vfio_device_add)
.map_err(|e| anyhow!("device_add vfio device failed {:?}", e))?;
let pci_path = self
.get_device_by_qdev_id(hostdev_id)
.context("get device by qdev_id failed")?;
Ok(Some(pci_path))
}
}
fn vcpu_id_from_core_id(core_id: i64) -> String {