Skip to content

Commit 4c8444f

Browse files
LuBaolujoergroedel
authored andcommitted
iommu: Cleanup iommu_change_dev_def_domain()
As the singleton group limitation has been removed, cleanup the code in iommu_change_dev_def_domain() accordingly. Documentation is also updated. Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com> Reviewed-by: Jason Gunthorpe <jgg@nvidia.com> Link: https://lore.kernel.org/r/20230322064956.263419-7-baolu.lu@linux.intel.com Signed-off-by: Joerg Roedel <jroedel@suse.de>
1 parent 49a22aa commit 4c8444f

2 files changed

Lines changed: 21 additions & 63 deletions

File tree

Documentation/ABI/testing/sysfs-kernel-iommu_groups

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@ Description: /sys/kernel/iommu_groups/<grp_id>/type shows the type of default
5353

5454
The default domain type of a group may be modified only when
5555

56-
- The group has only one device.
5756
- The device in the group is not bound to any device driver.
5857
So, the users must unbind the appropriate driver before
5958
changing the default domain type.

drivers/iommu/iommu.c

Lines changed: 21 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -2867,11 +2867,10 @@ int iommu_dev_disable_feature(struct device *dev, enum iommu_dev_features feat)
28672867
EXPORT_SYMBOL_GPL(iommu_dev_disable_feature);
28682868

28692869
/*
2870-
* Changes the default domain of an iommu group that has *only* one device
2870+
* Changes the default domain of an iommu group
28712871
*
28722872
* @group: The group for which the default domain should be changed
2873-
* @prev_dev: The device in the group (this is used to make sure that the device
2874-
* hasn't changed after the caller has called this function)
2873+
* @dev: The first device in the group
28752874
* @type: The type of the new default domain that gets associated with the group
28762875
*
28772876
* Returns 0 on success and error code on failure
@@ -2882,103 +2881,63 @@ EXPORT_SYMBOL_GPL(iommu_dev_disable_feature);
28822881
* Please take a closer look if intended to use for other purposes.
28832882
*/
28842883
static int iommu_change_dev_def_domain(struct iommu_group *group,
2885-
struct device *prev_dev, int type)
2884+
struct device *dev, int type)
28862885
{
2886+
struct __group_domain_type gtype = {NULL, 0};
28872887
struct iommu_domain *prev_dom;
2888-
struct group_device *grp_dev;
2889-
int ret, dev_def_dom;
2890-
struct device *dev;
2888+
int ret;
28912889

28922890
lockdep_assert_held(&group->mutex);
28932891

2894-
if (group->default_domain != group->domain) {
2895-
dev_err_ratelimited(prev_dev, "Group not assigned to default domain\n");
2896-
ret = -EBUSY;
2897-
goto out;
2898-
}
2899-
2900-
/*
2901-
* iommu group wasn't locked while acquiring device lock in
2902-
* iommu_group_store_type(). So, make sure that the device count hasn't
2903-
* changed while acquiring device lock.
2904-
*
2905-
* Changing default domain of an iommu group with two or more devices
2906-
* isn't supported because there could be a potential deadlock. Consider
2907-
* the following scenario. T1 is trying to acquire device locks of all
2908-
* the devices in the group and before it could acquire all of them,
2909-
* there could be another thread T2 (from different sub-system and use
2910-
* case) that has already acquired some of the device locks and might be
2911-
* waiting for T1 to release other device locks.
2912-
*/
2913-
if (iommu_group_device_count(group) != 1) {
2914-
dev_err_ratelimited(prev_dev, "Cannot change default domain: Group has more than one device\n");
2915-
ret = -EINVAL;
2916-
goto out;
2917-
}
2918-
2919-
/* Since group has only one device */
2920-
grp_dev = list_first_entry(&group->devices, struct group_device, list);
2921-
dev = grp_dev->dev;
2922-
2923-
if (prev_dev != dev) {
2924-
dev_err_ratelimited(prev_dev, "Cannot change default domain: Device has been changed\n");
2925-
ret = -EBUSY;
2926-
goto out;
2927-
}
2928-
29292892
prev_dom = group->default_domain;
2930-
if (!prev_dom) {
2931-
ret = -EINVAL;
2932-
goto out;
2933-
}
2934-
2935-
dev_def_dom = iommu_get_def_domain_type(dev);
2893+
__iommu_group_for_each_dev(group, &gtype,
2894+
probe_get_default_domain_type);
29362895
if (!type) {
29372896
/*
29382897
* If the user hasn't requested any specific type of domain and
29392898
* if the device supports both the domains, then default to the
29402899
* domain the device was booted with
29412900
*/
2942-
type = dev_def_dom ? : iommu_def_domain_type;
2943-
} else if (dev_def_dom && type != dev_def_dom) {
2944-
dev_err_ratelimited(prev_dev, "Device cannot be in %s domain\n",
2901+
type = gtype.type ? : iommu_def_domain_type;
2902+
} else if (gtype.type && type != gtype.type) {
2903+
dev_err_ratelimited(dev, "Device cannot be in %s domain\n",
29452904
iommu_domain_type_str(type));
2946-
ret = -EINVAL;
2947-
goto out;
2905+
return -EINVAL;
29482906
}
29492907

29502908
/*
29512909
* Switch to a new domain only if the requested domain type is different
29522910
* from the existing default domain type
29532911
*/
2954-
if (prev_dom->type == type) {
2955-
ret = 0;
2956-
goto out;
2957-
}
2912+
if (prev_dom->type == type)
2913+
return 0;
2914+
2915+
group->default_domain = NULL;
2916+
group->domain = NULL;
29582917

29592918
/* Sets group->default_domain to the newly allocated domain */
29602919
ret = iommu_group_alloc_default_domain(dev->bus, group, type);
29612920
if (ret)
2962-
goto out;
2921+
goto restore_old_domain;
29632922

2964-
ret = iommu_create_device_direct_mappings(group, dev);
2923+
ret = iommu_group_create_direct_mappings(group);
29652924
if (ret)
29662925
goto free_new_domain;
29672926

2968-
ret = __iommu_attach_device(group->default_domain, dev);
2927+
ret = __iommu_attach_group(group->default_domain, group);
29692928
if (ret)
29702929
goto free_new_domain;
29712930

2972-
group->domain = group->default_domain;
29732931
iommu_domain_free(prev_dom);
29742932

29752933
return 0;
29762934

29772935
free_new_domain:
29782936
iommu_domain_free(group->default_domain);
2937+
restore_old_domain:
29792938
group->default_domain = prev_dom;
29802939
group->domain = prev_dom;
2981-
out:
2940+
29822941
return ret;
29832942
}
29842943

0 commit comments

Comments
 (0)