mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2024-10-03 20:15:45 +00:00
vmm: Update DeviceTree upon PCI BAR reprogramming
By passing a reference of the DeviceTree to the AddressManager, we can now update the DeviceTree whenever a PCI BAR is reprogrammed. This is mandatory to maintain the correct resources information related to each virtio-pci device, which will ensure correct information will be stored upon VM snapshot. Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
This commit is contained in:
parent
d0ae9d7ce6
commit
c37da600e8
@ -411,6 +411,8 @@ struct AddressManager {
|
|||||||
io_bus: Arc<devices::Bus>,
|
io_bus: Arc<devices::Bus>,
|
||||||
mmio_bus: Arc<devices::Bus>,
|
mmio_bus: Arc<devices::Bus>,
|
||||||
vm_fd: Arc<VmFd>,
|
vm_fd: Arc<VmFd>,
|
||||||
|
#[cfg(feature = "pci_support")]
|
||||||
|
device_tree: Arc<Mutex<DeviceTree>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "pci_support")]
|
#[cfg(feature = "pci_support")]
|
||||||
@ -497,6 +499,44 @@ impl DeviceRelocation for AddressManager {
|
|||||||
|
|
||||||
let any_dev = pci_dev.as_any();
|
let any_dev = pci_dev.as_any();
|
||||||
if let Some(virtio_pci_dev) = any_dev.downcast_ref::<VirtioPciDevice>() {
|
if let Some(virtio_pci_dev) = any_dev.downcast_ref::<VirtioPciDevice>() {
|
||||||
|
// Update the device_tree resources associated with the device
|
||||||
|
if let Some(node) = self
|
||||||
|
.device_tree
|
||||||
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.get_mut(&virtio_pci_dev.id())
|
||||||
|
{
|
||||||
|
let mut resource_updated = false;
|
||||||
|
for resource in node.resources.iter_mut() {
|
||||||
|
if let Resource::MmioAddressRange { base, .. } = resource {
|
||||||
|
if *base == old_base {
|
||||||
|
*base = new_base;
|
||||||
|
resource_updated = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !resource_updated {
|
||||||
|
return Err(io::Error::new(
|
||||||
|
io::ErrorKind::Other,
|
||||||
|
format!(
|
||||||
|
"Couldn't find a resource with base 0x{:x} for device {}",
|
||||||
|
old_base,
|
||||||
|
virtio_pci_dev.id()
|
||||||
|
),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return Err(io::Error::new(
|
||||||
|
io::ErrorKind::Other,
|
||||||
|
format!(
|
||||||
|
"Couldn't find device {} from device tree",
|
||||||
|
virtio_pci_dev.id()
|
||||||
|
),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
let bar_addr = virtio_pci_dev.config_bar_addr();
|
let bar_addr = virtio_pci_dev.config_bar_addr();
|
||||||
if bar_addr == new_base {
|
if bar_addr == new_base {
|
||||||
for (event, addr) in virtio_pci_dev.ioeventfds(old_base) {
|
for (event, addr) in virtio_pci_dev.ioeventfds(old_base) {
|
||||||
@ -669,11 +709,15 @@ impl DeviceManager {
|
|||||||
reset_evt: &EventFd,
|
reset_evt: &EventFd,
|
||||||
vmm_path: PathBuf,
|
vmm_path: PathBuf,
|
||||||
) -> DeviceManagerResult<Arc<Mutex<Self>>> {
|
) -> DeviceManagerResult<Arc<Mutex<Self>>> {
|
||||||
|
let device_tree = Arc::new(Mutex::new(DeviceTree::new()));
|
||||||
|
|
||||||
let address_manager = Arc::new(AddressManager {
|
let address_manager = Arc::new(AddressManager {
|
||||||
allocator: memory_manager.lock().unwrap().allocator(),
|
allocator: memory_manager.lock().unwrap().allocator(),
|
||||||
io_bus: Arc::new(devices::Bus::new()),
|
io_bus: Arc::new(devices::Bus::new()),
|
||||||
mmio_bus: Arc::new(devices::Bus::new()),
|
mmio_bus: Arc::new(devices::Bus::new()),
|
||||||
vm_fd: vm_fd.clone(),
|
vm_fd: vm_fd.clone(),
|
||||||
|
#[cfg(feature = "pci_support")]
|
||||||
|
device_tree: Arc::clone(&device_tree),
|
||||||
});
|
});
|
||||||
|
|
||||||
// Create a shared list of GSI that can be shared through all PCI
|
// Create a shared list of GSI that can be shared through all PCI
|
||||||
@ -725,7 +769,7 @@ impl DeviceManager {
|
|||||||
pci_id_list: HashMap::new(),
|
pci_id_list: HashMap::new(),
|
||||||
#[cfg(feature = "pci_support")]
|
#[cfg(feature = "pci_support")]
|
||||||
pci_devices: HashMap::new(),
|
pci_devices: HashMap::new(),
|
||||||
device_tree: Arc::new(Mutex::new(DeviceTree::new())),
|
device_tree,
|
||||||
#[cfg(feature = "acpi")]
|
#[cfg(feature = "acpi")]
|
||||||
exit_evt: _exit_evt.try_clone().map_err(DeviceManagerError::EventFd)?,
|
exit_evt: _exit_evt.try_clone().map_err(DeviceManagerError::EventFd)?,
|
||||||
reset_evt: reset_evt.try_clone().map_err(DeviceManagerError::EventFd)?,
|
reset_evt: reset_evt.try_clone().map_err(DeviceManagerError::EventFd)?,
|
||||||
|
Loading…
Reference in New Issue
Block a user