diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c index 22d0c85fea..be7b8ffc12 100644 --- a/hw/vfio/pci.c +++ b/hw/vfio/pci.c @@ -48,6 +48,10 @@ #define VFIO_ALLOW_KVM_MSI 1 #define VFIO_ALLOW_KVM_MSIX 1 +enum { + VFIO_DEVICE_TYPE_PCI = 0, +}; + struct VFIOPCIDevice; typedef struct VFIOQuirk { @@ -186,7 +190,10 @@ typedef struct VFIOMSIXInfo { } VFIOMSIXInfo; typedef struct VFIODevice { + struct VFIOGroup *group; + char *name; int fd; + int type; } VFIODevice; typedef struct VFIOPCIDevice { @@ -208,7 +215,6 @@ typedef struct VFIOPCIDevice { VFIOVGA vga; /* 0xa0000, 0x3b0, 0x3c0 */ PCIHostDeviceAddress host; QLIST_ENTRY(VFIOPCIDevice) next; - struct VFIOGroup *group; EventNotifier err_notifier; uint32_t features; #define VFIO_FEATURE_ENABLE_VGA_BIT 0 @@ -3924,7 +3930,7 @@ static int vfio_get_device(VFIOGroup *group, const char *name, } vdev->vbasedev.fd = ret; - vdev->group = group; + vdev->vbasedev.group = group; QLIST_INSERT_HEAD(&group->device_list, vdev, next); /* Sanity check device */ @@ -4054,7 +4060,7 @@ static int vfio_get_device(VFIOGroup *group, const char *name, error: if (ret) { QLIST_REMOVE(vdev, next); - vdev->group = NULL; + vdev->vbasedev.group = NULL; close(vdev->vbasedev.fd); } return ret; @@ -4063,9 +4069,10 @@ error: static void vfio_put_device(VFIOPCIDevice *vdev) { QLIST_REMOVE(vdev, next); - vdev->group = NULL; + vdev->vbasedev.group = NULL; trace_vfio_put_device(vdev->vbasedev.fd); close(vdev->vbasedev.fd); + g_free(vdev->vbasedev.name); if (vdev->msix) { g_free(vdev->msix); vdev->msix = NULL; @@ -4197,6 +4204,11 @@ static int vfio_initfn(PCIDevice *pdev) return -errno; } + vdev->vbasedev.type = VFIO_DEVICE_TYPE_PCI; + vdev->vbasedev.name = g_strdup_printf("%04x:%02x:%02x.%01x", + vdev->host.domain, vdev->host.bus, + vdev->host.slot, vdev->host.function); + strncat(path, "iommu_group", sizeof(path) - strlen(path) - 1); len = readlink(path, iommu_group_path, sizeof(path)); @@ -4227,10 +4239,7 @@ static int vfio_initfn(PCIDevice *pdev) vdev->host.function); QLIST_FOREACH(pvdev, &group->device_list, next) { - if (pvdev->host.domain == vdev->host.domain && - pvdev->host.bus == vdev->host.bus && - pvdev->host.slot == vdev->host.slot && - pvdev->host.function == vdev->host.function) { + if (strcmp(pvdev->vbasedev.name, vdev->vbasedev.name) == 0) { error_report("vfio: error: device %s is already attached", path); vfio_put_group(group); @@ -4333,7 +4342,7 @@ out_put: static void vfio_exitfn(PCIDevice *pdev) { VFIOPCIDevice *vdev = DO_UPCAST(VFIOPCIDevice, pdev, pdev); - VFIOGroup *group = vdev->group; + VFIOGroup *group = vdev->vbasedev.group; vfio_unregister_err_notifier(vdev); pci_device_set_intx_routing_notifier(&vdev->pdev, NULL);