Hi Baolu,

On Sat, Mar 14, 2020 at 09:07:01AM +0800, Lu Baolu wrote:
> +static int iommu_group_change_def_domain(struct iommu_group *group, int type)
> +{
> +     struct group_device *grp_dev, *temp;
> +     struct iommu_domain *new, *old;
> +     const struct iommu_ops *ops;
> +     int ret = 0;
> +
> +     if ((type != IOMMU_DOMAIN_IDENTITY && type != IOMMU_DOMAIN_DMA) ||
> +         !group->default_domain || type == group->default_domain->type ||
> +         !group->default_domain->ops)
> +             return -EINVAL;
> +
> +     if (group->domain != group->default_domain)
> +             return -EBUSY;
> +
> +     iommu_group_ref_get(group);
> +     old = group->default_domain;
> +     ops = group->default_domain->ops;
> +
> +     /* Allocate a new domain of requested type. */
> +     new = ops->domain_alloc(type);
> +     if (!new) {
> +             ret = -ENOMEM;
> +             goto domain_out;
> +     }
> +     new->type = type;
> +     new->ops = ops;
> +     new->pgsize_bitmap = group->default_domain->pgsize_bitmap;
> +
> +     group->default_domain = new;
> +     group->domain = new;
> +     list_for_each_entry_safe(grp_dev, temp, &group->devices, list) {
> +             struct device *dev;
> +
> +             dev = grp_dev->dev;
> +             if (device_is_bound(dev)) {
> +                     ret = -EINVAL;
> +                     goto device_out;
> +             }
> +
> +             iommu_group_create_direct_mappings(group, dev);
> +             ret = __iommu_attach_device(group->domain, dev);
> +             if (ret)
> +                     goto device_out;

In case of a failure here with a group containing multiple devices, the
other devices temporarily lose their mappings. Please only do the
device_is_bound() check in the loop and the actual re-attachment of the
group with a call to __iommu_attach_group().

Regards,

        Joerg
_______________________________________________
iommu mailing list
[email protected]
https://lists.linuxfoundation.org/mailman/listinfo/iommu

Reply via email to