Skip to content

Commit a905ad0

Browse files
jgunthorpeawilliam
authored andcommitted
vfio: Change vfio_external_check_extension() to vfio_file_enforced_coherent()
Instead of a general extension check change the function into a limited test if the iommu_domain has enforced coherency, which is the only thing kvm needs to query. Make the new op self contained by properly refcounting the container before touching it. Reviewed-by: Christoph Hellwig <[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 c38ff5b commit a905ad0

File tree

3 files changed

+36
-13
lines changed

3 files changed

+36
-13
lines changed

drivers/vfio/vfio.c

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1701,11 +1701,35 @@ struct iommu_group *vfio_file_iommu_group(struct file *file)
17011701
}
17021702
EXPORT_SYMBOL_GPL(vfio_file_iommu_group);
17031703

1704-
long vfio_external_check_extension(struct vfio_group *group, unsigned long arg)
1704+
/**
1705+
* vfio_file_enforced_coherent - True if the DMA associated with the VFIO file
1706+
* is always CPU cache coherent
1707+
* @file: VFIO group file
1708+
*
1709+
* Enforced coherency means that the IOMMU ignores things like the PCIe no-snoop
1710+
* bit in DMA transactions. A return of false indicates that the user has
1711+
* rights to access additional instructions such as wbinvd on x86.
1712+
*/
1713+
bool vfio_file_enforced_coherent(struct file *file)
17051714
{
1706-
return vfio_ioctl_check_extension(group->container, arg);
1715+
struct vfio_group *group = file->private_data;
1716+
bool ret;
1717+
1718+
if (file->f_op != &vfio_group_fops)
1719+
return true;
1720+
1721+
/*
1722+
* Since the coherency state is determined only once a container is
1723+
* attached the user must do so before they can prove they have
1724+
* permission.
1725+
*/
1726+
if (vfio_group_add_container_user(group))
1727+
return true;
1728+
ret = vfio_ioctl_check_extension(group->container, VFIO_DMA_CC_IOMMU);
1729+
vfio_group_try_dissolve_container(group);
1730+
return ret;
17071731
}
1708-
EXPORT_SYMBOL_GPL(vfio_external_check_extension);
1732+
EXPORT_SYMBOL_GPL(vfio_file_enforced_coherent);
17091733

17101734
/*
17111735
* Sub-module support

include/linux/vfio.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -139,8 +139,7 @@ int vfio_mig_get_next_state(struct vfio_device *device,
139139
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 struct iommu_group *vfio_file_iommu_group(struct file *file);
142-
extern long vfio_external_check_extension(struct vfio_group *group,
143-
unsigned long arg);
142+
extern bool vfio_file_enforced_coherent(struct file *file);
144143

145144
#define VFIO_PIN_PAGES_MAX_ENTRIES (PAGE_SIZE/sizeof(unsigned long))
146145

virt/kvm/vfio.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -75,20 +75,20 @@ static void kvm_vfio_group_set_kvm(struct vfio_group *group, struct kvm *kvm)
7575
symbol_put(vfio_group_set_kvm);
7676
}
7777

78-
static bool kvm_vfio_group_is_coherent(struct vfio_group *vfio_group)
78+
static bool kvm_vfio_file_enforced_coherent(struct file *file)
7979
{
80-
long (*fn)(struct vfio_group *, unsigned long);
81-
long ret;
80+
bool (*fn)(struct file *file);
81+
bool ret;
8282

83-
fn = symbol_get(vfio_external_check_extension);
83+
fn = symbol_get(vfio_file_enforced_coherent);
8484
if (!fn)
8585
return false;
8686

87-
ret = fn(vfio_group, VFIO_DMA_CC_IOMMU);
87+
ret = fn(file);
8888

89-
symbol_put(vfio_external_check_extension);
89+
symbol_put(vfio_file_enforced_coherent);
9090

91-
return ret > 0;
91+
return ret;
9292
}
9393

9494
#ifdef CONFIG_SPAPR_TCE_IOMMU
@@ -136,7 +136,7 @@ static void kvm_vfio_update_coherency(struct kvm_device *dev)
136136
mutex_lock(&kv->lock);
137137

138138
list_for_each_entry(kvg, &kv->group_list, node) {
139-
if (!kvm_vfio_group_is_coherent(kvg->vfio_group)) {
139+
if (!kvm_vfio_file_enforced_coherent(kvg->file)) {
140140
noncoherent = true;
141141
break;
142142
}

0 commit comments

Comments
 (0)