@@ -114,8 +114,8 @@ static void virtio_iommu_put_endpoint(gpointer data)
g_free(ep);
}
-viommu_domain *virtio_iommu_get_domain(VirtIOIOMMU *s, uint32_t domain_id);
-viommu_domain *virtio_iommu_get_domain(VirtIOIOMMU *s, uint32_t domain_id)
+static viommu_domain *virtio_iommu_get_domain(VirtIOIOMMU *s,
+ uint32_t domain_id)
{
viommu_domain *domain;
@@ -194,6 +194,8 @@ static int virtio_iommu_attach(VirtIOIOMMU *s,
uint32_t domain_id = le32_to_cpu(req->domain);
uint32_t ep_id = le32_to_cpu(req->endpoint);
uint32_t reserved = le32_to_cpu(req->reserved);
+ viommu_domain *domain;
+ viommu_endpoint *ep;
trace_virtio_iommu_attach(domain_id, ep_id);
@@ -201,7 +203,22 @@ static int virtio_iommu_attach(VirtIOIOMMU *s,
return VIRTIO_IOMMU_S_INVAL;
}
- return VIRTIO_IOMMU_S_UNSUPP;
+ ep = virtio_iommu_get_endpoint(s, ep_id);
+ if (ep->domain) {
+ /*
+ * the device is already attached to a domain,
+ * detach it first
+ */
+ virtio_iommu_detach_endpoint_from_domain(ep);
+ }
+
+ domain = virtio_iommu_get_domain(s, domain_id);
+ QLIST_INSERT_HEAD(&domain->endpoint_list, ep, next);
+
+ ep->domain = domain;
+ g_tree_ref(domain->mappings);
+
+ return VIRTIO_IOMMU_S_OK;
}
static int virtio_iommu_detach(VirtIOIOMMU *s,
@@ -209,14 +226,24 @@ static int virtio_iommu_detach(VirtIOIOMMU *s,
{
uint32_t ep_id = le32_to_cpu(req->endpoint);
uint32_t reserved = le32_to_cpu(req->reserved);
-
- trace_virtio_iommu_detach(ep_id);
+ viommu_endpoint *ep;
if (reserved) {
return VIRTIO_IOMMU_S_INVAL;
}
- return VIRTIO_IOMMU_S_UNSUPP;
+ ep = g_tree_lookup(s->endpoints, GUINT_TO_POINTER(ep_id));
+ if (!ep) {
+ return VIRTIO_IOMMU_S_NOENT;
+ }
+
+ if (!ep->domain) {
+ return VIRTIO_IOMMU_S_INVAL;
+ }
+
+ virtio_iommu_detach_endpoint_from_domain(ep);
+ trace_virtio_iommu_detach(ep_id);
+ return VIRTIO_IOMMU_S_OK;
}
static int virtio_iommu_map(VirtIOIOMMU *s,
This patch implements the endpoint attach/detach to/from a domain. Signed-off-by: Eric Auger <eric.auger@redhat.com> --- hw/virtio/virtio-iommu.c | 39 +++++++++++++++++++++++++++++++++------ 1 file changed, 33 insertions(+), 6 deletions(-)