From a216c2ebd31a4fc230737678f6ba91580dac9a8b Mon Sep 17 00:00:00 2001 From: Rob Bradford Date: Wed, 8 Apr 2020 16:27:08 +0100 Subject: [PATCH] vm-virtio: pci: Implement free_bars() for VirtioPciDevice Implement the free_bars() method from the PciDevice trait which is used as part of the device removal process. Although there is only one BAR allocated by VirtioPciDevice simplify the code by using a vector. Signed-off-by: Rob Bradford --- vm-virtio/src/transport/pci_device.rs | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/vm-virtio/src/transport/pci_device.rs b/vm-virtio/src/transport/pci_device.rs index 482faea2d..76e048e28 100755 --- a/vm-virtio/src/transport/pci_device.rs +++ b/vm-virtio/src/transport/pci_device.rs @@ -300,6 +300,9 @@ pub struct VirtioPciDevice { // needed when the guest tries to early access the virtio configuration of // a device. cap_pci_cfg_info: VirtioPciCfgCapInfo, + + // Details of bar regions to free + bar_regions: Vec<(GuestAddress, GuestUsize, PciBarRegionType)>, } impl VirtioPciDevice { @@ -402,6 +405,7 @@ impl VirtioPciDevice { use_64bit_bar, interrupt_source_group, cap_pci_cfg_info: VirtioPciCfgCapInfo::default(), + bar_regions: vec![], }; if let Some(msix_config) = &virtio_pci_device.msix_config { @@ -721,6 +725,8 @@ impl PciDevice for VirtioPciDevice { ranges.push((addr, CAPABILITY_BAR_SIZE, region_type)); (addr, region_type) }; + self.bar_regions + .push((virtio_pci_bar_addr, CAPABILITY_BAR_SIZE, region_type)); let config = PciBarConfiguration::default() .set_register_index(0) @@ -763,6 +769,24 @@ impl PciDevice for VirtioPciDevice { Ok(ranges) } + fn free_bars( + &mut self, + allocator: &mut SystemAllocator, + ) -> std::result::Result<(), PciDeviceError> { + for (addr, length, type_) in self.bar_regions.drain(..) { + match type_ { + PciBarRegionType::Memory32BitRegion => { + allocator.free_mmio_hole_addresses(addr, length); + } + PciBarRegionType::Memory64BitRegion => { + allocator.free_mmio_addresses(addr, length); + } + _ => error!("Unexpected PCI bar type"), + } + } + Ok(()) + } + fn read_bar(&mut self, _base: u64, offset: u64, data: &mut [u8]) { match offset { o if o < COMMON_CONFIG_BAR_OFFSET + COMMON_CONFIG_SIZE => self.common_config.read(