All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Michael S. Tsirkin" <mst@redhat.com>
To: qemu-devel@nongnu.org
Cc: Peter Maydell <peter.maydell@linaro.org>,
	Peter Xu <peterx@redhat.com>,
	QEMU Stable <qemu-stable@nongnu.org>,
	Paolo Bonzini <pbonzini@redhat.com>,
	Richard Henderson <rth@twiddle.net>,
	Eduardo Habkost <ehabkost@redhat.com>,
	Marcel Apfelbaum <marcel.apfelbaum@gmail.com>
Subject: [Qemu-devel] [PULL 24/28] intel-iommu: introduce vtd_page_walk_info
Date: Wed, 23 May 2018 17:43:22 +0300	[thread overview]
Message-ID: <1527086545-68024-25-git-send-email-mst@redhat.com> (raw)
In-Reply-To: <1527086545-68024-1-git-send-email-mst@redhat.com>

From: Peter Xu <peterx@redhat.com>

During the recursive page walking of IOVA page tables, some stack
variables are constant variables and never changed during the whole page
walking procedure.  Isolate them into a struct so that we don't need to
pass those contants down the stack every time and multiple times.

CC: QEMU Stable <qemu-stable@nongnu.org>
Signed-off-by: Peter Xu <peterx@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
 hw/i386/intel_iommu.c | 84 +++++++++++++++++++++++++++++++--------------------
 1 file changed, 52 insertions(+), 32 deletions(-)

diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
index 38ccc74..e247269 100644
--- a/hw/i386/intel_iommu.c
+++ b/hw/i386/intel_iommu.c
@@ -748,9 +748,27 @@ static int vtd_iova_to_slpte(VTDContextEntry *ce, uint64_t iova, bool is_write,
 
 typedef int (*vtd_page_walk_hook)(IOMMUTLBEntry *entry, void *private);
 
+/**
+ * Constant information used during page walking
+ *
+ * @hook_fn: hook func to be called when detected page
+ * @private: private data to be passed into hook func
+ * @notify_unmap: whether we should notify invalid entries
+ * @aw: maximum address width
+ */
+typedef struct {
+    vtd_page_walk_hook hook_fn;
+    void *private;
+    bool notify_unmap;
+    uint8_t aw;
+} vtd_page_walk_info;
+
 static int vtd_page_walk_one(IOMMUTLBEntry *entry, int level,
-                             vtd_page_walk_hook hook_fn, void *private)
+                             vtd_page_walk_info *info)
 {
+    vtd_page_walk_hook hook_fn = info->hook_fn;
+    void *private = info->private;
+
     assert(hook_fn);
     trace_vtd_page_walk_one(level, entry->iova, entry->translated_addr,
                             entry->addr_mask, entry->perm);
@@ -763,17 +781,13 @@ static int vtd_page_walk_one(IOMMUTLBEntry *entry, int level,
  * @addr: base GPA addr to start the walk
  * @start: IOVA range start address
  * @end: IOVA range end address (start <= addr < end)
- * @hook_fn: hook func to be called when detected page
- * @private: private data to be passed into hook func
  * @read: whether parent level has read permission
  * @write: whether parent level has write permission
- * @notify_unmap: whether we should notify invalid entries
- * @aw: maximum address width
+ * @info: constant information for the page walk
  */
 static int vtd_page_walk_level(dma_addr_t addr, uint64_t start,
-                               uint64_t end, vtd_page_walk_hook hook_fn,
-                               void *private, uint32_t level, bool read,
-                               bool write, bool notify_unmap, uint8_t aw)
+                               uint64_t end, uint32_t level, bool read,
+                               bool write, vtd_page_walk_info *info)
 {
     bool read_cur, write_cur, entry_valid;
     uint32_t offset;
@@ -823,24 +837,24 @@ static int vtd_page_walk_level(dma_addr_t addr, uint64_t start,
 
         if (vtd_is_last_slpte(slpte, level)) {
             /* NOTE: this is only meaningful if entry_valid == true */
-            entry.translated_addr = vtd_get_slpte_addr(slpte, aw);
-            if (!entry_valid && !notify_unmap) {
+            entry.translated_addr = vtd_get_slpte_addr(slpte, info->aw);
+            if (!entry_valid && !info->notify_unmap) {
                 trace_vtd_page_walk_skip_perm(iova, iova_next);
                 goto next;
             }
-            ret = vtd_page_walk_one(&entry, level, hook_fn, private);
+            ret = vtd_page_walk_one(&entry, level, info);
             if (ret < 0) {
                 return ret;
             }
         } else {
             if (!entry_valid) {
-                if (notify_unmap) {
+                if (info->notify_unmap) {
                     /*
                      * The whole entry is invalid; unmap it all.
                      * Translated address is meaningless, zero it.
                      */
                     entry.translated_addr = 0x0;
-                    ret = vtd_page_walk_one(&entry, level, hook_fn, private);
+                    ret = vtd_page_walk_one(&entry, level, info);
                     if (ret < 0) {
                         return ret;
                     }
@@ -849,10 +863,9 @@ static int vtd_page_walk_level(dma_addr_t addr, uint64_t start,
                 }
                 goto next;
             }
-            ret = vtd_page_walk_level(vtd_get_slpte_addr(slpte, aw), iova,
-                                      MIN(iova_next, end), hook_fn, private,
-                                      level - 1, read_cur, write_cur,
-                                      notify_unmap, aw);
+            ret = vtd_page_walk_level(vtd_get_slpte_addr(slpte, info->aw),
+                                      iova, MIN(iova_next, end), level - 1,
+                                      read_cur, write_cur, info);
             if (ret < 0) {
                 return ret;
             }
@@ -871,28 +884,24 @@ next:
  * @ce: context entry to walk upon
  * @start: IOVA address to start the walk
  * @end: IOVA range end address (start <= addr < end)
- * @hook_fn: the hook that to be called for each detected area
- * @private: private data for the hook function
- * @aw: maximum address width
+ * @info: page walking information struct
  */
 static int vtd_page_walk(VTDContextEntry *ce, uint64_t start, uint64_t end,
-                         vtd_page_walk_hook hook_fn, void *private,
-                         bool notify_unmap, uint8_t aw)
+                         vtd_page_walk_info *info)
 {
     dma_addr_t addr = vtd_ce_get_slpt_base(ce);
     uint32_t level = vtd_ce_get_level(ce);
 
-    if (!vtd_iova_range_check(start, ce, aw)) {
+    if (!vtd_iova_range_check(start, ce, info->aw)) {
         return -VTD_FR_ADDR_BEYOND_MGAW;
     }
 
-    if (!vtd_iova_range_check(end, ce, aw)) {
+    if (!vtd_iova_range_check(end, ce, info->aw)) {
         /* Fix end so that it reaches the maximum */
-        end = vtd_iova_limit(ce, aw);
+        end = vtd_iova_limit(ce, info->aw);
     }
 
-    return vtd_page_walk_level(addr, start, end, hook_fn, private,
-                               level, true, true, notify_unmap, aw);
+    return vtd_page_walk_level(addr, start, end, level, true, true, info);
 }
 
 /* Map a device to its corresponding domain (context-entry) */
@@ -1449,14 +1458,19 @@ static void vtd_iotlb_page_invalidate_notify(IntelIOMMUState *s,
                                        vtd_as->devfn, &ce);
         if (!ret && domain_id == VTD_CONTEXT_ENTRY_DID(ce.hi)) {
             if (vtd_as_has_map_notifier(vtd_as)) {
+                vtd_page_walk_info info = {
+                    .hook_fn = vtd_page_invalidate_notify_hook,
+                    .private = (void *)&vtd_as->iommu,
+                    .notify_unmap = true,
+                    .aw = s->aw_bits,
+                };
+
                 /*
                  * As long as we have MAP notifications registered in
                  * any of our IOMMU notifiers, we need to sync the
                  * shadow page table.
                  */
-                vtd_page_walk(&ce, addr, addr + size,
-                              vtd_page_invalidate_notify_hook,
-                              (void *)&vtd_as->iommu, true, s->aw_bits);
+                vtd_page_walk(&ce, addr, addr + size, &info);
             } else {
                 /*
                  * For UNMAP-only notifiers, we don't need to walk the
@@ -2924,8 +2938,14 @@ static void vtd_iommu_replay(IOMMUMemoryRegion *iommu_mr, IOMMUNotifier *n)
                                   ce.hi, ce.lo);
         if (vtd_as_has_map_notifier(vtd_as)) {
             /* This is required only for MAP typed notifiers */
-            vtd_page_walk(&ce, 0, ~0ULL, vtd_replay_hook, (void *)n, false,
-                          s->aw_bits);
+            vtd_page_walk_info info = {
+                .hook_fn = vtd_replay_hook,
+                .private = (void *)n,
+                .notify_unmap = false,
+                .aw = s->aw_bits,
+            };
+
+            vtd_page_walk(&ce, 0, ~0ULL, &info);
         }
     } else {
         trace_vtd_replay_ce_invalid(bus_n, PCI_SLOT(vtd_as->devfn),
-- 
MST

  parent reply	other threads:[~2018-05-23 14:43 UTC|newest]

Thread overview: 52+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-05-23 14:42 [Qemu-devel] [PULL 00/28] pc, pci, virtio, vhost: fixes, features Michael S. Tsirkin
2018-05-23 14:42 ` [Qemu-devel] [PULL 01/28] hw/pci-host/q35: Replace hardcoded value with macro Michael S. Tsirkin
2018-05-23 14:42 ` [Qemu-devel] [PULL 02/28] allocate pci id for mdpy Michael S. Tsirkin
2018-05-23 14:42 ` [Qemu-devel] [PULL 04/28] vhost: add trace for IOTLB miss Michael S. Tsirkin
2018-05-23 14:42 ` [Qemu-devel] [PULL 03/28] virtio-balloon: add hugetlb page allocation counts Michael S. Tsirkin
2018-05-23 14:42 ` [Qemu-devel] [PULL 05/28] update-linux-headers.sh: drop kvm_para.h hacks Michael S. Tsirkin
2018-05-23 14:42 ` [Qemu-devel] [PULL 06/28] include/standard-headers: add asm-x86/kvm_para.h Michael S. Tsirkin
2018-05-23 14:43 ` [PULL 07/28] x86/cpu: use standard-headers/asm-x86.kvm_para.h Michael S. Tsirkin
2018-05-23 14:43   ` [Qemu-devel] " Michael S. Tsirkin
2018-05-25 11:06   ` Peter Maydell
2018-05-25 11:06     ` [Qemu-devel] " Peter Maydell
2018-05-25 11:53     ` Peter Maydell
2018-05-25 11:53       ` [Qemu-devel] " Peter Maydell
2018-05-25 12:18       ` Michael S. Tsirkin
2018-05-25 12:18         ` [Qemu-devel] " Michael S. Tsirkin
2018-05-25 12:21         ` Peter Maydell
2018-05-25 12:21           ` [Qemu-devel] " Peter Maydell
2018-05-25 12:27           ` Michael S. Tsirkin
2018-05-25 12:27             ` [Qemu-devel] " Michael S. Tsirkin
2018-05-25 12:30             ` Peter Maydell
2018-05-25 12:30               ` [Qemu-devel] " Peter Maydell
2018-05-25 12:35               ` Michael S. Tsirkin
2018-05-25 12:35                 ` [Qemu-devel] " Michael S. Tsirkin
2018-05-25 12:38                 ` Peter Maydell
2018-05-25 12:38                   ` [Qemu-devel] " Peter Maydell
2018-05-25 12:19     ` Michael S. Tsirkin
2018-05-25 12:19       ` [Qemu-devel] " Michael S. Tsirkin
2018-05-25 14:13     ` Paolo Bonzini
2018-05-25 14:13       ` [Qemu-devel] " Paolo Bonzini
2018-05-23 14:43 ` [Qemu-devel] [PULL 08/28] linux-headers: drop kvm_para.h Michael S. Tsirkin
2018-05-23 14:43 ` [Qemu-devel] [PULL 09/28] update-linux-headers.sh: unistd.h, kvm consistency Michael S. Tsirkin
2018-05-23 14:43 ` [Qemu-devel] [PULL 10/28] linux-headers: add unistd.h on all arches Michael S. Tsirkin
2018-05-23 14:43 ` [Qemu-devel] [PULL 12/28] vhost-user: add Net prefix to internal state structure Michael S. Tsirkin
2018-05-23 14:43 ` [Qemu-devel] [PULL 11/28] linux-headers: add kvm header for mips Michael S. Tsirkin
2018-05-23 14:43 ` [Qemu-devel] [PULL 13/28] vhost-user: support receiving file descriptors in slave_read Michael S. Tsirkin
2018-05-23 14:43 ` [Qemu-devel] [PULL 15/28] vhost-user+postcopy: Use qemu_set_nonblock Michael S. Tsirkin
2018-05-23 14:43 ` [Qemu-devel] [PULL 14/28] virtio: support setting memory region based host notifier Michael S. Tsirkin
2018-05-23 14:43 ` [Qemu-devel] [PULL 16/28] libvhost-user: Send messages with no data Michael S. Tsirkin
2018-05-23 14:43 ` [Qemu-devel] [PULL 17/28] hw/virtio: Fix brace Werror with clang 6.0.0 Michael S. Tsirkin
2018-05-23 14:43 ` [Qemu-devel] [PULL 18/28] contrib/vhost-user-blk: enable protocol feature for vhost-user-blk Michael S. Tsirkin
2018-05-23 14:43 ` [Qemu-devel] [PULL 19/28] nvdimm: fix typo in label-size definition Michael S. Tsirkin
2018-05-23 14:43 ` [Qemu-devel] [PULL 20/28] intel-iommu: send PSI always even if across PDEs Michael S. Tsirkin
2018-05-23 14:43 ` [Qemu-devel] [PULL 21/28] intel-iommu: remove IntelIOMMUNotifierNode Michael S. Tsirkin
2018-05-23 14:43 ` [Qemu-devel] [PULL 22/28] intel-iommu: add iommu lock Michael S. Tsirkin
2018-05-23 14:43 ` [Qemu-devel] [PULL 23/28] intel-iommu: only do page walk for MAP notifiers Michael S. Tsirkin
2018-05-23 14:43 ` Michael S. Tsirkin [this message]
2018-05-23 14:43 ` [Qemu-devel] [PULL 25/28] intel-iommu: pass in address space when page walk Michael S. Tsirkin
2018-05-23 14:43 ` [Qemu-devel] [PULL 26/28] intel-iommu: trace domain id during " Michael S. Tsirkin
2018-05-23 14:43 ` [Qemu-devel] [PULL 27/28] util: implement simple iova tree Michael S. Tsirkin
2018-05-23 14:43 ` [Qemu-devel] [PULL 28/28] intel-iommu: rework the page walk logic Michael S. Tsirkin
2018-05-23 15:17 ` [Qemu-devel] [PULL 00/28] pc, pci, virtio, vhost: fixes, features no-reply
2018-05-24 14:18 ` Peter Maydell

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=1527086545-68024-25-git-send-email-mst@redhat.com \
    --to=mst@redhat.com \
    --cc=ehabkost@redhat.com \
    --cc=marcel.apfelbaum@gmail.com \
    --cc=pbonzini@redhat.com \
    --cc=peter.maydell@linaro.org \
    --cc=peterx@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=qemu-stable@nongnu.org \
    --cc=rth@twiddle.net \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.