Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Lu Baolu and committed by
Joerg Roedel
4c8444f1 49a22aae

+21 -63
-1
Documentation/ABI/testing/sysfs-kernel-iommu_groups
··· 53 53 54 54 The default domain type of a group may be modified only when 55 55 56 - - The group has only one device. 57 56 - The device in the group is not bound to any device driver. 58 57 So, the users must unbind the appropriate driver before 59 58 changing the default domain type.
+21 -62
drivers/iommu/iommu.c
··· 2867 2867 EXPORT_SYMBOL_GPL(iommu_dev_disable_feature); 2868 2868 2869 2869 /* 2870 - * Changes the default domain of an iommu group that has *only* one device 2870 + * Changes the default domain of an iommu group 2871 2871 * 2872 2872 * @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 2875 2874 * @type: The type of the new default domain that gets associated with the group 2876 2875 * 2877 2876 * Returns 0 on success and error code on failure ··· 2881 2882 * Please take a closer look if intended to use for other purposes. 2882 2883 */ 2883 2884 static int iommu_change_dev_def_domain(struct iommu_group *group, 2884 - struct device *prev_dev, int type) 2885 + struct device *dev, int type) 2885 2886 { 2887 + struct __group_domain_type gtype = {NULL, 0}; 2886 2888 struct iommu_domain *prev_dom; 2887 - struct group_device *grp_dev; 2888 - int ret, dev_def_dom; 2889 - struct device *dev; 2889 + int ret; 2890 2890 2891 2891 lockdep_assert_held(&group->mutex); 2892 2892 2893 - if (group->default_domain != group->domain) { 2894 - dev_err_ratelimited(prev_dev, "Group not assigned to default domain\n"); 2895 - ret = -EBUSY; 2896 - goto out; 2897 - } 2898 - 2899 - /* 2900 - * iommu group wasn't locked while acquiring device lock in 2901 - * iommu_group_store_type(). So, make sure that the device count hasn't 2902 - * changed while acquiring device lock. 2903 - * 2904 - * Changing default domain of an iommu group with two or more devices 2905 - * isn't supported because there could be a potential deadlock. Consider 2906 - * the following scenario. T1 is trying to acquire device locks of all 2907 - * the devices in the group and before it could acquire all of them, 2908 - * there could be another thread T2 (from different sub-system and use 2909 - * case) that has already acquired some of the device locks and might be 2910 - * waiting for T1 to release other device locks. 2911 - */ 2912 - if (iommu_group_device_count(group) != 1) { 2913 - dev_err_ratelimited(prev_dev, "Cannot change default domain: Group has more than one device\n"); 2914 - ret = -EINVAL; 2915 - goto out; 2916 - } 2917 - 2918 - /* Since group has only one device */ 2919 - grp_dev = list_first_entry(&group->devices, struct group_device, list); 2920 - dev = grp_dev->dev; 2921 - 2922 - if (prev_dev != dev) { 2923 - dev_err_ratelimited(prev_dev, "Cannot change default domain: Device has been changed\n"); 2924 - ret = -EBUSY; 2925 - goto out; 2926 - } 2927 - 2928 2893 prev_dom = group->default_domain; 2929 - if (!prev_dom) { 2930 - ret = -EINVAL; 2931 - goto out; 2932 - } 2933 - 2934 - dev_def_dom = iommu_get_def_domain_type(dev); 2894 + __iommu_group_for_each_dev(group, &gtype, 2895 + probe_get_default_domain_type); 2935 2896 if (!type) { 2936 2897 /* 2937 2898 * If the user hasn't requested any specific type of domain and 2938 2899 * if the device supports both the domains, then default to the 2939 2900 * domain the device was booted with 2940 2901 */ 2941 - type = dev_def_dom ? : iommu_def_domain_type; 2942 - } else if (dev_def_dom && type != dev_def_dom) { 2943 - dev_err_ratelimited(prev_dev, "Device cannot be in %s domain\n", 2902 + type = gtype.type ? : iommu_def_domain_type; 2903 + } else if (gtype.type && type != gtype.type) { 2904 + dev_err_ratelimited(dev, "Device cannot be in %s domain\n", 2944 2905 iommu_domain_type_str(type)); 2945 - ret = -EINVAL; 2946 - goto out; 2906 + return -EINVAL; 2947 2907 } 2948 2908 2949 2909 /* 2950 2910 * Switch to a new domain only if the requested domain type is different 2951 2911 * from the existing default domain type 2952 2912 */ 2953 - if (prev_dom->type == type) { 2954 - ret = 0; 2955 - goto out; 2956 - } 2913 + if (prev_dom->type == type) 2914 + return 0; 2915 + 2916 + group->default_domain = NULL; 2917 + group->domain = NULL; 2957 2918 2958 2919 /* Sets group->default_domain to the newly allocated domain */ 2959 2920 ret = iommu_group_alloc_default_domain(dev->bus, group, type); 2960 2921 if (ret) 2961 - goto out; 2922 + goto restore_old_domain; 2962 2923 2963 - ret = iommu_create_device_direct_mappings(group, dev); 2924 + ret = iommu_group_create_direct_mappings(group); 2964 2925 if (ret) 2965 2926 goto free_new_domain; 2966 2927 2967 - ret = __iommu_attach_device(group->default_domain, dev); 2928 + ret = __iommu_attach_group(group->default_domain, group); 2968 2929 if (ret) 2969 2930 goto free_new_domain; 2970 2931 2971 - group->domain = group->default_domain; 2972 2932 iommu_domain_free(prev_dom); 2973 2933 2974 2934 return 0; 2975 2935 2976 2936 free_new_domain: 2977 2937 iommu_domain_free(group->default_domain); 2938 + restore_old_domain: 2978 2939 group->default_domain = prev_dom; 2979 2940 group->domain = prev_dom; 2980 - out: 2941 + 2981 2942 return ret; 2982 2943 } 2983 2944