From 5aa3692c6d3bad8abc87f9b0933f76393ec491ca Mon Sep 17 00:00:00 2001 From: Rob Bradford Date: Sat, 4 Apr 2026 11:09:01 -0700 Subject: [PATCH] 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 --- vmm/src/device_manager.rs | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/vmm/src/device_manager.rs b/vmm/src/device_manager.rs index 1f1dd2f05..6c52026e1 100644 --- a/vmm/src/device_manager.rs +++ b/vmm/src/device_manager.rs @@ -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> = 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,