> From: Lu Baolu <baolu.lu@xxxxxxxxxxxxxxx> > Sent: Tuesday, April 30, 2024 10:57 PM > > +/* Add an attach handle to the group's pasid array. */ > +static struct iommu_attach_handle * > +iommu_attach_handle_set(struct iommu_domain *domain, > + struct iommu_group *group, ioasid_t pasid) > +{ > + struct iommu_attach_handle *handle; > + void *curr; > + > + handle = kzalloc(sizeof(*handle), GFP_KERNEL); > + if (!handle) > + return ERR_PTR(-ENOMEM); > + > + handle->domain = domain; > + curr = xa_cmpxchg(&group->pasid_array, pasid, NULL, handle, > GFP_KERNEL); this could be just xa_insert() which returns -EBUSY if the entry isn't NULL. > + if (curr) { > + kfree(handle); > + return xa_err(curr) ? curr : ERR_PTR(-EBUSY); 'curr' is not an error pointer. You need ERR_PTR(xa_err(curr)). > int iommu_attach_group(struct iommu_domain *domain, struct > iommu_group *group) > { > + struct iommu_attach_handle *handle; > int ret; > > mutex_lock(&group->mutex); > + handle = iommu_attach_handle_set(domain, group, > IOMMU_NO_PASID); > + if (IS_ERR(handle)) { > + ret = PTR_ERR(handle); > + goto out_unlock; > + } > ret = __iommu_attach_group(domain, group); > + if (ret) > + goto out_remove_handle; > mutex_unlock(&group->mutex); It's slightly better to set the handler after __iommu_attach_group(). doing so is aligned to the sequence in iommu_group_replace_domain(). > @@ -2211,13 +2307,33 @@ EXPORT_SYMBOL_GPL(iommu_attach_group); > int iommu_group_replace_domain(struct iommu_group *group, > struct iommu_domain *new_domain) > { > + struct iommu_domain *old_domain = group->domain; > + struct iommu_attach_handle *handle; > int ret; > > if (!new_domain) > return -EINVAL; > > + if (new_domain == old_domain) > + return 0; > + __iommu_group_set_domain() already does the check.