From: Huguanshen Chen <chen...@chinatelecom.cn> On arm64 virtualization platform, vfio-user devices lose their interrupts after migration to the destination. This issue occurs because qemu fails to deliver the msi device id to the vGIC. The error device id is calculated based on the device's parent bus, so it is essential to save the parent pci config to prevent this issue.
Backtrace: QEMU: #0 qdev_get_parent_bus #1 pci_dev_bus_num #2 pci_req_id_cache_extract #3 pci_requester_id #4 kvm_irqchip_update_msi_route delivers 0(error id) to vGIC KVM: #0 find_its_device returns error #1 find_ite #2 vgic_its_resolve_lpi #3 vgic_its_trigger_msi #4 vgic_its_inject_msi #5 kvm_set_msi #6 kvm_send_userspace_msi Reported-by: Heng Zhang <zhangh...@chinatelecom.cn> Signed-off-by: Huguanshen Chen <chen...@chinatelecom.cn> Signed-off-by: Huaitong Han <han...@chinatelecom.cn> --- hw/vfio/pci.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c index a1bfdfe375..442113d0b7 100644 --- a/hw/vfio/pci.c +++ b/hw/vfio/pci.c @@ -2654,6 +2654,11 @@ static int vfio_pci_save_config(VFIODevice *vbasedev, QEMUFile *f, Error **errp) { VFIOPCIDevice *vdev = container_of(vbasedev, VFIOPCIDevice, vbasedev); + PCIDevice *pdev = &vdev->pdev; + BusState *qbus = qdev_get_parent_bus(DEVICE(pdev)); + + pci_device_save(PCI_DEVICE(qbus->parent), f); + return vmstate_save_state_with_err(f, &vmstate_vfio_pci_config, vdev, NULL, errp); } @@ -2662,6 +2667,7 @@ static int vfio_pci_load_config(VFIODevice *vbasedev, QEMUFile *f) { VFIOPCIDevice *vdev = container_of(vbasedev, VFIOPCIDevice, vbasedev); PCIDevice *pdev = &vdev->pdev; + BusState *qbus = qdev_get_parent_bus(DEVICE(pdev)); pcibus_t old_addr[PCI_NUM_REGIONS - 1]; int bar, ret; @@ -2669,6 +2675,11 @@ static int vfio_pci_load_config(VFIODevice *vbasedev, QEMUFile *f) old_addr[bar] = pdev->io_regions[bar].addr; } + ret = pci_device_load(PCI_DEVICE(qbus->parent), f); + if (ret) { + return ret; + } + ret = vmstate_load_state(f, &vmstate_vfio_pci_config, vdev, 1); if (ret) { return ret; -- 2.43.5