On 5/15/24 3:17 PM, Tian, Kevin wrote:
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.
Yes, exactly.
+ 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)).
Fixed.
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().
I did it in this way because erasing an attach handle is easier than
rolling back the group to the previous domain from the perspective of
coding. I didn't realize attaching the group and storing the attach
handle had to be done in a specific order.
@@ -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.
Removed.
Best regards,
baolu