2323
2424struct kvm_vfio_group {
2525 struct list_head node ;
26+ struct file * file ;
2627 struct vfio_group * vfio_group ;
2728};
2829
@@ -186,23 +187,17 @@ static int kvm_vfio_group_add(struct kvm_device *dev, unsigned int fd)
186187 struct kvm_vfio * kv = dev -> private ;
187188 struct vfio_group * vfio_group ;
188189 struct kvm_vfio_group * kvg ;
189- struct fd f ;
190+ struct file * filp ;
190191 int ret ;
191192
192- f = fdget (fd );
193- if (!f . file )
193+ filp = fget (fd );
194+ if (!filp )
194195 return - EBADF ;
195196
196- vfio_group = kvm_vfio_group_get_external_user (f .file );
197- fdput (f );
198-
199- if (IS_ERR (vfio_group ))
200- return PTR_ERR (vfio_group );
201-
202197 mutex_lock (& kv -> lock );
203198
204199 list_for_each_entry (kvg , & kv -> group_list , node ) {
205- if (kvg -> vfio_group == vfio_group ) {
200+ if (kvg -> file == filp ) {
206201 ret = - EEXIST ;
207202 goto err_unlock ;
208203 }
@@ -214,6 +209,13 @@ static int kvm_vfio_group_add(struct kvm_device *dev, unsigned int fd)
214209 goto err_unlock ;
215210 }
216211
212+ vfio_group = kvm_vfio_group_get_external_user (filp );
213+ if (IS_ERR (vfio_group )) {
214+ ret = PTR_ERR (vfio_group );
215+ goto err_free ;
216+ }
217+
218+ kvg -> file = filp ;
217219 list_add_tail (& kvg -> node , & kv -> group_list );
218220 kvg -> vfio_group = vfio_group ;
219221
@@ -225,9 +227,11 @@ static int kvm_vfio_group_add(struct kvm_device *dev, unsigned int fd)
225227 kvm_vfio_update_coherency (dev );
226228
227229 return 0 ;
230+ err_free :
231+ kfree (kvg );
228232err_unlock :
229233 mutex_unlock (& kv -> lock );
230- kvm_vfio_group_put_external_user ( vfio_group );
234+ fput ( filp );
231235 return ret ;
232236}
233237
@@ -258,6 +262,7 @@ static int kvm_vfio_group_del(struct kvm_device *dev, unsigned int fd)
258262#endif
259263 kvm_vfio_group_set_kvm (kvg -> vfio_group , NULL );
260264 kvm_vfio_group_put_external_user (kvg -> vfio_group );
265+ fput (kvg -> file );
261266 kfree (kvg );
262267 ret = 0 ;
263268 break ;
@@ -278,10 +283,8 @@ static int kvm_vfio_group_set_spapr_tce(struct kvm_device *dev,
278283{
279284 struct kvm_vfio_spapr_tce param ;
280285 struct kvm_vfio * kv = dev -> private ;
281- struct vfio_group * vfio_group ;
282286 struct kvm_vfio_group * kvg ;
283287 struct fd f ;
284- struct iommu_group * grp ;
285288 int ret ;
286289
287290 if (copy_from_user (& param , arg , sizeof (struct kvm_vfio_spapr_tce )))
@@ -291,36 +294,31 @@ static int kvm_vfio_group_set_spapr_tce(struct kvm_device *dev,
291294 if (!f .file )
292295 return - EBADF ;
293296
294- vfio_group = kvm_vfio_group_get_external_user (f .file );
295- fdput (f );
296-
297- if (IS_ERR (vfio_group ))
298- return PTR_ERR (vfio_group );
299-
300- grp = kvm_vfio_group_get_iommu_group (vfio_group );
301- if (WARN_ON_ONCE (!grp )) {
302- ret = - EIO ;
303- goto err_put_external ;
304- }
305-
306297 ret = - ENOENT ;
307298
308299 mutex_lock (& kv -> lock );
309300
310301 list_for_each_entry (kvg , & kv -> group_list , node ) {
311- if (kvg -> vfio_group != vfio_group )
302+ struct iommu_group * grp ;
303+
304+ if (kvg -> file != f .file )
312305 continue ;
313306
307+ grp = kvm_vfio_group_get_iommu_group (kvg -> vfio_group );
308+ if (WARN_ON_ONCE (!grp )) {
309+ ret = - EIO ;
310+ goto err_fdput ;
311+ }
312+
314313 ret = kvm_spapr_tce_attach_iommu_group (dev -> kvm , param .tablefd ,
315314 grp );
315+ iommu_group_put (grp );
316316 break ;
317317 }
318318
319319 mutex_unlock (& kv -> lock );
320-
321- iommu_group_put (grp );
322- err_put_external :
323- kvm_vfio_group_put_external_user (vfio_group );
320+ err_fdput :
321+ fdput (f );
324322 return ret ;
325323}
326324#endif
@@ -394,6 +392,7 @@ static void kvm_vfio_destroy(struct kvm_device *dev)
394392#endif
395393 kvm_vfio_group_set_kvm (kvg -> vfio_group , NULL );
396394 kvm_vfio_group_put_external_user (kvg -> vfio_group );
395+ fput (kvg -> file );
397396 list_del (& kvg -> node );
398397 kfree (kvg );
399398 kvm_arch_end_assignment (dev -> kvm );
0 commit comments