mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2024-12-21 21:25:19 +00:00
virtio-devices: save pci configuration capability state in snapshot
When restoring a VM, the VirtioPciCfgCapInfo struct is not properly initialized. All fields are 0, including the offset where the capabibility starts. Hence, when you read a PCI configuration register in the range [0..length(VirtioPciCfgCap)] you get the value 0 instead of the actual register contents. Linux rescans the whole PCI bus when adding a new device. It reads the values vendor_id and device_id for every device. Because these are stored at offset 0 in pci configuration space, their value is 0 for existing devices. As such, Linux considers that the devices have been unplugged and it removes them from the system. Fixes: #6265 Signed-off-by: Alexandru Matei <alexandru.matei@uipath.com>
This commit is contained in:
parent
58e6a289ab
commit
c3f1c3ee3d
@ -278,6 +278,8 @@ pub struct VirtioPciDeviceState {
|
||||
device_activated: bool,
|
||||
queues: Vec<QueueState>,
|
||||
interrupt_status: usize,
|
||||
cap_pci_cfg_offset: usize,
|
||||
cap_pci_cfg: Vec<u8>,
|
||||
}
|
||||
|
||||
impl VersionMapped for VirtioPciDeviceState {}
|
||||
@ -530,7 +532,7 @@ impl VirtioPciDevice {
|
||||
))
|
||||
})?;
|
||||
|
||||
let (device_activated, interrupt_status) = if let Some(state) = state {
|
||||
let (device_activated, interrupt_status, cap_pci_cfg_info) = if let Some(state) = state {
|
||||
// Update virtqueues indexes for both available and used rings.
|
||||
for (i, queue) in queues.iter_mut().enumerate() {
|
||||
queue.set_size(state.queues[i].size);
|
||||
@ -558,9 +560,16 @@ impl VirtioPciDevice {
|
||||
);
|
||||
}
|
||||
|
||||
(state.device_activated, state.interrupt_status)
|
||||
(
|
||||
state.device_activated,
|
||||
state.interrupt_status,
|
||||
VirtioPciCfgCapInfo {
|
||||
offset: state.cap_pci_cfg_offset,
|
||||
cap: *VirtioPciCfgCap::from_slice(&state.cap_pci_cfg).unwrap(),
|
||||
},
|
||||
)
|
||||
} else {
|
||||
(false, 0)
|
||||
(false, 0, VirtioPciCfgCapInfo::default())
|
||||
};
|
||||
|
||||
// Dropping the MutexGuard to unlock the VirtioDevice. This is required
|
||||
@ -585,7 +594,7 @@ impl VirtioPciDevice {
|
||||
settings_bar: 0,
|
||||
use_64bit_bar,
|
||||
interrupt_source_group,
|
||||
cap_pci_cfg_info: VirtioPciCfgCapInfo::default(),
|
||||
cap_pci_cfg_info,
|
||||
bar_regions: vec![],
|
||||
activate_evt,
|
||||
dma_handler,
|
||||
@ -634,6 +643,8 @@ impl VirtioPciDevice {
|
||||
used_ring: q.used_ring(),
|
||||
})
|
||||
.collect(),
|
||||
cap_pci_cfg_offset: self.cap_pci_cfg_info.offset,
|
||||
cap_pci_cfg: self.cap_pci_cfg_info.cap.bytes().to_vec(),
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user