[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PULL 16/23] vfio: introduce vfio_get_vaddr()
From: |
Michael S. Tsirkin |
Subject: |
[Qemu-devel] [PULL 16/23] vfio: introduce vfio_get_vaddr() |
Date: |
Fri, 17 Feb 2017 21:54:46 +0200 |
From: Peter Xu <address@hidden>
A cleanup for vfio_iommu_map_notify(). Now we will fetch vaddr even if
the operation is unmap, but it won't hurt much.
One thing to mention is that we need the RCU read lock to protect the
whole translation and map/unmap procedure.
Acked-by: Alex Williamson <address@hidden>
Reviewed-by: David Gibson <address@hidden>
Signed-off-by: Peter Xu <address@hidden>
Reviewed-by: Michael S. Tsirkin <address@hidden>
Signed-off-by: Michael S. Tsirkin <address@hidden>
---
hw/vfio/common.c | 65 +++++++++++++++++++++++++++++++++++++++-----------------
1 file changed, 45 insertions(+), 20 deletions(-)
diff --git a/hw/vfio/common.c b/hw/vfio/common.c
index 174f351..42c4790 100644
--- a/hw/vfio/common.c
+++ b/hw/vfio/common.c
@@ -294,54 +294,79 @@ static bool
vfio_listener_skipped_section(MemoryRegionSection *section)
section->offset_within_address_space & (1ULL << 63);
}
-static void vfio_iommu_map_notify(IOMMUNotifier *n, IOMMUTLBEntry *iotlb)
+/* Called with rcu_read_lock held. */
+static bool vfio_get_vaddr(IOMMUTLBEntry *iotlb, void **vaddr,
+ bool *read_only)
{
- VFIOGuestIOMMU *giommu = container_of(n, VFIOGuestIOMMU, n);
- VFIOContainer *container = giommu->container;
- hwaddr iova = iotlb->iova + giommu->iommu_offset;
MemoryRegion *mr;
hwaddr xlat;
hwaddr len = iotlb->addr_mask + 1;
- void *vaddr;
- int ret;
-
- trace_vfio_iommu_map_notify(iotlb->perm == IOMMU_NONE ? "UNMAP" : "MAP",
- iova, iova + iotlb->addr_mask);
-
- if (iotlb->target_as != &address_space_memory) {
- error_report("Wrong target AS \"%s\", only system memory is allowed",
- iotlb->target_as->name ? iotlb->target_as->name : "none");
- return;
- }
+ bool writable = iotlb->perm & IOMMU_WO;
/*
* The IOMMU TLB entry we have just covers translation through
* this IOMMU to its immediate target. We need to translate
* it the rest of the way through to memory.
*/
- rcu_read_lock();
mr = address_space_translate(&address_space_memory,
iotlb->translated_addr,
- &xlat, &len, iotlb->perm & IOMMU_WO);
+ &xlat, &len, writable);
if (!memory_region_is_ram(mr)) {
error_report("iommu map to non memory area %"HWADDR_PRIx"",
xlat);
- goto out;
+ return false;
}
+
/*
* Translation truncates length to the IOMMU page size,
* check that it did not truncate too much.
*/
if (len & iotlb->addr_mask) {
error_report("iommu has granularity incompatible with target AS");
+ return false;
+ }
+
+ *vaddr = memory_region_get_ram_ptr(mr) + xlat;
+ *read_only = !writable || mr->readonly;
+
+ return true;
+}
+
+static void vfio_iommu_map_notify(IOMMUNotifier *n, IOMMUTLBEntry *iotlb)
+{
+ VFIOGuestIOMMU *giommu = container_of(n, VFIOGuestIOMMU, n);
+ VFIOContainer *container = giommu->container;
+ hwaddr iova = iotlb->iova + giommu->iommu_offset;
+ bool read_only;
+ void *vaddr;
+ int ret;
+
+ trace_vfio_iommu_map_notify(iotlb->perm == IOMMU_NONE ? "UNMAP" : "MAP",
+ iova, iova + iotlb->addr_mask);
+
+ if (iotlb->target_as != &address_space_memory) {
+ error_report("Wrong target AS \"%s\", only system memory is allowed",
+ iotlb->target_as->name ? iotlb->target_as->name : "none");
+ return;
+ }
+
+ rcu_read_lock();
+
+ if (!vfio_get_vaddr(iotlb, &vaddr, &read_only)) {
goto out;
}
if ((iotlb->perm & IOMMU_RW) != IOMMU_NONE) {
- vaddr = memory_region_get_ram_ptr(mr) + xlat;
+ /*
+ * vaddr is only valid until rcu_read_unlock(). But after
+ * vfio_dma_map has set up the mapping the pages will be
+ * pinned by the kernel. This makes sure that the RAM backend
+ * of vaddr will always be there, even if the memory object is
+ * destroyed and its backing memory munmap-ed.
+ */
ret = vfio_dma_map(container, iova,
iotlb->addr_mask + 1, vaddr,
- !(iotlb->perm & IOMMU_WO) || mr->readonly);
+ read_only);
if (ret) {
error_report("vfio_dma_map(%p, 0x%"HWADDR_PRIx", "
"0x%"HWADDR_PRIx", %p) = %d (%m)",
--
MST
- [Qemu-devel] [PULL 05/23] virtio: add virtio_*_phys_cached, (continued)
- [Qemu-devel] [PULL 05/23] virtio: add virtio_*_phys_cached, Michael S. Tsirkin, 2017/02/17
- [Qemu-devel] [PULL 07/23] exec: make address_space_cache_destroy idempotent, Michael S. Tsirkin, 2017/02/17
- [Qemu-devel] [PULL 06/23] virtio: use address_space_map/unmap to access descriptors, Michael S. Tsirkin, 2017/02/17
- [Qemu-devel] [PULL 08/23] virtio: use MemoryRegionCache to access descriptors, Michael S. Tsirkin, 2017/02/17
- [Qemu-devel] [PULL 09/23] virtio: add MemoryListener to cache ring translations, Michael S. Tsirkin, 2017/02/17
- [Qemu-devel] [PULL 11/23] virtio: check for vring setup in virtio_queue_update_used_idx, Michael S. Tsirkin, 2017/02/17
- [Qemu-devel] [PULL 10/23] virtio: use VRingMemoryRegionCaches for descriptor ring, Michael S. Tsirkin, 2017/02/17
- [Qemu-devel] [PULL 13/23] virtio: Fix no interrupt when not creating msi controller, Michael S. Tsirkin, 2017/02/17
- [Qemu-devel] [PULL 12/23] virtio: use VRingMemoryRegionCaches for avail and used rings, Michael S. Tsirkin, 2017/02/17
- [Qemu-devel] [PULL 14/23] pcie: simplify pcie_add_capability(), Michael S. Tsirkin, 2017/02/17
- [Qemu-devel] [PULL 16/23] vfio: introduce vfio_get_vaddr(),
Michael S. Tsirkin <=
- [Qemu-devel] [PULL 15/23] vfio: trace map/unmap for notify as well, Michael S. Tsirkin, 2017/02/17
- [Qemu-devel] [PULL 17/23] vfio: allow to notify unmap for very large region, Michael S. Tsirkin, 2017/02/17
- [Qemu-devel] [PULL 18/23] intel_iommu: add "caching-mode" option, Michael S. Tsirkin, 2017/02/17
- [Qemu-devel] [PULL 19/23] intel_iommu: simplify irq region translation, Michael S. Tsirkin, 2017/02/17
- [Qemu-devel] [PULL 20/23] intel_iommu: renaming gpa to iova where proper, Michael S. Tsirkin, 2017/02/17
- [Qemu-devel] [PULL 23/23] intel_iommu: vtd_slpt_level_shift check level, Michael S. Tsirkin, 2017/02/17
- [Qemu-devel] [PULL 22/23] intel_iommu: convert dbg macros to trace for trans, Michael S. Tsirkin, 2017/02/17
- [Qemu-devel] [PULL 21/23] intel_iommu: convert dbg macros to traces for inv, Michael S. Tsirkin, 2017/02/17
- Re: [Qemu-devel] [PULL 00/23] virtio, pci: fixes, features, Peter Maydell, 2017/02/20