On Mon, 13 Sep 2021 09:16:05 +0200 Christoph Hellwig <hch@xxxxxx> wrote: > The external_domain concept rather misleading and not actually needed. > Replace it with a list of emulated groups in struct vfio_iommu. > > Signed-off-by: Christoph Hellwig <hch@xxxxxx> > Reviewed-by: Jason Gunthorpe <jgg@xxxxxxxxxx> > Reviewed-by: Kevin Tian <kevin.tian@xxxxxxxxx> > --- > drivers/vfio/vfio_iommu_type1.c | 121 ++++++++++++++------------------ > 1 file changed, 54 insertions(+), 67 deletions(-) > > diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c > index a48e9f597cb213..d2db62cb2aaa39 100644 > --- a/drivers/vfio/vfio_iommu_type1.c > +++ b/drivers/vfio/vfio_iommu_type1.c ... > @@ -2163,62 +2163,52 @@ static int vfio_iommu_type1_attach_group(void *iommu_data, > struct vfio_iommu_group *group; > struct vfio_domain *domain, *d; > struct bus_type *bus = NULL; > - int ret; > bool resv_msi, msi_remap; > phys_addr_t resv_msi_base = 0; > struct iommu_domain_geometry *geo; > LIST_HEAD(iova_copy); > LIST_HEAD(group_resv_regions); > + int ret = -EINVAL; > > mutex_lock(&iommu->lock); > > /* Check for duplicates */ > - if (vfio_iommu_find_iommu_group(iommu, iommu_group)) { > - mutex_unlock(&iommu->lock); > - return -EINVAL; > - } > + if (vfio_iommu_find_iommu_group(iommu, iommu_group)) > + goto out_unlock; > > + ret = -ENOMEM; > group = kzalloc(sizeof(*group), GFP_KERNEL); > - domain = kzalloc(sizeof(*domain), GFP_KERNEL); > - if (!group || !domain) { > - ret = -ENOMEM; > - goto out_free; > - } > - > + if (!group) > + goto out_unlock; > group->iommu_group = iommu_group; > > - /* Determine bus_type in order to allocate a domain */ > - ret = iommu_group_for_each_dev(iommu_group, &bus, vfio_bus_type); > - if (ret) > - goto out_free; > - > if (type == VFIO_EMULATED_IOMMU) { > - if (!iommu->external_domain) { > - INIT_LIST_HEAD(&domain->group_list); > - iommu->external_domain = domain; > - vfio_update_pgsize_bitmap(iommu); > - } else { > - kfree(domain); > - } > - > - list_add(&group->next, &iommu->external_domain->group_list); > + list_add(&group->next, &iommu->emulated_iommu_groups); > /* > - * Non-iommu backed group cannot dirty memory directly, it can > + * An emulated IOMMU group cannot dirty memory directly, it can > * only use interfaces that provide dirty tracking. > * The iommu scope can only be promoted with the addition of a > * dirty tracking group. > */ > group->pinned_page_dirty_scope = true; > - mutex_unlock(&iommu->lock); > - > - return 0; > + ret = 0; > + goto out_unlock; > } I think this dropped the call to vfio_update_pgsize_bitmap(), which would leave iommu->pgsize_bitmap = 0 for a container hosting only mdev devices, which leads us to undefined behavior when we're using ffs on it to validate maps, unmaps, dirty bitmap support, etc. Did I miss this getting moved elsewhere? Thanks, Alex