summary refs log tree commit diff stats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--hw/vfio/pci.c27
1 files changed, 18 insertions, 9 deletions
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);