@@ -43,7 +43,6 @@ static struct iommu_mm_data *iommu_alloc_mm_data(struct mm_struct *mm, struct de
4343 }
4444 iommu_mm -> pasid = pasid ;
4545 INIT_LIST_HEAD (& iommu_mm -> sva_domains );
46- INIT_LIST_HEAD (& iommu_mm -> sva_handles );
4746 /*
4847 * Make sure the write to mm->iommu_mm is not reordered in front of
4948 * initialization to iommu_mm fields. If it does, readers may see a
@@ -71,11 +70,16 @@ static struct iommu_mm_data *iommu_alloc_mm_data(struct mm_struct *mm, struct de
7170 */
7271struct iommu_sva * iommu_sva_bind_device (struct device * dev , struct mm_struct * mm )
7372{
73+ struct iommu_group * group = dev -> iommu_group ;
74+ struct iommu_attach_handle * attach_handle ;
7475 struct iommu_mm_data * iommu_mm ;
7576 struct iommu_domain * domain ;
7677 struct iommu_sva * handle ;
7778 int ret ;
7879
80+ if (!group )
81+ return ERR_PTR (- ENODEV );
82+
7983 mutex_lock (& iommu_sva_lock );
8084
8185 /* Allocate mm->pasid if necessary. */
@@ -85,12 +89,22 @@ struct iommu_sva *iommu_sva_bind_device(struct device *dev, struct mm_struct *mm
8589 goto out_unlock ;
8690 }
8791
88- list_for_each_entry (handle , & mm -> iommu_mm -> sva_handles , handle_item ) {
89- if (handle -> dev == dev ) {
90- refcount_inc (& handle -> users );
91- mutex_unlock (& iommu_sva_lock );
92- return handle ;
92+ /* A bond already exists, just take a reference`. */
93+ attach_handle = iommu_attach_handle_get (group , iommu_mm -> pasid , IOMMU_DOMAIN_SVA );
94+ if (!IS_ERR (attach_handle )) {
95+ handle = container_of (attach_handle , struct iommu_sva , handle );
96+ if (attach_handle -> domain -> mm != mm ) {
97+ ret = - EBUSY ;
98+ goto out_unlock ;
9399 }
100+ refcount_inc (& handle -> users );
101+ mutex_unlock (& iommu_sva_lock );
102+ return handle ;
103+ }
104+
105+ if (PTR_ERR (attach_handle ) != - ENOENT ) {
106+ ret = PTR_ERR (attach_handle );
107+ goto out_unlock ;
94108 }
95109
96110 handle = kzalloc (sizeof (* handle ), GFP_KERNEL );
@@ -101,7 +115,8 @@ struct iommu_sva *iommu_sva_bind_device(struct device *dev, struct mm_struct *mm
101115
102116 /* Search for an existing domain. */
103117 list_for_each_entry (domain , & mm -> iommu_mm -> sva_domains , next ) {
104- ret = iommu_attach_device_pasid (domain , dev , iommu_mm -> pasid );
118+ ret = iommu_attach_device_pasid (domain , dev , iommu_mm -> pasid ,
119+ & handle -> handle );
105120 if (!ret ) {
106121 domain -> users ++ ;
107122 goto out ;
@@ -115,18 +130,17 @@ struct iommu_sva *iommu_sva_bind_device(struct device *dev, struct mm_struct *mm
115130 goto out_free_handle ;
116131 }
117132
118- ret = iommu_attach_device_pasid (domain , dev , iommu_mm -> pasid );
133+ ret = iommu_attach_device_pasid (domain , dev , iommu_mm -> pasid ,
134+ & handle -> handle );
119135 if (ret )
120136 goto out_free_domain ;
121137 domain -> users = 1 ;
122138 list_add (& domain -> next , & mm -> iommu_mm -> sva_domains );
123139
124140out :
125141 refcount_set (& handle -> users , 1 );
126- list_add (& handle -> handle_item , & mm -> iommu_mm -> sva_handles );
127142 mutex_unlock (& iommu_sva_lock );
128143 handle -> dev = dev ;
129- handle -> domain = domain ;
130144 return handle ;
131145
132146out_free_domain :
@@ -149,7 +163,7 @@ EXPORT_SYMBOL_GPL(iommu_sva_bind_device);
149163 */
150164void iommu_sva_unbind_device (struct iommu_sva * handle )
151165{
152- struct iommu_domain * domain = handle -> domain ;
166+ struct iommu_domain * domain = handle -> handle . domain ;
153167 struct iommu_mm_data * iommu_mm = domain -> mm -> iommu_mm ;
154168 struct device * dev = handle -> dev ;
155169
@@ -158,7 +172,6 @@ void iommu_sva_unbind_device(struct iommu_sva *handle)
158172 mutex_unlock (& iommu_sva_lock );
159173 return ;
160174 }
161- list_del (& handle -> handle_item );
162175
163176 iommu_detach_device_pasid (domain , dev , iommu_mm -> pasid );
164177 if (-- domain -> users == 0 ) {
@@ -172,7 +185,7 @@ EXPORT_SYMBOL_GPL(iommu_sva_unbind_device);
172185
173186u32 iommu_sva_get_pasid (struct iommu_sva * handle )
174187{
175- struct iommu_domain * domain = handle -> domain ;
188+ struct iommu_domain * domain = handle -> handle . domain ;
176189
177190 return mm_get_enqcmd_pasid (domain -> mm );
178191}
@@ -261,7 +274,8 @@ static void iommu_sva_handle_iopf(struct work_struct *work)
261274 if (status != IOMMU_PAGE_RESP_SUCCESS )
262275 break ;
263276
264- status = iommu_sva_handle_mm (& iopf -> fault , group -> domain -> mm );
277+ status = iommu_sva_handle_mm (& iopf -> fault ,
278+ group -> attach_handle -> domain -> mm );
265279 }
266280
267281 iopf_group_response (group , status );
0 commit comments