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 <robert.bradford@intel.com>
This commit is contained in:
Rob Bradford 2020-04-08 16:27:08 +01:00 committed by Sebastien Boeuf
parent 72fdfff15d
commit a216c2ebd3

View File

@ -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(