qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v1 0/6] Allow memory_region_register_iommu_notifier() to fail
@ 2019-09-13  8:36 Eric Auger
  2019-09-13  8:36 ` [Qemu-devel] [PATCH v1 1/6] memory: allow " Eric Auger
                   ` (5 more replies)
  0 siblings, 6 replies; 11+ messages in thread
From: Eric Auger @ 2019-09-13  8:36 UTC (permalink / raw)
  To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, peter.maydell,
	pbonzini, alex.williamson, peterx
  Cc: mst

This series allows the memory_region_register_iommu_notifier()
to fail. As of now, when a MAP notifier is attempted to be
registered along with SMMUv3, Intel iommu without caching mode
or AMD IOMMU, we exit in the IOMMU MR notify_flag_changed()
callback. In case of VFIO assigned device hotplug, this could be
handled more nicely directly within the VFIO code, simply rejecting
the hotplug without exiting. This is what the series achieves
by handling the memory_region_register_iommu_notifier() returned
value.

Best Regards

Eric

This series can be found at:
https://github.com/eauger/qemu/tree/v4.1.0_register_iommu_notifier_fail_v1

History:

Follow-up of "VFIO/SMMUv3: Fail on VFIO/HW nested paging detection"
https://patchew.org/QEMU/20190829090141.21821-1-eric.auger@redhat.com/

Eric Auger (6):
  memory: allow memory_region_register_iommu_notifier() to fail
  vfio/common: Handle memory_region_register_iommu_notifier() failure
  exec: assert on memory_region_register_iommu_notifier() failure
  vhost: assert on memory_region_register_iommu_notifier() failure
  intel_iommu: Let vtd_iommu_notify_flag_changed() fail
  amd_iommu: Let amdvi_iommu_notify_flag_changed() fail

 exec.c                |  3 ++-
 hw/arm/smmuv3.c       |  8 +++++---
 hw/i386/amd_iommu.c   |  9 +++++----
 hw/i386/intel_iommu.c |  9 +++++----
 hw/ppc/spapr_iommu.c  |  7 ++++---
 hw/vfio/common.c      |  8 ++++++--
 hw/virtio/vhost.c     |  2 +-
 include/exec/memory.h | 18 +++++++++++++-----
 memory.c              | 28 ++++++++++++++++++----------
 9 files changed, 59 insertions(+), 33 deletions(-)

-- 
2.20.1



^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Qemu-devel] [PATCH v1 1/6] memory: allow memory_region_register_iommu_notifier() to fail
  2019-09-13  8:36 [Qemu-devel] [PATCH v1 0/6] Allow memory_region_register_iommu_notifier() to fail Eric Auger
@ 2019-09-13  8:36 ` Eric Auger
  2019-09-16  3:23   ` Peter Xu
  2019-09-13  8:36 ` [Qemu-devel] [PATCH v1 2/6] vfio/common: Handle memory_region_register_iommu_notifier() failure Eric Auger
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 11+ messages in thread
From: Eric Auger @ 2019-09-13  8:36 UTC (permalink / raw)
  To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, peter.maydell,
	pbonzini, alex.williamson, peterx
  Cc: mst

Currently, when a notifier is attempted to be registered and its
flags are not supported (especially the MAP one) by the IOMMU MR,
we generally abruptly exit in the IOMMU code. The failure could be
handled more nicely in the caller and especially in the VFIO code.

So let's allow memory_region_register_iommu_notifier() to fail as
well as notify_flag_changed() callback.

All sites implementing the callback are updated. This patch does
not yet remove the exit(1) in the intel_iommu and amd_iommu code.

Signed-off-by: Eric Auger <eric.auger@redhat.com>
---
 hw/arm/smmuv3.c       |  8 +++++---
 hw/i386/amd_iommu.c   |  7 ++++---
 hw/i386/intel_iommu.c |  7 ++++---
 hw/ppc/spapr_iommu.c  |  7 ++++---
 include/exec/memory.h | 18 +++++++++++++-----
 memory.c              | 28 ++++++++++++++++++----------
 6 files changed, 48 insertions(+), 27 deletions(-)

diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
index db051dcac8..d7a86fc505 100644
--- a/hw/arm/smmuv3.c
+++ b/hw/arm/smmuv3.c
@@ -1469,9 +1469,9 @@ static void smmuv3_class_init(ObjectClass *klass, void *data)
     dc->realize = smmu_realize;
 }
 
-static void smmuv3_notify_flag_changed(IOMMUMemoryRegion *iommu,
-                                       IOMMUNotifierFlag old,
-                                       IOMMUNotifierFlag new)
+static int smmuv3_notify_flag_changed(IOMMUMemoryRegion *iommu,
+                                      IOMMUNotifierFlag old,
+                                      IOMMUNotifierFlag new)
 {
     SMMUDevice *sdev = container_of(iommu, SMMUDevice, iommu);
     SMMUv3State *s3 = sdev->smmu;
@@ -1483,6 +1483,7 @@ static void smmuv3_notify_flag_changed(IOMMUMemoryRegion *iommu,
 
         warn_report("SMMUv3 does not support notification on MAP: "
                      "device %s will not function properly", pcidev->name);
+        return -EINVAL;
     }
 
     if (old == IOMMU_NOTIFIER_NONE) {
@@ -1492,6 +1493,7 @@ static void smmuv3_notify_flag_changed(IOMMUMemoryRegion *iommu,
         trace_smmuv3_notify_flag_del(iommu->parent_obj.name);
         QLIST_REMOVE(sdev, next);
     }
+    return 0;
 }
 
 static void smmuv3_iommu_memory_region_class_init(ObjectClass *klass,
diff --git a/hw/i386/amd_iommu.c b/hw/i386/amd_iommu.c
index 08884523e2..137ba367db 100644
--- a/hw/i386/amd_iommu.c
+++ b/hw/i386/amd_iommu.c
@@ -1466,9 +1466,9 @@ static const MemoryRegionOps mmio_mem_ops = {
     }
 };
 
-static void amdvi_iommu_notify_flag_changed(IOMMUMemoryRegion *iommu,
-                                            IOMMUNotifierFlag old,
-                                            IOMMUNotifierFlag new)
+static int amdvi_iommu_notify_flag_changed(IOMMUMemoryRegion *iommu,
+                                           IOMMUNotifierFlag old,
+                                           IOMMUNotifierFlag new)
 {
     AMDVIAddressSpace *as = container_of(iommu, AMDVIAddressSpace, iommu);
 
@@ -1478,6 +1478,7 @@ static void amdvi_iommu_notify_flag_changed(IOMMUMemoryRegion *iommu,
                      PCI_FUNC(as->devfn));
         exit(1);
     }
+    return 0;
 }
 
 static void amdvi_init(AMDVIState *s)
diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
index 75ca6f9c70..7a89ea9ba1 100644
--- a/hw/i386/intel_iommu.c
+++ b/hw/i386/intel_iommu.c
@@ -2921,9 +2921,9 @@ static IOMMUTLBEntry vtd_iommu_translate(IOMMUMemoryRegion *iommu, hwaddr addr,
     return iotlb;
 }
 
-static void vtd_iommu_notify_flag_changed(IOMMUMemoryRegion *iommu,
-                                          IOMMUNotifierFlag old,
-                                          IOMMUNotifierFlag new)
+static int vtd_iommu_notify_flag_changed(IOMMUMemoryRegion *iommu,
+                                         IOMMUNotifierFlag old,
+                                         IOMMUNotifierFlag new)
 {
     VTDAddressSpace *vtd_as = container_of(iommu, VTDAddressSpace, iommu);
     IntelIOMMUState *s = vtd_as->iommu_state;
@@ -2942,6 +2942,7 @@ static void vtd_iommu_notify_flag_changed(IOMMUMemoryRegion *iommu,
     } else if (new == IOMMU_NOTIFIER_NONE) {
         QLIST_REMOVE(vtd_as, next);
     }
+    return 0;
 }
 
 static int vtd_post_load(void *opaque, int version_id)
diff --git a/hw/ppc/spapr_iommu.c b/hw/ppc/spapr_iommu.c
index e87b3d50f7..8d3b38f90b 100644
--- a/hw/ppc/spapr_iommu.c
+++ b/hw/ppc/spapr_iommu.c
@@ -205,9 +205,9 @@ static int spapr_tce_get_attr(IOMMUMemoryRegion *iommu,
     return -EINVAL;
 }
 
-static void spapr_tce_notify_flag_changed(IOMMUMemoryRegion *iommu,
-                                          IOMMUNotifierFlag old,
-                                          IOMMUNotifierFlag new)
+static int spapr_tce_notify_flag_changed(IOMMUMemoryRegion *iommu,
+                                         IOMMUNotifierFlag old,
+                                         IOMMUNotifierFlag new)
 {
     struct SpaprTceTable *tbl = container_of(iommu, SpaprTceTable, iommu);
 
@@ -216,6 +216,7 @@ static void spapr_tce_notify_flag_changed(IOMMUMemoryRegion *iommu,
     } else if (old != IOMMU_NOTIFIER_NONE && new == IOMMU_NOTIFIER_NONE) {
         spapr_tce_set_need_vfio(tbl, false);
     }
+    return 0;
 }
 
 static int spapr_tce_table_post_load(void *opaque, int version_id)
diff --git a/include/exec/memory.h b/include/exec/memory.h
index 2dd810259d..504c19ecd9 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -288,10 +288,14 @@ typedef struct IOMMUMemoryRegionClass {
      * @iommu: the IOMMUMemoryRegion
      * @old_flags: events which previously needed to be notified
      * @new_flags: events which now need to be notified
+     *
+     * Returns 0 on success, or a negative errno; in particular
+     * returns -EINVAL if the new flag bitmap is not supported by the
+     * IOMMU memory region.
      */
-    void (*notify_flag_changed)(IOMMUMemoryRegion *iommu,
-                                IOMMUNotifierFlag old_flags,
-                                IOMMUNotifierFlag new_flags);
+    int (*notify_flag_changed)(IOMMUMemoryRegion *iommu,
+                               IOMMUNotifierFlag old_flags,
+                               IOMMUNotifierFlag new_flags);
     /* Called to handle memory_region_iommu_replay().
      *
      * The default implementation of memory_region_iommu_replay() is to
@@ -1067,13 +1071,17 @@ void memory_region_notify_one(IOMMUNotifier *notifier,
  * memory_region_register_iommu_notifier: register a notifier for changes to
  * IOMMU translation entries.
  *
+ * Returns 0 on success, or a negative errno otherwise. In particular,
+ * -EINVAL indicates that at least one of the attributes of the notifier
+ * is not supported (flag/range) by the IOMMU memory region.
+ *
  * @mr: the memory region to observe
  * @n: the IOMMUNotifier to be added; the notify callback receives a
  *     pointer to an #IOMMUTLBEntry as the opaque value; the pointer
  *     ceases to be valid on exit from the notifier.
  */
-void memory_region_register_iommu_notifier(MemoryRegion *mr,
-                                           IOMMUNotifier *n);
+int memory_region_register_iommu_notifier(MemoryRegion *mr,
+                                          IOMMUNotifier *n);
 
 /**
  * memory_region_iommu_replay: replay existing IOMMU translations to
diff --git a/memory.c b/memory.c
index 61a254c3f9..699a3d61a6 100644
--- a/memory.c
+++ b/memory.c
@@ -1837,33 +1837,37 @@ bool memory_region_is_logging(MemoryRegion *mr, uint8_t client)
     return memory_region_get_dirty_log_mask(mr) & (1 << client);
 }
 
-static void memory_region_update_iommu_notify_flags(IOMMUMemoryRegion *iommu_mr)
+static int memory_region_update_iommu_notify_flags(IOMMUMemoryRegion *iommu_mr)
 {
     IOMMUNotifierFlag flags = IOMMU_NOTIFIER_NONE;
     IOMMUNotifier *iommu_notifier;
     IOMMUMemoryRegionClass *imrc = IOMMU_MEMORY_REGION_GET_CLASS(iommu_mr);
+    int ret = 0;
 
     IOMMU_NOTIFIER_FOREACH(iommu_notifier, iommu_mr) {
         flags |= iommu_notifier->notifier_flags;
     }
 
     if (flags != iommu_mr->iommu_notify_flags && imrc->notify_flag_changed) {
-        imrc->notify_flag_changed(iommu_mr,
-                                  iommu_mr->iommu_notify_flags,
-                                  flags);
+        ret = imrc->notify_flag_changed(iommu_mr,
+                                        iommu_mr->iommu_notify_flags,
+                                        flags);
     }
 
-    iommu_mr->iommu_notify_flags = flags;
+    if (!ret) {
+        iommu_mr->iommu_notify_flags = flags;
+    }
+    return ret;
 }
 
-void memory_region_register_iommu_notifier(MemoryRegion *mr,
-                                           IOMMUNotifier *n)
+int memory_region_register_iommu_notifier(MemoryRegion *mr,
+                                          IOMMUNotifier *n)
 {
     IOMMUMemoryRegion *iommu_mr;
+    int ret;
 
     if (mr->alias) {
-        memory_region_register_iommu_notifier(mr->alias, n);
-        return;
+        return memory_region_register_iommu_notifier(mr->alias, n);
     }
 
     /* We need to register for at least one bitfield */
@@ -1874,7 +1878,11 @@ void memory_region_register_iommu_notifier(MemoryRegion *mr,
            n->iommu_idx < memory_region_iommu_num_indexes(iommu_mr));
 
     QLIST_INSERT_HEAD(&iommu_mr->iommu_notify, n, node);
-    memory_region_update_iommu_notify_flags(iommu_mr);
+    ret = memory_region_update_iommu_notify_flags(iommu_mr);
+    if (ret) {
+        QLIST_REMOVE(n, node);
+    }
+    return ret;
 }
 
 uint64_t memory_region_iommu_get_min_page_size(IOMMUMemoryRegion *iommu_mr)
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [Qemu-devel] [PATCH v1 2/6] vfio/common: Handle memory_region_register_iommu_notifier() failure
  2019-09-13  8:36 [Qemu-devel] [PATCH v1 0/6] Allow memory_region_register_iommu_notifier() to fail Eric Auger
  2019-09-13  8:36 ` [Qemu-devel] [PATCH v1 1/6] memory: allow " Eric Auger
@ 2019-09-13  8:36 ` Eric Auger
  2019-09-13  8:36 ` [Qemu-devel] [PATCH v1 3/6] exec: assert on " Eric Auger
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 11+ messages in thread
From: Eric Auger @ 2019-09-13  8:36 UTC (permalink / raw)
  To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, peter.maydell,
	pbonzini, alex.williamson, peterx
  Cc: mst

Now memory_region_register_iommu_notifier() is allowed to fail,
let's handle the returned value in vfio_listener_region_add().

This will allow to remove the error handling (exit) in the
IOMMUs that implement a notify_flag_changed() that sometimes
cannot accept the MAP flag.

Signed-off-by: Eric Auger <eric.auger@redhat.com>
---
 hw/vfio/common.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/hw/vfio/common.c b/hw/vfio/common.c
index 3e03c495d8..d57d72cfb9 100644
--- a/hw/vfio/common.c
+++ b/hw/vfio/common.c
@@ -630,9 +630,13 @@ static void vfio_listener_region_add(MemoryListener *listener,
                             section->offset_within_region,
                             int128_get64(llend),
                             iommu_idx);
-        QLIST_INSERT_HEAD(&container->giommu_list, giommu, giommu_next);
 
-        memory_region_register_iommu_notifier(section->mr, &giommu->n);
+        ret = memory_region_register_iommu_notifier(section->mr, &giommu->n);
+        if (ret) {
+            g_free(giommu);
+            goto fail;
+        }
+        QLIST_INSERT_HEAD(&container->giommu_list, giommu, giommu_next);
         memory_region_iommu_replay(giommu->iommu, &giommu->n);
 
         return;
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [Qemu-devel] [PATCH v1 3/6] exec: assert on memory_region_register_iommu_notifier() failure
  2019-09-13  8:36 [Qemu-devel] [PATCH v1 0/6] Allow memory_region_register_iommu_notifier() to fail Eric Auger
  2019-09-13  8:36 ` [Qemu-devel] [PATCH v1 1/6] memory: allow " Eric Auger
  2019-09-13  8:36 ` [Qemu-devel] [PATCH v1 2/6] vfio/common: Handle memory_region_register_iommu_notifier() failure Eric Auger
@ 2019-09-13  8:36 ` Eric Auger
  2019-09-13  9:20   ` Andrew Jones
  2019-09-13  8:36 ` [Qemu-devel] [PATCH v1 4/6] vhost: " Eric Auger
                   ` (2 subsequent siblings)
  5 siblings, 1 reply; 11+ messages in thread
From: Eric Auger @ 2019-09-13  8:36 UTC (permalink / raw)
  To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, peter.maydell,
	pbonzini, alex.williamson, peterx
  Cc: mst

memory_region_register_iommu_notifier now returns an error
in case of failure. Assert in such a case.

Signed-off-by: Eric Auger <eric.auger@redhat.com>
---
 exec.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/exec.c b/exec.c
index 235d6bc883..da30251a2b 100644
--- a/exec.c
+++ b/exec.c
@@ -692,7 +692,8 @@ static void tcg_register_iommu_notifier(CPUState *cpu,
                             0,
                             HWADDR_MAX,
                             iommu_idx);
-        memory_region_register_iommu_notifier(notifier->mr, &notifier->n);
+        assert(!memory_region_register_iommu_notifier(notifier->mr,
+                                                      &notifier->n));
     }
 
     if (!notifier->active) {
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [Qemu-devel] [PATCH v1 4/6] vhost: assert on memory_region_register_iommu_notifier() failure
  2019-09-13  8:36 [Qemu-devel] [PATCH v1 0/6] Allow memory_region_register_iommu_notifier() to fail Eric Auger
                   ` (2 preceding siblings ...)
  2019-09-13  8:36 ` [Qemu-devel] [PATCH v1 3/6] exec: assert on " Eric Auger
@ 2019-09-13  8:36 ` Eric Auger
  2019-09-13  8:36 ` [Qemu-devel] [PATCH v1 5/6] intel_iommu: Let vtd_iommu_notify_flag_changed() fail Eric Auger
  2019-09-13  8:36 ` [Qemu-devel] [PATCH v1 6/6] amd_iommu: Let amdvi_iommu_notify_flag_changed() fail Eric Auger
  5 siblings, 0 replies; 11+ messages in thread
From: Eric Auger @ 2019-09-13  8:36 UTC (permalink / raw)
  To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, peter.maydell,
	pbonzini, alex.williamson, peterx
  Cc: mst

memory_region_register_iommu_notifier now returns an error
in case of failure. Assert in such a case.

Signed-off-by: Eric Auger <eric.auger@redhat.com>
---
 hw/virtio/vhost.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
index 34accdf615..9b5551fc4d 100644
--- a/hw/virtio/vhost.c
+++ b/hw/virtio/vhost.c
@@ -696,7 +696,7 @@ static void vhost_iommu_region_add(MemoryListener *listener,
     iommu->iommu_offset = section->offset_within_address_space -
                           section->offset_within_region;
     iommu->hdev = dev;
-    memory_region_register_iommu_notifier(section->mr, &iommu->n);
+    assert(!memory_region_register_iommu_notifier(section->mr, &iommu->n));
     QLIST_INSERT_HEAD(&dev->iommu_list, iommu, iommu_next);
     /* TODO: can replay help performance here? */
 }
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [Qemu-devel] [PATCH v1 5/6] intel_iommu: Let vtd_iommu_notify_flag_changed() fail
  2019-09-13  8:36 [Qemu-devel] [PATCH v1 0/6] Allow memory_region_register_iommu_notifier() to fail Eric Auger
                   ` (3 preceding siblings ...)
  2019-09-13  8:36 ` [Qemu-devel] [PATCH v1 4/6] vhost: " Eric Auger
@ 2019-09-13  8:36 ` Eric Auger
  2019-09-16  3:33   ` Peter Xu
  2019-09-13  8:36 ` [Qemu-devel] [PATCH v1 6/6] amd_iommu: Let amdvi_iommu_notify_flag_changed() fail Eric Auger
  5 siblings, 1 reply; 11+ messages in thread
From: Eric Auger @ 2019-09-13  8:36 UTC (permalink / raw)
  To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, peter.maydell,
	pbonzini, alex.williamson, peterx
  Cc: mst

In case a MAP notifier is attempted to be registered without
caching mode, let's simply return an error. This latter now is
handled in the VFIO code.

Signed-off-by: Eric Auger <eric.auger@redhat.com>
---
 hw/i386/intel_iommu.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
index 7a89ea9ba1..2f66d6882c 100644
--- a/hw/i386/intel_iommu.c
+++ b/hw/i386/intel_iommu.c
@@ -2931,7 +2931,7 @@ static int vtd_iommu_notify_flag_changed(IOMMUMemoryRegion *iommu,
     if (!s->caching_mode && new & IOMMU_NOTIFIER_MAP) {
         error_report("We need to set caching-mode=on for intel-iommu to enable "
                      "device assignment with IOMMU protection.");
-        exit(1);
+        return -EINVAL;
     }
 
     /* Update per-address-space notifier flags */
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [Qemu-devel] [PATCH v1 6/6] amd_iommu: Let amdvi_iommu_notify_flag_changed() fail
  2019-09-13  8:36 [Qemu-devel] [PATCH v1 0/6] Allow memory_region_register_iommu_notifier() to fail Eric Auger
                   ` (4 preceding siblings ...)
  2019-09-13  8:36 ` [Qemu-devel] [PATCH v1 5/6] intel_iommu: Let vtd_iommu_notify_flag_changed() fail Eric Auger
@ 2019-09-13  8:36 ` Eric Auger
  5 siblings, 0 replies; 11+ messages in thread
From: Eric Auger @ 2019-09-13  8:36 UTC (permalink / raw)
  To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, peter.maydell,
	pbonzini, alex.williamson, peterx
  Cc: mst

In case a MAP notifier is attempted to be registered,
let's simply return an error. This latter now is
handled in the VFIO code.

Signed-off-by: Eric Auger <eric.auger@redhat.com>
---
 hw/i386/amd_iommu.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/i386/amd_iommu.c b/hw/i386/amd_iommu.c
index 137ba367db..09dee48fac 100644
--- a/hw/i386/amd_iommu.c
+++ b/hw/i386/amd_iommu.c
@@ -1476,7 +1476,7 @@ static int amdvi_iommu_notify_flag_changed(IOMMUMemoryRegion *iommu,
         error_report("device %02x.%02x.%x requires iommu notifier which is not "
                      "currently supported", as->bus_num, PCI_SLOT(as->devfn),
                      PCI_FUNC(as->devfn));
-        exit(1);
+        return -EINVAL;
     }
     return 0;
 }
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [Qemu-devel] [PATCH v1 3/6] exec: assert on memory_region_register_iommu_notifier() failure
  2019-09-13  8:36 ` [Qemu-devel] [PATCH v1 3/6] exec: assert on " Eric Auger
@ 2019-09-13  9:20   ` Andrew Jones
  0 siblings, 0 replies; 11+ messages in thread
From: Andrew Jones @ 2019-09-13  9:20 UTC (permalink / raw)
  To: Eric Auger
  Cc: peter.maydell, mst, qemu-devel, peterx, alex.williamson,
	qemu-arm, pbonzini, eric.auger.pro

On Fri, Sep 13, 2019 at 10:36:12AM +0200, Eric Auger wrote:
> memory_region_register_iommu_notifier now returns an error
> in case of failure. Assert in such a case.
> 
> Signed-off-by: Eric Auger <eric.auger@redhat.com>
> ---
>  exec.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/exec.c b/exec.c
> index 235d6bc883..da30251a2b 100644
> --- a/exec.c
> +++ b/exec.c
> @@ -692,7 +692,8 @@ static void tcg_register_iommu_notifier(CPUState *cpu,
>                              0,
>                              HWADDR_MAX,
>                              iommu_idx);
> -        memory_region_register_iommu_notifier(notifier->mr, &notifier->n);
> +        assert(!memory_region_register_iommu_notifier(notifier->mr,
> +                                                      &notifier->n));

 ret = memory_region_register_iommu_notifier(notifier->mr, &notifier->n);
 assert(!ret);

to avoid functions with side effects being called inside assert()'s, as
assert()'s could be compiled as no-ops.

Same comment for next patch.

Thanks,
drew

>      }
>  
>      if (!notifier->active) {
> -- 
> 2.20.1
> 
> 


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Qemu-devel] [PATCH v1 1/6] memory: allow memory_region_register_iommu_notifier() to fail
  2019-09-13  8:36 ` [Qemu-devel] [PATCH v1 1/6] memory: allow " Eric Auger
@ 2019-09-16  3:23   ` Peter Xu
  2019-09-19 11:45     ` Auger Eric
  0 siblings, 1 reply; 11+ messages in thread
From: Peter Xu @ 2019-09-16  3:23 UTC (permalink / raw)
  To: Eric Auger
  Cc: peter.maydell, mst, qemu-devel, alex.williamson, qemu-arm,
	pbonzini, eric.auger.pro

On Fri, Sep 13, 2019 at 10:36:10AM +0200, Eric Auger wrote:
> Currently, when a notifier is attempted to be registered and its
> flags are not supported (especially the MAP one) by the IOMMU MR,
> we generally abruptly exit in the IOMMU code. The failure could be
> handled more nicely in the caller and especially in the VFIO code.
> 
> So let's allow memory_region_register_iommu_notifier() to fail as
> well as notify_flag_changed() callback.
> 
> All sites implementing the callback are updated. This patch does
> not yet remove the exit(1) in the intel_iommu and amd_iommu code.

The idea looks sane to me, though how about using "Error **" instead
of returning int (or, both)?  Just like the majority of rest of QEMU.

Regards,

-- 
Peter Xu


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Qemu-devel] [PATCH v1 5/6] intel_iommu: Let vtd_iommu_notify_flag_changed() fail
  2019-09-13  8:36 ` [Qemu-devel] [PATCH v1 5/6] intel_iommu: Let vtd_iommu_notify_flag_changed() fail Eric Auger
@ 2019-09-16  3:33   ` Peter Xu
  0 siblings, 0 replies; 11+ messages in thread
From: Peter Xu @ 2019-09-16  3:33 UTC (permalink / raw)
  To: Eric Auger
  Cc: peter.maydell, mst, qemu-devel, alex.williamson, qemu-arm,
	pbonzini, eric.auger.pro

On Fri, Sep 13, 2019 at 10:36:14AM +0200, Eric Auger wrote:
> In case a MAP notifier is attempted to be registered without
> caching mode, let's simply return an error. This latter now is
> handled in the VFIO code.
> 
> Signed-off-by: Eric Auger <eric.auger@redhat.com>
> ---
>  hw/i386/intel_iommu.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
> index 7a89ea9ba1..2f66d6882c 100644
> --- a/hw/i386/intel_iommu.c
> +++ b/hw/i386/intel_iommu.c
> @@ -2931,7 +2931,7 @@ static int vtd_iommu_notify_flag_changed(IOMMUMemoryRegion *iommu,
>      if (!s->caching_mode && new & IOMMU_NOTIFIER_MAP) {
>          error_report("We need to set caching-mode=on for intel-iommu to enable "
>                       "device assignment with IOMMU protection.");
> -        exit(1);
> +        return -EINVAL;

This might be conflicting with the other series because that's going
to drop these lines:

https://lists.gnu.org/archive/html/qemu-devel/2019-08/msg01968.html

Though current change looks ok to me, and I don't even know which one
will reach master earlier after all so let's see. :)

The rest patches besides patch 1 all look sane to me. If we're going
to have "Error **" then the rest patches might need trivial touch-ups
of course.  And, IMHO squashing the whole series into patch 1 could be
better, but it's a personal preference only.

Thanks,

-- 
Peter Xu


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Qemu-devel] [PATCH v1 1/6] memory: allow memory_region_register_iommu_notifier() to fail
  2019-09-16  3:23   ` Peter Xu
@ 2019-09-19 11:45     ` Auger Eric
  0 siblings, 0 replies; 11+ messages in thread
From: Auger Eric @ 2019-09-19 11:45 UTC (permalink / raw)
  To: Peter Xu
  Cc: peter.maydell, mst, qemu-devel, alex.williamson, qemu-arm,
	pbonzini, eric.auger.pro

Hi Peter,

On 9/16/19 5:23 AM, Peter Xu wrote:
> On Fri, Sep 13, 2019 at 10:36:10AM +0200, Eric Auger wrote:
>> Currently, when a notifier is attempted to be registered and its
>> flags are not supported (especially the MAP one) by the IOMMU MR,
>> we generally abruptly exit in the IOMMU code. The failure could be
>> handled more nicely in the caller and especially in the VFIO code.
>>
>> So let's allow memory_region_register_iommu_notifier() to fail as
>> well as notify_flag_changed() callback.
>>
>> All sites implementing the callback are updated. This patch does
>> not yet remove the exit(1) in the intel_iommu and amd_iommu code.
> 
> The idea looks sane to me, though how about using "Error **" instead
> of returning int (or, both)?  Just like the majority of rest of QEMU.
None of the memory_region_register_iommu_notifier callsites would really
use the Error object and pass it up. I am a bit reluctant to add it if
not really used. There are still plenty of functions in the memory API
that do not use any Error handle. Anyway I will follow recommendations
if there is a consensus.

Thanks

Eric
> 
> Regards,
> 


^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2019-09-19 11:58 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-09-13  8:36 [Qemu-devel] [PATCH v1 0/6] Allow memory_region_register_iommu_notifier() to fail Eric Auger
2019-09-13  8:36 ` [Qemu-devel] [PATCH v1 1/6] memory: allow " Eric Auger
2019-09-16  3:23   ` Peter Xu
2019-09-19 11:45     ` Auger Eric
2019-09-13  8:36 ` [Qemu-devel] [PATCH v1 2/6] vfio/common: Handle memory_region_register_iommu_notifier() failure Eric Auger
2019-09-13  8:36 ` [Qemu-devel] [PATCH v1 3/6] exec: assert on " Eric Auger
2019-09-13  9:20   ` Andrew Jones
2019-09-13  8:36 ` [Qemu-devel] [PATCH v1 4/6] vhost: " Eric Auger
2019-09-13  8:36 ` [Qemu-devel] [PATCH v1 5/6] intel_iommu: Let vtd_iommu_notify_flag_changed() fail Eric Auger
2019-09-16  3:33   ` Peter Xu
2019-09-13  8:36 ` [Qemu-devel] [PATCH v1 6/6] amd_iommu: Let amdvi_iommu_notify_flag_changed() fail Eric Auger

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).