diff options
Diffstat (limited to 'hw')
-rw-r--r-- | hw/vfio/common.c | 5 | ||||
-rw-r--r-- | hw/vfio/pci.c | 24 |
2 files changed, 18 insertions, 11 deletions
diff --git a/hw/vfio/common.c b/hw/vfio/common.c index 6e299b3dfd..b230ef102b 100644 --- a/hw/vfio/common.c +++ b/hw/vfio/common.c @@ -847,7 +847,7 @@ free_group_exit: void vfio_put_group(VFIOGroup *group) { - if (!QLIST_EMPTY(&group->device_list)) { + if (!group || !QLIST_EMPTY(&group->device_list)) { return; } @@ -902,6 +902,9 @@ int vfio_get_device(VFIOGroup *group, const char *name, void vfio_put_base_device(VFIODevice *vbasedev) { + if (!vbasedev->group) { + return; + } QLIST_REMOVE(vbasedev, next); vbasedev->group = NULL; trace_vfio_put_base_device(vbasedev->fd); diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c index 23fe9fa030..0271c801b6 100644 --- a/hw/vfio/pci.c +++ b/hw/vfio/pci.c @@ -3248,7 +3248,7 @@ static int vfio_initfn(PCIDevice *pdev) ret = vfio_populate_device(vdev); if (ret) { - goto out_put; + return ret; } /* Get a copy of config space */ @@ -3258,7 +3258,7 @@ static int vfio_initfn(PCIDevice *pdev) if (ret < (int)MIN(pci_config_size(&vdev->pdev), vdev->config_size)) { ret = ret < 0 ? -errno : -EFAULT; error_report("vfio: Failed to read device config space"); - goto out_put; + return ret; } /* vfio emulates a lot for us, but some bits need extra love */ @@ -3290,7 +3290,7 @@ static int vfio_initfn(PCIDevice *pdev) ret = vfio_early_setup_msix(vdev); if (ret) { - goto out_put; + return ret; } vfio_map_bars(vdev); @@ -3329,17 +3329,24 @@ out_teardown: pci_device_set_intx_routing_notifier(&vdev->pdev, NULL); vfio_teardown_msi(vdev); vfio_unmap_bars(vdev); -out_put: + return ret; +} + +static void vfio_instance_finalize(Object *obj) +{ + PCIDevice *pci_dev = PCI_DEVICE(obj); + VFIOPCIDevice *vdev = DO_UPCAST(VFIOPCIDevice, pdev, pci_dev); + VFIOGroup *group = vdev->vbasedev.group; + g_free(vdev->emulated_config_bits); + g_free(vdev->rom); vfio_put_device(vdev); vfio_put_group(group); - return ret; } static void vfio_exitfn(PCIDevice *pdev) { VFIOPCIDevice *vdev = DO_UPCAST(VFIOPCIDevice, pdev, pdev); - VFIOGroup *group = vdev->vbasedev.group; vfio_unregister_err_notifier(vdev); pci_device_set_intx_routing_notifier(&vdev->pdev, NULL); @@ -3349,10 +3356,6 @@ static void vfio_exitfn(PCIDevice *pdev) } vfio_teardown_msi(vdev); vfio_unmap_bars(vdev); - g_free(vdev->emulated_config_bits); - g_free(vdev->rom); - vfio_put_device(vdev); - vfio_put_group(group); } static void vfio_pci_reset(DeviceState *dev) @@ -3440,6 +3443,7 @@ static const TypeInfo vfio_pci_dev_info = { .instance_size = sizeof(VFIOPCIDevice), .class_init = vfio_pci_dev_class_init, .instance_init = vfio_instance_init, + .instance_finalize = vfio_instance_finalize, }; static void register_vfio_pci_dev_type(void) |