All of lore.kernel.org
 help / color / mirror / Atom feed
From: Eric Auger <eric.auger@redhat.com>
To: eric.auger.pro@gmail.com, eric.auger@redhat.com,
	qemu-devel@nongnu.org, qemu-arm@nongnu.org, mst@redhat.com,
	peter.maydell@linaro.org, alex.williamson@redhat.com,
	jean-philippe@linaro.org, kevin.tian@intel.com
Cc: tn@semihalf.com, bharat.bhushan@nxp.com, peterx@redhat.com
Subject: [Qemu-devel] [PATCH for-4.2 v10 08/15] virtio-iommu: Implement map/unmap
Date: Tue, 30 Jul 2019 19:21:30 +0200	[thread overview]
Message-ID: <20190730172137.23114-9-eric.auger@redhat.com> (raw)
In-Reply-To: <20190730172137.23114-1-eric.auger@redhat.com>

This patch implements virtio_iommu_map/unmap.

Signed-off-by: Eric Auger <eric.auger@redhat.com>

---

v5 -> v6:
- use new v0.6 fields
- replace error_report by qemu_log_mask

v3 -> v4:
- implement unmap semantics as specified in v0.4
---
 hw/virtio/trace-events   |  3 ++
 hw/virtio/virtio-iommu.c | 94 +++++++++++++++++++++++++++++++++++++++-
 2 files changed, 95 insertions(+), 2 deletions(-)

diff --git a/hw/virtio/trace-events b/hw/virtio/trace-events
index a373bdebb3..25a71b0505 100644
--- a/hw/virtio/trace-events
+++ b/hw/virtio/trace-events
@@ -71,3 +71,6 @@ virtio_iommu_get_endpoint(uint32_t ep_id) "Alloc endpoint=%d"
 virtio_iommu_put_endpoint(uint32_t ep_id) "Free endpoint=%d"
 virtio_iommu_get_domain(uint32_t domain_id) "Alloc domain=%d"
 virtio_iommu_put_domain(uint32_t domain_id) "Free domain=%d"
+virtio_iommu_unmap_left_interval(uint64_t low, uint64_t high, uint64_t next_low, uint64_t next_high) "Unmap left [0x%"PRIx64",0x%"PRIx64"], new interval=[0x%"PRIx64",0x%"PRIx64"]"
+virtio_iommu_unmap_right_interval(uint64_t low, uint64_t high, uint64_t next_low, uint64_t next_high) "Unmap right [0x%"PRIx64",0x%"PRIx64"], new interval=[0x%"PRIx64",0x%"PRIx64"]"
+virtio_iommu_unmap_inc_interval(uint64_t low, uint64_t high) "Unmap inc [0x%"PRIx64",0x%"PRIx64"]"
diff --git a/hw/virtio/virtio-iommu.c b/hw/virtio/virtio-iommu.c
index 5ea0930cc2..4706b9da6e 100644
--- a/hw/virtio/virtio-iommu.c
+++ b/hw/virtio/virtio-iommu.c
@@ -18,6 +18,7 @@
  */
 
 #include "qemu/osdep.h"
+#include "qemu/log.h"
 #include "qemu/iov.h"
 #include "qemu-common.h"
 #include "hw/virtio/virtio.h"
@@ -55,6 +56,13 @@ typedef struct viommu_interval {
     uint64_t high;
 } viommu_interval;
 
+typedef struct viommu_mapping {
+    uint64_t virt_addr;
+    uint64_t phys_addr;
+    uint64_t size;
+    uint32_t flags;
+} viommu_mapping;
+
 static inline uint16_t virtio_iommu_get_sid(IOMMUDevice *dev)
 {
     return PCI_BUILD_BDF(pci_bus_num(dev->bus), dev->devfn);
@@ -240,10 +248,37 @@ static int virtio_iommu_map(VirtIOIOMMU *s,
     uint64_t virt_start = le64_to_cpu(req->virt_start);
     uint64_t virt_end = le64_to_cpu(req->virt_end);
     uint32_t flags = le32_to_cpu(req->flags);
+    viommu_domain *domain;
+    viommu_interval *interval;
+    viommu_mapping *mapping;
+
+    interval = g_malloc0(sizeof(*interval));
+
+    interval->low = virt_start;
+    interval->high = virt_end;
+
+    domain = g_tree_lookup(s->domains, GUINT_TO_POINTER(domain_id));
+    if (!domain) {
+        return VIRTIO_IOMMU_S_NOENT;
+    }
+
+    mapping = g_tree_lookup(domain->mappings, (gpointer)interval);
+    if (mapping) {
+        g_free(interval);
+        return VIRTIO_IOMMU_S_INVAL;
+    }
 
     trace_virtio_iommu_map(domain_id, virt_start, virt_end, phys_start, flags);
 
-    return VIRTIO_IOMMU_S_UNSUPP;
+    mapping = g_malloc0(sizeof(*mapping));
+    mapping->virt_addr = virt_start;
+    mapping->phys_addr = phys_start;
+    mapping->size = virt_end - virt_start + 1;
+    mapping->flags = flags;
+
+    g_tree_insert(domain->mappings, interval, mapping);
+
+    return VIRTIO_IOMMU_S_OK;
 }
 
 static int virtio_iommu_unmap(VirtIOIOMMU *s,
@@ -252,10 +287,65 @@ static int virtio_iommu_unmap(VirtIOIOMMU *s,
     uint32_t domain_id = le32_to_cpu(req->domain);
     uint64_t virt_start = le64_to_cpu(req->virt_start);
     uint64_t virt_end = le64_to_cpu(req->virt_end);
+    uint64_t size = virt_end - virt_start + 1;
+    viommu_mapping *mapping;
+    viommu_interval interval;
+    viommu_domain *domain;
 
     trace_virtio_iommu_unmap(domain_id, virt_start, virt_end);
 
-    return VIRTIO_IOMMU_S_UNSUPP;
+    domain = g_tree_lookup(s->domains, GUINT_TO_POINTER(domain_id));
+    if (!domain) {
+        qemu_log_mask(LOG_GUEST_ERROR, "%s: no domain\n", __func__);
+        return VIRTIO_IOMMU_S_NOENT;
+    }
+    interval.low = virt_start;
+    interval.high = virt_end;
+
+    mapping = g_tree_lookup(domain->mappings, (gpointer)(&interval));
+
+    while (mapping) {
+        viommu_interval current;
+        uint64_t low  = mapping->virt_addr;
+        uint64_t high = mapping->virt_addr + mapping->size - 1;
+
+        current.low = low;
+        current.high = high;
+
+        if (low == interval.low && size >= mapping->size) {
+            g_tree_remove(domain->mappings, (gpointer)(&current));
+            interval.low = high + 1;
+            trace_virtio_iommu_unmap_left_interval(current.low, current.high,
+                interval.low, interval.high);
+        } else if (high == interval.high && size >= mapping->size) {
+            trace_virtio_iommu_unmap_right_interval(current.low, current.high,
+                interval.low, interval.high);
+            g_tree_remove(domain->mappings, (gpointer)(&current));
+            interval.high = low - 1;
+        } else if (low > interval.low && high < interval.high) {
+            trace_virtio_iommu_unmap_inc_interval(current.low, current.high);
+            g_tree_remove(domain->mappings, (gpointer)(&current));
+        } else {
+            break;
+        }
+        if (interval.low >= interval.high) {
+            return VIRTIO_IOMMU_S_OK;
+        } else {
+            mapping = g_tree_lookup(domain->mappings, (gpointer)(&interval));
+        }
+    }
+
+    if (mapping) {
+        qemu_log_mask(LOG_GUEST_ERROR,
+                      "****** %s: Unmap 0x%"PRIx64" size=0x%"PRIx64
+                     " from 0x%"PRIx64" size=0x%"PRIx64" is not supported\n",
+                     __func__, interval.low, size,
+                     mapping->virt_addr, mapping->size);
+    } else {
+        return VIRTIO_IOMMU_S_OK;
+    }
+
+    return VIRTIO_IOMMU_S_INVAL;
 }
 
 static int virtio_iommu_iov_to_req(struct iovec *iov,
-- 
2.20.1



  parent reply	other threads:[~2019-07-30 17:27 UTC|newest]

Thread overview: 55+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-07-30 17:21 [Qemu-devel] [PATCH for-4.2 v10 00/15] VIRTIO-IOMMU device Eric Auger
2019-07-30 17:21 ` [Qemu-devel] [PATCH for-4.2 v10 01/15] update-linux-headers: Import virtio_iommu.h Eric Auger
2019-07-30 17:21 ` [Qemu-devel] [PATCH for-4.2 v10 02/15] linux-headers: update against 5.3-rc2 Eric Auger
2019-07-30 17:21 ` [Qemu-devel] [PATCH for-4.2 v10 03/15] virtio-iommu: Add skeleton Eric Auger
2019-08-15 13:54   ` Peter Xu
2019-08-29 12:18     ` Auger Eric
2019-08-30  1:26       ` Peter Xu
2019-08-30  8:12         ` Auger Eric
2019-07-30 17:21 ` [Qemu-devel] [PATCH for-4.2 v10 04/15] virtio-iommu: Decode the command payload Eric Auger
2019-07-30 17:21 ` [Qemu-devel] [PATCH for-4.2 v10 05/15] virtio-iommu: Add the iommu regions Eric Auger
2019-08-16  4:00   ` Peter Xu
2019-08-29 12:51     ` Auger Eric
2019-07-30 17:21 ` [Qemu-devel] [PATCH for-4.2 v10 06/15] virtio-iommu: Endpoint and domains structs and helpers Eric Auger
2019-08-16  4:17   ` Peter Xu
2019-11-04 18:31   ` Jean-Philippe Brucker
2019-11-25 13:14     ` Auger Eric
2019-07-30 17:21 ` [Qemu-devel] [PATCH for-4.2 v10 07/15] virtio-iommu: Implement attach/detach command Eric Auger
2019-08-16  4:27   ` Peter Xu
2019-08-29 14:24     ` Auger Eric
2019-07-30 17:21 ` Eric Auger [this message]
2019-08-19  8:11   ` [Qemu-devel] [PATCH for-4.2 v10 08/15] virtio-iommu: Implement map/unmap Peter Xu
2019-09-03 11:37     ` Auger Eric
2019-09-04  1:44       ` Peter Xu
2019-09-04  4:23         ` Tian, Kevin
2019-09-04  5:37           ` Peter Xu
2019-09-04  5:46             ` Tian, Kevin
2019-09-04  7:54               ` Auger Eric
2019-09-04  8:32                 ` Peter Xu
2019-07-30 17:21 ` [Qemu-devel] [PATCH for-4.2 v10 09/15] virtio-iommu: Implement translate Eric Auger
2019-08-19  8:24   ` Peter Xu
2019-09-03 11:45     ` Auger Eric
2019-09-04  1:58       ` Peter Xu
2019-07-30 17:21 ` [Qemu-devel] [PATCH for-4.2 v10 10/15] virtio-iommu: Implement probe request Eric Auger
2019-08-19 12:08   ` Peter Xu
2019-09-03 12:23     ` Auger Eric
2019-07-30 17:21 ` [Qemu-devel] [PATCH for-4.2 v10 11/15] virtio-iommu: Expose the IOAPIC MSI reserved region when relevant Eric Auger
2019-07-30 19:38   ` Michael S. Tsirkin
2019-07-30 23:20     ` Tian, Kevin
2019-07-31  9:05       ` Auger Eric
2019-07-31 19:25       ` Michael S. Tsirkin
2019-07-31 19:44         ` Auger Eric
2019-07-31 23:23           ` Tian, Kevin
2019-07-30 17:21 ` [Qemu-devel] [PATCH for-4.2 v10 12/15] virtio-iommu: Implement fault reporting Eric Auger
2019-07-30 17:21 ` [Qemu-devel] [PATCH for-4.2 v10 13/15] virtio_iommu: Handle reserved regions in translation process Eric Auger
2019-08-19 12:44   ` Peter Xu
2019-09-01  6:38   ` Michael S. Tsirkin
2019-07-30 17:21 ` [Qemu-devel] [PATCH for-4.2 v10 14/15] virtio-iommu-pci: Add virtio iommu pci support Eric Auger
2019-07-30 19:35   ` Michael S. Tsirkin
2019-08-01 12:15     ` Auger Eric
2019-08-01 13:06       ` Michael S. Tsirkin
2019-08-01 13:49         ` Auger Eric
2019-09-01  6:40           ` Michael S. Tsirkin
2019-09-04 14:19             ` Auger Eric
2019-09-04 21:36               ` Michael S. Tsirkin
2019-07-30 17:21 ` [Qemu-devel] [PATCH for-4.2 v10 15/15] hw/arm/virt: Add the virtio-iommu device tree mappings Eric Auger

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=20190730172137.23114-9-eric.auger@redhat.com \
    --to=eric.auger@redhat.com \
    --cc=alex.williamson@redhat.com \
    --cc=bharat.bhushan@nxp.com \
    --cc=eric.auger.pro@gmail.com \
    --cc=jean-philippe@linaro.org \
    --cc=kevin.tian@intel.com \
    --cc=mst@redhat.com \
    --cc=peter.maydell@linaro.org \
    --cc=peterx@redhat.com \
    --cc=qemu-arm@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    --cc=tn@semihalf.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 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.