qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: "Michael S. Tsirkin" <mst@redhat.com>
To: qemu-devel@nongnu.org
Cc: Peter Maydell <peter.maydell@linaro.org>,
	Jean-Philippe Brucker <jean-philippe@linaro.org>,
	Tina Zhang <tina.zhang@intel.com>,
	Eric Auger <eric.auger@redhat.com>
Subject: [PULL 16/16] hw/virtio/virtio-iommu: Enforce power-of-two notify for both MAP and UNMAP
Date: Tue, 26 Jul 2022 15:41:01 -0400	[thread overview]
Message-ID: <20220726193858.177462-17-mst@redhat.com> (raw)
In-Reply-To: <20220726193858.177462-1-mst@redhat.com>

From: Jean-Philippe Brucker <jean-philippe@linaro.org>

Currently we only enforce power-of-two mappings (required by the QEMU
notifier) for UNMAP requests. A MAP request not aligned on a
power-of-two may be successfully handled by VFIO, and then the
corresponding UNMAP notify will fail because it will attempt to split
that mapping. Ensure MAP and UNMAP notifications are consistent.

Fixes: dde3f08b5cab ("virtio-iommu: Handle non power of 2 range invalidations")
Reported-by: Tina Zhang <tina.zhang@intel.com>
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
Message-Id: <20220718135636.338264-1-jean-philippe@linaro.org>
Tested-by: Tina Zhang <tina.zhang@intel.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
 hw/virtio/virtio-iommu.c | 47 ++++++++++++++++++++++++----------------
 1 file changed, 28 insertions(+), 19 deletions(-)

diff --git a/hw/virtio/virtio-iommu.c b/hw/virtio/virtio-iommu.c
index 281152d338..62e07ec2e4 100644
--- a/hw/virtio/virtio-iommu.c
+++ b/hw/virtio/virtio-iommu.c
@@ -197,6 +197,32 @@ static gint interval_cmp(gconstpointer a, gconstpointer b, gpointer user_data)
     }
 }
 
+static void virtio_iommu_notify_map_unmap(IOMMUMemoryRegion *mr,
+                                          IOMMUTLBEvent *event,
+                                          hwaddr virt_start, hwaddr virt_end)
+{
+    uint64_t delta = virt_end - virt_start;
+
+    event->entry.iova = virt_start;
+    event->entry.addr_mask = delta;
+
+    if (delta == UINT64_MAX) {
+        memory_region_notify_iommu(mr, 0, *event);
+    }
+
+    while (virt_start != virt_end + 1) {
+        uint64_t mask = dma_aligned_pow2_mask(virt_start, virt_end, 64);
+
+        event->entry.addr_mask = mask;
+        event->entry.iova = virt_start;
+        memory_region_notify_iommu(mr, 0, *event);
+        virt_start += mask + 1;
+        if (event->entry.perm != IOMMU_NONE) {
+            event->entry.translated_addr += mask + 1;
+        }
+    }
+}
+
 static void virtio_iommu_notify_map(IOMMUMemoryRegion *mr, hwaddr virt_start,
                                     hwaddr virt_end, hwaddr paddr,
                                     uint32_t flags)
@@ -215,19 +241,16 @@ static void virtio_iommu_notify_map(IOMMUMemoryRegion *mr, hwaddr virt_start,
 
     event.type = IOMMU_NOTIFIER_MAP;
     event.entry.target_as = &address_space_memory;
-    event.entry.addr_mask = virt_end - virt_start;
-    event.entry.iova = virt_start;
     event.entry.perm = perm;
     event.entry.translated_addr = paddr;
 
-    memory_region_notify_iommu(mr, 0, event);
+    virtio_iommu_notify_map_unmap(mr, &event, virt_start, virt_end);
 }
 
 static void virtio_iommu_notify_unmap(IOMMUMemoryRegion *mr, hwaddr virt_start,
                                       hwaddr virt_end)
 {
     IOMMUTLBEvent event;
-    uint64_t delta = virt_end - virt_start;
 
     if (!(mr->iommu_notify_flags & IOMMU_NOTIFIER_UNMAP)) {
         return;
@@ -239,22 +262,8 @@ static void virtio_iommu_notify_unmap(IOMMUMemoryRegion *mr, hwaddr virt_start,
     event.entry.target_as = &address_space_memory;
     event.entry.perm = IOMMU_NONE;
     event.entry.translated_addr = 0;
-    event.entry.addr_mask = delta;
-    event.entry.iova = virt_start;
 
-    if (delta == UINT64_MAX) {
-        memory_region_notify_iommu(mr, 0, event);
-    }
-
-
-    while (virt_start != virt_end + 1) {
-        uint64_t mask = dma_aligned_pow2_mask(virt_start, virt_end, 64);
-
-        event.entry.addr_mask = mask;
-        event.entry.iova = virt_start;
-        memory_region_notify_iommu(mr, 0, event);
-        virt_start += mask + 1;
-    }
+    virtio_iommu_notify_map_unmap(mr, &event, virt_start, virt_end);
 }
 
 static gboolean virtio_iommu_notify_unmap_cb(gpointer key, gpointer value,
-- 
MST



  parent reply	other threads:[~2022-07-26 19:48 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-07-26 19:40 [PULL 00/16] pc,virtio: fixes Michael S. Tsirkin
2022-07-26 19:40 ` [PULL 01/16] acpi/nvdimm: Define trace events for NVDIMM and substitute nvdimm_debug() Michael S. Tsirkin
2022-07-26 19:40 ` [PULL 02/16] hw/machine: Clear out left over CXL related pointer from move of state handling to machines Michael S. Tsirkin
2022-07-26 19:40 ` [PULL 03/16] hw/i386/pc: Always place CXL Memory Regions after device_memory Michael S. Tsirkin
2022-07-26 19:40 ` [PULL 04/16] hw/cxl: Fix size of constant in interleave granularity function Michael S. Tsirkin
2022-07-26 19:40 ` [PULL 05/16] hw/i386: add 4g boundary start to X86MachineState Michael S. Tsirkin
2022-07-26 19:40 ` [PULL 06/16] i386/pc: create pci-host qdev prior to pc_memory_init() Michael S. Tsirkin
2022-07-26 19:40 ` [PULL 07/16] i386/pc: pass pci_hole64_size " Michael S. Tsirkin
2022-07-26 19:40 ` [PULL 08/16] i386/pc: factor out above-4g end to an helper Michael S. Tsirkin
2022-07-26 19:40 ` [PULL 09/16] i386/pc: factor out cxl range end to helper Michael S. Tsirkin
2022-07-26 19:40 ` [PULL 10/16] i386/pc: factor out cxl range start " Michael S. Tsirkin
2022-07-26 19:40 ` [PULL 11/16] i386/pc: handle unitialized mr in pc_get_cxl_range_end() Michael S. Tsirkin
2022-07-26 19:40 ` [PULL 12/16] i386/pc: factor out device_memory base/size to helper Michael S. Tsirkin
2022-07-26 19:40 ` [PULL 13/16] i386/pc: bounds check phys-bits against max used GPA Michael S. Tsirkin
2022-07-26 19:40 ` [PULL 14/16] i386/pc: relocate 4g start to 1T where applicable Michael S. Tsirkin
2022-07-26 19:40 ` [PULL 15/16] i386/pc: restrict AMD only enforcing of 1Tb hole to new machine type Michael S. Tsirkin
2022-07-26 19:41 ` Michael S. Tsirkin [this message]
2022-07-26 21:51 ` [PULL 00/16] pc,virtio: fixes Richard Henderson

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=20220726193858.177462-17-mst@redhat.com \
    --to=mst@redhat.com \
    --cc=eric.auger@redhat.com \
    --cc=jean-philippe@linaro.org \
    --cc=peter.maydell@linaro.org \
    --cc=qemu-devel@nongnu.org \
    --cc=tina.zhang@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).