summaryrefslogtreecommitdiffstats
path: root/hw/vfio
diff options
context:
space:
mode:
Diffstat (limited to 'hw/vfio')
-rw-r--r--hw/vfio/common.c5
-rw-r--r--hw/vfio/pci.c24
2 files changed, 18 insertions, 11 deletions
diff --git a/hw/vfio/common.c b/hw/vfio/common.c
index 6e299b3..b230ef1 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 23fe9fa..0271c80 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)
OpenPOWER on IntegriCloud