@@ -3108,41 +3108,49 @@ static int __iommu_group_alloc_blocking_domain(struct iommu_group *group)
31083108 return 0 ;
31093109}
31103110
3111+ static int __iommu_take_dma_ownership (struct iommu_group * group , void * owner )
3112+ {
3113+ int ret ;
3114+
3115+ if ((group -> domain && group -> domain != group -> default_domain ) ||
3116+ !xa_empty (& group -> pasid_array ))
3117+ return - EBUSY ;
3118+
3119+ ret = __iommu_group_alloc_blocking_domain (group );
3120+ if (ret )
3121+ return ret ;
3122+ ret = __iommu_group_set_domain (group , group -> blocking_domain );
3123+ if (ret )
3124+ return ret ;
3125+
3126+ group -> owner = owner ;
3127+ group -> owner_cnt ++ ;
3128+ return 0 ;
3129+ }
3130+
31113131/**
31123132 * iommu_group_claim_dma_owner() - Set DMA ownership of a group
31133133 * @group: The group.
31143134 * @owner: Caller specified pointer. Used for exclusive ownership.
31153135 *
3116- * This is to support backward compatibility for vfio which manages
3117- * the dma ownership in iommu_group level. New invocations on this
3118- * interface should be prohibited .
3136+ * This is to support backward compatibility for vfio which manages the dma
3137+ * ownership in iommu_group level. New invocations on this interface should be
3138+ * prohibited. Only a single owner may exist for a group .
31193139 */
31203140int iommu_group_claim_dma_owner (struct iommu_group * group , void * owner )
31213141{
31223142 int ret = 0 ;
31233143
3144+ if (WARN_ON (!owner ))
3145+ return - EINVAL ;
3146+
31243147 mutex_lock (& group -> mutex );
31253148 if (group -> owner_cnt ) {
31263149 ret = - EPERM ;
31273150 goto unlock_out ;
3128- } else {
3129- if ((group -> domain && group -> domain != group -> default_domain ) ||
3130- !xa_empty (& group -> pasid_array )) {
3131- ret = - EBUSY ;
3132- goto unlock_out ;
3133- }
3134-
3135- ret = __iommu_group_alloc_blocking_domain (group );
3136- if (ret )
3137- goto unlock_out ;
3138-
3139- ret = __iommu_group_set_domain (group , group -> blocking_domain );
3140- if (ret )
3141- goto unlock_out ;
3142- group -> owner = owner ;
31433151 }
31443152
3145- group -> owner_cnt ++ ;
3153+ ret = __iommu_take_dma_ownership ( group , owner ) ;
31463154unlock_out :
31473155 mutex_unlock (& group -> mutex );
31483156
@@ -3151,30 +3159,91 @@ int iommu_group_claim_dma_owner(struct iommu_group *group, void *owner)
31513159EXPORT_SYMBOL_GPL (iommu_group_claim_dma_owner );
31523160
31533161/**
3154- * iommu_group_release_dma_owner() - Release DMA ownership of a group
3155- * @group: The group.
3162+ * iommu_device_claim_dma_owner() - Set DMA ownership of a device
3163+ * @dev: The device.
3164+ * @owner: Caller specified pointer. Used for exclusive ownership.
31563165 *
3157- * Release the DMA ownership claimed by iommu_group_claim_dma_owner().
3166+ * Claim the DMA ownership of a device. Multiple devices in the same group may
3167+ * concurrently claim ownership if they present the same owner value. Returns 0
3168+ * on success and error code on failure
31583169 */
3159- void iommu_group_release_dma_owner (struct iommu_group * group )
3170+ int iommu_device_claim_dma_owner (struct device * dev , void * owner )
31603171{
3161- int ret ;
3172+ struct iommu_group * group = iommu_group_get (dev );
3173+ int ret = 0 ;
3174+
3175+ if (!group )
3176+ return - ENODEV ;
3177+ if (WARN_ON (!owner ))
3178+ return - EINVAL ;
31623179
31633180 mutex_lock (& group -> mutex );
3181+ if (group -> owner_cnt ) {
3182+ if (group -> owner != owner ) {
3183+ ret = - EPERM ;
3184+ goto unlock_out ;
3185+ }
3186+ group -> owner_cnt ++ ;
3187+ goto unlock_out ;
3188+ }
3189+
3190+ ret = __iommu_take_dma_ownership (group , owner );
3191+ unlock_out :
3192+ mutex_unlock (& group -> mutex );
3193+ iommu_group_put (group );
3194+
3195+ return ret ;
3196+ }
3197+ EXPORT_SYMBOL_GPL (iommu_device_claim_dma_owner );
3198+
3199+ static void __iommu_release_dma_ownership (struct iommu_group * group )
3200+ {
3201+ int ret ;
3202+
31643203 if (WARN_ON (!group -> owner_cnt || !group -> owner ||
31653204 !xa_empty (& group -> pasid_array )))
3166- goto unlock_out ;
3205+ return ;
31673206
31683207 group -> owner_cnt = 0 ;
31693208 group -> owner = NULL ;
31703209 ret = __iommu_group_set_domain (group , group -> default_domain );
31713210 WARN (ret , "iommu driver failed to attach the default domain" );
3211+ }
31723212
3173- unlock_out :
3213+ /**
3214+ * iommu_group_release_dma_owner() - Release DMA ownership of a group
3215+ * @dev: The device
3216+ *
3217+ * Release the DMA ownership claimed by iommu_group_claim_dma_owner().
3218+ */
3219+ void iommu_group_release_dma_owner (struct iommu_group * group )
3220+ {
3221+ mutex_lock (& group -> mutex );
3222+ __iommu_release_dma_ownership (group );
31743223 mutex_unlock (& group -> mutex );
31753224}
31763225EXPORT_SYMBOL_GPL (iommu_group_release_dma_owner );
31773226
3227+ /**
3228+ * iommu_device_release_dma_owner() - Release DMA ownership of a device
3229+ * @group: The device.
3230+ *
3231+ * Release the DMA ownership claimed by iommu_device_claim_dma_owner().
3232+ */
3233+ void iommu_device_release_dma_owner (struct device * dev )
3234+ {
3235+ struct iommu_group * group = iommu_group_get (dev );
3236+
3237+ mutex_lock (& group -> mutex );
3238+ if (group -> owner_cnt > 1 )
3239+ group -> owner_cnt -- ;
3240+ else
3241+ __iommu_release_dma_ownership (group );
3242+ mutex_unlock (& group -> mutex );
3243+ iommu_group_put (group );
3244+ }
3245+ EXPORT_SYMBOL_GPL (iommu_device_release_dma_owner );
3246+
31783247/**
31793248 * iommu_group_dma_owner_claimed() - Query group dma ownership status
31803249 * @group: The group.
0 commit comments