lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:   Sun, 23 Aug 2020 09:40:36 +0300
From:   Eli Cohen <elic@...dia.com>
To:     Jason Wang <jasowang@...hat.com>
CC:     <mst@...hat.com>, <virtualization@...ts.linux-foundation.org>,
        <linux-kernel@...r.kernel.org>, <rob.miller@...adcom.com>,
        <lingshan.zhu@...el.com>, <eperezma@...hat.com>, <lulu@...hat.com>,
        <shahafs@...lanox.com>, <hanand@...inx.com>,
        <mhabets@...arflare.com>, <gdawar@...inx.com>,
        <saugatm@...inx.com>, <vmireyno@...vell.com>,
        <zhangweining@...jie.com.cn>, <eli@...lanox.com>
Subject: Re: [PATCH V2 2/3] vhost: vdpa: report iova range

On Fri, Aug 21, 2020 at 05:28:12AM -0400, Jason Wang wrote:
> This patch introduces a new ioctl for vhost-vdpa device that can
> report the iova range by the device.
> 
> For device that implements get_iova_range() method, we fetch it from
> the vDPA device. If device doesn't implement get_iova_range() but
> depends on platform IOMMU, we will query via DOMAIN_ATTR_GEOMETRY,
> otherwise [0, ULLONG_MAX] is assumed.
> 
> For safety, this patch also rules out the map request which is not in
> the valid range.
> 
> Signed-off-by: Jason Wang <jasowang@...hat.com>
> ---
>  drivers/vhost/vdpa.c             | 41 ++++++++++++++++++++++++++++++++
>  include/uapi/linux/vhost.h       |  4 ++++
>  include/uapi/linux/vhost_types.h |  9 +++++++
>  3 files changed, 54 insertions(+)
> 
> diff --git a/drivers/vhost/vdpa.c b/drivers/vhost/vdpa.c
> index 3fab94f88894..1adb4adb0345 100644
> --- a/drivers/vhost/vdpa.c
> +++ b/drivers/vhost/vdpa.c
> @@ -48,6 +48,7 @@ struct vhost_vdpa {
>  	int minor;
>  	struct eventfd_ctx *config_ctx;
>  	int in_batch;
> +	struct vdpa_iova_range range;
>  };
>  
>  static DEFINE_IDA(vhost_vdpa_ida);
> @@ -344,6 +345,16 @@ static long vhost_vdpa_set_config_call(struct vhost_vdpa *v, u32 __user *argp)
>  	return 0;
>  }
>  
> +static long vhost_vdpa_get_iova_range(struct vhost_vdpa *v, u32 __user *argp)
> +{
> +	struct vhost_vdpa_iova_range range = {
> +		.first = v->range.first,
> +		.last = v->range.last,
> +	};
> +
> +	return copy_to_user(argp, &range, sizeof(range));
> +}
> +
>  static long vhost_vdpa_vring_ioctl(struct vhost_vdpa *v, unsigned int cmd,
>  				   void __user *argp)
>  {
> @@ -476,6 +487,9 @@ static long vhost_vdpa_unlocked_ioctl(struct file *filep,
>  	case VHOST_VDPA_SET_CONFIG_CALL:
>  		r = vhost_vdpa_set_config_call(v, argp);
>  		break;
> +	case VHOST_VDPA_GET_IOVA_RANGE:
> +		r = vhost_vdpa_get_iova_range(v, argp);
> +		break;
>  	default:
>  		r = vhost_dev_ioctl(&v->vdev, cmd, argp);
>  		if (r == -ENOIOCTLCMD)
> @@ -597,6 +611,10 @@ static int vhost_vdpa_process_iotlb_update(struct vhost_vdpa *v,
>  	u64 iova = msg->iova;
>  	int ret = 0;
>  
> +	if (msg->iova < v->range.first ||
> +	    msg->iova + msg->size - 1 > v->range.last)
> +		return -EINVAL;
> +
>  	if (vhost_iotlb_itree_first(iotlb, msg->iova,
>  				    msg->iova + msg->size - 1))
>  		return -EEXIST;
> @@ -762,6 +780,27 @@ static void vhost_vdpa_free_domain(struct vhost_vdpa *v)
>  	v->domain = NULL;
>  }
>  
> +static void vhost_vdpa_set_iova_range(struct vhost_vdpa *v)
> +{
> +	struct vdpa_iova_range *range = &v->range;
> +	struct iommu_domain_geometry geo;
> +	struct vdpa_device *vdpa = v->vdpa;
> +	const struct vdpa_config_ops *ops = vdpa->config;
> +
> +	if (ops->get_iova_range) {
> +		*range = ops->get_iova_range(vdpa);
> +	} else if (v->domain &&
> +		   !iommu_domain_get_attr(v->domain,
> +		   DOMAIN_ATTR_GEOMETRY, &geo) &&
> +		   geo.force_aperture) {
> +		range->first = geo.aperture_start;
> +		range->last = geo.aperture_end;
> +	} else {
> +		range->first = 0;
> +		range->last = ULLONG_MAX;
> +	}

Shouldn't we require drivers that publish VIRTIO_F_ACCESS_PLATFORM to
implement get_iova_range?

> +}
> +
>  static int vhost_vdpa_open(struct inode *inode, struct file *filep)
>  {
>  	struct vhost_vdpa *v;
> @@ -802,6 +841,8 @@ static int vhost_vdpa_open(struct inode *inode, struct file *filep)
>  	if (r)
>  		goto err_init_iotlb;
>  
> +	vhost_vdpa_set_iova_range(v);
> +
>  	filep->private_data = v;
>  
>  	return 0;
> diff --git a/include/uapi/linux/vhost.h b/include/uapi/linux/vhost.h
> index 75232185324a..c998860d7bbc 100644
> --- a/include/uapi/linux/vhost.h
> +++ b/include/uapi/linux/vhost.h
> @@ -146,4 +146,8 @@
>  
>  /* Set event fd for config interrupt*/
>  #define VHOST_VDPA_SET_CONFIG_CALL	_IOW(VHOST_VIRTIO, 0x77, int)
> +
> +/* Get the valid iova range */
> +#define VHOST_VDPA_GET_IOVA_RANGE	_IOR(VHOST_VIRTIO, 0x78, \
> +					     struct vhost_vdpa_iova_range)
>  #endif
> diff --git a/include/uapi/linux/vhost_types.h b/include/uapi/linux/vhost_types.h
> index 9a269a88a6ff..f7f6a3a28977 100644
> --- a/include/uapi/linux/vhost_types.h
> +++ b/include/uapi/linux/vhost_types.h
> @@ -138,6 +138,15 @@ struct vhost_vdpa_config {
>  	__u8 buf[0];
>  };
>  
> +/* vhost vdpa IOVA range
> + * @first: First address that can be mapped by vhost-vDPA
> + * @last: Last address that can be mapped by vhost-vDPA
> + */
> +struct vhost_vdpa_iova_range {
> +	__u64 first;
> +	__u64 last;
> +};
> +
>  /* Feature bits */
>  /* Log all write descriptors. Can be changed while device is active. */
>  #define VHOST_F_LOG_ALL 26
> -- 
> 2.18.1
> 

Powered by blists - more mailing lists