Skip to content

Commit 50d63b5

Browse files
jgunthorpeawilliam
authored andcommitted
vfio: Change vfio_external_user_iommu_id() to vfio_file_iommu_group()
The only caller wants to get a pointer to the struct iommu_group associated with the VFIO group file. Instead of returning the group ID then searching sysfs for that string to get the struct iommu_group just directly return the iommu_group pointer already held by the vfio_group struct. It already has a safe lifetime due to the struct file kref, the vfio_group and thus the iommu_group cannot be destroyed while the group file is open. Reviewed-by: Kevin Tian <[email protected]> Reviewed-by: Christoph Hellwig <[email protected]> Reviewed-by: Yi Liu <[email protected]> Signed-off-by: Jason Gunthorpe <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Alex Williamson <[email protected]>
1 parent d55d9e7 commit 50d63b5

File tree

3 files changed

+27
-33
lines changed

3 files changed

+27
-33
lines changed

drivers/vfio/vfio.c

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1653,10 +1653,7 @@ static const struct file_operations vfio_device_fops = {
16531653
* increments the container user counter to prevent
16541654
* the VFIO group from disposal before KVM exits.
16551655
*
1656-
* 3. The external user calls vfio_external_user_iommu_id()
1657-
* to know an IOMMU ID.
1658-
*
1659-
* 4. When the external KVM finishes, it calls
1656+
* 3. When the external KVM finishes, it calls
16601657
* vfio_group_put_external_user() to release the VFIO group.
16611658
* This call decrements the container user counter.
16621659
*/
@@ -1697,11 +1694,21 @@ bool vfio_external_group_match_file(struct vfio_group *test_group,
16971694
}
16981695
EXPORT_SYMBOL_GPL(vfio_external_group_match_file);
16991696

1700-
int vfio_external_user_iommu_id(struct vfio_group *group)
1697+
/**
1698+
* vfio_file_iommu_group - Return the struct iommu_group for the vfio group file
1699+
* @file: VFIO group file
1700+
*
1701+
* The returned iommu_group is valid as long as a ref is held on the file.
1702+
*/
1703+
struct iommu_group *vfio_file_iommu_group(struct file *file)
17011704
{
1702-
return iommu_group_id(group->iommu_group);
1705+
struct vfio_group *group = file->private_data;
1706+
1707+
if (file->f_op != &vfio_group_fops)
1708+
return NULL;
1709+
return group->iommu_group;
17031710
}
1704-
EXPORT_SYMBOL_GPL(vfio_external_user_iommu_id);
1711+
EXPORT_SYMBOL_GPL(vfio_file_iommu_group);
17051712

17061713
long vfio_external_check_extension(struct vfio_group *group, unsigned long arg)
17071714
{

include/linux/vfio.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ extern struct vfio_group *vfio_group_get_external_user(struct file *filep);
140140
extern void vfio_group_put_external_user(struct vfio_group *group);
141141
extern bool vfio_external_group_match_file(struct vfio_group *group,
142142
struct file *filep);
143-
extern int vfio_external_user_iommu_id(struct vfio_group *group);
143+
extern struct iommu_group *vfio_file_iommu_group(struct file *file);
144144
extern long vfio_external_check_extension(struct vfio_group *group,
145145
unsigned long arg);
146146

virt/kvm/vfio.c

Lines changed: 12 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -108,43 +108,31 @@ static bool kvm_vfio_group_is_coherent(struct vfio_group *vfio_group)
108108
}
109109

110110
#ifdef CONFIG_SPAPR_TCE_IOMMU
111-
static int kvm_vfio_external_user_iommu_id(struct vfio_group *vfio_group)
111+
static struct iommu_group *kvm_vfio_file_iommu_group(struct file *file)
112112
{
113-
int (*fn)(struct vfio_group *);
114-
int ret = -EINVAL;
113+
struct iommu_group *(*fn)(struct file *file);
114+
struct iommu_group *ret;
115115

116-
fn = symbol_get(vfio_external_user_iommu_id);
116+
fn = symbol_get(vfio_file_iommu_group);
117117
if (!fn)
118-
return ret;
118+
return NULL;
119119

120-
ret = fn(vfio_group);
120+
ret = fn(file);
121121

122-
symbol_put(vfio_external_user_iommu_id);
122+
symbol_put(vfio_file_iommu_group);
123123

124124
return ret;
125125
}
126126

127-
static struct iommu_group *kvm_vfio_group_get_iommu_group(
128-
struct vfio_group *group)
129-
{
130-
int group_id = kvm_vfio_external_user_iommu_id(group);
131-
132-
if (group_id < 0)
133-
return NULL;
134-
135-
return iommu_group_get_by_id(group_id);
136-
}
137-
138127
static void kvm_spapr_tce_release_vfio_group(struct kvm *kvm,
139-
struct vfio_group *vfio_group)
128+
struct kvm_vfio_group *kvg)
140129
{
141-
struct iommu_group *grp = kvm_vfio_group_get_iommu_group(vfio_group);
130+
struct iommu_group *grp = kvm_vfio_file_iommu_group(kvg->file);
142131

143132
if (WARN_ON_ONCE(!grp))
144133
return;
145134

146135
kvm_spapr_tce_release_iommu_group(kvm, grp);
147-
iommu_group_put(grp);
148136
}
149137
#endif
150138

@@ -258,7 +246,7 @@ static int kvm_vfio_group_del(struct kvm_device *dev, unsigned int fd)
258246
list_del(&kvg->node);
259247
kvm_arch_end_assignment(dev->kvm);
260248
#ifdef CONFIG_SPAPR_TCE_IOMMU
261-
kvm_spapr_tce_release_vfio_group(dev->kvm, kvg->vfio_group);
249+
kvm_spapr_tce_release_vfio_group(dev->kvm, kvg);
262250
#endif
263251
kvm_vfio_group_set_kvm(kvg->vfio_group, NULL);
264252
kvm_vfio_group_put_external_user(kvg->vfio_group);
@@ -304,15 +292,14 @@ static int kvm_vfio_group_set_spapr_tce(struct kvm_device *dev,
304292
if (kvg->file != f.file)
305293
continue;
306294

307-
grp = kvm_vfio_group_get_iommu_group(kvg->vfio_group);
295+
grp = kvm_vfio_file_iommu_group(kvg->file);
308296
if (WARN_ON_ONCE(!grp)) {
309297
ret = -EIO;
310298
goto err_fdput;
311299
}
312300

313301
ret = kvm_spapr_tce_attach_iommu_group(dev->kvm, param.tablefd,
314302
grp);
315-
iommu_group_put(grp);
316303
break;
317304
}
318305

@@ -388,7 +375,7 @@ static void kvm_vfio_destroy(struct kvm_device *dev)
388375

389376
list_for_each_entry_safe(kvg, tmp, &kv->group_list, node) {
390377
#ifdef CONFIG_SPAPR_TCE_IOMMU
391-
kvm_spapr_tce_release_vfio_group(dev->kvm, kvg->vfio_group);
378+
kvm_spapr_tce_release_vfio_group(dev->kvm, kvg);
392379
#endif
393380
kvm_vfio_group_set_kvm(kvg->vfio_group, NULL);
394381
kvm_vfio_group_put_external_user(kvg->vfio_group);

0 commit comments

Comments
 (0)