mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-27 12:02:04 -06:00
vfio-pci: skip reset during cpr
Do not reset a vfio-pci device during CPR, and do not complain if the kernel's PCI config space changes for non-emulated bits between the vmstate save and load, which can happen due to ongoing interrupt activity. Signed-off-by: Steve Sistare <steven.sistare@oracle.com> Reviewed-by: Cédric Le Goater <clg@redhat.com> Link: https://lore.kernel.org/qemu-devel/1749569991-25171-12-git-send-email-steven.sistare@oracle.com Signed-off-by: Cédric Le Goater <clg@redhat.com>
This commit is contained in:
parent
24c156dcd9
commit
031fbb7110
3 changed files with 40 additions and 0 deletions
|
@ -8,6 +8,8 @@
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include "hw/vfio/vfio-device.h"
|
#include "hw/vfio/vfio-device.h"
|
||||||
#include "hw/vfio/vfio-cpr.h"
|
#include "hw/vfio/vfio-cpr.h"
|
||||||
|
#include "hw/vfio/pci.h"
|
||||||
|
#include "migration/cpr.h"
|
||||||
#include "qapi/error.h"
|
#include "qapi/error.h"
|
||||||
#include "system/runstate.h"
|
#include "system/runstate.h"
|
||||||
|
|
||||||
|
@ -37,3 +39,32 @@ void vfio_cpr_unregister_container(VFIOContainerBase *bcontainer)
|
||||||
{
|
{
|
||||||
migration_remove_notifier(&bcontainer->cpr_reboot_notifier);
|
migration_remove_notifier(&bcontainer->cpr_reboot_notifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The kernel may change non-emulated config bits. Exclude them from the
|
||||||
|
* changed-bits check in get_pci_config_device.
|
||||||
|
*/
|
||||||
|
static int vfio_cpr_pci_pre_load(void *opaque)
|
||||||
|
{
|
||||||
|
VFIOPCIDevice *vdev = opaque;
|
||||||
|
PCIDevice *pdev = &vdev->pdev;
|
||||||
|
int size = MIN(pci_config_size(pdev), vdev->config_size);
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < size; i++) {
|
||||||
|
pdev->cmask[i] &= vdev->emulated_config_bits[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const VMStateDescription vfio_cpr_pci_vmstate = {
|
||||||
|
.name = "vfio-cpr-pci",
|
||||||
|
.version_id = 0,
|
||||||
|
.minimum_version_id = 0,
|
||||||
|
.pre_load = vfio_cpr_pci_pre_load,
|
||||||
|
.needed = cpr_incoming_needed,
|
||||||
|
.fields = (VMStateField[]) {
|
||||||
|
VMSTATE_END_OF_LIST()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
#include "hw/qdev-properties.h"
|
#include "hw/qdev-properties.h"
|
||||||
#include "hw/qdev-properties-system.h"
|
#include "hw/qdev-properties-system.h"
|
||||||
#include "migration/vmstate.h"
|
#include "migration/vmstate.h"
|
||||||
|
#include "migration/cpr.h"
|
||||||
#include "qobject/qdict.h"
|
#include "qobject/qdict.h"
|
||||||
#include "qemu/error-report.h"
|
#include "qemu/error-report.h"
|
||||||
#include "qemu/main-loop.h"
|
#include "qemu/main-loop.h"
|
||||||
|
@ -3354,6 +3355,11 @@ static void vfio_pci_reset(DeviceState *dev)
|
||||||
{
|
{
|
||||||
VFIOPCIDevice *vdev = VFIO_PCI_BASE(dev);
|
VFIOPCIDevice *vdev = VFIO_PCI_BASE(dev);
|
||||||
|
|
||||||
|
/* Do not reset the device during qemu_system_reset prior to cpr load */
|
||||||
|
if (cpr_is_incoming()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
trace_vfio_pci_reset(vdev->vbasedev.name);
|
trace_vfio_pci_reset(vdev->vbasedev.name);
|
||||||
|
|
||||||
vfio_pci_pre_reset(vdev);
|
vfio_pci_pre_reset(vdev);
|
||||||
|
@ -3530,6 +3536,7 @@ static void vfio_pci_dev_class_init(ObjectClass *klass, const void *data)
|
||||||
#ifdef CONFIG_IOMMUFD
|
#ifdef CONFIG_IOMMUFD
|
||||||
object_class_property_add_str(klass, "fd", NULL, vfio_pci_set_fd);
|
object_class_property_add_str(klass, "fd", NULL, vfio_pci_set_fd);
|
||||||
#endif
|
#endif
|
||||||
|
dc->vmsd = &vfio_cpr_pci_vmstate;
|
||||||
dc->desc = "VFIO-based PCI device assignment";
|
dc->desc = "VFIO-based PCI device assignment";
|
||||||
pdc->realize = vfio_pci_realize;
|
pdc->realize = vfio_pci_realize;
|
||||||
|
|
||||||
|
|
|
@ -52,4 +52,6 @@ void vfio_cpr_giommu_remap(struct VFIOContainerBase *bcontainer,
|
||||||
bool vfio_cpr_ram_discard_register_listener(
|
bool vfio_cpr_ram_discard_register_listener(
|
||||||
struct VFIOContainerBase *bcontainer, MemoryRegionSection *section);
|
struct VFIOContainerBase *bcontainer, MemoryRegionSection *section);
|
||||||
|
|
||||||
|
extern const VMStateDescription vfio_cpr_pci_vmstate;
|
||||||
|
|
||||||
#endif /* HW_VFIO_VFIO_CPR_H */
|
#endif /* HW_VFIO_VFIO_CPR_H */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue