mirror of
https://github.com/torvalds/linux.git
synced 2024-11-21 19:41:42 +00:00
vfio: Refine vfio file kAPIs for KVM
This prepares for making the below kAPIs to accept both group file and device file instead of only vfio group file. bool vfio_file_enforced_coherent(struct file *file); void vfio_file_set_kvm(struct file *file, struct kvm *kvm); Reviewed-by: Kevin Tian <kevin.tian@intel.com> Reviewed-by: Eric Auger <eric.auger@redhat.com> Reviewed-by: Jason Gunthorpe <jgg@nvidia.com> Tested-by: Terrence Xu <terrence.xu@intel.com> Tested-by: Nicolin Chen <nicolinc@nvidia.com> Tested-by: Matthew Rosato <mjrosato@linux.ibm.com> Tested-by: Yanting Jiang <yanting.jiang@intel.com> Tested-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com> Tested-by: Zhenzhong Duan <zhenzhong.duan@intel.com> Signed-off-by: Yi Liu <yi.l.liu@intel.com> Link: https://lore.kernel.org/r/20230718135551.6592-3-yi.l.liu@intel.com Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
This commit is contained in:
parent
b1a3b5c61d
commit
b1a59be8a2
@ -754,6 +754,15 @@ bool vfio_device_has_container(struct vfio_device *device)
|
||||
return device->group->container;
|
||||
}
|
||||
|
||||
struct vfio_group *vfio_group_from_file(struct file *file)
|
||||
{
|
||||
struct vfio_group *group = file->private_data;
|
||||
|
||||
if (file->f_op != &vfio_group_fops)
|
||||
return NULL;
|
||||
return group;
|
||||
}
|
||||
|
||||
/**
|
||||
* vfio_file_iommu_group - Return the struct iommu_group for the vfio group file
|
||||
* @file: VFIO group file
|
||||
@ -764,13 +773,13 @@ bool vfio_device_has_container(struct vfio_device *device)
|
||||
*/
|
||||
struct iommu_group *vfio_file_iommu_group(struct file *file)
|
||||
{
|
||||
struct vfio_group *group = file->private_data;
|
||||
struct vfio_group *group = vfio_group_from_file(file);
|
||||
struct iommu_group *iommu_group = NULL;
|
||||
|
||||
if (!IS_ENABLED(CONFIG_SPAPR_TCE_IOMMU))
|
||||
return NULL;
|
||||
|
||||
if (!vfio_file_is_group(file))
|
||||
if (!group)
|
||||
return NULL;
|
||||
|
||||
mutex_lock(&group->group_lock);
|
||||
@ -784,33 +793,20 @@ struct iommu_group *vfio_file_iommu_group(struct file *file)
|
||||
EXPORT_SYMBOL_GPL(vfio_file_iommu_group);
|
||||
|
||||
/**
|
||||
* vfio_file_is_group - True if the file is usable with VFIO aPIS
|
||||
* vfio_file_is_group - True if the file is a vfio group file
|
||||
* @file: VFIO group file
|
||||
*/
|
||||
bool vfio_file_is_group(struct file *file)
|
||||
{
|
||||
return file->f_op == &vfio_group_fops;
|
||||
return vfio_group_from_file(file);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(vfio_file_is_group);
|
||||
|
||||
/**
|
||||
* vfio_file_enforced_coherent - True if the DMA associated with the VFIO file
|
||||
* is always CPU cache coherent
|
||||
* @file: VFIO group file
|
||||
*
|
||||
* Enforced coherency means that the IOMMU ignores things like the PCIe no-snoop
|
||||
* bit in DMA transactions. A return of false indicates that the user has
|
||||
* rights to access additional instructions such as wbinvd on x86.
|
||||
*/
|
||||
bool vfio_file_enforced_coherent(struct file *file)
|
||||
bool vfio_group_enforced_coherent(struct vfio_group *group)
|
||||
{
|
||||
struct vfio_group *group = file->private_data;
|
||||
struct vfio_device *device;
|
||||
bool ret = true;
|
||||
|
||||
if (!vfio_file_is_group(file))
|
||||
return true;
|
||||
|
||||
/*
|
||||
* If the device does not have IOMMU_CAP_ENFORCE_CACHE_COHERENCY then
|
||||
* any domain later attached to it will also not support it. If the cap
|
||||
@ -828,28 +824,13 @@ bool vfio_file_enforced_coherent(struct file *file)
|
||||
mutex_unlock(&group->device_lock);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(vfio_file_enforced_coherent);
|
||||
|
||||
/**
|
||||
* vfio_file_set_kvm - Link a kvm with VFIO drivers
|
||||
* @file: VFIO group file
|
||||
* @kvm: KVM to link
|
||||
*
|
||||
* When a VFIO device is first opened the KVM will be available in
|
||||
* device->kvm if one was associated with the group.
|
||||
*/
|
||||
void vfio_file_set_kvm(struct file *file, struct kvm *kvm)
|
||||
void vfio_group_set_kvm(struct vfio_group *group, struct kvm *kvm)
|
||||
{
|
||||
struct vfio_group *group = file->private_data;
|
||||
|
||||
if (!vfio_file_is_group(file))
|
||||
return;
|
||||
|
||||
spin_lock(&group->kvm_ref_lock);
|
||||
group->kvm = kvm;
|
||||
spin_unlock(&group->kvm_ref_lock);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(vfio_file_set_kvm);
|
||||
|
||||
/**
|
||||
* vfio_file_has_dev - True if the VFIO file is a handle for device
|
||||
@ -860,9 +841,9 @@ EXPORT_SYMBOL_GPL(vfio_file_set_kvm);
|
||||
*/
|
||||
bool vfio_file_has_dev(struct file *file, struct vfio_device *device)
|
||||
{
|
||||
struct vfio_group *group = file->private_data;
|
||||
struct vfio_group *group = vfio_group_from_file(file);
|
||||
|
||||
if (!vfio_file_is_group(file))
|
||||
if (!group)
|
||||
return false;
|
||||
|
||||
return group == device->group;
|
||||
|
@ -90,6 +90,9 @@ void vfio_device_group_unregister(struct vfio_device *device);
|
||||
int vfio_device_group_use_iommu(struct vfio_device *device);
|
||||
void vfio_device_group_unuse_iommu(struct vfio_device *device);
|
||||
void vfio_device_group_close(struct vfio_device *device);
|
||||
struct vfio_group *vfio_group_from_file(struct file *file);
|
||||
bool vfio_group_enforced_coherent(struct vfio_group *group);
|
||||
void vfio_group_set_kvm(struct vfio_group *group, struct kvm *kvm);
|
||||
bool vfio_device_has_container(struct vfio_device *device);
|
||||
int __init vfio_group_init(void);
|
||||
void vfio_group_cleanup(void);
|
||||
|
@ -1190,6 +1190,55 @@ const struct file_operations vfio_device_fops = {
|
||||
.mmap = vfio_device_fops_mmap,
|
||||
};
|
||||
|
||||
/**
|
||||
* vfio_file_is_valid - True if the file is valid vfio file
|
||||
* @file: VFIO group file or VFIO device file
|
||||
*/
|
||||
bool vfio_file_is_valid(struct file *file)
|
||||
{
|
||||
return vfio_group_from_file(file);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(vfio_file_is_valid);
|
||||
|
||||
/**
|
||||
* vfio_file_enforced_coherent - True if the DMA associated with the VFIO file
|
||||
* is always CPU cache coherent
|
||||
* @file: VFIO group file or VFIO device file
|
||||
*
|
||||
* Enforced coherency means that the IOMMU ignores things like the PCIe no-snoop
|
||||
* bit in DMA transactions. A return of false indicates that the user has
|
||||
* rights to access additional instructions such as wbinvd on x86.
|
||||
*/
|
||||
bool vfio_file_enforced_coherent(struct file *file)
|
||||
{
|
||||
struct vfio_group *group;
|
||||
|
||||
group = vfio_group_from_file(file);
|
||||
if (group)
|
||||
return vfio_group_enforced_coherent(group);
|
||||
|
||||
return true;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(vfio_file_enforced_coherent);
|
||||
|
||||
/**
|
||||
* vfio_file_set_kvm - Link a kvm with VFIO drivers
|
||||
* @file: VFIO group file or VFIO device file
|
||||
* @kvm: KVM to link
|
||||
*
|
||||
* When a VFIO device is first opened the KVM will be available in
|
||||
* device->kvm if one was associated with the file.
|
||||
*/
|
||||
void vfio_file_set_kvm(struct file *file, struct kvm *kvm)
|
||||
{
|
||||
struct vfio_group *group;
|
||||
|
||||
group = vfio_group_from_file(file);
|
||||
if (group)
|
||||
vfio_group_set_kvm(group, kvm);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(vfio_file_set_kvm);
|
||||
|
||||
/*
|
||||
* Sub-module support
|
||||
*/
|
||||
|
@ -272,6 +272,7 @@ int vfio_mig_get_next_state(struct vfio_device *device,
|
||||
*/
|
||||
struct iommu_group *vfio_file_iommu_group(struct file *file);
|
||||
bool vfio_file_is_group(struct file *file);
|
||||
bool vfio_file_is_valid(struct file *file);
|
||||
bool vfio_file_enforced_coherent(struct file *file);
|
||||
void vfio_file_set_kvm(struct file *file, struct kvm *kvm);
|
||||
bool vfio_file_has_dev(struct file *file, struct vfio_device *device);
|
||||
|
@ -64,18 +64,18 @@ static bool kvm_vfio_file_enforced_coherent(struct file *file)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool kvm_vfio_file_is_group(struct file *file)
|
||||
static bool kvm_vfio_file_is_valid(struct file *file)
|
||||
{
|
||||
bool (*fn)(struct file *file);
|
||||
bool ret;
|
||||
|
||||
fn = symbol_get(vfio_file_is_group);
|
||||
fn = symbol_get(vfio_file_is_valid);
|
||||
if (!fn)
|
||||
return false;
|
||||
|
||||
ret = fn(file);
|
||||
|
||||
symbol_put(vfio_file_is_group);
|
||||
symbol_put(vfio_file_is_valid);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -154,8 +154,8 @@ static int kvm_vfio_group_add(struct kvm_device *dev, unsigned int fd)
|
||||
if (!filp)
|
||||
return -EBADF;
|
||||
|
||||
/* Ensure the FD is a vfio group FD.*/
|
||||
if (!kvm_vfio_file_is_group(filp)) {
|
||||
/* Ensure the FD is a vfio FD. */
|
||||
if (!kvm_vfio_file_is_valid(filp)) {
|
||||
ret = -EINVAL;
|
||||
goto err_fput;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user