mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2024-12-22 13:45:20 +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,
|
device_activated: bool,
|
||||||
queues: Vec<QueueState>,
|
queues: Vec<QueueState>,
|
||||||
interrupt_status: usize,
|
interrupt_status: usize,
|
||||||
|
cap_pci_cfg_offset: usize,
|
||||||
|
cap_pci_cfg: Vec<u8>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl VersionMapped for VirtioPciDeviceState {}
|
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.
|
// Update virtqueues indexes for both available and used rings.
|
||||||
for (i, queue) in queues.iter_mut().enumerate() {
|
for (i, queue) in queues.iter_mut().enumerate() {
|
||||||
queue.set_size(state.queues[i].size);
|
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 {
|
} else {
|
||||||
(false, 0)
|
(false, 0, VirtioPciCfgCapInfo::default())
|
||||||
};
|
};
|
||||||
|
|
||||||
// Dropping the MutexGuard to unlock the VirtioDevice. This is required
|
// Dropping the MutexGuard to unlock the VirtioDevice. This is required
|
||||||
@ -585,7 +594,7 @@ impl VirtioPciDevice {
|
|||||||
settings_bar: 0,
|
settings_bar: 0,
|
||||||
use_64bit_bar,
|
use_64bit_bar,
|
||||||
interrupt_source_group,
|
interrupt_source_group,
|
||||||
cap_pci_cfg_info: VirtioPciCfgCapInfo::default(),
|
cap_pci_cfg_info,
|
||||||
bar_regions: vec![],
|
bar_regions: vec![],
|
||||||
activate_evt,
|
activate_evt,
|
||||||
dma_handler,
|
dma_handler,
|
||||||
@ -634,6 +643,8 @@ impl VirtioPciDevice {
|
|||||||
used_ring: q.used_ring(),
|
used_ring: q.used_ring(),
|
||||||
})
|
})
|
||||||
.collect(),
|
.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