[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PULL 16/16] hw/virtio/virtio-iommu: Enforce power-of-two notify for bot
From: |
Michael S. Tsirkin |
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 |
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
- [PULL 04/16] hw/cxl: Fix size of constant in interleave granularity function., (continued)
- [PULL 04/16] hw/cxl: Fix size of constant in interleave granularity function., Michael S. Tsirkin, 2022/07/26
- [PULL 07/16] i386/pc: pass pci_hole64_size to pc_memory_init(), Michael S. Tsirkin, 2022/07/26
- [PULL 09/16] i386/pc: factor out cxl range end to helper, Michael S. Tsirkin, 2022/07/26
- [PULL 10/16] i386/pc: factor out cxl range start to helper, Michael S. Tsirkin, 2022/07/26
- [PULL 08/16] i386/pc: factor out above-4g end to an helper, Michael S. Tsirkin, 2022/07/26
- [PULL 11/16] i386/pc: handle unitialized mr in pc_get_cxl_range_end(), Michael S. Tsirkin, 2022/07/26
- [PULL 13/16] i386/pc: bounds check phys-bits against max used GPA, Michael S. Tsirkin, 2022/07/26
- [PULL 14/16] i386/pc: relocate 4g start to 1T where applicable, Michael S. Tsirkin, 2022/07/26
- [PULL 12/16] i386/pc: factor out device_memory base/size to helper, Michael S. Tsirkin, 2022/07/26
- [PULL 15/16] i386/pc: restrict AMD only enforcing of 1Tb hole to new machine type, Michael S. Tsirkin, 2022/07/26
- [PULL 16/16] hw/virtio/virtio-iommu: Enforce power-of-two notify for both MAP and UNMAP,
Michael S. Tsirkin <=
- Re: [PULL 00/16] pc,virtio: fixes, Richard Henderson, 2022/07/26