qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Peter Xu <peterx@redhat.com>
To: qemu-devel@nongnu.org
Cc: tianyu.lan@intel.com, kevin.tian@intel.com, mst@redhat.com,
	jan.kiszka@siemens.com, bd.aviv@gmail.com, peterx@redhat.com,
	alex.williamson@redhat.com, jasowang@redhat.com
Subject: [Qemu-devel] [RFC PATCH 13/13] intel_iommu: use page_walk for iotlb inv notify
Date: Tue,  6 Dec 2016 18:36:28 +0800	[thread overview]
Message-ID: <1481020588-4245-14-git-send-email-peterx@redhat.com> (raw)
In-Reply-To: <1481020588-4245-1-git-send-email-peterx@redhat.com>

Instead of translate() every page for iotlb invalidations (which is
slower), we walk the pages when needed and notify in a hook function.
This will also simplify the code a bit.

Signed-off-by: Peter Xu <peterx@redhat.com>
---
 hw/i386/intel_iommu.c | 64 +++++++++++++++------------------------------------
 1 file changed, 19 insertions(+), 45 deletions(-)

diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
index 0220e63..226dbcd 100644
--- a/hw/i386/intel_iommu.c
+++ b/hw/i386/intel_iommu.c
@@ -149,23 +149,6 @@ static uint64_t vtd_set_clear_mask_quad(IntelIOMMUState *s, hwaddr addr,
     return new_val;
 }
 
-static int vtd_get_did_dev(IntelIOMMUState *s, uint8_t bus_num, uint8_t devfn,
-                           uint16_t *domain_id)
-{
-    VTDContextEntry ce;
-    int ret_fr;
-
-    assert(domain_id);
-
-    ret_fr = vtd_dev_to_context_entry(s, bus_num, devfn, &ce);
-    if (ret_fr) {
-        return -1;
-    }
-
-    *domain_id =  VTD_CONTEXT_ENTRY_DID(ce.hi);
-    return 0;
-}
-
 /* GHashTable functions */
 static gboolean vtd_uint64_equal(gconstpointer v1, gconstpointer v2)
 {
@@ -868,7 +851,8 @@ next:
  * @private: private data for the hook function
  */
 static int vtd_page_walk(VTDContextEntry *ce, uint64_t start, uint64_t end,
-                         vtd_page_walk_hook hook_fn, void *private)
+                         vtd_page_walk_hook hook_fn, void *private,
+                         bool notify_unmap)
 {
     dma_addr_t addr = vtd_get_slpt_base_from_context(ce);
     uint32_t level = vtd_get_level_from_context_entry(ce);
@@ -887,7 +871,7 @@ static int vtd_page_walk(VTDContextEntry *ce, uint64_t start, uint64_t end,
     trace_vtd_page_walk(ce->hi, ce->lo, start, end);
 
     return vtd_page_walk_level(addr, start, end, hook_fn, private,
-                               level, true, true, NULL, false);
+                               level, true, true, NULL, notify_unmap);
 }
 
 /* Map a device to its corresponding domain (context-entry) */
@@ -1238,39 +1222,29 @@ static void vtd_iotlb_domain_invalidate(IntelIOMMUState *s, uint16_t domain_id)
                                 &domain_id);
 }
 
+static int vtd_page_invalidate_notify_hook(IOMMUTLBEntry *entry,
+                                           void *private)
+{
+    memory_region_notify_iommu((MemoryRegion *)private, *entry);
+    return 0;
+}
+
 static void vtd_iotlb_page_invalidate_notify(IntelIOMMUState *s,
                                            uint16_t domain_id, hwaddr addr,
                                            uint8_t am)
 {
     IntelIOMMUNotifierNode *node;
+    VTDContextEntry ce;
+    int ret;
 
     QLIST_FOREACH(node, &(s->notifiers_list), next) {
         VTDAddressSpace *vtd_as = node->vtd_as;
-        uint16_t vfio_domain_id;
-        int ret = vtd_get_did_dev(s, pci_bus_num(vtd_as->bus), vtd_as->devfn,
-                                  &vfio_domain_id);
-        if (!ret && domain_id == vfio_domain_id) {
-            hwaddr original_addr = addr;
-
-            while (addr < original_addr + (1 << am) * VTD_PAGE_SIZE) {
-                IOMMUTLBEntry entry = s->iommu_ops.translate(
-                                                         &node->vtd_as->iommu,
-                                                         addr,
-                                                         IOMMU_NO_FAIL);
-
-                if (entry.perm == IOMMU_NONE &&
-                        node->notifier_flag & IOMMU_NOTIFIER_UNMAP) {
-                    entry.target_as = &address_space_memory;
-                    entry.iova = addr & VTD_PAGE_MASK_4K;
-                    entry.translated_addr = 0;
-                    entry.addr_mask = ~VTD_PAGE_MASK(VTD_PAGE_SHIFT);
-                    memory_region_notify_iommu(&node->vtd_as->iommu, entry);
-                    addr += VTD_PAGE_SIZE;
-                } else if (node->notifier_flag & IOMMU_NOTIFIER_MAP) {
-                        memory_region_notify_iommu(&node->vtd_as->iommu, entry);
-                        addr += entry.addr_mask + 1;
-                }
-            }
+        ret = vtd_dev_to_context_entry(s, pci_bus_num(vtd_as->bus),
+                                       vtd_as->devfn, &ce);
+        if (!ret && domain_id == VTD_CONTEXT_ENTRY_DID(ce.hi)) {
+            vtd_page_walk(&ce, addr, addr + (1 << am) * VTD_PAGE_SIZE,
+                          vtd_page_invalidate_notify_hook,
+                          (void *)&vtd_as->iommu, true);
         }
     }
 }
@@ -2623,7 +2597,7 @@ static void vtd_iommu_replay(MemoryRegion *mr, IOMMUNotifier *n)
          */
         trace_vtd_replay_ce_valid(bus_n, PCI_SLOT(vtd_as->devfn),
                                   PCI_FUNC(vtd_as->devfn), ce.hi, ce.lo);
-        vtd_page_walk(&ce, 0, ~0, vtd_replay_hook, (void *)n);
+        vtd_page_walk(&ce, 0, ~0, vtd_replay_hook, (void *)n, false);
     } else {
         trace_vtd_replay_ce_invalid(bus_n, PCI_SLOT(vtd_as->devfn),
                                     PCI_FUNC(vtd_as->devfn));
-- 
2.7.4

  parent reply	other threads:[~2016-12-06 10:37 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-12-06 10:36 [Qemu-devel] [RFC PATCH 00/13] VT-d replay and misc cleanup Peter Xu
2016-12-06 10:36 ` [Qemu-devel] [RFC PATCH 01/13] intel_iommu: allocate new key when creating new address space Peter Xu
2016-12-12  8:16   ` Liu, Yi L
2016-12-14  3:05     ` Peter Xu
2016-12-14  3:24       ` Liu, Yi L
2016-12-06 10:36 ` [Qemu-devel] [RFC PATCH 02/13] intel_iommu: simplify irq region translation Peter Xu
2016-12-06 10:36 ` [Qemu-devel] [RFC PATCH 03/13] intel_iommu: renaming gpa to iova where proper Peter Xu
2016-12-18  8:39   ` Liu, Yi L
2016-12-19  9:23     ` Peter Xu
2016-12-06 10:36 ` [Qemu-devel] [RFC PATCH 04/13] intel_iommu: fix trace for inv desc handling Peter Xu
2016-12-06 10:36 ` [Qemu-devel] [RFC PATCH 05/13] intel_iommu: fix trace for addr translation Peter Xu
2016-12-06 10:36 ` [Qemu-devel] [RFC PATCH 06/13] intel_iommu: vtd_slpt_level_shift check level Peter Xu
2016-12-06 10:36 ` [Qemu-devel] [RFC PATCH 07/13] memory: add section range info for IOMMU notifier Peter Xu
2016-12-06 10:36 ` [Qemu-devel] [RFC PATCH 08/13] memory: provide iommu_replay_all() Peter Xu
2016-12-06 10:36 ` [Qemu-devel] [RFC PATCH 09/13] memory: introduce memory_region_notify_one() Peter Xu
2016-12-06 10:36 ` [Qemu-devel] [RFC PATCH 10/13] memory: add MemoryRegionIOMMUOps.replay() callback Peter Xu
2016-12-06 10:36 ` [Qemu-devel] [RFC PATCH 11/13] intel_iommu: provide its own replay() callback Peter Xu
2016-12-08  3:01   ` Lan Tianyu
2016-12-09  1:56     ` Peter Xu
2016-12-06 10:36 ` [Qemu-devel] [RFC PATCH 12/13] intel_iommu: do replay when context invalidate Peter Xu
2016-12-06 10:36 ` Peter Xu [this message]
2016-12-06 10:49 ` [Qemu-devel] [RFC PATCH 00/13] VT-d replay and misc cleanup Peter Xu
2016-12-13  7:45 ` Peter Xu
2016-12-18  8:42 ` Liu, Yi L
2016-12-19  9:22   ` Peter Xu
2016-12-19 11:25     ` Liu, Yi L
2016-12-19  9:33 ` Peter Xu

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=1481020588-4245-14-git-send-email-peterx@redhat.com \
    --to=peterx@redhat.com \
    --cc=alex.williamson@redhat.com \
    --cc=bd.aviv@gmail.com \
    --cc=jan.kiszka@siemens.com \
    --cc=jasowang@redhat.com \
    --cc=kevin.tian@intel.com \
    --cc=mst@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=tianyu.lan@intel.com \
    /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).