qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Alex Williamson <alex.williamson@redhat.com>
To: qemu-devel@nongnu.org
Cc: Laurent Vivier <lvivier@redhat.com>,
	Paolo Bonzini <pbonzini@redhat.com>,
	David Gibson <david@gibson.dropbear.id.au>
Subject: [Qemu-devel] [PULL 08/10] memory: Allow replay of IOMMU mapping notifications
Date: Mon, 05 Oct 2015 14:37:42 -0600	[thread overview]
Message-ID: <20151005203739.310.15495.stgit@gimli.home> (raw)
In-Reply-To: <20151005203357.310.44414.stgit@gimli.home>

From: David Gibson <david@gibson.dropbear.id.au>

When we have guest visible IOMMUs, we allow notifiers to be registered
which will be informed of all changes to IOMMU mappings.  This is used by
vfio to keep the host IOMMU mappings in sync with guest IOMMU mappings.

However, unlike with a memory region listener, an iommu notifier won't be
told about any mappings which already exist in the (guest) IOMMU at the
time it is registered.  This can cause problems if hotplugging a VFIO
device onto a guest bus which had existing guest IOMMU mappings, but didn't
previously have an VFIO devices (and hence no host IOMMU mappings).

This adds a memory_region_iommu_replay() function to handle this case.  It
replays any existing mappings in an IOMMU memory region to a specified
notifier.  Because the IOMMU memory region doesn't internally remember the
granularity of the guest IOMMU it has a small hack where the caller must
specify a granularity at which to replay mappings.

If there are finer mappings in the guest IOMMU these will be reported in
the iotlb structures passed to the notifier which it must handle (probably
causing it to flag an error).  This isn't new - the VFIO iommu notifier
must already handle notifications about guest IOMMU mappings too short
for it to represent in the host IOMMU.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Reviewed-by: Laurent Vivier <lvivier@redhat.com>
Acked-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
---
 include/exec/memory.h |   13 +++++++++++++
 memory.c              |   20 ++++++++++++++++++++
 2 files changed, 33 insertions(+)

diff --git a/include/exec/memory.h b/include/exec/memory.h
index 5baaf48..0f07159 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -583,6 +583,19 @@ void memory_region_notify_iommu(MemoryRegion *mr,
 void memory_region_register_iommu_notifier(MemoryRegion *mr, Notifier *n);
 
 /**
+ * memory_region_iommu_replay: replay existing IOMMU translations to
+ * a notifier
+ *
+ * @mr: the memory region to observe
+ * @n: the notifier to which to replay iommu mappings
+ * @granularity: Minimum page granularity to replay notifications for
+ * @is_write: Whether to treat the replay as a translate "write"
+ *     through the iommu
+ */
+void memory_region_iommu_replay(MemoryRegion *mr, Notifier *n,
+                                hwaddr granularity, bool is_write);
+
+/**
  * memory_region_unregister_iommu_notifier: unregister a notifier for
  * changes to IOMMU translation entries.
  *
diff --git a/memory.c b/memory.c
index ef87363..1b03d22 100644
--- a/memory.c
+++ b/memory.c
@@ -1403,6 +1403,26 @@ void memory_region_register_iommu_notifier(MemoryRegion *mr, Notifier *n)
     notifier_list_add(&mr->iommu_notify, n);
 }
 
+void memory_region_iommu_replay(MemoryRegion *mr, Notifier *n,
+                                hwaddr granularity, bool is_write)
+{
+    hwaddr addr;
+    IOMMUTLBEntry iotlb;
+
+    for (addr = 0; addr < memory_region_size(mr); addr += granularity) {
+        iotlb = mr->iommu_ops->translate(mr, addr, is_write);
+        if (iotlb.perm != IOMMU_NONE) {
+            n->notify(n, &iotlb);
+        }
+
+        /* if (2^64 - MR size) < granularity, it's possible to get an
+         * infinite loop here.  This should catch such a wraparound */
+        if ((addr + granularity) < addr) {
+            break;
+        }
+    }
+}
+
 void memory_region_unregister_iommu_notifier(Notifier *n)
 {
     notifier_remove(n);

  parent reply	other threads:[~2015-10-05 20:37 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-10-05 20:36 [Qemu-devel] [PULL 00/10] VFIO updates for 2015-10-05 Alex Williamson
2015-10-05 20:36 ` [Qemu-devel] [PULL 01/10] hw/vfio/platform: irqfd setup sequence update Alex Williamson
2015-10-05 20:36 ` [Qemu-devel] [PULL 02/10] hw/vfio/platform: change interrupt/unmask fields into pointer Alex Williamson
2015-10-05 20:36 ` [Qemu-devel] [PULL 03/10] hw/vfio/platform: do not set resamplefd for edge-sensitive IRQS Alex Williamson
2015-10-05 20:37 ` [Qemu-devel] [PULL 04/10] vfio: Remove unneeded union from VFIOContainer Alex Williamson
2015-10-05 20:37 ` [Qemu-devel] [PULL 05/10] vfio: Generalize vfio_listener_region_add failure path Alex Williamson
2015-10-05 20:37 ` [Qemu-devel] [PULL 06/10] vfio: Check guest IOVA ranges against host IOMMU capabilities Alex Williamson
2015-10-05 20:37 ` [Qemu-devel] [PULL 07/10] vfio: Record host IOMMU's available IO page sizes Alex Williamson
2015-10-05 20:37 ` Alex Williamson [this message]
2015-10-05 20:37 ` [Qemu-devel] [PULL 09/10] vfio: Allow hotplug of containers onto existing guest IOMMU mappings Alex Williamson
2015-10-05 20:37 ` [Qemu-devel] [PULL 10/10] vfio: Expose a VFIO PCI device's group for EEH Alex Williamson
2015-10-06 14:50 ` [Qemu-devel] [PULL 00/10] VFIO updates for 2015-10-05 Peter Maydell
2015-10-06 15:35   ` Alex Williamson
2015-10-06 23:31     ` David Gibson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20151005203739.310.15495.stgit@gimli.home \
    --to=alex.williamson@redhat.com \
    --cc=david@gibson.dropbear.id.au \
    --cc=lvivier@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).