vmm: device_manager: Reserve explicitly used PCI device IDs

Use two passes to first reserve PCI device IDs and then allocate them
when adding the devices to the bus. This prevents a situation where an
anonymous PCI device allocation clashes with an explicitly allocated PCI
device ID.

Signed-off-by: Rob Bradford <rbradford@meta.com>
This commit is contained in:
Rob Bradford
2026-04-04 11:09:01 -07:00
parent aace90f270
commit 5aa3692c6d

View File

@@ -1697,6 +1697,10 @@ impl DeviceManager {
let mut iommu_attached_devices = Vec::new();
{
// Reserve all explicit PCI device IDs before any device creation
// so that they won't be picked for dynamic allocation.
self.reserve_explicit_device_ids()?;
for handle in self.virtio_devices.clone() {
let mapping: Option<Arc<IommuMapping>> = if handle.pci_common.iommu {
self.iommu_mapping.clone()
@@ -4534,6 +4538,37 @@ impl DeviceManager {
Ok(Some(ivshmem_device))
}
fn reserve_explicit_device_ids(&self) -> DeviceManagerResult<()> {
for handle in &self.virtio_devices {
if let Some(device_id) = handle.pci_common.pci_device_id {
self.pci_segments[handle.pci_common.pci_segment as usize]
.reserve_device_id(device_id)?;
}
}
let config = self.config.lock().unwrap();
if let Some(devices) = &config.devices {
for device_cfg in devices {
if let Some(device_id) = device_cfg.pci_common.pci_device_id {
self.pci_segments[device_cfg.pci_common.pci_segment as usize]
.reserve_device_id(device_id)?;
}
}
}
if let Some(user_devices) = &config.user_devices {
for device_cfg in user_devices {
if let Some(device_id) = device_cfg.pci_common.pci_device_id {
self.pci_segments[device_cfg.pci_common.pci_segment as usize]
.reserve_device_id(device_id)?;
}
}
}
Ok(())
}
fn pci_resources(
&self,
id: &str,