All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Chen, Xiaoguang" <xiaoguang.chen@intel.com>
To: Alex Williamson <alex.williamson@redhat.com>
Cc: "kraxel@redhat.com" <kraxel@redhat.com>,
	"chris@chris-wilson.co.uk" <chris@chris-wilson.co.uk>,
	"intel-gfx@lists.freedesktop.org"
	<intel-gfx@lists.freedesktop.org>,
	"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
	"zhenyuw@linux.intel.com" <zhenyuw@linux.intel.com>,
	"Lv, Zhiyuan" <zhiyuan.lv@intel.com>,
	"intel-gvt-dev@lists.freedesktop.org" 
	<intel-gvt-dev@lists.freedesktop.org>,
	"Wang, Zhi A" <zhi.a.wang@intel.com>,
	"Tian, Kevin" <kevin.tian@intel.com>
Subject: RE: [PATCH v6 6/6] drm/i915/gvt: Adding interface so user space can get the dma-buf
Date: Fri, 2 Jun 2017 03:24:35 +0000	[thread overview]
Message-ID: <DD379D741F77464281CE7ED1CD7C12DE7066A99D@SHSMSX101.ccr.corp.intel.com> (raw)
In-Reply-To: <20170601120820.3358f7dd@w520.home>

Hi Alex,

>-----Original Message-----
>From: Alex Williamson [mailto:alex.williamson@redhat.com]
>Sent: Friday, June 02, 2017 2:08 AM
>To: Chen, Xiaoguang <xiaoguang.chen@intel.com>
>Cc: kraxel@redhat.com; chris@chris-wilson.co.uk; intel-
>gfx@lists.freedesktop.org; linux-kernel@vger.kernel.org;
>zhenyuw@linux.intel.com; Lv, Zhiyuan <zhiyuan.lv@intel.com>; intel-gvt-
>dev@lists.freedesktop.org; Wang, Zhi A <zhi.a.wang@intel.com>; Tian, Kevin
><kevin.tian@intel.com>
>Subject: Re: [PATCH v6 6/6] drm/i915/gvt: Adding interface so user space can get
>the dma-buf
>
>On Sat, 27 May 2017 16:38:52 +0800
>Xiaoguang Chen <xiaoguang.chen@intel.com> wrote:
>
>> User space should create the management fd for the dma-buf operation first.
>> Then user can query the plane information and create dma-buf if
>> necessary using the management fd.
>>
>> Signed-off-by: Xiaoguang Chen <xiaoguang.chen@intel.com>
>> ---
>>  drivers/gpu/drm/i915/gvt/dmabuf.c |  12 ++++
>>  drivers/gpu/drm/i915/gvt/dmabuf.h |   5 ++
>>  drivers/gpu/drm/i915/gvt/gvt.c    |   2 +
>>  drivers/gpu/drm/i915/gvt/gvt.h    |   5 ++
>>  drivers/gpu/drm/i915/gvt/kvmgt.c  | 144
>++++++++++++++++++++++++++++++++++++++
>>  drivers/gpu/drm/i915/gvt/vgpu.c   |   1 +
>>  6 files changed, 169 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/i915/gvt/dmabuf.c
>> b/drivers/gpu/drm/i915/gvt/dmabuf.c
>> index c831e91..9759e9a 100644
>> --- a/drivers/gpu/drm/i915/gvt/dmabuf.c
>> +++ b/drivers/gpu/drm/i915/gvt/dmabuf.c
>> @@ -226,6 +226,7 @@ int intel_vgpu_create_dmabuf(struct intel_vgpu *vgpu,
>void *args)
>>  	struct vfio_vgpu_dmabuf_info *gvt_dmabuf = args;
>>  	struct intel_vgpu_fb_info *fb_info;
>>  	int ret;
>> +	struct intel_vgpu_dmabuf_obj *dmabuf_obj;
>>
>>  	ret = intel_vgpu_get_plane_info(dev, vgpu, &gvt_dmabuf->plane_info);
>>  	if (ret != 0)
>> @@ -263,6 +264,17 @@ int intel_vgpu_create_dmabuf(struct intel_vgpu *vgpu,
>void *args)
>>  		gvt_vgpu_err("create dma-buf fd failed ret:%d\n", ret);
>>  		return ret;
>>  	}
>> +	dmabuf_obj = kmalloc(sizeof(*dmabuf_obj), GFP_KERNEL);
>> +	if (dmabuf_obj == NULL) {
>> +		kfree(fb_info);
>> +		i915_gem_object_put(obj);
>> +		gvt_vgpu_err("alloc dmabuf_obj failed\n");
>> +		return -ENOMEM;
>> +	}
>> +	dmabuf_obj->obj = obj;
>> +	INIT_LIST_HEAD(&dmabuf_obj->list);
>> +	list_add_tail(&dmabuf_obj->list, &vgpu->dmabuf_obj_list_head);
>> +
>>  	gvt_dmabuf->fd = ret;
>>
>>  	return 0;
>> diff --git a/drivers/gpu/drm/i915/gvt/dmabuf.h
>> b/drivers/gpu/drm/i915/gvt/dmabuf.h
>> index 8be9979..cafa781 100644
>> --- a/drivers/gpu/drm/i915/gvt/dmabuf.h
>> +++ b/drivers/gpu/drm/i915/gvt/dmabuf.h
>> @@ -31,6 +31,11 @@ struct intel_vgpu_fb_info {
>>  	uint32_t fb_size;
>>  };
>>
>> +struct intel_vgpu_dmabuf_obj {
>> +	struct drm_i915_gem_object *obj;
>> +	struct list_head list;
>> +};
>> +
>>  int intel_vgpu_query_plane(struct intel_vgpu *vgpu, void *args);  int
>> intel_vgpu_create_dmabuf(struct intel_vgpu *vgpu, void *args);
>>
>> diff --git a/drivers/gpu/drm/i915/gvt/gvt.c
>> b/drivers/gpu/drm/i915/gvt/gvt.c index 2032917..dbc3f86 100644
>> --- a/drivers/gpu/drm/i915/gvt/gvt.c
>> +++ b/drivers/gpu/drm/i915/gvt/gvt.c
>> @@ -54,6 +54,8 @@ static const struct intel_gvt_ops intel_gvt_ops = {
>>  	.vgpu_reset = intel_gvt_reset_vgpu,
>>  	.vgpu_activate = intel_gvt_activate_vgpu,
>>  	.vgpu_deactivate = intel_gvt_deactivate_vgpu,
>> +	.vgpu_query_plane = intel_vgpu_query_plane,
>> +	.vgpu_create_dmabuf = intel_vgpu_create_dmabuf,
>>  };
>>
>>  /**
>> diff --git a/drivers/gpu/drm/i915/gvt/gvt.h
>> b/drivers/gpu/drm/i915/gvt/gvt.h index 763a8c5..a855797 100644
>> --- a/drivers/gpu/drm/i915/gvt/gvt.h
>> +++ b/drivers/gpu/drm/i915/gvt/gvt.h
>> @@ -185,8 +185,11 @@ struct intel_vgpu {
>>  		struct kvm *kvm;
>>  		struct work_struct release_work;
>>  		atomic_t released;
>> +		struct vfio_device *vfio_device;
>>  	} vdev;
>>  #endif
>> +	int dmabuf_mgr_fd;
>> +	struct list_head dmabuf_obj_list_head;
>>  };
>>
>>  struct intel_gvt_gm {
>> @@ -467,6 +470,8 @@ struct intel_gvt_ops {
>>  	void (*vgpu_reset)(struct intel_vgpu *);
>>  	void (*vgpu_activate)(struct intel_vgpu *);
>>  	void (*vgpu_deactivate)(struct intel_vgpu *);
>> +	int (*vgpu_query_plane)(struct intel_vgpu *vgpu, void *);
>> +	int (*vgpu_create_dmabuf)(struct intel_vgpu *vgpu, void *);
>>  };
>>
>>
>> diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c
>> b/drivers/gpu/drm/i915/gvt/kvmgt.c
>> index 389f072..a079080 100644
>> --- a/drivers/gpu/drm/i915/gvt/kvmgt.c
>> +++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
>> @@ -41,6 +41,7 @@
>>  #include <linux/kvm_host.h>
>>  #include <linux/vfio.h>
>>  #include <linux/mdev.h>
>> +#include <linux/anon_inodes.h>
>>
>>  #include "i915_drv.h"
>>  #include "gvt.h"
>> @@ -524,6 +525,125 @@ static int intel_vgpu_reg_init_opregion(struct
>intel_vgpu *vgpu)
>>  	return ret;
>>  }
>>
>> +static int kvmgt_get_vfio_device(struct intel_vgpu *vgpu) {
>> +	struct vfio_device *device;
>> +
>> +	device = vfio_device_get_from_dev(mdev_dev(vgpu->vdev.mdev));
>> +	if (device == NULL)
>> +		return -ENODEV;
>> +	vgpu->vdev.vfio_device = device;
>> +
>> +	return 0;
>> +}
>> +
>> +static void kvmgt_put_vfio_device(struct intel_vgpu *vgpu) {
>> +	vfio_device_put(vgpu->vdev.vfio_device);
>> +}
>> +
>> +static int intel_vgpu_dmabuf_mgr_fd_mmap(struct file *file,
>> +		struct vm_area_struct *vma)
>> +{
>> +	return -EPERM;
>> +}
>> +
>> +static int intel_vgpu_dmabuf_mgr_fd_release(struct inode *inode,
>> +		struct file *filp)
>> +{
>> +	struct intel_vgpu *vgpu = filp->private_data;
>> +	struct intel_vgpu_dmabuf_obj *obj;
>> +	struct list_head *pos;
>> +
>> +	if (WARN_ON(!vgpu->vdev.vfio_device))
>> +		return -ENODEV;
>> +
>> +	list_for_each(pos, &vgpu->dmabuf_obj_list_head) {
>> +		obj = container_of(pos, struct intel_vgpu_dmabuf_obj, list);
>> +		if (WARN_ON(!obj))
>> +			return -ENODEV;
>> +		kfree(obj->obj->gvt_info);
>> +		i915_gem_object_put(obj->obj);
>> +		kfree(obj);
>> +		kvmgt_put_vfio_device(vgpu);
>
>Can we do this?  If I understand, we're releasing all the references and allocations
>for the dmabuf fds on release of the manager fd.  What happens if the user
>continues trying to access those dmabuf fds after this?
I think we can do this here.
The dma-buf's release function dma_buf_release() will be called by kernel which means all the created dmabufs will be invalid even we do not release all the references and allocations here.

>
>> +	}
>> +	kvmgt_put_vfio_device(vgpu);
>> +
>> +	return 0;
>> +}
>> +
>> +static long intel_vgpu_dmabuf_mgr_fd_ioctl(struct file *filp,
>> +		unsigned int ioctl, unsigned long arg) {
>> +	struct intel_vgpu *vgpu = filp->private_data;
>> +	int minsz;
>> +	int ret;
>> +	struct fd f;
>> +
>> +	f = fdget(vgpu->dmabuf_mgr_fd);
>> +	if (!f.file)
>> +		return -EBADF;
>> +
>> +	if (ioctl == VFIO_DEVICE_QUERY_PLANE) {
>> +		struct vfio_vgpu_plane_info info;
>> +
>> +		minsz = offsetofend(struct vfio_vgpu_plane_info, resv);
>> +		if (copy_from_user(&info, (void __user *)arg, minsz)) {
>> +			fdput(f);
>> +			return -EFAULT;
>> +		}
>> +		if (info.argsz < minsz) {
>> +			fdput(f);
>> +			return -EINVAL;
>> +		}
>> +		ret = intel_gvt_ops->vgpu_query_plane(vgpu, &info);
>> +		if (ret != 0) {
>> +			fdput(f);
>> +			gvt_vgpu_err("query plane failed:%d\n", ret);
>> +			return -EINVAL;
>> +		}
>> +		fdput(f);
>> +		return copy_to_user((void __user *)arg, &info, minsz) ?
>> +								-EFAULT : 0;
>> +	} else if (ioctl == VFIO_DEVICE_CREATE_DMABUF) {
>> +		struct vfio_vgpu_dmabuf_info dmabuf;
>> +
>> +		minsz = offsetofend(struct vfio_vgpu_dmabuf_info, resv);
>> +		if (copy_from_user(&dmabuf, (void __user *)arg, minsz)) {
>> +			fdput(f);
>> +			return -EFAULT;
>> +		}
>> +		if (dmabuf.argsz < minsz) {
>> +			fdput(f);
>> +			return -EINVAL;
>> +		}
>> +		ret = kvmgt_get_vfio_device(vgpu);
>> +		if (ret != 0)
>> +			return ret;
>
>Missed an fdput, though I'm not sure I understand the value of the original fdget
>or the dmabuf_mgr_fd field at all.  dmabuf_mgr_fd is only used here, presumably
>to add a reference to the fd while we're in the ioctl, but we're in the ioctl function
>of that fd, so I think there are already references elsewhere.
Make sense. Fdget/fdput can be removed.

>
>> +
>> +		ret = intel_gvt_ops->vgpu_create_dmabuf(vgpu, &dmabuf);
>> +		if (ret != 0) {
>> +			kvmgt_put_vfio_device(vgpu);
>> +			fdput(f);
>> +			return -EINVAL;
>
>Why not return the errno that vgpu_create_dmabuf provided?
Will change to use the returned errno.

>
>> +		}
>> +		fdput(f);
>> +		return copy_to_user((void __user *)arg, &dmabuf, minsz) ?
>> +								-EFAULT : 0;
>> +	}
>> +
>> +	fdput(f);
>> +	gvt_vgpu_err("unsupported dmabuf operation\n");
>> +
>> +	return -EINVAL;
>> +}
>> +
>> +static const struct file_operations intel_vgpu_dmabuf_mgr_fd_ops = {
>> +	.release        = intel_vgpu_dmabuf_mgr_fd_release,
>> +	.unlocked_ioctl = intel_vgpu_dmabuf_mgr_fd_ioctl,
>> +	.mmap           = intel_vgpu_dmabuf_mgr_fd_mmap,
>> +	.llseek         = noop_llseek,
>> +};
>>  static int intel_vgpu_create(struct kobject *kobj, struct mdev_device
>> *mdev)  {
>>  	struct intel_vgpu *vgpu = NULL;
>> @@ -1259,6 +1379,30 @@ static long intel_vgpu_ioctl(struct mdev_device
>*mdev, unsigned int cmd,
>>  	} else if (cmd == VFIO_DEVICE_RESET) {
>>  		intel_gvt_ops->vgpu_reset(vgpu);
>>  		return 0;
>> +	} else if (cmd == VFIO_DEVICE_GET_FD) {
>> +		int fd;
>> +		u32 type;
>> +		int ret;
>> +
>> +		if (copy_from_user(&type, (void __user *)arg, sizeof(type)))
>> +			return -EINVAL;
>> +		if (type != VFIO_DEVICE_DMABUF_MGR_FD)
>> +			return -EINVAL;
>> +
>> +		ret = kvmgt_get_vfio_device(vgpu);
>> +		if (ret != 0)
>> +			return ret;
>> +
>> +		fd = anon_inode_getfd("intel-vgpu-dmabuf-mgr-fd",
>> +			&intel_vgpu_dmabuf_mgr_fd_ops,
>> +			vgpu, O_RDWR | O_CLOEXEC);
>> +		if (fd < 0) {
>> +			gvt_vgpu_err("create dmabuf mgr fd failed\n");
>> +			return -EINVAL;
>
>Error path leaks vfio_device reference.
Will correct in the next version.

>
>> +		}
>> +		vgpu->dmabuf_mgr_fd = fd;
>
>As above, unclear value of this field, additionally, what if the user calls
>VFIO_DEVICE_GET_FD more than once?
Ah, good question.
VFIO_DEVICE_GET_FD should only be called once.
And we should add a check if the vgpu->dmabuf_mgr_fd is not 0 which means VFIO_DEVICE_GET_FD had been called before we should return an error.

>
>> +
>> +		return fd;
>>  	}
>>
>>  	return 0;
>> diff --git a/drivers/gpu/drm/i915/gvt/vgpu.c
>> b/drivers/gpu/drm/i915/gvt/vgpu.c index 6e3cbd8..af6fc74 100644
>> --- a/drivers/gpu/drm/i915/gvt/vgpu.c
>> +++ b/drivers/gpu/drm/i915/gvt/vgpu.c
>> @@ -346,6 +346,7 @@ static struct intel_vgpu
>*__intel_gvt_create_vgpu(struct intel_gvt *gvt,
>>  	vgpu->gvt = gvt;
>>  	vgpu->sched_ctl.weight = param->weight;
>>  	bitmap_zero(vgpu->tlb_handle_pending, I915_NUM_ENGINES);
>> +	INIT_LIST_HEAD(&vgpu->dmabuf_obj_list_head);
>>
>>  	intel_vgpu_init_cfg_space(vgpu, param->primary);
>>

WARNING: multiple messages have this Message-ID (diff)
From: "Chen, Xiaoguang" <xiaoguang.chen@intel.com>
To: Alex Williamson <alex.williamson@redhat.com>
Cc: "intel-gfx@lists.freedesktop.org"
	<intel-gfx@lists.freedesktop.org>,
	"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
	"Lv, Zhiyuan" <zhiyuan.lv@intel.com>,
	"intel-gvt-dev@lists.freedesktop.org"
	<intel-gvt-dev@lists.freedesktop.org>,
	"kraxel@redhat.com" <kraxel@redhat.com>
Subject: Re: [PATCH v6 6/6] drm/i915/gvt: Adding interface so user space can get the dma-buf
Date: Fri, 2 Jun 2017 03:24:35 +0000	[thread overview]
Message-ID: <DD379D741F77464281CE7ED1CD7C12DE7066A99D@SHSMSX101.ccr.corp.intel.com> (raw)
In-Reply-To: <20170601120820.3358f7dd@w520.home>

Hi Alex,

>-----Original Message-----
>From: Alex Williamson [mailto:alex.williamson@redhat.com]
>Sent: Friday, June 02, 2017 2:08 AM
>To: Chen, Xiaoguang <xiaoguang.chen@intel.com>
>Cc: kraxel@redhat.com; chris@chris-wilson.co.uk; intel-
>gfx@lists.freedesktop.org; linux-kernel@vger.kernel.org;
>zhenyuw@linux.intel.com; Lv, Zhiyuan <zhiyuan.lv@intel.com>; intel-gvt-
>dev@lists.freedesktop.org; Wang, Zhi A <zhi.a.wang@intel.com>; Tian, Kevin
><kevin.tian@intel.com>
>Subject: Re: [PATCH v6 6/6] drm/i915/gvt: Adding interface so user space can get
>the dma-buf
>
>On Sat, 27 May 2017 16:38:52 +0800
>Xiaoguang Chen <xiaoguang.chen@intel.com> wrote:
>
>> User space should create the management fd for the dma-buf operation first.
>> Then user can query the plane information and create dma-buf if
>> necessary using the management fd.
>>
>> Signed-off-by: Xiaoguang Chen <xiaoguang.chen@intel.com>
>> ---
>>  drivers/gpu/drm/i915/gvt/dmabuf.c |  12 ++++
>>  drivers/gpu/drm/i915/gvt/dmabuf.h |   5 ++
>>  drivers/gpu/drm/i915/gvt/gvt.c    |   2 +
>>  drivers/gpu/drm/i915/gvt/gvt.h    |   5 ++
>>  drivers/gpu/drm/i915/gvt/kvmgt.c  | 144
>++++++++++++++++++++++++++++++++++++++
>>  drivers/gpu/drm/i915/gvt/vgpu.c   |   1 +
>>  6 files changed, 169 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/i915/gvt/dmabuf.c
>> b/drivers/gpu/drm/i915/gvt/dmabuf.c
>> index c831e91..9759e9a 100644
>> --- a/drivers/gpu/drm/i915/gvt/dmabuf.c
>> +++ b/drivers/gpu/drm/i915/gvt/dmabuf.c
>> @@ -226,6 +226,7 @@ int intel_vgpu_create_dmabuf(struct intel_vgpu *vgpu,
>void *args)
>>  	struct vfio_vgpu_dmabuf_info *gvt_dmabuf = args;
>>  	struct intel_vgpu_fb_info *fb_info;
>>  	int ret;
>> +	struct intel_vgpu_dmabuf_obj *dmabuf_obj;
>>
>>  	ret = intel_vgpu_get_plane_info(dev, vgpu, &gvt_dmabuf->plane_info);
>>  	if (ret != 0)
>> @@ -263,6 +264,17 @@ int intel_vgpu_create_dmabuf(struct intel_vgpu *vgpu,
>void *args)
>>  		gvt_vgpu_err("create dma-buf fd failed ret:%d\n", ret);
>>  		return ret;
>>  	}
>> +	dmabuf_obj = kmalloc(sizeof(*dmabuf_obj), GFP_KERNEL);
>> +	if (dmabuf_obj == NULL) {
>> +		kfree(fb_info);
>> +		i915_gem_object_put(obj);
>> +		gvt_vgpu_err("alloc dmabuf_obj failed\n");
>> +		return -ENOMEM;
>> +	}
>> +	dmabuf_obj->obj = obj;
>> +	INIT_LIST_HEAD(&dmabuf_obj->list);
>> +	list_add_tail(&dmabuf_obj->list, &vgpu->dmabuf_obj_list_head);
>> +
>>  	gvt_dmabuf->fd = ret;
>>
>>  	return 0;
>> diff --git a/drivers/gpu/drm/i915/gvt/dmabuf.h
>> b/drivers/gpu/drm/i915/gvt/dmabuf.h
>> index 8be9979..cafa781 100644
>> --- a/drivers/gpu/drm/i915/gvt/dmabuf.h
>> +++ b/drivers/gpu/drm/i915/gvt/dmabuf.h
>> @@ -31,6 +31,11 @@ struct intel_vgpu_fb_info {
>>  	uint32_t fb_size;
>>  };
>>
>> +struct intel_vgpu_dmabuf_obj {
>> +	struct drm_i915_gem_object *obj;
>> +	struct list_head list;
>> +};
>> +
>>  int intel_vgpu_query_plane(struct intel_vgpu *vgpu, void *args);  int
>> intel_vgpu_create_dmabuf(struct intel_vgpu *vgpu, void *args);
>>
>> diff --git a/drivers/gpu/drm/i915/gvt/gvt.c
>> b/drivers/gpu/drm/i915/gvt/gvt.c index 2032917..dbc3f86 100644
>> --- a/drivers/gpu/drm/i915/gvt/gvt.c
>> +++ b/drivers/gpu/drm/i915/gvt/gvt.c
>> @@ -54,6 +54,8 @@ static const struct intel_gvt_ops intel_gvt_ops = {
>>  	.vgpu_reset = intel_gvt_reset_vgpu,
>>  	.vgpu_activate = intel_gvt_activate_vgpu,
>>  	.vgpu_deactivate = intel_gvt_deactivate_vgpu,
>> +	.vgpu_query_plane = intel_vgpu_query_plane,
>> +	.vgpu_create_dmabuf = intel_vgpu_create_dmabuf,
>>  };
>>
>>  /**
>> diff --git a/drivers/gpu/drm/i915/gvt/gvt.h
>> b/drivers/gpu/drm/i915/gvt/gvt.h index 763a8c5..a855797 100644
>> --- a/drivers/gpu/drm/i915/gvt/gvt.h
>> +++ b/drivers/gpu/drm/i915/gvt/gvt.h
>> @@ -185,8 +185,11 @@ struct intel_vgpu {
>>  		struct kvm *kvm;
>>  		struct work_struct release_work;
>>  		atomic_t released;
>> +		struct vfio_device *vfio_device;
>>  	} vdev;
>>  #endif
>> +	int dmabuf_mgr_fd;
>> +	struct list_head dmabuf_obj_list_head;
>>  };
>>
>>  struct intel_gvt_gm {
>> @@ -467,6 +470,8 @@ struct intel_gvt_ops {
>>  	void (*vgpu_reset)(struct intel_vgpu *);
>>  	void (*vgpu_activate)(struct intel_vgpu *);
>>  	void (*vgpu_deactivate)(struct intel_vgpu *);
>> +	int (*vgpu_query_plane)(struct intel_vgpu *vgpu, void *);
>> +	int (*vgpu_create_dmabuf)(struct intel_vgpu *vgpu, void *);
>>  };
>>
>>
>> diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c
>> b/drivers/gpu/drm/i915/gvt/kvmgt.c
>> index 389f072..a079080 100644
>> --- a/drivers/gpu/drm/i915/gvt/kvmgt.c
>> +++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
>> @@ -41,6 +41,7 @@
>>  #include <linux/kvm_host.h>
>>  #include <linux/vfio.h>
>>  #include <linux/mdev.h>
>> +#include <linux/anon_inodes.h>
>>
>>  #include "i915_drv.h"
>>  #include "gvt.h"
>> @@ -524,6 +525,125 @@ static int intel_vgpu_reg_init_opregion(struct
>intel_vgpu *vgpu)
>>  	return ret;
>>  }
>>
>> +static int kvmgt_get_vfio_device(struct intel_vgpu *vgpu) {
>> +	struct vfio_device *device;
>> +
>> +	device = vfio_device_get_from_dev(mdev_dev(vgpu->vdev.mdev));
>> +	if (device == NULL)
>> +		return -ENODEV;
>> +	vgpu->vdev.vfio_device = device;
>> +
>> +	return 0;
>> +}
>> +
>> +static void kvmgt_put_vfio_device(struct intel_vgpu *vgpu) {
>> +	vfio_device_put(vgpu->vdev.vfio_device);
>> +}
>> +
>> +static int intel_vgpu_dmabuf_mgr_fd_mmap(struct file *file,
>> +		struct vm_area_struct *vma)
>> +{
>> +	return -EPERM;
>> +}
>> +
>> +static int intel_vgpu_dmabuf_mgr_fd_release(struct inode *inode,
>> +		struct file *filp)
>> +{
>> +	struct intel_vgpu *vgpu = filp->private_data;
>> +	struct intel_vgpu_dmabuf_obj *obj;
>> +	struct list_head *pos;
>> +
>> +	if (WARN_ON(!vgpu->vdev.vfio_device))
>> +		return -ENODEV;
>> +
>> +	list_for_each(pos, &vgpu->dmabuf_obj_list_head) {
>> +		obj = container_of(pos, struct intel_vgpu_dmabuf_obj, list);
>> +		if (WARN_ON(!obj))
>> +			return -ENODEV;
>> +		kfree(obj->obj->gvt_info);
>> +		i915_gem_object_put(obj->obj);
>> +		kfree(obj);
>> +		kvmgt_put_vfio_device(vgpu);
>
>Can we do this?  If I understand, we're releasing all the references and allocations
>for the dmabuf fds on release of the manager fd.  What happens if the user
>continues trying to access those dmabuf fds after this?
I think we can do this here.
The dma-buf's release function dma_buf_release() will be called by kernel which means all the created dmabufs will be invalid even we do not release all the references and allocations here.

>
>> +	}
>> +	kvmgt_put_vfio_device(vgpu);
>> +
>> +	return 0;
>> +}
>> +
>> +static long intel_vgpu_dmabuf_mgr_fd_ioctl(struct file *filp,
>> +		unsigned int ioctl, unsigned long arg) {
>> +	struct intel_vgpu *vgpu = filp->private_data;
>> +	int minsz;
>> +	int ret;
>> +	struct fd f;
>> +
>> +	f = fdget(vgpu->dmabuf_mgr_fd);
>> +	if (!f.file)
>> +		return -EBADF;
>> +
>> +	if (ioctl == VFIO_DEVICE_QUERY_PLANE) {
>> +		struct vfio_vgpu_plane_info info;
>> +
>> +		minsz = offsetofend(struct vfio_vgpu_plane_info, resv);
>> +		if (copy_from_user(&info, (void __user *)arg, minsz)) {
>> +			fdput(f);
>> +			return -EFAULT;
>> +		}
>> +		if (info.argsz < minsz) {
>> +			fdput(f);
>> +			return -EINVAL;
>> +		}
>> +		ret = intel_gvt_ops->vgpu_query_plane(vgpu, &info);
>> +		if (ret != 0) {
>> +			fdput(f);
>> +			gvt_vgpu_err("query plane failed:%d\n", ret);
>> +			return -EINVAL;
>> +		}
>> +		fdput(f);
>> +		return copy_to_user((void __user *)arg, &info, minsz) ?
>> +								-EFAULT : 0;
>> +	} else if (ioctl == VFIO_DEVICE_CREATE_DMABUF) {
>> +		struct vfio_vgpu_dmabuf_info dmabuf;
>> +
>> +		minsz = offsetofend(struct vfio_vgpu_dmabuf_info, resv);
>> +		if (copy_from_user(&dmabuf, (void __user *)arg, minsz)) {
>> +			fdput(f);
>> +			return -EFAULT;
>> +		}
>> +		if (dmabuf.argsz < minsz) {
>> +			fdput(f);
>> +			return -EINVAL;
>> +		}
>> +		ret = kvmgt_get_vfio_device(vgpu);
>> +		if (ret != 0)
>> +			return ret;
>
>Missed an fdput, though I'm not sure I understand the value of the original fdget
>or the dmabuf_mgr_fd field at all.  dmabuf_mgr_fd is only used here, presumably
>to add a reference to the fd while we're in the ioctl, but we're in the ioctl function
>of that fd, so I think there are already references elsewhere.
Make sense. Fdget/fdput can be removed.

>
>> +
>> +		ret = intel_gvt_ops->vgpu_create_dmabuf(vgpu, &dmabuf);
>> +		if (ret != 0) {
>> +			kvmgt_put_vfio_device(vgpu);
>> +			fdput(f);
>> +			return -EINVAL;
>
>Why not return the errno that vgpu_create_dmabuf provided?
Will change to use the returned errno.

>
>> +		}
>> +		fdput(f);
>> +		return copy_to_user((void __user *)arg, &dmabuf, minsz) ?
>> +								-EFAULT : 0;
>> +	}
>> +
>> +	fdput(f);
>> +	gvt_vgpu_err("unsupported dmabuf operation\n");
>> +
>> +	return -EINVAL;
>> +}
>> +
>> +static const struct file_operations intel_vgpu_dmabuf_mgr_fd_ops = {
>> +	.release        = intel_vgpu_dmabuf_mgr_fd_release,
>> +	.unlocked_ioctl = intel_vgpu_dmabuf_mgr_fd_ioctl,
>> +	.mmap           = intel_vgpu_dmabuf_mgr_fd_mmap,
>> +	.llseek         = noop_llseek,
>> +};
>>  static int intel_vgpu_create(struct kobject *kobj, struct mdev_device
>> *mdev)  {
>>  	struct intel_vgpu *vgpu = NULL;
>> @@ -1259,6 +1379,30 @@ static long intel_vgpu_ioctl(struct mdev_device
>*mdev, unsigned int cmd,
>>  	} else if (cmd == VFIO_DEVICE_RESET) {
>>  		intel_gvt_ops->vgpu_reset(vgpu);
>>  		return 0;
>> +	} else if (cmd == VFIO_DEVICE_GET_FD) {
>> +		int fd;
>> +		u32 type;
>> +		int ret;
>> +
>> +		if (copy_from_user(&type, (void __user *)arg, sizeof(type)))
>> +			return -EINVAL;
>> +		if (type != VFIO_DEVICE_DMABUF_MGR_FD)
>> +			return -EINVAL;
>> +
>> +		ret = kvmgt_get_vfio_device(vgpu);
>> +		if (ret != 0)
>> +			return ret;
>> +
>> +		fd = anon_inode_getfd("intel-vgpu-dmabuf-mgr-fd",
>> +			&intel_vgpu_dmabuf_mgr_fd_ops,
>> +			vgpu, O_RDWR | O_CLOEXEC);
>> +		if (fd < 0) {
>> +			gvt_vgpu_err("create dmabuf mgr fd failed\n");
>> +			return -EINVAL;
>
>Error path leaks vfio_device reference.
Will correct in the next version.

>
>> +		}
>> +		vgpu->dmabuf_mgr_fd = fd;
>
>As above, unclear value of this field, additionally, what if the user calls
>VFIO_DEVICE_GET_FD more than once?
Ah, good question.
VFIO_DEVICE_GET_FD should only be called once.
And we should add a check if the vgpu->dmabuf_mgr_fd is not 0 which means VFIO_DEVICE_GET_FD had been called before we should return an error.

>
>> +
>> +		return fd;
>>  	}
>>
>>  	return 0;
>> diff --git a/drivers/gpu/drm/i915/gvt/vgpu.c
>> b/drivers/gpu/drm/i915/gvt/vgpu.c index 6e3cbd8..af6fc74 100644
>> --- a/drivers/gpu/drm/i915/gvt/vgpu.c
>> +++ b/drivers/gpu/drm/i915/gvt/vgpu.c
>> @@ -346,6 +346,7 @@ static struct intel_vgpu
>*__intel_gvt_create_vgpu(struct intel_gvt *gvt,
>>  	vgpu->gvt = gvt;
>>  	vgpu->sched_ctl.weight = param->weight;
>>  	bitmap_zero(vgpu->tlb_handle_pending, I915_NUM_ENGINES);
>> +	INIT_LIST_HEAD(&vgpu->dmabuf_obj_list_head);
>>
>>  	intel_vgpu_init_cfg_space(vgpu, param->primary);
>>

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

  reply	other threads:[~2017-06-02  3:24 UTC|newest]

Thread overview: 74+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-05-27  8:38 [PATCH v6 0/6] drm/i915/gvt: Dma-buf support for GVT-g Xiaoguang Chen
2017-05-27  8:38 ` Xiaoguang Chen
2017-05-27  8:38 ` [PATCH v6 1/6] drm/i915/gvt: Extend the GVT-g architecture to support vfio device region Xiaoguang Chen
2017-05-27  8:38   ` Xiaoguang Chen
2017-05-27  8:38 ` [PATCH v6 2/6] drm/i915/gvt: OpRegion support for GVT-g Xiaoguang Chen
2017-05-27  8:38   ` Xiaoguang Chen
2017-05-31  4:47   ` Zhenyu Wang
2017-05-31  4:47     ` Zhenyu Wang
2017-05-31  6:22     ` Chen, Xiaoguang
2017-05-31  6:22       ` Chen, Xiaoguang
2017-05-31  6:30       ` Zhenyu Wang
2017-05-31  6:30         ` Zhenyu Wang
2017-05-31  6:44         ` Chen, Xiaoguang
2017-05-31  6:44           ` Chen, Xiaoguang
2017-05-27  8:38 ` [PATCH v6 3/6] drm/i915/gvt: Frame buffer decoder " Xiaoguang Chen
2017-05-27  8:38   ` Xiaoguang Chen
2017-05-31  5:12   ` Zhenyu Wang
2017-05-31  5:12     ` Zhenyu Wang
2017-05-31  6:46     ` Chen, Xiaoguang
2017-05-31  6:46       ` Chen, Xiaoguang
2017-05-27  8:38 ` [PATCH v6 4/6] vfio: Define vfio based vgpu's dma-buf operations Xiaoguang Chen
2017-05-29  7:20   ` Gerd Hoffmann
2017-05-29  7:20     ` Gerd Hoffmann
2017-05-31  6:18     ` Chen, Xiaoguang
2017-05-31  6:18       ` Chen, Xiaoguang
2017-05-31 17:22       ` Kirti Wankhede
2017-05-31 17:22         ` Kirti Wankhede
2017-06-01  3:01         ` Chen, Xiaoguang
2017-06-01  3:01           ` Chen, Xiaoguang
2017-06-01 16:38           ` Alex Williamson
2017-06-01 16:38             ` Alex Williamson
2017-06-01 18:46             ` Kirti Wankhede
2017-06-01 18:46               ` Kirti Wankhede
2017-06-02  8:38               ` Gerd Hoffmann
2017-06-02  8:38                 ` Gerd Hoffmann
2017-06-05  8:26                 ` Kirti Wankhede
2017-06-05  8:26                   ` Kirti Wankhede
2017-06-06  7:59                   ` Gerd Hoffmann
2017-06-06  7:59                     ` Gerd Hoffmann
2017-05-27  8:38 ` [PATCH v6 5/6] drm/i915/gvt: Dmabuf support for GVT-g Xiaoguang Chen
2017-05-27  8:38   ` Xiaoguang Chen
2017-05-31 12:04   ` Gerd Hoffmann
2017-05-31 12:04     ` Gerd Hoffmann
2017-06-01  3:02     ` Chen, Xiaoguang
2017-06-01  3:02       ` Chen, Xiaoguang
2017-06-01  9:15   ` Chris Wilson
2017-06-01  9:15     ` Chris Wilson
2017-05-27  8:38 ` [PATCH v6 6/6] drm/i915/gvt: Adding interface so user space can get the dma-buf Xiaoguang Chen
2017-05-27  8:38   ` Xiaoguang Chen
2017-06-01 18:08   ` Alex Williamson
2017-06-01 18:08     ` Alex Williamson
2017-06-02  3:24     ` Chen, Xiaoguang [this message]
2017-06-02  3:24       ` Chen, Xiaoguang
2017-06-02  3:34       ` Alex Williamson
2017-06-02  3:34         ` Alex Williamson
2017-06-02  9:31         ` Chen, Xiaoguang
2017-06-02  9:31           ` Chen, Xiaoguang
2017-06-02 14:58           ` Alex Williamson
2017-06-02 14:58             ` Alex Williamson
2017-06-02 15:23             ` Gerd Hoffmann
2017-06-02 15:23               ` Gerd Hoffmann
2017-06-05  2:39               ` Chen, Xiaoguang
2017-06-05  2:39                 ` Chen, Xiaoguang
2017-06-06  7:35                 ` Gerd Hoffmann
2017-06-06  7:35                   ` Gerd Hoffmann
2017-05-27  8:44 ` ✗ Fi.CI.BAT: failure for drm/i915/gvt: dma-buf support for GVT-g (rev6) Patchwork
2017-05-30 10:23 ` [PATCH v6 0/6] drm/i915/gvt: Dma-buf support for GVT-g Gerd Hoffmann
2017-05-30 10:23   ` Gerd Hoffmann
2017-05-31  2:29   ` Chen, Xiaoguang
2017-05-31  2:29     ` Chen, Xiaoguang
2017-05-31  8:59     ` Gerd Hoffmann
2017-05-31  8:59       ` Gerd Hoffmann
2017-05-31  9:07       ` Chen, Xiaoguang
2017-05-31  9:07         ` Chen, Xiaoguang

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=DD379D741F77464281CE7ED1CD7C12DE7066A99D@SHSMSX101.ccr.corp.intel.com \
    --to=xiaoguang.chen@intel.com \
    --cc=alex.williamson@redhat.com \
    --cc=chris@chris-wilson.co.uk \
    --cc=intel-gfx@lists.freedesktop.org \
    --cc=intel-gvt-dev@lists.freedesktop.org \
    --cc=kevin.tian@intel.com \
    --cc=kraxel@redhat.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=zhenyuw@linux.intel.com \
    --cc=zhi.a.wang@intel.com \
    --cc=zhiyuan.lv@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.