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,
peter.maydell@linaro.org, jean-philippe@linaro.org,
dgilbert@redhat.com, quintela@redhat.com, mst@redhat.com,
peterx@redhat.com
Cc: kevin.tian@intel.com, bharatb.linux@gmail.com, tnowicki@marvell.com
Subject: [PATCH v13 04/10] virtio-iommu: Implement map/unmap
Date: Sat, 25 Jan 2020 18:19:49 +0100 [thread overview]
Message-ID: <20200125171955.12825-5-eric.auger@redhat.com> (raw)
In-Reply-To: <20200125171955.12825-1-eric.auger@redhat.com>
This patch implements virtio_iommu_map/unmap.
Signed-off-by: Eric Auger <eric.auger@redhat.com>
Reviewed-by: Peter Xu <peterx@redhat.com>
---
v11 -> v12:
- check unmanaged managed flags on map
- removed 2 qemu_log_mask in unmap()
- fix leak
v10 -> v11:
- revisit the implementation of unmap according to Peter's suggestion
- removed virt_addr and size from viommu_mapping struct
- use g_tree_lookup_extended()
- return VIRTIO_IOMMU_S_RANGE in case a mapping were
to be split on unmap (instead of INVAL)
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 | 1 +
hw/virtio/virtio-iommu.c | 63 ++++++++++++++++++++++++++++++++++++++--
2 files changed, 62 insertions(+), 2 deletions(-)
diff --git a/hw/virtio/trace-events b/hw/virtio/trace-events
index 15595f8cd7..22162d6583 100644
--- a/hw/virtio/trace-events
+++ b/hw/virtio/trace-events
@@ -64,6 +64,7 @@ virtio_iommu_attach(uint32_t domain_id, uint32_t ep_id) "domain=%d endpoint=%d"
virtio_iommu_detach(uint32_t domain_id, uint32_t ep_id) "domain=%d endpoint=%d"
virtio_iommu_map(uint32_t domain_id, uint64_t virt_start, uint64_t virt_end, uint64_t phys_start, uint32_t flags) "domain=%d virt_start=0x%"PRIx64" virt_end=0x%"PRIx64 " phys_start=0x%"PRIx64" flags=%d"
virtio_iommu_unmap(uint32_t domain_id, uint64_t virt_start, uint64_t virt_end) "domain=%d virt_start=0x%"PRIx64" virt_end=0x%"PRIx64
+virtio_iommu_unmap_done(uint32_t domain_id, uint64_t virt_start, uint64_t virt_end) "domain=%d virt_start=0x%"PRIx64" virt_end=0x%"PRIx64
virtio_iommu_translate(const char *name, uint32_t rid, uint64_t iova, int flag) "mr=%s rid=%d addr=0x%"PRIx64" flag=%d"
virtio_iommu_init_iommu_mr(char *iommu_mr) "init %s"
virtio_iommu_get_endpoint(uint32_t ep_id) "Alloc endpoint=%d"
diff --git a/hw/virtio/virtio-iommu.c b/hw/virtio/virtio-iommu.c
index e5cc94138b..e1e0c69473 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/qdev-properties.h"
@@ -55,6 +56,11 @@ typedef struct VirtIOIOMMUInterval {
uint64_t high;
} VirtIOIOMMUInterval;
+typedef struct VirtIOIOMMUMapping {
+ uint64_t phys_addr;
+ uint32_t flags;
+} VirtIOIOMMUMapping;
+
static inline uint16_t virtio_iommu_get_bdf(IOMMUDevice *dev)
{
return PCI_BUILD_BDF(pci_bus_num(dev->bus), dev->devfn);
@@ -305,10 +311,39 @@ 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);
+ VirtIOIOMMUDomain *domain;
+ VirtIOIOMMUInterval *interval;
+ VirtIOIOMMUMapping *mapping;
+
+ if (flags & ~VIRTIO_IOMMU_MAP_F_MASK) {
+ return VIRTIO_IOMMU_S_INVAL;
+ }
+
+ domain = g_tree_lookup(s->domains, GUINT_TO_POINTER(domain_id));
+ if (!domain) {
+ return VIRTIO_IOMMU_S_NOENT;
+ }
+
+ interval = g_malloc0(sizeof(*interval));
+
+ interval->low = virt_start;
+ interval->high = virt_end;
+
+ 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->phys_addr = phys_start;
+ mapping->flags = flags;
+
+ g_tree_insert(domain->mappings, interval, mapping);
+
+ return VIRTIO_IOMMU_S_OK;
}
static int virtio_iommu_unmap(VirtIOIOMMU *s,
@@ -317,10 +352,34 @@ 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);
+ VirtIOIOMMUMapping *iter_val;
+ VirtIOIOMMUInterval interval, *iter_key;
+ VirtIOIOMMUDomain *domain;
+ int ret = VIRTIO_IOMMU_S_OK;
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) {
+ return VIRTIO_IOMMU_S_NOENT;
+ }
+ interval.low = virt_start;
+ interval.high = virt_end;
+
+ while (g_tree_lookup_extended(domain->mappings, &interval,
+ (void **)&iter_key, (void**)&iter_val)) {
+ uint64_t current_low = iter_key->low;
+ uint64_t current_high = iter_key->high;
+
+ if (interval.low <= current_low && interval.high >= current_high) {
+ g_tree_remove(domain->mappings, iter_key);
+ trace_virtio_iommu_unmap_done(domain_id, current_low, current_high);
+ } else {
+ ret = VIRTIO_IOMMU_S_RANGE;
+ break;
+ }
+ }
+ return ret;
}
static int virtio_iommu_iov_to_req(struct iovec *iov,
--
2.20.1
next prev parent reply other threads:[~2020-01-25 17:25 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-01-25 17:19 [PATCH v13 00/10] VIRTIO-IOMMU device Eric Auger
2020-01-25 17:19 ` [PATCH v13 01/10] virtio-iommu: Add skeleton Eric Auger
2020-01-25 17:19 ` [PATCH v13 02/10] virtio-iommu: Decode the command payload Eric Auger
2020-01-25 17:19 ` [PATCH v13 03/10] virtio-iommu: Implement attach/detach command Eric Auger
2020-02-03 13:49 ` Peter Xu
2020-02-03 14:59 ` Auger Eric
2020-02-03 15:19 ` Peter Xu
2020-02-03 17:46 ` Auger Eric
2020-02-03 18:19 ` Peter Xu
2020-02-04 12:26 ` Auger Eric
2020-01-25 17:19 ` Eric Auger [this message]
2020-01-25 17:19 ` [PATCH v13 05/10] virtio-iommu: Implement translate Eric Auger
2020-01-25 17:19 ` [PATCH v13 06/10] virtio-iommu: Implement fault reporting Eric Auger
2020-02-03 13:55 ` Peter Xu
2020-02-03 15:01 ` Auger Eric
2020-01-25 17:19 ` [PATCH v13 07/10] virtio-iommu-pci: Add virtio iommu pci support Eric Auger
2020-02-03 13:03 ` Michael S. Tsirkin
2020-02-03 13:20 ` Auger Eric
2020-02-03 13:28 ` Michael S. Tsirkin
2020-02-03 13:38 ` Auger Eric
2020-02-03 13:46 ` Michael S. Tsirkin
2020-02-03 13:52 ` Auger Eric
2020-01-25 17:19 ` [PATCH v13 08/10] hw/arm/virt: Add the virtio-iommu device tree mappings Eric Auger
2020-01-25 17:19 ` [PATCH v13 09/10] virtio-iommu: Support migration Eric Auger
2020-01-25 17:19 ` [PATCH v13 10/10] tests: Add virtio-iommu test Eric Auger
2020-02-03 12:58 ` [PATCH v13 00/10] VIRTIO-IOMMU device Auger Eric
2020-02-03 13:49 ` Peter Xu
2020-02-03 13:51 ` Auger Eric
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=20200125171955.12825-5-eric.auger@redhat.com \
--to=eric.auger@redhat.com \
--cc=bharatb.linux@gmail.com \
--cc=dgilbert@redhat.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=quintela@redhat.com \
--cc=tnowicki@marvell.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.