On Tue, Jul 30, 2019 at 07:21:29PM +0200, Eric Auger wrote: > This patch implements the endpoint attach/detach to/from > a domain. > > Signed-off-by: Eric Auger <eric.au...@redhat.com> > > --- > --- > hw/virtio/virtio-iommu.c | 40 ++++++++++++++++++++++++++++++++++------ > 1 file changed, 34 insertions(+), 6 deletions(-) > > diff --git a/hw/virtio/virtio-iommu.c b/hw/virtio/virtio-iommu.c > index 77dccecc0a..5ea0930cc2 100644 > --- a/hw/virtio/virtio-iommu.c > +++ b/hw/virtio/virtio-iommu.c > @@ -80,8 +80,8 @@ static void > virtio_iommu_detach_endpoint_from_domain(viommu_endpoint *ep) > ep->domain = NULL; > } > > -viommu_endpoint *virtio_iommu_get_endpoint(VirtIOIOMMU *s, uint32_t ep_id); > -viommu_endpoint *virtio_iommu_get_endpoint(VirtIOIOMMU *s, uint32_t ep_id)
These lines were just introduced in previous patch, I wanted to ask why the definition was needed but I don't know whether it'll be used in follow up patches. Looks like it wasn't really used. I would prefer patches like these to be squashed together not only to avoid the maintainance of diffs like this between patches, but also as a reviewer it'll be easier too when with all the contexts together. But I won't ask for it because it can be a personal preference only... > +static viommu_endpoint *virtio_iommu_get_endpoint(VirtIOIOMMU *s, > + uint32_t ep_id) > { > viommu_endpoint *ep; > > @@ -110,8 +110,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; > > @@ -187,10 +187,27 @@ 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); > + viommu_domain *domain; > + viommu_endpoint *ep; > > trace_virtio_iommu_attach(domain_id, ep_id); > > - 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); Hmm... so this can be called without virtio_iommu_put_endpoint(). Then I think we'd better move: g_tree_unref(ep->domain->mappings); >From virtio_iommu_put_endpoint() to inside virtio_iommu_detach_endpoint_from_domain() otherwise domain refs might leak? > + } > + > + 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; > } Regards, -- Peter Xu