From: Eric Auger <eric.auger@redhat.com>
To: eric.auger.pro@gmail.com, eric.auger@redhat.com,
peter.maydell@linaro.org, alex.williamson@redhat.com,
mst@redhat.com, qemu-arm@nongnu.org, qemu-devel@nongnu.org,
jean-philippe.brucker@arm.com
Cc: wei@redhat.com, kevin.tian@intel.com, marc.zyngier@arm.com,
tn@semihalf.com, will.deacon@arm.com, drjones@redhat.com,
peterx@redhat.com, linuc.decode@gmail.com,
bharat.bhushan@nxp.com, christoffer.dall@linaro.org
Subject: [Qemu-devel] [RFC v5 13/22] virtio-iommu: Implement probe request
Date: Fri, 19 Jan 2018 14:49:06 +0000 [thread overview]
Message-ID: <1516373355-305-14-git-send-email-eric.auger@redhat.com> (raw)
In-Reply-To: <1516373355-305-1-git-send-email-eric.auger@redhat.com>
This patch implements the PROBE request. At the moment,
no reserved regions are returned as none are registered
per device. Only a NONE property is returned.
Signed-off-by: Eric Auger <eric.auger@redhat.com>
---
v4 -> v5:
- initialize bufstate.error to false
- add cpu_to_le64(size)
---
hw/virtio/trace-events | 2 +
hw/virtio/virtio-iommu.c | 190 ++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 190 insertions(+), 2 deletions(-)
diff --git a/hw/virtio/trace-events b/hw/virtio/trace-events
index 873e4fc..6a502cc 100644
--- a/hw/virtio/trace-events
+++ b/hw/virtio/trace-events
@@ -46,3 +46,5 @@ virtio_iommu_unmap_left_interval(uint64_t low, uint64_t high, uint64_t next_low,
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"]"
virtio_iommu_translate_out(uint64_t virt_addr, uint64_t phys_addr, uint32_t sid) "0x%"PRIx64" -> 0x%"PRIx64 " for sid=%d"
+virtio_iommu_fill_resv_property(uint32_t devid, uint8_t subtype, uint64_t addr, uint64_t size, uint32_t flags, size_t filled) "dev= %d, subtype=%d addr=0x%"PRIx64" size=0x%"PRIx64" flags=%d filled=0x%lx"
+virtio_iommu_fill_none_property(uint32_t devid) "devid=%d"
diff --git a/hw/virtio/virtio-iommu.c b/hw/virtio/virtio-iommu.c
index c96aacc..0e712b3 100644
--- a/hw/virtio/virtio-iommu.c
+++ b/hw/virtio/virtio-iommu.c
@@ -39,6 +39,11 @@
/* Max size */
#define VIOMMU_DEFAULT_QUEUE_SIZE 256
+#define VIOMMU_PROBE_SIZE 512
+
+#define SUPPORTED_PROBE_PROPERTIES (\
+ VIRTIO_IOMMU_PROBE_T_NONE | \
+ VIRTIO_IOMMU_PROBE_T_RESV_MEM)
typedef struct viommu_domain {
uint32_t id;
@@ -51,6 +56,7 @@ typedef struct viommu_endpoint {
viommu_domain *domain;
QLIST_ENTRY(viommu_endpoint) next;
VirtIOIOMMU *viommu;
+ GTree *reserved_regions;
} viommu_endpoint;
typedef struct viommu_interval {
@@ -65,6 +71,13 @@ typedef struct viommu_mapping {
uint32_t flags;
} viommu_mapping;
+typedef struct viommu_property_buffer {
+ viommu_endpoint *endpoint;
+ size_t filled;
+ uint8_t *start;
+ bool error;
+} viommu_property_buffer;
+
static inline uint16_t virtio_iommu_get_sid(IOMMUDevice *dev)
{
return PCI_BUILD_BDF(pci_bus_num(dev->bus), dev->devfn);
@@ -104,6 +117,9 @@ static viommu_endpoint *virtio_iommu_get_endpoint(VirtIOIOMMU *s,
ep->viommu = s;
trace_virtio_iommu_get_endpoint(ep_id);
g_tree_insert(s->endpoints, GUINT_TO_POINTER(ep_id), ep);
+ ep->reserved_regions = g_tree_new_full((GCompareDataFunc)interval_cmp,
+ NULL, (GDestroyNotify)g_free,
+ (GDestroyNotify)g_free);
return ep;
}
@@ -117,6 +133,7 @@ static void virtio_iommu_put_endpoint(gpointer data)
}
trace_virtio_iommu_put_endpoint(ep->id);
+ g_tree_destroy(ep->reserved_regions);
g_free(ep);
}
@@ -358,6 +375,139 @@ static int virtio_iommu_unmap(VirtIOIOMMU *s,
return VIRTIO_IOMMU_S_INVAL;
}
+/**
+ * virtio_iommu_fill_resv_mem_prop - Add a RESV_MEM probe
+ * property into the probe request buffer
+ *
+ * @key: interval handle
+ * @value: handle to the reserved memory region
+ * @data: handle to the probe request buffer state
+ */
+static gboolean virtio_iommu_fill_resv_mem_prop(gpointer key,
+ gpointer value,
+ gpointer data)
+{
+ struct virtio_iommu_probe_resv_mem *resv =
+ (struct virtio_iommu_probe_resv_mem *)value;
+ struct virtio_iommu_probe_property *prop;
+ struct virtio_iommu_probe_resv_mem *current;
+ viommu_property_buffer *bufstate = (viommu_property_buffer *)data;
+ size_t size = sizeof(*resv), total_size;
+
+ total_size = size + sizeof(*prop);
+
+ if (bufstate->filled + total_size >= VIOMMU_PROBE_SIZE) {
+ bufstate->error = true;
+ /* get the traversal stopped by returning true */
+ return true;
+ }
+ prop = (struct virtio_iommu_probe_property *)
+ (bufstate->start + bufstate->filled);
+ prop->type = cpu_to_le16(VIRTIO_IOMMU_PROBE_T_RESV_MEM) &
+ VIRTIO_IOMMU_PROBE_T_MASK;
+ prop->length = cpu_to_le16(size);
+
+ current = (struct virtio_iommu_probe_resv_mem *)prop->value;
+ *current = *resv;
+ bufstate->filled += total_size;
+ trace_virtio_iommu_fill_resv_property(bufstate->endpoint->id,
+ resv->subtype, resv->addr,
+ resv->size, resv->subtype,
+ bufstate->filled);
+ return false;
+}
+
+static int virtio_iommu_fill_none_prop(viommu_property_buffer *bufstate)
+{
+ struct virtio_iommu_probe_property *prop;
+
+ prop = (struct virtio_iommu_probe_property *)
+ (bufstate->start + bufstate->filled);
+ prop->type = cpu_to_le16(VIRTIO_IOMMU_PROBE_T_NONE)
+ & VIRTIO_IOMMU_PROBE_T_MASK;
+ prop->length = 0;
+ bufstate->filled += sizeof(*prop);
+ trace_virtio_iommu_fill_none_property(bufstate->endpoint->id);
+ return 0;
+}
+
+static int virtio_iommu_fill_property(int type,
+ viommu_property_buffer *bufstate)
+{
+ int ret = -ENOSPC;
+
+ if (bufstate->filled + 4 >= VIOMMU_PROBE_SIZE) {
+ /* Even the property header cannot be filled */
+ bufstate->error = true;
+ goto out;
+ }
+
+ switch (type) {
+ case VIRTIO_IOMMU_PROBE_T_NONE:
+ ret = virtio_iommu_fill_none_prop(bufstate);
+ break;
+ case VIRTIO_IOMMU_PROBE_T_RESV_MEM:
+ {
+ viommu_endpoint *ep = bufstate->endpoint;
+
+ g_tree_foreach(ep->reserved_regions,
+ virtio_iommu_fill_resv_mem_prop,
+ bufstate);
+ if (!bufstate->error) {
+ ret = 0;
+ }
+ break;
+ }
+ default:
+ ret = -ENOENT;
+ break;
+ }
+out:
+ if (ret) {
+ error_report("%s property of type=%d could not be filled (%d),"
+ " remaining size = 0x%lx",
+ __func__, type, ret, bufstate->filled);
+ }
+ return ret;
+}
+
+/**
+ * virtio_iommu_probe - Fill the probe request buffer with all
+ * the properties the device is able to return and add a NONE
+ * property at the end.
+ */
+static int virtio_iommu_probe(VirtIOIOMMU *s,
+ struct virtio_iommu_req_probe *req,
+ uint8_t *buf)
+{
+ uint32_t ep_id = le32_to_cpu(req->endpoint);
+ int16_t prop_types = SUPPORTED_PROBE_PROPERTIES, type;
+ viommu_property_buffer bufstate;
+ viommu_endpoint *ep;
+ int ret;
+
+ ep = g_tree_lookup(s->endpoints, GUINT_TO_POINTER(ep_id));
+ if (!ep) {
+ return -EINVAL;
+ }
+
+ bufstate.start = buf;
+ bufstate.filled = 0;
+ bufstate.error = false;
+ bufstate.endpoint = ep;
+
+ while ((type = ctz32(prop_types)) != 32) {
+ ret = virtio_iommu_fill_property(1 << type, &bufstate);
+ if (ret) {
+ break;
+ }
+ prop_types &= ~(1 << type);
+ }
+ virtio_iommu_fill_property(VIRTIO_IOMMU_PROBE_T_NONE, &bufstate);
+
+ return VIRTIO_IOMMU_S_OK;
+}
+
#define get_payload_size(req) (\
sizeof((req)) - sizeof(struct virtio_iommu_req_tail))
@@ -422,6 +572,24 @@ static int virtio_iommu_handle_unmap(VirtIOIOMMU *s,
return virtio_iommu_unmap(s, &req);
}
+static int virtio_iommu_handle_probe(VirtIOIOMMU *s,
+ struct iovec *iov,
+ unsigned int iov_cnt,
+ uint8_t *buf)
+{
+ struct virtio_iommu_req_probe req;
+ size_t sz, payload_sz;
+
+ payload_sz = sizeof(req);
+
+ sz = iov_to_buf(iov, iov_cnt, 0, &req, payload_sz);
+ if (sz != payload_sz) {
+ return VIRTIO_IOMMU_S_INVAL;
+ }
+
+ return virtio_iommu_probe(s, &req, buf);
+}
+
static void virtio_iommu_handle_command(VirtIODevice *vdev, VirtQueue *vq)
{
VirtIOIOMMU *s = VIRTIO_IOMMU(vdev);
@@ -466,16 +634,32 @@ static void virtio_iommu_handle_command(VirtIODevice *vdev, VirtQueue *vq)
case VIRTIO_IOMMU_T_UNMAP:
tail.status = virtio_iommu_handle_unmap(s, iov, iov_cnt);
break;
+ case VIRTIO_IOMMU_T_PROBE:
+ {
+ struct virtio_iommu_req_tail *ptail;
+ uint8_t *buf = g_malloc0(s->config.probe_size + sizeof(tail));
+
+ ptail = (struct virtio_iommu_req_tail *)
+ (buf + s->config.probe_size);
+ ptail->status = virtio_iommu_handle_probe(s, iov, iov_cnt, buf);
+
+ sz = iov_from_buf(elem->in_sg, elem->in_num, 0,
+ buf, s->config.probe_size + sizeof(tail));
+ g_free(buf);
+ assert(sz == s->config.probe_size + sizeof(tail));
+ goto push;
+ }
default:
tail.status = VIRTIO_IOMMU_S_UNSUPP;
}
- qemu_mutex_unlock(&s->mutex);
sz = iov_from_buf(elem->in_sg, elem->in_num, 0,
&tail, sizeof(tail));
assert(sz == sizeof(tail));
- virtqueue_push(vq, elem, sizeof(tail));
+push:
+ qemu_mutex_unlock(&s->mutex);
+ virtqueue_push(vq, elem, sz);
virtio_notify(vdev, vq);
g_free(elem);
}
@@ -568,6 +752,7 @@ static uint64_t virtio_iommu_get_features(VirtIODevice *vdev, uint64_t f,
virtio_add_feature(&f, VIRTIO_RING_F_INDIRECT_DESC);
virtio_add_feature(&f, VIRTIO_IOMMU_F_INPUT_RANGE);
virtio_add_feature(&f, VIRTIO_IOMMU_F_MAP_UNMAP);
+ virtio_add_feature(&f, VIRTIO_IOMMU_F_PROBE);
return f;
}
@@ -623,6 +808,7 @@ static void virtio_iommu_device_realize(DeviceState *dev, Error **errp)
s->config.page_size_mask = TARGET_PAGE_MASK;
s->config.input_range.end = -1UL;
+ s->config.probe_size = VIOMMU_PROBE_SIZE;
qemu_mutex_init(&s->mutex);
--
1.9.1
WARNING: multiple messages have this Message-ID (diff)
From: Eric Auger <eric.auger@redhat.com>
To: eric.auger.pro@gmail.com, eric.auger@redhat.com,
peter.maydell@linaro.org, alex.williamson@redhat.com,
mst@redhat.com, qemu-arm@nongnu.org, qemu-devel@nongnu.org,
jean-philippe.brucker@arm.com
Cc: will.deacon@arm.com, kevin.tian@intel.com, marc.zyngier@arm.com,
christoffer.dall@linaro.org, drjones@redhat.com, wei@redhat.com,
tn@semihalf.com, bharat.bhushan@nxp.com, peterx@redhat.com,
linuc.decode@gmail.com
Subject: [Qemu-devel] [RFC v5 13/22] virtio-iommu: Implement probe request
Date: Fri, 19 Jan 2018 14:49:06 +0000 [thread overview]
Message-ID: <1516373355-305-14-git-send-email-eric.auger@redhat.com> (raw)
In-Reply-To: <1516373355-305-1-git-send-email-eric.auger@redhat.com>
This patch implements the PROBE request. At the moment,
no reserved regions are returned as none are registered
per device. Only a NONE property is returned.
Signed-off-by: Eric Auger <eric.auger@redhat.com>
---
v4 -> v5:
- initialize bufstate.error to false
- add cpu_to_le64(size)
---
hw/virtio/trace-events | 2 +
hw/virtio/virtio-iommu.c | 190 ++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 190 insertions(+), 2 deletions(-)
diff --git a/hw/virtio/trace-events b/hw/virtio/trace-events
index 873e4fc..6a502cc 100644
--- a/hw/virtio/trace-events
+++ b/hw/virtio/trace-events
@@ -46,3 +46,5 @@ virtio_iommu_unmap_left_interval(uint64_t low, uint64_t high, uint64_t next_low,
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"]"
virtio_iommu_translate_out(uint64_t virt_addr, uint64_t phys_addr, uint32_t sid) "0x%"PRIx64" -> 0x%"PRIx64 " for sid=%d"
+virtio_iommu_fill_resv_property(uint32_t devid, uint8_t subtype, uint64_t addr, uint64_t size, uint32_t flags, size_t filled) "dev= %d, subtype=%d addr=0x%"PRIx64" size=0x%"PRIx64" flags=%d filled=0x%lx"
+virtio_iommu_fill_none_property(uint32_t devid) "devid=%d"
diff --git a/hw/virtio/virtio-iommu.c b/hw/virtio/virtio-iommu.c
index c96aacc..0e712b3 100644
--- a/hw/virtio/virtio-iommu.c
+++ b/hw/virtio/virtio-iommu.c
@@ -39,6 +39,11 @@
/* Max size */
#define VIOMMU_DEFAULT_QUEUE_SIZE 256
+#define VIOMMU_PROBE_SIZE 512
+
+#define SUPPORTED_PROBE_PROPERTIES (\
+ VIRTIO_IOMMU_PROBE_T_NONE | \
+ VIRTIO_IOMMU_PROBE_T_RESV_MEM)
typedef struct viommu_domain {
uint32_t id;
@@ -51,6 +56,7 @@ typedef struct viommu_endpoint {
viommu_domain *domain;
QLIST_ENTRY(viommu_endpoint) next;
VirtIOIOMMU *viommu;
+ GTree *reserved_regions;
} viommu_endpoint;
typedef struct viommu_interval {
@@ -65,6 +71,13 @@ typedef struct viommu_mapping {
uint32_t flags;
} viommu_mapping;
+typedef struct viommu_property_buffer {
+ viommu_endpoint *endpoint;
+ size_t filled;
+ uint8_t *start;
+ bool error;
+} viommu_property_buffer;
+
static inline uint16_t virtio_iommu_get_sid(IOMMUDevice *dev)
{
return PCI_BUILD_BDF(pci_bus_num(dev->bus), dev->devfn);
@@ -104,6 +117,9 @@ static viommu_endpoint *virtio_iommu_get_endpoint(VirtIOIOMMU *s,
ep->viommu = s;
trace_virtio_iommu_get_endpoint(ep_id);
g_tree_insert(s->endpoints, GUINT_TO_POINTER(ep_id), ep);
+ ep->reserved_regions = g_tree_new_full((GCompareDataFunc)interval_cmp,
+ NULL, (GDestroyNotify)g_free,
+ (GDestroyNotify)g_free);
return ep;
}
@@ -117,6 +133,7 @@ static void virtio_iommu_put_endpoint(gpointer data)
}
trace_virtio_iommu_put_endpoint(ep->id);
+ g_tree_destroy(ep->reserved_regions);
g_free(ep);
}
@@ -358,6 +375,139 @@ static int virtio_iommu_unmap(VirtIOIOMMU *s,
return VIRTIO_IOMMU_S_INVAL;
}
+/**
+ * virtio_iommu_fill_resv_mem_prop - Add a RESV_MEM probe
+ * property into the probe request buffer
+ *
+ * @key: interval handle
+ * @value: handle to the reserved memory region
+ * @data: handle to the probe request buffer state
+ */
+static gboolean virtio_iommu_fill_resv_mem_prop(gpointer key,
+ gpointer value,
+ gpointer data)
+{
+ struct virtio_iommu_probe_resv_mem *resv =
+ (struct virtio_iommu_probe_resv_mem *)value;
+ struct virtio_iommu_probe_property *prop;
+ struct virtio_iommu_probe_resv_mem *current;
+ viommu_property_buffer *bufstate = (viommu_property_buffer *)data;
+ size_t size = sizeof(*resv), total_size;
+
+ total_size = size + sizeof(*prop);
+
+ if (bufstate->filled + total_size >= VIOMMU_PROBE_SIZE) {
+ bufstate->error = true;
+ /* get the traversal stopped by returning true */
+ return true;
+ }
+ prop = (struct virtio_iommu_probe_property *)
+ (bufstate->start + bufstate->filled);
+ prop->type = cpu_to_le16(VIRTIO_IOMMU_PROBE_T_RESV_MEM) &
+ VIRTIO_IOMMU_PROBE_T_MASK;
+ prop->length = cpu_to_le16(size);
+
+ current = (struct virtio_iommu_probe_resv_mem *)prop->value;
+ *current = *resv;
+ bufstate->filled += total_size;
+ trace_virtio_iommu_fill_resv_property(bufstate->endpoint->id,
+ resv->subtype, resv->addr,
+ resv->size, resv->subtype,
+ bufstate->filled);
+ return false;
+}
+
+static int virtio_iommu_fill_none_prop(viommu_property_buffer *bufstate)
+{
+ struct virtio_iommu_probe_property *prop;
+
+ prop = (struct virtio_iommu_probe_property *)
+ (bufstate->start + bufstate->filled);
+ prop->type = cpu_to_le16(VIRTIO_IOMMU_PROBE_T_NONE)
+ & VIRTIO_IOMMU_PROBE_T_MASK;
+ prop->length = 0;
+ bufstate->filled += sizeof(*prop);
+ trace_virtio_iommu_fill_none_property(bufstate->endpoint->id);
+ return 0;
+}
+
+static int virtio_iommu_fill_property(int type,
+ viommu_property_buffer *bufstate)
+{
+ int ret = -ENOSPC;
+
+ if (bufstate->filled + 4 >= VIOMMU_PROBE_SIZE) {
+ /* Even the property header cannot be filled */
+ bufstate->error = true;
+ goto out;
+ }
+
+ switch (type) {
+ case VIRTIO_IOMMU_PROBE_T_NONE:
+ ret = virtio_iommu_fill_none_prop(bufstate);
+ break;
+ case VIRTIO_IOMMU_PROBE_T_RESV_MEM:
+ {
+ viommu_endpoint *ep = bufstate->endpoint;
+
+ g_tree_foreach(ep->reserved_regions,
+ virtio_iommu_fill_resv_mem_prop,
+ bufstate);
+ if (!bufstate->error) {
+ ret = 0;
+ }
+ break;
+ }
+ default:
+ ret = -ENOENT;
+ break;
+ }
+out:
+ if (ret) {
+ error_report("%s property of type=%d could not be filled (%d),"
+ " remaining size = 0x%lx",
+ __func__, type, ret, bufstate->filled);
+ }
+ return ret;
+}
+
+/**
+ * virtio_iommu_probe - Fill the probe request buffer with all
+ * the properties the device is able to return and add a NONE
+ * property at the end.
+ */
+static int virtio_iommu_probe(VirtIOIOMMU *s,
+ struct virtio_iommu_req_probe *req,
+ uint8_t *buf)
+{
+ uint32_t ep_id = le32_to_cpu(req->endpoint);
+ int16_t prop_types = SUPPORTED_PROBE_PROPERTIES, type;
+ viommu_property_buffer bufstate;
+ viommu_endpoint *ep;
+ int ret;
+
+ ep = g_tree_lookup(s->endpoints, GUINT_TO_POINTER(ep_id));
+ if (!ep) {
+ return -EINVAL;
+ }
+
+ bufstate.start = buf;
+ bufstate.filled = 0;
+ bufstate.error = false;
+ bufstate.endpoint = ep;
+
+ while ((type = ctz32(prop_types)) != 32) {
+ ret = virtio_iommu_fill_property(1 << type, &bufstate);
+ if (ret) {
+ break;
+ }
+ prop_types &= ~(1 << type);
+ }
+ virtio_iommu_fill_property(VIRTIO_IOMMU_PROBE_T_NONE, &bufstate);
+
+ return VIRTIO_IOMMU_S_OK;
+}
+
#define get_payload_size(req) (\
sizeof((req)) - sizeof(struct virtio_iommu_req_tail))
@@ -422,6 +572,24 @@ static int virtio_iommu_handle_unmap(VirtIOIOMMU *s,
return virtio_iommu_unmap(s, &req);
}
+static int virtio_iommu_handle_probe(VirtIOIOMMU *s,
+ struct iovec *iov,
+ unsigned int iov_cnt,
+ uint8_t *buf)
+{
+ struct virtio_iommu_req_probe req;
+ size_t sz, payload_sz;
+
+ payload_sz = sizeof(req);
+
+ sz = iov_to_buf(iov, iov_cnt, 0, &req, payload_sz);
+ if (sz != payload_sz) {
+ return VIRTIO_IOMMU_S_INVAL;
+ }
+
+ return virtio_iommu_probe(s, &req, buf);
+}
+
static void virtio_iommu_handle_command(VirtIODevice *vdev, VirtQueue *vq)
{
VirtIOIOMMU *s = VIRTIO_IOMMU(vdev);
@@ -466,16 +634,32 @@ static void virtio_iommu_handle_command(VirtIODevice *vdev, VirtQueue *vq)
case VIRTIO_IOMMU_T_UNMAP:
tail.status = virtio_iommu_handle_unmap(s, iov, iov_cnt);
break;
+ case VIRTIO_IOMMU_T_PROBE:
+ {
+ struct virtio_iommu_req_tail *ptail;
+ uint8_t *buf = g_malloc0(s->config.probe_size + sizeof(tail));
+
+ ptail = (struct virtio_iommu_req_tail *)
+ (buf + s->config.probe_size);
+ ptail->status = virtio_iommu_handle_probe(s, iov, iov_cnt, buf);
+
+ sz = iov_from_buf(elem->in_sg, elem->in_num, 0,
+ buf, s->config.probe_size + sizeof(tail));
+ g_free(buf);
+ assert(sz == s->config.probe_size + sizeof(tail));
+ goto push;
+ }
default:
tail.status = VIRTIO_IOMMU_S_UNSUPP;
}
- qemu_mutex_unlock(&s->mutex);
sz = iov_from_buf(elem->in_sg, elem->in_num, 0,
&tail, sizeof(tail));
assert(sz == sizeof(tail));
- virtqueue_push(vq, elem, sizeof(tail));
+push:
+ qemu_mutex_unlock(&s->mutex);
+ virtqueue_push(vq, elem, sz);
virtio_notify(vdev, vq);
g_free(elem);
}
@@ -568,6 +752,7 @@ static uint64_t virtio_iommu_get_features(VirtIODevice *vdev, uint64_t f,
virtio_add_feature(&f, VIRTIO_RING_F_INDIRECT_DESC);
virtio_add_feature(&f, VIRTIO_IOMMU_F_INPUT_RANGE);
virtio_add_feature(&f, VIRTIO_IOMMU_F_MAP_UNMAP);
+ virtio_add_feature(&f, VIRTIO_IOMMU_F_PROBE);
return f;
}
@@ -623,6 +808,7 @@ static void virtio_iommu_device_realize(DeviceState *dev, Error **errp)
s->config.page_size_mask = TARGET_PAGE_MASK;
s->config.input_range.end = -1UL;
+ s->config.probe_size = VIOMMU_PROBE_SIZE;
qemu_mutex_init(&s->mutex);
--
1.9.1
next prev parent reply other threads:[~2018-01-19 15:07 UTC|newest]
Thread overview: 46+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-01-19 14:48 [Qemu-arm] [RFC v5 00/22] VIRTIO-IOMMU device Eric Auger
2018-01-19 14:48 ` [Qemu-devel] " Eric Auger
2018-01-19 14:48 ` [Qemu-devel] [RFC v5 01/22] machine: Add a get_primary_pci_bus callback Eric Auger
2018-01-19 14:48 ` Eric Auger
2018-01-19 14:48 ` [Qemu-arm] [RFC v5 02/22] hw/arm/virt: Implement get_primary_pci_bus Eric Auger
2018-01-19 14:48 ` [Qemu-devel] " Eric Auger
2018-01-19 14:48 ` [Qemu-arm] [RFC v5 03/22] pc: " Eric Auger
2018-01-19 14:48 ` [Qemu-devel] " Eric Auger
2018-01-19 14:48 ` [Qemu-arm] [RFC v5 04/22] update-linux-headers: Import virtio_iommu.h Eric Auger
2018-01-19 14:48 ` [Qemu-devel] " Eric Auger
2018-01-19 14:48 ` [Qemu-arm] [RFC v5 05/22] linux-headers: Partial update for virtio-iommu Eric Auger
2018-01-19 14:48 ` [Qemu-devel] " Eric Auger
2018-01-19 14:48 ` [Qemu-arm] [RFC v5 06/22] virtio-iommu: Add skeleton Eric Auger
2018-01-19 14:48 ` [Qemu-devel] " Eric Auger
2018-01-19 14:49 ` [Qemu-arm] [RFC v5 07/22] virtio-iommu: Decode the command payload Eric Auger
2018-01-19 14:49 ` [Qemu-devel] " Eric Auger
2018-01-19 14:49 ` [Qemu-devel] [RFC v5 08/22] virtio-iommu: Add the iommu regions Eric Auger
2018-01-19 14:49 ` Eric Auger
2018-01-19 14:49 ` [Qemu-devel] [RFC v5 09/22] virtio-iommu: Register attached endpoints Eric Auger
2018-01-19 14:49 ` Eric Auger
2018-01-19 14:49 ` [Qemu-arm] [RFC v5 10/22] virtio-iommu: Implement attach/detach command Eric Auger
2018-01-19 14:49 ` [Qemu-devel] " Eric Auger
2018-01-19 14:49 ` [Qemu-arm] [RFC v5 11/22] virtio-iommu: Implement map/unmap Eric Auger
2018-01-19 14:49 ` [Qemu-devel] " Eric Auger
2018-01-19 14:49 ` [Qemu-arm] [RFC v5 12/22] virtio-iommu: Implement translate Eric Auger
2018-01-19 14:49 ` [Qemu-devel] " Eric Auger
2018-01-19 14:49 ` Eric Auger [this message]
2018-01-19 14:49 ` [Qemu-devel] [RFC v5 13/22] virtio-iommu: Implement probe request Eric Auger
2018-01-19 14:49 ` [Qemu-arm] [RFC v5 14/22] virtio-iommu: Add an msi_bypass property Eric Auger
2018-01-19 14:49 ` [Qemu-devel] " Eric Auger
2018-01-19 14:49 ` [Qemu-devel] [RFC v5 15/22] virtio-iommu: Implement fault reporting Eric Auger
2018-01-19 14:49 ` Eric Auger
2018-01-19 14:49 ` [Qemu-arm] [RFC v5 16/22] virtio_iommu: Handle reserved regions in translation process Eric Auger
2018-01-19 14:49 ` [Qemu-devel] " Eric Auger
2018-01-19 14:49 ` [Qemu-arm] [RFC v5 17/22] hw/arm/virt: Add virtio-iommu to the virt board Eric Auger
2018-01-19 14:49 ` [Qemu-devel] " Eric Auger
2018-01-19 14:49 ` [Qemu-arm] [RFC v5 18/22] hw/arm/virt-acpi-build: Add virtio-iommu node in IORT table Eric Auger
2018-01-19 14:49 ` [Qemu-devel] " Eric Auger
2018-01-19 14:49 ` [Qemu-arm] [RFC v5 19/22] memory.h: Add set_page_size_mask IOMMUMemoryRegion callback Eric Auger
2018-01-19 14:49 ` [Qemu-devel] " Eric Auger
2018-01-19 14:49 ` [Qemu-arm] [RFC v5 20/22] hw/vfio/common: Set the IOMMUMemoryRegion supported page sizes Eric Auger
2018-01-19 14:49 ` [Qemu-devel] " Eric Auger
2018-01-19 14:49 ` [Qemu-arm] [RFC v5 21/22] virtio-iommu: Implement set_page_size_mask Eric Auger
2018-01-19 14:49 ` [Qemu-devel] " Eric Auger
2018-01-19 14:49 ` [Qemu-devel] [RFC v5 22/22] hw/vfio/common: Do not print error when viommu translates into an mmio region Eric Auger
2018-01-19 14:49 ` 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=1516373355-305-14-git-send-email-eric.auger@redhat.com \
--to=eric.auger@redhat.com \
--cc=alex.williamson@redhat.com \
--cc=bharat.bhushan@nxp.com \
--cc=christoffer.dall@linaro.org \
--cc=drjones@redhat.com \
--cc=eric.auger.pro@gmail.com \
--cc=jean-philippe.brucker@arm.com \
--cc=kevin.tian@intel.com \
--cc=linuc.decode@gmail.com \
--cc=marc.zyngier@arm.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 \
--cc=wei@redhat.com \
--cc=will.deacon@arm.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.