pci, virtio-devices: Restore proper BAR type

When restoring a VM, the BAR type can be found directly from the
snapshot resources. It is more reliable than the previous method which
was using self.use_64bit_bar from VirtioPciDevice because at the time
the BARs are allocated, the VirtioDevice hasn't been restored yet,
meaning the way to determine the value of use_64bit_bar is wrong for a
device like vDPA. At this time, the device type is not known and relying
on the stored resources is the only reliable way.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
This commit is contained in:
Sebastien Boeuf 2022-10-11 15:49:42 +02:00
parent 204bf2e3f5
commit 2b150ac2ea
2 changed files with 20 additions and 6 deletions

View File

@ -21,6 +21,8 @@ pub enum Error {
IoRegistrationFailed(u64, configuration::Error),
/// Expected resource not found.
MissingResource,
/// Invalid resource.
InvalidResource(Resource),
}
pub type Result<T> = std::result::Result<T, Error>;
@ -37,6 +39,7 @@ impl Display for Error {
write!(f, "failed to register an IO BAR, addr={} err={}", addr, e)
}
MissingResource => write!(f, "failed to find expected resource"),
InvalidResource(r) => write!(f, "invalid resource {:?}", r),
}
}
}

View File

@ -36,7 +36,7 @@ use vm_device::dma_mapping::ExternalDmaMapping;
use vm_device::interrupt::{
InterruptIndex, InterruptManager, InterruptSourceGroup, MsiIrqGroupConfig,
};
use vm_device::{BusDevice, Resource};
use vm_device::{BusDevice, PciBarType, Resource};
use vm_memory::{Address, ByteValued, GuestAddress, GuestAddressSpace, GuestMemoryAtomic, Le32};
use vm_migration::{
Migratable, MigratableError, Pausable, Snapshot, Snapshottable, Transportable, VersionMapped,
@ -882,11 +882,22 @@ impl PciDevice for VirtioPciDevice {
let device = device_clone.lock().unwrap();
let mut settings_bar_addr = None;
if let Some(resources) = &resources {
let mut use_64bit_bar = self.use_64bit_bar;
if let Some(resources) = resources {
for resource in resources {
if let Resource::PciBar { index, base, .. } = resource {
if *index == VIRTIO_COMMON_BAR_INDEX {
settings_bar_addr = Some(GuestAddress(*base));
if let Resource::PciBar {
index, base, type_, ..
} = resource
{
if index == VIRTIO_COMMON_BAR_INDEX {
settings_bar_addr = Some(GuestAddress(base));
use_64bit_bar = match type_ {
PciBarType::Io => {
return Err(PciDeviceError::InvalidResource(resource))
}
PciBarType::Mmio32 => false,
PciBarType::Mmio64 => true,
};
break;
}
}
@ -899,7 +910,7 @@ impl PciDevice for VirtioPciDevice {
// Allocate the virtio-pci capability BAR.
// See http://docs.oasis-open.org/virtio/virtio/v1.0/cs04/virtio-v1.0-cs04.html#x1-740004
let (virtio_pci_bar_addr, region_type) = if self.use_64bit_bar {
let (virtio_pci_bar_addr, region_type) = if use_64bit_bar {
let region_type = PciBarRegionType::Memory64BitRegion;
let addr = mmio_allocator
.allocate(