RE: [PATCH v2 5/8] vfio: Change vfio_external_check_extension() to vfio_file_enforced_coherent()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



> From: Jason Gunthorpe <jgg@xxxxxxxxxx>
> Sent: Thursday, April 21, 2022 3:23 AM
> 
> 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.
> 
> Signed-off-by: Jason Gunthorpe <jgg@xxxxxxxxxx>
> ---
>  drivers/vfio/vfio.c  | 30 +++++++++++++++++++++++++++---
>  include/linux/vfio.h |  3 +--
>  virt/kvm/vfio.c      | 16 ++++++++--------
>  3 files changed, 36 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/vfio/vfio.c b/drivers/vfio/vfio.c
> index c9122c84583aa1..ae3e802991edf2 100644
> --- a/drivers/vfio/vfio.c
> +++ b/drivers/vfio/vfio.c
> @@ -2005,11 +2005,35 @@ struct iommu_group
> *vfio_file_iommu_group(struct file *file)
>  }
>  EXPORT_SYMBOL_GPL(vfio_file_iommu_group);
> 
> -long vfio_external_check_extension(struct vfio_group *group, unsigned long
> arg)
> +/**
> + * 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)
>  {
> -	return vfio_ioctl_check_extension(group->container, arg);
> +	struct vfio_group *group = file->private_data;
> +	bool ret;
> +
> +	if (file->f_op != &vfio_group_fops)
> +		return true;
> +
> +	/*
> +	 * Since the coherency state is determined only once a container is
> +	 * attached the user must do so before they can prove they have
> +	 * permission.
> +	 */
> +	if (vfio_group_add_container_user(group))
> +		return true;

IMHO I still think returning an error here is better for 'user must
do so' than telling inaccurate info and leading to a situation 
where lacking of wbinvd may incur various cache problem which
is hard to debug. Yes, it's user's own problem but having a place
to capture this problem early is still a nice thing to do.

> +	ret = vfio_ioctl_check_extension(group->container,
> VFIO_DMA_CC_IOMMU);
> +	vfio_group_try_dissolve_container(group);
> +	return ret;
>  }
> -EXPORT_SYMBOL_GPL(vfio_external_check_extension);
> +EXPORT_SYMBOL_GPL(vfio_file_enforced_coherent);
> 
>  /*
>   * Sub-module support
> diff --git a/include/linux/vfio.h b/include/linux/vfio.h
> index 132cf3e7cda8db..7f022ae126a392 100644
> --- a/include/linux/vfio.h
> +++ b/include/linux/vfio.h
> @@ -143,8 +143,7 @@ extern void vfio_group_put_external_user(struct
> vfio_group *group);
>  extern struct vfio_group *vfio_group_get_external_user_from_dev(struct
> device
>  								*dev);
>  extern struct iommu_group *vfio_file_iommu_group(struct file *file);
> -extern long vfio_external_check_extension(struct vfio_group *group,
> -					  unsigned long arg);
> +extern bool vfio_file_enforced_coherent(struct file *file);
> 
>  #define VFIO_PIN_PAGES_MAX_ENTRIES	(PAGE_SIZE/sizeof(unsigned
> long))
> 
> diff --git a/virt/kvm/vfio.c b/virt/kvm/vfio.c
> index 50193ae270faca..2330b0c272e671 100644
> --- a/virt/kvm/vfio.c
> +++ b/virt/kvm/vfio.c
> @@ -75,20 +75,20 @@ static void kvm_vfio_group_set_kvm(struct
> vfio_group *group, struct kvm *kvm)
>  	symbol_put(vfio_group_set_kvm);
>  }
> 
> -static bool kvm_vfio_group_is_coherent(struct vfio_group *vfio_group)
> +static bool kvm_vfio_file_enforced_coherent(struct file *file)
>  {
> -	long (*fn)(struct vfio_group *, unsigned long);
> -	long ret;
> +	bool (*fn)(struct file *file);
> +	bool ret;
> 
> -	fn = symbol_get(vfio_external_check_extension);
> +	fn = symbol_get(vfio_file_enforced_coherent);
>  	if (!fn)
>  		return false;
> 
> -	ret = fn(vfio_group, VFIO_DMA_CC_IOMMU);
> +	ret = fn(file);
> 
> -	symbol_put(vfio_external_check_extension);
> +	symbol_put(vfio_file_enforced_coherent);
> 
> -	return ret > 0;
> +	return ret;
>  }
> 
>  #ifdef CONFIG_SPAPR_TCE_IOMMU
> @@ -136,7 +136,7 @@ static void kvm_vfio_update_coherency(struct
> kvm_device *dev)
>  	mutex_lock(&kv->lock);
> 
>  	list_for_each_entry(kvg, &kv->group_list, node) {
> -		if (!kvm_vfio_group_is_coherent(kvg->vfio_group)) {
> +		if (!kvm_vfio_file_enforced_coherent(kvg->file)) {
>  			noncoherent = true;
>  			break;
>  		}
> --
> 2.36.0





[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux