<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">From cc796b4e7e5d7591b9b7c9c80ee44b8ddb7f5c19 Mon Sep 17 00:00:00 2001
From: David Gibson &lt;dgibson@redhat.com&gt;
Date: Wed, 30 Sep 2015 06:43:09 +0200
Subject: [PATCH 01/10] vfio: Remove unneeded union from VFIOContainer

Message-id: &lt;1443595398-20898-2-git-send-email-dgibson@redhat.com&gt;
Patchwork-id: 67985
O-Subject: [RHEL7.2 qemu-kvm-rhev PATCHv4 01/10] vfio: Remove unneeded union from VFIOContainer
Bugzilla: 1259556
RH-Acked-by: Alex Williamson &lt;alex.williamson@redhat.com&gt;
RH-Acked-by: Laurent Vivier &lt;lvivier@redhat.com&gt;
RH-Acked-by: Thomas Huth &lt;thuth@redhat.com&gt;

Currently the VFIOContainer iommu_data field contains a union with
different information for different host iommu types.  However:
   * It only actually contains information for the x86-like "Type1" iommu
   * Because we have a common listener the Type1 fields are actually used
on all IOMMU types, including the SPAPR TCE type as well

In fact we now have a general structure for the listener which is unlikely
to ever need per-iommu-type information, so this patch removes the union.

In a similar way we can unify the setup of the vfio memory listener in
vfio_connect_container() that is currently split across a switch on iommu
type, but is effectively the same in both cases.

The iommu_data.release pointer was only needed as a cleanup function
which would handle potentially different data in the union.  With the
union gone, it too can be removed.

Signed-off-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;

Upstream: ee0bf0e59bb1c07c0196142f2ecfd88f7f8b194e

Signed-off-by: David Gibson &lt;dgibson@redhat.com&gt;
Signed-off-by: Miroslav Rezanina &lt;mrezanin@redhat.com&gt;
---
 hw/vfio/common.c              | 52 ++++++++++++++++---------------------------
 include/hw/vfio/vfio-common.h | 16 +++----------
 2 files changed, 22 insertions(+), 46 deletions(-)

diff --git a/hw/vfio/common.c b/hw/vfio/common.c
index 6155e73..c583e62 100644
--- a/hw/vfio/common.c
+++ b/hw/vfio/common.c
@@ -312,8 +312,7 @@ static void vfio_iommu_map_notify(Notifier *n, void *data)
 static void vfio_listener_region_add(MemoryListener *listener,
                                      MemoryRegionSection *section)
 {
-    VFIOContainer *container = container_of(listener, VFIOContainer,
-                                            iommu_data.type1.listener);
+    VFIOContainer *container = container_of(listener, VFIOContainer, listener);
     hwaddr iova, end;
     Int128 llend;
     void *vaddr;
@@ -403,9 +402,9 @@ static void vfio_listener_region_add(MemoryListener *listener,
          * can gracefully fail.  Runtime, there's not much we can do other
          * than throw a hardware error.
          */
-        if (!container-&gt;iommu_data.type1.initialized) {
-            if (!container-&gt;iommu_data.type1.error) {
-                container-&gt;iommu_data.type1.error = ret;
+        if (!container-&gt;initialized) {
+            if (!container-&gt;error) {
+                container-&gt;error = ret;
             }
         } else {
             hw_error("vfio: DMA mapping failed, unable to continue");
@@ -416,8 +415,7 @@ static void vfio_listener_region_add(MemoryListener *listener,
 static void vfio_listener_region_del(MemoryListener *listener,
                                      MemoryRegionSection *section)
 {
-    VFIOContainer *container = container_of(listener, VFIOContainer,
-                                            iommu_data.type1.listener);
+    VFIOContainer *container = container_of(listener, VFIOContainer, listener);
     hwaddr iova, end;
     int ret;
 
@@ -482,7 +480,7 @@ static const MemoryListener vfio_memory_listener = {
 
 static void vfio_listener_release(VFIOContainer *container)
 {
-    memory_listener_unregister(&amp;container-&gt;iommu_data.type1.listener);
+    memory_listener_unregister(&amp;container-&gt;listener);
 }
 
 int vfio_mmap_region(Object *obj, VFIORegion *region,
@@ -688,21 +686,6 @@ static int vfio_connect_container(VFIOGroup *group, AddressSpace *as)
             ret = -errno;
             goto free_container_exit;
         }
-
-        container-&gt;iommu_data.type1.listener = vfio_memory_listener;
-        container-&gt;iommu_data.release = vfio_listener_release;
-
-        memory_listener_register(&amp;container-&gt;iommu_data.type1.listener,
-                                 container-&gt;space-&gt;as);
-
-        if (container-&gt;iommu_data.type1.error) {
-            ret = container-&gt;iommu_data.type1.error;
-            error_report("vfio: memory listener initialization failed for container");
-            goto listener_release_exit;
-        }
-
-        container-&gt;iommu_data.type1.initialized = true;
-
     } else if (ioctl(fd, VFIO_CHECK_EXTENSION, VFIO_SPAPR_TCE_IOMMU)) {
         ret = ioctl(group-&gt;fd, VFIO_GROUP_SET_CONTAINER, &amp;fd);
         if (ret) {
@@ -728,19 +711,24 @@ static int vfio_connect_container(VFIOGroup *group, AddressSpace *as)
             ret = -errno;
             goto free_container_exit;
         }
-
-        container-&gt;iommu_data.type1.listener = vfio_memory_listener;
-        container-&gt;iommu_data.release = vfio_listener_release;
-
-        memory_listener_register(&amp;container-&gt;iommu_data.type1.listener,
-                                 container-&gt;space-&gt;as);
-
     } else {
         error_report("vfio: No available IOMMU models");
         ret = -EINVAL;
         goto free_container_exit;
     }
 
+    container-&gt;listener = vfio_memory_listener;
+
+    memory_listener_register(&amp;container-&gt;listener, container-&gt;space-&gt;as);
+
+    if (container-&gt;error) {
+        ret = container-&gt;error;
+        error_report("vfio: memory listener initialization failed for container");
+        goto listener_release_exit;
+    }
+
+    container-&gt;initialized = true;
+
     QLIST_INIT(&amp;container-&gt;group_list);
     QLIST_INSERT_HEAD(&amp;space-&gt;containers, container, next);
 
@@ -778,9 +766,7 @@ static void vfio_disconnect_container(VFIOGroup *group)
     if (QLIST_EMPTY(&amp;container-&gt;group_list)) {
         VFIOAddressSpace *space = container-&gt;space;
 
-        if (container-&gt;iommu_data.release) {
-            container-&gt;iommu_data.release(container);
-        }
+        vfio_listener_release(container);
         QLIST_REMOVE(container, next);
         trace_vfio_disconnect_container(container-&gt;fd);
         close(container-&gt;fd);
diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h
index 0d1fb80..ec49c61 100644
--- a/include/hw/vfio/vfio-common.h
+++ b/include/hw/vfio/vfio-common.h
@@ -63,22 +63,12 @@ typedef struct VFIOAddressSpace {
 
 struct VFIOGroup;
 
-typedef struct VFIOType1 {
-    MemoryListener listener;
-    int error;
-    bool initialized;
-} VFIOType1;
-
 typedef struct VFIOContainer {
     VFIOAddressSpace *space;
     int fd; /* /dev/vfio/vfio, empowered by the attached groups */
-    struct {
-        /* enable abstraction to support various iommu backends */
-        union {
-            VFIOType1 type1;
-        };
-        void (*release)(struct VFIOContainer *);
-    } iommu_data;
+    MemoryListener listener;
+    int error;
+    bool initialized;
     QLIST_HEAD(, VFIOGuestIOMMU) giommu_list;
     QLIST_HEAD(, VFIOGroup) group_list;
     QLIST_ENTRY(VFIOContainer) next;
-- 
1.8.3.1

</pre></body></html>