23
23
24
24
struct kvm_vfio_group {
25
25
struct list_head node ;
26
+ struct file * file ;
26
27
struct vfio_group * vfio_group ;
27
28
};
28
29
@@ -186,23 +187,17 @@ static int kvm_vfio_group_add(struct kvm_device *dev, unsigned int fd)
186
187
struct kvm_vfio * kv = dev -> private ;
187
188
struct vfio_group * vfio_group ;
188
189
struct kvm_vfio_group * kvg ;
189
- struct fd f ;
190
+ struct file * filp ;
190
191
int ret ;
191
192
192
- f = fdget (fd );
193
- if (!f . file )
193
+ filp = fget (fd );
194
+ if (!filp )
194
195
return - EBADF ;
195
196
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
-
202
197
mutex_lock (& kv -> lock );
203
198
204
199
list_for_each_entry (kvg , & kv -> group_list , node ) {
205
- if (kvg -> vfio_group == vfio_group ) {
200
+ if (kvg -> file == filp ) {
206
201
ret = - EEXIST ;
207
202
goto err_unlock ;
208
203
}
@@ -214,6 +209,13 @@ static int kvm_vfio_group_add(struct kvm_device *dev, unsigned int fd)
214
209
goto err_unlock ;
215
210
}
216
211
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 ;
217
219
list_add_tail (& kvg -> node , & kv -> group_list );
218
220
kvg -> vfio_group = vfio_group ;
219
221
@@ -225,9 +227,11 @@ static int kvm_vfio_group_add(struct kvm_device *dev, unsigned int fd)
225
227
kvm_vfio_update_coherency (dev );
226
228
227
229
return 0 ;
230
+ err_free :
231
+ kfree (kvg );
228
232
err_unlock :
229
233
mutex_unlock (& kv -> lock );
230
- kvm_vfio_group_put_external_user ( vfio_group );
234
+ fput ( filp );
231
235
return ret ;
232
236
}
233
237
@@ -258,6 +262,7 @@ static int kvm_vfio_group_del(struct kvm_device *dev, unsigned int fd)
258
262
#endif
259
263
kvm_vfio_group_set_kvm (kvg -> vfio_group , NULL );
260
264
kvm_vfio_group_put_external_user (kvg -> vfio_group );
265
+ fput (kvg -> file );
261
266
kfree (kvg );
262
267
ret = 0 ;
263
268
break ;
@@ -278,10 +283,8 @@ static int kvm_vfio_group_set_spapr_tce(struct kvm_device *dev,
278
283
{
279
284
struct kvm_vfio_spapr_tce param ;
280
285
struct kvm_vfio * kv = dev -> private ;
281
- struct vfio_group * vfio_group ;
282
286
struct kvm_vfio_group * kvg ;
283
287
struct fd f ;
284
- struct iommu_group * grp ;
285
288
int ret ;
286
289
287
290
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,
291
294
if (!f .file )
292
295
return - EBADF ;
293
296
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
-
306
297
ret = - ENOENT ;
307
298
308
299
mutex_lock (& kv -> lock );
309
300
310
301
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 )
312
305
continue ;
313
306
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
+
314
313
ret = kvm_spapr_tce_attach_iommu_group (dev -> kvm , param .tablefd ,
315
314
grp );
315
+ iommu_group_put (grp );
316
316
break ;
317
317
}
318
318
319
319
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 );
324
322
return ret ;
325
323
}
326
324
#endif
@@ -394,6 +392,7 @@ static void kvm_vfio_destroy(struct kvm_device *dev)
394
392
#endif
395
393
kvm_vfio_group_set_kvm (kvg -> vfio_group , NULL );
396
394
kvm_vfio_group_put_external_user (kvg -> vfio_group );
395
+ fput (kvg -> file );
397
396
list_del (& kvg -> node );
398
397
kfree (kvg );
399
398
kvm_arch_end_assignment (dev -> kvm );
0 commit comments