pci: vfio: Restore BARs at expected addresses

Relying on the list of resources, VfioCommon is now able to allocate the
BARs at specific addresses. This will be useful for restoring VFIO and
vfio-user devices.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
This commit is contained in:
Sebastien Boeuf 2022-04-07 14:56:03 +02:00
parent 0c34846ef6
commit 6175cc0977

View File

@ -363,7 +363,7 @@ impl VfioCommon {
allocator: &Arc<Mutex<SystemAllocator>>,
mmio_allocator: &mut AddressAllocator,
vfio_wrapper: &dyn Vfio,
_resources: Option<Vec<Resource>>,
resources: Option<Vec<Resource>>,
) -> Result<Vec<(GuestAddress, GuestUsize, PciBarRegionType)>, PciDeviceError> {
let mut ranges = Vec::new();
let mut bar_id = VFIO_PCI_BAR0_REGION_INDEX as u32;
@ -376,6 +376,19 @@ impl VfioCommon {
let region_size: u64;
let bar_addr: GuestAddress;
let restored_bar_addr = if let Some(resources) = &resources {
match resources
.get(ranges.len())
.ok_or(PciDeviceError::MissingResource)?
{
Resource::MmioAddressRange { base, .. } => Some(GuestAddress(*base)),
Resource::PioAddressRange { base, .. } => Some(GuestAddress(*base as u64)),
_ => return Err(PciDeviceError::InvalidResourceType),
}
} else {
None
};
let bar_offset = if bar_id == VFIO_PCI_ROM_REGION_INDEX {
(PCI_ROM_EXP_BAR_INDEX * 4) as u32
} else {
@ -433,7 +446,7 @@ impl VfioCommon {
bar_addr = allocator
.lock()
.unwrap()
.allocate_io_addresses(None, region_size, Some(0x4))
.allocate_io_addresses(restored_bar_addr, region_size, Some(0x4))
.ok_or(PciDeviceError::IoAllocationFailed(region_size))?;
}
#[cfg(target_arch = "aarch64")]
@ -463,7 +476,7 @@ impl VfioCommon {
// BAR allocation must be naturally aligned
bar_addr = mmio_allocator
.allocate(None, region_size, Some(region_size))
.allocate(restored_bar_addr, region_size, Some(region_size))
.ok_or(PciDeviceError::IoAllocationFailed(region_size))?;
} else {
// Mask out flag bits (lowest 4 for memory bars)
@ -481,7 +494,7 @@ impl VfioCommon {
bar_addr = allocator
.lock()
.unwrap()
.allocate_mmio_hole_addresses(None, region_size, Some(region_size))
.allocate_mmio_hole_addresses(restored_bar_addr, region_size, Some(region_size))
.ok_or(PciDeviceError::IoAllocationFailed(region_size))?;
}