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 <sebastien.boeuf@intel.com>
This commit is contained in:
Sebastien Boeuf 2020-05-11 19:11:27 +02:00 committed by Rob Bradford
parent 8a826ae24c
commit 02bd50f6ab

View File

@ -307,8 +307,9 @@ pub struct VirtioPciDevice {
// Guest memory
memory: Option<GuestMemoryAtomic<GuestMemoryMmap>>,
// Setting PCI BAR
// Settings PCI BAR
settings_bar: u8,
settings_bar_addr: Option<GuestAddress>,
// 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)