From b50cbe5064156a50a1cda3c22b3440c3bd5d42f8 Mon Sep 17 00:00:00 2001 From: Sebastien Boeuf Date: Mon, 9 Mar 2020 16:32:27 +0100 Subject: [PATCH] pci: Give PCI device ID back when removing a device Upon removal of a PCI device, make sure we don't hold onto the device ID as it could be reused for another device later. Signed-off-by: Sebastien Boeuf --- pci/src/bus.rs | 11 +++++++++++ vmm/src/device_manager.rs | 10 ++++++++++ 2 files changed, 21 insertions(+) diff --git a/pci/src/bus.rs b/pci/src/bus.rs index 85df331a0..e5c423e18 100644 --- a/pci/src/bus.rs +++ b/pci/src/bus.rs @@ -31,6 +31,8 @@ pub enum PciRootError { MmioInsert(devices::BusError), /// Could not find an available device slot on the PCI bus. NoPciDeviceSlotAvailable, + /// Invalid PCI device identifier provided. + InvalidPciDeviceSlot(usize), } pub type Result = std::result::Result; @@ -146,6 +148,15 @@ impl PciBus { Err(PciRootError::NoPciDeviceSlotAvailable) } + + pub fn put_device_id(&mut self, id: usize) -> Result<()> { + if id < NUM_DEVICE_IDS { + self.device_ids[id] = false; + Ok(()) + } else { + Err(PciRootError::InvalidPciDeviceSlot(id)) + } + } } pub struct PciConfigIo { diff --git a/vmm/src/device_manager.rs b/vmm/src/device_manager.rs index 5d9a201b9..eb4d087d8 100644 --- a/vmm/src/device_manager.rs +++ b/vmm/src/device_manager.rs @@ -244,6 +244,10 @@ pub enum DeviceManagerError { /// Failed to find an available PCI device ID. #[cfg(feature = "pci_support")] NextPciDeviceId(pci::PciRootError), + + /// Could not give the PCI device ID back. + #[cfg(feature = "pci_support")] + PutPciDeviceId(pci::PciRootError), } pub type DeviceManagerResult = result::Result; @@ -1839,6 +1843,12 @@ impl DeviceManager { // the device entry. self.pci_id_list.retain(|_, bdf| *bdf != pci_device_bdf); + // Give the PCI device ID back to the PCI bus. + pci.lock() + .unwrap() + .put_device_id(device_id as usize) + .map_err(DeviceManagerError::PutPciDeviceId)?; + if let Some(any_device) = self.pci_devices.remove(&pci_device_bdf) { let (pci_device, bus_device, migratable_device) = if let Ok(vfio_pci_device) = any_device.downcast::>() {