From 02bd50f6ab8fa8c0474655bb6b8b48a6562917d7 Mon Sep 17 00:00:00 2001 From: Sebastien Boeuf Date: Mon, 11 May 2020 19:11:27 +0200 Subject: [PATCH] vm-virtio: Add helper to set the configuration BAR value From a VirtioPciDevice perspective, there are two types of BARs, either the virtio configuration BAR or the SHaredMemory BAR. The SHaredMemory BAR address comes from the virtio device directly as the memory region had been previously allocated when the virtio device has been created. So for this BAR, there's nothing to do when restoring a VM, since the associated virtio device is already restored with the appropriate resources, hence the BAR will already be at the right address. The remaining configuration BAR is different, as we usually get its address from the SystemAllocator. This means in case we restore a VM, we must provide this value, bypassing the allocator. This is what this commit takes care of, by letting the caller set the base address for the configuration BAR prior to allocating the BARs. Signed-off-by: Sebastien Boeuf --- vm-virtio/src/transport/pci_device.rs | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/vm-virtio/src/transport/pci_device.rs b/vm-virtio/src/transport/pci_device.rs index 8ae396ff5..41a44c069 100755 --- a/vm-virtio/src/transport/pci_device.rs +++ b/vm-virtio/src/transport/pci_device.rs @@ -307,8 +307,9 @@ pub struct VirtioPciDevice { // Guest memory memory: Option>, - // Setting PCI BAR + // Settings PCI BAR settings_bar: u8, + settings_bar_addr: Option, // Whether to use 64-bit bar location or 32-bit use_64bit_bar: bool, @@ -425,6 +426,7 @@ impl VirtioPciDevice { queue_evts, memory: Some(memory), settings_bar: 0, + settings_bar_addr: None, use_64bit_bar, interrupt_source_group, cap_pci_cfg_info: VirtioPciCfgCapInfo::default(), @@ -503,6 +505,12 @@ impl VirtioPciDevice { } } + // This function is used by the caller to provide the expected base address + // for the virtio-pci configuration BAR. + pub fn set_config_bar_addr(&mut self, bar_addr: u64) { + self.settings_bar_addr = Some(GuestAddress(bar_addr)); + } + pub fn config_bar_addr(&self) -> u64 { self.configuration.get_bar_addr(self.settings_bar as usize) } @@ -774,14 +782,14 @@ impl PciDevice for VirtioPciDevice { let (virtio_pci_bar_addr, region_type) = if self.use_64bit_bar { let region_type = PciBarRegionType::Memory64BitRegion; let addr = allocator - .allocate_mmio_addresses(None, CAPABILITY_BAR_SIZE, None) + .allocate_mmio_addresses(self.settings_bar_addr, CAPABILITY_BAR_SIZE, None) .ok_or(PciDeviceError::IoAllocationFailed(CAPABILITY_BAR_SIZE))?; ranges.push((addr, CAPABILITY_BAR_SIZE, region_type)); (addr, region_type) } else { let region_type = PciBarRegionType::Memory32BitRegion; let addr = allocator - .allocate_mmio_hole_addresses(None, CAPABILITY_BAR_SIZE, None) + .allocate_mmio_hole_addresses(self.settings_bar_addr, CAPABILITY_BAR_SIZE, None) .ok_or(PciDeviceError::IoAllocationFailed(CAPABILITY_BAR_SIZE))?; ranges.push((addr, CAPABILITY_BAR_SIZE, region_type)); (addr, region_type)