mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2025-02-22 19:32:20 +00:00
vmm: device_manager: Fix PCI device unplug issues
Because of the PCI refactoring that happened in the previous commit d793cc4da365ef960a239ff32589efc2635072bd, the ability to fully remove a PCI device was altered. The refactoring was correct, but the usage of a generic function to pass the same reference for both BusDevice, PciDevice and Any + Send + Sync causes the Arc::ptr_eq() function to behave differently than expected, as it does not match the references later in the code. That means we were not able to remove the device reference from the MMIO and/or PIO buses, which was leading to some bus range overlapping error once we were trying to add a device again to the previous range that should have been removed. Fixes #1802 Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
This commit is contained in:
parent
a32bd2fae1
commit
6aa5e21212
@ -2703,9 +2703,13 @@ impl DeviceManager {
|
|||||||
})
|
})
|
||||||
.map_err(DeviceManagerError::VfioMapRegion)?;
|
.map_err(DeviceManagerError::VfioMapRegion)?;
|
||||||
|
|
||||||
|
let vfio_pci_device = Arc::new(Mutex::new(vfio_pci_device));
|
||||||
|
|
||||||
self.add_pci_device(
|
self.add_pci_device(
|
||||||
pci,
|
pci,
|
||||||
Arc::new(Mutex::new(vfio_pci_device)),
|
vfio_pci_device.clone(),
|
||||||
|
vfio_pci_device.clone(),
|
||||||
|
vfio_pci_device,
|
||||||
pci_device_bdf,
|
pci_device_bdf,
|
||||||
vfio_name.clone(),
|
vfio_name.clone(),
|
||||||
)?;
|
)?;
|
||||||
@ -2714,34 +2718,31 @@ impl DeviceManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "pci_support")]
|
#[cfg(feature = "pci_support")]
|
||||||
fn add_pci_device<T>(
|
fn add_pci_device(
|
||||||
&mut self,
|
&mut self,
|
||||||
pci_bus: &mut PciBus,
|
pci_bus: &mut PciBus,
|
||||||
device: Arc<Mutex<T>>,
|
bus_device: Arc<Mutex<dyn BusDevice>>,
|
||||||
|
pci_device: Arc<Mutex<dyn PciDevice>>,
|
||||||
|
any_device: Arc<dyn Any + Send + Sync>,
|
||||||
bdf: u32,
|
bdf: u32,
|
||||||
device_id: String,
|
device_id: String,
|
||||||
) -> DeviceManagerResult<Vec<(GuestAddress, GuestUsize, PciBarRegionType)>>
|
) -> DeviceManagerResult<Vec<(GuestAddress, GuestUsize, PciBarRegionType)>> {
|
||||||
where
|
let bars = pci_device
|
||||||
T: BusDevice + PciDevice + Any + Send + Sync,
|
|
||||||
{
|
|
||||||
let bars = device
|
|
||||||
.lock()
|
.lock()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.allocate_bars(&mut self.address_manager.allocator.lock().unwrap())
|
.allocate_bars(&mut self.address_manager.allocator.lock().unwrap())
|
||||||
.map_err(DeviceManagerError::AllocateBars)?;
|
.map_err(DeviceManagerError::AllocateBars)?;
|
||||||
|
|
||||||
pci_bus
|
pci_bus
|
||||||
.add_device(bdf, device.clone())
|
.add_device(bdf, pci_device)
|
||||||
.map_err(DeviceManagerError::AddPciDevice)?;
|
.map_err(DeviceManagerError::AddPciDevice)?;
|
||||||
|
|
||||||
self.pci_devices
|
self.pci_devices.insert(bdf, any_device);
|
||||||
.insert(bdf, Arc::clone(&device) as Arc<dyn Any + Send + Sync>);
|
self.bus_devices.push(Arc::clone(&bus_device));
|
||||||
self.bus_devices
|
|
||||||
.push(Arc::clone(&device) as Arc<Mutex<dyn BusDevice>>);
|
|
||||||
|
|
||||||
pci_bus
|
pci_bus
|
||||||
.register_mapping(
|
.register_mapping(
|
||||||
device,
|
bus_device,
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
self.address_manager.io_bus.as_ref(),
|
self.address_manager.io_bus.as_ref(),
|
||||||
self.address_manager.mmio_bus.as_ref(),
|
self.address_manager.mmio_bus.as_ref(),
|
||||||
@ -2901,6 +2902,8 @@ impl DeviceManager {
|
|||||||
let bars = self.add_pci_device(
|
let bars = self.add_pci_device(
|
||||||
pci,
|
pci,
|
||||||
virtio_pci_device.clone(),
|
virtio_pci_device.clone(),
|
||||||
|
virtio_pci_device.clone(),
|
||||||
|
virtio_pci_device.clone(),
|
||||||
pci_device_bdf,
|
pci_device_bdf,
|
||||||
virtio_device_id,
|
virtio_device_id,
|
||||||
)?;
|
)?;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user