[PATCH v9 4/7] drm/i915/gvt: Frame buffer decoder support for GVT-g

2017-06-15 Thread Xiaoguang Chen
decode frambuffer attributes of primary, cursor and sprite plane

Signed-off-by: Xiaoguang Chen <xiaoguang.c...@intel.com>
---
 drivers/gpu/drm/i915/gvt/Makefile |   3 +-
 drivers/gpu/drm/i915/gvt/display.c|   2 +-
 drivers/gpu/drm/i915/gvt/display.h|   2 +
 drivers/gpu/drm/i915/gvt/fb_decoder.c | 425 ++
 drivers/gpu/drm/i915/gvt/fb_decoder.h | 171 ++
 drivers/gpu/drm/i915/gvt/gvt.h|   1 +
 6 files changed, 602 insertions(+), 2 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/gvt/fb_decoder.c
 create mode 100644 drivers/gpu/drm/i915/gvt/fb_decoder.h

diff --git a/drivers/gpu/drm/i915/gvt/Makefile 
b/drivers/gpu/drm/i915/gvt/Makefile
index b123c20..192ca26 100644
--- a/drivers/gpu/drm/i915/gvt/Makefile
+++ b/drivers/gpu/drm/i915/gvt/Makefile
@@ -1,7 +1,8 @@
 GVT_DIR := gvt
 GVT_SOURCE := gvt.o aperture_gm.o handlers.o vgpu.o trace_points.o firmware.o \
interrupt.o gtt.o cfg_space.o opregion.o mmio.o display.o edid.o \
-   execlist.o scheduler.o sched_policy.o render.o cmd_parser.o
+   execlist.o scheduler.o sched_policy.o render.o cmd_parser.o \
+   fb_decoder.o
 
 ccflags-y  += -I$(src) -I$(src)/$(GVT_DIR) -Wall
 i915-y += $(addprefix $(GVT_DIR)/, 
$(GVT_SOURCE))
diff --git a/drivers/gpu/drm/i915/gvt/display.c 
b/drivers/gpu/drm/i915/gvt/display.c
index e0261fc..f5f63c5 100644
--- a/drivers/gpu/drm/i915/gvt/display.c
+++ b/drivers/gpu/drm/i915/gvt/display.c
@@ -67,7 +67,7 @@ static int edp_pipe_is_enabled(struct intel_vgpu *vgpu)
return 1;
 }
 
-static int pipe_is_enabled(struct intel_vgpu *vgpu, int pipe)
+int pipe_is_enabled(struct intel_vgpu *vgpu, int pipe)
 {
struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv;
 
diff --git a/drivers/gpu/drm/i915/gvt/display.h 
b/drivers/gpu/drm/i915/gvt/display.h
index d73de22..b46b868 100644
--- a/drivers/gpu/drm/i915/gvt/display.h
+++ b/drivers/gpu/drm/i915/gvt/display.h
@@ -179,4 +179,6 @@ int intel_vgpu_init_display(struct intel_vgpu *vgpu, u64 
resolution);
 void intel_vgpu_reset_display(struct intel_vgpu *vgpu);
 void intel_vgpu_clean_display(struct intel_vgpu *vgpu);
 
+int pipe_is_enabled(struct intel_vgpu *vgpu, int pipe);
+
 #endif
diff --git a/drivers/gpu/drm/i915/gvt/fb_decoder.c 
b/drivers/gpu/drm/i915/gvt/fb_decoder.c
new file mode 100644
index 000..a4614b5
--- /dev/null
+++ b/drivers/gpu/drm/i915/gvt/fb_decoder.c
@@ -0,0 +1,425 @@
+/*
+ * Copyright(c) 2011-2016 Intel Corporation. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 
THE
+ * SOFTWARE.
+ *
+ * Authors:
+ *Kevin Tian <kevin.t...@intel.com>
+ *
+ * Contributors:
+ *Bing Niu <bing@intel.com>
+ *Xu Han <xu@intel.com>
+ *    Ping Gao <ping.a@intel.com>
+ *Xiaoguang Chen <xiaoguang.c...@intel.com>
+ *Yang Liu <yang2@intel.com>
+ *
+ */
+
+#include 
+#include "i915_drv.h"
+#include "gvt.h"
+
+#define PRIMARY_FORMAT_NUM 16
+struct pixel_format {
+   int drm_format; /* Pixel format in DRM definition */
+   int bpp;/* Bits per pixel, 0 indicates invalid */
+   char *desc; /* The description */
+};
+
+/* non-supported format has bpp default to 0 */
+static struct pixel_format bdw_pixel_formats[PRIMARY_FORMAT_NUM] = {
+   [0x2] = {DRM_FORMAT_C8, 8, "8-bit Indexed"},
+   [0x5] = {DRM_FORMAT_RGB565, 16, "16-bit BGRX (5:6:5 MSB-R:G:B)"},
+   [0x6] = {DRM_FORMAT_XRGB, 32,
+   "32-bit BGRX (8:8:8:8 MSB-X:R:G:B)"},
+   [0x8] = {DRM_FORMAT_XBGR2101010, 32,
+   "32-bit RGBX (2:10:10:10 MSB-X:B:G:R)"},
+   [0xa] = {DRM_FORMAT_XRGB2101010, 32,
+   "32-bit BGRX (2:10:10:10 MSB-X:R:G:B

[PATCH v9 4/7] drm/i915/gvt: Frame buffer decoder support for GVT-g

2017-06-15 Thread Xiaoguang Chen
decode frambuffer attributes of primary, cursor and sprite plane

Signed-off-by: Xiaoguang Chen 
---
 drivers/gpu/drm/i915/gvt/Makefile |   3 +-
 drivers/gpu/drm/i915/gvt/display.c|   2 +-
 drivers/gpu/drm/i915/gvt/display.h|   2 +
 drivers/gpu/drm/i915/gvt/fb_decoder.c | 425 ++
 drivers/gpu/drm/i915/gvt/fb_decoder.h | 171 ++
 drivers/gpu/drm/i915/gvt/gvt.h|   1 +
 6 files changed, 602 insertions(+), 2 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/gvt/fb_decoder.c
 create mode 100644 drivers/gpu/drm/i915/gvt/fb_decoder.h

diff --git a/drivers/gpu/drm/i915/gvt/Makefile 
b/drivers/gpu/drm/i915/gvt/Makefile
index b123c20..192ca26 100644
--- a/drivers/gpu/drm/i915/gvt/Makefile
+++ b/drivers/gpu/drm/i915/gvt/Makefile
@@ -1,7 +1,8 @@
 GVT_DIR := gvt
 GVT_SOURCE := gvt.o aperture_gm.o handlers.o vgpu.o trace_points.o firmware.o \
interrupt.o gtt.o cfg_space.o opregion.o mmio.o display.o edid.o \
-   execlist.o scheduler.o sched_policy.o render.o cmd_parser.o
+   execlist.o scheduler.o sched_policy.o render.o cmd_parser.o \
+   fb_decoder.o
 
 ccflags-y  += -I$(src) -I$(src)/$(GVT_DIR) -Wall
 i915-y += $(addprefix $(GVT_DIR)/, 
$(GVT_SOURCE))
diff --git a/drivers/gpu/drm/i915/gvt/display.c 
b/drivers/gpu/drm/i915/gvt/display.c
index e0261fc..f5f63c5 100644
--- a/drivers/gpu/drm/i915/gvt/display.c
+++ b/drivers/gpu/drm/i915/gvt/display.c
@@ -67,7 +67,7 @@ static int edp_pipe_is_enabled(struct intel_vgpu *vgpu)
return 1;
 }
 
-static int pipe_is_enabled(struct intel_vgpu *vgpu, int pipe)
+int pipe_is_enabled(struct intel_vgpu *vgpu, int pipe)
 {
struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv;
 
diff --git a/drivers/gpu/drm/i915/gvt/display.h 
b/drivers/gpu/drm/i915/gvt/display.h
index d73de22..b46b868 100644
--- a/drivers/gpu/drm/i915/gvt/display.h
+++ b/drivers/gpu/drm/i915/gvt/display.h
@@ -179,4 +179,6 @@ int intel_vgpu_init_display(struct intel_vgpu *vgpu, u64 
resolution);
 void intel_vgpu_reset_display(struct intel_vgpu *vgpu);
 void intel_vgpu_clean_display(struct intel_vgpu *vgpu);
 
+int pipe_is_enabled(struct intel_vgpu *vgpu, int pipe);
+
 #endif
diff --git a/drivers/gpu/drm/i915/gvt/fb_decoder.c 
b/drivers/gpu/drm/i915/gvt/fb_decoder.c
new file mode 100644
index 000..a4614b5
--- /dev/null
+++ b/drivers/gpu/drm/i915/gvt/fb_decoder.c
@@ -0,0 +1,425 @@
+/*
+ * Copyright(c) 2011-2016 Intel Corporation. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 
THE
+ * SOFTWARE.
+ *
+ * Authors:
+ *Kevin Tian 
+ *
+ * Contributors:
+ *Bing Niu 
+ *Xu Han 
+ *Ping Gao 
+ *Xiaoguang Chen 
+ *Yang Liu 
+ *
+ */
+
+#include 
+#include "i915_drv.h"
+#include "gvt.h"
+
+#define PRIMARY_FORMAT_NUM 16
+struct pixel_format {
+   int drm_format; /* Pixel format in DRM definition */
+   int bpp;/* Bits per pixel, 0 indicates invalid */
+   char *desc; /* The description */
+};
+
+/* non-supported format has bpp default to 0 */
+static struct pixel_format bdw_pixel_formats[PRIMARY_FORMAT_NUM] = {
+   [0x2] = {DRM_FORMAT_C8, 8, "8-bit Indexed"},
+   [0x5] = {DRM_FORMAT_RGB565, 16, "16-bit BGRX (5:6:5 MSB-R:G:B)"},
+   [0x6] = {DRM_FORMAT_XRGB, 32,
+   "32-bit BGRX (8:8:8:8 MSB-X:R:G:B)"},
+   [0x8] = {DRM_FORMAT_XBGR2101010, 32,
+   "32-bit RGBX (2:10:10:10 MSB-X:B:G:R)"},
+   [0xa] = {DRM_FORMAT_XRGB2101010, 32,
+   "32-bit BGRX (2:10:10:10 MSB-X:R:G:B)"},
+   [0xc] = {DRM_FORMAT_XRGB161616, 64,
+   "64-bit RGBX Floating Point(16:16:16:16 MSB-X:B:G:R)"},
+   [0xe] = {DRM_FORMAT_XBGR, 32,
+   "32-bit R

[PATCH v9 5/7] vfio: Define vfio based dma-buf operations

2017-06-15 Thread Xiaoguang Chen
Here we defined a new ioctl to create a fd for a vfio device based on
the input type. Now only one type is supported that is a dma-buf
management fd.
Two ioctls are defined for the dma-buf management fd: query the vfio
vgpu's plane information and create a dma-buf for a plane.

Signed-off-by: Xiaoguang Chen <xiaoguang.c...@intel.com>
---
 include/uapi/linux/vfio.h | 57 +++
 1 file changed, 57 insertions(+)

diff --git a/include/uapi/linux/vfio.h b/include/uapi/linux/vfio.h
index ae46105..7d86101 100644
--- a/include/uapi/linux/vfio.h
+++ b/include/uapi/linux/vfio.h
@@ -502,6 +502,63 @@ struct vfio_pci_hot_reset {
 
 #define VFIO_DEVICE_PCI_HOT_RESET  _IO(VFIO_TYPE, VFIO_BASE + 13)
 
+/**
+ * VFIO_DEVICE_GET_FD - _IO(VFIO_TYPE, VFIO_BASE + 14, __u32)
+ *
+ * Create a fd for a vfio device based on the input type
+ * Vendor driver should handle this ioctl to create a fd and manage the
+ * life cycle of this fd.
+ *
+ * Return: a fd if vendor support that type, -errno if not supported
+ */
+
+#define VFIO_DEVICE_GET_FD _IO(VFIO_TYPE, VFIO_BASE + 14)
+
+#define VFIO_DEVICE_DMABUF_MGR_FD  0 /* Supported fd types */
+
+struct vfio_dmabuf_mgr_plane_info {
+   __u64 start;
+   __u64 drm_format_mod;
+   __u32 drm_format;
+   __u32 width;
+   __u32 height;
+   __u32 stride;
+   __u32 size;
+   __u32 x_pos;
+   __u32 y_pos;
+   __u32 padding;
+};
+
+/*
+ * VFIO_DMABUF_MGR_QUERY_PLANE - _IO(VFIO_TYPE, VFIO_BASE + 15,
+ * struct vfio_dmabuf_mgr_query_plane)
+ * Query plane information
+ */
+struct vfio_dmabuf_mgr_query_plane {
+   __u32 argsz;
+   __u32 flags;
+   struct vfio_dmabuf_mgr_plane_info plane_info;
+   __u32 plane_id;
+};
+
+#define VFIO_DMABUF_MGR_QUERY_PLANE _IO(VFIO_TYPE, VFIO_BASE + 15)
+
+/*
+ * VFIO_DMABUF_MGR_CREATE_DMABUF - _IO(VFIO, VFIO_BASE + 16,
+ * struct vfio_dmabuf_mgr_create_dmabuf)
+ *
+ * Create a dma-buf for a plane
+ */
+struct vfio_dmabuf_mgr_create_dmabuf {
+   __u32 argsz;
+   __u32 flags;
+   struct vfio_dmabuf_mgr_plane_info plane_info;
+   __u32 plane_id;
+   __s32 fd;
+};
+
+#define VFIO_DMABUF_MGR_CREATE_DMABUF _IO(VFIO_TYPE, VFIO_BASE + 16)
+
 /*  API for Type1 VFIO IOMMU  */
 
 /**
-- 
2.7.4



[PATCH v9 5/7] vfio: Define vfio based dma-buf operations

2017-06-15 Thread Xiaoguang Chen
Here we defined a new ioctl to create a fd for a vfio device based on
the input type. Now only one type is supported that is a dma-buf
management fd.
Two ioctls are defined for the dma-buf management fd: query the vfio
vgpu's plane information and create a dma-buf for a plane.

Signed-off-by: Xiaoguang Chen 
---
 include/uapi/linux/vfio.h | 57 +++
 1 file changed, 57 insertions(+)

diff --git a/include/uapi/linux/vfio.h b/include/uapi/linux/vfio.h
index ae46105..7d86101 100644
--- a/include/uapi/linux/vfio.h
+++ b/include/uapi/linux/vfio.h
@@ -502,6 +502,63 @@ struct vfio_pci_hot_reset {
 
 #define VFIO_DEVICE_PCI_HOT_RESET  _IO(VFIO_TYPE, VFIO_BASE + 13)
 
+/**
+ * VFIO_DEVICE_GET_FD - _IO(VFIO_TYPE, VFIO_BASE + 14, __u32)
+ *
+ * Create a fd for a vfio device based on the input type
+ * Vendor driver should handle this ioctl to create a fd and manage the
+ * life cycle of this fd.
+ *
+ * Return: a fd if vendor support that type, -errno if not supported
+ */
+
+#define VFIO_DEVICE_GET_FD _IO(VFIO_TYPE, VFIO_BASE + 14)
+
+#define VFIO_DEVICE_DMABUF_MGR_FD  0 /* Supported fd types */
+
+struct vfio_dmabuf_mgr_plane_info {
+   __u64 start;
+   __u64 drm_format_mod;
+   __u32 drm_format;
+   __u32 width;
+   __u32 height;
+   __u32 stride;
+   __u32 size;
+   __u32 x_pos;
+   __u32 y_pos;
+   __u32 padding;
+};
+
+/*
+ * VFIO_DMABUF_MGR_QUERY_PLANE - _IO(VFIO_TYPE, VFIO_BASE + 15,
+ * struct vfio_dmabuf_mgr_query_plane)
+ * Query plane information
+ */
+struct vfio_dmabuf_mgr_query_plane {
+   __u32 argsz;
+   __u32 flags;
+   struct vfio_dmabuf_mgr_plane_info plane_info;
+   __u32 plane_id;
+};
+
+#define VFIO_DMABUF_MGR_QUERY_PLANE _IO(VFIO_TYPE, VFIO_BASE + 15)
+
+/*
+ * VFIO_DMABUF_MGR_CREATE_DMABUF - _IO(VFIO, VFIO_BASE + 16,
+ * struct vfio_dmabuf_mgr_create_dmabuf)
+ *
+ * Create a dma-buf for a plane
+ */
+struct vfio_dmabuf_mgr_create_dmabuf {
+   __u32 argsz;
+   __u32 flags;
+   struct vfio_dmabuf_mgr_plane_info plane_info;
+   __u32 plane_id;
+   __s32 fd;
+};
+
+#define VFIO_DMABUF_MGR_CREATE_DMABUF _IO(VFIO_TYPE, VFIO_BASE + 16)
+
 /*  API for Type1 VFIO IOMMU  */
 
 /**
-- 
2.7.4



[PATCH v9 3/7] drm: Extend the drm format

2017-06-15 Thread Xiaoguang Chen
Add new drm format which will be used by GVT-g.

Signed-off-by: Xiaoguang Chen <xiaoguang.c...@intel.com>
---
 include/uapi/drm/drm_fourcc.h | 4 
 1 file changed, 4 insertions(+)

diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h
index 55e3010..2681862 100644
--- a/include/uapi/drm/drm_fourcc.h
+++ b/include/uapi/drm/drm_fourcc.h
@@ -113,6 +113,10 @@ extern "C" {
 
 #define DRM_FORMAT_AYUVfourcc_code('A', 'Y', 'U', 'V') /* 
[31:0] A:Y:Cb:Cr 8:8:8:8 little endian */
 
+/* 64 bpp RGB */
+#define DRM_FORMAT_XRGB161616  fourcc_code('X', 'R', '4', '8') /* [63:0] 
x:R:G:B 16:16:16:16 little endian */
+#define DRM_FORMAT_XBGR161616  fourcc_code('X', 'B', '4', '8') /* [63:0] 
x:B:G:R 16:16:16:16 little endian */
+
 /*
  * 2 plane RGB + A
  * index 0 = RGB plane, same format as the corresponding non _A8 format has
-- 
2.7.4



[PATCH v9 3/7] drm: Extend the drm format

2017-06-15 Thread Xiaoguang Chen
Add new drm format which will be used by GVT-g.

Signed-off-by: Xiaoguang Chen 
---
 include/uapi/drm/drm_fourcc.h | 4 
 1 file changed, 4 insertions(+)

diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h
index 55e3010..2681862 100644
--- a/include/uapi/drm/drm_fourcc.h
+++ b/include/uapi/drm/drm_fourcc.h
@@ -113,6 +113,10 @@ extern "C" {
 
 #define DRM_FORMAT_AYUVfourcc_code('A', 'Y', 'U', 'V') /* 
[31:0] A:Y:Cb:Cr 8:8:8:8 little endian */
 
+/* 64 bpp RGB */
+#define DRM_FORMAT_XRGB161616  fourcc_code('X', 'R', '4', '8') /* [63:0] 
x:R:G:B 16:16:16:16 little endian */
+#define DRM_FORMAT_XBGR161616  fourcc_code('X', 'B', '4', '8') /* [63:0] 
x:B:G:R 16:16:16:16 little endian */
+
 /*
  * 2 plane RGB + A
  * index 0 = RGB plane, same format as the corresponding non _A8 format has
-- 
2.7.4



[PATCH v9 7/7] drm/i915/gvt: Adding user interface for dma-buf

2017-06-15 Thread Xiaoguang Chen
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.c...@intel.com>
Tested-by: Kechen Lu <kechen...@intel.com>
---
 drivers/gpu/drm/i915/gvt/dmabuf.c|  45 +++-
 drivers/gpu/drm/i915/gvt/dmabuf.h|   5 ++
 drivers/gpu/drm/i915/gvt/gvt.c   |   3 +
 drivers/gpu/drm/i915/gvt/gvt.h   |   6 ++
 drivers/gpu/drm/i915/gvt/hypercall.h |   3 +
 drivers/gpu/drm/i915/gvt/kvmgt.c | 136 +++
 drivers/gpu/drm/i915/gvt/mpt.h   |  30 
 drivers/gpu/drm/i915/gvt/vgpu.c  |   2 +
 8 files changed, 229 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/gvt/dmabuf.c 
b/drivers/gpu/drm/i915/gvt/dmabuf.c
index 6ef4f60..a6a6f6d 100644
--- a/drivers/gpu/drm/i915/gvt/dmabuf.c
+++ b/drivers/gpu/drm/i915/gvt/dmabuf.c
@@ -81,6 +81,31 @@ static void intel_vgpu_gem_put_pages(struct 
drm_i915_gem_object *obj,
 
 static void intel_vgpu_gem_release(struct drm_i915_gem_object *obj)
 {
+   struct intel_vgpu_dmabuf_obj *dmabuf_obj;
+   struct intel_vgpu_fb_info *fb_info;
+   struct intel_vgpu *vgpu;
+   struct list_head *pos;
+
+   fb_info = (struct intel_vgpu_fb_info *)obj->gvt_info;
+   if (WARN_ON(!fb_info || !fb_info->vgpu)) {
+   gvt_vgpu_err("gvt info is invalid\n");
+   goto out;
+   }
+
+   vgpu = fb_info->vgpu;
+   mutex_lock(>dmabuf_list_lock);
+   list_for_each(pos, >dmabuf_obj_list_head) {
+   dmabuf_obj = container_of(pos, struct intel_vgpu_dmabuf_obj,
+   list);
+   if ((dmabuf_obj != NULL) && (dmabuf_obj->obj == obj)) {
+   kfree(dmabuf_obj);
+   list_del(pos);
+   break;
+   }
+   }
+   mutex_unlock(>dmabuf_list_lock);
+   intel_gvt_hypervisor_put_vfio_device(vgpu);
+out:
kfree(obj->gvt_info);
 }
 
@@ -216,6 +241,7 @@ int intel_vgpu_create_dmabuf(struct intel_vgpu *vgpu, void 
*args)
struct vfio_dmabuf_mgr_create_dmabuf *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, _dmabuf->plane_info,
gvt_dmabuf->plane_id);
@@ -238,6 +264,18 @@ int intel_vgpu_create_dmabuf(struct intel_vgpu *vgpu, void 
*args)
fb_info->vgpu = vgpu;
obj->gvt_info = fb_info;
 
+   dmabuf_obj = kmalloc(sizeof(*dmabuf_obj), GFP_KERNEL);
+   if (!dmabuf_obj) {
+   gvt_vgpu_err("alloc dmabuf_obj failed\n");
+   ret = -ENOMEM;
+   goto out_free_info;
+   }
+   dmabuf_obj->obj = obj;
+   INIT_LIST_HEAD(_obj->list);
+   mutex_lock(>dmabuf_list_lock);
+   list_add_tail(_obj->list, >dmabuf_obj_list_head);
+   mutex_unlock(>dmabuf_list_lock);
+
dmabuf = i915_gem_prime_export(dev, >base, DRM_CLOEXEC | DRM_RDWR);
 
if (IS_ERR(dmabuf)) {
@@ -251,11 +289,16 @@ int intel_vgpu_create_dmabuf(struct intel_vgpu *vgpu, 
void *args)
gvt_vgpu_err("create dma-buf fd failed ret:%d\n", ret);
goto out_free;
}
-
+   if (intel_gvt_hypervisor_get_vfio_device(vgpu)) {
+   gvt_vgpu_err("get vfio device failed\n");
+   goto out_free;
+   }
gvt_dmabuf->fd = ret;
 
return 0;
 out_free:
+   kfree(dmabuf_obj);
+out_free_info:
kfree(fb_info);
 out:
i915_gem_object_put(obj);
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..d589830 100644
--- a/drivers/gpu/drm/i915/gvt/gvt.c
+++ b/drivers/gpu/drm/i915/gvt/gvt.c
@@ -54,6 +54,9 @@ 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..df7e216 100644
--- a/drivers/gpu/drm/i915

[PATCH v9 7/7] drm/i915/gvt: Adding user interface for dma-buf

2017-06-15 Thread Xiaoguang Chen
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 
Tested-by: Kechen Lu 
---
 drivers/gpu/drm/i915/gvt/dmabuf.c|  45 +++-
 drivers/gpu/drm/i915/gvt/dmabuf.h|   5 ++
 drivers/gpu/drm/i915/gvt/gvt.c   |   3 +
 drivers/gpu/drm/i915/gvt/gvt.h   |   6 ++
 drivers/gpu/drm/i915/gvt/hypercall.h |   3 +
 drivers/gpu/drm/i915/gvt/kvmgt.c | 136 +++
 drivers/gpu/drm/i915/gvt/mpt.h   |  30 
 drivers/gpu/drm/i915/gvt/vgpu.c  |   2 +
 8 files changed, 229 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/gvt/dmabuf.c 
b/drivers/gpu/drm/i915/gvt/dmabuf.c
index 6ef4f60..a6a6f6d 100644
--- a/drivers/gpu/drm/i915/gvt/dmabuf.c
+++ b/drivers/gpu/drm/i915/gvt/dmabuf.c
@@ -81,6 +81,31 @@ static void intel_vgpu_gem_put_pages(struct 
drm_i915_gem_object *obj,
 
 static void intel_vgpu_gem_release(struct drm_i915_gem_object *obj)
 {
+   struct intel_vgpu_dmabuf_obj *dmabuf_obj;
+   struct intel_vgpu_fb_info *fb_info;
+   struct intel_vgpu *vgpu;
+   struct list_head *pos;
+
+   fb_info = (struct intel_vgpu_fb_info *)obj->gvt_info;
+   if (WARN_ON(!fb_info || !fb_info->vgpu)) {
+   gvt_vgpu_err("gvt info is invalid\n");
+   goto out;
+   }
+
+   vgpu = fb_info->vgpu;
+   mutex_lock(>dmabuf_list_lock);
+   list_for_each(pos, >dmabuf_obj_list_head) {
+   dmabuf_obj = container_of(pos, struct intel_vgpu_dmabuf_obj,
+   list);
+   if ((dmabuf_obj != NULL) && (dmabuf_obj->obj == obj)) {
+   kfree(dmabuf_obj);
+   list_del(pos);
+   break;
+   }
+   }
+   mutex_unlock(>dmabuf_list_lock);
+   intel_gvt_hypervisor_put_vfio_device(vgpu);
+out:
kfree(obj->gvt_info);
 }
 
@@ -216,6 +241,7 @@ int intel_vgpu_create_dmabuf(struct intel_vgpu *vgpu, void 
*args)
struct vfio_dmabuf_mgr_create_dmabuf *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, _dmabuf->plane_info,
gvt_dmabuf->plane_id);
@@ -238,6 +264,18 @@ int intel_vgpu_create_dmabuf(struct intel_vgpu *vgpu, void 
*args)
fb_info->vgpu = vgpu;
obj->gvt_info = fb_info;
 
+   dmabuf_obj = kmalloc(sizeof(*dmabuf_obj), GFP_KERNEL);
+   if (!dmabuf_obj) {
+   gvt_vgpu_err("alloc dmabuf_obj failed\n");
+   ret = -ENOMEM;
+   goto out_free_info;
+   }
+   dmabuf_obj->obj = obj;
+   INIT_LIST_HEAD(_obj->list);
+   mutex_lock(>dmabuf_list_lock);
+   list_add_tail(_obj->list, >dmabuf_obj_list_head);
+   mutex_unlock(>dmabuf_list_lock);
+
dmabuf = i915_gem_prime_export(dev, >base, DRM_CLOEXEC | DRM_RDWR);
 
if (IS_ERR(dmabuf)) {
@@ -251,11 +289,16 @@ int intel_vgpu_create_dmabuf(struct intel_vgpu *vgpu, 
void *args)
gvt_vgpu_err("create dma-buf fd failed ret:%d\n", ret);
goto out_free;
}
-
+   if (intel_gvt_hypervisor_get_vfio_device(vgpu)) {
+   gvt_vgpu_err("get vfio device failed\n");
+   goto out_free;
+   }
gvt_dmabuf->fd = ret;
 
return 0;
 out_free:
+   kfree(dmabuf_obj);
+out_free_info:
kfree(fb_info);
 out:
i915_gem_object_put(obj);
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..d589830 100644
--- a/drivers/gpu/drm/i915/gvt/gvt.c
+++ b/drivers/gpu/drm/i915/gvt/gvt.c
@@ -54,6 +54,9 @@ 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..df7e216 100644
--- a/drivers/gpu/drm/i915/gvt/gvt.h
+++ b/drivers/gpu/drm/i915/gvt/gvt.h
@@ -185,8 +18

[PATCH v9 6/7] drm/i915/gvt: Dmabuf support for GVT-g

2017-06-15 Thread Xiaoguang Chen
dmabuf for GVT-g can be exported to users who can use the dmabuf to show
the desktop of vm which use intel vgpu.

Currently we provide query and create new dmabuf operations.

Users of dmabuf can cache some created dmabufs and related information
such as the framebuffer's address, size, tiling mode, width, height etc.
When refresh the screen first query the currnet vgpu's frambuffer and
compare with the cached ones(address, size, tiling, width, height etc)
if found one then reuse the found dmabuf to gain performance improvment.

If there is no dmabuf created yet or not found in the cached dmabufs then
need to create a new dmabuf. To create a dmabuf first a gem object will
be created and the backing storage of this gem object is the vgpu's
framebuffer(primary/cursor).
Set caching mode, change tiling mode and set domains of this gem object
is not supported.
Then associate this gem object to a dmabuf and export this dmabuf.
A file descriptor will be generated for this dmabuf and this file
descriptor can be sent to user space to do display.

Signed-off-by: Xiaoguang Chen <xiaoguang.c...@intel.com>
Tested-by: Kechen Lu <kechen...@intel.com>
---
 drivers/gpu/drm/i915/gvt/Makefile  |   2 +-
 drivers/gpu/drm/i915/gvt/dmabuf.c  | 264 +
 drivers/gpu/drm/i915/gvt/dmabuf.h  |  37 +
 drivers/gpu/drm/i915/gvt/gvt.h |   1 +
 drivers/gpu/drm/i915/i915_gem.c|  26 +++-
 drivers/gpu/drm/i915/i915_gem_object.h |   9 ++
 drivers/gpu/drm/i915/i915_gem_tiling.c |   5 +
 7 files changed, 342 insertions(+), 2 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/gvt/dmabuf.c
 create mode 100644 drivers/gpu/drm/i915/gvt/dmabuf.h

diff --git a/drivers/gpu/drm/i915/gvt/Makefile 
b/drivers/gpu/drm/i915/gvt/Makefile
index 192ca26..e480f7d 100644
--- a/drivers/gpu/drm/i915/gvt/Makefile
+++ b/drivers/gpu/drm/i915/gvt/Makefile
@@ -2,7 +2,7 @@ GVT_DIR := gvt
 GVT_SOURCE := gvt.o aperture_gm.o handlers.o vgpu.o trace_points.o firmware.o \
interrupt.o gtt.o cfg_space.o opregion.o mmio.o display.o edid.o \
execlist.o scheduler.o sched_policy.o render.o cmd_parser.o \
-   fb_decoder.o
+   fb_decoder.o dmabuf.o
 
 ccflags-y  += -I$(src) -I$(src)/$(GVT_DIR) -Wall
 i915-y += $(addprefix $(GVT_DIR)/, 
$(GVT_SOURCE))
diff --git a/drivers/gpu/drm/i915/gvt/dmabuf.c 
b/drivers/gpu/drm/i915/gvt/dmabuf.c
new file mode 100644
index 000..6ef4f60
--- /dev/null
+++ b/drivers/gpu/drm/i915/gvt/dmabuf.c
@@ -0,0 +1,264 @@
+/*
+ * Copyright 2017 Intel Corporation. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *Zhiyuan Lv <zhiyuan...@intel.com>
+ *
+ * Contributors:
+ *Xiaoguang Chen <xiaoguang.c...@intel.com>
+ */
+
+#include 
+#include 
+#include 
+
+#include "i915_drv.h"
+#include "gvt.h"
+
+#define GEN8_DECODE_PTE(pte) (pte & GENMASK_ULL(63, 12))
+
+static struct sg_table *intel_vgpu_gem_get_pages(
+   struct drm_i915_gem_object *obj)
+{
+   struct drm_i915_private *dev_priv = to_i915(obj->base.dev);
+   struct sg_table *st;
+   struct scatterlist *sg;
+   int i, ret;
+   gen8_pte_t __iomem *gtt_entries;
+   struct intel_vgpu_fb_info *fb_info;
+
+   fb_info = (struct intel_vgpu_fb_info *)obj->gvt_info;
+   if (WARN_ON(!fb_info))
+   return ERR_PTR(-ENODEV);
+
+   st = kmalloc(sizeof(*st), GFP_KERNEL);
+   if (!st)
+   return ERR_PTR(-ENOMEM);
+
+   ret = sg_alloc_table(st, fb_info->fb_size, GFP_KERNEL);
+   if (ret) {
+   kfree(st);
+   return ERR_PTR(ret);
+   }
+   gtt_entries = (gen8_pte_t __iomem *)dev_priv->ggtt.gsm +
+   (fb_info->fb_addr >> PAGE_SHIFT);
+   for_each_sg(st-&g

[PATCH v9 6/7] drm/i915/gvt: Dmabuf support for GVT-g

2017-06-15 Thread Xiaoguang Chen
dmabuf for GVT-g can be exported to users who can use the dmabuf to show
the desktop of vm which use intel vgpu.

Currently we provide query and create new dmabuf operations.

Users of dmabuf can cache some created dmabufs and related information
such as the framebuffer's address, size, tiling mode, width, height etc.
When refresh the screen first query the currnet vgpu's frambuffer and
compare with the cached ones(address, size, tiling, width, height etc)
if found one then reuse the found dmabuf to gain performance improvment.

If there is no dmabuf created yet or not found in the cached dmabufs then
need to create a new dmabuf. To create a dmabuf first a gem object will
be created and the backing storage of this gem object is the vgpu's
framebuffer(primary/cursor).
Set caching mode, change tiling mode and set domains of this gem object
is not supported.
Then associate this gem object to a dmabuf and export this dmabuf.
A file descriptor will be generated for this dmabuf and this file
descriptor can be sent to user space to do display.

Signed-off-by: Xiaoguang Chen 
Tested-by: Kechen Lu 
---
 drivers/gpu/drm/i915/gvt/Makefile  |   2 +-
 drivers/gpu/drm/i915/gvt/dmabuf.c  | 264 +
 drivers/gpu/drm/i915/gvt/dmabuf.h  |  37 +
 drivers/gpu/drm/i915/gvt/gvt.h |   1 +
 drivers/gpu/drm/i915/i915_gem.c|  26 +++-
 drivers/gpu/drm/i915/i915_gem_object.h |   9 ++
 drivers/gpu/drm/i915/i915_gem_tiling.c |   5 +
 7 files changed, 342 insertions(+), 2 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/gvt/dmabuf.c
 create mode 100644 drivers/gpu/drm/i915/gvt/dmabuf.h

diff --git a/drivers/gpu/drm/i915/gvt/Makefile 
b/drivers/gpu/drm/i915/gvt/Makefile
index 192ca26..e480f7d 100644
--- a/drivers/gpu/drm/i915/gvt/Makefile
+++ b/drivers/gpu/drm/i915/gvt/Makefile
@@ -2,7 +2,7 @@ GVT_DIR := gvt
 GVT_SOURCE := gvt.o aperture_gm.o handlers.o vgpu.o trace_points.o firmware.o \
interrupt.o gtt.o cfg_space.o opregion.o mmio.o display.o edid.o \
execlist.o scheduler.o sched_policy.o render.o cmd_parser.o \
-   fb_decoder.o
+   fb_decoder.o dmabuf.o
 
 ccflags-y  += -I$(src) -I$(src)/$(GVT_DIR) -Wall
 i915-y += $(addprefix $(GVT_DIR)/, 
$(GVT_SOURCE))
diff --git a/drivers/gpu/drm/i915/gvt/dmabuf.c 
b/drivers/gpu/drm/i915/gvt/dmabuf.c
new file mode 100644
index 000..6ef4f60
--- /dev/null
+++ b/drivers/gpu/drm/i915/gvt/dmabuf.c
@@ -0,0 +1,264 @@
+/*
+ * Copyright 2017 Intel Corporation. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *Zhiyuan Lv 
+ *
+ * Contributors:
+ *Xiaoguang Chen 
+ */
+
+#include 
+#include 
+#include 
+
+#include "i915_drv.h"
+#include "gvt.h"
+
+#define GEN8_DECODE_PTE(pte) (pte & GENMASK_ULL(63, 12))
+
+static struct sg_table *intel_vgpu_gem_get_pages(
+   struct drm_i915_gem_object *obj)
+{
+   struct drm_i915_private *dev_priv = to_i915(obj->base.dev);
+   struct sg_table *st;
+   struct scatterlist *sg;
+   int i, ret;
+   gen8_pte_t __iomem *gtt_entries;
+   struct intel_vgpu_fb_info *fb_info;
+
+   fb_info = (struct intel_vgpu_fb_info *)obj->gvt_info;
+   if (WARN_ON(!fb_info))
+   return ERR_PTR(-ENODEV);
+
+   st = kmalloc(sizeof(*st), GFP_KERNEL);
+   if (!st)
+   return ERR_PTR(-ENOMEM);
+
+   ret = sg_alloc_table(st, fb_info->fb_size, GFP_KERNEL);
+   if (ret) {
+   kfree(st);
+   return ERR_PTR(ret);
+   }
+   gtt_entries = (gen8_pte_t __iomem *)dev_priv->ggtt.gsm +
+   (fb_info->fb_addr >> PAGE_SHIFT);
+   for_each_sg(st->sgl, sg, fb_info->fb_size, i) {
+   sg->offset = 0;
+   sg->length = PAGE_SIZE;
+

[PATCH v9 2/7] drm/i915/gvt: OpRegion support for GVT-g

2017-06-15 Thread Xiaoguang Chen
OpRegion is needed to support display related operation for
intel vgpu.

A vfio device region is added to intel vgpu to deliver the
host OpRegion information to user space so user space can
construct the OpRegion for vgpu.

Signed-off-by: Bing Niu <bing@intel.com>
Signed-off-by: Xiaoguang Chen <xiaoguang.c...@intel.com>
---
 drivers/gpu/drm/i915/gvt/hypercall.h |  1 +
 drivers/gpu/drm/i915/gvt/kvmgt.c | 88 
 drivers/gpu/drm/i915/gvt/mpt.h   | 15 ++
 drivers/gpu/drm/i915/gvt/opregion.c  | 26 ---
 drivers/gpu/drm/i915/gvt/vgpu.c  |  4 ++
 5 files changed, 128 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/gvt/hypercall.h 
b/drivers/gpu/drm/i915/gvt/hypercall.h
index df7f33a..32c345c 100644
--- a/drivers/gpu/drm/i915/gvt/hypercall.h
+++ b/drivers/gpu/drm/i915/gvt/hypercall.h
@@ -55,6 +55,7 @@ struct intel_gvt_mpt {
  unsigned long mfn, unsigned int nr, bool map);
int (*set_trap_area)(unsigned long handle, u64 start, u64 end,
 bool map);
+   int (*set_opregion)(void *vgpu);
 };
 
 extern struct intel_gvt_mpt xengt_mpt;
diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
index 3c6a02b..6b4652a 100644
--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
+++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
@@ -53,6 +53,8 @@ static const struct intel_gvt_ops *intel_gvt_ops;
 #define VFIO_PCI_INDEX_TO_OFFSET(index) ((u64)(index) << VFIO_PCI_OFFSET_SHIFT)
 #define VFIO_PCI_OFFSET_MASK(((u64)(1) << VFIO_PCI_OFFSET_SHIFT) - 1)
 
+#define OPREGION_SIGNATURE "IntelGraphicsMem"
+
 struct vfio_region;
 struct intel_vgpu_regops {
size_t (*rw)(struct intel_vgpu *vgpu, char *buf,
@@ -436,6 +438,91 @@ static void kvmgt_protect_table_del(struct 
kvmgt_guest_info *info,
}
 }
 
+static size_t intel_vgpu_reg_rw_opregion(struct intel_vgpu *vgpu, char *buf,
+   size_t count, loff_t *ppos, bool iswrite)
+{
+   unsigned int i = VFIO_PCI_OFFSET_TO_INDEX(*ppos) -
+   VFIO_PCI_NUM_REGIONS;
+   void *base = vgpu->vdev.region[i].data;
+   loff_t pos = *ppos & VFIO_PCI_OFFSET_MASK;
+
+   if (pos >= vgpu->vdev.region[i].size || iswrite) {
+   gvt_vgpu_err("invalid op or offset for Intel vgpu OpRegion\n");
+   return -EINVAL;
+   }
+   count = min(count, (size_t)(vgpu->vdev.region[i].size - pos));
+   memcpy(buf, base + pos, count);
+
+   return count;
+}
+
+static void intel_vgpu_reg_release_opregion(struct intel_vgpu *vgpu,
+   struct vfio_region *region)
+{
+   memunmap(region->data);
+}
+
+static const struct intel_vgpu_regops intel_vgpu_regops_opregion = {
+   .rw = intel_vgpu_reg_rw_opregion,
+   .release = intel_vgpu_reg_release_opregion,
+};
+
+static int intel_vgpu_register_reg(struct intel_vgpu *vgpu,
+   unsigned int type, unsigned int subtype,
+   const struct intel_vgpu_regops *ops,
+   size_t size, u32 flags, void *data)
+{
+   struct vfio_region *region;
+
+   region = krealloc(vgpu->vdev.region,
+   (vgpu->vdev.num_regions + 1) * sizeof(*region),
+   GFP_KERNEL);
+   if (!region)
+   return -ENOMEM;
+
+   vgpu->vdev.region = region;
+   vgpu->vdev.region[vgpu->vdev.num_regions].type = type;
+   vgpu->vdev.region[vgpu->vdev.num_regions].subtype = subtype;
+   vgpu->vdev.region[vgpu->vdev.num_regions].ops = ops;
+   vgpu->vdev.region[vgpu->vdev.num_regions].size = size;
+   vgpu->vdev.region[vgpu->vdev.num_regions].flags = flags;
+   vgpu->vdev.region[vgpu->vdev.num_regions].data = data;
+   vgpu->vdev.num_regions++;
+
+   return 0;
+}
+
+static int kvmgt_set_opregion(void *p_vgpu)
+{
+   struct intel_vgpu *vgpu = (struct intel_vgpu *)p_vgpu;
+   unsigned int addr;
+   void *base;
+   int ret;
+
+   addr = vgpu->gvt->opregion.opregion_pa;
+   if (!addr || !(~addr))
+   return -ENODEV;
+
+   base = memremap(addr, OPREGION_SIZE, MEMREMAP_WB);
+   if (!base)
+   return -ENOMEM;
+
+   if (memcmp(base, OPREGION_SIGNATURE, 16)) {
+   memunmap(base);
+   return -EINVAL;
+   }
+
+   ret = intel_vgpu_register_reg(vgpu,
+   PCI_VENDOR_ID_INTEL | VFIO_REGION_TYPE_PCI_VENDOR_TYPE,
+   VFIO_REGION_SUBTYPE_INTEL_IGD_OPREGION,
+   _vgpu_regops_opregion, OPREGION_SIZE,
+   VFIO_REGION_INFO_FLAG_READ, base);
+   if (ret)
+   memunmap(base);
+
+   return ret;
+}
+
 static int intel_vgpu_create(struct kobject *kobj, struct mdev_device *mdev)
 {
struct intel_vgpu *vgpu = NULL;
@@ -1524,6 +1611,7 @@ struct inte

[PATCH v9 2/7] drm/i915/gvt: OpRegion support for GVT-g

2017-06-15 Thread Xiaoguang Chen
OpRegion is needed to support display related operation for
intel vgpu.

A vfio device region is added to intel vgpu to deliver the
host OpRegion information to user space so user space can
construct the OpRegion for vgpu.

Signed-off-by: Bing Niu 
Signed-off-by: Xiaoguang Chen 
---
 drivers/gpu/drm/i915/gvt/hypercall.h |  1 +
 drivers/gpu/drm/i915/gvt/kvmgt.c | 88 
 drivers/gpu/drm/i915/gvt/mpt.h   | 15 ++
 drivers/gpu/drm/i915/gvt/opregion.c  | 26 ---
 drivers/gpu/drm/i915/gvt/vgpu.c  |  4 ++
 5 files changed, 128 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/gvt/hypercall.h 
b/drivers/gpu/drm/i915/gvt/hypercall.h
index df7f33a..32c345c 100644
--- a/drivers/gpu/drm/i915/gvt/hypercall.h
+++ b/drivers/gpu/drm/i915/gvt/hypercall.h
@@ -55,6 +55,7 @@ struct intel_gvt_mpt {
  unsigned long mfn, unsigned int nr, bool map);
int (*set_trap_area)(unsigned long handle, u64 start, u64 end,
 bool map);
+   int (*set_opregion)(void *vgpu);
 };
 
 extern struct intel_gvt_mpt xengt_mpt;
diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
index 3c6a02b..6b4652a 100644
--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
+++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
@@ -53,6 +53,8 @@ static const struct intel_gvt_ops *intel_gvt_ops;
 #define VFIO_PCI_INDEX_TO_OFFSET(index) ((u64)(index) << VFIO_PCI_OFFSET_SHIFT)
 #define VFIO_PCI_OFFSET_MASK(((u64)(1) << VFIO_PCI_OFFSET_SHIFT) - 1)
 
+#define OPREGION_SIGNATURE "IntelGraphicsMem"
+
 struct vfio_region;
 struct intel_vgpu_regops {
size_t (*rw)(struct intel_vgpu *vgpu, char *buf,
@@ -436,6 +438,91 @@ static void kvmgt_protect_table_del(struct 
kvmgt_guest_info *info,
}
 }
 
+static size_t intel_vgpu_reg_rw_opregion(struct intel_vgpu *vgpu, char *buf,
+   size_t count, loff_t *ppos, bool iswrite)
+{
+   unsigned int i = VFIO_PCI_OFFSET_TO_INDEX(*ppos) -
+   VFIO_PCI_NUM_REGIONS;
+   void *base = vgpu->vdev.region[i].data;
+   loff_t pos = *ppos & VFIO_PCI_OFFSET_MASK;
+
+   if (pos >= vgpu->vdev.region[i].size || iswrite) {
+   gvt_vgpu_err("invalid op or offset for Intel vgpu OpRegion\n");
+   return -EINVAL;
+   }
+   count = min(count, (size_t)(vgpu->vdev.region[i].size - pos));
+   memcpy(buf, base + pos, count);
+
+   return count;
+}
+
+static void intel_vgpu_reg_release_opregion(struct intel_vgpu *vgpu,
+   struct vfio_region *region)
+{
+   memunmap(region->data);
+}
+
+static const struct intel_vgpu_regops intel_vgpu_regops_opregion = {
+   .rw = intel_vgpu_reg_rw_opregion,
+   .release = intel_vgpu_reg_release_opregion,
+};
+
+static int intel_vgpu_register_reg(struct intel_vgpu *vgpu,
+   unsigned int type, unsigned int subtype,
+   const struct intel_vgpu_regops *ops,
+   size_t size, u32 flags, void *data)
+{
+   struct vfio_region *region;
+
+   region = krealloc(vgpu->vdev.region,
+   (vgpu->vdev.num_regions + 1) * sizeof(*region),
+   GFP_KERNEL);
+   if (!region)
+   return -ENOMEM;
+
+   vgpu->vdev.region = region;
+   vgpu->vdev.region[vgpu->vdev.num_regions].type = type;
+   vgpu->vdev.region[vgpu->vdev.num_regions].subtype = subtype;
+   vgpu->vdev.region[vgpu->vdev.num_regions].ops = ops;
+   vgpu->vdev.region[vgpu->vdev.num_regions].size = size;
+   vgpu->vdev.region[vgpu->vdev.num_regions].flags = flags;
+   vgpu->vdev.region[vgpu->vdev.num_regions].data = data;
+   vgpu->vdev.num_regions++;
+
+   return 0;
+}
+
+static int kvmgt_set_opregion(void *p_vgpu)
+{
+   struct intel_vgpu *vgpu = (struct intel_vgpu *)p_vgpu;
+   unsigned int addr;
+   void *base;
+   int ret;
+
+   addr = vgpu->gvt->opregion.opregion_pa;
+   if (!addr || !(~addr))
+   return -ENODEV;
+
+   base = memremap(addr, OPREGION_SIZE, MEMREMAP_WB);
+   if (!base)
+   return -ENOMEM;
+
+   if (memcmp(base, OPREGION_SIGNATURE, 16)) {
+   memunmap(base);
+   return -EINVAL;
+   }
+
+   ret = intel_vgpu_register_reg(vgpu,
+   PCI_VENDOR_ID_INTEL | VFIO_REGION_TYPE_PCI_VENDOR_TYPE,
+   VFIO_REGION_SUBTYPE_INTEL_IGD_OPREGION,
+   _vgpu_regops_opregion, OPREGION_SIZE,
+   VFIO_REGION_INFO_FLAG_READ, base);
+   if (ret)
+   memunmap(base);
+
+   return ret;
+}
+
 static int intel_vgpu_create(struct kobject *kobj, struct mdev_device *mdev)
 {
struct intel_vgpu *vgpu = NULL;
@@ -1524,6 +1611,7 @@ struct intel_gvt_mpt kvmgt_mpt = {
.read_gpa = kvmgt_read

[PATCH v9 0/7] drm/i915/gvt: Dma-buf support for GVT-g

2017-06-15 Thread Xiaoguang Chen
v8->v9:
1) refine the dma-buf ioctl definition
2) add a lock to protect the dmabuf list
3) move drm format change to a separate patch
4) codes cleanup

v7->v8:
1) refine framebuffer decoder code
2) fix a bug in decoding primary plane

v6->v7:
1) release dma-buf related allocations in dma-buf's associated release
function.
2) refine ioctl interface for querying plane info or create dma-buf
3) refine framebuffer decoder code
4) the patch series is based on 4.12.0-rc1

v5->v6:
1) align the dma-buf life cycle with the vfio device.
2) add the dma-buf releated operations in a separate patch.
3) i915 releated changes.

v4->v5:
1) fix bug while checking whether the gem obj is gvt's dma-buf when user
change caching mode or domains. Add a helper function to do it.
2) add definition for the query plane and create dma-buf.

v3->v4:
1) fix bug while checking whether the gem obj is gvt's dma-buf when set
caching mode or doamins.

v2->v3:
1) add a field gvt_plane_info in the drm_i915_gem_obj structure to save
the decoded plane information to avoid look up while need the plane info.
2) declare a new flag I915_GEM_OBJECT_IS_GVT_DMABUF in drm_i915_gem_object
to represent the gem obj for gvt's dma-buf. The tiling mode, caching mode
and domains can not be changed for this kind of gem object.
3) change dma-buf related information to be more generic. So other vendor
can use the same interface.

v1->v2:
1) create a management fd for dma-buf operations.
2) alloc gem object's backing storage in gem obj's get_pages() callback.

This patch set adds the dma-buf support for intel GVT-g.
dma-buf is a uniform mechanism to share DMA buffers across different
devices and sub-systems.
dma-buf for intel GVT-g is mainly used to share the vgpu's framebuffer
to other users or sub-systems so they can use the dma-buf to show the
desktop of a vm which uses intel vgpu.

The main idea is we create a gem object and set vgpu's framebuffer as
the backing storage of this gem object. And associate this gem obj
to a dma-buf object then export this dma-buf at the meantime
generate a file descriptor for this dma-buf. Finally deliver this file
descriptor to user space. And user can use this dma-buf fd to do render
or other operations.
User need to create a fd(for intel GVT-g dma-buf support it is a:dma-buf
management fd) then user can use this fd to query the plane information
or create a dma-buf. The life cycle of this fd is managed by GVT-g user
do not need to care about that.

We have an example program on how to use the dma-buf. You can download
the program to have a try. Good luck :)
git repo: https://github.com/01org/igvtg-qemu branch:kvmgt_dmabuf_example

Xiaoguang Chen (7):
  drm/i915/gvt: Extend the GVT-g architecture
  drm/i915/gvt: OpRegion support for GVT-g
  drm: Extend the drm format
  drm/i915/gvt: Frame buffer decoder support for GVT-g
  vfio: Define vfio based dma-buf operations
  drm/i915/gvt: Dmabuf support for GVT-g
  drm/i915/gvt: Adding user interface for dma-buf

 drivers/gpu/drm/i915/gvt/Makefile  |   3 +-
 drivers/gpu/drm/i915/gvt/display.c |   2 +-
 drivers/gpu/drm/i915/gvt/display.h |   2 +
 drivers/gpu/drm/i915/gvt/dmabuf.c  | 307 
 drivers/gpu/drm/i915/gvt/dmabuf.h  |  42 
 drivers/gpu/drm/i915/gvt/fb_decoder.c  | 425 +
 drivers/gpu/drm/i915/gvt/fb_decoder.h  | 171 +
 drivers/gpu/drm/i915/gvt/gvt.c |   3 +
 drivers/gpu/drm/i915/gvt/gvt.h |   8 +
 drivers/gpu/drm/i915/gvt/hypercall.h   |   4 +
 drivers/gpu/drm/i915/gvt/kvmgt.c   | 245 ++-
 drivers/gpu/drm/i915/gvt/mpt.h |  45 
 drivers/gpu/drm/i915/gvt/opregion.c|  26 +-
 drivers/gpu/drm/i915/gvt/vgpu.c|   6 +
 drivers/gpu/drm/i915/i915_gem.c|  26 +-
 drivers/gpu/drm/i915/i915_gem_object.h |   9 +
 drivers/gpu/drm/i915/i915_gem_tiling.c |   5 +
 include/uapi/drm/drm_fourcc.h  |   4 +
 include/uapi/linux/vfio.h  |  57 +
 19 files changed, 1378 insertions(+), 12 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/gvt/dmabuf.c
 create mode 100644 drivers/gpu/drm/i915/gvt/dmabuf.h
 create mode 100644 drivers/gpu/drm/i915/gvt/fb_decoder.c
 create mode 100644 drivers/gpu/drm/i915/gvt/fb_decoder.h

-- 
2.7.4



[PATCH v9 0/7] drm/i915/gvt: Dma-buf support for GVT-g

2017-06-15 Thread Xiaoguang Chen
v8->v9:
1) refine the dma-buf ioctl definition
2) add a lock to protect the dmabuf list
3) move drm format change to a separate patch
4) codes cleanup

v7->v8:
1) refine framebuffer decoder code
2) fix a bug in decoding primary plane

v6->v7:
1) release dma-buf related allocations in dma-buf's associated release
function.
2) refine ioctl interface for querying plane info or create dma-buf
3) refine framebuffer decoder code
4) the patch series is based on 4.12.0-rc1

v5->v6:
1) align the dma-buf life cycle with the vfio device.
2) add the dma-buf releated operations in a separate patch.
3) i915 releated changes.

v4->v5:
1) fix bug while checking whether the gem obj is gvt's dma-buf when user
change caching mode or domains. Add a helper function to do it.
2) add definition for the query plane and create dma-buf.

v3->v4:
1) fix bug while checking whether the gem obj is gvt's dma-buf when set
caching mode or doamins.

v2->v3:
1) add a field gvt_plane_info in the drm_i915_gem_obj structure to save
the decoded plane information to avoid look up while need the plane info.
2) declare a new flag I915_GEM_OBJECT_IS_GVT_DMABUF in drm_i915_gem_object
to represent the gem obj for gvt's dma-buf. The tiling mode, caching mode
and domains can not be changed for this kind of gem object.
3) change dma-buf related information to be more generic. So other vendor
can use the same interface.

v1->v2:
1) create a management fd for dma-buf operations.
2) alloc gem object's backing storage in gem obj's get_pages() callback.

This patch set adds the dma-buf support for intel GVT-g.
dma-buf is a uniform mechanism to share DMA buffers across different
devices and sub-systems.
dma-buf for intel GVT-g is mainly used to share the vgpu's framebuffer
to other users or sub-systems so they can use the dma-buf to show the
desktop of a vm which uses intel vgpu.

The main idea is we create a gem object and set vgpu's framebuffer as
the backing storage of this gem object. And associate this gem obj
to a dma-buf object then export this dma-buf at the meantime
generate a file descriptor for this dma-buf. Finally deliver this file
descriptor to user space. And user can use this dma-buf fd to do render
or other operations.
User need to create a fd(for intel GVT-g dma-buf support it is a:dma-buf
management fd) then user can use this fd to query the plane information
or create a dma-buf. The life cycle of this fd is managed by GVT-g user
do not need to care about that.

We have an example program on how to use the dma-buf. You can download
the program to have a try. Good luck :)
git repo: https://github.com/01org/igvtg-qemu branch:kvmgt_dmabuf_example

Xiaoguang Chen (7):
  drm/i915/gvt: Extend the GVT-g architecture
  drm/i915/gvt: OpRegion support for GVT-g
  drm: Extend the drm format
  drm/i915/gvt: Frame buffer decoder support for GVT-g
  vfio: Define vfio based dma-buf operations
  drm/i915/gvt: Dmabuf support for GVT-g
  drm/i915/gvt: Adding user interface for dma-buf

 drivers/gpu/drm/i915/gvt/Makefile  |   3 +-
 drivers/gpu/drm/i915/gvt/display.c |   2 +-
 drivers/gpu/drm/i915/gvt/display.h |   2 +
 drivers/gpu/drm/i915/gvt/dmabuf.c  | 307 
 drivers/gpu/drm/i915/gvt/dmabuf.h  |  42 
 drivers/gpu/drm/i915/gvt/fb_decoder.c  | 425 +
 drivers/gpu/drm/i915/gvt/fb_decoder.h  | 171 +
 drivers/gpu/drm/i915/gvt/gvt.c |   3 +
 drivers/gpu/drm/i915/gvt/gvt.h |   8 +
 drivers/gpu/drm/i915/gvt/hypercall.h   |   4 +
 drivers/gpu/drm/i915/gvt/kvmgt.c   | 245 ++-
 drivers/gpu/drm/i915/gvt/mpt.h |  45 
 drivers/gpu/drm/i915/gvt/opregion.c|  26 +-
 drivers/gpu/drm/i915/gvt/vgpu.c|   6 +
 drivers/gpu/drm/i915/i915_gem.c|  26 +-
 drivers/gpu/drm/i915/i915_gem_object.h |   9 +
 drivers/gpu/drm/i915/i915_gem_tiling.c |   5 +
 include/uapi/drm/drm_fourcc.h  |   4 +
 include/uapi/linux/vfio.h  |  57 +
 19 files changed, 1378 insertions(+), 12 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/gvt/dmabuf.c
 create mode 100644 drivers/gpu/drm/i915/gvt/dmabuf.h
 create mode 100644 drivers/gpu/drm/i915/gvt/fb_decoder.c
 create mode 100644 drivers/gpu/drm/i915/gvt/fb_decoder.h

-- 
2.7.4



[PATCH v9 1/7] drm/i915/gvt: Extend the GVT-g architecture

2017-06-15 Thread Xiaoguang Chen
This patch extends the GVT-g architecture to support vfio device region.
Later we will add a vfio device region for the vgpu to support OpRegion.

Signed-off-by: Xiaoguang Chen <xiaoguang.c...@intel.com>
---
 drivers/gpu/drm/i915/gvt/kvmgt.c | 21 ++---
 1 file changed, 18 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
index 1ae0b40..3c6a02b 100644
--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
+++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
@@ -53,11 +53,21 @@ static const struct intel_gvt_ops *intel_gvt_ops;
 #define VFIO_PCI_INDEX_TO_OFFSET(index) ((u64)(index) << VFIO_PCI_OFFSET_SHIFT)
 #define VFIO_PCI_OFFSET_MASK(((u64)(1) << VFIO_PCI_OFFSET_SHIFT) - 1)
 
+struct vfio_region;
+struct intel_vgpu_regops {
+   size_t (*rw)(struct intel_vgpu *vgpu, char *buf,
+   size_t count, loff_t *ppos, bool iswrite);
+   void (*release)(struct intel_vgpu *vgpu,
+   struct vfio_region *region);
+};
+
 struct vfio_region {
u32 type;
u32 subtype;
size_t  size;
u32 flags;
+   const struct intel_vgpu_regops  *ops;
+   void*data;
 };
 
 struct kvmgt_pgfn {
@@ -642,7 +652,7 @@ static ssize_t intel_vgpu_rw(struct mdev_device *mdev, char 
*buf,
int ret = -EINVAL;
 
 
-   if (index >= VFIO_PCI_NUM_REGIONS) {
+   if (index >= VFIO_PCI_NUM_REGIONS + vgpu->vdev.num_regions) {
gvt_vgpu_err("invalid index: %u\n", index);
return -EINVAL;
}
@@ -676,8 +686,11 @@ static ssize_t intel_vgpu_rw(struct mdev_device *mdev, 
char *buf,
case VFIO_PCI_BAR5_REGION_INDEX:
case VFIO_PCI_VGA_REGION_INDEX:
case VFIO_PCI_ROM_REGION_INDEX:
+   break;
default:
-   gvt_vgpu_err("unsupported region: %u\n", index);
+   index -= VFIO_PCI_NUM_REGIONS;
+   return vgpu->vdev.region[index].ops->rw(vgpu, buf, count,
+   ppos, is_write);
}
 
return ret == 0 ? count : ret;
@@ -940,7 +953,8 @@ static long intel_vgpu_ioctl(struct mdev_device *mdev, 
unsigned int cmd,
 
info.flags = VFIO_DEVICE_FLAGS_PCI;
info.flags |= VFIO_DEVICE_FLAGS_RESET;
-   info.num_regions = VFIO_PCI_NUM_REGIONS;
+   info.num_regions = VFIO_PCI_NUM_REGIONS +
+   vgpu->vdev.num_regions;
info.num_irqs = VFIO_PCI_NUM_IRQS;
 
return copy_to_user((void __user *)arg, , minsz) ?
@@ -1061,6 +1075,7 @@ static long intel_vgpu_ioctl(struct mdev_device *mdev, 
unsigned int cmd,
}
 
if (caps.size) {
+   info.flags |= VFIO_REGION_INFO_FLAG_CAPS;
if (info.argsz < sizeof(info) + caps.size) {
info.argsz = sizeof(info) + caps.size;
info.cap_offset = 0;
-- 
2.7.4



[PATCH v9 1/7] drm/i915/gvt: Extend the GVT-g architecture

2017-06-15 Thread Xiaoguang Chen
This patch extends the GVT-g architecture to support vfio device region.
Later we will add a vfio device region for the vgpu to support OpRegion.

Signed-off-by: Xiaoguang Chen 
---
 drivers/gpu/drm/i915/gvt/kvmgt.c | 21 ++---
 1 file changed, 18 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
index 1ae0b40..3c6a02b 100644
--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
+++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
@@ -53,11 +53,21 @@ static const struct intel_gvt_ops *intel_gvt_ops;
 #define VFIO_PCI_INDEX_TO_OFFSET(index) ((u64)(index) << VFIO_PCI_OFFSET_SHIFT)
 #define VFIO_PCI_OFFSET_MASK(((u64)(1) << VFIO_PCI_OFFSET_SHIFT) - 1)
 
+struct vfio_region;
+struct intel_vgpu_regops {
+   size_t (*rw)(struct intel_vgpu *vgpu, char *buf,
+   size_t count, loff_t *ppos, bool iswrite);
+   void (*release)(struct intel_vgpu *vgpu,
+   struct vfio_region *region);
+};
+
 struct vfio_region {
u32 type;
u32 subtype;
size_t  size;
u32 flags;
+   const struct intel_vgpu_regops  *ops;
+   void*data;
 };
 
 struct kvmgt_pgfn {
@@ -642,7 +652,7 @@ static ssize_t intel_vgpu_rw(struct mdev_device *mdev, char 
*buf,
int ret = -EINVAL;
 
 
-   if (index >= VFIO_PCI_NUM_REGIONS) {
+   if (index >= VFIO_PCI_NUM_REGIONS + vgpu->vdev.num_regions) {
gvt_vgpu_err("invalid index: %u\n", index);
return -EINVAL;
}
@@ -676,8 +686,11 @@ static ssize_t intel_vgpu_rw(struct mdev_device *mdev, 
char *buf,
case VFIO_PCI_BAR5_REGION_INDEX:
case VFIO_PCI_VGA_REGION_INDEX:
case VFIO_PCI_ROM_REGION_INDEX:
+   break;
default:
-   gvt_vgpu_err("unsupported region: %u\n", index);
+   index -= VFIO_PCI_NUM_REGIONS;
+   return vgpu->vdev.region[index].ops->rw(vgpu, buf, count,
+   ppos, is_write);
}
 
return ret == 0 ? count : ret;
@@ -940,7 +953,8 @@ static long intel_vgpu_ioctl(struct mdev_device *mdev, 
unsigned int cmd,
 
info.flags = VFIO_DEVICE_FLAGS_PCI;
info.flags |= VFIO_DEVICE_FLAGS_RESET;
-   info.num_regions = VFIO_PCI_NUM_REGIONS;
+   info.num_regions = VFIO_PCI_NUM_REGIONS +
+   vgpu->vdev.num_regions;
info.num_irqs = VFIO_PCI_NUM_IRQS;
 
return copy_to_user((void __user *)arg, , minsz) ?
@@ -1061,6 +1075,7 @@ static long intel_vgpu_ioctl(struct mdev_device *mdev, 
unsigned int cmd,
}
 
if (caps.size) {
+   info.flags |= VFIO_REGION_INFO_FLAG_CAPS;
if (info.argsz < sizeof(info) + caps.size) {
info.argsz = sizeof(info) + caps.size;
info.cap_offset = 0;
-- 
2.7.4



[PATCH v8 4/6] vfio: Define vfio based vgpu's dma-buf operations

2017-06-09 Thread Xiaoguang Chen
Here we defined a new ioctl to create a fd for a vfio device based on
the input type. Now only one type is supported that is a dma-buf
management fd.
Two ioctls are defined for the dma-buf management fd: query the vfio
vgpu's plane information and create a dma-buf for a plane.

Signed-off-by: Xiaoguang Chen <xiaoguang.c...@intel.com>
---
 include/uapi/linux/vfio.h | 58 +++
 1 file changed, 58 insertions(+)

diff --git a/include/uapi/linux/vfio.h b/include/uapi/linux/vfio.h
index ae46105..24427b7 100644
--- a/include/uapi/linux/vfio.h
+++ b/include/uapi/linux/vfio.h
@@ -502,6 +502,64 @@ struct vfio_pci_hot_reset {
 
 #define VFIO_DEVICE_PCI_HOT_RESET  _IO(VFIO_TYPE, VFIO_BASE + 13)
 
+/**
+ * VFIO_DEVICE_GET_FD - _IO(VFIO_TYPE, VFIO_BASE + 14, __u32)
+ *
+ * Create a fd for a vfio device based on the input type
+ * Vendor driver should handle this ioctl to create a fd and manage the
+ * life cycle of this fd.
+ *
+ * Return: a fd if vendor support that type, -errno if not supported
+ */
+
+#define VFIO_DEVICE_GET_FD _IO(VFIO_TYPE, VFIO_BASE + 14)
+
+struct vfio_vgpu_plane_info {
+   __u64 start;
+   __u64 drm_format_mod;
+   __u32 drm_format;
+   __u32 width;
+   __u32 height;
+   __u32 stride;
+   __u32 size;
+   __u32 x_pos;
+   __u32 y_pos;
+   __u32 padding;
+};
+
+#define VFIO_DEVICE_DMABUF_MGR_FD  0 /* Supported fd types */
+
+/*
+ * VFIO_DEVICE_QUERY_PLANE - _IO(VFIO_TYPE, VFIO_BASE + 15,
+ * struct vfio_vgpu_query_plane)
+ * Query plane information
+ */
+struct vfio_vgpu_query_plane {
+   __u32 argsz;
+   __u32 flags;
+   struct vfio_vgpu_plane_info plane_info;
+   __u32 plane_id;
+   __u32 padding;
+};
+
+#define VFIO_DEVICE_QUERY_PLANE _IO(VFIO_TYPE, VFIO_BASE + 15)
+
+/*
+ * VFIO_DEVICE_CREATE_DMABUF - _IO(VFIO, VFIO_BASE + 16,
+ * struct vfio_vgpu_create_dmabuf)
+ *
+ * Create a dma-buf for a plane
+ */
+struct vfio_vgpu_create_dmabuf {
+   __u32 argsz;
+   __u32 flags;
+   struct vfio_vgpu_plane_info plane_info;
+   __s32 fd;
+   __u32 plane_id;
+};
+
+#define VFIO_DEVICE_CREATE_DMABUF _IO(VFIO_TYPE, VFIO_BASE + 16)
+
 /*  API for Type1 VFIO IOMMU  */
 
 /**
-- 
2.7.4



[PATCH v8 4/6] vfio: Define vfio based vgpu's dma-buf operations

2017-06-09 Thread Xiaoguang Chen
Here we defined a new ioctl to create a fd for a vfio device based on
the input type. Now only one type is supported that is a dma-buf
management fd.
Two ioctls are defined for the dma-buf management fd: query the vfio
vgpu's plane information and create a dma-buf for a plane.

Signed-off-by: Xiaoguang Chen 
---
 include/uapi/linux/vfio.h | 58 +++
 1 file changed, 58 insertions(+)

diff --git a/include/uapi/linux/vfio.h b/include/uapi/linux/vfio.h
index ae46105..24427b7 100644
--- a/include/uapi/linux/vfio.h
+++ b/include/uapi/linux/vfio.h
@@ -502,6 +502,64 @@ struct vfio_pci_hot_reset {
 
 #define VFIO_DEVICE_PCI_HOT_RESET  _IO(VFIO_TYPE, VFIO_BASE + 13)
 
+/**
+ * VFIO_DEVICE_GET_FD - _IO(VFIO_TYPE, VFIO_BASE + 14, __u32)
+ *
+ * Create a fd for a vfio device based on the input type
+ * Vendor driver should handle this ioctl to create a fd and manage the
+ * life cycle of this fd.
+ *
+ * Return: a fd if vendor support that type, -errno if not supported
+ */
+
+#define VFIO_DEVICE_GET_FD _IO(VFIO_TYPE, VFIO_BASE + 14)
+
+struct vfio_vgpu_plane_info {
+   __u64 start;
+   __u64 drm_format_mod;
+   __u32 drm_format;
+   __u32 width;
+   __u32 height;
+   __u32 stride;
+   __u32 size;
+   __u32 x_pos;
+   __u32 y_pos;
+   __u32 padding;
+};
+
+#define VFIO_DEVICE_DMABUF_MGR_FD  0 /* Supported fd types */
+
+/*
+ * VFIO_DEVICE_QUERY_PLANE - _IO(VFIO_TYPE, VFIO_BASE + 15,
+ * struct vfio_vgpu_query_plane)
+ * Query plane information
+ */
+struct vfio_vgpu_query_plane {
+   __u32 argsz;
+   __u32 flags;
+   struct vfio_vgpu_plane_info plane_info;
+   __u32 plane_id;
+   __u32 padding;
+};
+
+#define VFIO_DEVICE_QUERY_PLANE _IO(VFIO_TYPE, VFIO_BASE + 15)
+
+/*
+ * VFIO_DEVICE_CREATE_DMABUF - _IO(VFIO, VFIO_BASE + 16,
+ * struct vfio_vgpu_create_dmabuf)
+ *
+ * Create a dma-buf for a plane
+ */
+struct vfio_vgpu_create_dmabuf {
+   __u32 argsz;
+   __u32 flags;
+   struct vfio_vgpu_plane_info plane_info;
+   __s32 fd;
+   __u32 plane_id;
+};
+
+#define VFIO_DEVICE_CREATE_DMABUF _IO(VFIO_TYPE, VFIO_BASE + 16)
+
 /*  API for Type1 VFIO IOMMU  */
 
 /**
-- 
2.7.4



[PATCH v8 6/6] drm/i915/gvt: Adding user interface for dma-buf

2017-06-09 Thread Xiaoguang Chen
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.c...@intel.com>
Tested-by: Kechen Lu <kechen...@intel.com>
---
 drivers/gpu/drm/i915/gvt/dmabuf.c|  37 -
 drivers/gpu/drm/i915/gvt/dmabuf.h|   5 ++
 drivers/gpu/drm/i915/gvt/gvt.c   |   3 +
 drivers/gpu/drm/i915/gvt/gvt.h   |   5 ++
 drivers/gpu/drm/i915/gvt/hypercall.h |   3 +
 drivers/gpu/drm/i915/gvt/kvmgt.c | 145 +++
 drivers/gpu/drm/i915/gvt/mpt.h   |  30 
 drivers/gpu/drm/i915/gvt/vgpu.c  |   2 +
 8 files changed, 229 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/gvt/dmabuf.c 
b/drivers/gpu/drm/i915/gvt/dmabuf.c
index c38ed8e9fc..1811abd 100644
--- a/drivers/gpu/drm/i915/gvt/dmabuf.c
+++ b/drivers/gpu/drm/i915/gvt/dmabuf.c
@@ -81,6 +81,28 @@ static void intel_vgpu_gem_put_pages(struct 
drm_i915_gem_object *obj,
 
 static void intel_vgpu_gem_release(struct drm_i915_gem_object *obj)
 {
+   struct intel_vgpu_dmabuf_obj *dmabuf_obj;
+   struct intel_vgpu_fb_info *fb_info;
+   struct intel_vgpu *vgpu = NULL;
+   struct list_head *pos;
+
+   fb_info = (struct intel_vgpu_fb_info *)obj->gvt_info;
+   if (WARN_ON(!fb_info && !fb_info->vgpu)) {
+   gvt_vgpu_err("gvt info is invalid\n");
+   goto out;
+   }
+
+   vgpu = fb_info->vgpu;
+   list_for_each(pos, >dmabuf_obj_list_head) {
+   dmabuf_obj = container_of(pos, struct intel_vgpu_dmabuf_obj,
+   list);
+   if ((dmabuf_obj != NULL) && (dmabuf_obj->obj == obj)) {
+   kfree(dmabuf_obj);
+   break;
+   }
+   }
+   intel_gvt_hypervisor_put_vfio_device(vgpu);
+out:
kfree(obj->gvt_info);
 }
 
@@ -215,6 +237,7 @@ int intel_vgpu_create_dmabuf(struct intel_vgpu *vgpu, void 
*args)
struct vfio_vgpu_create_dmabuf *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, _dmabuf->plane_info,
gvt_dmabuf->plane_id);
@@ -237,6 +260,16 @@ int intel_vgpu_create_dmabuf(struct intel_vgpu *vgpu, void 
*args)
fb_info->vgpu = vgpu;
obj->gvt_info = fb_info;
 
+   dmabuf_obj = kmalloc(sizeof(*dmabuf_obj), GFP_KERNEL);
+   if (!dmabuf_obj) {
+   gvt_vgpu_err("alloc dmabuf_obj failed\n");
+   ret = -ENOMEM;
+   goto out_free_info;
+   }
+   dmabuf_obj->obj = obj;
+   INIT_LIST_HEAD(_obj->list);
+   list_add_tail(_obj->list, >dmabuf_obj_list_head);
+
dmabuf = i915_gem_prime_export(dev, >base, DRM_CLOEXEC | DRM_RDWR);
 
if (IS_ERR(dmabuf)) {
@@ -250,11 +283,13 @@ int intel_vgpu_create_dmabuf(struct intel_vgpu *vgpu, 
void *args)
gvt_vgpu_err("create dma-buf fd failed ret:%d\n", ret);
goto out_free;
}
-
+   intel_gvt_hypervisor_get_vfio_device(vgpu);
gvt_dmabuf->fd = ret;
 
return 0;
 out_free:
+   kfree(dmabuf_obj);
+out_free_info:
kfree(fb_info);
 out:
i915_gem_object_put(obj);
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..d589830 100644
--- a/drivers/gpu/drm/i915/gvt/gvt.c
+++ b/drivers/gpu/drm/i915/gvt/gvt.c
@@ -54,6 +54,9 @@ 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..8f08c42 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
+   atomic_t mgr_fd_opened;
+   st

[PATCH v8 3/6] drm/i915/gvt: Frame buffer decoder support for GVT-g

2017-06-09 Thread Xiaoguang Chen
decode frambuffer attributes of primary, cursor and sprite plane

Signed-off-by: Xiaoguang Chen <xiaoguang.c...@intel.com>
---
 drivers/gpu/drm/i915/gvt/Makefile |   3 +-
 drivers/gpu/drm/i915/gvt/display.c|   2 +-
 drivers/gpu/drm/i915/gvt/display.h|   2 +
 drivers/gpu/drm/i915/gvt/fb_decoder.c | 425 ++
 drivers/gpu/drm/i915/gvt/fb_decoder.h | 171 ++
 drivers/gpu/drm/i915/gvt/gvt.h|   1 +
 include/uapi/drm/drm_fourcc.h |   6 +
 7 files changed, 608 insertions(+), 2 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/gvt/fb_decoder.c
 create mode 100644 drivers/gpu/drm/i915/gvt/fb_decoder.h

diff --git a/drivers/gpu/drm/i915/gvt/Makefile 
b/drivers/gpu/drm/i915/gvt/Makefile
index b123c20..192ca26 100644
--- a/drivers/gpu/drm/i915/gvt/Makefile
+++ b/drivers/gpu/drm/i915/gvt/Makefile
@@ -1,7 +1,8 @@
 GVT_DIR := gvt
 GVT_SOURCE := gvt.o aperture_gm.o handlers.o vgpu.o trace_points.o firmware.o \
interrupt.o gtt.o cfg_space.o opregion.o mmio.o display.o edid.o \
-   execlist.o scheduler.o sched_policy.o render.o cmd_parser.o
+   execlist.o scheduler.o sched_policy.o render.o cmd_parser.o \
+   fb_decoder.o
 
 ccflags-y  += -I$(src) -I$(src)/$(GVT_DIR) -Wall
 i915-y += $(addprefix $(GVT_DIR)/, 
$(GVT_SOURCE))
diff --git a/drivers/gpu/drm/i915/gvt/display.c 
b/drivers/gpu/drm/i915/gvt/display.c
index e0261fc..f5f63c5 100644
--- a/drivers/gpu/drm/i915/gvt/display.c
+++ b/drivers/gpu/drm/i915/gvt/display.c
@@ -67,7 +67,7 @@ static int edp_pipe_is_enabled(struct intel_vgpu *vgpu)
return 1;
 }
 
-static int pipe_is_enabled(struct intel_vgpu *vgpu, int pipe)
+int pipe_is_enabled(struct intel_vgpu *vgpu, int pipe)
 {
struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv;
 
diff --git a/drivers/gpu/drm/i915/gvt/display.h 
b/drivers/gpu/drm/i915/gvt/display.h
index d73de22..b46b868 100644
--- a/drivers/gpu/drm/i915/gvt/display.h
+++ b/drivers/gpu/drm/i915/gvt/display.h
@@ -179,4 +179,6 @@ int intel_vgpu_init_display(struct intel_vgpu *vgpu, u64 
resolution);
 void intel_vgpu_reset_display(struct intel_vgpu *vgpu);
 void intel_vgpu_clean_display(struct intel_vgpu *vgpu);
 
+int pipe_is_enabled(struct intel_vgpu *vgpu, int pipe);
+
 #endif
diff --git a/drivers/gpu/drm/i915/gvt/fb_decoder.c 
b/drivers/gpu/drm/i915/gvt/fb_decoder.c
new file mode 100644
index 000..beac70b
--- /dev/null
+++ b/drivers/gpu/drm/i915/gvt/fb_decoder.c
@@ -0,0 +1,425 @@
+/*
+ * Copyright(c) 2011-2016 Intel Corporation. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 
THE
+ * SOFTWARE.
+ *
+ * Authors:
+ *Kevin Tian <kevin.t...@intel.com>
+ *
+ * Contributors:
+ *Bing Niu <bing@intel.com>
+ *Xu Han <xu@intel.com>
+ *    Ping Gao <ping.a@intel.com>
+ *Xiaoguang Chen <xiaoguang.c...@intel.com>
+ *Yang Liu <yang2@intel.com>
+ *
+ */
+
+#include 
+#include "i915_drv.h"
+#include "gvt.h"
+
+#define PRIMARY_FORMAT_NUM 16
+struct pixel_format {
+   int drm_format; /* Pixel format in DRM definition */
+   int bpp;/* Bits per pixel, 0 indicates invalid */
+   char *desc; /* The description */
+};
+
+/* non-supported format has bpp default to 0 */
+static struct pixel_format bdw_pixel_formats[PRIMARY_FORMAT_NUM] = {
+   [0x2] = {DRM_FORMAT_C8, 8, "8-bit Indexed"},
+   [0x5] = {DRM_FORMAT_RGB565, 16, "16-bit BGRX (5:6:5 MSB-R:G:B)"},
+   [0x6] = {DRM_FORMAT_XRGB, 32,
+   "32-bit BGRX (8:8:8:8 MSB-X:R:G:B)"},
+   [0x8] = {DRM_FORMAT_XBGR2101010, 32,
+   "32-bit RGBX (2:10:10:10 MSB-X:B:G:R)"},
+   [0xa] = {DRM_FORMAT_XRGB2101010, 32,
+   "32-bit 

[PATCH v8 0/6] drm/i915/gvt: Dma-buf support for GVT-g

2017-06-09 Thread Xiaoguang Chen
v7->v8:
1) refine framebuffer decoder code
2) fix a bug in decoding primary plane

v6->v7:
1) release dma-buf related allocations in dma-buf's associated release
function.
2) refine ioctl interface for querying plane info or create dma-buf
3) refine framebuffer decoder code
4) the patch series is based on 4.12.0-rc1

v5->v6:
1) align the dma-buf life cycle with the vfio device.
2) add the dma-buf releated operations in a separate patch.
3) i915 releated changes.

v4->v5:
1) fix bug while checking whether the gem obj is gvt's dma-buf when user
change caching mode or domains. Add a helper function to do it.
2) add definition for the query plane and create dma-buf.

v3->v4:
1) fix bug while checking whether the gem obj is gvt's dma-buf when set
caching mode or doamins.

v2->v3:
1) add a field gvt_plane_info in the drm_i915_gem_obj structure to save
the decoded plane information to avoid look up while need the plane info.
2) declare a new flag I915_GEM_OBJECT_IS_GVT_DMABUF in drm_i915_gem_object
to represent the gem obj for gvt's dma-buf. The tiling mode, caching mode
and domains can not be changed for this kind of gem object.
3) change dma-buf related information to be more generic. So other vendor
can use the same interface.

v1->v2:
1) create a management fd for dma-buf operations.
2) alloc gem object's backing storage in gem obj's get_pages() callback.

This patch set adds the dma-buf support for intel GVT-g.
dma-buf is a uniform mechanism to share DMA buffers across different
devices and sub-systems.
dma-buf for intel GVT-g is mainly used to share the vgpu's framebuffer
to other users or sub-systems so they can use the dma-buf to show the
desktop of a vm which uses intel vgpu.

The main idea is we create a gem object and set vgpu's framebuffer as
the backing storage of this gem object. And associate this gem obj
to a dma-buf object then export this dma-buf at the meantime
generate a file descriptor for this dma-buf. Finally deliver this file
descriptor to user space. And user can use this dma-buf fd to do render
or other operations.
User need to create a fd(for intel GVT-g dma-buf support it is a:dma-buf
management fd) then user can use this fd to query the plane information
or create a dma-buf. The life cycle of this fd is managed by GVT-g user
do not need to care about that.

We have an example program on how to use the dma-buf. You can download
the program to have a try. Good luck :)
git repo: https://github.com/01org/igvtg-qemu branch:kvmgt_dmabuf_example

Xiaoguang Chen (6):
  drm/i915/gvt: Extend the GVT-g architecture to support vfio device
region
  drm/i915/gvt: OpRegion support for GVT-g
  drm/i915/gvt: Frame buffer decoder support for GVT-g
  vfio: Define vfio based vgpu's dma-buf operations
  drm/i915/gvt: Dmabuf support for GVT-g
  drm/i915/gvt: Adding user interface for dma-buf

 drivers/gpu/drm/i915/gvt/Makefile  |   3 +-
 drivers/gpu/drm/i915/gvt/display.c |   2 +-
 drivers/gpu/drm/i915/gvt/display.h |   2 +
 drivers/gpu/drm/i915/gvt/dmabuf.c  | 298 +++
 drivers/gpu/drm/i915/gvt/dmabuf.h  |  42 
 drivers/gpu/drm/i915/gvt/fb_decoder.c  | 425 +
 drivers/gpu/drm/i915/gvt/fb_decoder.h  | 171 +
 drivers/gpu/drm/i915/gvt/gvt.c |   3 +
 drivers/gpu/drm/i915/gvt/gvt.h |   7 +
 drivers/gpu/drm/i915/gvt/hypercall.h   |   4 +
 drivers/gpu/drm/i915/gvt/kvmgt.c   | 254 +++-
 drivers/gpu/drm/i915/gvt/mpt.h |  45 
 drivers/gpu/drm/i915/gvt/opregion.c|  26 +-
 drivers/gpu/drm/i915/gvt/vgpu.c|   6 +
 drivers/gpu/drm/i915/i915_gem.c|  26 +-
 drivers/gpu/drm/i915/i915_gem_object.h |   9 +
 drivers/gpu/drm/i915/i915_gem_tiling.c |   5 +
 include/uapi/drm/drm_fourcc.h  |   6 +
 include/uapi/linux/vfio.h  |  58 +
 19 files changed, 1380 insertions(+), 12 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/gvt/dmabuf.c
 create mode 100644 drivers/gpu/drm/i915/gvt/dmabuf.h
 create mode 100644 drivers/gpu/drm/i915/gvt/fb_decoder.c
 create mode 100644 drivers/gpu/drm/i915/gvt/fb_decoder.h

-- 
2.7.4



[PATCH v8 6/6] drm/i915/gvt: Adding user interface for dma-buf

2017-06-09 Thread Xiaoguang Chen
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 
Tested-by: Kechen Lu 
---
 drivers/gpu/drm/i915/gvt/dmabuf.c|  37 -
 drivers/gpu/drm/i915/gvt/dmabuf.h|   5 ++
 drivers/gpu/drm/i915/gvt/gvt.c   |   3 +
 drivers/gpu/drm/i915/gvt/gvt.h   |   5 ++
 drivers/gpu/drm/i915/gvt/hypercall.h |   3 +
 drivers/gpu/drm/i915/gvt/kvmgt.c | 145 +++
 drivers/gpu/drm/i915/gvt/mpt.h   |  30 
 drivers/gpu/drm/i915/gvt/vgpu.c  |   2 +
 8 files changed, 229 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/gvt/dmabuf.c 
b/drivers/gpu/drm/i915/gvt/dmabuf.c
index c38ed8e9fc..1811abd 100644
--- a/drivers/gpu/drm/i915/gvt/dmabuf.c
+++ b/drivers/gpu/drm/i915/gvt/dmabuf.c
@@ -81,6 +81,28 @@ static void intel_vgpu_gem_put_pages(struct 
drm_i915_gem_object *obj,
 
 static void intel_vgpu_gem_release(struct drm_i915_gem_object *obj)
 {
+   struct intel_vgpu_dmabuf_obj *dmabuf_obj;
+   struct intel_vgpu_fb_info *fb_info;
+   struct intel_vgpu *vgpu = NULL;
+   struct list_head *pos;
+
+   fb_info = (struct intel_vgpu_fb_info *)obj->gvt_info;
+   if (WARN_ON(!fb_info && !fb_info->vgpu)) {
+   gvt_vgpu_err("gvt info is invalid\n");
+   goto out;
+   }
+
+   vgpu = fb_info->vgpu;
+   list_for_each(pos, >dmabuf_obj_list_head) {
+   dmabuf_obj = container_of(pos, struct intel_vgpu_dmabuf_obj,
+   list);
+   if ((dmabuf_obj != NULL) && (dmabuf_obj->obj == obj)) {
+   kfree(dmabuf_obj);
+   break;
+   }
+   }
+   intel_gvt_hypervisor_put_vfio_device(vgpu);
+out:
kfree(obj->gvt_info);
 }
 
@@ -215,6 +237,7 @@ int intel_vgpu_create_dmabuf(struct intel_vgpu *vgpu, void 
*args)
struct vfio_vgpu_create_dmabuf *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, _dmabuf->plane_info,
gvt_dmabuf->plane_id);
@@ -237,6 +260,16 @@ int intel_vgpu_create_dmabuf(struct intel_vgpu *vgpu, void 
*args)
fb_info->vgpu = vgpu;
obj->gvt_info = fb_info;
 
+   dmabuf_obj = kmalloc(sizeof(*dmabuf_obj), GFP_KERNEL);
+   if (!dmabuf_obj) {
+   gvt_vgpu_err("alloc dmabuf_obj failed\n");
+   ret = -ENOMEM;
+   goto out_free_info;
+   }
+   dmabuf_obj->obj = obj;
+   INIT_LIST_HEAD(_obj->list);
+   list_add_tail(_obj->list, >dmabuf_obj_list_head);
+
dmabuf = i915_gem_prime_export(dev, >base, DRM_CLOEXEC | DRM_RDWR);
 
if (IS_ERR(dmabuf)) {
@@ -250,11 +283,13 @@ int intel_vgpu_create_dmabuf(struct intel_vgpu *vgpu, 
void *args)
gvt_vgpu_err("create dma-buf fd failed ret:%d\n", ret);
goto out_free;
}
-
+   intel_gvt_hypervisor_get_vfio_device(vgpu);
gvt_dmabuf->fd = ret;
 
return 0;
 out_free:
+   kfree(dmabuf_obj);
+out_free_info:
kfree(fb_info);
 out:
i915_gem_object_put(obj);
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..d589830 100644
--- a/drivers/gpu/drm/i915/gvt/gvt.c
+++ b/drivers/gpu/drm/i915/gvt/gvt.c
@@ -54,6 +54,9 @@ 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..8f08c42 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
+   atomic_t mgr_fd_opened;
+   struct list_head dmabuf_obj_list_head;
 };
 
 struct intel_gv

[PATCH v8 3/6] drm/i915/gvt: Frame buffer decoder support for GVT-g

2017-06-09 Thread Xiaoguang Chen
decode frambuffer attributes of primary, cursor and sprite plane

Signed-off-by: Xiaoguang Chen 
---
 drivers/gpu/drm/i915/gvt/Makefile |   3 +-
 drivers/gpu/drm/i915/gvt/display.c|   2 +-
 drivers/gpu/drm/i915/gvt/display.h|   2 +
 drivers/gpu/drm/i915/gvt/fb_decoder.c | 425 ++
 drivers/gpu/drm/i915/gvt/fb_decoder.h | 171 ++
 drivers/gpu/drm/i915/gvt/gvt.h|   1 +
 include/uapi/drm/drm_fourcc.h |   6 +
 7 files changed, 608 insertions(+), 2 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/gvt/fb_decoder.c
 create mode 100644 drivers/gpu/drm/i915/gvt/fb_decoder.h

diff --git a/drivers/gpu/drm/i915/gvt/Makefile 
b/drivers/gpu/drm/i915/gvt/Makefile
index b123c20..192ca26 100644
--- a/drivers/gpu/drm/i915/gvt/Makefile
+++ b/drivers/gpu/drm/i915/gvt/Makefile
@@ -1,7 +1,8 @@
 GVT_DIR := gvt
 GVT_SOURCE := gvt.o aperture_gm.o handlers.o vgpu.o trace_points.o firmware.o \
interrupt.o gtt.o cfg_space.o opregion.o mmio.o display.o edid.o \
-   execlist.o scheduler.o sched_policy.o render.o cmd_parser.o
+   execlist.o scheduler.o sched_policy.o render.o cmd_parser.o \
+   fb_decoder.o
 
 ccflags-y  += -I$(src) -I$(src)/$(GVT_DIR) -Wall
 i915-y += $(addprefix $(GVT_DIR)/, 
$(GVT_SOURCE))
diff --git a/drivers/gpu/drm/i915/gvt/display.c 
b/drivers/gpu/drm/i915/gvt/display.c
index e0261fc..f5f63c5 100644
--- a/drivers/gpu/drm/i915/gvt/display.c
+++ b/drivers/gpu/drm/i915/gvt/display.c
@@ -67,7 +67,7 @@ static int edp_pipe_is_enabled(struct intel_vgpu *vgpu)
return 1;
 }
 
-static int pipe_is_enabled(struct intel_vgpu *vgpu, int pipe)
+int pipe_is_enabled(struct intel_vgpu *vgpu, int pipe)
 {
struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv;
 
diff --git a/drivers/gpu/drm/i915/gvt/display.h 
b/drivers/gpu/drm/i915/gvt/display.h
index d73de22..b46b868 100644
--- a/drivers/gpu/drm/i915/gvt/display.h
+++ b/drivers/gpu/drm/i915/gvt/display.h
@@ -179,4 +179,6 @@ int intel_vgpu_init_display(struct intel_vgpu *vgpu, u64 
resolution);
 void intel_vgpu_reset_display(struct intel_vgpu *vgpu);
 void intel_vgpu_clean_display(struct intel_vgpu *vgpu);
 
+int pipe_is_enabled(struct intel_vgpu *vgpu, int pipe);
+
 #endif
diff --git a/drivers/gpu/drm/i915/gvt/fb_decoder.c 
b/drivers/gpu/drm/i915/gvt/fb_decoder.c
new file mode 100644
index 000..beac70b
--- /dev/null
+++ b/drivers/gpu/drm/i915/gvt/fb_decoder.c
@@ -0,0 +1,425 @@
+/*
+ * Copyright(c) 2011-2016 Intel Corporation. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 
THE
+ * SOFTWARE.
+ *
+ * Authors:
+ *Kevin Tian 
+ *
+ * Contributors:
+ *Bing Niu 
+ *Xu Han 
+ *Ping Gao 
+ *Xiaoguang Chen 
+ *Yang Liu 
+ *
+ */
+
+#include 
+#include "i915_drv.h"
+#include "gvt.h"
+
+#define PRIMARY_FORMAT_NUM 16
+struct pixel_format {
+   int drm_format; /* Pixel format in DRM definition */
+   int bpp;/* Bits per pixel, 0 indicates invalid */
+   char *desc; /* The description */
+};
+
+/* non-supported format has bpp default to 0 */
+static struct pixel_format bdw_pixel_formats[PRIMARY_FORMAT_NUM] = {
+   [0x2] = {DRM_FORMAT_C8, 8, "8-bit Indexed"},
+   [0x5] = {DRM_FORMAT_RGB565, 16, "16-bit BGRX (5:6:5 MSB-R:G:B)"},
+   [0x6] = {DRM_FORMAT_XRGB, 32,
+   "32-bit BGRX (8:8:8:8 MSB-X:R:G:B)"},
+   [0x8] = {DRM_FORMAT_XBGR2101010, 32,
+   "32-bit RGBX (2:10:10:10 MSB-X:B:G:R)"},
+   [0xa] = {DRM_FORMAT_XRGB2101010, 32,
+   "32-bit BGRX (2:10:10:10 MSB-X:R:G:B)"},
+   [0xc] = {DRM_FORMAT_XRGB161616_GVT, 64,
+   "64-bit RGBX Floating Point(16:16:16:16 MSB-X:B:G:R)"},
+   [0xe] = {DRM_FORMAT_

[PATCH v8 0/6] drm/i915/gvt: Dma-buf support for GVT-g

2017-06-09 Thread Xiaoguang Chen
v7->v8:
1) refine framebuffer decoder code
2) fix a bug in decoding primary plane

v6->v7:
1) release dma-buf related allocations in dma-buf's associated release
function.
2) refine ioctl interface for querying plane info or create dma-buf
3) refine framebuffer decoder code
4) the patch series is based on 4.12.0-rc1

v5->v6:
1) align the dma-buf life cycle with the vfio device.
2) add the dma-buf releated operations in a separate patch.
3) i915 releated changes.

v4->v5:
1) fix bug while checking whether the gem obj is gvt's dma-buf when user
change caching mode or domains. Add a helper function to do it.
2) add definition for the query plane and create dma-buf.

v3->v4:
1) fix bug while checking whether the gem obj is gvt's dma-buf when set
caching mode or doamins.

v2->v3:
1) add a field gvt_plane_info in the drm_i915_gem_obj structure to save
the decoded plane information to avoid look up while need the plane info.
2) declare a new flag I915_GEM_OBJECT_IS_GVT_DMABUF in drm_i915_gem_object
to represent the gem obj for gvt's dma-buf. The tiling mode, caching mode
and domains can not be changed for this kind of gem object.
3) change dma-buf related information to be more generic. So other vendor
can use the same interface.

v1->v2:
1) create a management fd for dma-buf operations.
2) alloc gem object's backing storage in gem obj's get_pages() callback.

This patch set adds the dma-buf support for intel GVT-g.
dma-buf is a uniform mechanism to share DMA buffers across different
devices and sub-systems.
dma-buf for intel GVT-g is mainly used to share the vgpu's framebuffer
to other users or sub-systems so they can use the dma-buf to show the
desktop of a vm which uses intel vgpu.

The main idea is we create a gem object and set vgpu's framebuffer as
the backing storage of this gem object. And associate this gem obj
to a dma-buf object then export this dma-buf at the meantime
generate a file descriptor for this dma-buf. Finally deliver this file
descriptor to user space. And user can use this dma-buf fd to do render
or other operations.
User need to create a fd(for intel GVT-g dma-buf support it is a:dma-buf
management fd) then user can use this fd to query the plane information
or create a dma-buf. The life cycle of this fd is managed by GVT-g user
do not need to care about that.

We have an example program on how to use the dma-buf. You can download
the program to have a try. Good luck :)
git repo: https://github.com/01org/igvtg-qemu branch:kvmgt_dmabuf_example

Xiaoguang Chen (6):
  drm/i915/gvt: Extend the GVT-g architecture to support vfio device
region
  drm/i915/gvt: OpRegion support for GVT-g
  drm/i915/gvt: Frame buffer decoder support for GVT-g
  vfio: Define vfio based vgpu's dma-buf operations
  drm/i915/gvt: Dmabuf support for GVT-g
  drm/i915/gvt: Adding user interface for dma-buf

 drivers/gpu/drm/i915/gvt/Makefile  |   3 +-
 drivers/gpu/drm/i915/gvt/display.c |   2 +-
 drivers/gpu/drm/i915/gvt/display.h |   2 +
 drivers/gpu/drm/i915/gvt/dmabuf.c  | 298 +++
 drivers/gpu/drm/i915/gvt/dmabuf.h  |  42 
 drivers/gpu/drm/i915/gvt/fb_decoder.c  | 425 +
 drivers/gpu/drm/i915/gvt/fb_decoder.h  | 171 +
 drivers/gpu/drm/i915/gvt/gvt.c |   3 +
 drivers/gpu/drm/i915/gvt/gvt.h |   7 +
 drivers/gpu/drm/i915/gvt/hypercall.h   |   4 +
 drivers/gpu/drm/i915/gvt/kvmgt.c   | 254 +++-
 drivers/gpu/drm/i915/gvt/mpt.h |  45 
 drivers/gpu/drm/i915/gvt/opregion.c|  26 +-
 drivers/gpu/drm/i915/gvt/vgpu.c|   6 +
 drivers/gpu/drm/i915/i915_gem.c|  26 +-
 drivers/gpu/drm/i915/i915_gem_object.h |   9 +
 drivers/gpu/drm/i915/i915_gem_tiling.c |   5 +
 include/uapi/drm/drm_fourcc.h  |   6 +
 include/uapi/linux/vfio.h  |  58 +
 19 files changed, 1380 insertions(+), 12 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/gvt/dmabuf.c
 create mode 100644 drivers/gpu/drm/i915/gvt/dmabuf.h
 create mode 100644 drivers/gpu/drm/i915/gvt/fb_decoder.c
 create mode 100644 drivers/gpu/drm/i915/gvt/fb_decoder.h

-- 
2.7.4



[PATCH v8 2/6] drm/i915/gvt: OpRegion support for GVT-g

2017-06-09 Thread Xiaoguang Chen
OpRegion is needed to support display related operation for
intel vgpu.

A vfio device region is added to intel vgpu to deliver the
host OpRegion information to user space so user space can
construct the OpRegion for vgpu.

Signed-off-by: Bing Niu <bing@intel.com>
Signed-off-by: Xiaoguang Chen <xiaoguang.c...@intel.com>
---
 drivers/gpu/drm/i915/gvt/hypercall.h |  1 +
 drivers/gpu/drm/i915/gvt/kvmgt.c | 88 
 drivers/gpu/drm/i915/gvt/mpt.h   | 15 ++
 drivers/gpu/drm/i915/gvt/opregion.c  | 26 ---
 drivers/gpu/drm/i915/gvt/vgpu.c  |  4 ++
 5 files changed, 128 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/gvt/hypercall.h 
b/drivers/gpu/drm/i915/gvt/hypercall.h
index df7f33a..32c345c 100644
--- a/drivers/gpu/drm/i915/gvt/hypercall.h
+++ b/drivers/gpu/drm/i915/gvt/hypercall.h
@@ -55,6 +55,7 @@ struct intel_gvt_mpt {
  unsigned long mfn, unsigned int nr, bool map);
int (*set_trap_area)(unsigned long handle, u64 start, u64 end,
 bool map);
+   int (*set_opregion)(void *vgpu);
 };
 
 extern struct intel_gvt_mpt xengt_mpt;
diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
index 3c6a02b..6b4652a 100644
--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
+++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
@@ -53,6 +53,8 @@ static const struct intel_gvt_ops *intel_gvt_ops;
 #define VFIO_PCI_INDEX_TO_OFFSET(index) ((u64)(index) << VFIO_PCI_OFFSET_SHIFT)
 #define VFIO_PCI_OFFSET_MASK(((u64)(1) << VFIO_PCI_OFFSET_SHIFT) - 1)
 
+#define OPREGION_SIGNATURE "IntelGraphicsMem"
+
 struct vfio_region;
 struct intel_vgpu_regops {
size_t (*rw)(struct intel_vgpu *vgpu, char *buf,
@@ -436,6 +438,91 @@ static void kvmgt_protect_table_del(struct 
kvmgt_guest_info *info,
}
 }
 
+static size_t intel_vgpu_reg_rw_opregion(struct intel_vgpu *vgpu, char *buf,
+   size_t count, loff_t *ppos, bool iswrite)
+{
+   unsigned int i = VFIO_PCI_OFFSET_TO_INDEX(*ppos) -
+   VFIO_PCI_NUM_REGIONS;
+   void *base = vgpu->vdev.region[i].data;
+   loff_t pos = *ppos & VFIO_PCI_OFFSET_MASK;
+
+   if (pos >= vgpu->vdev.region[i].size || iswrite) {
+   gvt_vgpu_err("invalid op or offset for Intel vgpu OpRegion\n");
+   return -EINVAL;
+   }
+   count = min(count, (size_t)(vgpu->vdev.region[i].size - pos));
+   memcpy(buf, base + pos, count);
+
+   return count;
+}
+
+static void intel_vgpu_reg_release_opregion(struct intel_vgpu *vgpu,
+   struct vfio_region *region)
+{
+   memunmap(region->data);
+}
+
+static const struct intel_vgpu_regops intel_vgpu_regops_opregion = {
+   .rw = intel_vgpu_reg_rw_opregion,
+   .release = intel_vgpu_reg_release_opregion,
+};
+
+static int intel_vgpu_register_reg(struct intel_vgpu *vgpu,
+   unsigned int type, unsigned int subtype,
+   const struct intel_vgpu_regops *ops,
+   size_t size, u32 flags, void *data)
+{
+   struct vfio_region *region;
+
+   region = krealloc(vgpu->vdev.region,
+   (vgpu->vdev.num_regions + 1) * sizeof(*region),
+   GFP_KERNEL);
+   if (!region)
+   return -ENOMEM;
+
+   vgpu->vdev.region = region;
+   vgpu->vdev.region[vgpu->vdev.num_regions].type = type;
+   vgpu->vdev.region[vgpu->vdev.num_regions].subtype = subtype;
+   vgpu->vdev.region[vgpu->vdev.num_regions].ops = ops;
+   vgpu->vdev.region[vgpu->vdev.num_regions].size = size;
+   vgpu->vdev.region[vgpu->vdev.num_regions].flags = flags;
+   vgpu->vdev.region[vgpu->vdev.num_regions].data = data;
+   vgpu->vdev.num_regions++;
+
+   return 0;
+}
+
+static int kvmgt_set_opregion(void *p_vgpu)
+{
+   struct intel_vgpu *vgpu = (struct intel_vgpu *)p_vgpu;
+   unsigned int addr;
+   void *base;
+   int ret;
+
+   addr = vgpu->gvt->opregion.opregion_pa;
+   if (!addr || !(~addr))
+   return -ENODEV;
+
+   base = memremap(addr, OPREGION_SIZE, MEMREMAP_WB);
+   if (!base)
+   return -ENOMEM;
+
+   if (memcmp(base, OPREGION_SIGNATURE, 16)) {
+   memunmap(base);
+   return -EINVAL;
+   }
+
+   ret = intel_vgpu_register_reg(vgpu,
+   PCI_VENDOR_ID_INTEL | VFIO_REGION_TYPE_PCI_VENDOR_TYPE,
+   VFIO_REGION_SUBTYPE_INTEL_IGD_OPREGION,
+   _vgpu_regops_opregion, OPREGION_SIZE,
+   VFIO_REGION_INFO_FLAG_READ, base);
+   if (ret)
+   memunmap(base);
+
+   return ret;
+}
+
 static int intel_vgpu_create(struct kobject *kobj, struct mdev_device *mdev)
 {
struct intel_vgpu *vgpu = NULL;
@@ -1524,6 +1611,7 @@ struct inte

[PATCH v8 1/6] drm/i915/gvt: Extend the GVT-g architecture to support vfio device region

2017-06-09 Thread Xiaoguang Chen
Signed-off-by: Xiaoguang Chen <xiaoguang.c...@intel.com>
---
 drivers/gpu/drm/i915/gvt/kvmgt.c | 21 ++---
 1 file changed, 18 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
index 1ae0b40..3c6a02b 100644
--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
+++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
@@ -53,11 +53,21 @@ static const struct intel_gvt_ops *intel_gvt_ops;
 #define VFIO_PCI_INDEX_TO_OFFSET(index) ((u64)(index) << VFIO_PCI_OFFSET_SHIFT)
 #define VFIO_PCI_OFFSET_MASK(((u64)(1) << VFIO_PCI_OFFSET_SHIFT) - 1)
 
+struct vfio_region;
+struct intel_vgpu_regops {
+   size_t (*rw)(struct intel_vgpu *vgpu, char *buf,
+   size_t count, loff_t *ppos, bool iswrite);
+   void (*release)(struct intel_vgpu *vgpu,
+   struct vfio_region *region);
+};
+
 struct vfio_region {
u32 type;
u32 subtype;
size_t  size;
u32 flags;
+   const struct intel_vgpu_regops  *ops;
+   void*data;
 };
 
 struct kvmgt_pgfn {
@@ -642,7 +652,7 @@ static ssize_t intel_vgpu_rw(struct mdev_device *mdev, char 
*buf,
int ret = -EINVAL;
 
 
-   if (index >= VFIO_PCI_NUM_REGIONS) {
+   if (index >= VFIO_PCI_NUM_REGIONS + vgpu->vdev.num_regions) {
gvt_vgpu_err("invalid index: %u\n", index);
return -EINVAL;
}
@@ -676,8 +686,11 @@ static ssize_t intel_vgpu_rw(struct mdev_device *mdev, 
char *buf,
case VFIO_PCI_BAR5_REGION_INDEX:
case VFIO_PCI_VGA_REGION_INDEX:
case VFIO_PCI_ROM_REGION_INDEX:
+   break;
default:
-   gvt_vgpu_err("unsupported region: %u\n", index);
+   index -= VFIO_PCI_NUM_REGIONS;
+   return vgpu->vdev.region[index].ops->rw(vgpu, buf, count,
+   ppos, is_write);
}
 
return ret == 0 ? count : ret;
@@ -940,7 +953,8 @@ static long intel_vgpu_ioctl(struct mdev_device *mdev, 
unsigned int cmd,
 
info.flags = VFIO_DEVICE_FLAGS_PCI;
info.flags |= VFIO_DEVICE_FLAGS_RESET;
-   info.num_regions = VFIO_PCI_NUM_REGIONS;
+   info.num_regions = VFIO_PCI_NUM_REGIONS +
+   vgpu->vdev.num_regions;
info.num_irqs = VFIO_PCI_NUM_IRQS;
 
return copy_to_user((void __user *)arg, , minsz) ?
@@ -1061,6 +1075,7 @@ static long intel_vgpu_ioctl(struct mdev_device *mdev, 
unsigned int cmd,
}
 
if (caps.size) {
+   info.flags |= VFIO_REGION_INFO_FLAG_CAPS;
if (info.argsz < sizeof(info) + caps.size) {
info.argsz = sizeof(info) + caps.size;
info.cap_offset = 0;
-- 
2.7.4



[PATCH v8 5/6] drm/i915/gvt: Dmabuf support for GVT-g

2017-06-09 Thread Xiaoguang Chen
dmabuf for GVT-g can be exported to users who can use the dmabuf to show
the desktop of vm which use intel vgpu.

Currently we provide query and create new dmabuf operations.

Users of dmabuf can cache some created dmabufs and related information
such as the framebuffer's address, size, tiling mode, width, height etc.
When refresh the screen first query the currnet vgpu's frambuffer and
compare with the cached ones(address, size, tiling, width, height etc)
if found one then reuse the found dmabuf to gain performance improvment.

If there is no dmabuf created yet or not found in the cached dmabufs then
need to create a new dmabuf. To create a dmabuf first a gem object will
be created and the backing storage of this gem object is the vgpu's
framebuffer(primary/cursor).
Set caching mode, change tiling mode and set domains of this gem object
is not supported.
Then associate this gem object to a dmabuf and export this dmabuf.
A file descriptor will be generated for this dmabuf and this file
descriptor can be sent to user space to do display.

Signed-off-by: Xiaoguang Chen <xiaoguang.c...@intel.com>
Tested-by: Kechen Lu <kechen...@intel.com>
---
 drivers/gpu/drm/i915/gvt/Makefile  |   2 +-
 drivers/gpu/drm/i915/gvt/dmabuf.c  | 263 +
 drivers/gpu/drm/i915/gvt/dmabuf.h  |  37 +
 drivers/gpu/drm/i915/gvt/gvt.h |   1 +
 drivers/gpu/drm/i915/i915_gem.c|  26 +++-
 drivers/gpu/drm/i915/i915_gem_object.h |   9 ++
 drivers/gpu/drm/i915/i915_gem_tiling.c |   5 +
 7 files changed, 341 insertions(+), 2 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/gvt/dmabuf.c
 create mode 100644 drivers/gpu/drm/i915/gvt/dmabuf.h

diff --git a/drivers/gpu/drm/i915/gvt/Makefile 
b/drivers/gpu/drm/i915/gvt/Makefile
index 192ca26..e480f7d 100644
--- a/drivers/gpu/drm/i915/gvt/Makefile
+++ b/drivers/gpu/drm/i915/gvt/Makefile
@@ -2,7 +2,7 @@ GVT_DIR := gvt
 GVT_SOURCE := gvt.o aperture_gm.o handlers.o vgpu.o trace_points.o firmware.o \
interrupt.o gtt.o cfg_space.o opregion.o mmio.o display.o edid.o \
execlist.o scheduler.o sched_policy.o render.o cmd_parser.o \
-   fb_decoder.o
+   fb_decoder.o dmabuf.o
 
 ccflags-y  += -I$(src) -I$(src)/$(GVT_DIR) -Wall
 i915-y += $(addprefix $(GVT_DIR)/, 
$(GVT_SOURCE))
diff --git a/drivers/gpu/drm/i915/gvt/dmabuf.c 
b/drivers/gpu/drm/i915/gvt/dmabuf.c
new file mode 100644
index 000..c38ed8e9fc
--- /dev/null
+++ b/drivers/gpu/drm/i915/gvt/dmabuf.c
@@ -0,0 +1,263 @@
+/*
+ * Copyright 2017 Intel Corporation. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *Zhiyuan Lv <zhiyuan...@intel.com>
+ *
+ * Contributors:
+ *Xiaoguang Chen <xiaoguang.c...@intel.com>
+ */
+
+#include 
+#include 
+#include 
+
+#include "i915_drv.h"
+#include "gvt.h"
+
+#define GEN8_DECODE_PTE(pte) (pte & GENMASK_ULL(63, 12))
+
+static struct sg_table *intel_vgpu_gem_get_pages(
+   struct drm_i915_gem_object *obj)
+{
+   struct drm_i915_private *dev_priv = to_i915(obj->base.dev);
+   struct sg_table *st;
+   struct scatterlist *sg;
+   int i, ret;
+   gen8_pte_t __iomem *gtt_entries;
+   struct intel_vgpu_fb_info *fb_info;
+
+   fb_info = (struct intel_vgpu_fb_info *)obj->gvt_info;
+   if (WARN_ON(!fb_info))
+   return ERR_PTR(-ENODEV);
+
+   st = kmalloc(sizeof(*st), GFP_KERNEL);
+   if (!st)
+   return ERR_PTR(-ENOMEM);
+
+   ret = sg_alloc_table(st, fb_info->fb_size, GFP_KERNEL);
+   if (ret) {
+   kfree(st);
+   return ERR_PTR(ret);
+   }
+   gtt_entries = (gen8_pte_t __iomem *)dev_priv->ggtt.gsm +
+   (fb_info->fb_addr >> PAGE_SHIFT);
+   for_each_

[PATCH v8 2/6] drm/i915/gvt: OpRegion support for GVT-g

2017-06-09 Thread Xiaoguang Chen
OpRegion is needed to support display related operation for
intel vgpu.

A vfio device region is added to intel vgpu to deliver the
host OpRegion information to user space so user space can
construct the OpRegion for vgpu.

Signed-off-by: Bing Niu 
Signed-off-by: Xiaoguang Chen 
---
 drivers/gpu/drm/i915/gvt/hypercall.h |  1 +
 drivers/gpu/drm/i915/gvt/kvmgt.c | 88 
 drivers/gpu/drm/i915/gvt/mpt.h   | 15 ++
 drivers/gpu/drm/i915/gvt/opregion.c  | 26 ---
 drivers/gpu/drm/i915/gvt/vgpu.c  |  4 ++
 5 files changed, 128 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/gvt/hypercall.h 
b/drivers/gpu/drm/i915/gvt/hypercall.h
index df7f33a..32c345c 100644
--- a/drivers/gpu/drm/i915/gvt/hypercall.h
+++ b/drivers/gpu/drm/i915/gvt/hypercall.h
@@ -55,6 +55,7 @@ struct intel_gvt_mpt {
  unsigned long mfn, unsigned int nr, bool map);
int (*set_trap_area)(unsigned long handle, u64 start, u64 end,
 bool map);
+   int (*set_opregion)(void *vgpu);
 };
 
 extern struct intel_gvt_mpt xengt_mpt;
diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
index 3c6a02b..6b4652a 100644
--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
+++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
@@ -53,6 +53,8 @@ static const struct intel_gvt_ops *intel_gvt_ops;
 #define VFIO_PCI_INDEX_TO_OFFSET(index) ((u64)(index) << VFIO_PCI_OFFSET_SHIFT)
 #define VFIO_PCI_OFFSET_MASK(((u64)(1) << VFIO_PCI_OFFSET_SHIFT) - 1)
 
+#define OPREGION_SIGNATURE "IntelGraphicsMem"
+
 struct vfio_region;
 struct intel_vgpu_regops {
size_t (*rw)(struct intel_vgpu *vgpu, char *buf,
@@ -436,6 +438,91 @@ static void kvmgt_protect_table_del(struct 
kvmgt_guest_info *info,
}
 }
 
+static size_t intel_vgpu_reg_rw_opregion(struct intel_vgpu *vgpu, char *buf,
+   size_t count, loff_t *ppos, bool iswrite)
+{
+   unsigned int i = VFIO_PCI_OFFSET_TO_INDEX(*ppos) -
+   VFIO_PCI_NUM_REGIONS;
+   void *base = vgpu->vdev.region[i].data;
+   loff_t pos = *ppos & VFIO_PCI_OFFSET_MASK;
+
+   if (pos >= vgpu->vdev.region[i].size || iswrite) {
+   gvt_vgpu_err("invalid op or offset for Intel vgpu OpRegion\n");
+   return -EINVAL;
+   }
+   count = min(count, (size_t)(vgpu->vdev.region[i].size - pos));
+   memcpy(buf, base + pos, count);
+
+   return count;
+}
+
+static void intel_vgpu_reg_release_opregion(struct intel_vgpu *vgpu,
+   struct vfio_region *region)
+{
+   memunmap(region->data);
+}
+
+static const struct intel_vgpu_regops intel_vgpu_regops_opregion = {
+   .rw = intel_vgpu_reg_rw_opregion,
+   .release = intel_vgpu_reg_release_opregion,
+};
+
+static int intel_vgpu_register_reg(struct intel_vgpu *vgpu,
+   unsigned int type, unsigned int subtype,
+   const struct intel_vgpu_regops *ops,
+   size_t size, u32 flags, void *data)
+{
+   struct vfio_region *region;
+
+   region = krealloc(vgpu->vdev.region,
+   (vgpu->vdev.num_regions + 1) * sizeof(*region),
+   GFP_KERNEL);
+   if (!region)
+   return -ENOMEM;
+
+   vgpu->vdev.region = region;
+   vgpu->vdev.region[vgpu->vdev.num_regions].type = type;
+   vgpu->vdev.region[vgpu->vdev.num_regions].subtype = subtype;
+   vgpu->vdev.region[vgpu->vdev.num_regions].ops = ops;
+   vgpu->vdev.region[vgpu->vdev.num_regions].size = size;
+   vgpu->vdev.region[vgpu->vdev.num_regions].flags = flags;
+   vgpu->vdev.region[vgpu->vdev.num_regions].data = data;
+   vgpu->vdev.num_regions++;
+
+   return 0;
+}
+
+static int kvmgt_set_opregion(void *p_vgpu)
+{
+   struct intel_vgpu *vgpu = (struct intel_vgpu *)p_vgpu;
+   unsigned int addr;
+   void *base;
+   int ret;
+
+   addr = vgpu->gvt->opregion.opregion_pa;
+   if (!addr || !(~addr))
+   return -ENODEV;
+
+   base = memremap(addr, OPREGION_SIZE, MEMREMAP_WB);
+   if (!base)
+   return -ENOMEM;
+
+   if (memcmp(base, OPREGION_SIGNATURE, 16)) {
+   memunmap(base);
+   return -EINVAL;
+   }
+
+   ret = intel_vgpu_register_reg(vgpu,
+   PCI_VENDOR_ID_INTEL | VFIO_REGION_TYPE_PCI_VENDOR_TYPE,
+   VFIO_REGION_SUBTYPE_INTEL_IGD_OPREGION,
+   _vgpu_regops_opregion, OPREGION_SIZE,
+   VFIO_REGION_INFO_FLAG_READ, base);
+   if (ret)
+   memunmap(base);
+
+   return ret;
+}
+
 static int intel_vgpu_create(struct kobject *kobj, struct mdev_device *mdev)
 {
struct intel_vgpu *vgpu = NULL;
@@ -1524,6 +1611,7 @@ struct intel_gvt_mpt kvmgt_mpt = {
.read_gpa = kvmgt_read

[PATCH v8 1/6] drm/i915/gvt: Extend the GVT-g architecture to support vfio device region

2017-06-09 Thread Xiaoguang Chen
Signed-off-by: Xiaoguang Chen 
---
 drivers/gpu/drm/i915/gvt/kvmgt.c | 21 ++---
 1 file changed, 18 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
index 1ae0b40..3c6a02b 100644
--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
+++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
@@ -53,11 +53,21 @@ static const struct intel_gvt_ops *intel_gvt_ops;
 #define VFIO_PCI_INDEX_TO_OFFSET(index) ((u64)(index) << VFIO_PCI_OFFSET_SHIFT)
 #define VFIO_PCI_OFFSET_MASK(((u64)(1) << VFIO_PCI_OFFSET_SHIFT) - 1)
 
+struct vfio_region;
+struct intel_vgpu_regops {
+   size_t (*rw)(struct intel_vgpu *vgpu, char *buf,
+   size_t count, loff_t *ppos, bool iswrite);
+   void (*release)(struct intel_vgpu *vgpu,
+   struct vfio_region *region);
+};
+
 struct vfio_region {
u32 type;
u32 subtype;
size_t  size;
u32 flags;
+   const struct intel_vgpu_regops  *ops;
+   void*data;
 };
 
 struct kvmgt_pgfn {
@@ -642,7 +652,7 @@ static ssize_t intel_vgpu_rw(struct mdev_device *mdev, char 
*buf,
int ret = -EINVAL;
 
 
-   if (index >= VFIO_PCI_NUM_REGIONS) {
+   if (index >= VFIO_PCI_NUM_REGIONS + vgpu->vdev.num_regions) {
gvt_vgpu_err("invalid index: %u\n", index);
return -EINVAL;
}
@@ -676,8 +686,11 @@ static ssize_t intel_vgpu_rw(struct mdev_device *mdev, 
char *buf,
case VFIO_PCI_BAR5_REGION_INDEX:
case VFIO_PCI_VGA_REGION_INDEX:
case VFIO_PCI_ROM_REGION_INDEX:
+   break;
default:
-   gvt_vgpu_err("unsupported region: %u\n", index);
+   index -= VFIO_PCI_NUM_REGIONS;
+   return vgpu->vdev.region[index].ops->rw(vgpu, buf, count,
+   ppos, is_write);
}
 
return ret == 0 ? count : ret;
@@ -940,7 +953,8 @@ static long intel_vgpu_ioctl(struct mdev_device *mdev, 
unsigned int cmd,
 
info.flags = VFIO_DEVICE_FLAGS_PCI;
info.flags |= VFIO_DEVICE_FLAGS_RESET;
-   info.num_regions = VFIO_PCI_NUM_REGIONS;
+   info.num_regions = VFIO_PCI_NUM_REGIONS +
+   vgpu->vdev.num_regions;
info.num_irqs = VFIO_PCI_NUM_IRQS;
 
return copy_to_user((void __user *)arg, , minsz) ?
@@ -1061,6 +1075,7 @@ static long intel_vgpu_ioctl(struct mdev_device *mdev, 
unsigned int cmd,
}
 
if (caps.size) {
+   info.flags |= VFIO_REGION_INFO_FLAG_CAPS;
if (info.argsz < sizeof(info) + caps.size) {
info.argsz = sizeof(info) + caps.size;
info.cap_offset = 0;
-- 
2.7.4



[PATCH v8 5/6] drm/i915/gvt: Dmabuf support for GVT-g

2017-06-09 Thread Xiaoguang Chen
dmabuf for GVT-g can be exported to users who can use the dmabuf to show
the desktop of vm which use intel vgpu.

Currently we provide query and create new dmabuf operations.

Users of dmabuf can cache some created dmabufs and related information
such as the framebuffer's address, size, tiling mode, width, height etc.
When refresh the screen first query the currnet vgpu's frambuffer and
compare with the cached ones(address, size, tiling, width, height etc)
if found one then reuse the found dmabuf to gain performance improvment.

If there is no dmabuf created yet or not found in the cached dmabufs then
need to create a new dmabuf. To create a dmabuf first a gem object will
be created and the backing storage of this gem object is the vgpu's
framebuffer(primary/cursor).
Set caching mode, change tiling mode and set domains of this gem object
is not supported.
Then associate this gem object to a dmabuf and export this dmabuf.
A file descriptor will be generated for this dmabuf and this file
descriptor can be sent to user space to do display.

Signed-off-by: Xiaoguang Chen 
Tested-by: Kechen Lu 
---
 drivers/gpu/drm/i915/gvt/Makefile  |   2 +-
 drivers/gpu/drm/i915/gvt/dmabuf.c  | 263 +
 drivers/gpu/drm/i915/gvt/dmabuf.h  |  37 +
 drivers/gpu/drm/i915/gvt/gvt.h |   1 +
 drivers/gpu/drm/i915/i915_gem.c|  26 +++-
 drivers/gpu/drm/i915/i915_gem_object.h |   9 ++
 drivers/gpu/drm/i915/i915_gem_tiling.c |   5 +
 7 files changed, 341 insertions(+), 2 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/gvt/dmabuf.c
 create mode 100644 drivers/gpu/drm/i915/gvt/dmabuf.h

diff --git a/drivers/gpu/drm/i915/gvt/Makefile 
b/drivers/gpu/drm/i915/gvt/Makefile
index 192ca26..e480f7d 100644
--- a/drivers/gpu/drm/i915/gvt/Makefile
+++ b/drivers/gpu/drm/i915/gvt/Makefile
@@ -2,7 +2,7 @@ GVT_DIR := gvt
 GVT_SOURCE := gvt.o aperture_gm.o handlers.o vgpu.o trace_points.o firmware.o \
interrupt.o gtt.o cfg_space.o opregion.o mmio.o display.o edid.o \
execlist.o scheduler.o sched_policy.o render.o cmd_parser.o \
-   fb_decoder.o
+   fb_decoder.o dmabuf.o
 
 ccflags-y  += -I$(src) -I$(src)/$(GVT_DIR) -Wall
 i915-y += $(addprefix $(GVT_DIR)/, 
$(GVT_SOURCE))
diff --git a/drivers/gpu/drm/i915/gvt/dmabuf.c 
b/drivers/gpu/drm/i915/gvt/dmabuf.c
new file mode 100644
index 000..c38ed8e9fc
--- /dev/null
+++ b/drivers/gpu/drm/i915/gvt/dmabuf.c
@@ -0,0 +1,263 @@
+/*
+ * Copyright 2017 Intel Corporation. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *Zhiyuan Lv 
+ *
+ * Contributors:
+ *Xiaoguang Chen 
+ */
+
+#include 
+#include 
+#include 
+
+#include "i915_drv.h"
+#include "gvt.h"
+
+#define GEN8_DECODE_PTE(pte) (pte & GENMASK_ULL(63, 12))
+
+static struct sg_table *intel_vgpu_gem_get_pages(
+   struct drm_i915_gem_object *obj)
+{
+   struct drm_i915_private *dev_priv = to_i915(obj->base.dev);
+   struct sg_table *st;
+   struct scatterlist *sg;
+   int i, ret;
+   gen8_pte_t __iomem *gtt_entries;
+   struct intel_vgpu_fb_info *fb_info;
+
+   fb_info = (struct intel_vgpu_fb_info *)obj->gvt_info;
+   if (WARN_ON(!fb_info))
+   return ERR_PTR(-ENODEV);
+
+   st = kmalloc(sizeof(*st), GFP_KERNEL);
+   if (!st)
+   return ERR_PTR(-ENOMEM);
+
+   ret = sg_alloc_table(st, fb_info->fb_size, GFP_KERNEL);
+   if (ret) {
+   kfree(st);
+   return ERR_PTR(ret);
+   }
+   gtt_entries = (gen8_pte_t __iomem *)dev_priv->ggtt.gsm +
+   (fb_info->fb_addr >> PAGE_SHIFT);
+   for_each_sg(st->sgl, sg, fb_info->fb_size, i) {
+   sg->offset = 0;
+   sg->length = PAGE_SIZE;

[PATCH v7 2/6] drm/i915/gvt: OpRegion support for GVT-g

2017-06-07 Thread Xiaoguang Chen
OpRegion is needed to support display related operation for
intel vgpu.

A vfio device region is added to intel vgpu to deliver the
host OpRegion information to user space so user space can
construct the OpRegion for vgpu.

Signed-off-by: Bing Niu <bing@intel.com>
Signed-off-by: Xiaoguang Chen <xiaoguang.c...@intel.com>
---
 drivers/gpu/drm/i915/gvt/hypercall.h |  1 +
 drivers/gpu/drm/i915/gvt/kvmgt.c | 88 
 drivers/gpu/drm/i915/gvt/mpt.h   | 15 ++
 drivers/gpu/drm/i915/gvt/opregion.c  | 26 ---
 drivers/gpu/drm/i915/gvt/vgpu.c  |  4 ++
 5 files changed, 128 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/gvt/hypercall.h 
b/drivers/gpu/drm/i915/gvt/hypercall.h
index df7f33a..32c345c 100644
--- a/drivers/gpu/drm/i915/gvt/hypercall.h
+++ b/drivers/gpu/drm/i915/gvt/hypercall.h
@@ -55,6 +55,7 @@ struct intel_gvt_mpt {
  unsigned long mfn, unsigned int nr, bool map);
int (*set_trap_area)(unsigned long handle, u64 start, u64 end,
 bool map);
+   int (*set_opregion)(void *vgpu);
 };
 
 extern struct intel_gvt_mpt xengt_mpt;
diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
index 3c6a02b..6b4652a 100644
--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
+++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
@@ -53,6 +53,8 @@ static const struct intel_gvt_ops *intel_gvt_ops;
 #define VFIO_PCI_INDEX_TO_OFFSET(index) ((u64)(index) << VFIO_PCI_OFFSET_SHIFT)
 #define VFIO_PCI_OFFSET_MASK(((u64)(1) << VFIO_PCI_OFFSET_SHIFT) - 1)
 
+#define OPREGION_SIGNATURE "IntelGraphicsMem"
+
 struct vfio_region;
 struct intel_vgpu_regops {
size_t (*rw)(struct intel_vgpu *vgpu, char *buf,
@@ -436,6 +438,91 @@ static void kvmgt_protect_table_del(struct 
kvmgt_guest_info *info,
}
 }
 
+static size_t intel_vgpu_reg_rw_opregion(struct intel_vgpu *vgpu, char *buf,
+   size_t count, loff_t *ppos, bool iswrite)
+{
+   unsigned int i = VFIO_PCI_OFFSET_TO_INDEX(*ppos) -
+   VFIO_PCI_NUM_REGIONS;
+   void *base = vgpu->vdev.region[i].data;
+   loff_t pos = *ppos & VFIO_PCI_OFFSET_MASK;
+
+   if (pos >= vgpu->vdev.region[i].size || iswrite) {
+   gvt_vgpu_err("invalid op or offset for Intel vgpu OpRegion\n");
+   return -EINVAL;
+   }
+   count = min(count, (size_t)(vgpu->vdev.region[i].size - pos));
+   memcpy(buf, base + pos, count);
+
+   return count;
+}
+
+static void intel_vgpu_reg_release_opregion(struct intel_vgpu *vgpu,
+   struct vfio_region *region)
+{
+   memunmap(region->data);
+}
+
+static const struct intel_vgpu_regops intel_vgpu_regops_opregion = {
+   .rw = intel_vgpu_reg_rw_opregion,
+   .release = intel_vgpu_reg_release_opregion,
+};
+
+static int intel_vgpu_register_reg(struct intel_vgpu *vgpu,
+   unsigned int type, unsigned int subtype,
+   const struct intel_vgpu_regops *ops,
+   size_t size, u32 flags, void *data)
+{
+   struct vfio_region *region;
+
+   region = krealloc(vgpu->vdev.region,
+   (vgpu->vdev.num_regions + 1) * sizeof(*region),
+   GFP_KERNEL);
+   if (!region)
+   return -ENOMEM;
+
+   vgpu->vdev.region = region;
+   vgpu->vdev.region[vgpu->vdev.num_regions].type = type;
+   vgpu->vdev.region[vgpu->vdev.num_regions].subtype = subtype;
+   vgpu->vdev.region[vgpu->vdev.num_regions].ops = ops;
+   vgpu->vdev.region[vgpu->vdev.num_regions].size = size;
+   vgpu->vdev.region[vgpu->vdev.num_regions].flags = flags;
+   vgpu->vdev.region[vgpu->vdev.num_regions].data = data;
+   vgpu->vdev.num_regions++;
+
+   return 0;
+}
+
+static int kvmgt_set_opregion(void *p_vgpu)
+{
+   struct intel_vgpu *vgpu = (struct intel_vgpu *)p_vgpu;
+   unsigned int addr;
+   void *base;
+   int ret;
+
+   addr = vgpu->gvt->opregion.opregion_pa;
+   if (!addr || !(~addr))
+   return -ENODEV;
+
+   base = memremap(addr, OPREGION_SIZE, MEMREMAP_WB);
+   if (!base)
+   return -ENOMEM;
+
+   if (memcmp(base, OPREGION_SIGNATURE, 16)) {
+   memunmap(base);
+   return -EINVAL;
+   }
+
+   ret = intel_vgpu_register_reg(vgpu,
+   PCI_VENDOR_ID_INTEL | VFIO_REGION_TYPE_PCI_VENDOR_TYPE,
+   VFIO_REGION_SUBTYPE_INTEL_IGD_OPREGION,
+   _vgpu_regops_opregion, OPREGION_SIZE,
+   VFIO_REGION_INFO_FLAG_READ, base);
+   if (ret)
+   memunmap(base);
+
+   return ret;
+}
+
 static int intel_vgpu_create(struct kobject *kobj, struct mdev_device *mdev)
 {
struct intel_vgpu *vgpu = NULL;
@@ -1524,6 +1611,7 @@ struct inte

[PATCH v7 2/6] drm/i915/gvt: OpRegion support for GVT-g

2017-06-07 Thread Xiaoguang Chen
OpRegion is needed to support display related operation for
intel vgpu.

A vfio device region is added to intel vgpu to deliver the
host OpRegion information to user space so user space can
construct the OpRegion for vgpu.

Signed-off-by: Bing Niu 
Signed-off-by: Xiaoguang Chen 
---
 drivers/gpu/drm/i915/gvt/hypercall.h |  1 +
 drivers/gpu/drm/i915/gvt/kvmgt.c | 88 
 drivers/gpu/drm/i915/gvt/mpt.h   | 15 ++
 drivers/gpu/drm/i915/gvt/opregion.c  | 26 ---
 drivers/gpu/drm/i915/gvt/vgpu.c  |  4 ++
 5 files changed, 128 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/gvt/hypercall.h 
b/drivers/gpu/drm/i915/gvt/hypercall.h
index df7f33a..32c345c 100644
--- a/drivers/gpu/drm/i915/gvt/hypercall.h
+++ b/drivers/gpu/drm/i915/gvt/hypercall.h
@@ -55,6 +55,7 @@ struct intel_gvt_mpt {
  unsigned long mfn, unsigned int nr, bool map);
int (*set_trap_area)(unsigned long handle, u64 start, u64 end,
 bool map);
+   int (*set_opregion)(void *vgpu);
 };
 
 extern struct intel_gvt_mpt xengt_mpt;
diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
index 3c6a02b..6b4652a 100644
--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
+++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
@@ -53,6 +53,8 @@ static const struct intel_gvt_ops *intel_gvt_ops;
 #define VFIO_PCI_INDEX_TO_OFFSET(index) ((u64)(index) << VFIO_PCI_OFFSET_SHIFT)
 #define VFIO_PCI_OFFSET_MASK(((u64)(1) << VFIO_PCI_OFFSET_SHIFT) - 1)
 
+#define OPREGION_SIGNATURE "IntelGraphicsMem"
+
 struct vfio_region;
 struct intel_vgpu_regops {
size_t (*rw)(struct intel_vgpu *vgpu, char *buf,
@@ -436,6 +438,91 @@ static void kvmgt_protect_table_del(struct 
kvmgt_guest_info *info,
}
 }
 
+static size_t intel_vgpu_reg_rw_opregion(struct intel_vgpu *vgpu, char *buf,
+   size_t count, loff_t *ppos, bool iswrite)
+{
+   unsigned int i = VFIO_PCI_OFFSET_TO_INDEX(*ppos) -
+   VFIO_PCI_NUM_REGIONS;
+   void *base = vgpu->vdev.region[i].data;
+   loff_t pos = *ppos & VFIO_PCI_OFFSET_MASK;
+
+   if (pos >= vgpu->vdev.region[i].size || iswrite) {
+   gvt_vgpu_err("invalid op or offset for Intel vgpu OpRegion\n");
+   return -EINVAL;
+   }
+   count = min(count, (size_t)(vgpu->vdev.region[i].size - pos));
+   memcpy(buf, base + pos, count);
+
+   return count;
+}
+
+static void intel_vgpu_reg_release_opregion(struct intel_vgpu *vgpu,
+   struct vfio_region *region)
+{
+   memunmap(region->data);
+}
+
+static const struct intel_vgpu_regops intel_vgpu_regops_opregion = {
+   .rw = intel_vgpu_reg_rw_opregion,
+   .release = intel_vgpu_reg_release_opregion,
+};
+
+static int intel_vgpu_register_reg(struct intel_vgpu *vgpu,
+   unsigned int type, unsigned int subtype,
+   const struct intel_vgpu_regops *ops,
+   size_t size, u32 flags, void *data)
+{
+   struct vfio_region *region;
+
+   region = krealloc(vgpu->vdev.region,
+   (vgpu->vdev.num_regions + 1) * sizeof(*region),
+   GFP_KERNEL);
+   if (!region)
+   return -ENOMEM;
+
+   vgpu->vdev.region = region;
+   vgpu->vdev.region[vgpu->vdev.num_regions].type = type;
+   vgpu->vdev.region[vgpu->vdev.num_regions].subtype = subtype;
+   vgpu->vdev.region[vgpu->vdev.num_regions].ops = ops;
+   vgpu->vdev.region[vgpu->vdev.num_regions].size = size;
+   vgpu->vdev.region[vgpu->vdev.num_regions].flags = flags;
+   vgpu->vdev.region[vgpu->vdev.num_regions].data = data;
+   vgpu->vdev.num_regions++;
+
+   return 0;
+}
+
+static int kvmgt_set_opregion(void *p_vgpu)
+{
+   struct intel_vgpu *vgpu = (struct intel_vgpu *)p_vgpu;
+   unsigned int addr;
+   void *base;
+   int ret;
+
+   addr = vgpu->gvt->opregion.opregion_pa;
+   if (!addr || !(~addr))
+   return -ENODEV;
+
+   base = memremap(addr, OPREGION_SIZE, MEMREMAP_WB);
+   if (!base)
+   return -ENOMEM;
+
+   if (memcmp(base, OPREGION_SIGNATURE, 16)) {
+   memunmap(base);
+   return -EINVAL;
+   }
+
+   ret = intel_vgpu_register_reg(vgpu,
+   PCI_VENDOR_ID_INTEL | VFIO_REGION_TYPE_PCI_VENDOR_TYPE,
+   VFIO_REGION_SUBTYPE_INTEL_IGD_OPREGION,
+   _vgpu_regops_opregion, OPREGION_SIZE,
+   VFIO_REGION_INFO_FLAG_READ, base);
+   if (ret)
+   memunmap(base);
+
+   return ret;
+}
+
 static int intel_vgpu_create(struct kobject *kobj, struct mdev_device *mdev)
 {
struct intel_vgpu *vgpu = NULL;
@@ -1524,6 +1611,7 @@ struct intel_gvt_mpt kvmgt_mpt = {
.read_gpa = kvmgt_read

[PATCH v7 0/6] drm/i915/gvt: Dma-buf support for GVT-g

2017-06-07 Thread Xiaoguang Chen
v6->v7:
1) release dma-buf related allocations in dma-buf's associated release
function.
2) refine ioctl interface for querying plane info or create dma-buf
3) refine framebuffer decoder code
4) the patch series is based on 4.12.0-rc1

v5->v6:
1) align the dma-buf life cycle with the vfio device.
2) add the dma-buf releated operations in a separate patch.
3) i915 releated changes.

v4->v5:
1) fix bug while checking whether the gem obj is gvt's dma-buf when user
change caching mode or domains. Add a helper function to do it.
2) add definition for the query plane and create dma-buf.

v3->v4:
1) fix bug while checking whether the gem obj is gvt's dma-buf when set
caching mode or doamins.

v2->v3:
1) add a field gvt_plane_info in the drm_i915_gem_obj structure to save
the decoded plane information to avoid look up while need the plane info.
2) declare a new flag I915_GEM_OBJECT_IS_GVT_DMABUF in drm_i915_gem_object
to represent the gem obj for gvt's dma-buf. The tiling mode, caching mode
and domains can not be changed for this kind of gem object.
3) change dma-buf related information to be more generic. So other vendor
can use the same interface.

v1->v2:
1) create a management fd for dma-buf operations.
2) alloc gem object's backing storage in gem obj's get_pages() callback.

This patch set adds the dma-buf support for intel GVT-g.
dma-buf is a uniform mechanism to share DMA buffers across different
devices and sub-systems.
dma-buf for intel GVT-g is mainly used to share the vgpu's framebuffer
to other users or sub-systems so they can use the dma-buf to show the
desktop of a vm which uses intel vgpu.

The main idea is we create a gem object and set vgpu's framebuffer as
the backing storage of this gem object. And associate this gem obj
to a dma-buf object then export this dma-buf at the meantime
generate a file descriptor for this dma-buf. Finally deliver this file
descriptor to user space. And user can use this dma-buf fd to do render
or other operations.
User need to create a fd(for intel GVT-g dma-buf support it is a:dma-buf
management fd) then user can use this fd to query the plane information
or create a dma-buf. The life cycle of this fd is managed by GVT-g user
do not need to care about that.

We have an example program on how to use the dma-buf. You can download
the program to have a try. Good luck :)
git repo: https://github.com/01org/igvtg-qemu branch:kvmgt_dmabuf_example

Xiaoguang Chen (6):
  drm/i915/gvt: Extend the GVT-g architecture to support vfio device
region
  drm/i915/gvt: OpRegion support for GVT-g
  drm/i915/gvt: Frame buffer decoder support for GVT-g
  vfio: Define vfio based vgpu's dma-buf operations
  drm/i915/gvt: Dmabuf support for GVT-g
  drm/i915/gvt: Adding user interface for dma-buf

 drivers/gpu/drm/i915/gvt/Makefile  |   3 +-
 drivers/gpu/drm/i915/gvt/display.c |   2 +-
 drivers/gpu/drm/i915/gvt/display.h |   2 +
 drivers/gpu/drm/i915/gvt/dmabuf.c  | 308 +++
 drivers/gpu/drm/i915/gvt/dmabuf.h  |  42 
 drivers/gpu/drm/i915/gvt/fb_decoder.c  | 439 +
 drivers/gpu/drm/i915/gvt/fb_decoder.h  | 167 +
 drivers/gpu/drm/i915/gvt/gvt.c |   3 +
 drivers/gpu/drm/i915/gvt/gvt.h |   7 +
 drivers/gpu/drm/i915/gvt/hypercall.h   |   4 +
 drivers/gpu/drm/i915/gvt/kvmgt.c   | 258 ++-
 drivers/gpu/drm/i915/gvt/mpt.h |  45 
 drivers/gpu/drm/i915/gvt/opregion.c|  26 +-
 drivers/gpu/drm/i915/gvt/vgpu.c|   6 +
 drivers/gpu/drm/i915/i915_gem.c|  26 +-
 drivers/gpu/drm/i915/i915_gem_object.h |   9 +
 drivers/gpu/drm/i915/i915_gem_tiling.c |   5 +
 include/uapi/drm/drm_fourcc.h  |   6 +
 include/uapi/linux/vfio.h  |  58 +
 19 files changed, 1404 insertions(+), 12 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/gvt/dmabuf.c
 create mode 100644 drivers/gpu/drm/i915/gvt/dmabuf.h
 create mode 100644 drivers/gpu/drm/i915/gvt/fb_decoder.c
 create mode 100644 drivers/gpu/drm/i915/gvt/fb_decoder.h

-- 
2.7.4



[PATCH v7 0/6] drm/i915/gvt: Dma-buf support for GVT-g

2017-06-07 Thread Xiaoguang Chen
v6->v7:
1) release dma-buf related allocations in dma-buf's associated release
function.
2) refine ioctl interface for querying plane info or create dma-buf
3) refine framebuffer decoder code
4) the patch series is based on 4.12.0-rc1

v5->v6:
1) align the dma-buf life cycle with the vfio device.
2) add the dma-buf releated operations in a separate patch.
3) i915 releated changes.

v4->v5:
1) fix bug while checking whether the gem obj is gvt's dma-buf when user
change caching mode or domains. Add a helper function to do it.
2) add definition for the query plane and create dma-buf.

v3->v4:
1) fix bug while checking whether the gem obj is gvt's dma-buf when set
caching mode or doamins.

v2->v3:
1) add a field gvt_plane_info in the drm_i915_gem_obj structure to save
the decoded plane information to avoid look up while need the plane info.
2) declare a new flag I915_GEM_OBJECT_IS_GVT_DMABUF in drm_i915_gem_object
to represent the gem obj for gvt's dma-buf. The tiling mode, caching mode
and domains can not be changed for this kind of gem object.
3) change dma-buf related information to be more generic. So other vendor
can use the same interface.

v1->v2:
1) create a management fd for dma-buf operations.
2) alloc gem object's backing storage in gem obj's get_pages() callback.

This patch set adds the dma-buf support for intel GVT-g.
dma-buf is a uniform mechanism to share DMA buffers across different
devices and sub-systems.
dma-buf for intel GVT-g is mainly used to share the vgpu's framebuffer
to other users or sub-systems so they can use the dma-buf to show the
desktop of a vm which uses intel vgpu.

The main idea is we create a gem object and set vgpu's framebuffer as
the backing storage of this gem object. And associate this gem obj
to a dma-buf object then export this dma-buf at the meantime
generate a file descriptor for this dma-buf. Finally deliver this file
descriptor to user space. And user can use this dma-buf fd to do render
or other operations.
User need to create a fd(for intel GVT-g dma-buf support it is a:dma-buf
management fd) then user can use this fd to query the plane information
or create a dma-buf. The life cycle of this fd is managed by GVT-g user
do not need to care about that.

We have an example program on how to use the dma-buf. You can download
the program to have a try. Good luck :)
git repo: https://github.com/01org/igvtg-qemu branch:kvmgt_dmabuf_example

Xiaoguang Chen (6):
  drm/i915/gvt: Extend the GVT-g architecture to support vfio device
region
  drm/i915/gvt: OpRegion support for GVT-g
  drm/i915/gvt: Frame buffer decoder support for GVT-g
  vfio: Define vfio based vgpu's dma-buf operations
  drm/i915/gvt: Dmabuf support for GVT-g
  drm/i915/gvt: Adding user interface for dma-buf

 drivers/gpu/drm/i915/gvt/Makefile  |   3 +-
 drivers/gpu/drm/i915/gvt/display.c |   2 +-
 drivers/gpu/drm/i915/gvt/display.h |   2 +
 drivers/gpu/drm/i915/gvt/dmabuf.c  | 308 +++
 drivers/gpu/drm/i915/gvt/dmabuf.h  |  42 
 drivers/gpu/drm/i915/gvt/fb_decoder.c  | 439 +
 drivers/gpu/drm/i915/gvt/fb_decoder.h  | 167 +
 drivers/gpu/drm/i915/gvt/gvt.c |   3 +
 drivers/gpu/drm/i915/gvt/gvt.h |   7 +
 drivers/gpu/drm/i915/gvt/hypercall.h   |   4 +
 drivers/gpu/drm/i915/gvt/kvmgt.c   | 258 ++-
 drivers/gpu/drm/i915/gvt/mpt.h |  45 
 drivers/gpu/drm/i915/gvt/opregion.c|  26 +-
 drivers/gpu/drm/i915/gvt/vgpu.c|   6 +
 drivers/gpu/drm/i915/i915_gem.c|  26 +-
 drivers/gpu/drm/i915/i915_gem_object.h |   9 +
 drivers/gpu/drm/i915/i915_gem_tiling.c |   5 +
 include/uapi/drm/drm_fourcc.h  |   6 +
 include/uapi/linux/vfio.h  |  58 +
 19 files changed, 1404 insertions(+), 12 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/gvt/dmabuf.c
 create mode 100644 drivers/gpu/drm/i915/gvt/dmabuf.h
 create mode 100644 drivers/gpu/drm/i915/gvt/fb_decoder.c
 create mode 100644 drivers/gpu/drm/i915/gvt/fb_decoder.h

-- 
2.7.4



[PATCH v7 3/6] drm/i915/gvt: Frame buffer decoder support for GVT-g

2017-06-07 Thread Xiaoguang Chen
decode frambuffer attributes of primary, cursor and sprite plane

Signed-off-by: Xiaoguang Chen <xiaoguang.c...@intel.com>
---
 drivers/gpu/drm/i915/gvt/Makefile |   3 +-
 drivers/gpu/drm/i915/gvt/display.c|   2 +-
 drivers/gpu/drm/i915/gvt/display.h|   2 +
 drivers/gpu/drm/i915/gvt/fb_decoder.c | 439 ++
 drivers/gpu/drm/i915/gvt/fb_decoder.h | 167 +
 drivers/gpu/drm/i915/gvt/gvt.h|   1 +
 include/uapi/drm/drm_fourcc.h |   6 +
 7 files changed, 618 insertions(+), 2 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/gvt/fb_decoder.c
 create mode 100644 drivers/gpu/drm/i915/gvt/fb_decoder.h

diff --git a/drivers/gpu/drm/i915/gvt/Makefile 
b/drivers/gpu/drm/i915/gvt/Makefile
index b123c20..192ca26 100644
--- a/drivers/gpu/drm/i915/gvt/Makefile
+++ b/drivers/gpu/drm/i915/gvt/Makefile
@@ -1,7 +1,8 @@
 GVT_DIR := gvt
 GVT_SOURCE := gvt.o aperture_gm.o handlers.o vgpu.o trace_points.o firmware.o \
interrupt.o gtt.o cfg_space.o opregion.o mmio.o display.o edid.o \
-   execlist.o scheduler.o sched_policy.o render.o cmd_parser.o
+   execlist.o scheduler.o sched_policy.o render.o cmd_parser.o \
+   fb_decoder.o
 
 ccflags-y  += -I$(src) -I$(src)/$(GVT_DIR) -Wall
 i915-y += $(addprefix $(GVT_DIR)/, 
$(GVT_SOURCE))
diff --git a/drivers/gpu/drm/i915/gvt/display.c 
b/drivers/gpu/drm/i915/gvt/display.c
index e0261fc..f5f63c5 100644
--- a/drivers/gpu/drm/i915/gvt/display.c
+++ b/drivers/gpu/drm/i915/gvt/display.c
@@ -67,7 +67,7 @@ static int edp_pipe_is_enabled(struct intel_vgpu *vgpu)
return 1;
 }
 
-static int pipe_is_enabled(struct intel_vgpu *vgpu, int pipe)
+int pipe_is_enabled(struct intel_vgpu *vgpu, int pipe)
 {
struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv;
 
diff --git a/drivers/gpu/drm/i915/gvt/display.h 
b/drivers/gpu/drm/i915/gvt/display.h
index d73de22..b46b868 100644
--- a/drivers/gpu/drm/i915/gvt/display.h
+++ b/drivers/gpu/drm/i915/gvt/display.h
@@ -179,4 +179,6 @@ int intel_vgpu_init_display(struct intel_vgpu *vgpu, u64 
resolution);
 void intel_vgpu_reset_display(struct intel_vgpu *vgpu);
 void intel_vgpu_clean_display(struct intel_vgpu *vgpu);
 
+int pipe_is_enabled(struct intel_vgpu *vgpu, int pipe);
+
 #endif
diff --git a/drivers/gpu/drm/i915/gvt/fb_decoder.c 
b/drivers/gpu/drm/i915/gvt/fb_decoder.c
new file mode 100644
index 000..0825949
--- /dev/null
+++ b/drivers/gpu/drm/i915/gvt/fb_decoder.c
@@ -0,0 +1,439 @@
+/*
+ * Copyright(c) 2011-2016 Intel Corporation. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 
THE
+ * SOFTWARE.
+ *
+ * Authors:
+ *Kevin Tian <kevin.t...@intel.com>
+ *
+ * Contributors:
+ *Bing Niu <bing@intel.com>
+ *Xu Han <xu@intel.com>
+ *    Ping Gao <ping.a@intel.com>
+ *Xiaoguang Chen <xiaoguang.c...@intel.com>
+ *Yang Liu <yang2@intel.com>
+ *
+ */
+
+#include 
+#include "i915_drv.h"
+#include "gvt.h"
+
+#define PRIMARY_FORMAT_NUM 16
+struct pixel_format {
+   int drm_format; /* Pixel format in DRM definition */
+   int bpp;/* Bits per pixel, 0 indicates invalid */
+   char *desc; /* The description */
+};
+
+/* non-supported format has bpp default to 0 */
+static struct pixel_format bdw_pixel_formats[PRIMARY_FORMAT_NUM] = {
+   [0x2] = {DRM_FORMAT_C8, 8, "8-bit Indexed"},
+   [0x5] = {DRM_FORMAT_RGB565, 16, "16-bit BGRX (5:6:5 MSB-R:G:B)"},
+   [0x6] = {DRM_FORMAT_XRGB, 32,
+   "32-bit BGRX (8:8:8:8 MSB-X:R:G:B)"},
+   [0x8] = {DRM_FORMAT_XBGR2101010, 32,
+   "32-bit RGBX (2:10:10:10 MSB-X:B:G:R)"},
+   [0xa] = {DRM_FORMAT_XRGB2101010, 32,
+   "32-bit BGR

[PATCH v7 3/6] drm/i915/gvt: Frame buffer decoder support for GVT-g

2017-06-07 Thread Xiaoguang Chen
decode frambuffer attributes of primary, cursor and sprite plane

Signed-off-by: Xiaoguang Chen 
---
 drivers/gpu/drm/i915/gvt/Makefile |   3 +-
 drivers/gpu/drm/i915/gvt/display.c|   2 +-
 drivers/gpu/drm/i915/gvt/display.h|   2 +
 drivers/gpu/drm/i915/gvt/fb_decoder.c | 439 ++
 drivers/gpu/drm/i915/gvt/fb_decoder.h | 167 +
 drivers/gpu/drm/i915/gvt/gvt.h|   1 +
 include/uapi/drm/drm_fourcc.h |   6 +
 7 files changed, 618 insertions(+), 2 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/gvt/fb_decoder.c
 create mode 100644 drivers/gpu/drm/i915/gvt/fb_decoder.h

diff --git a/drivers/gpu/drm/i915/gvt/Makefile 
b/drivers/gpu/drm/i915/gvt/Makefile
index b123c20..192ca26 100644
--- a/drivers/gpu/drm/i915/gvt/Makefile
+++ b/drivers/gpu/drm/i915/gvt/Makefile
@@ -1,7 +1,8 @@
 GVT_DIR := gvt
 GVT_SOURCE := gvt.o aperture_gm.o handlers.o vgpu.o trace_points.o firmware.o \
interrupt.o gtt.o cfg_space.o opregion.o mmio.o display.o edid.o \
-   execlist.o scheduler.o sched_policy.o render.o cmd_parser.o
+   execlist.o scheduler.o sched_policy.o render.o cmd_parser.o \
+   fb_decoder.o
 
 ccflags-y  += -I$(src) -I$(src)/$(GVT_DIR) -Wall
 i915-y += $(addprefix $(GVT_DIR)/, 
$(GVT_SOURCE))
diff --git a/drivers/gpu/drm/i915/gvt/display.c 
b/drivers/gpu/drm/i915/gvt/display.c
index e0261fc..f5f63c5 100644
--- a/drivers/gpu/drm/i915/gvt/display.c
+++ b/drivers/gpu/drm/i915/gvt/display.c
@@ -67,7 +67,7 @@ static int edp_pipe_is_enabled(struct intel_vgpu *vgpu)
return 1;
 }
 
-static int pipe_is_enabled(struct intel_vgpu *vgpu, int pipe)
+int pipe_is_enabled(struct intel_vgpu *vgpu, int pipe)
 {
struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv;
 
diff --git a/drivers/gpu/drm/i915/gvt/display.h 
b/drivers/gpu/drm/i915/gvt/display.h
index d73de22..b46b868 100644
--- a/drivers/gpu/drm/i915/gvt/display.h
+++ b/drivers/gpu/drm/i915/gvt/display.h
@@ -179,4 +179,6 @@ int intel_vgpu_init_display(struct intel_vgpu *vgpu, u64 
resolution);
 void intel_vgpu_reset_display(struct intel_vgpu *vgpu);
 void intel_vgpu_clean_display(struct intel_vgpu *vgpu);
 
+int pipe_is_enabled(struct intel_vgpu *vgpu, int pipe);
+
 #endif
diff --git a/drivers/gpu/drm/i915/gvt/fb_decoder.c 
b/drivers/gpu/drm/i915/gvt/fb_decoder.c
new file mode 100644
index 000..0825949
--- /dev/null
+++ b/drivers/gpu/drm/i915/gvt/fb_decoder.c
@@ -0,0 +1,439 @@
+/*
+ * Copyright(c) 2011-2016 Intel Corporation. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 
THE
+ * SOFTWARE.
+ *
+ * Authors:
+ *Kevin Tian 
+ *
+ * Contributors:
+ *Bing Niu 
+ *Xu Han 
+ *Ping Gao 
+ *Xiaoguang Chen 
+ *Yang Liu 
+ *
+ */
+
+#include 
+#include "i915_drv.h"
+#include "gvt.h"
+
+#define PRIMARY_FORMAT_NUM 16
+struct pixel_format {
+   int drm_format; /* Pixel format in DRM definition */
+   int bpp;/* Bits per pixel, 0 indicates invalid */
+   char *desc; /* The description */
+};
+
+/* non-supported format has bpp default to 0 */
+static struct pixel_format bdw_pixel_formats[PRIMARY_FORMAT_NUM] = {
+   [0x2] = {DRM_FORMAT_C8, 8, "8-bit Indexed"},
+   [0x5] = {DRM_FORMAT_RGB565, 16, "16-bit BGRX (5:6:5 MSB-R:G:B)"},
+   [0x6] = {DRM_FORMAT_XRGB, 32,
+   "32-bit BGRX (8:8:8:8 MSB-X:R:G:B)"},
+   [0x8] = {DRM_FORMAT_XBGR2101010, 32,
+   "32-bit RGBX (2:10:10:10 MSB-X:B:G:R)"},
+   [0xa] = {DRM_FORMAT_XRGB2101010, 32,
+   "32-bit BGRX (2:10:10:10 MSB-X:R:G:B)"},
+   [0xc] = {DRM_FORMAT_XRGB161616_GVT, 64,
+   "64-bit RGBX Floating Point(16:16:16:16 MSB-X:B:G:R)"},
+   [0xe] = {DRM_FORMAT_

[PATCH v7 4/6] vfio: Define vfio based vgpu's dma-buf operations

2017-06-07 Thread Xiaoguang Chen
Here we defined a new ioctl to create a fd for a vfio device based on
the input type. Now only one type is supported that is a dma-buf
management fd.
Two ioctls are defined for the dma-buf management fd: query the vfio
vgpu's plane information and create a dma-buf for a plane.

Signed-off-by: Xiaoguang Chen <xiaoguang.c...@intel.com>
---
 include/uapi/linux/vfio.h | 58 +++
 1 file changed, 58 insertions(+)

diff --git a/include/uapi/linux/vfio.h b/include/uapi/linux/vfio.h
index ae46105..24427b7 100644
--- a/include/uapi/linux/vfio.h
+++ b/include/uapi/linux/vfio.h
@@ -502,6 +502,64 @@ struct vfio_pci_hot_reset {
 
 #define VFIO_DEVICE_PCI_HOT_RESET  _IO(VFIO_TYPE, VFIO_BASE + 13)
 
+/**
+ * VFIO_DEVICE_GET_FD - _IO(VFIO_TYPE, VFIO_BASE + 14, __u32)
+ *
+ * Create a fd for a vfio device based on the input type
+ * Vendor driver should handle this ioctl to create a fd and manage the
+ * life cycle of this fd.
+ *
+ * Return: a fd if vendor support that type, -errno if not supported
+ */
+
+#define VFIO_DEVICE_GET_FD _IO(VFIO_TYPE, VFIO_BASE + 14)
+
+struct vfio_vgpu_plane_info {
+   __u64 start;
+   __u64 drm_format_mod;
+   __u32 drm_format;
+   __u32 width;
+   __u32 height;
+   __u32 stride;
+   __u32 size;
+   __u32 x_pos;
+   __u32 y_pos;
+   __u32 padding;
+};
+
+#define VFIO_DEVICE_DMABUF_MGR_FD  0 /* Supported fd types */
+
+/*
+ * VFIO_DEVICE_QUERY_PLANE - _IO(VFIO_TYPE, VFIO_BASE + 15,
+ * struct vfio_vgpu_query_plane)
+ * Query plane information
+ */
+struct vfio_vgpu_query_plane {
+   __u32 argsz;
+   __u32 flags;
+   struct vfio_vgpu_plane_info plane_info;
+   __u32 plane_id;
+   __u32 padding;
+};
+
+#define VFIO_DEVICE_QUERY_PLANE _IO(VFIO_TYPE, VFIO_BASE + 15)
+
+/*
+ * VFIO_DEVICE_CREATE_DMABUF - _IO(VFIO, VFIO_BASE + 16,
+ * struct vfio_vgpu_create_dmabuf)
+ *
+ * Create a dma-buf for a plane
+ */
+struct vfio_vgpu_create_dmabuf {
+   __u32 argsz;
+   __u32 flags;
+   struct vfio_vgpu_plane_info plane_info;
+   __s32 fd;
+   __u32 plane_id;
+};
+
+#define VFIO_DEVICE_CREATE_DMABUF _IO(VFIO_TYPE, VFIO_BASE + 16)
+
 /*  API for Type1 VFIO IOMMU  */
 
 /**
-- 
2.7.4



[PATCH v7 5/6] drm/i915/gvt: Dmabuf support for GVT-g

2017-06-07 Thread Xiaoguang Chen
dmabuf for GVT-g can be exported to users who can use the dmabuf to show
the desktop of vm which use intel vgpu.

Currently we provide query and create new dmabuf operations.

Users of dmabuf can cache some created dmabufs and related information
such as the framebuffer's address, size, tiling mode, width, height etc.
When refresh the screen first query the currnet vgpu's frambuffer and
compare with the cached ones(address, size, tiling, width, height etc)
if found one then reuse the found dmabuf to gain performance improvment.

If there is no dmabuf created yet or not found in the cached dmabufs then
need to create a new dmabuf. To create a dmabuf first a gem object will
be created and the backing storage of this gem object is the vgpu's
framebuffer(primary/cursor).
Set caching mode, change tiling mode and set domains of this gem object
is not supported.
Then associate this gem object to a dmabuf and export this dmabuf.
A file descriptor will be generated for this dmabuf and this file
descriptor can be sent to user space to do display.

Signed-off-by: Xiaoguang Chen <xiaoguang.c...@intel.com>
---
 drivers/gpu/drm/i915/gvt/Makefile  |   2 +-
 drivers/gpu/drm/i915/gvt/dmabuf.c  | 273 +
 drivers/gpu/drm/i915/gvt/dmabuf.h  |  37 +
 drivers/gpu/drm/i915/gvt/gvt.h |   1 +
 drivers/gpu/drm/i915/i915_gem.c|  26 +++-
 drivers/gpu/drm/i915/i915_gem_object.h |   9 ++
 drivers/gpu/drm/i915/i915_gem_tiling.c |   5 +
 7 files changed, 351 insertions(+), 2 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/gvt/dmabuf.c
 create mode 100644 drivers/gpu/drm/i915/gvt/dmabuf.h

diff --git a/drivers/gpu/drm/i915/gvt/Makefile 
b/drivers/gpu/drm/i915/gvt/Makefile
index 192ca26..e480f7d 100644
--- a/drivers/gpu/drm/i915/gvt/Makefile
+++ b/drivers/gpu/drm/i915/gvt/Makefile
@@ -2,7 +2,7 @@ GVT_DIR := gvt
 GVT_SOURCE := gvt.o aperture_gm.o handlers.o vgpu.o trace_points.o firmware.o \
interrupt.o gtt.o cfg_space.o opregion.o mmio.o display.o edid.o \
execlist.o scheduler.o sched_policy.o render.o cmd_parser.o \
-   fb_decoder.o
+   fb_decoder.o dmabuf.o
 
 ccflags-y  += -I$(src) -I$(src)/$(GVT_DIR) -Wall
 i915-y += $(addprefix $(GVT_DIR)/, 
$(GVT_SOURCE))
diff --git a/drivers/gpu/drm/i915/gvt/dmabuf.c 
b/drivers/gpu/drm/i915/gvt/dmabuf.c
new file mode 100644
index 000..411165da
--- /dev/null
+++ b/drivers/gpu/drm/i915/gvt/dmabuf.c
@@ -0,0 +1,273 @@
+/*
+ * Copyright 2017 Intel Corporation. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *Zhiyuan Lv <zhiyuan...@intel.com>
+ *
+ * Contributors:
+ *Xiaoguang Chen <xiaoguang.c...@intel.com>
+ */
+
+#include 
+#include 
+#include 
+
+#include "i915_drv.h"
+#include "gvt.h"
+
+#define GEN8_DECODE_PTE(pte) (pte & GENMASK_ULL(63, 12))
+
+static struct sg_table *intel_vgpu_gem_get_pages(
+   struct drm_i915_gem_object *obj)
+{
+   struct drm_i915_private *dev_priv = to_i915(obj->base.dev);
+   struct sg_table *st;
+   struct scatterlist *sg;
+   int i, ret;
+   gen8_pte_t __iomem *gtt_entries;
+   struct intel_vgpu_fb_info *fb_info;
+
+   fb_info = (struct intel_vgpu_fb_info *)obj->gvt_info;
+   if (WARN_ON(!fb_info))
+   return ERR_PTR(-ENODEV);
+
+   st = kmalloc(sizeof(*st), GFP_KERNEL);
+   if (!st)
+   return ERR_PTR(-ENOMEM);
+
+   ret = sg_alloc_table(st, fb_info->fb_size, GFP_KERNEL);
+   if (ret) {
+   kfree(st);
+   return ERR_PTR(ret);
+   }
+   gtt_entries = (gen8_pte_t __iomem *)dev_priv->ggtt.gsm +
+   (fb_info->fb_addr >> PAGE_SHIFT);
+   for_each_sg(st->sgl, sg, fb_info->fb_size, i) {
+

[PATCH v7 4/6] vfio: Define vfio based vgpu's dma-buf operations

2017-06-07 Thread Xiaoguang Chen
Here we defined a new ioctl to create a fd for a vfio device based on
the input type. Now only one type is supported that is a dma-buf
management fd.
Two ioctls are defined for the dma-buf management fd: query the vfio
vgpu's plane information and create a dma-buf for a plane.

Signed-off-by: Xiaoguang Chen 
---
 include/uapi/linux/vfio.h | 58 +++
 1 file changed, 58 insertions(+)

diff --git a/include/uapi/linux/vfio.h b/include/uapi/linux/vfio.h
index ae46105..24427b7 100644
--- a/include/uapi/linux/vfio.h
+++ b/include/uapi/linux/vfio.h
@@ -502,6 +502,64 @@ struct vfio_pci_hot_reset {
 
 #define VFIO_DEVICE_PCI_HOT_RESET  _IO(VFIO_TYPE, VFIO_BASE + 13)
 
+/**
+ * VFIO_DEVICE_GET_FD - _IO(VFIO_TYPE, VFIO_BASE + 14, __u32)
+ *
+ * Create a fd for a vfio device based on the input type
+ * Vendor driver should handle this ioctl to create a fd and manage the
+ * life cycle of this fd.
+ *
+ * Return: a fd if vendor support that type, -errno if not supported
+ */
+
+#define VFIO_DEVICE_GET_FD _IO(VFIO_TYPE, VFIO_BASE + 14)
+
+struct vfio_vgpu_plane_info {
+   __u64 start;
+   __u64 drm_format_mod;
+   __u32 drm_format;
+   __u32 width;
+   __u32 height;
+   __u32 stride;
+   __u32 size;
+   __u32 x_pos;
+   __u32 y_pos;
+   __u32 padding;
+};
+
+#define VFIO_DEVICE_DMABUF_MGR_FD  0 /* Supported fd types */
+
+/*
+ * VFIO_DEVICE_QUERY_PLANE - _IO(VFIO_TYPE, VFIO_BASE + 15,
+ * struct vfio_vgpu_query_plane)
+ * Query plane information
+ */
+struct vfio_vgpu_query_plane {
+   __u32 argsz;
+   __u32 flags;
+   struct vfio_vgpu_plane_info plane_info;
+   __u32 plane_id;
+   __u32 padding;
+};
+
+#define VFIO_DEVICE_QUERY_PLANE _IO(VFIO_TYPE, VFIO_BASE + 15)
+
+/*
+ * VFIO_DEVICE_CREATE_DMABUF - _IO(VFIO, VFIO_BASE + 16,
+ * struct vfio_vgpu_create_dmabuf)
+ *
+ * Create a dma-buf for a plane
+ */
+struct vfio_vgpu_create_dmabuf {
+   __u32 argsz;
+   __u32 flags;
+   struct vfio_vgpu_plane_info plane_info;
+   __s32 fd;
+   __u32 plane_id;
+};
+
+#define VFIO_DEVICE_CREATE_DMABUF _IO(VFIO_TYPE, VFIO_BASE + 16)
+
 /*  API for Type1 VFIO IOMMU  */
 
 /**
-- 
2.7.4



[PATCH v7 5/6] drm/i915/gvt: Dmabuf support for GVT-g

2017-06-07 Thread Xiaoguang Chen
dmabuf for GVT-g can be exported to users who can use the dmabuf to show
the desktop of vm which use intel vgpu.

Currently we provide query and create new dmabuf operations.

Users of dmabuf can cache some created dmabufs and related information
such as the framebuffer's address, size, tiling mode, width, height etc.
When refresh the screen first query the currnet vgpu's frambuffer and
compare with the cached ones(address, size, tiling, width, height etc)
if found one then reuse the found dmabuf to gain performance improvment.

If there is no dmabuf created yet or not found in the cached dmabufs then
need to create a new dmabuf. To create a dmabuf first a gem object will
be created and the backing storage of this gem object is the vgpu's
framebuffer(primary/cursor).
Set caching mode, change tiling mode and set domains of this gem object
is not supported.
Then associate this gem object to a dmabuf and export this dmabuf.
A file descriptor will be generated for this dmabuf and this file
descriptor can be sent to user space to do display.

Signed-off-by: Xiaoguang Chen 
---
 drivers/gpu/drm/i915/gvt/Makefile  |   2 +-
 drivers/gpu/drm/i915/gvt/dmabuf.c  | 273 +
 drivers/gpu/drm/i915/gvt/dmabuf.h  |  37 +
 drivers/gpu/drm/i915/gvt/gvt.h |   1 +
 drivers/gpu/drm/i915/i915_gem.c|  26 +++-
 drivers/gpu/drm/i915/i915_gem_object.h |   9 ++
 drivers/gpu/drm/i915/i915_gem_tiling.c |   5 +
 7 files changed, 351 insertions(+), 2 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/gvt/dmabuf.c
 create mode 100644 drivers/gpu/drm/i915/gvt/dmabuf.h

diff --git a/drivers/gpu/drm/i915/gvt/Makefile 
b/drivers/gpu/drm/i915/gvt/Makefile
index 192ca26..e480f7d 100644
--- a/drivers/gpu/drm/i915/gvt/Makefile
+++ b/drivers/gpu/drm/i915/gvt/Makefile
@@ -2,7 +2,7 @@ GVT_DIR := gvt
 GVT_SOURCE := gvt.o aperture_gm.o handlers.o vgpu.o trace_points.o firmware.o \
interrupt.o gtt.o cfg_space.o opregion.o mmio.o display.o edid.o \
execlist.o scheduler.o sched_policy.o render.o cmd_parser.o \
-   fb_decoder.o
+   fb_decoder.o dmabuf.o
 
 ccflags-y  += -I$(src) -I$(src)/$(GVT_DIR) -Wall
 i915-y += $(addprefix $(GVT_DIR)/, 
$(GVT_SOURCE))
diff --git a/drivers/gpu/drm/i915/gvt/dmabuf.c 
b/drivers/gpu/drm/i915/gvt/dmabuf.c
new file mode 100644
index 000..411165da
--- /dev/null
+++ b/drivers/gpu/drm/i915/gvt/dmabuf.c
@@ -0,0 +1,273 @@
+/*
+ * Copyright 2017 Intel Corporation. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *Zhiyuan Lv 
+ *
+ * Contributors:
+ *Xiaoguang Chen 
+ */
+
+#include 
+#include 
+#include 
+
+#include "i915_drv.h"
+#include "gvt.h"
+
+#define GEN8_DECODE_PTE(pte) (pte & GENMASK_ULL(63, 12))
+
+static struct sg_table *intel_vgpu_gem_get_pages(
+   struct drm_i915_gem_object *obj)
+{
+   struct drm_i915_private *dev_priv = to_i915(obj->base.dev);
+   struct sg_table *st;
+   struct scatterlist *sg;
+   int i, ret;
+   gen8_pte_t __iomem *gtt_entries;
+   struct intel_vgpu_fb_info *fb_info;
+
+   fb_info = (struct intel_vgpu_fb_info *)obj->gvt_info;
+   if (WARN_ON(!fb_info))
+   return ERR_PTR(-ENODEV);
+
+   st = kmalloc(sizeof(*st), GFP_KERNEL);
+   if (!st)
+   return ERR_PTR(-ENOMEM);
+
+   ret = sg_alloc_table(st, fb_info->fb_size, GFP_KERNEL);
+   if (ret) {
+   kfree(st);
+   return ERR_PTR(ret);
+   }
+   gtt_entries = (gen8_pte_t __iomem *)dev_priv->ggtt.gsm +
+   (fb_info->fb_addr >> PAGE_SHIFT);
+   for_each_sg(st->sgl, sg, fb_info->fb_size, i) {
+   sg->offset = 0;
+   sg->length = PAGE_SIZE;
+   

[PATCH v7 6/6] drm/i915/gvt: Adding user interface for dma-buf

2017-06-07 Thread Xiaoguang Chen
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.c...@intel.com>
---
 drivers/gpu/drm/i915/gvt/dmabuf.c|  37 -
 drivers/gpu/drm/i915/gvt/dmabuf.h|   5 ++
 drivers/gpu/drm/i915/gvt/gvt.c   |   3 +
 drivers/gpu/drm/i915/gvt/gvt.h   |   5 ++
 drivers/gpu/drm/i915/gvt/hypercall.h |   3 +
 drivers/gpu/drm/i915/gvt/kvmgt.c | 149 +++
 drivers/gpu/drm/i915/gvt/mpt.h   |  30 +++
 drivers/gpu/drm/i915/gvt/vgpu.c  |   2 +
 8 files changed, 233 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/gvt/dmabuf.c 
b/drivers/gpu/drm/i915/gvt/dmabuf.c
index 411165da..ce1041f 100644
--- a/drivers/gpu/drm/i915/gvt/dmabuf.c
+++ b/drivers/gpu/drm/i915/gvt/dmabuf.c
@@ -81,6 +81,28 @@ static void intel_vgpu_gem_put_pages(struct 
drm_i915_gem_object *obj,
 
 static void intel_vgpu_gem_release(struct drm_i915_gem_object *obj)
 {
+   struct intel_vgpu_dmabuf_obj *dmabuf_obj;
+   struct intel_vgpu_fb_info *fb_info;
+   struct intel_vgpu *vgpu = NULL;
+   struct list_head *pos;
+
+   fb_info = (struct intel_vgpu_fb_info *)obj->gvt_info;
+   if (WARN_ON(!fb_info && !fb_info->vgpu)) {
+   gvt_vgpu_err("gvt info is invalid\n");
+   goto out;
+   }
+
+   vgpu = fb_info->vgpu;
+   list_for_each(pos, >dmabuf_obj_list_head) {
+   dmabuf_obj = container_of(pos, struct intel_vgpu_dmabuf_obj,
+   list);
+   if ((dmabuf_obj != NULL) && (dmabuf_obj->obj == obj)) {
+   kfree(dmabuf_obj);
+   break;
+   }
+   }
+   intel_gvt_hypervisor_put_vfio_device(vgpu);
+out:
kfree(obj->gvt_info);
 }
 
@@ -225,6 +247,7 @@ int intel_vgpu_create_dmabuf(struct intel_vgpu *vgpu, void 
*args)
struct vfio_vgpu_create_dmabuf *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, _dmabuf->plane_info,
gvt_dmabuf->plane_id);
@@ -247,6 +270,16 @@ int intel_vgpu_create_dmabuf(struct intel_vgpu *vgpu, void 
*args)
fb_info->vgpu = vgpu;
obj->gvt_info = fb_info;
 
+   dmabuf_obj = kmalloc(sizeof(*dmabuf_obj), GFP_KERNEL);
+   if (!dmabuf_obj) {
+   gvt_vgpu_err("alloc dmabuf_obj failed\n");
+   ret = -ENOMEM;
+   goto out_free_info;
+   }
+   dmabuf_obj->obj = obj;
+   INIT_LIST_HEAD(_obj->list);
+   list_add_tail(_obj->list, >dmabuf_obj_list_head);
+
dmabuf = i915_gem_prime_export(dev, >base, DRM_CLOEXEC | DRM_RDWR);
 
if (IS_ERR(dmabuf)) {
@@ -260,11 +293,13 @@ int intel_vgpu_create_dmabuf(struct intel_vgpu *vgpu, 
void *args)
gvt_vgpu_err("create dma-buf fd failed ret:%d\n", ret);
goto out_free;
}
-
+   intel_gvt_hypervisor_get_vfio_device(vgpu);
gvt_dmabuf->fd = ret;
 
return 0;
 out_free:
+   kfree(dmabuf_obj);
+out_free_info:
kfree(fb_info);
 out:
i915_gem_object_put(obj);
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..d589830 100644
--- a/drivers/gpu/drm/i915/gvt/gvt.c
+++ b/drivers/gpu/drm/i915/gvt/gvt.c
@@ -54,6 +54,9 @@ 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..8f08c42 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
+   atomic_t mgr_fd_opened;
+   struct list_head dmabuf_obj_list_head;
 };
 
 struct in

[PATCH v7 6/6] drm/i915/gvt: Adding user interface for dma-buf

2017-06-07 Thread Xiaoguang Chen
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 
---
 drivers/gpu/drm/i915/gvt/dmabuf.c|  37 -
 drivers/gpu/drm/i915/gvt/dmabuf.h|   5 ++
 drivers/gpu/drm/i915/gvt/gvt.c   |   3 +
 drivers/gpu/drm/i915/gvt/gvt.h   |   5 ++
 drivers/gpu/drm/i915/gvt/hypercall.h |   3 +
 drivers/gpu/drm/i915/gvt/kvmgt.c | 149 +++
 drivers/gpu/drm/i915/gvt/mpt.h   |  30 +++
 drivers/gpu/drm/i915/gvt/vgpu.c  |   2 +
 8 files changed, 233 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/gvt/dmabuf.c 
b/drivers/gpu/drm/i915/gvt/dmabuf.c
index 411165da..ce1041f 100644
--- a/drivers/gpu/drm/i915/gvt/dmabuf.c
+++ b/drivers/gpu/drm/i915/gvt/dmabuf.c
@@ -81,6 +81,28 @@ static void intel_vgpu_gem_put_pages(struct 
drm_i915_gem_object *obj,
 
 static void intel_vgpu_gem_release(struct drm_i915_gem_object *obj)
 {
+   struct intel_vgpu_dmabuf_obj *dmabuf_obj;
+   struct intel_vgpu_fb_info *fb_info;
+   struct intel_vgpu *vgpu = NULL;
+   struct list_head *pos;
+
+   fb_info = (struct intel_vgpu_fb_info *)obj->gvt_info;
+   if (WARN_ON(!fb_info && !fb_info->vgpu)) {
+   gvt_vgpu_err("gvt info is invalid\n");
+   goto out;
+   }
+
+   vgpu = fb_info->vgpu;
+   list_for_each(pos, >dmabuf_obj_list_head) {
+   dmabuf_obj = container_of(pos, struct intel_vgpu_dmabuf_obj,
+   list);
+   if ((dmabuf_obj != NULL) && (dmabuf_obj->obj == obj)) {
+   kfree(dmabuf_obj);
+   break;
+   }
+   }
+   intel_gvt_hypervisor_put_vfio_device(vgpu);
+out:
kfree(obj->gvt_info);
 }
 
@@ -225,6 +247,7 @@ int intel_vgpu_create_dmabuf(struct intel_vgpu *vgpu, void 
*args)
struct vfio_vgpu_create_dmabuf *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, _dmabuf->plane_info,
gvt_dmabuf->plane_id);
@@ -247,6 +270,16 @@ int intel_vgpu_create_dmabuf(struct intel_vgpu *vgpu, void 
*args)
fb_info->vgpu = vgpu;
obj->gvt_info = fb_info;
 
+   dmabuf_obj = kmalloc(sizeof(*dmabuf_obj), GFP_KERNEL);
+   if (!dmabuf_obj) {
+   gvt_vgpu_err("alloc dmabuf_obj failed\n");
+   ret = -ENOMEM;
+   goto out_free_info;
+   }
+   dmabuf_obj->obj = obj;
+   INIT_LIST_HEAD(_obj->list);
+   list_add_tail(_obj->list, >dmabuf_obj_list_head);
+
dmabuf = i915_gem_prime_export(dev, >base, DRM_CLOEXEC | DRM_RDWR);
 
if (IS_ERR(dmabuf)) {
@@ -260,11 +293,13 @@ int intel_vgpu_create_dmabuf(struct intel_vgpu *vgpu, 
void *args)
gvt_vgpu_err("create dma-buf fd failed ret:%d\n", ret);
goto out_free;
}
-
+   intel_gvt_hypervisor_get_vfio_device(vgpu);
gvt_dmabuf->fd = ret;
 
return 0;
 out_free:
+   kfree(dmabuf_obj);
+out_free_info:
kfree(fb_info);
 out:
i915_gem_object_put(obj);
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..d589830 100644
--- a/drivers/gpu/drm/i915/gvt/gvt.c
+++ b/drivers/gpu/drm/i915/gvt/gvt.c
@@ -54,6 +54,9 @@ 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..8f08c42 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
+   atomic_t mgr_fd_opened;
+   struct list_head dmabuf_obj_list_head;
 };
 
 struct intel_gvt_gm {
@@ -467,6 

[PATCH v7 1/6] drm/i915/gvt: Extend the GVT-g architecture to support vfio device region

2017-06-07 Thread Xiaoguang Chen
Signed-off-by: Xiaoguang Chen <xiaoguang.c...@intel.com>
---
 drivers/gpu/drm/i915/gvt/kvmgt.c | 21 ++---
 1 file changed, 18 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
index 1ae0b40..3c6a02b 100644
--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
+++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
@@ -53,11 +53,21 @@ static const struct intel_gvt_ops *intel_gvt_ops;
 #define VFIO_PCI_INDEX_TO_OFFSET(index) ((u64)(index) << VFIO_PCI_OFFSET_SHIFT)
 #define VFIO_PCI_OFFSET_MASK(((u64)(1) << VFIO_PCI_OFFSET_SHIFT) - 1)
 
+struct vfio_region;
+struct intel_vgpu_regops {
+   size_t (*rw)(struct intel_vgpu *vgpu, char *buf,
+   size_t count, loff_t *ppos, bool iswrite);
+   void (*release)(struct intel_vgpu *vgpu,
+   struct vfio_region *region);
+};
+
 struct vfio_region {
u32 type;
u32 subtype;
size_t  size;
u32 flags;
+   const struct intel_vgpu_regops  *ops;
+   void*data;
 };
 
 struct kvmgt_pgfn {
@@ -642,7 +652,7 @@ static ssize_t intel_vgpu_rw(struct mdev_device *mdev, char 
*buf,
int ret = -EINVAL;
 
 
-   if (index >= VFIO_PCI_NUM_REGIONS) {
+   if (index >= VFIO_PCI_NUM_REGIONS + vgpu->vdev.num_regions) {
gvt_vgpu_err("invalid index: %u\n", index);
return -EINVAL;
}
@@ -676,8 +686,11 @@ static ssize_t intel_vgpu_rw(struct mdev_device *mdev, 
char *buf,
case VFIO_PCI_BAR5_REGION_INDEX:
case VFIO_PCI_VGA_REGION_INDEX:
case VFIO_PCI_ROM_REGION_INDEX:
+   break;
default:
-   gvt_vgpu_err("unsupported region: %u\n", index);
+   index -= VFIO_PCI_NUM_REGIONS;
+   return vgpu->vdev.region[index].ops->rw(vgpu, buf, count,
+   ppos, is_write);
}
 
return ret == 0 ? count : ret;
@@ -940,7 +953,8 @@ static long intel_vgpu_ioctl(struct mdev_device *mdev, 
unsigned int cmd,
 
info.flags = VFIO_DEVICE_FLAGS_PCI;
info.flags |= VFIO_DEVICE_FLAGS_RESET;
-   info.num_regions = VFIO_PCI_NUM_REGIONS;
+   info.num_regions = VFIO_PCI_NUM_REGIONS +
+   vgpu->vdev.num_regions;
info.num_irqs = VFIO_PCI_NUM_IRQS;
 
return copy_to_user((void __user *)arg, , minsz) ?
@@ -1061,6 +1075,7 @@ static long intel_vgpu_ioctl(struct mdev_device *mdev, 
unsigned int cmd,
}
 
if (caps.size) {
+   info.flags |= VFIO_REGION_INFO_FLAG_CAPS;
if (info.argsz < sizeof(info) + caps.size) {
info.argsz = sizeof(info) + caps.size;
info.cap_offset = 0;
-- 
2.7.4



[PATCH v7 1/6] drm/i915/gvt: Extend the GVT-g architecture to support vfio device region

2017-06-07 Thread Xiaoguang Chen
Signed-off-by: Xiaoguang Chen 
---
 drivers/gpu/drm/i915/gvt/kvmgt.c | 21 ++---
 1 file changed, 18 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
index 1ae0b40..3c6a02b 100644
--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
+++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
@@ -53,11 +53,21 @@ static const struct intel_gvt_ops *intel_gvt_ops;
 #define VFIO_PCI_INDEX_TO_OFFSET(index) ((u64)(index) << VFIO_PCI_OFFSET_SHIFT)
 #define VFIO_PCI_OFFSET_MASK(((u64)(1) << VFIO_PCI_OFFSET_SHIFT) - 1)
 
+struct vfio_region;
+struct intel_vgpu_regops {
+   size_t (*rw)(struct intel_vgpu *vgpu, char *buf,
+   size_t count, loff_t *ppos, bool iswrite);
+   void (*release)(struct intel_vgpu *vgpu,
+   struct vfio_region *region);
+};
+
 struct vfio_region {
u32 type;
u32 subtype;
size_t  size;
u32 flags;
+   const struct intel_vgpu_regops  *ops;
+   void*data;
 };
 
 struct kvmgt_pgfn {
@@ -642,7 +652,7 @@ static ssize_t intel_vgpu_rw(struct mdev_device *mdev, char 
*buf,
int ret = -EINVAL;
 
 
-   if (index >= VFIO_PCI_NUM_REGIONS) {
+   if (index >= VFIO_PCI_NUM_REGIONS + vgpu->vdev.num_regions) {
gvt_vgpu_err("invalid index: %u\n", index);
return -EINVAL;
}
@@ -676,8 +686,11 @@ static ssize_t intel_vgpu_rw(struct mdev_device *mdev, 
char *buf,
case VFIO_PCI_BAR5_REGION_INDEX:
case VFIO_PCI_VGA_REGION_INDEX:
case VFIO_PCI_ROM_REGION_INDEX:
+   break;
default:
-   gvt_vgpu_err("unsupported region: %u\n", index);
+   index -= VFIO_PCI_NUM_REGIONS;
+   return vgpu->vdev.region[index].ops->rw(vgpu, buf, count,
+   ppos, is_write);
}
 
return ret == 0 ? count : ret;
@@ -940,7 +953,8 @@ static long intel_vgpu_ioctl(struct mdev_device *mdev, 
unsigned int cmd,
 
info.flags = VFIO_DEVICE_FLAGS_PCI;
info.flags |= VFIO_DEVICE_FLAGS_RESET;
-   info.num_regions = VFIO_PCI_NUM_REGIONS;
+   info.num_regions = VFIO_PCI_NUM_REGIONS +
+   vgpu->vdev.num_regions;
info.num_irqs = VFIO_PCI_NUM_IRQS;
 
return copy_to_user((void __user *)arg, , minsz) ?
@@ -1061,6 +1075,7 @@ static long intel_vgpu_ioctl(struct mdev_device *mdev, 
unsigned int cmd,
}
 
if (caps.size) {
+   info.flags |= VFIO_REGION_INFO_FLAG_CAPS;
if (info.argsz < sizeof(info) + caps.size) {
info.argsz = sizeof(info) + caps.size;
info.cap_offset = 0;
-- 
2.7.4



[PATCH v6 2/6] drm/i915/gvt: OpRegion support for GVT-g

2017-05-27 Thread Xiaoguang Chen
OpRegion is needed to support display related operation for
intel vgpu.

A vfio device region is added to intel vgpu to deliver the
host OpRegion information to user space so user space can
construct the OpRegion for vgpu.

Signed-off-by: Bing Niu <bing@intel.com>
Signed-off-by: Xiaoguang Chen <xiaoguang.c...@intel.com>
---
 drivers/gpu/drm/i915/gvt/kvmgt.c| 97 +
 drivers/gpu/drm/i915/gvt/opregion.c |  8 ++-
 2 files changed, 104 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
index 3c6a02b..389f072 100644
--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
+++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
@@ -53,6 +53,8 @@ static const struct intel_gvt_ops *intel_gvt_ops;
 #define VFIO_PCI_INDEX_TO_OFFSET(index) ((u64)(index) << VFIO_PCI_OFFSET_SHIFT)
 #define VFIO_PCI_OFFSET_MASK(((u64)(1) << VFIO_PCI_OFFSET_SHIFT) - 1)
 
+#define OPREGION_SIGNATURE "IntelGraphicsMem"
+
 struct vfio_region;
 struct intel_vgpu_regops {
size_t (*rw)(struct intel_vgpu *vgpu, char *buf,
@@ -436,6 +438,92 @@ static void kvmgt_protect_table_del(struct 
kvmgt_guest_info *info,
}
 }
 
+static size_t intel_vgpu_reg_rw_opregion(struct intel_vgpu *vgpu, char *buf,
+   size_t count, loff_t *ppos, bool iswrite)
+{
+   unsigned int i = VFIO_PCI_OFFSET_TO_INDEX(*ppos) -
+   VFIO_PCI_NUM_REGIONS;
+   void *base = vgpu->vdev.region[i].data;
+   loff_t pos = *ppos & VFIO_PCI_OFFSET_MASK;
+
+   if (pos >= vgpu->vdev.region[i].size || iswrite) {
+   gvt_vgpu_err("invalid op or offset for Intel vgpu OpRegion\n");
+   return -EINVAL;
+   }
+   count = min(count, (size_t)(vgpu->vdev.region[i].size - pos));
+   memcpy(buf, base + pos, count);
+
+   return count;
+}
+
+static void intel_vgpu_reg_release_opregion(struct intel_vgpu *vgpu,
+   struct vfio_region *region)
+{
+   memunmap(region->data);
+}
+
+static const struct intel_vgpu_regops intel_vgpu_regops_opregion = {
+   .rw = intel_vgpu_reg_rw_opregion,
+   .release = intel_vgpu_reg_release_opregion,
+};
+
+static int intel_vgpu_register_reg(struct intel_vgpu *vgpu,
+   unsigned int type, unsigned int subtype,
+   const struct intel_vgpu_regops *ops,
+   size_t size, u32 flags, void *data)
+{
+   struct vfio_region *region;
+
+   region = krealloc(vgpu->vdev.region,
+   (vgpu->vdev.num_regions + 1) * sizeof(*region),
+   GFP_KERNEL);
+   if (!region)
+   return -ENOMEM;
+
+   vgpu->vdev.region = region;
+   vgpu->vdev.region[vgpu->vdev.num_regions].type = type;
+   vgpu->vdev.region[vgpu->vdev.num_regions].subtype = subtype;
+   vgpu->vdev.region[vgpu->vdev.num_regions].ops = ops;
+   vgpu->vdev.region[vgpu->vdev.num_regions].size = size;
+   vgpu->vdev.region[vgpu->vdev.num_regions].flags = flags;
+   vgpu->vdev.region[vgpu->vdev.num_regions].data = data;
+   vgpu->vdev.num_regions++;
+
+   return 0;
+}
+
+static int intel_vgpu_reg_init_opregion(struct intel_vgpu *vgpu)
+{
+   unsigned int addr;
+   void *base;
+   int ret;
+
+   addr = vgpu->gvt->opregion.opregion_pa;
+   if (!addr || !(~addr))
+   return -ENODEV;
+
+   base = memremap(addr, OPREGION_SIZE, MEMREMAP_WB);
+   if (!base)
+   return -ENOMEM;
+
+   if (memcmp(base, OPREGION_SIGNATURE, 16)) {
+   memunmap(base);
+   return -EINVAL;
+   }
+
+   ret = intel_vgpu_register_reg(vgpu,
+   PCI_VENDOR_ID_INTEL | VFIO_REGION_TYPE_PCI_VENDOR_TYPE,
+   VFIO_REGION_SUBTYPE_INTEL_IGD_OPREGION,
+   _vgpu_regops_opregion, OPREGION_SIZE,
+   VFIO_REGION_INFO_FLAG_READ, base);
+   if (ret) {
+   memunmap(base);
+   return ret;
+   }
+
+   return ret;
+}
+
 static int intel_vgpu_create(struct kobject *kobj, struct mdev_device *mdev)
 {
struct intel_vgpu *vgpu = NULL;
@@ -467,6 +555,15 @@ static int intel_vgpu_create(struct kobject *kobj, struct 
mdev_device *mdev)
vgpu->vdev.mdev = mdev;
mdev_set_drvdata(mdev, vgpu);
 
+   ret = intel_vgpu_reg_init_opregion(vgpu);
+   if (ret) {
+   gvt_vgpu_err("create OpRegion failed\n");
+   goto out;
+   }
+
+   gvt_dbg_core("create OpRegion succeeded for mdev:%s\n",
+   dev_name(mdev_dev(mdev)));
+
gvt_dbg_core("intel_vgpu_create succeeded for mdev: %s\n",
 dev_name(mdev_dev(mdev)));
ret = 0;
diff --git a/drivers/gpu/drm/i915/gvt/opregion.c 
b/drivers/gpu/drm/i915/gvt/opregion.c
index 3117991.

[PATCH v6 0/6] drm/i915/gvt: Dma-buf support for GVT-g

2017-05-27 Thread Xiaoguang Chen
v5->v6:
1) align the dma-buf life cycle with the vfio device.
2) add the dma-buf releated operations in a separate patch.
3) i915 releated changes.

v4->v5:
1) fix bug while checking whether the gem obj is gvt's dma-buf when user
change caching mode or domains. Add a helper function to do it.
2) add definition for the query plane and create dma-buf.

v3->v4:
1) fix bug while checking whether the gem obj is gvt's dma-buf when set
caching mode or doamins.

v2->v3:
1) add a field gvt_plane_info in the drm_i915_gem_obj structure to save
the decoded plane information to avoid look up while need the plane info.
2) declare a new flag I915_GEM_OBJECT_IS_GVT_DMABUF in drm_i915_gem_object
to represent the gem obj for gvt's dma-buf. The tiling mode, caching mode
and domains can not be changed for this kind of gem object.
3) change dma-buf related information to be more generic. So other vendor
can use the same interface.

v1->v2:
1) create a management fd for dma-buf operations.
2) alloc gem object's backing storage in gem obj's get_pages() callback.

This patch set adds the dma-buf support for intel GVT-g.
dma-buf is a uniform mechanism to share DMA buffers across different
devices and sub-systems.
dma-buf for intel GVT-g is mainly used to share the vgpu's framebuffer
to other users or sub-systems so they can use the dma-buf to show the
desktop of a vm which uses intel vgpu.

The main idea is we create a gem object and set vgpu's framebuffer as
the backing storage of this gem object. And associate this gem obj
to a dma-buf object then export this dma-buf at the meantime
generate a file descriptor for this dma-buf. Finally deliver this file
descriptor to user space. And user can use this dma-buf fd to do render
or other operations.
User need to create a fd(for intel GVT-g dma-buf support it is a:dma-buf
management fd) then user can use this fd to query the plane information
or create a dma-buf. The life cycle of this fd is managed by GVT-g user
do not need to care about that.

We have an example program on how to use the dma-buf. You can download
the program to have a try. Good luck :)
git repo: https://github.com/01org/igvtg-qemu branch:kvmgt_dmabuf_example

Xiaoguang Chen (6):
  drm/i915/gvt: Extend the GVT-g architecture to support vfio device
region
  drm/i915/gvt: OpRegion support for GVT-g
  drm/i915/gvt: Frame buffer decoder support for GVT-g
  vfio: Define vfio based vgpu's dma-buf operations
  drm/i915/gvt: Dmabuf support for GVT-g
  drm/i915/gvt: Adding interface so user space can get the dma-buf

 drivers/gpu/drm/i915/gvt/Makefile  |   3 +-
 drivers/gpu/drm/i915/gvt/display.c |   2 +-
 drivers/gpu/drm/i915/gvt/display.h |   2 +
 drivers/gpu/drm/i915/gvt/dmabuf.c  | 281 +++
 drivers/gpu/drm/i915/gvt/dmabuf.h  |  42 +++
 drivers/gpu/drm/i915/gvt/fb_decoder.c  | 479 +
 drivers/gpu/drm/i915/gvt/fb_decoder.h  | 166 
 drivers/gpu/drm/i915/gvt/gvt.c |   2 +
 drivers/gpu/drm/i915/gvt/gvt.h |   7 +
 drivers/gpu/drm/i915/gvt/kvmgt.c   | 262 +-
 drivers/gpu/drm/i915/gvt/opregion.c|   8 +-
 drivers/gpu/drm/i915/gvt/vgpu.c|   1 +
 drivers/gpu/drm/i915/i915_gem.c|  26 +-
 drivers/gpu/drm/i915/i915_gem_object.h |   9 +
 include/uapi/linux/vfio.h  |  50 
 15 files changed, 1333 insertions(+), 7 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/gvt/dmabuf.c
 create mode 100644 drivers/gpu/drm/i915/gvt/dmabuf.h
 create mode 100644 drivers/gpu/drm/i915/gvt/fb_decoder.c
 create mode 100644 drivers/gpu/drm/i915/gvt/fb_decoder.h

-- 
2.7.4



[PATCH v6 2/6] drm/i915/gvt: OpRegion support for GVT-g

2017-05-27 Thread Xiaoguang Chen
OpRegion is needed to support display related operation for
intel vgpu.

A vfio device region is added to intel vgpu to deliver the
host OpRegion information to user space so user space can
construct the OpRegion for vgpu.

Signed-off-by: Bing Niu 
Signed-off-by: Xiaoguang Chen 
---
 drivers/gpu/drm/i915/gvt/kvmgt.c| 97 +
 drivers/gpu/drm/i915/gvt/opregion.c |  8 ++-
 2 files changed, 104 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
index 3c6a02b..389f072 100644
--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
+++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
@@ -53,6 +53,8 @@ static const struct intel_gvt_ops *intel_gvt_ops;
 #define VFIO_PCI_INDEX_TO_OFFSET(index) ((u64)(index) << VFIO_PCI_OFFSET_SHIFT)
 #define VFIO_PCI_OFFSET_MASK(((u64)(1) << VFIO_PCI_OFFSET_SHIFT) - 1)
 
+#define OPREGION_SIGNATURE "IntelGraphicsMem"
+
 struct vfio_region;
 struct intel_vgpu_regops {
size_t (*rw)(struct intel_vgpu *vgpu, char *buf,
@@ -436,6 +438,92 @@ static void kvmgt_protect_table_del(struct 
kvmgt_guest_info *info,
}
 }
 
+static size_t intel_vgpu_reg_rw_opregion(struct intel_vgpu *vgpu, char *buf,
+   size_t count, loff_t *ppos, bool iswrite)
+{
+   unsigned int i = VFIO_PCI_OFFSET_TO_INDEX(*ppos) -
+   VFIO_PCI_NUM_REGIONS;
+   void *base = vgpu->vdev.region[i].data;
+   loff_t pos = *ppos & VFIO_PCI_OFFSET_MASK;
+
+   if (pos >= vgpu->vdev.region[i].size || iswrite) {
+   gvt_vgpu_err("invalid op or offset for Intel vgpu OpRegion\n");
+   return -EINVAL;
+   }
+   count = min(count, (size_t)(vgpu->vdev.region[i].size - pos));
+   memcpy(buf, base + pos, count);
+
+   return count;
+}
+
+static void intel_vgpu_reg_release_opregion(struct intel_vgpu *vgpu,
+   struct vfio_region *region)
+{
+   memunmap(region->data);
+}
+
+static const struct intel_vgpu_regops intel_vgpu_regops_opregion = {
+   .rw = intel_vgpu_reg_rw_opregion,
+   .release = intel_vgpu_reg_release_opregion,
+};
+
+static int intel_vgpu_register_reg(struct intel_vgpu *vgpu,
+   unsigned int type, unsigned int subtype,
+   const struct intel_vgpu_regops *ops,
+   size_t size, u32 flags, void *data)
+{
+   struct vfio_region *region;
+
+   region = krealloc(vgpu->vdev.region,
+   (vgpu->vdev.num_regions + 1) * sizeof(*region),
+   GFP_KERNEL);
+   if (!region)
+   return -ENOMEM;
+
+   vgpu->vdev.region = region;
+   vgpu->vdev.region[vgpu->vdev.num_regions].type = type;
+   vgpu->vdev.region[vgpu->vdev.num_regions].subtype = subtype;
+   vgpu->vdev.region[vgpu->vdev.num_regions].ops = ops;
+   vgpu->vdev.region[vgpu->vdev.num_regions].size = size;
+   vgpu->vdev.region[vgpu->vdev.num_regions].flags = flags;
+   vgpu->vdev.region[vgpu->vdev.num_regions].data = data;
+   vgpu->vdev.num_regions++;
+
+   return 0;
+}
+
+static int intel_vgpu_reg_init_opregion(struct intel_vgpu *vgpu)
+{
+   unsigned int addr;
+   void *base;
+   int ret;
+
+   addr = vgpu->gvt->opregion.opregion_pa;
+   if (!addr || !(~addr))
+   return -ENODEV;
+
+   base = memremap(addr, OPREGION_SIZE, MEMREMAP_WB);
+   if (!base)
+   return -ENOMEM;
+
+   if (memcmp(base, OPREGION_SIGNATURE, 16)) {
+   memunmap(base);
+   return -EINVAL;
+   }
+
+   ret = intel_vgpu_register_reg(vgpu,
+   PCI_VENDOR_ID_INTEL | VFIO_REGION_TYPE_PCI_VENDOR_TYPE,
+   VFIO_REGION_SUBTYPE_INTEL_IGD_OPREGION,
+   _vgpu_regops_opregion, OPREGION_SIZE,
+   VFIO_REGION_INFO_FLAG_READ, base);
+   if (ret) {
+   memunmap(base);
+   return ret;
+   }
+
+   return ret;
+}
+
 static int intel_vgpu_create(struct kobject *kobj, struct mdev_device *mdev)
 {
struct intel_vgpu *vgpu = NULL;
@@ -467,6 +555,15 @@ static int intel_vgpu_create(struct kobject *kobj, struct 
mdev_device *mdev)
vgpu->vdev.mdev = mdev;
mdev_set_drvdata(mdev, vgpu);
 
+   ret = intel_vgpu_reg_init_opregion(vgpu);
+   if (ret) {
+   gvt_vgpu_err("create OpRegion failed\n");
+   goto out;
+   }
+
+   gvt_dbg_core("create OpRegion succeeded for mdev:%s\n",
+   dev_name(mdev_dev(mdev)));
+
gvt_dbg_core("intel_vgpu_create succeeded for mdev: %s\n",
 dev_name(mdev_dev(mdev)));
ret = 0;
diff --git a/drivers/gpu/drm/i915/gvt/opregion.c 
b/drivers/gpu/drm/i915/gvt/opregion.c
index 3117991..5c7496d 100644
--- a/drivers/gpu/drm/i915

[PATCH v6 0/6] drm/i915/gvt: Dma-buf support for GVT-g

2017-05-27 Thread Xiaoguang Chen
v5->v6:
1) align the dma-buf life cycle with the vfio device.
2) add the dma-buf releated operations in a separate patch.
3) i915 releated changes.

v4->v5:
1) fix bug while checking whether the gem obj is gvt's dma-buf when user
change caching mode or domains. Add a helper function to do it.
2) add definition for the query plane and create dma-buf.

v3->v4:
1) fix bug while checking whether the gem obj is gvt's dma-buf when set
caching mode or doamins.

v2->v3:
1) add a field gvt_plane_info in the drm_i915_gem_obj structure to save
the decoded plane information to avoid look up while need the plane info.
2) declare a new flag I915_GEM_OBJECT_IS_GVT_DMABUF in drm_i915_gem_object
to represent the gem obj for gvt's dma-buf. The tiling mode, caching mode
and domains can not be changed for this kind of gem object.
3) change dma-buf related information to be more generic. So other vendor
can use the same interface.

v1->v2:
1) create a management fd for dma-buf operations.
2) alloc gem object's backing storage in gem obj's get_pages() callback.

This patch set adds the dma-buf support for intel GVT-g.
dma-buf is a uniform mechanism to share DMA buffers across different
devices and sub-systems.
dma-buf for intel GVT-g is mainly used to share the vgpu's framebuffer
to other users or sub-systems so they can use the dma-buf to show the
desktop of a vm which uses intel vgpu.

The main idea is we create a gem object and set vgpu's framebuffer as
the backing storage of this gem object. And associate this gem obj
to a dma-buf object then export this dma-buf at the meantime
generate a file descriptor for this dma-buf. Finally deliver this file
descriptor to user space. And user can use this dma-buf fd to do render
or other operations.
User need to create a fd(for intel GVT-g dma-buf support it is a:dma-buf
management fd) then user can use this fd to query the plane information
or create a dma-buf. The life cycle of this fd is managed by GVT-g user
do not need to care about that.

We have an example program on how to use the dma-buf. You can download
the program to have a try. Good luck :)
git repo: https://github.com/01org/igvtg-qemu branch:kvmgt_dmabuf_example

Xiaoguang Chen (6):
  drm/i915/gvt: Extend the GVT-g architecture to support vfio device
region
  drm/i915/gvt: OpRegion support for GVT-g
  drm/i915/gvt: Frame buffer decoder support for GVT-g
  vfio: Define vfio based vgpu's dma-buf operations
  drm/i915/gvt: Dmabuf support for GVT-g
  drm/i915/gvt: Adding interface so user space can get the dma-buf

 drivers/gpu/drm/i915/gvt/Makefile  |   3 +-
 drivers/gpu/drm/i915/gvt/display.c |   2 +-
 drivers/gpu/drm/i915/gvt/display.h |   2 +
 drivers/gpu/drm/i915/gvt/dmabuf.c  | 281 +++
 drivers/gpu/drm/i915/gvt/dmabuf.h  |  42 +++
 drivers/gpu/drm/i915/gvt/fb_decoder.c  | 479 +
 drivers/gpu/drm/i915/gvt/fb_decoder.h  | 166 
 drivers/gpu/drm/i915/gvt/gvt.c |   2 +
 drivers/gpu/drm/i915/gvt/gvt.h |   7 +
 drivers/gpu/drm/i915/gvt/kvmgt.c   | 262 +-
 drivers/gpu/drm/i915/gvt/opregion.c|   8 +-
 drivers/gpu/drm/i915/gvt/vgpu.c|   1 +
 drivers/gpu/drm/i915/i915_gem.c|  26 +-
 drivers/gpu/drm/i915/i915_gem_object.h |   9 +
 include/uapi/linux/vfio.h  |  50 
 15 files changed, 1333 insertions(+), 7 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/gvt/dmabuf.c
 create mode 100644 drivers/gpu/drm/i915/gvt/dmabuf.h
 create mode 100644 drivers/gpu/drm/i915/gvt/fb_decoder.c
 create mode 100644 drivers/gpu/drm/i915/gvt/fb_decoder.h

-- 
2.7.4



[PATCH v6 4/6] vfio: Define vfio based vgpu's dma-buf operations

2017-05-27 Thread Xiaoguang Chen
Here we defined a new ioctl to create a fd for a vfio device based on
the input type. Now only one type is supported that is a dma-buf
management fd.
Two ioctls are defined for the dma-buf management fd: query the vfio
vgpu's plane information and create a dma-buf for a plane.

Signed-off-by: Xiaoguang Chen <xiaoguang.c...@intel.com>
---
 include/uapi/linux/vfio.h | 50 +++
 1 file changed, 50 insertions(+)

diff --git a/include/uapi/linux/vfio.h b/include/uapi/linux/vfio.h
index ae46105..308e7a2 100644
--- a/include/uapi/linux/vfio.h
+++ b/include/uapi/linux/vfio.h
@@ -502,6 +502,56 @@ struct vfio_pci_hot_reset {
 
 #define VFIO_DEVICE_PCI_HOT_RESET  _IO(VFIO_TYPE, VFIO_BASE + 13)
 
+/**
+ * VFIO_DEVICE_GET_FD - _IO(VFIO_TYPE, VFIO_BASE + 14, __u32)
+ *
+ * Create a fd for a vfio device based on the input type
+ * Vendor driver should handle this ioctl to create a fd and manage the
+ * life cycle of this fd.
+ *
+ * Return: a fd if vendor support that type, -errno if not supported
+ */
+
+#define VFIO_DEVICE_GET_FD _IO(VFIO_TYPE, VFIO_BASE + 14)
+
+#define VFIO_DEVICE_DMABUF_MGR_FD  0 /* Supported fd types */
+
+/*
+ * VFIO_DEVICE_QUERY_PLANE - _IO(VFIO_TYPE, VFIO_BASE + 15, struct plane_info)
+ * Query plane information for a plane
+ */
+struct vfio_vgpu_plane_info {
+   __u32 argsz;
+   __u32 flags;
+   __u32 plane_id;
+   __u32 drm_format;
+   __u32 width;
+   __u32 height;
+   __u32 stride;
+   __u32 start;
+   __u32 x_pos;
+   __u32 y_pos;
+   __u64 drm_format_mod;
+   __u32 size;
+   __u32 pad;
+};
+
+#define VFIO_DEVICE_QUERY_PLANE _IO(VFIO_TYPE, VFIO_BASE + 15)
+
+/*
+ * VFIO_DEVICE_CREATE_DMABUF - _IO(VFIO, VFIO_BASE + 16, struct dmabuf_info)
+ *
+ * Create a dma-buf for a plane
+ */
+struct vfio_vgpu_dmabuf_info {
+   __u32 argsz;
+   __u32 flags;
+   struct vfio_vgpu_plane_info plane_info;
+   __s32 fd;
+   __u32 pad;
+};
+#define VFIO_DEVICE_CREATE_DMABUF _IO(VFIO_TYPE, VFIO_BASE + 16)
+
 /*  API for Type1 VFIO IOMMU  */
 
 /**
-- 
2.7.4



[PATCH v6 3/6] drm/i915/gvt: Frame buffer decoder support for GVT-g

2017-05-27 Thread Xiaoguang Chen
decode frambuffer attributes of primary, cursor and sprite plane

Signed-off-by: Xiaoguang Chen <xiaoguang.c...@intel.com>
---
 drivers/gpu/drm/i915/gvt/Makefile |   3 +-
 drivers/gpu/drm/i915/gvt/display.c|   2 +-
 drivers/gpu/drm/i915/gvt/display.h|   2 +
 drivers/gpu/drm/i915/gvt/fb_decoder.c | 479 ++
 drivers/gpu/drm/i915/gvt/fb_decoder.h | 166 
 drivers/gpu/drm/i915/gvt/gvt.h|   1 +
 6 files changed, 651 insertions(+), 2 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/gvt/fb_decoder.c
 create mode 100644 drivers/gpu/drm/i915/gvt/fb_decoder.h

diff --git a/drivers/gpu/drm/i915/gvt/Makefile 
b/drivers/gpu/drm/i915/gvt/Makefile
index b123c20..192ca26 100644
--- a/drivers/gpu/drm/i915/gvt/Makefile
+++ b/drivers/gpu/drm/i915/gvt/Makefile
@@ -1,7 +1,8 @@
 GVT_DIR := gvt
 GVT_SOURCE := gvt.o aperture_gm.o handlers.o vgpu.o trace_points.o firmware.o \
interrupt.o gtt.o cfg_space.o opregion.o mmio.o display.o edid.o \
-   execlist.o scheduler.o sched_policy.o render.o cmd_parser.o
+   execlist.o scheduler.o sched_policy.o render.o cmd_parser.o \
+   fb_decoder.o
 
 ccflags-y  += -I$(src) -I$(src)/$(GVT_DIR) -Wall
 i915-y += $(addprefix $(GVT_DIR)/, 
$(GVT_SOURCE))
diff --git a/drivers/gpu/drm/i915/gvt/display.c 
b/drivers/gpu/drm/i915/gvt/display.c
index e0261fc..f5f63c5 100644
--- a/drivers/gpu/drm/i915/gvt/display.c
+++ b/drivers/gpu/drm/i915/gvt/display.c
@@ -67,7 +67,7 @@ static int edp_pipe_is_enabled(struct intel_vgpu *vgpu)
return 1;
 }
 
-static int pipe_is_enabled(struct intel_vgpu *vgpu, int pipe)
+int pipe_is_enabled(struct intel_vgpu *vgpu, int pipe)
 {
struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv;
 
diff --git a/drivers/gpu/drm/i915/gvt/display.h 
b/drivers/gpu/drm/i915/gvt/display.h
index d73de22..b46b868 100644
--- a/drivers/gpu/drm/i915/gvt/display.h
+++ b/drivers/gpu/drm/i915/gvt/display.h
@@ -179,4 +179,6 @@ int intel_vgpu_init_display(struct intel_vgpu *vgpu, u64 
resolution);
 void intel_vgpu_reset_display(struct intel_vgpu *vgpu);
 void intel_vgpu_clean_display(struct intel_vgpu *vgpu);
 
+int pipe_is_enabled(struct intel_vgpu *vgpu, int pipe);
+
 #endif
diff --git a/drivers/gpu/drm/i915/gvt/fb_decoder.c 
b/drivers/gpu/drm/i915/gvt/fb_decoder.c
new file mode 100644
index 000..d4404fd
--- /dev/null
+++ b/drivers/gpu/drm/i915/gvt/fb_decoder.c
@@ -0,0 +1,479 @@
+/*
+ * Copyright(c) 2011-2016 Intel Corporation. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 
THE
+ * SOFTWARE.
+ *
+ * Authors:
+ *Kevin Tian <kevin.t...@intel.com>
+ *
+ * Contributors:
+ *Bing Niu <bing@intel.com>
+ *Xu Han <xu@intel.com>
+ *    Ping Gao <ping.a@intel.com>
+ *Xiaoguang Chen <xiaoguang.c...@intel.com>
+ *Yang Liu <yang2@intel.com>
+ *
+ */
+
+#include 
+#include "i915_drv.h"
+#include "gvt.h"
+
+/* The below definitions are required by guest. */
+// [63:0] x:R:G:B 16:16:16:16 little endian
+#define DRM_FORMAT_XRGB161616_GVT  fourcc_code('X', 'R', '4', '8')
+// [63:0] x:B:G:R 16:16:16:16 little endian
+#define DRM_FORMAT_XBGR161616_GVT  fourcc_code('X', 'B', '4', '8')
+
+#define FORMAT_NUM 16
+struct pixel_format {
+   int drm_format; /* Pixel format in DRM definition */
+   int bpp;/* Bits per pixel, 0 indicates invalid */
+   char *desc; /* The description */
+};
+
+/* non-supported format has bpp default to 0 */
+static struct pixel_format primary_pixel_formats[FORMAT_NUM] = {
+   [0x2] = {DRM_FORMAT_C8, 8, "8-bit Indexed"},
+   [0x5] = {DRM_FORMAT_RGB565, 16, "16-bit BGRX (5:6:5 MSB-R:G:B)"},
+   [0x6] = {DRM_FORMAT_XRGB, 32,
+   "32-bit BG

[PATCH v6 4/6] vfio: Define vfio based vgpu's dma-buf operations

2017-05-27 Thread Xiaoguang Chen
Here we defined a new ioctl to create a fd for a vfio device based on
the input type. Now only one type is supported that is a dma-buf
management fd.
Two ioctls are defined for the dma-buf management fd: query the vfio
vgpu's plane information and create a dma-buf for a plane.

Signed-off-by: Xiaoguang Chen 
---
 include/uapi/linux/vfio.h | 50 +++
 1 file changed, 50 insertions(+)

diff --git a/include/uapi/linux/vfio.h b/include/uapi/linux/vfio.h
index ae46105..308e7a2 100644
--- a/include/uapi/linux/vfio.h
+++ b/include/uapi/linux/vfio.h
@@ -502,6 +502,56 @@ struct vfio_pci_hot_reset {
 
 #define VFIO_DEVICE_PCI_HOT_RESET  _IO(VFIO_TYPE, VFIO_BASE + 13)
 
+/**
+ * VFIO_DEVICE_GET_FD - _IO(VFIO_TYPE, VFIO_BASE + 14, __u32)
+ *
+ * Create a fd for a vfio device based on the input type
+ * Vendor driver should handle this ioctl to create a fd and manage the
+ * life cycle of this fd.
+ *
+ * Return: a fd if vendor support that type, -errno if not supported
+ */
+
+#define VFIO_DEVICE_GET_FD _IO(VFIO_TYPE, VFIO_BASE + 14)
+
+#define VFIO_DEVICE_DMABUF_MGR_FD  0 /* Supported fd types */
+
+/*
+ * VFIO_DEVICE_QUERY_PLANE - _IO(VFIO_TYPE, VFIO_BASE + 15, struct plane_info)
+ * Query plane information for a plane
+ */
+struct vfio_vgpu_plane_info {
+   __u32 argsz;
+   __u32 flags;
+   __u32 plane_id;
+   __u32 drm_format;
+   __u32 width;
+   __u32 height;
+   __u32 stride;
+   __u32 start;
+   __u32 x_pos;
+   __u32 y_pos;
+   __u64 drm_format_mod;
+   __u32 size;
+   __u32 pad;
+};
+
+#define VFIO_DEVICE_QUERY_PLANE _IO(VFIO_TYPE, VFIO_BASE + 15)
+
+/*
+ * VFIO_DEVICE_CREATE_DMABUF - _IO(VFIO, VFIO_BASE + 16, struct dmabuf_info)
+ *
+ * Create a dma-buf for a plane
+ */
+struct vfio_vgpu_dmabuf_info {
+   __u32 argsz;
+   __u32 flags;
+   struct vfio_vgpu_plane_info plane_info;
+   __s32 fd;
+   __u32 pad;
+};
+#define VFIO_DEVICE_CREATE_DMABUF _IO(VFIO_TYPE, VFIO_BASE + 16)
+
 /*  API for Type1 VFIO IOMMU  */
 
 /**
-- 
2.7.4



[PATCH v6 3/6] drm/i915/gvt: Frame buffer decoder support for GVT-g

2017-05-27 Thread Xiaoguang Chen
decode frambuffer attributes of primary, cursor and sprite plane

Signed-off-by: Xiaoguang Chen 
---
 drivers/gpu/drm/i915/gvt/Makefile |   3 +-
 drivers/gpu/drm/i915/gvt/display.c|   2 +-
 drivers/gpu/drm/i915/gvt/display.h|   2 +
 drivers/gpu/drm/i915/gvt/fb_decoder.c | 479 ++
 drivers/gpu/drm/i915/gvt/fb_decoder.h | 166 
 drivers/gpu/drm/i915/gvt/gvt.h|   1 +
 6 files changed, 651 insertions(+), 2 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/gvt/fb_decoder.c
 create mode 100644 drivers/gpu/drm/i915/gvt/fb_decoder.h

diff --git a/drivers/gpu/drm/i915/gvt/Makefile 
b/drivers/gpu/drm/i915/gvt/Makefile
index b123c20..192ca26 100644
--- a/drivers/gpu/drm/i915/gvt/Makefile
+++ b/drivers/gpu/drm/i915/gvt/Makefile
@@ -1,7 +1,8 @@
 GVT_DIR := gvt
 GVT_SOURCE := gvt.o aperture_gm.o handlers.o vgpu.o trace_points.o firmware.o \
interrupt.o gtt.o cfg_space.o opregion.o mmio.o display.o edid.o \
-   execlist.o scheduler.o sched_policy.o render.o cmd_parser.o
+   execlist.o scheduler.o sched_policy.o render.o cmd_parser.o \
+   fb_decoder.o
 
 ccflags-y  += -I$(src) -I$(src)/$(GVT_DIR) -Wall
 i915-y += $(addprefix $(GVT_DIR)/, 
$(GVT_SOURCE))
diff --git a/drivers/gpu/drm/i915/gvt/display.c 
b/drivers/gpu/drm/i915/gvt/display.c
index e0261fc..f5f63c5 100644
--- a/drivers/gpu/drm/i915/gvt/display.c
+++ b/drivers/gpu/drm/i915/gvt/display.c
@@ -67,7 +67,7 @@ static int edp_pipe_is_enabled(struct intel_vgpu *vgpu)
return 1;
 }
 
-static int pipe_is_enabled(struct intel_vgpu *vgpu, int pipe)
+int pipe_is_enabled(struct intel_vgpu *vgpu, int pipe)
 {
struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv;
 
diff --git a/drivers/gpu/drm/i915/gvt/display.h 
b/drivers/gpu/drm/i915/gvt/display.h
index d73de22..b46b868 100644
--- a/drivers/gpu/drm/i915/gvt/display.h
+++ b/drivers/gpu/drm/i915/gvt/display.h
@@ -179,4 +179,6 @@ int intel_vgpu_init_display(struct intel_vgpu *vgpu, u64 
resolution);
 void intel_vgpu_reset_display(struct intel_vgpu *vgpu);
 void intel_vgpu_clean_display(struct intel_vgpu *vgpu);
 
+int pipe_is_enabled(struct intel_vgpu *vgpu, int pipe);
+
 #endif
diff --git a/drivers/gpu/drm/i915/gvt/fb_decoder.c 
b/drivers/gpu/drm/i915/gvt/fb_decoder.c
new file mode 100644
index 000..d4404fd
--- /dev/null
+++ b/drivers/gpu/drm/i915/gvt/fb_decoder.c
@@ -0,0 +1,479 @@
+/*
+ * Copyright(c) 2011-2016 Intel Corporation. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 
THE
+ * SOFTWARE.
+ *
+ * Authors:
+ *Kevin Tian 
+ *
+ * Contributors:
+ *Bing Niu 
+ *Xu Han 
+ *Ping Gao 
+ *Xiaoguang Chen 
+ *Yang Liu 
+ *
+ */
+
+#include 
+#include "i915_drv.h"
+#include "gvt.h"
+
+/* The below definitions are required by guest. */
+// [63:0] x:R:G:B 16:16:16:16 little endian
+#define DRM_FORMAT_XRGB161616_GVT  fourcc_code('X', 'R', '4', '8')
+// [63:0] x:B:G:R 16:16:16:16 little endian
+#define DRM_FORMAT_XBGR161616_GVT  fourcc_code('X', 'B', '4', '8')
+
+#define FORMAT_NUM 16
+struct pixel_format {
+   int drm_format; /* Pixel format in DRM definition */
+   int bpp;/* Bits per pixel, 0 indicates invalid */
+   char *desc; /* The description */
+};
+
+/* non-supported format has bpp default to 0 */
+static struct pixel_format primary_pixel_formats[FORMAT_NUM] = {
+   [0x2] = {DRM_FORMAT_C8, 8, "8-bit Indexed"},
+   [0x5] = {DRM_FORMAT_RGB565, 16, "16-bit BGRX (5:6:5 MSB-R:G:B)"},
+   [0x6] = {DRM_FORMAT_XRGB, 32,
+   "32-bit BGRX (8:8:8:8 MSB-X:R:G:B)"},
+   [0x8] = {DRM_FORMAT_XBGR2101010, 32,
+   "32-bit RGBX (2:10:10:10 MSB-X:B:G:R)"},
+   [0xa] = {DRM_FORMAT_

[PATCH v6 6/6] drm/i915/gvt: Adding interface so user space can get the dma-buf

2017-05-27 Thread Xiaoguang Chen
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.c...@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, _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(_obj->list);
+   list_add_tail(_obj->list, >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 
 #include 
 #include 
+#include 
 
 #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))
+  

[PATCH v6 6/6] drm/i915/gvt: Adding interface so user space can get the dma-buf

2017-05-27 Thread Xiaoguang Chen
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 
---
 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, _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(_obj->list);
+   list_add_tail(_obj->list, >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 
 #include 
 #include 
+#include 
 
 #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_

[PATCH v6 5/6] drm/i915/gvt: Dmabuf support for GVT-g

2017-05-27 Thread Xiaoguang Chen
dmabuf for GVT-g can be exported to users who can use the dmabuf to show
the desktop of vm which use intel vgpu.

Currently we provide query and create new dmabuf operations.

Users of dmabuf can cache some created dmabufs and related information
such as the framebuffer's address, size, tiling mode, width, height etc.
When refresh the screen first query the currnet vgpu's frambuffer and
compare with the cached ones(address, size, tiling, width, height etc)
if found one then reuse the found dmabuf to gain performance improvment.

If there is no dmabuf created yet or not found in the cached dmabufs then
need to create a new dmabuf. To create a dmabuf first a gem object will
be created and the backing storage of this gem object is the vgpu's
framebuffer(primary/cursor).
Set caching mode, change tiling mode and set domains of this gem object
is not supported.
Then associate this gem object to a dmabuf and export this dmabuf.
A file descriptor will be generated for this dmabuf and this file
descriptor can be sent to user space to do display.

Signed-off-by: Xiaoguang Chen <xiaoguang.c...@intel.com>
---
 drivers/gpu/drm/i915/gvt/Makefile  |   2 +-
 drivers/gpu/drm/i915/gvt/dmabuf.c  | 269 +
 drivers/gpu/drm/i915/gvt/dmabuf.h  |  37 +
 drivers/gpu/drm/i915/gvt/gvt.h |   1 +
 drivers/gpu/drm/i915/i915_gem.c|  26 +++-
 drivers/gpu/drm/i915/i915_gem_object.h |   9 ++
 6 files changed, 342 insertions(+), 2 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/gvt/dmabuf.c
 create mode 100644 drivers/gpu/drm/i915/gvt/dmabuf.h

diff --git a/drivers/gpu/drm/i915/gvt/Makefile 
b/drivers/gpu/drm/i915/gvt/Makefile
index 192ca26..e480f7d 100644
--- a/drivers/gpu/drm/i915/gvt/Makefile
+++ b/drivers/gpu/drm/i915/gvt/Makefile
@@ -2,7 +2,7 @@ GVT_DIR := gvt
 GVT_SOURCE := gvt.o aperture_gm.o handlers.o vgpu.o trace_points.o firmware.o \
interrupt.o gtt.o cfg_space.o opregion.o mmio.o display.o edid.o \
execlist.o scheduler.o sched_policy.o render.o cmd_parser.o \
-   fb_decoder.o
+   fb_decoder.o dmabuf.o
 
 ccflags-y  += -I$(src) -I$(src)/$(GVT_DIR) -Wall
 i915-y += $(addprefix $(GVT_DIR)/, 
$(GVT_SOURCE))
diff --git a/drivers/gpu/drm/i915/gvt/dmabuf.c 
b/drivers/gpu/drm/i915/gvt/dmabuf.c
new file mode 100644
index 000..c831e91
--- /dev/null
+++ b/drivers/gpu/drm/i915/gvt/dmabuf.c
@@ -0,0 +1,269 @@
+/*
+ * Copyright 2017 Intel Corporation. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *Zhiyuan Lv <zhiyuan...@intel.com>
+ *
+ * Contributors:
+ *Xiaoguang Chen <xiaoguang.c...@intel.com>
+ */
+
+#include 
+#include 
+#include 
+
+#include "i915_drv.h"
+#include "gvt.h"
+
+#define GEN8_DECODE_PTE(pte) (pte & GENMASK_ULL(63, 12))
+
+static struct sg_table *intel_vgpu_gem_get_pages(
+   struct drm_i915_gem_object *obj)
+{
+   struct drm_i915_private *dev_priv = to_i915(obj->base.dev);
+   struct sg_table *st;
+   struct scatterlist *sg;
+   int i, ret;
+   gen8_pte_t __iomem *gtt_entries;
+   struct intel_vgpu_fb_info *fb_info;
+
+   fb_info = (struct intel_vgpu_fb_info *)obj->gvt_info;
+   if (WARN_ON(!fb_info))
+   return ERR_PTR(-ENODEV);
+
+   st = kmalloc(sizeof(*st), GFP_KERNEL);
+   if (!st) {
+   ret = -ENOMEM;
+   return ERR_PTR(ret);
+   }
+
+   ret = sg_alloc_table(st, fb_info->fb_size, GFP_KERNEL);
+   if (ret) {
+   kfree(st);
+   return ERR_PTR(ret);
+   }
+   gtt_entries = (gen8_pte_t __iomem *)dev_priv->ggtt.gsm +
+   (fb_info->fb_addr >> PAGE_SHIFT);
+   for_each_sg(st->sgl, sg, fb_info->fb_size, i) {
+   

[PATCH v6 1/6] drm/i915/gvt: Extend the GVT-g architecture to support vfio device region

2017-05-27 Thread Xiaoguang Chen
Signed-off-by: Xiaoguang Chen <xiaoguang.c...@intel.com>
---
 drivers/gpu/drm/i915/gvt/kvmgt.c | 21 ++---
 1 file changed, 18 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
index 1ae0b40..3c6a02b 100644
--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
+++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
@@ -53,11 +53,21 @@ static const struct intel_gvt_ops *intel_gvt_ops;
 #define VFIO_PCI_INDEX_TO_OFFSET(index) ((u64)(index) << VFIO_PCI_OFFSET_SHIFT)
 #define VFIO_PCI_OFFSET_MASK(((u64)(1) << VFIO_PCI_OFFSET_SHIFT) - 1)
 
+struct vfio_region;
+struct intel_vgpu_regops {
+   size_t (*rw)(struct intel_vgpu *vgpu, char *buf,
+   size_t count, loff_t *ppos, bool iswrite);
+   void (*release)(struct intel_vgpu *vgpu,
+   struct vfio_region *region);
+};
+
 struct vfio_region {
u32 type;
u32 subtype;
size_t  size;
u32 flags;
+   const struct intel_vgpu_regops  *ops;
+   void*data;
 };
 
 struct kvmgt_pgfn {
@@ -642,7 +652,7 @@ static ssize_t intel_vgpu_rw(struct mdev_device *mdev, char 
*buf,
int ret = -EINVAL;
 
 
-   if (index >= VFIO_PCI_NUM_REGIONS) {
+   if (index >= VFIO_PCI_NUM_REGIONS + vgpu->vdev.num_regions) {
gvt_vgpu_err("invalid index: %u\n", index);
return -EINVAL;
}
@@ -676,8 +686,11 @@ static ssize_t intel_vgpu_rw(struct mdev_device *mdev, 
char *buf,
case VFIO_PCI_BAR5_REGION_INDEX:
case VFIO_PCI_VGA_REGION_INDEX:
case VFIO_PCI_ROM_REGION_INDEX:
+   break;
default:
-   gvt_vgpu_err("unsupported region: %u\n", index);
+   index -= VFIO_PCI_NUM_REGIONS;
+   return vgpu->vdev.region[index].ops->rw(vgpu, buf, count,
+   ppos, is_write);
}
 
return ret == 0 ? count : ret;
@@ -940,7 +953,8 @@ static long intel_vgpu_ioctl(struct mdev_device *mdev, 
unsigned int cmd,
 
info.flags = VFIO_DEVICE_FLAGS_PCI;
info.flags |= VFIO_DEVICE_FLAGS_RESET;
-   info.num_regions = VFIO_PCI_NUM_REGIONS;
+   info.num_regions = VFIO_PCI_NUM_REGIONS +
+   vgpu->vdev.num_regions;
info.num_irqs = VFIO_PCI_NUM_IRQS;
 
return copy_to_user((void __user *)arg, , minsz) ?
@@ -1061,6 +1075,7 @@ static long intel_vgpu_ioctl(struct mdev_device *mdev, 
unsigned int cmd,
}
 
if (caps.size) {
+   info.flags |= VFIO_REGION_INFO_FLAG_CAPS;
if (info.argsz < sizeof(info) + caps.size) {
info.argsz = sizeof(info) + caps.size;
info.cap_offset = 0;
-- 
2.7.4



[PATCH v6 5/6] drm/i915/gvt: Dmabuf support for GVT-g

2017-05-27 Thread Xiaoguang Chen
dmabuf for GVT-g can be exported to users who can use the dmabuf to show
the desktop of vm which use intel vgpu.

Currently we provide query and create new dmabuf operations.

Users of dmabuf can cache some created dmabufs and related information
such as the framebuffer's address, size, tiling mode, width, height etc.
When refresh the screen first query the currnet vgpu's frambuffer and
compare with the cached ones(address, size, tiling, width, height etc)
if found one then reuse the found dmabuf to gain performance improvment.

If there is no dmabuf created yet or not found in the cached dmabufs then
need to create a new dmabuf. To create a dmabuf first a gem object will
be created and the backing storage of this gem object is the vgpu's
framebuffer(primary/cursor).
Set caching mode, change tiling mode and set domains of this gem object
is not supported.
Then associate this gem object to a dmabuf and export this dmabuf.
A file descriptor will be generated for this dmabuf and this file
descriptor can be sent to user space to do display.

Signed-off-by: Xiaoguang Chen 
---
 drivers/gpu/drm/i915/gvt/Makefile  |   2 +-
 drivers/gpu/drm/i915/gvt/dmabuf.c  | 269 +
 drivers/gpu/drm/i915/gvt/dmabuf.h  |  37 +
 drivers/gpu/drm/i915/gvt/gvt.h |   1 +
 drivers/gpu/drm/i915/i915_gem.c|  26 +++-
 drivers/gpu/drm/i915/i915_gem_object.h |   9 ++
 6 files changed, 342 insertions(+), 2 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/gvt/dmabuf.c
 create mode 100644 drivers/gpu/drm/i915/gvt/dmabuf.h

diff --git a/drivers/gpu/drm/i915/gvt/Makefile 
b/drivers/gpu/drm/i915/gvt/Makefile
index 192ca26..e480f7d 100644
--- a/drivers/gpu/drm/i915/gvt/Makefile
+++ b/drivers/gpu/drm/i915/gvt/Makefile
@@ -2,7 +2,7 @@ GVT_DIR := gvt
 GVT_SOURCE := gvt.o aperture_gm.o handlers.o vgpu.o trace_points.o firmware.o \
interrupt.o gtt.o cfg_space.o opregion.o mmio.o display.o edid.o \
execlist.o scheduler.o sched_policy.o render.o cmd_parser.o \
-   fb_decoder.o
+   fb_decoder.o dmabuf.o
 
 ccflags-y  += -I$(src) -I$(src)/$(GVT_DIR) -Wall
 i915-y += $(addprefix $(GVT_DIR)/, 
$(GVT_SOURCE))
diff --git a/drivers/gpu/drm/i915/gvt/dmabuf.c 
b/drivers/gpu/drm/i915/gvt/dmabuf.c
new file mode 100644
index 000..c831e91
--- /dev/null
+++ b/drivers/gpu/drm/i915/gvt/dmabuf.c
@@ -0,0 +1,269 @@
+/*
+ * Copyright 2017 Intel Corporation. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *Zhiyuan Lv 
+ *
+ * Contributors:
+ *Xiaoguang Chen 
+ */
+
+#include 
+#include 
+#include 
+
+#include "i915_drv.h"
+#include "gvt.h"
+
+#define GEN8_DECODE_PTE(pte) (pte & GENMASK_ULL(63, 12))
+
+static struct sg_table *intel_vgpu_gem_get_pages(
+   struct drm_i915_gem_object *obj)
+{
+   struct drm_i915_private *dev_priv = to_i915(obj->base.dev);
+   struct sg_table *st;
+   struct scatterlist *sg;
+   int i, ret;
+   gen8_pte_t __iomem *gtt_entries;
+   struct intel_vgpu_fb_info *fb_info;
+
+   fb_info = (struct intel_vgpu_fb_info *)obj->gvt_info;
+   if (WARN_ON(!fb_info))
+   return ERR_PTR(-ENODEV);
+
+   st = kmalloc(sizeof(*st), GFP_KERNEL);
+   if (!st) {
+   ret = -ENOMEM;
+   return ERR_PTR(ret);
+   }
+
+   ret = sg_alloc_table(st, fb_info->fb_size, GFP_KERNEL);
+   if (ret) {
+   kfree(st);
+   return ERR_PTR(ret);
+   }
+   gtt_entries = (gen8_pte_t __iomem *)dev_priv->ggtt.gsm +
+   (fb_info->fb_addr >> PAGE_SHIFT);
+   for_each_sg(st->sgl, sg, fb_info->fb_size, i) {
+   sg->offset = 0;
+   sg->length = PAGE_SIZE;
+   

[PATCH v6 1/6] drm/i915/gvt: Extend the GVT-g architecture to support vfio device region

2017-05-27 Thread Xiaoguang Chen
Signed-off-by: Xiaoguang Chen 
---
 drivers/gpu/drm/i915/gvt/kvmgt.c | 21 ++---
 1 file changed, 18 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
index 1ae0b40..3c6a02b 100644
--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
+++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
@@ -53,11 +53,21 @@ static const struct intel_gvt_ops *intel_gvt_ops;
 #define VFIO_PCI_INDEX_TO_OFFSET(index) ((u64)(index) << VFIO_PCI_OFFSET_SHIFT)
 #define VFIO_PCI_OFFSET_MASK(((u64)(1) << VFIO_PCI_OFFSET_SHIFT) - 1)
 
+struct vfio_region;
+struct intel_vgpu_regops {
+   size_t (*rw)(struct intel_vgpu *vgpu, char *buf,
+   size_t count, loff_t *ppos, bool iswrite);
+   void (*release)(struct intel_vgpu *vgpu,
+   struct vfio_region *region);
+};
+
 struct vfio_region {
u32 type;
u32 subtype;
size_t  size;
u32 flags;
+   const struct intel_vgpu_regops  *ops;
+   void*data;
 };
 
 struct kvmgt_pgfn {
@@ -642,7 +652,7 @@ static ssize_t intel_vgpu_rw(struct mdev_device *mdev, char 
*buf,
int ret = -EINVAL;
 
 
-   if (index >= VFIO_PCI_NUM_REGIONS) {
+   if (index >= VFIO_PCI_NUM_REGIONS + vgpu->vdev.num_regions) {
gvt_vgpu_err("invalid index: %u\n", index);
return -EINVAL;
}
@@ -676,8 +686,11 @@ static ssize_t intel_vgpu_rw(struct mdev_device *mdev, 
char *buf,
case VFIO_PCI_BAR5_REGION_INDEX:
case VFIO_PCI_VGA_REGION_INDEX:
case VFIO_PCI_ROM_REGION_INDEX:
+   break;
default:
-   gvt_vgpu_err("unsupported region: %u\n", index);
+   index -= VFIO_PCI_NUM_REGIONS;
+   return vgpu->vdev.region[index].ops->rw(vgpu, buf, count,
+   ppos, is_write);
}
 
return ret == 0 ? count : ret;
@@ -940,7 +953,8 @@ static long intel_vgpu_ioctl(struct mdev_device *mdev, 
unsigned int cmd,
 
info.flags = VFIO_DEVICE_FLAGS_PCI;
info.flags |= VFIO_DEVICE_FLAGS_RESET;
-   info.num_regions = VFIO_PCI_NUM_REGIONS;
+   info.num_regions = VFIO_PCI_NUM_REGIONS +
+   vgpu->vdev.num_regions;
info.num_irqs = VFIO_PCI_NUM_IRQS;
 
return copy_to_user((void __user *)arg, , minsz) ?
@@ -1061,6 +1075,7 @@ static long intel_vgpu_ioctl(struct mdev_device *mdev, 
unsigned int cmd,
}
 
if (caps.size) {
+   info.flags |= VFIO_REGION_INFO_FLAG_CAPS;
if (info.argsz < sizeof(info) + caps.size) {
info.argsz = sizeof(info) + caps.size;
info.cap_offset = 0;
-- 
2.7.4



[PATCH v5 4/5] drm/i915/gvt: Dmabuf support for GVT-g

2017-05-23 Thread Xiaoguang Chen
dmabuf for GVT-g can be exported to users who can use the dmabuf to show
the desktop of vm which use intel vgpu.

Currently we provide query and create new dmabuf operations.

Users of dmabuf can cache some created dmabufs and related information
such as the framebuffer's address, size, tiling mode, width, height etc.
When refresh the screen first query the currnet vgpu's frambuffer and
compare with the cached ones(address, size, tiling, width, height etc)
if found one then reuse the found dmabuf to gain performance improvment.

If there is no dmabuf created yet or not found in the cached dmabufs then
need to create a new dmabuf. To create a dmabuf first a gem object will
be created and the backing storage of this gem object is the vgpu's
framebuffer(primary/cursor).
Set caching mode, change tiling mode and set domains of this gem object
is not supported.
Then associate this gem object to a dmabuf and export this dmabuf.
A file descriptor will be generated for this dmabuf and this file
descriptor can be sent to user space to do display.

Signed-off-by: Xiaoguang Chen <xiaoguang.c...@intel.com>
---
 drivers/gpu/drm/i915/gvt/Makefile  |   2 +-
 drivers/gpu/drm/i915/gvt/dmabuf.c  | 276 +
 drivers/gpu/drm/i915/gvt/dmabuf.h  |  53 +++
 drivers/gpu/drm/i915/gvt/gvt.h |   1 +
 drivers/gpu/drm/i915/i915_gem.c|   8 +
 drivers/gpu/drm/i915/i915_gem_object.h |   9 ++
 6 files changed, 348 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/i915/gvt/dmabuf.c
 create mode 100644 drivers/gpu/drm/i915/gvt/dmabuf.h

diff --git a/drivers/gpu/drm/i915/gvt/Makefile 
b/drivers/gpu/drm/i915/gvt/Makefile
index 192ca26..e480f7d 100644
--- a/drivers/gpu/drm/i915/gvt/Makefile
+++ b/drivers/gpu/drm/i915/gvt/Makefile
@@ -2,7 +2,7 @@ GVT_DIR := gvt
 GVT_SOURCE := gvt.o aperture_gm.o handlers.o vgpu.o trace_points.o firmware.o \
interrupt.o gtt.o cfg_space.o opregion.o mmio.o display.o edid.o \
execlist.o scheduler.o sched_policy.o render.o cmd_parser.o \
-   fb_decoder.o
+   fb_decoder.o dmabuf.o
 
 ccflags-y  += -I$(src) -I$(src)/$(GVT_DIR) -Wall
 i915-y += $(addprefix $(GVT_DIR)/, 
$(GVT_SOURCE))
diff --git a/drivers/gpu/drm/i915/gvt/dmabuf.c 
b/drivers/gpu/drm/i915/gvt/dmabuf.c
new file mode 100644
index 000..415453b
--- /dev/null
+++ b/drivers/gpu/drm/i915/gvt/dmabuf.c
@@ -0,0 +1,276 @@
+/*
+ * Copyright 2017 Intel Corporation. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *Zhiyuan Lv <zhiyuan...@intel.com>
+ *
+ * Contributors:
+ *Xiaoguang Chen <xiaoguang.c...@intel.com>
+ */
+
+#include 
+#include 
+
+#include "i915_drv.h"
+#include "gvt.h"
+
+#define GEN8_DECODE_PTE(pte) \
+   ((dma_addr_t)(u64)pte) >> 12) & 0x7ffULL) << 12))
+
+static struct sg_table *intel_vgpu_gem_get_pages(
+   struct drm_i915_gem_object *obj)
+{
+   struct drm_i915_private *dev_priv = to_i915(obj->base.dev);
+   struct sg_table *st;
+   struct scatterlist *sg;
+   int i, ret;
+   gen8_pte_t __iomem *gtt_entries;
+   unsigned int fb_gma = 0, fb_size = 0;
+   struct intel_vgpu_plane_info *plane_info;
+
+   plane_info = (struct intel_vgpu_plane_info *)obj->gvt_plane_info;
+   if (WARN_ON(!plane_info))
+   return ERR_PTR(-EINVAL);
+
+   fb_gma = plane_info->start;
+   fb_size = plane_info->size;
+
+   st = kmalloc(sizeof(*st), GFP_KERNEL);
+   if (!st) {
+   ret = -ENOMEM;
+   return ERR_PTR(ret);
+   }
+
+   ret = sg_alloc_table(st, fb_size, GFP_KERNEL);
+   if (ret) {
+   kfree(st);
+   return ERR_PTR(ret);
+   }
+   gtt_entries = (gen8_pte_t __io

[PATCH v5 3/5] drm/i915/gvt: Frame buffer decoder support for GVT-g

2017-05-23 Thread Xiaoguang Chen
decode frambuffer attributes of primary, cursor and sprite plane

Signed-off-by: Xiaoguang Chen <xiaoguang.c...@intel.com>
---
 drivers/gpu/drm/i915/gvt/Makefile |   3 +-
 drivers/gpu/drm/i915/gvt/display.c|   2 +-
 drivers/gpu/drm/i915/gvt/display.h|   2 +
 drivers/gpu/drm/i915/gvt/fb_decoder.c | 479 ++
 drivers/gpu/drm/i915/gvt/fb_decoder.h | 170 
 drivers/gpu/drm/i915/gvt/gvt.h|   1 +
 6 files changed, 655 insertions(+), 2 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/gvt/fb_decoder.c
 create mode 100644 drivers/gpu/drm/i915/gvt/fb_decoder.h

diff --git a/drivers/gpu/drm/i915/gvt/Makefile 
b/drivers/gpu/drm/i915/gvt/Makefile
index b123c20..192ca26 100644
--- a/drivers/gpu/drm/i915/gvt/Makefile
+++ b/drivers/gpu/drm/i915/gvt/Makefile
@@ -1,7 +1,8 @@
 GVT_DIR := gvt
 GVT_SOURCE := gvt.o aperture_gm.o handlers.o vgpu.o trace_points.o firmware.o \
interrupt.o gtt.o cfg_space.o opregion.o mmio.o display.o edid.o \
-   execlist.o scheduler.o sched_policy.o render.o cmd_parser.o
+   execlist.o scheduler.o sched_policy.o render.o cmd_parser.o \
+   fb_decoder.o
 
 ccflags-y  += -I$(src) -I$(src)/$(GVT_DIR) -Wall
 i915-y += $(addprefix $(GVT_DIR)/, 
$(GVT_SOURCE))
diff --git a/drivers/gpu/drm/i915/gvt/display.c 
b/drivers/gpu/drm/i915/gvt/display.c
index e0261fc..f5f63c5 100644
--- a/drivers/gpu/drm/i915/gvt/display.c
+++ b/drivers/gpu/drm/i915/gvt/display.c
@@ -67,7 +67,7 @@ static int edp_pipe_is_enabled(struct intel_vgpu *vgpu)
return 1;
 }
 
-static int pipe_is_enabled(struct intel_vgpu *vgpu, int pipe)
+int pipe_is_enabled(struct intel_vgpu *vgpu, int pipe)
 {
struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv;
 
diff --git a/drivers/gpu/drm/i915/gvt/display.h 
b/drivers/gpu/drm/i915/gvt/display.h
index d73de22..b46b868 100644
--- a/drivers/gpu/drm/i915/gvt/display.h
+++ b/drivers/gpu/drm/i915/gvt/display.h
@@ -179,4 +179,6 @@ int intel_vgpu_init_display(struct intel_vgpu *vgpu, u64 
resolution);
 void intel_vgpu_reset_display(struct intel_vgpu *vgpu);
 void intel_vgpu_clean_display(struct intel_vgpu *vgpu);
 
+int pipe_is_enabled(struct intel_vgpu *vgpu, int pipe);
+
 #endif
diff --git a/drivers/gpu/drm/i915/gvt/fb_decoder.c 
b/drivers/gpu/drm/i915/gvt/fb_decoder.c
new file mode 100644
index 000..d4404fd
--- /dev/null
+++ b/drivers/gpu/drm/i915/gvt/fb_decoder.c
@@ -0,0 +1,479 @@
+/*
+ * Copyright(c) 2011-2016 Intel Corporation. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 
THE
+ * SOFTWARE.
+ *
+ * Authors:
+ *Kevin Tian <kevin.t...@intel.com>
+ *
+ * Contributors:
+ *Bing Niu <bing@intel.com>
+ *Xu Han <xu@intel.com>
+ *    Ping Gao <ping.a@intel.com>
+ *Xiaoguang Chen <xiaoguang.c...@intel.com>
+ *Yang Liu <yang2@intel.com>
+ *
+ */
+
+#include 
+#include "i915_drv.h"
+#include "gvt.h"
+
+/* The below definitions are required by guest. */
+// [63:0] x:R:G:B 16:16:16:16 little endian
+#define DRM_FORMAT_XRGB161616_GVT  fourcc_code('X', 'R', '4', '8')
+// [63:0] x:B:G:R 16:16:16:16 little endian
+#define DRM_FORMAT_XBGR161616_GVT  fourcc_code('X', 'B', '4', '8')
+
+#define FORMAT_NUM 16
+struct pixel_format {
+   int drm_format; /* Pixel format in DRM definition */
+   int bpp;/* Bits per pixel, 0 indicates invalid */
+   char *desc; /* The description */
+};
+
+/* non-supported format has bpp default to 0 */
+static struct pixel_format primary_pixel_formats[FORMAT_NUM] = {
+   [0x2] = {DRM_FORMAT_C8, 8, "8-bit Indexed"},
+   [0x5] = {DRM_FORMAT_RGB565, 16, "16-bit BGRX (5:6:5 MSB-R:G:B)"},
+   [0x6] = {DRM_FORMAT_XRGB, 32,
+   "32-bit BG

[PATCH v5 3/5] drm/i915/gvt: Frame buffer decoder support for GVT-g

2017-05-23 Thread Xiaoguang Chen
decode frambuffer attributes of primary, cursor and sprite plane

Signed-off-by: Xiaoguang Chen 
---
 drivers/gpu/drm/i915/gvt/Makefile |   3 +-
 drivers/gpu/drm/i915/gvt/display.c|   2 +-
 drivers/gpu/drm/i915/gvt/display.h|   2 +
 drivers/gpu/drm/i915/gvt/fb_decoder.c | 479 ++
 drivers/gpu/drm/i915/gvt/fb_decoder.h | 170 
 drivers/gpu/drm/i915/gvt/gvt.h|   1 +
 6 files changed, 655 insertions(+), 2 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/gvt/fb_decoder.c
 create mode 100644 drivers/gpu/drm/i915/gvt/fb_decoder.h

diff --git a/drivers/gpu/drm/i915/gvt/Makefile 
b/drivers/gpu/drm/i915/gvt/Makefile
index b123c20..192ca26 100644
--- a/drivers/gpu/drm/i915/gvt/Makefile
+++ b/drivers/gpu/drm/i915/gvt/Makefile
@@ -1,7 +1,8 @@
 GVT_DIR := gvt
 GVT_SOURCE := gvt.o aperture_gm.o handlers.o vgpu.o trace_points.o firmware.o \
interrupt.o gtt.o cfg_space.o opregion.o mmio.o display.o edid.o \
-   execlist.o scheduler.o sched_policy.o render.o cmd_parser.o
+   execlist.o scheduler.o sched_policy.o render.o cmd_parser.o \
+   fb_decoder.o
 
 ccflags-y  += -I$(src) -I$(src)/$(GVT_DIR) -Wall
 i915-y += $(addprefix $(GVT_DIR)/, 
$(GVT_SOURCE))
diff --git a/drivers/gpu/drm/i915/gvt/display.c 
b/drivers/gpu/drm/i915/gvt/display.c
index e0261fc..f5f63c5 100644
--- a/drivers/gpu/drm/i915/gvt/display.c
+++ b/drivers/gpu/drm/i915/gvt/display.c
@@ -67,7 +67,7 @@ static int edp_pipe_is_enabled(struct intel_vgpu *vgpu)
return 1;
 }
 
-static int pipe_is_enabled(struct intel_vgpu *vgpu, int pipe)
+int pipe_is_enabled(struct intel_vgpu *vgpu, int pipe)
 {
struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv;
 
diff --git a/drivers/gpu/drm/i915/gvt/display.h 
b/drivers/gpu/drm/i915/gvt/display.h
index d73de22..b46b868 100644
--- a/drivers/gpu/drm/i915/gvt/display.h
+++ b/drivers/gpu/drm/i915/gvt/display.h
@@ -179,4 +179,6 @@ int intel_vgpu_init_display(struct intel_vgpu *vgpu, u64 
resolution);
 void intel_vgpu_reset_display(struct intel_vgpu *vgpu);
 void intel_vgpu_clean_display(struct intel_vgpu *vgpu);
 
+int pipe_is_enabled(struct intel_vgpu *vgpu, int pipe);
+
 #endif
diff --git a/drivers/gpu/drm/i915/gvt/fb_decoder.c 
b/drivers/gpu/drm/i915/gvt/fb_decoder.c
new file mode 100644
index 000..d4404fd
--- /dev/null
+++ b/drivers/gpu/drm/i915/gvt/fb_decoder.c
@@ -0,0 +1,479 @@
+/*
+ * Copyright(c) 2011-2016 Intel Corporation. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 
THE
+ * SOFTWARE.
+ *
+ * Authors:
+ *Kevin Tian 
+ *
+ * Contributors:
+ *Bing Niu 
+ *Xu Han 
+ *Ping Gao 
+ *Xiaoguang Chen 
+ *Yang Liu 
+ *
+ */
+
+#include 
+#include "i915_drv.h"
+#include "gvt.h"
+
+/* The below definitions are required by guest. */
+// [63:0] x:R:G:B 16:16:16:16 little endian
+#define DRM_FORMAT_XRGB161616_GVT  fourcc_code('X', 'R', '4', '8')
+// [63:0] x:B:G:R 16:16:16:16 little endian
+#define DRM_FORMAT_XBGR161616_GVT  fourcc_code('X', 'B', '4', '8')
+
+#define FORMAT_NUM 16
+struct pixel_format {
+   int drm_format; /* Pixel format in DRM definition */
+   int bpp;/* Bits per pixel, 0 indicates invalid */
+   char *desc; /* The description */
+};
+
+/* non-supported format has bpp default to 0 */
+static struct pixel_format primary_pixel_formats[FORMAT_NUM] = {
+   [0x2] = {DRM_FORMAT_C8, 8, "8-bit Indexed"},
+   [0x5] = {DRM_FORMAT_RGB565, 16, "16-bit BGRX (5:6:5 MSB-R:G:B)"},
+   [0x6] = {DRM_FORMAT_XRGB, 32,
+   "32-bit BGRX (8:8:8:8 MSB-X:R:G:B)"},
+   [0x8] = {DRM_FORMAT_XBGR2101010, 32,
+   "32-bit RGBX (2:10:10:10 MSB-X:B:G:R)"},
+   [0xa] = {DRM_FORMAT_

[PATCH v5 4/5] drm/i915/gvt: Dmabuf support for GVT-g

2017-05-23 Thread Xiaoguang Chen
dmabuf for GVT-g can be exported to users who can use the dmabuf to show
the desktop of vm which use intel vgpu.

Currently we provide query and create new dmabuf operations.

Users of dmabuf can cache some created dmabufs and related information
such as the framebuffer's address, size, tiling mode, width, height etc.
When refresh the screen first query the currnet vgpu's frambuffer and
compare with the cached ones(address, size, tiling, width, height etc)
if found one then reuse the found dmabuf to gain performance improvment.

If there is no dmabuf created yet or not found in the cached dmabufs then
need to create a new dmabuf. To create a dmabuf first a gem object will
be created and the backing storage of this gem object is the vgpu's
framebuffer(primary/cursor).
Set caching mode, change tiling mode and set domains of this gem object
is not supported.
Then associate this gem object to a dmabuf and export this dmabuf.
A file descriptor will be generated for this dmabuf and this file
descriptor can be sent to user space to do display.

Signed-off-by: Xiaoguang Chen 
---
 drivers/gpu/drm/i915/gvt/Makefile  |   2 +-
 drivers/gpu/drm/i915/gvt/dmabuf.c  | 276 +
 drivers/gpu/drm/i915/gvt/dmabuf.h  |  53 +++
 drivers/gpu/drm/i915/gvt/gvt.h |   1 +
 drivers/gpu/drm/i915/i915_gem.c|   8 +
 drivers/gpu/drm/i915/i915_gem_object.h |   9 ++
 6 files changed, 348 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/i915/gvt/dmabuf.c
 create mode 100644 drivers/gpu/drm/i915/gvt/dmabuf.h

diff --git a/drivers/gpu/drm/i915/gvt/Makefile 
b/drivers/gpu/drm/i915/gvt/Makefile
index 192ca26..e480f7d 100644
--- a/drivers/gpu/drm/i915/gvt/Makefile
+++ b/drivers/gpu/drm/i915/gvt/Makefile
@@ -2,7 +2,7 @@ GVT_DIR := gvt
 GVT_SOURCE := gvt.o aperture_gm.o handlers.o vgpu.o trace_points.o firmware.o \
interrupt.o gtt.o cfg_space.o opregion.o mmio.o display.o edid.o \
execlist.o scheduler.o sched_policy.o render.o cmd_parser.o \
-   fb_decoder.o
+   fb_decoder.o dmabuf.o
 
 ccflags-y  += -I$(src) -I$(src)/$(GVT_DIR) -Wall
 i915-y += $(addprefix $(GVT_DIR)/, 
$(GVT_SOURCE))
diff --git a/drivers/gpu/drm/i915/gvt/dmabuf.c 
b/drivers/gpu/drm/i915/gvt/dmabuf.c
new file mode 100644
index 000..415453b
--- /dev/null
+++ b/drivers/gpu/drm/i915/gvt/dmabuf.c
@@ -0,0 +1,276 @@
+/*
+ * Copyright 2017 Intel Corporation. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *Zhiyuan Lv 
+ *
+ * Contributors:
+ *Xiaoguang Chen 
+ */
+
+#include 
+#include 
+
+#include "i915_drv.h"
+#include "gvt.h"
+
+#define GEN8_DECODE_PTE(pte) \
+   ((dma_addr_t)(u64)pte) >> 12) & 0x7ffULL) << 12))
+
+static struct sg_table *intel_vgpu_gem_get_pages(
+   struct drm_i915_gem_object *obj)
+{
+   struct drm_i915_private *dev_priv = to_i915(obj->base.dev);
+   struct sg_table *st;
+   struct scatterlist *sg;
+   int i, ret;
+   gen8_pte_t __iomem *gtt_entries;
+   unsigned int fb_gma = 0, fb_size = 0;
+   struct intel_vgpu_plane_info *plane_info;
+
+   plane_info = (struct intel_vgpu_plane_info *)obj->gvt_plane_info;
+   if (WARN_ON(!plane_info))
+   return ERR_PTR(-EINVAL);
+
+   fb_gma = plane_info->start;
+   fb_size = plane_info->size;
+
+   st = kmalloc(sizeof(*st), GFP_KERNEL);
+   if (!st) {
+   ret = -ENOMEM;
+   return ERR_PTR(ret);
+   }
+
+   ret = sg_alloc_table(st, fb_size, GFP_KERNEL);
+   if (ret) {
+   kfree(st);
+   return ERR_PTR(ret);
+   }
+   gtt_entries = (gen8_pte_t __iomem *)dev_priv->ggtt.gsm +
+   (fb_gma >> PAGE_SHIFT);

[PATCH v5 0/5] drm/i915/gvt: Dma-buf support for GVT-g

2017-05-23 Thread Xiaoguang Chen
v4->v5:
1) fix bug while checking whether the gem obj is gvt's dma-buf when user
change caching mode or domains. Add a helper function to do it.
2) add definition for the query plane and create dma-buf.

v3->v4:
1) fix bug while checking whether the gem obj is gvt's dma-buf when set
caching mode or doamins.

v2->v3:
1) add a field gvt_plane_info in the drm_i915_gem_obj structure to save
the decoded plane information to avoid look up while need the plane info.
2) declare a new flag I915_GEM_OBJECT_IS_GVT_DMABUF in drm_i915_gem_object
to represent the gem obj for gvt's dma-buf. The tiling mode, caching mode
and domains can not be changed for this kind of gem object.
3) change dma-buf related information to be more generic. So other vendor
can use the same interface.

v1->v2:
1) create a management fd for dma-buf operations.
2) alloc gem object's backing storage in gem obj's get_pages() callback.

This patch set adds the dma-buf support for intel GVT-g.
dma-buf is a uniform mechanism to share DMA buffers across different
devices and sub-systems.
dma-buf for intel GVT-g is mainly used to share the vgpu's framebuffer
to other users or sub-systems so they can use the dma-buf to show the
desktop of a vm which uses intel vgpu.

The main idea is we create a gem object and set vgpu's framebuffer as
the backing storage of this gem object. And associate this gem obj
to a dma-buf object then export this dma-buf at the meantime
generate a file descriptor for this dma-buf. Finally deliver this file
descriptor to user space. And user can use this dma-buf fd to do render
or other operations.
User need to create a fd(for intel GVT-g dma-buf support it is a:dma-buf
management fd) then user can use this fd to query the plane information
or create a dma-buf. The life cycle of this fd is managed by GVT-g user
do not need to care about that.

We have an example program on how to use the dma-buf. You can download
the program to have a try. Good luck :)
git repo: https://github.com/01org/igvtg-qemu branch:kvmgt_dmabuf_example

Xiaoguang Chen (5):
  drm/i915/gvt: Extend the GVT-g architecture to support vfio device
region
  drm/i915/gvt: OpRegion support for GVT-g
  drm/i915/gvt: Frame buffer decoder support for GVT-g
  drm/i915/gvt: Dmabuf support for GVT-g
  drm/i915/gvt: Adding interface so user space can get the dma-buf

 drivers/gpu/drm/i915/gvt/Makefile  |   3 +-
 drivers/gpu/drm/i915/gvt/display.c |   2 +-
 drivers/gpu/drm/i915/gvt/display.h |   2 +
 drivers/gpu/drm/i915/gvt/dmabuf.c  | 277 +++
 drivers/gpu/drm/i915/gvt/dmabuf.h  |  32 +++
 drivers/gpu/drm/i915/gvt/fb_decoder.c  | 479 +
 drivers/gpu/drm/i915/gvt/fb_decoder.h  | 168 
 drivers/gpu/drm/i915/gvt/gvt.c |   2 +
 drivers/gpu/drm/i915/gvt/gvt.h |   6 +
 drivers/gpu/drm/i915/gvt/kvmgt.c   | 225 +++-
 drivers/gpu/drm/i915/gvt/opregion.c|   8 +-
 drivers/gpu/drm/i915/i915_gem.c|   8 +
 drivers/gpu/drm/i915/i915_gem_object.h |   9 +
 include/uapi/linux/vfio.h  |  50 +++-
 14 files changed, 1264 insertions(+), 7 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/gvt/dmabuf.c
 create mode 100644 drivers/gpu/drm/i915/gvt/dmabuf.h
 create mode 100644 drivers/gpu/drm/i915/gvt/fb_decoder.c
 create mode 100644 drivers/gpu/drm/i915/gvt/fb_decoder.h

-- 
2.7.4



[PATCH v5 0/5] drm/i915/gvt: Dma-buf support for GVT-g

2017-05-23 Thread Xiaoguang Chen
v4->v5:
1) fix bug while checking whether the gem obj is gvt's dma-buf when user
change caching mode or domains. Add a helper function to do it.
2) add definition for the query plane and create dma-buf.

v3->v4:
1) fix bug while checking whether the gem obj is gvt's dma-buf when set
caching mode or doamins.

v2->v3:
1) add a field gvt_plane_info in the drm_i915_gem_obj structure to save
the decoded plane information to avoid look up while need the plane info.
2) declare a new flag I915_GEM_OBJECT_IS_GVT_DMABUF in drm_i915_gem_object
to represent the gem obj for gvt's dma-buf. The tiling mode, caching mode
and domains can not be changed for this kind of gem object.
3) change dma-buf related information to be more generic. So other vendor
can use the same interface.

v1->v2:
1) create a management fd for dma-buf operations.
2) alloc gem object's backing storage in gem obj's get_pages() callback.

This patch set adds the dma-buf support for intel GVT-g.
dma-buf is a uniform mechanism to share DMA buffers across different
devices and sub-systems.
dma-buf for intel GVT-g is mainly used to share the vgpu's framebuffer
to other users or sub-systems so they can use the dma-buf to show the
desktop of a vm which uses intel vgpu.

The main idea is we create a gem object and set vgpu's framebuffer as
the backing storage of this gem object. And associate this gem obj
to a dma-buf object then export this dma-buf at the meantime
generate a file descriptor for this dma-buf. Finally deliver this file
descriptor to user space. And user can use this dma-buf fd to do render
or other operations.
User need to create a fd(for intel GVT-g dma-buf support it is a:dma-buf
management fd) then user can use this fd to query the plane information
or create a dma-buf. The life cycle of this fd is managed by GVT-g user
do not need to care about that.

We have an example program on how to use the dma-buf. You can download
the program to have a try. Good luck :)
git repo: https://github.com/01org/igvtg-qemu branch:kvmgt_dmabuf_example

Xiaoguang Chen (5):
  drm/i915/gvt: Extend the GVT-g architecture to support vfio device
region
  drm/i915/gvt: OpRegion support for GVT-g
  drm/i915/gvt: Frame buffer decoder support for GVT-g
  drm/i915/gvt: Dmabuf support for GVT-g
  drm/i915/gvt: Adding interface so user space can get the dma-buf

 drivers/gpu/drm/i915/gvt/Makefile  |   3 +-
 drivers/gpu/drm/i915/gvt/display.c |   2 +-
 drivers/gpu/drm/i915/gvt/display.h |   2 +
 drivers/gpu/drm/i915/gvt/dmabuf.c  | 277 +++
 drivers/gpu/drm/i915/gvt/dmabuf.h  |  32 +++
 drivers/gpu/drm/i915/gvt/fb_decoder.c  | 479 +
 drivers/gpu/drm/i915/gvt/fb_decoder.h  | 168 
 drivers/gpu/drm/i915/gvt/gvt.c |   2 +
 drivers/gpu/drm/i915/gvt/gvt.h |   6 +
 drivers/gpu/drm/i915/gvt/kvmgt.c   | 225 +++-
 drivers/gpu/drm/i915/gvt/opregion.c|   8 +-
 drivers/gpu/drm/i915/i915_gem.c|   8 +
 drivers/gpu/drm/i915/i915_gem_object.h |   9 +
 include/uapi/linux/vfio.h  |  50 +++-
 14 files changed, 1264 insertions(+), 7 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/gvt/dmabuf.c
 create mode 100644 drivers/gpu/drm/i915/gvt/dmabuf.h
 create mode 100644 drivers/gpu/drm/i915/gvt/fb_decoder.c
 create mode 100644 drivers/gpu/drm/i915/gvt/fb_decoder.h

-- 
2.7.4



[PATCH v5 1/5] drm/i915/gvt: Extend the GVT-g architecture to support vfio device region

2017-05-23 Thread Xiaoguang Chen
Signed-off-by: Xiaoguang Chen <xiaoguang.c...@intel.com>
---
 drivers/gpu/drm/i915/gvt/kvmgt.c | 21 ++---
 1 file changed, 18 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
index 1ae0b40..3c6a02b 100644
--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
+++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
@@ -53,11 +53,21 @@ static const struct intel_gvt_ops *intel_gvt_ops;
 #define VFIO_PCI_INDEX_TO_OFFSET(index) ((u64)(index) << VFIO_PCI_OFFSET_SHIFT)
 #define VFIO_PCI_OFFSET_MASK(((u64)(1) << VFIO_PCI_OFFSET_SHIFT) - 1)
 
+struct vfio_region;
+struct intel_vgpu_regops {
+   size_t (*rw)(struct intel_vgpu *vgpu, char *buf,
+   size_t count, loff_t *ppos, bool iswrite);
+   void (*release)(struct intel_vgpu *vgpu,
+   struct vfio_region *region);
+};
+
 struct vfio_region {
u32 type;
u32 subtype;
size_t  size;
u32 flags;
+   const struct intel_vgpu_regops  *ops;
+   void*data;
 };
 
 struct kvmgt_pgfn {
@@ -642,7 +652,7 @@ static ssize_t intel_vgpu_rw(struct mdev_device *mdev, char 
*buf,
int ret = -EINVAL;
 
 
-   if (index >= VFIO_PCI_NUM_REGIONS) {
+   if (index >= VFIO_PCI_NUM_REGIONS + vgpu->vdev.num_regions) {
gvt_vgpu_err("invalid index: %u\n", index);
return -EINVAL;
}
@@ -676,8 +686,11 @@ static ssize_t intel_vgpu_rw(struct mdev_device *mdev, 
char *buf,
case VFIO_PCI_BAR5_REGION_INDEX:
case VFIO_PCI_VGA_REGION_INDEX:
case VFIO_PCI_ROM_REGION_INDEX:
+   break;
default:
-   gvt_vgpu_err("unsupported region: %u\n", index);
+   index -= VFIO_PCI_NUM_REGIONS;
+   return vgpu->vdev.region[index].ops->rw(vgpu, buf, count,
+   ppos, is_write);
}
 
return ret == 0 ? count : ret;
@@ -940,7 +953,8 @@ static long intel_vgpu_ioctl(struct mdev_device *mdev, 
unsigned int cmd,
 
info.flags = VFIO_DEVICE_FLAGS_PCI;
info.flags |= VFIO_DEVICE_FLAGS_RESET;
-   info.num_regions = VFIO_PCI_NUM_REGIONS;
+   info.num_regions = VFIO_PCI_NUM_REGIONS +
+   vgpu->vdev.num_regions;
info.num_irqs = VFIO_PCI_NUM_IRQS;
 
return copy_to_user((void __user *)arg, , minsz) ?
@@ -1061,6 +1075,7 @@ static long intel_vgpu_ioctl(struct mdev_device *mdev, 
unsigned int cmd,
}
 
if (caps.size) {
+   info.flags |= VFIO_REGION_INFO_FLAG_CAPS;
if (info.argsz < sizeof(info) + caps.size) {
info.argsz = sizeof(info) + caps.size;
info.cap_offset = 0;
-- 
2.7.4



[PATCH v5 1/5] drm/i915/gvt: Extend the GVT-g architecture to support vfio device region

2017-05-23 Thread Xiaoguang Chen
Signed-off-by: Xiaoguang Chen 
---
 drivers/gpu/drm/i915/gvt/kvmgt.c | 21 ++---
 1 file changed, 18 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
index 1ae0b40..3c6a02b 100644
--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
+++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
@@ -53,11 +53,21 @@ static const struct intel_gvt_ops *intel_gvt_ops;
 #define VFIO_PCI_INDEX_TO_OFFSET(index) ((u64)(index) << VFIO_PCI_OFFSET_SHIFT)
 #define VFIO_PCI_OFFSET_MASK(((u64)(1) << VFIO_PCI_OFFSET_SHIFT) - 1)
 
+struct vfio_region;
+struct intel_vgpu_regops {
+   size_t (*rw)(struct intel_vgpu *vgpu, char *buf,
+   size_t count, loff_t *ppos, bool iswrite);
+   void (*release)(struct intel_vgpu *vgpu,
+   struct vfio_region *region);
+};
+
 struct vfio_region {
u32 type;
u32 subtype;
size_t  size;
u32 flags;
+   const struct intel_vgpu_regops  *ops;
+   void*data;
 };
 
 struct kvmgt_pgfn {
@@ -642,7 +652,7 @@ static ssize_t intel_vgpu_rw(struct mdev_device *mdev, char 
*buf,
int ret = -EINVAL;
 
 
-   if (index >= VFIO_PCI_NUM_REGIONS) {
+   if (index >= VFIO_PCI_NUM_REGIONS + vgpu->vdev.num_regions) {
gvt_vgpu_err("invalid index: %u\n", index);
return -EINVAL;
}
@@ -676,8 +686,11 @@ static ssize_t intel_vgpu_rw(struct mdev_device *mdev, 
char *buf,
case VFIO_PCI_BAR5_REGION_INDEX:
case VFIO_PCI_VGA_REGION_INDEX:
case VFIO_PCI_ROM_REGION_INDEX:
+   break;
default:
-   gvt_vgpu_err("unsupported region: %u\n", index);
+   index -= VFIO_PCI_NUM_REGIONS;
+   return vgpu->vdev.region[index].ops->rw(vgpu, buf, count,
+   ppos, is_write);
}
 
return ret == 0 ? count : ret;
@@ -940,7 +953,8 @@ static long intel_vgpu_ioctl(struct mdev_device *mdev, 
unsigned int cmd,
 
info.flags = VFIO_DEVICE_FLAGS_PCI;
info.flags |= VFIO_DEVICE_FLAGS_RESET;
-   info.num_regions = VFIO_PCI_NUM_REGIONS;
+   info.num_regions = VFIO_PCI_NUM_REGIONS +
+   vgpu->vdev.num_regions;
info.num_irqs = VFIO_PCI_NUM_IRQS;
 
return copy_to_user((void __user *)arg, , minsz) ?
@@ -1061,6 +1075,7 @@ static long intel_vgpu_ioctl(struct mdev_device *mdev, 
unsigned int cmd,
}
 
if (caps.size) {
+   info.flags |= VFIO_REGION_INFO_FLAG_CAPS;
if (info.argsz < sizeof(info) + caps.size) {
info.argsz = sizeof(info) + caps.size;
info.cap_offset = 0;
-- 
2.7.4



[PATCH v5 5/5] drm/i915/gvt: Adding interface so user space can get the dma-buf

2017-05-23 Thread Xiaoguang Chen
User space will try to create a management fd for the dma-buf operation.
Using this management fd user can query the plane information and create
a dma-buf fd if necessary.
GVT-g will handle the life cycle of the management fd and will align the
life cycle of the fd with the vfio device.
User space should handle the life cycle of the created dma-buf fd close
the dma-buf fd timely when finishing use.

Signed-off-by: Xiaoguang Chen <xiaoguang.c...@intel.com>
---
 drivers/gpu/drm/i915/gvt/dmabuf.c |  25 
 drivers/gpu/drm/i915/gvt/dmabuf.h |  21 ---
 drivers/gpu/drm/i915/gvt/fb_decoder.h |   2 -
 drivers/gpu/drm/i915/gvt/gvt.c|   2 +
 drivers/gpu/drm/i915/gvt/gvt.h|   4 ++
 drivers/gpu/drm/i915/gvt/kvmgt.c  | 107 ++
 include/uapi/linux/vfio.h |  50 +++-
 7 files changed, 175 insertions(+), 36 deletions(-)

diff --git a/drivers/gpu/drm/i915/gvt/dmabuf.c 
b/drivers/gpu/drm/i915/gvt/dmabuf.c
index 415453b..a72b86efb 100644
--- a/drivers/gpu/drm/i915/gvt/dmabuf.c
+++ b/drivers/gpu/drm/i915/gvt/dmabuf.c
@@ -29,6 +29,7 @@
 
 #include 
 #include 
+#include 
 
 #include "i915_drv.h"
 #include "gvt.h"
@@ -45,9 +46,9 @@ static struct sg_table *intel_vgpu_gem_get_pages(
int i, ret;
gen8_pte_t __iomem *gtt_entries;
unsigned int fb_gma = 0, fb_size = 0;
-   struct intel_vgpu_plane_info *plane_info;
+   struct plane_info *plane_info;
 
-   plane_info = (struct intel_vgpu_plane_info *)obj->gvt_plane_info;
+   plane_info = (struct plane_info *)obj->gvt_plane_info;
if (WARN_ON(!plane_info))
return ERR_PTR(-EINVAL);
 
@@ -81,9 +82,9 @@ static struct sg_table *intel_vgpu_gem_get_pages(
 static void intel_vgpu_gem_put_pages(struct drm_i915_gem_object *obj,
struct sg_table *pages)
 {
-   struct intel_vgpu_plane_info *plane_info;
+   struct plane_info *plane_info;
 
-   plane_info = (struct intel_vgpu_plane_info *)obj->gvt_plane_info;
+   plane_info = (struct plane_info *)obj->gvt_plane_info;
if (WARN_ON(!plane_info))
return;
 
@@ -98,7 +99,7 @@ static const struct drm_i915_gem_object_ops 
intel_vgpu_gem_ops = {
 };
 
 static struct drm_i915_gem_object *intel_vgpu_create_gem(struct drm_device 
*dev,
-   struct intel_vgpu_plane_info *info)
+   struct plane_info *info)
 {
struct drm_i915_private *pri = dev->dev_private;
struct drm_i915_gem_object *obj;
@@ -141,14 +142,14 @@ static struct drm_i915_gem_object 
*intel_vgpu_create_gem(struct drm_device *dev,
return obj;
 }
 
-static struct intel_vgpu_plane_info *intel_vgpu_get_plane_info(
+static struct plane_info *intel_vgpu_get_plane_info(
struct drm_device *dev,
struct intel_vgpu *vgpu, uint32_t plane_id)
 {
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_vgpu_primary_plane_format *p;
struct intel_vgpu_cursor_plane_format *c;
-   struct intel_vgpu_plane_info *info;
+   struct plane_info *info;
struct intel_vgpu_pipe_format *pipe;
 
info = kmalloc(sizeof(*info), GFP_KERNEL);
@@ -159,7 +160,7 @@ static struct intel_vgpu_plane_info 
*intel_vgpu_get_plane_info(
if (pipe == NULL)
return NULL;
 
-   if (plane_id == INTEL_GVT_PLANE_PRIMARY) {
+   if (plane_id == VFIO_PRIMARY_PLANE) {
p = >primary;
if (p != NULL) {
info->start = p->base;
@@ -175,7 +176,7 @@ static struct intel_vgpu_plane_info 
*intel_vgpu_get_plane_info(
gvt_vgpu_err("invalid primary plane\n");
return NULL;
}
-   } else if (plane_id == INTEL_GVT_PLANE_CURSOR) {
+   } else if (plane_id == VFIO_CURSOR_PLANE) {
c = >cursor;
if (c != NULL) {
info->start = c->base;
@@ -228,7 +229,7 @@ static struct intel_vgpu_plane_info 
*intel_vgpu_get_plane_info(
 int intel_vgpu_query_plane(struct intel_vgpu *vgpu, void *args)
 {
struct drm_device *dev = >gvt->dev_priv->drm;
-   struct intel_vgpu_plane_info *info = args;
+   struct plane_info *info = args;
 
info = intel_vgpu_get_plane_info(dev, vgpu, info->plane_id);
if (info == NULL)
@@ -242,8 +243,8 @@ int intel_vgpu_create_dmabuf(struct intel_vgpu *vgpu, void 
*args)
struct dma_buf *dmabuf;
struct drm_i915_gem_object *obj;
struct drm_device *dev = >gvt->dev_priv->drm;
-   struct intel_vgpu_dmabuf *gvt_dmabuf = args;
-   struct intel_vgpu_plane_info *info;
+   struct dmabuf_info *gvt_dmabuf = args;
+   struct plane_info *info;
int ret;
 
info = intel_vgpu_get_plane_info(dev, vgpu,
diff --git a/drivers/gpu/drm/i915/gvt/dmabuf.h 
b/drivers/gpu/drm/

[PATCH v5 5/5] drm/i915/gvt: Adding interface so user space can get the dma-buf

2017-05-23 Thread Xiaoguang Chen
User space will try to create a management fd for the dma-buf operation.
Using this management fd user can query the plane information and create
a dma-buf fd if necessary.
GVT-g will handle the life cycle of the management fd and will align the
life cycle of the fd with the vfio device.
User space should handle the life cycle of the created dma-buf fd close
the dma-buf fd timely when finishing use.

Signed-off-by: Xiaoguang Chen 
---
 drivers/gpu/drm/i915/gvt/dmabuf.c |  25 
 drivers/gpu/drm/i915/gvt/dmabuf.h |  21 ---
 drivers/gpu/drm/i915/gvt/fb_decoder.h |   2 -
 drivers/gpu/drm/i915/gvt/gvt.c|   2 +
 drivers/gpu/drm/i915/gvt/gvt.h|   4 ++
 drivers/gpu/drm/i915/gvt/kvmgt.c  | 107 ++
 include/uapi/linux/vfio.h |  50 +++-
 7 files changed, 175 insertions(+), 36 deletions(-)

diff --git a/drivers/gpu/drm/i915/gvt/dmabuf.c 
b/drivers/gpu/drm/i915/gvt/dmabuf.c
index 415453b..a72b86efb 100644
--- a/drivers/gpu/drm/i915/gvt/dmabuf.c
+++ b/drivers/gpu/drm/i915/gvt/dmabuf.c
@@ -29,6 +29,7 @@
 
 #include 
 #include 
+#include 
 
 #include "i915_drv.h"
 #include "gvt.h"
@@ -45,9 +46,9 @@ static struct sg_table *intel_vgpu_gem_get_pages(
int i, ret;
gen8_pte_t __iomem *gtt_entries;
unsigned int fb_gma = 0, fb_size = 0;
-   struct intel_vgpu_plane_info *plane_info;
+   struct plane_info *plane_info;
 
-   plane_info = (struct intel_vgpu_plane_info *)obj->gvt_plane_info;
+   plane_info = (struct plane_info *)obj->gvt_plane_info;
if (WARN_ON(!plane_info))
return ERR_PTR(-EINVAL);
 
@@ -81,9 +82,9 @@ static struct sg_table *intel_vgpu_gem_get_pages(
 static void intel_vgpu_gem_put_pages(struct drm_i915_gem_object *obj,
struct sg_table *pages)
 {
-   struct intel_vgpu_plane_info *plane_info;
+   struct plane_info *plane_info;
 
-   plane_info = (struct intel_vgpu_plane_info *)obj->gvt_plane_info;
+   plane_info = (struct plane_info *)obj->gvt_plane_info;
if (WARN_ON(!plane_info))
return;
 
@@ -98,7 +99,7 @@ static const struct drm_i915_gem_object_ops 
intel_vgpu_gem_ops = {
 };
 
 static struct drm_i915_gem_object *intel_vgpu_create_gem(struct drm_device 
*dev,
-   struct intel_vgpu_plane_info *info)
+   struct plane_info *info)
 {
struct drm_i915_private *pri = dev->dev_private;
struct drm_i915_gem_object *obj;
@@ -141,14 +142,14 @@ static struct drm_i915_gem_object 
*intel_vgpu_create_gem(struct drm_device *dev,
return obj;
 }
 
-static struct intel_vgpu_plane_info *intel_vgpu_get_plane_info(
+static struct plane_info *intel_vgpu_get_plane_info(
struct drm_device *dev,
struct intel_vgpu *vgpu, uint32_t plane_id)
 {
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_vgpu_primary_plane_format *p;
struct intel_vgpu_cursor_plane_format *c;
-   struct intel_vgpu_plane_info *info;
+   struct plane_info *info;
struct intel_vgpu_pipe_format *pipe;
 
info = kmalloc(sizeof(*info), GFP_KERNEL);
@@ -159,7 +160,7 @@ static struct intel_vgpu_plane_info 
*intel_vgpu_get_plane_info(
if (pipe == NULL)
return NULL;
 
-   if (plane_id == INTEL_GVT_PLANE_PRIMARY) {
+   if (plane_id == VFIO_PRIMARY_PLANE) {
p = >primary;
if (p != NULL) {
info->start = p->base;
@@ -175,7 +176,7 @@ static struct intel_vgpu_plane_info 
*intel_vgpu_get_plane_info(
gvt_vgpu_err("invalid primary plane\n");
return NULL;
}
-   } else if (plane_id == INTEL_GVT_PLANE_CURSOR) {
+   } else if (plane_id == VFIO_CURSOR_PLANE) {
c = >cursor;
if (c != NULL) {
info->start = c->base;
@@ -228,7 +229,7 @@ static struct intel_vgpu_plane_info 
*intel_vgpu_get_plane_info(
 int intel_vgpu_query_plane(struct intel_vgpu *vgpu, void *args)
 {
struct drm_device *dev = >gvt->dev_priv->drm;
-   struct intel_vgpu_plane_info *info = args;
+   struct plane_info *info = args;
 
info = intel_vgpu_get_plane_info(dev, vgpu, info->plane_id);
if (info == NULL)
@@ -242,8 +243,8 @@ int intel_vgpu_create_dmabuf(struct intel_vgpu *vgpu, void 
*args)
struct dma_buf *dmabuf;
struct drm_i915_gem_object *obj;
struct drm_device *dev = >gvt->dev_priv->drm;
-   struct intel_vgpu_dmabuf *gvt_dmabuf = args;
-   struct intel_vgpu_plane_info *info;
+   struct dmabuf_info *gvt_dmabuf = args;
+   struct plane_info *info;
int ret;
 
info = intel_vgpu_get_plane_info(dev, vgpu,
diff --git a/drivers/gpu/drm/i915/gvt/dmabuf.h 
b/drivers/gpu/drm/i915/gvt/dmabuf.h
index 43562af

[PATCH v5 2/5] drm/i915/gvt: OpRegion support for GVT-g

2017-05-23 Thread Xiaoguang Chen
OpRegion is needed to support display related operation for
intel vgpu.

A vfio device region is added to intel vgpu to deliver the
host OpRegion information to user space so user space can
construct the OpRegion for vgpu.

Signed-off-by: Bing Niu <bing@intel.com>
Signed-off-by: Xiaoguang Chen <xiaoguang.c...@intel.com>
---
 drivers/gpu/drm/i915/gvt/kvmgt.c| 97 +
 drivers/gpu/drm/i915/gvt/opregion.c |  8 ++-
 2 files changed, 104 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
index 3c6a02b..389f072 100644
--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
+++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
@@ -53,6 +53,8 @@ static const struct intel_gvt_ops *intel_gvt_ops;
 #define VFIO_PCI_INDEX_TO_OFFSET(index) ((u64)(index) << VFIO_PCI_OFFSET_SHIFT)
 #define VFIO_PCI_OFFSET_MASK(((u64)(1) << VFIO_PCI_OFFSET_SHIFT) - 1)
 
+#define OPREGION_SIGNATURE "IntelGraphicsMem"
+
 struct vfio_region;
 struct intel_vgpu_regops {
size_t (*rw)(struct intel_vgpu *vgpu, char *buf,
@@ -436,6 +438,92 @@ static void kvmgt_protect_table_del(struct 
kvmgt_guest_info *info,
}
 }
 
+static size_t intel_vgpu_reg_rw_opregion(struct intel_vgpu *vgpu, char *buf,
+   size_t count, loff_t *ppos, bool iswrite)
+{
+   unsigned int i = VFIO_PCI_OFFSET_TO_INDEX(*ppos) -
+   VFIO_PCI_NUM_REGIONS;
+   void *base = vgpu->vdev.region[i].data;
+   loff_t pos = *ppos & VFIO_PCI_OFFSET_MASK;
+
+   if (pos >= vgpu->vdev.region[i].size || iswrite) {
+   gvt_vgpu_err("invalid op or offset for Intel vgpu OpRegion\n");
+   return -EINVAL;
+   }
+   count = min(count, (size_t)(vgpu->vdev.region[i].size - pos));
+   memcpy(buf, base + pos, count);
+
+   return count;
+}
+
+static void intel_vgpu_reg_release_opregion(struct intel_vgpu *vgpu,
+   struct vfio_region *region)
+{
+   memunmap(region->data);
+}
+
+static const struct intel_vgpu_regops intel_vgpu_regops_opregion = {
+   .rw = intel_vgpu_reg_rw_opregion,
+   .release = intel_vgpu_reg_release_opregion,
+};
+
+static int intel_vgpu_register_reg(struct intel_vgpu *vgpu,
+   unsigned int type, unsigned int subtype,
+   const struct intel_vgpu_regops *ops,
+   size_t size, u32 flags, void *data)
+{
+   struct vfio_region *region;
+
+   region = krealloc(vgpu->vdev.region,
+   (vgpu->vdev.num_regions + 1) * sizeof(*region),
+   GFP_KERNEL);
+   if (!region)
+   return -ENOMEM;
+
+   vgpu->vdev.region = region;
+   vgpu->vdev.region[vgpu->vdev.num_regions].type = type;
+   vgpu->vdev.region[vgpu->vdev.num_regions].subtype = subtype;
+   vgpu->vdev.region[vgpu->vdev.num_regions].ops = ops;
+   vgpu->vdev.region[vgpu->vdev.num_regions].size = size;
+   vgpu->vdev.region[vgpu->vdev.num_regions].flags = flags;
+   vgpu->vdev.region[vgpu->vdev.num_regions].data = data;
+   vgpu->vdev.num_regions++;
+
+   return 0;
+}
+
+static int intel_vgpu_reg_init_opregion(struct intel_vgpu *vgpu)
+{
+   unsigned int addr;
+   void *base;
+   int ret;
+
+   addr = vgpu->gvt->opregion.opregion_pa;
+   if (!addr || !(~addr))
+   return -ENODEV;
+
+   base = memremap(addr, OPREGION_SIZE, MEMREMAP_WB);
+   if (!base)
+   return -ENOMEM;
+
+   if (memcmp(base, OPREGION_SIGNATURE, 16)) {
+   memunmap(base);
+   return -EINVAL;
+   }
+
+   ret = intel_vgpu_register_reg(vgpu,
+   PCI_VENDOR_ID_INTEL | VFIO_REGION_TYPE_PCI_VENDOR_TYPE,
+   VFIO_REGION_SUBTYPE_INTEL_IGD_OPREGION,
+   _vgpu_regops_opregion, OPREGION_SIZE,
+   VFIO_REGION_INFO_FLAG_READ, base);
+   if (ret) {
+   memunmap(base);
+   return ret;
+   }
+
+   return ret;
+}
+
 static int intel_vgpu_create(struct kobject *kobj, struct mdev_device *mdev)
 {
struct intel_vgpu *vgpu = NULL;
@@ -467,6 +555,15 @@ static int intel_vgpu_create(struct kobject *kobj, struct 
mdev_device *mdev)
vgpu->vdev.mdev = mdev;
mdev_set_drvdata(mdev, vgpu);
 
+   ret = intel_vgpu_reg_init_opregion(vgpu);
+   if (ret) {
+   gvt_vgpu_err("create OpRegion failed\n");
+   goto out;
+   }
+
+   gvt_dbg_core("create OpRegion succeeded for mdev:%s\n",
+   dev_name(mdev_dev(mdev)));
+
gvt_dbg_core("intel_vgpu_create succeeded for mdev: %s\n",
 dev_name(mdev_dev(mdev)));
ret = 0;
diff --git a/drivers/gpu/drm/i915/gvt/opregion.c 
b/drivers/gpu/drm/i915/gvt/opregion.c
index 3117991.

[PATCH v5 2/5] drm/i915/gvt: OpRegion support for GVT-g

2017-05-23 Thread Xiaoguang Chen
OpRegion is needed to support display related operation for
intel vgpu.

A vfio device region is added to intel vgpu to deliver the
host OpRegion information to user space so user space can
construct the OpRegion for vgpu.

Signed-off-by: Bing Niu 
Signed-off-by: Xiaoguang Chen 
---
 drivers/gpu/drm/i915/gvt/kvmgt.c| 97 +
 drivers/gpu/drm/i915/gvt/opregion.c |  8 ++-
 2 files changed, 104 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
index 3c6a02b..389f072 100644
--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
+++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
@@ -53,6 +53,8 @@ static const struct intel_gvt_ops *intel_gvt_ops;
 #define VFIO_PCI_INDEX_TO_OFFSET(index) ((u64)(index) << VFIO_PCI_OFFSET_SHIFT)
 #define VFIO_PCI_OFFSET_MASK(((u64)(1) << VFIO_PCI_OFFSET_SHIFT) - 1)
 
+#define OPREGION_SIGNATURE "IntelGraphicsMem"
+
 struct vfio_region;
 struct intel_vgpu_regops {
size_t (*rw)(struct intel_vgpu *vgpu, char *buf,
@@ -436,6 +438,92 @@ static void kvmgt_protect_table_del(struct 
kvmgt_guest_info *info,
}
 }
 
+static size_t intel_vgpu_reg_rw_opregion(struct intel_vgpu *vgpu, char *buf,
+   size_t count, loff_t *ppos, bool iswrite)
+{
+   unsigned int i = VFIO_PCI_OFFSET_TO_INDEX(*ppos) -
+   VFIO_PCI_NUM_REGIONS;
+   void *base = vgpu->vdev.region[i].data;
+   loff_t pos = *ppos & VFIO_PCI_OFFSET_MASK;
+
+   if (pos >= vgpu->vdev.region[i].size || iswrite) {
+   gvt_vgpu_err("invalid op or offset for Intel vgpu OpRegion\n");
+   return -EINVAL;
+   }
+   count = min(count, (size_t)(vgpu->vdev.region[i].size - pos));
+   memcpy(buf, base + pos, count);
+
+   return count;
+}
+
+static void intel_vgpu_reg_release_opregion(struct intel_vgpu *vgpu,
+   struct vfio_region *region)
+{
+   memunmap(region->data);
+}
+
+static const struct intel_vgpu_regops intel_vgpu_regops_opregion = {
+   .rw = intel_vgpu_reg_rw_opregion,
+   .release = intel_vgpu_reg_release_opregion,
+};
+
+static int intel_vgpu_register_reg(struct intel_vgpu *vgpu,
+   unsigned int type, unsigned int subtype,
+   const struct intel_vgpu_regops *ops,
+   size_t size, u32 flags, void *data)
+{
+   struct vfio_region *region;
+
+   region = krealloc(vgpu->vdev.region,
+   (vgpu->vdev.num_regions + 1) * sizeof(*region),
+   GFP_KERNEL);
+   if (!region)
+   return -ENOMEM;
+
+   vgpu->vdev.region = region;
+   vgpu->vdev.region[vgpu->vdev.num_regions].type = type;
+   vgpu->vdev.region[vgpu->vdev.num_regions].subtype = subtype;
+   vgpu->vdev.region[vgpu->vdev.num_regions].ops = ops;
+   vgpu->vdev.region[vgpu->vdev.num_regions].size = size;
+   vgpu->vdev.region[vgpu->vdev.num_regions].flags = flags;
+   vgpu->vdev.region[vgpu->vdev.num_regions].data = data;
+   vgpu->vdev.num_regions++;
+
+   return 0;
+}
+
+static int intel_vgpu_reg_init_opregion(struct intel_vgpu *vgpu)
+{
+   unsigned int addr;
+   void *base;
+   int ret;
+
+   addr = vgpu->gvt->opregion.opregion_pa;
+   if (!addr || !(~addr))
+   return -ENODEV;
+
+   base = memremap(addr, OPREGION_SIZE, MEMREMAP_WB);
+   if (!base)
+   return -ENOMEM;
+
+   if (memcmp(base, OPREGION_SIGNATURE, 16)) {
+   memunmap(base);
+   return -EINVAL;
+   }
+
+   ret = intel_vgpu_register_reg(vgpu,
+   PCI_VENDOR_ID_INTEL | VFIO_REGION_TYPE_PCI_VENDOR_TYPE,
+   VFIO_REGION_SUBTYPE_INTEL_IGD_OPREGION,
+   _vgpu_regops_opregion, OPREGION_SIZE,
+   VFIO_REGION_INFO_FLAG_READ, base);
+   if (ret) {
+   memunmap(base);
+   return ret;
+   }
+
+   return ret;
+}
+
 static int intel_vgpu_create(struct kobject *kobj, struct mdev_device *mdev)
 {
struct intel_vgpu *vgpu = NULL;
@@ -467,6 +555,15 @@ static int intel_vgpu_create(struct kobject *kobj, struct 
mdev_device *mdev)
vgpu->vdev.mdev = mdev;
mdev_set_drvdata(mdev, vgpu);
 
+   ret = intel_vgpu_reg_init_opregion(vgpu);
+   if (ret) {
+   gvt_vgpu_err("create OpRegion failed\n");
+   goto out;
+   }
+
+   gvt_dbg_core("create OpRegion succeeded for mdev:%s\n",
+   dev_name(mdev_dev(mdev)));
+
gvt_dbg_core("intel_vgpu_create succeeded for mdev: %s\n",
 dev_name(mdev_dev(mdev)));
ret = 0;
diff --git a/drivers/gpu/drm/i915/gvt/opregion.c 
b/drivers/gpu/drm/i915/gvt/opregion.c
index 3117991..5c7496d 100644
--- a/drivers/gpu/drm/i915

[PATCH v4 2/5] drm/i915/gvt: OpRegion support for GVT-g

2017-05-22 Thread Xiaoguang Chen
OpRegion is needed to support display related operation for
intel vgpu.

A vfio device region is added to intel vgpu to deliver the
host OpRegion information to user space so user space can
construct the OpRegion for vgpu.

Signed-off-by: Bing Niu <bing@intel.com>
Signed-off-by: Xiaoguang Chen <xiaoguang.c...@intel.com>
---
 drivers/gpu/drm/i915/gvt/kvmgt.c| 97 +
 drivers/gpu/drm/i915/gvt/opregion.c |  8 ++-
 2 files changed, 104 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
index 3c6a02b..389f072 100644
--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
+++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
@@ -53,6 +53,8 @@ static const struct intel_gvt_ops *intel_gvt_ops;
 #define VFIO_PCI_INDEX_TO_OFFSET(index) ((u64)(index) << VFIO_PCI_OFFSET_SHIFT)
 #define VFIO_PCI_OFFSET_MASK(((u64)(1) << VFIO_PCI_OFFSET_SHIFT) - 1)
 
+#define OPREGION_SIGNATURE "IntelGraphicsMem"
+
 struct vfio_region;
 struct intel_vgpu_regops {
size_t (*rw)(struct intel_vgpu *vgpu, char *buf,
@@ -436,6 +438,92 @@ static void kvmgt_protect_table_del(struct 
kvmgt_guest_info *info,
}
 }
 
+static size_t intel_vgpu_reg_rw_opregion(struct intel_vgpu *vgpu, char *buf,
+   size_t count, loff_t *ppos, bool iswrite)
+{
+   unsigned int i = VFIO_PCI_OFFSET_TO_INDEX(*ppos) -
+   VFIO_PCI_NUM_REGIONS;
+   void *base = vgpu->vdev.region[i].data;
+   loff_t pos = *ppos & VFIO_PCI_OFFSET_MASK;
+
+   if (pos >= vgpu->vdev.region[i].size || iswrite) {
+   gvt_vgpu_err("invalid op or offset for Intel vgpu OpRegion\n");
+   return -EINVAL;
+   }
+   count = min(count, (size_t)(vgpu->vdev.region[i].size - pos));
+   memcpy(buf, base + pos, count);
+
+   return count;
+}
+
+static void intel_vgpu_reg_release_opregion(struct intel_vgpu *vgpu,
+   struct vfio_region *region)
+{
+   memunmap(region->data);
+}
+
+static const struct intel_vgpu_regops intel_vgpu_regops_opregion = {
+   .rw = intel_vgpu_reg_rw_opregion,
+   .release = intel_vgpu_reg_release_opregion,
+};
+
+static int intel_vgpu_register_reg(struct intel_vgpu *vgpu,
+   unsigned int type, unsigned int subtype,
+   const struct intel_vgpu_regops *ops,
+   size_t size, u32 flags, void *data)
+{
+   struct vfio_region *region;
+
+   region = krealloc(vgpu->vdev.region,
+   (vgpu->vdev.num_regions + 1) * sizeof(*region),
+   GFP_KERNEL);
+   if (!region)
+   return -ENOMEM;
+
+   vgpu->vdev.region = region;
+   vgpu->vdev.region[vgpu->vdev.num_regions].type = type;
+   vgpu->vdev.region[vgpu->vdev.num_regions].subtype = subtype;
+   vgpu->vdev.region[vgpu->vdev.num_regions].ops = ops;
+   vgpu->vdev.region[vgpu->vdev.num_regions].size = size;
+   vgpu->vdev.region[vgpu->vdev.num_regions].flags = flags;
+   vgpu->vdev.region[vgpu->vdev.num_regions].data = data;
+   vgpu->vdev.num_regions++;
+
+   return 0;
+}
+
+static int intel_vgpu_reg_init_opregion(struct intel_vgpu *vgpu)
+{
+   unsigned int addr;
+   void *base;
+   int ret;
+
+   addr = vgpu->gvt->opregion.opregion_pa;
+   if (!addr || !(~addr))
+   return -ENODEV;
+
+   base = memremap(addr, OPREGION_SIZE, MEMREMAP_WB);
+   if (!base)
+   return -ENOMEM;
+
+   if (memcmp(base, OPREGION_SIGNATURE, 16)) {
+   memunmap(base);
+   return -EINVAL;
+   }
+
+   ret = intel_vgpu_register_reg(vgpu,
+   PCI_VENDOR_ID_INTEL | VFIO_REGION_TYPE_PCI_VENDOR_TYPE,
+   VFIO_REGION_SUBTYPE_INTEL_IGD_OPREGION,
+   _vgpu_regops_opregion, OPREGION_SIZE,
+   VFIO_REGION_INFO_FLAG_READ, base);
+   if (ret) {
+   memunmap(base);
+   return ret;
+   }
+
+   return ret;
+}
+
 static int intel_vgpu_create(struct kobject *kobj, struct mdev_device *mdev)
 {
struct intel_vgpu *vgpu = NULL;
@@ -467,6 +555,15 @@ static int intel_vgpu_create(struct kobject *kobj, struct 
mdev_device *mdev)
vgpu->vdev.mdev = mdev;
mdev_set_drvdata(mdev, vgpu);
 
+   ret = intel_vgpu_reg_init_opregion(vgpu);
+   if (ret) {
+   gvt_vgpu_err("create OpRegion failed\n");
+   goto out;
+   }
+
+   gvt_dbg_core("create OpRegion succeeded for mdev:%s\n",
+   dev_name(mdev_dev(mdev)));
+
gvt_dbg_core("intel_vgpu_create succeeded for mdev: %s\n",
 dev_name(mdev_dev(mdev)));
ret = 0;
diff --git a/drivers/gpu/drm/i915/gvt/opregion.c 
b/drivers/gpu/drm/i915/gvt/opregion.c
index 3117991.

[PATCH v4 2/5] drm/i915/gvt: OpRegion support for GVT-g

2017-05-22 Thread Xiaoguang Chen
OpRegion is needed to support display related operation for
intel vgpu.

A vfio device region is added to intel vgpu to deliver the
host OpRegion information to user space so user space can
construct the OpRegion for vgpu.

Signed-off-by: Bing Niu 
Signed-off-by: Xiaoguang Chen 
---
 drivers/gpu/drm/i915/gvt/kvmgt.c| 97 +
 drivers/gpu/drm/i915/gvt/opregion.c |  8 ++-
 2 files changed, 104 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
index 3c6a02b..389f072 100644
--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
+++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
@@ -53,6 +53,8 @@ static const struct intel_gvt_ops *intel_gvt_ops;
 #define VFIO_PCI_INDEX_TO_OFFSET(index) ((u64)(index) << VFIO_PCI_OFFSET_SHIFT)
 #define VFIO_PCI_OFFSET_MASK(((u64)(1) << VFIO_PCI_OFFSET_SHIFT) - 1)
 
+#define OPREGION_SIGNATURE "IntelGraphicsMem"
+
 struct vfio_region;
 struct intel_vgpu_regops {
size_t (*rw)(struct intel_vgpu *vgpu, char *buf,
@@ -436,6 +438,92 @@ static void kvmgt_protect_table_del(struct 
kvmgt_guest_info *info,
}
 }
 
+static size_t intel_vgpu_reg_rw_opregion(struct intel_vgpu *vgpu, char *buf,
+   size_t count, loff_t *ppos, bool iswrite)
+{
+   unsigned int i = VFIO_PCI_OFFSET_TO_INDEX(*ppos) -
+   VFIO_PCI_NUM_REGIONS;
+   void *base = vgpu->vdev.region[i].data;
+   loff_t pos = *ppos & VFIO_PCI_OFFSET_MASK;
+
+   if (pos >= vgpu->vdev.region[i].size || iswrite) {
+   gvt_vgpu_err("invalid op or offset for Intel vgpu OpRegion\n");
+   return -EINVAL;
+   }
+   count = min(count, (size_t)(vgpu->vdev.region[i].size - pos));
+   memcpy(buf, base + pos, count);
+
+   return count;
+}
+
+static void intel_vgpu_reg_release_opregion(struct intel_vgpu *vgpu,
+   struct vfio_region *region)
+{
+   memunmap(region->data);
+}
+
+static const struct intel_vgpu_regops intel_vgpu_regops_opregion = {
+   .rw = intel_vgpu_reg_rw_opregion,
+   .release = intel_vgpu_reg_release_opregion,
+};
+
+static int intel_vgpu_register_reg(struct intel_vgpu *vgpu,
+   unsigned int type, unsigned int subtype,
+   const struct intel_vgpu_regops *ops,
+   size_t size, u32 flags, void *data)
+{
+   struct vfio_region *region;
+
+   region = krealloc(vgpu->vdev.region,
+   (vgpu->vdev.num_regions + 1) * sizeof(*region),
+   GFP_KERNEL);
+   if (!region)
+   return -ENOMEM;
+
+   vgpu->vdev.region = region;
+   vgpu->vdev.region[vgpu->vdev.num_regions].type = type;
+   vgpu->vdev.region[vgpu->vdev.num_regions].subtype = subtype;
+   vgpu->vdev.region[vgpu->vdev.num_regions].ops = ops;
+   vgpu->vdev.region[vgpu->vdev.num_regions].size = size;
+   vgpu->vdev.region[vgpu->vdev.num_regions].flags = flags;
+   vgpu->vdev.region[vgpu->vdev.num_regions].data = data;
+   vgpu->vdev.num_regions++;
+
+   return 0;
+}
+
+static int intel_vgpu_reg_init_opregion(struct intel_vgpu *vgpu)
+{
+   unsigned int addr;
+   void *base;
+   int ret;
+
+   addr = vgpu->gvt->opregion.opregion_pa;
+   if (!addr || !(~addr))
+   return -ENODEV;
+
+   base = memremap(addr, OPREGION_SIZE, MEMREMAP_WB);
+   if (!base)
+   return -ENOMEM;
+
+   if (memcmp(base, OPREGION_SIGNATURE, 16)) {
+   memunmap(base);
+   return -EINVAL;
+   }
+
+   ret = intel_vgpu_register_reg(vgpu,
+   PCI_VENDOR_ID_INTEL | VFIO_REGION_TYPE_PCI_VENDOR_TYPE,
+   VFIO_REGION_SUBTYPE_INTEL_IGD_OPREGION,
+   _vgpu_regops_opregion, OPREGION_SIZE,
+   VFIO_REGION_INFO_FLAG_READ, base);
+   if (ret) {
+   memunmap(base);
+   return ret;
+   }
+
+   return ret;
+}
+
 static int intel_vgpu_create(struct kobject *kobj, struct mdev_device *mdev)
 {
struct intel_vgpu *vgpu = NULL;
@@ -467,6 +555,15 @@ static int intel_vgpu_create(struct kobject *kobj, struct 
mdev_device *mdev)
vgpu->vdev.mdev = mdev;
mdev_set_drvdata(mdev, vgpu);
 
+   ret = intel_vgpu_reg_init_opregion(vgpu);
+   if (ret) {
+   gvt_vgpu_err("create OpRegion failed\n");
+   goto out;
+   }
+
+   gvt_dbg_core("create OpRegion succeeded for mdev:%s\n",
+   dev_name(mdev_dev(mdev)));
+
gvt_dbg_core("intel_vgpu_create succeeded for mdev: %s\n",
 dev_name(mdev_dev(mdev)));
ret = 0;
diff --git a/drivers/gpu/drm/i915/gvt/opregion.c 
b/drivers/gpu/drm/i915/gvt/opregion.c
index 3117991..5c7496d 100644
--- a/drivers/gpu/drm/i915

[PATCH v4 5/5] drm/i915/gvt: Adding interface so user space can get the dma-buf

2017-05-22 Thread Xiaoguang Chen
User space will try to create a management fd for the dma-buf operation.
Using this management fd user can query the plane information and create
a dma-buf fd if necessary.
GVT-g will handle the life cycle of the management fd and will align the
life cycle of the fd with the vfio device.
User space should handle the life cycle of the created dma-buf fd close
the dma-buf fd timely when finishing use.

Signed-off-by: Xiaoguang Chen <xiaoguang.c...@intel.com>
---
 drivers/gpu/drm/i915/gvt/dmabuf.c | 23 ++-
 drivers/gpu/drm/i915/gvt/dmabuf.h | 22 --
 drivers/gpu/drm/i915/gvt/gvt.c|  2 +
 drivers/gpu/drm/i915/gvt/gvt.h|  3 ++
 drivers/gpu/drm/i915/gvt/kvmgt.c  | 87 +++
 include/uapi/linux/vfio.h | 36 
 6 files changed, 140 insertions(+), 33 deletions(-)

diff --git a/drivers/gpu/drm/i915/gvt/dmabuf.c 
b/drivers/gpu/drm/i915/gvt/dmabuf.c
index c9f283c..c74762f 100644
--- a/drivers/gpu/drm/i915/gvt/dmabuf.c
+++ b/drivers/gpu/drm/i915/gvt/dmabuf.c
@@ -29,6 +29,7 @@
 
 #include 
 #include 
+#include 
 
 #include "i915_drv.h"
 #include "gvt.h"
@@ -45,9 +46,9 @@ static struct sg_table *intel_vgpu_gem_get_pages(
int i, ret;
gen8_pte_t __iomem *gtt_entries;
unsigned int fb_gma = 0, fb_size = 0;
-   struct intel_vgpu_plane_info *plane_info;
+   struct plane_info *plane_info;
 
-   plane_info = (struct intel_vgpu_plane_info *)obj->gvt_plane_info;
+   plane_info = (struct plane_info *)obj->gvt_plane_info;
if (WARN_ON(!plane_info))
return ERR_PTR(-EINVAL);
 
@@ -81,9 +82,9 @@ static struct sg_table *intel_vgpu_gem_get_pages(
 static void intel_vgpu_gem_put_pages(struct drm_i915_gem_object *obj,
struct sg_table *pages)
 {
-   struct intel_vgpu_plane_info *plane_info;
+   struct plane_info *plane_info;
 
-   plane_info = (struct intel_vgpu_plane_info *)obj->gvt_plane_info;
+   plane_info = (struct plane_info *)obj->gvt_plane_info;
if (WARN_ON(!plane_info))
return;
 
@@ -98,7 +99,7 @@ static const struct drm_i915_gem_object_ops 
intel_vgpu_gem_ops = {
 };
 
 static struct drm_i915_gem_object *intel_vgpu_create_gem(struct drm_device 
*dev,
-   struct intel_vgpu_plane_info *info)
+   struct plane_info *info)
 {
struct drm_i915_private *pri = dev->dev_private;
struct drm_i915_gem_object *obj;
@@ -141,14 +142,14 @@ static struct drm_i915_gem_object 
*intel_vgpu_create_gem(struct drm_device *dev,
return obj;
 }
 
-static struct intel_vgpu_plane_info *intel_vgpu_get_plane_info(
+static struct plane_info *intel_vgpu_get_plane_info(
struct drm_device *dev,
struct intel_vgpu *vgpu, int plane_id)
 {
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_vgpu_primary_plane_format *p;
struct intel_vgpu_cursor_plane_format *c;
-   struct intel_vgpu_plane_info *info;
+   struct plane_info *info;
 
info = kmalloc(sizeof(*info), GFP_KERNEL);
if (!info)
@@ -225,8 +226,8 @@ static struct intel_vgpu_plane_info 
*intel_vgpu_get_plane_info(
 int intel_vgpu_query_dmabuf(struct intel_vgpu *vgpu, void *args)
 {
struct drm_device *dev = >gvt->dev_priv->drm;
-   struct intel_vgpu_dmabuf *gvt_dmabuf = args;
-   struct intel_vgpu_plane_info *info;
+   struct dmabuf_info *gvt_dmabuf = args;
+   struct plane_info *info;
 
info = intel_vgpu_get_plane_info(dev, vgpu, gvt_dmabuf->plane_id);
if (info == NULL)
@@ -242,8 +243,8 @@ int intel_vgpu_create_dmabuf(struct intel_vgpu *vgpu, void 
*args)
struct dma_buf *dmabuf;
struct drm_i915_gem_object *obj;
struct drm_device *dev = >gvt->dev_priv->drm;
-   struct intel_vgpu_dmabuf *gvt_dmabuf = args;
-   struct intel_vgpu_plane_info *info;
+   struct dmabuf_info *gvt_dmabuf = args;
+   struct plane_info *info;
int ret;
 
info = intel_vgpu_get_plane_info(dev, vgpu, gvt_dmabuf->plane_id);
diff --git a/drivers/gpu/drm/i915/gvt/dmabuf.h 
b/drivers/gpu/drm/i915/gvt/dmabuf.h
index c7ce642..0ddea78 100644
--- a/drivers/gpu/drm/i915/gvt/dmabuf.h
+++ b/drivers/gpu/drm/i915/gvt/dmabuf.h
@@ -26,28 +26,6 @@
 #ifndef _GVT_DMABUF_H_
 #define _GVT_DMABUF_H_
 
-struct intel_vgpu_plane_info {
-   uint32_t drm_format;
-   uint32_t width;
-   uint32_t height;
-   uint32_t stride;
-   uint32_t start;
-   uint32_t x_pos;
-   uint32_t y_pos;
-   uint32_t size;
-   uint64_t drm_format_mod;
-};
-
-#define INTEL_VGPU_QUERY_DMABUF0
-#define INTEL_VGPU_GENERATE_DMABUF 1
-
-struct intel_vgpu_dmabuf {
-   uint32_t plane_id;
-   /* out */
-   uint32_t fd;
-   struct intel_vgpu_plane_info plane_info;
-};
-
 int intel_vgpu_query_dmabuf(struct intel_vgpu *vgpu, void *args

[PATCH v4 4/5] drm/i915/gvt: Dmabuf support for GVT-g

2017-05-22 Thread Xiaoguang Chen
dmabuf for GVT-g can be exported to users who can use the dmabuf to show
the desktop of vm which use intel vgpu.

Currently we provide query and create new dmabuf operations.

Users of dmabuf can cache some created dmabufs and related information
such as the framebuffer's address, size, tiling mode, width, height etc.
When refresh the screen first query the currnet vgpu's frambuffer and
compare with the cached ones(address, size, tiling, width, height etc)
if found one then reuse the found dmabuf to gain performance improvment.

If there is no dmabuf created yet or not found in the cached dmabufs then
need to create a new dmabuf. To create a dmabuf first a gem object will
be created and the backing storage of this gem object is the vgpu's
framebuffer(primary/cursor).
Set caching mode, change tiling mode and set domains of this gem object
is not supported.
Then associate this gem object to a dmabuf and export this dmabuf.
A file descriptor will be generated for this dmabuf and this file
descriptor can be sent to user space to do display.

Signed-off-by: Xiaoguang Chen <xiaoguang.c...@intel.com>
---
 drivers/gpu/drm/i915/gvt/Makefile  |   2 +-
 drivers/gpu/drm/i915/gvt/dmabuf.c  | 275 +
 drivers/gpu/drm/i915/gvt/dmabuf.h  |  54 +++
 drivers/gpu/drm/i915/gvt/gvt.h |   1 +
 drivers/gpu/drm/i915/i915_gem.c|   8 +
 drivers/gpu/drm/i915/i915_gem_object.h |   3 +
 6 files changed, 342 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/i915/gvt/dmabuf.c
 create mode 100644 drivers/gpu/drm/i915/gvt/dmabuf.h

diff --git a/drivers/gpu/drm/i915/gvt/Makefile 
b/drivers/gpu/drm/i915/gvt/Makefile
index 192ca26..e480f7d 100644
--- a/drivers/gpu/drm/i915/gvt/Makefile
+++ b/drivers/gpu/drm/i915/gvt/Makefile
@@ -2,7 +2,7 @@ GVT_DIR := gvt
 GVT_SOURCE := gvt.o aperture_gm.o handlers.o vgpu.o trace_points.o firmware.o \
interrupt.o gtt.o cfg_space.o opregion.o mmio.o display.o edid.o \
execlist.o scheduler.o sched_policy.o render.o cmd_parser.o \
-   fb_decoder.o
+   fb_decoder.o dmabuf.o
 
 ccflags-y  += -I$(src) -I$(src)/$(GVT_DIR) -Wall
 i915-y += $(addprefix $(GVT_DIR)/, 
$(GVT_SOURCE))
diff --git a/drivers/gpu/drm/i915/gvt/dmabuf.c 
b/drivers/gpu/drm/i915/gvt/dmabuf.c
new file mode 100644
index 000..c9f283c
--- /dev/null
+++ b/drivers/gpu/drm/i915/gvt/dmabuf.c
@@ -0,0 +1,275 @@
+/*
+ * Copyright 2017 Intel Corporation. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *Zhiyuan Lv <zhiyuan...@intel.com>
+ *
+ * Contributors:
+ *Xiaoguang Chen <xiaoguang.c...@intel.com>
+ */
+
+#include 
+#include 
+
+#include "i915_drv.h"
+#include "gvt.h"
+
+#define GEN8_DECODE_PTE(pte) \
+   ((dma_addr_t)(u64)pte) >> 12) & 0x7ffULL) << 12))
+
+static struct sg_table *intel_vgpu_gem_get_pages(
+   struct drm_i915_gem_object *obj)
+{
+   struct drm_i915_private *dev_priv = to_i915(obj->base.dev);
+   struct sg_table *st;
+   struct scatterlist *sg;
+   int i, ret;
+   gen8_pte_t __iomem *gtt_entries;
+   unsigned int fb_gma = 0, fb_size = 0;
+   struct intel_vgpu_plane_info *plane_info;
+
+   plane_info = (struct intel_vgpu_plane_info *)obj->gvt_plane_info;
+   if (WARN_ON(!plane_info))
+   return ERR_PTR(-EINVAL);
+
+   fb_gma = plane_info->start;
+   fb_size = plane_info->size;
+
+   st = kmalloc(sizeof(*st), GFP_KERNEL);
+   if (!st) {
+   ret = -ENOMEM;
+   return ERR_PTR(ret);
+   }
+
+   ret = sg_alloc_table(st, fb_size, GFP_KERNEL);
+   if (ret) {
+   kfree(st);
+   return ERR_PTR(ret);
+   }
+   gtt_entries = (gen8_pte_t __io

[PATCH v4 1/5] drm/i915/gvt: Extend the GVT-g architecture to support vfio device region

2017-05-22 Thread Xiaoguang Chen
Signed-off-by: Xiaoguang Chen <xiaoguang.c...@intel.com>
---
 drivers/gpu/drm/i915/gvt/kvmgt.c | 21 ++---
 1 file changed, 18 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
index 1ae0b40..3c6a02b 100644
--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
+++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
@@ -53,11 +53,21 @@ static const struct intel_gvt_ops *intel_gvt_ops;
 #define VFIO_PCI_INDEX_TO_OFFSET(index) ((u64)(index) << VFIO_PCI_OFFSET_SHIFT)
 #define VFIO_PCI_OFFSET_MASK(((u64)(1) << VFIO_PCI_OFFSET_SHIFT) - 1)
 
+struct vfio_region;
+struct intel_vgpu_regops {
+   size_t (*rw)(struct intel_vgpu *vgpu, char *buf,
+   size_t count, loff_t *ppos, bool iswrite);
+   void (*release)(struct intel_vgpu *vgpu,
+   struct vfio_region *region);
+};
+
 struct vfio_region {
u32 type;
u32 subtype;
size_t  size;
u32 flags;
+   const struct intel_vgpu_regops  *ops;
+   void*data;
 };
 
 struct kvmgt_pgfn {
@@ -642,7 +652,7 @@ static ssize_t intel_vgpu_rw(struct mdev_device *mdev, char 
*buf,
int ret = -EINVAL;
 
 
-   if (index >= VFIO_PCI_NUM_REGIONS) {
+   if (index >= VFIO_PCI_NUM_REGIONS + vgpu->vdev.num_regions) {
gvt_vgpu_err("invalid index: %u\n", index);
return -EINVAL;
}
@@ -676,8 +686,11 @@ static ssize_t intel_vgpu_rw(struct mdev_device *mdev, 
char *buf,
case VFIO_PCI_BAR5_REGION_INDEX:
case VFIO_PCI_VGA_REGION_INDEX:
case VFIO_PCI_ROM_REGION_INDEX:
+   break;
default:
-   gvt_vgpu_err("unsupported region: %u\n", index);
+   index -= VFIO_PCI_NUM_REGIONS;
+   return vgpu->vdev.region[index].ops->rw(vgpu, buf, count,
+   ppos, is_write);
}
 
return ret == 0 ? count : ret;
@@ -940,7 +953,8 @@ static long intel_vgpu_ioctl(struct mdev_device *mdev, 
unsigned int cmd,
 
info.flags = VFIO_DEVICE_FLAGS_PCI;
info.flags |= VFIO_DEVICE_FLAGS_RESET;
-   info.num_regions = VFIO_PCI_NUM_REGIONS;
+   info.num_regions = VFIO_PCI_NUM_REGIONS +
+   vgpu->vdev.num_regions;
info.num_irqs = VFIO_PCI_NUM_IRQS;
 
return copy_to_user((void __user *)arg, , minsz) ?
@@ -1061,6 +1075,7 @@ static long intel_vgpu_ioctl(struct mdev_device *mdev, 
unsigned int cmd,
}
 
if (caps.size) {
+   info.flags |= VFIO_REGION_INFO_FLAG_CAPS;
if (info.argsz < sizeof(info) + caps.size) {
info.argsz = sizeof(info) + caps.size;
info.cap_offset = 0;
-- 
2.7.4



[PATCH v4 4/5] drm/i915/gvt: Dmabuf support for GVT-g

2017-05-22 Thread Xiaoguang Chen
dmabuf for GVT-g can be exported to users who can use the dmabuf to show
the desktop of vm which use intel vgpu.

Currently we provide query and create new dmabuf operations.

Users of dmabuf can cache some created dmabufs and related information
such as the framebuffer's address, size, tiling mode, width, height etc.
When refresh the screen first query the currnet vgpu's frambuffer and
compare with the cached ones(address, size, tiling, width, height etc)
if found one then reuse the found dmabuf to gain performance improvment.

If there is no dmabuf created yet or not found in the cached dmabufs then
need to create a new dmabuf. To create a dmabuf first a gem object will
be created and the backing storage of this gem object is the vgpu's
framebuffer(primary/cursor).
Set caching mode, change tiling mode and set domains of this gem object
is not supported.
Then associate this gem object to a dmabuf and export this dmabuf.
A file descriptor will be generated for this dmabuf and this file
descriptor can be sent to user space to do display.

Signed-off-by: Xiaoguang Chen 
---
 drivers/gpu/drm/i915/gvt/Makefile  |   2 +-
 drivers/gpu/drm/i915/gvt/dmabuf.c  | 275 +
 drivers/gpu/drm/i915/gvt/dmabuf.h  |  54 +++
 drivers/gpu/drm/i915/gvt/gvt.h |   1 +
 drivers/gpu/drm/i915/i915_gem.c|   8 +
 drivers/gpu/drm/i915/i915_gem_object.h |   3 +
 6 files changed, 342 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/i915/gvt/dmabuf.c
 create mode 100644 drivers/gpu/drm/i915/gvt/dmabuf.h

diff --git a/drivers/gpu/drm/i915/gvt/Makefile 
b/drivers/gpu/drm/i915/gvt/Makefile
index 192ca26..e480f7d 100644
--- a/drivers/gpu/drm/i915/gvt/Makefile
+++ b/drivers/gpu/drm/i915/gvt/Makefile
@@ -2,7 +2,7 @@ GVT_DIR := gvt
 GVT_SOURCE := gvt.o aperture_gm.o handlers.o vgpu.o trace_points.o firmware.o \
interrupt.o gtt.o cfg_space.o opregion.o mmio.o display.o edid.o \
execlist.o scheduler.o sched_policy.o render.o cmd_parser.o \
-   fb_decoder.o
+   fb_decoder.o dmabuf.o
 
 ccflags-y  += -I$(src) -I$(src)/$(GVT_DIR) -Wall
 i915-y += $(addprefix $(GVT_DIR)/, 
$(GVT_SOURCE))
diff --git a/drivers/gpu/drm/i915/gvt/dmabuf.c 
b/drivers/gpu/drm/i915/gvt/dmabuf.c
new file mode 100644
index 000..c9f283c
--- /dev/null
+++ b/drivers/gpu/drm/i915/gvt/dmabuf.c
@@ -0,0 +1,275 @@
+/*
+ * Copyright 2017 Intel Corporation. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *Zhiyuan Lv 
+ *
+ * Contributors:
+ *Xiaoguang Chen 
+ */
+
+#include 
+#include 
+
+#include "i915_drv.h"
+#include "gvt.h"
+
+#define GEN8_DECODE_PTE(pte) \
+   ((dma_addr_t)(u64)pte) >> 12) & 0x7ffULL) << 12))
+
+static struct sg_table *intel_vgpu_gem_get_pages(
+   struct drm_i915_gem_object *obj)
+{
+   struct drm_i915_private *dev_priv = to_i915(obj->base.dev);
+   struct sg_table *st;
+   struct scatterlist *sg;
+   int i, ret;
+   gen8_pte_t __iomem *gtt_entries;
+   unsigned int fb_gma = 0, fb_size = 0;
+   struct intel_vgpu_plane_info *plane_info;
+
+   plane_info = (struct intel_vgpu_plane_info *)obj->gvt_plane_info;
+   if (WARN_ON(!plane_info))
+   return ERR_PTR(-EINVAL);
+
+   fb_gma = plane_info->start;
+   fb_size = plane_info->size;
+
+   st = kmalloc(sizeof(*st), GFP_KERNEL);
+   if (!st) {
+   ret = -ENOMEM;
+   return ERR_PTR(ret);
+   }
+
+   ret = sg_alloc_table(st, fb_size, GFP_KERNEL);
+   if (ret) {
+   kfree(st);
+   return ERR_PTR(ret);
+   }
+   gtt_entries = (gen8_pte_t __iomem *)dev_priv->ggtt.gsm +
+   (fb_gma >> PAGE_SHIFT);

[PATCH v4 1/5] drm/i915/gvt: Extend the GVT-g architecture to support vfio device region

2017-05-22 Thread Xiaoguang Chen
Signed-off-by: Xiaoguang Chen 
---
 drivers/gpu/drm/i915/gvt/kvmgt.c | 21 ++---
 1 file changed, 18 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
index 1ae0b40..3c6a02b 100644
--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
+++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
@@ -53,11 +53,21 @@ static const struct intel_gvt_ops *intel_gvt_ops;
 #define VFIO_PCI_INDEX_TO_OFFSET(index) ((u64)(index) << VFIO_PCI_OFFSET_SHIFT)
 #define VFIO_PCI_OFFSET_MASK(((u64)(1) << VFIO_PCI_OFFSET_SHIFT) - 1)
 
+struct vfio_region;
+struct intel_vgpu_regops {
+   size_t (*rw)(struct intel_vgpu *vgpu, char *buf,
+   size_t count, loff_t *ppos, bool iswrite);
+   void (*release)(struct intel_vgpu *vgpu,
+   struct vfio_region *region);
+};
+
 struct vfio_region {
u32 type;
u32 subtype;
size_t  size;
u32 flags;
+   const struct intel_vgpu_regops  *ops;
+   void*data;
 };
 
 struct kvmgt_pgfn {
@@ -642,7 +652,7 @@ static ssize_t intel_vgpu_rw(struct mdev_device *mdev, char 
*buf,
int ret = -EINVAL;
 
 
-   if (index >= VFIO_PCI_NUM_REGIONS) {
+   if (index >= VFIO_PCI_NUM_REGIONS + vgpu->vdev.num_regions) {
gvt_vgpu_err("invalid index: %u\n", index);
return -EINVAL;
}
@@ -676,8 +686,11 @@ static ssize_t intel_vgpu_rw(struct mdev_device *mdev, 
char *buf,
case VFIO_PCI_BAR5_REGION_INDEX:
case VFIO_PCI_VGA_REGION_INDEX:
case VFIO_PCI_ROM_REGION_INDEX:
+   break;
default:
-   gvt_vgpu_err("unsupported region: %u\n", index);
+   index -= VFIO_PCI_NUM_REGIONS;
+   return vgpu->vdev.region[index].ops->rw(vgpu, buf, count,
+   ppos, is_write);
}
 
return ret == 0 ? count : ret;
@@ -940,7 +953,8 @@ static long intel_vgpu_ioctl(struct mdev_device *mdev, 
unsigned int cmd,
 
info.flags = VFIO_DEVICE_FLAGS_PCI;
info.flags |= VFIO_DEVICE_FLAGS_RESET;
-   info.num_regions = VFIO_PCI_NUM_REGIONS;
+   info.num_regions = VFIO_PCI_NUM_REGIONS +
+   vgpu->vdev.num_regions;
info.num_irqs = VFIO_PCI_NUM_IRQS;
 
return copy_to_user((void __user *)arg, , minsz) ?
@@ -1061,6 +1075,7 @@ static long intel_vgpu_ioctl(struct mdev_device *mdev, 
unsigned int cmd,
}
 
if (caps.size) {
+   info.flags |= VFIO_REGION_INFO_FLAG_CAPS;
if (info.argsz < sizeof(info) + caps.size) {
info.argsz = sizeof(info) + caps.size;
info.cap_offset = 0;
-- 
2.7.4



[PATCH v4 5/5] drm/i915/gvt: Adding interface so user space can get the dma-buf

2017-05-22 Thread Xiaoguang Chen
User space will try to create a management fd for the dma-buf operation.
Using this management fd user can query the plane information and create
a dma-buf fd if necessary.
GVT-g will handle the life cycle of the management fd and will align the
life cycle of the fd with the vfio device.
User space should handle the life cycle of the created dma-buf fd close
the dma-buf fd timely when finishing use.

Signed-off-by: Xiaoguang Chen 
---
 drivers/gpu/drm/i915/gvt/dmabuf.c | 23 ++-
 drivers/gpu/drm/i915/gvt/dmabuf.h | 22 --
 drivers/gpu/drm/i915/gvt/gvt.c|  2 +
 drivers/gpu/drm/i915/gvt/gvt.h|  3 ++
 drivers/gpu/drm/i915/gvt/kvmgt.c  | 87 +++
 include/uapi/linux/vfio.h | 36 
 6 files changed, 140 insertions(+), 33 deletions(-)

diff --git a/drivers/gpu/drm/i915/gvt/dmabuf.c 
b/drivers/gpu/drm/i915/gvt/dmabuf.c
index c9f283c..c74762f 100644
--- a/drivers/gpu/drm/i915/gvt/dmabuf.c
+++ b/drivers/gpu/drm/i915/gvt/dmabuf.c
@@ -29,6 +29,7 @@
 
 #include 
 #include 
+#include 
 
 #include "i915_drv.h"
 #include "gvt.h"
@@ -45,9 +46,9 @@ static struct sg_table *intel_vgpu_gem_get_pages(
int i, ret;
gen8_pte_t __iomem *gtt_entries;
unsigned int fb_gma = 0, fb_size = 0;
-   struct intel_vgpu_plane_info *plane_info;
+   struct plane_info *plane_info;
 
-   plane_info = (struct intel_vgpu_plane_info *)obj->gvt_plane_info;
+   plane_info = (struct plane_info *)obj->gvt_plane_info;
if (WARN_ON(!plane_info))
return ERR_PTR(-EINVAL);
 
@@ -81,9 +82,9 @@ static struct sg_table *intel_vgpu_gem_get_pages(
 static void intel_vgpu_gem_put_pages(struct drm_i915_gem_object *obj,
struct sg_table *pages)
 {
-   struct intel_vgpu_plane_info *plane_info;
+   struct plane_info *plane_info;
 
-   plane_info = (struct intel_vgpu_plane_info *)obj->gvt_plane_info;
+   plane_info = (struct plane_info *)obj->gvt_plane_info;
if (WARN_ON(!plane_info))
return;
 
@@ -98,7 +99,7 @@ static const struct drm_i915_gem_object_ops 
intel_vgpu_gem_ops = {
 };
 
 static struct drm_i915_gem_object *intel_vgpu_create_gem(struct drm_device 
*dev,
-   struct intel_vgpu_plane_info *info)
+   struct plane_info *info)
 {
struct drm_i915_private *pri = dev->dev_private;
struct drm_i915_gem_object *obj;
@@ -141,14 +142,14 @@ static struct drm_i915_gem_object 
*intel_vgpu_create_gem(struct drm_device *dev,
return obj;
 }
 
-static struct intel_vgpu_plane_info *intel_vgpu_get_plane_info(
+static struct plane_info *intel_vgpu_get_plane_info(
struct drm_device *dev,
struct intel_vgpu *vgpu, int plane_id)
 {
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_vgpu_primary_plane_format *p;
struct intel_vgpu_cursor_plane_format *c;
-   struct intel_vgpu_plane_info *info;
+   struct plane_info *info;
 
info = kmalloc(sizeof(*info), GFP_KERNEL);
if (!info)
@@ -225,8 +226,8 @@ static struct intel_vgpu_plane_info 
*intel_vgpu_get_plane_info(
 int intel_vgpu_query_dmabuf(struct intel_vgpu *vgpu, void *args)
 {
struct drm_device *dev = >gvt->dev_priv->drm;
-   struct intel_vgpu_dmabuf *gvt_dmabuf = args;
-   struct intel_vgpu_plane_info *info;
+   struct dmabuf_info *gvt_dmabuf = args;
+   struct plane_info *info;
 
info = intel_vgpu_get_plane_info(dev, vgpu, gvt_dmabuf->plane_id);
if (info == NULL)
@@ -242,8 +243,8 @@ int intel_vgpu_create_dmabuf(struct intel_vgpu *vgpu, void 
*args)
struct dma_buf *dmabuf;
struct drm_i915_gem_object *obj;
struct drm_device *dev = >gvt->dev_priv->drm;
-   struct intel_vgpu_dmabuf *gvt_dmabuf = args;
-   struct intel_vgpu_plane_info *info;
+   struct dmabuf_info *gvt_dmabuf = args;
+   struct plane_info *info;
int ret;
 
info = intel_vgpu_get_plane_info(dev, vgpu, gvt_dmabuf->plane_id);
diff --git a/drivers/gpu/drm/i915/gvt/dmabuf.h 
b/drivers/gpu/drm/i915/gvt/dmabuf.h
index c7ce642..0ddea78 100644
--- a/drivers/gpu/drm/i915/gvt/dmabuf.h
+++ b/drivers/gpu/drm/i915/gvt/dmabuf.h
@@ -26,28 +26,6 @@
 #ifndef _GVT_DMABUF_H_
 #define _GVT_DMABUF_H_
 
-struct intel_vgpu_plane_info {
-   uint32_t drm_format;
-   uint32_t width;
-   uint32_t height;
-   uint32_t stride;
-   uint32_t start;
-   uint32_t x_pos;
-   uint32_t y_pos;
-   uint32_t size;
-   uint64_t drm_format_mod;
-};
-
-#define INTEL_VGPU_QUERY_DMABUF0
-#define INTEL_VGPU_GENERATE_DMABUF 1
-
-struct intel_vgpu_dmabuf {
-   uint32_t plane_id;
-   /* out */
-   uint32_t fd;
-   struct intel_vgpu_plane_info plane_info;
-};
-
 int intel_vgpu_query_dmabuf(struct intel_vgpu *vgpu, void *args);
 int intel_vgpu_create_dmabuf(struct

[PATCH v4 3/5] drm/i915/gvt: Frame buffer decoder support for GVT-g

2017-05-22 Thread Xiaoguang Chen
decode frambuffer attributes of primary, cursor and sprite plane

Signed-off-by: Xiaoguang Chen <xiaoguang.c...@intel.com>
---
 drivers/gpu/drm/i915/gvt/Makefile |   3 +-
 drivers/gpu/drm/i915/gvt/display.c|   2 +-
 drivers/gpu/drm/i915/gvt/display.h|   2 +
 drivers/gpu/drm/i915/gvt/fb_decoder.c | 487 ++
 drivers/gpu/drm/i915/gvt/fb_decoder.h | 170 
 drivers/gpu/drm/i915/gvt/gvt.h|   1 +
 6 files changed, 663 insertions(+), 2 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/gvt/fb_decoder.c
 create mode 100644 drivers/gpu/drm/i915/gvt/fb_decoder.h

diff --git a/drivers/gpu/drm/i915/gvt/Makefile 
b/drivers/gpu/drm/i915/gvt/Makefile
index b123c20..192ca26 100644
--- a/drivers/gpu/drm/i915/gvt/Makefile
+++ b/drivers/gpu/drm/i915/gvt/Makefile
@@ -1,7 +1,8 @@
 GVT_DIR := gvt
 GVT_SOURCE := gvt.o aperture_gm.o handlers.o vgpu.o trace_points.o firmware.o \
interrupt.o gtt.o cfg_space.o opregion.o mmio.o display.o edid.o \
-   execlist.o scheduler.o sched_policy.o render.o cmd_parser.o
+   execlist.o scheduler.o sched_policy.o render.o cmd_parser.o \
+   fb_decoder.o
 
 ccflags-y  += -I$(src) -I$(src)/$(GVT_DIR) -Wall
 i915-y += $(addprefix $(GVT_DIR)/, 
$(GVT_SOURCE))
diff --git a/drivers/gpu/drm/i915/gvt/display.c 
b/drivers/gpu/drm/i915/gvt/display.c
index e0261fc..f5f63c5 100644
--- a/drivers/gpu/drm/i915/gvt/display.c
+++ b/drivers/gpu/drm/i915/gvt/display.c
@@ -67,7 +67,7 @@ static int edp_pipe_is_enabled(struct intel_vgpu *vgpu)
return 1;
 }
 
-static int pipe_is_enabled(struct intel_vgpu *vgpu, int pipe)
+int pipe_is_enabled(struct intel_vgpu *vgpu, int pipe)
 {
struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv;
 
diff --git a/drivers/gpu/drm/i915/gvt/display.h 
b/drivers/gpu/drm/i915/gvt/display.h
index d73de22..b46b868 100644
--- a/drivers/gpu/drm/i915/gvt/display.h
+++ b/drivers/gpu/drm/i915/gvt/display.h
@@ -179,4 +179,6 @@ int intel_vgpu_init_display(struct intel_vgpu *vgpu, u64 
resolution);
 void intel_vgpu_reset_display(struct intel_vgpu *vgpu);
 void intel_vgpu_clean_display(struct intel_vgpu *vgpu);
 
+int pipe_is_enabled(struct intel_vgpu *vgpu, int pipe);
+
 #endif
diff --git a/drivers/gpu/drm/i915/gvt/fb_decoder.c 
b/drivers/gpu/drm/i915/gvt/fb_decoder.c
new file mode 100644
index 000..954f047
--- /dev/null
+++ b/drivers/gpu/drm/i915/gvt/fb_decoder.c
@@ -0,0 +1,487 @@
+/*
+ * Copyright(c) 2011-2016 Intel Corporation. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 
THE
+ * SOFTWARE.
+ *
+ * Authors:
+ *Kevin Tian <kevin.t...@intel.com>
+ *
+ * Contributors:
+ *Bing Niu <bing@intel.com>
+ *Xu Han <xu@intel.com>
+ *    Ping Gao <ping.a@intel.com>
+ *Xiaoguang Chen <xiaoguang.c...@intel.com>
+ *Yang Liu <yang2@intel.com>
+ *
+ */
+
+#include 
+#include "i915_drv.h"
+#include "gvt.h"
+
+/* The below definitions are required by guest. */
+// [63:0] x:R:G:B 16:16:16:16 little endian
+#define DRM_FORMAT_XRGB161616_GVT  fourcc_code('X', 'R', '4', '8')
+// [63:0] x:B:G:R 16:16:16:16 little endian
+#define DRM_FORMAT_XBGR161616_GVT  fourcc_code('X', 'B', '4', '8')
+
+#define FORMAT_NUM 16
+struct pixel_format {
+   int drm_format; /* Pixel format in DRM definition */
+   int bpp;/* Bits per pixel, 0 indicates invalid */
+   char *desc; /* The description */
+};
+
+/* non-supported format has bpp default to 0 */
+static struct pixel_format primary_pixel_formats[FORMAT_NUM] = {
+   [0x2] = {DRM_FORMAT_C8, 8, "8-bit Indexed"},
+   [0x5] = {DRM_FORMAT_RGB565, 16, "16-bit BGRX (5:6:5 MSB-R:G:B)"},
+   [0x6] = {DRM_FORMAT_XRGB, 32,
+   "32-bit BG

[PATCH v4 3/5] drm/i915/gvt: Frame buffer decoder support for GVT-g

2017-05-22 Thread Xiaoguang Chen
decode frambuffer attributes of primary, cursor and sprite plane

Signed-off-by: Xiaoguang Chen 
---
 drivers/gpu/drm/i915/gvt/Makefile |   3 +-
 drivers/gpu/drm/i915/gvt/display.c|   2 +-
 drivers/gpu/drm/i915/gvt/display.h|   2 +
 drivers/gpu/drm/i915/gvt/fb_decoder.c | 487 ++
 drivers/gpu/drm/i915/gvt/fb_decoder.h | 170 
 drivers/gpu/drm/i915/gvt/gvt.h|   1 +
 6 files changed, 663 insertions(+), 2 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/gvt/fb_decoder.c
 create mode 100644 drivers/gpu/drm/i915/gvt/fb_decoder.h

diff --git a/drivers/gpu/drm/i915/gvt/Makefile 
b/drivers/gpu/drm/i915/gvt/Makefile
index b123c20..192ca26 100644
--- a/drivers/gpu/drm/i915/gvt/Makefile
+++ b/drivers/gpu/drm/i915/gvt/Makefile
@@ -1,7 +1,8 @@
 GVT_DIR := gvt
 GVT_SOURCE := gvt.o aperture_gm.o handlers.o vgpu.o trace_points.o firmware.o \
interrupt.o gtt.o cfg_space.o opregion.o mmio.o display.o edid.o \
-   execlist.o scheduler.o sched_policy.o render.o cmd_parser.o
+   execlist.o scheduler.o sched_policy.o render.o cmd_parser.o \
+   fb_decoder.o
 
 ccflags-y  += -I$(src) -I$(src)/$(GVT_DIR) -Wall
 i915-y += $(addprefix $(GVT_DIR)/, 
$(GVT_SOURCE))
diff --git a/drivers/gpu/drm/i915/gvt/display.c 
b/drivers/gpu/drm/i915/gvt/display.c
index e0261fc..f5f63c5 100644
--- a/drivers/gpu/drm/i915/gvt/display.c
+++ b/drivers/gpu/drm/i915/gvt/display.c
@@ -67,7 +67,7 @@ static int edp_pipe_is_enabled(struct intel_vgpu *vgpu)
return 1;
 }
 
-static int pipe_is_enabled(struct intel_vgpu *vgpu, int pipe)
+int pipe_is_enabled(struct intel_vgpu *vgpu, int pipe)
 {
struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv;
 
diff --git a/drivers/gpu/drm/i915/gvt/display.h 
b/drivers/gpu/drm/i915/gvt/display.h
index d73de22..b46b868 100644
--- a/drivers/gpu/drm/i915/gvt/display.h
+++ b/drivers/gpu/drm/i915/gvt/display.h
@@ -179,4 +179,6 @@ int intel_vgpu_init_display(struct intel_vgpu *vgpu, u64 
resolution);
 void intel_vgpu_reset_display(struct intel_vgpu *vgpu);
 void intel_vgpu_clean_display(struct intel_vgpu *vgpu);
 
+int pipe_is_enabled(struct intel_vgpu *vgpu, int pipe);
+
 #endif
diff --git a/drivers/gpu/drm/i915/gvt/fb_decoder.c 
b/drivers/gpu/drm/i915/gvt/fb_decoder.c
new file mode 100644
index 000..954f047
--- /dev/null
+++ b/drivers/gpu/drm/i915/gvt/fb_decoder.c
@@ -0,0 +1,487 @@
+/*
+ * Copyright(c) 2011-2016 Intel Corporation. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 
THE
+ * SOFTWARE.
+ *
+ * Authors:
+ *Kevin Tian 
+ *
+ * Contributors:
+ *Bing Niu 
+ *Xu Han 
+ *Ping Gao 
+ *Xiaoguang Chen 
+ *Yang Liu 
+ *
+ */
+
+#include 
+#include "i915_drv.h"
+#include "gvt.h"
+
+/* The below definitions are required by guest. */
+// [63:0] x:R:G:B 16:16:16:16 little endian
+#define DRM_FORMAT_XRGB161616_GVT  fourcc_code('X', 'R', '4', '8')
+// [63:0] x:B:G:R 16:16:16:16 little endian
+#define DRM_FORMAT_XBGR161616_GVT  fourcc_code('X', 'B', '4', '8')
+
+#define FORMAT_NUM 16
+struct pixel_format {
+   int drm_format; /* Pixel format in DRM definition */
+   int bpp;/* Bits per pixel, 0 indicates invalid */
+   char *desc; /* The description */
+};
+
+/* non-supported format has bpp default to 0 */
+static struct pixel_format primary_pixel_formats[FORMAT_NUM] = {
+   [0x2] = {DRM_FORMAT_C8, 8, "8-bit Indexed"},
+   [0x5] = {DRM_FORMAT_RGB565, 16, "16-bit BGRX (5:6:5 MSB-R:G:B)"},
+   [0x6] = {DRM_FORMAT_XRGB, 32,
+   "32-bit BGRX (8:8:8:8 MSB-X:R:G:B)"},
+   [0x8] = {DRM_FORMAT_XBGR2101010, 32,
+   "32-bit RGBX (2:10:10:10 MSB-X:B:G:R)"},
+   [0xa] = {DRM_FORMAT_

[PATCH v4 0/5] drm/i915/gvt: Dma-buf support for GVT-g

2017-05-22 Thread Xiaoguang Chen
v3->v4:
1) fix bug while checking whether the gem obj is gvt's dma-buf when set
caching mode or doamins.
2) add more comments for patch set.

v2->v3:
1) add a field gvt_plane_info in the drm_i915_gem_obj structure to save
the decoded plane information to avoid look up while need the plane info.
2) declare a new flag I915_GEM_OBJECT_IS_GVT_DMABUF in drm_i915_gem_object
to represent the gem obj for gvt's dma-buf. The tiling mode, caching mode
and domains can not be changed for this kind of gem object.
3) change dma-buf related information to be more generic. So other vendor
can use the same interface.

v1->v2:
1) create a management fd for dma-buf operations.
2) alloc gem object's backing storage in gem obj's get_pages() callback.

This patch set adds the dma-buf support for intel GVT-g.
dma-buf is a uniform mechanism to share DMA buffers across different
devices and sub-systems.
dma-buf for intel GVT-g is mainly used to share the vgpu's framebuffer
to other users or sub-systems so they can use the dma-buf to show the
desktop of a vm which uses intel vgpu.

The main idea is we create a gem object and set vgpu's framebuffer as
the backing storage of this gem object. And associate this gem obj
to a dma-buf object then export this dma-buf at the meantime
generate a file descriptor for this dma-buf. Finally deliver this file
descriptor to user space. And user can use this dma-buf fd to do render
or other operations.
User need to create a fd(for intel GVT-g dma-buf support it is a:dma-buf
management fd) then user can use this fd to query the plane information
or create a dma-buf. The life cycle of this fd is managed by GVT-g user
do not need to care about that.

We have an example program on how to use the dma-buf. You can download
the program to have a try. Good luck :)
git repo: https://github.com/01org/igvtg-qemu branch:kvmgt_dmabuf_example

Xiaoguang Chen (5):
  drm/i915/gvt: Extend the GVT-g architecture to support vfio device
region
  drm/i915/gvt: OpRegion support for GVT-g
  drm/i915/gvt: Frame buffer decoder support for GVT-g
  drm/i915/gvt: Dmabuf support for GVT-g
  drm/i915/gvt: Adding interface so user space can get the dma-buf

 drivers/gpu/drm/i915/gvt/Makefile  |   3 +-
 drivers/gpu/drm/i915/gvt/display.c |   2 +-
 drivers/gpu/drm/i915/gvt/display.h |   2 +
 drivers/gpu/drm/i915/gvt/dmabuf.c  | 276 +++
 drivers/gpu/drm/i915/gvt/dmabuf.h  |  32 +++
 drivers/gpu/drm/i915/gvt/fb_decoder.c  | 487 +
 drivers/gpu/drm/i915/gvt/fb_decoder.h  | 170 
 drivers/gpu/drm/i915/gvt/gvt.c |   2 +
 drivers/gpu/drm/i915/gvt/gvt.h |   5 +
 drivers/gpu/drm/i915/gvt/kvmgt.c   | 205 +-
 drivers/gpu/drm/i915/gvt/opregion.c|   8 +-
 drivers/gpu/drm/i915/i915_gem.c|   8 +
 drivers/gpu/drm/i915/i915_gem_object.h |   3 +
 include/uapi/linux/vfio.h  |  36 +++
 14 files changed, 1233 insertions(+), 6 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/gvt/dmabuf.c
 create mode 100644 drivers/gpu/drm/i915/gvt/dmabuf.h
 create mode 100644 drivers/gpu/drm/i915/gvt/fb_decoder.c
 create mode 100644 drivers/gpu/drm/i915/gvt/fb_decoder.h

-- 
2.7.4



[PATCH v4 0/5] drm/i915/gvt: Dma-buf support for GVT-g

2017-05-22 Thread Xiaoguang Chen
v3->v4:
1) fix bug while checking whether the gem obj is gvt's dma-buf when set
caching mode or doamins.
2) add more comments for patch set.

v2->v3:
1) add a field gvt_plane_info in the drm_i915_gem_obj structure to save
the decoded plane information to avoid look up while need the plane info.
2) declare a new flag I915_GEM_OBJECT_IS_GVT_DMABUF in drm_i915_gem_object
to represent the gem obj for gvt's dma-buf. The tiling mode, caching mode
and domains can not be changed for this kind of gem object.
3) change dma-buf related information to be more generic. So other vendor
can use the same interface.

v1->v2:
1) create a management fd for dma-buf operations.
2) alloc gem object's backing storage in gem obj's get_pages() callback.

This patch set adds the dma-buf support for intel GVT-g.
dma-buf is a uniform mechanism to share DMA buffers across different
devices and sub-systems.
dma-buf for intel GVT-g is mainly used to share the vgpu's framebuffer
to other users or sub-systems so they can use the dma-buf to show the
desktop of a vm which uses intel vgpu.

The main idea is we create a gem object and set vgpu's framebuffer as
the backing storage of this gem object. And associate this gem obj
to a dma-buf object then export this dma-buf at the meantime
generate a file descriptor for this dma-buf. Finally deliver this file
descriptor to user space. And user can use this dma-buf fd to do render
or other operations.
User need to create a fd(for intel GVT-g dma-buf support it is a:dma-buf
management fd) then user can use this fd to query the plane information
or create a dma-buf. The life cycle of this fd is managed by GVT-g user
do not need to care about that.

We have an example program on how to use the dma-buf. You can download
the program to have a try. Good luck :)
git repo: https://github.com/01org/igvtg-qemu branch:kvmgt_dmabuf_example

Xiaoguang Chen (5):
  drm/i915/gvt: Extend the GVT-g architecture to support vfio device
region
  drm/i915/gvt: OpRegion support for GVT-g
  drm/i915/gvt: Frame buffer decoder support for GVT-g
  drm/i915/gvt: Dmabuf support for GVT-g
  drm/i915/gvt: Adding interface so user space can get the dma-buf

 drivers/gpu/drm/i915/gvt/Makefile  |   3 +-
 drivers/gpu/drm/i915/gvt/display.c |   2 +-
 drivers/gpu/drm/i915/gvt/display.h |   2 +
 drivers/gpu/drm/i915/gvt/dmabuf.c  | 276 +++
 drivers/gpu/drm/i915/gvt/dmabuf.h  |  32 +++
 drivers/gpu/drm/i915/gvt/fb_decoder.c  | 487 +
 drivers/gpu/drm/i915/gvt/fb_decoder.h  | 170 
 drivers/gpu/drm/i915/gvt/gvt.c |   2 +
 drivers/gpu/drm/i915/gvt/gvt.h |   5 +
 drivers/gpu/drm/i915/gvt/kvmgt.c   | 205 +-
 drivers/gpu/drm/i915/gvt/opregion.c|   8 +-
 drivers/gpu/drm/i915/i915_gem.c|   8 +
 drivers/gpu/drm/i915/i915_gem_object.h |   3 +
 include/uapi/linux/vfio.h  |  36 +++
 14 files changed, 1233 insertions(+), 6 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/gvt/dmabuf.c
 create mode 100644 drivers/gpu/drm/i915/gvt/dmabuf.h
 create mode 100644 drivers/gpu/drm/i915/gvt/fb_decoder.c
 create mode 100644 drivers/gpu/drm/i915/gvt/fb_decoder.h

-- 
2.7.4



[PATCH v3 1/5] drm/i915/gvt: Extend the GVT-g architecture to support vfio device region

2017-05-22 Thread Xiaoguang Chen
Signed-off-by: Xiaoguang Chen <xiaoguang.c...@intel.com>
---
 drivers/gpu/drm/i915/gvt/kvmgt.c | 21 ++---
 1 file changed, 18 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
index 1ae0b40..3c6a02b 100644
--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
+++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
@@ -53,11 +53,21 @@ static const struct intel_gvt_ops *intel_gvt_ops;
 #define VFIO_PCI_INDEX_TO_OFFSET(index) ((u64)(index) << VFIO_PCI_OFFSET_SHIFT)
 #define VFIO_PCI_OFFSET_MASK(((u64)(1) << VFIO_PCI_OFFSET_SHIFT) - 1)
 
+struct vfio_region;
+struct intel_vgpu_regops {
+   size_t (*rw)(struct intel_vgpu *vgpu, char *buf,
+   size_t count, loff_t *ppos, bool iswrite);
+   void (*release)(struct intel_vgpu *vgpu,
+   struct vfio_region *region);
+};
+
 struct vfio_region {
u32 type;
u32 subtype;
size_t  size;
u32 flags;
+   const struct intel_vgpu_regops  *ops;
+   void*data;
 };
 
 struct kvmgt_pgfn {
@@ -642,7 +652,7 @@ static ssize_t intel_vgpu_rw(struct mdev_device *mdev, char 
*buf,
int ret = -EINVAL;
 
 
-   if (index >= VFIO_PCI_NUM_REGIONS) {
+   if (index >= VFIO_PCI_NUM_REGIONS + vgpu->vdev.num_regions) {
gvt_vgpu_err("invalid index: %u\n", index);
return -EINVAL;
}
@@ -676,8 +686,11 @@ static ssize_t intel_vgpu_rw(struct mdev_device *mdev, 
char *buf,
case VFIO_PCI_BAR5_REGION_INDEX:
case VFIO_PCI_VGA_REGION_INDEX:
case VFIO_PCI_ROM_REGION_INDEX:
+   break;
default:
-   gvt_vgpu_err("unsupported region: %u\n", index);
+   index -= VFIO_PCI_NUM_REGIONS;
+   return vgpu->vdev.region[index].ops->rw(vgpu, buf, count,
+   ppos, is_write);
}
 
return ret == 0 ? count : ret;
@@ -940,7 +953,8 @@ static long intel_vgpu_ioctl(struct mdev_device *mdev, 
unsigned int cmd,
 
info.flags = VFIO_DEVICE_FLAGS_PCI;
info.flags |= VFIO_DEVICE_FLAGS_RESET;
-   info.num_regions = VFIO_PCI_NUM_REGIONS;
+   info.num_regions = VFIO_PCI_NUM_REGIONS +
+   vgpu->vdev.num_regions;
info.num_irqs = VFIO_PCI_NUM_IRQS;
 
return copy_to_user((void __user *)arg, , minsz) ?
@@ -1061,6 +1075,7 @@ static long intel_vgpu_ioctl(struct mdev_device *mdev, 
unsigned int cmd,
}
 
if (caps.size) {
+   info.flags |= VFIO_REGION_INFO_FLAG_CAPS;
if (info.argsz < sizeof(info) + caps.size) {
info.argsz = sizeof(info) + caps.size;
info.cap_offset = 0;
-- 
2.7.4



[PATCH v3 0/5] drm/i915/gvt: Dma-buf support for GVT-g

2017-05-22 Thread Xiaoguang Chen
v2->v3:
1) add a field gvt_plane_info in the drm_i915_gem_obj structure to save
the decoded plane information to avoid look up while need the plane info.
2) declare a new flag I915_GEM_OBJECT_IS_GVT_DMABUF in drm_i915_gem_object
to represent the gem obj for gvt's dma-buf. The tiling mode, caching mode
and domains can not be changed for this kind of gem object.
3) change dma-buf related information to be more generic. So other vendor
can use the same interface.

v1->v2:
1) create a management fd for dma-buf operations.
2) alloc gem object's backing storage in gem obj's get_pages() callback.

This patch set adds the dma-buf support for intel GVT-g.
dma-buf is a uniform mechanism to share DMA buffers across different
devices and sub-systems.
dma-buf for intel GVT-g is mainly used to share the vgpu's framebuffer
to other users or sub-systems so they can use the dma-buf to show the
desktop of a vm which uses intel vgpu.

The main idea is we create a gem object and set vgpu's framebuffer as
the backing storage of this gem object. And associate this gem obj
to a dma-buf object then export this dma-buf at the meantime
generate a file descriptor for this dma-buf. Finally deliver this file
descriptor to user space. And user can use this dma-buf fd to do render
or other operations.
User need to create a fd(for intel GVT-g dma-buf support it is a:dma-buf
management fd) then user can use this fd to query the plane information
or create a dma-buf. The life cycle of this fd is managed by GVT-g user
do not need to care about that.

We have an example program on how to use the dma-buf. You can download
the program to have a try. Good luck :)
git repo: https://github.com/01org/igvtg-qemu branch:kvmgt_dmabuf_example

Xiaoguang Chen (5):
  drm/i915/gvt: Extend the GVT-g architecture to support vfio device
region
  drm/i915/gvt: OpRegion support for GVT-g
  drm/i915/gvt: Frame buffer decoder support for GVT-g
  drm/i915/gvt: Dmabuf support for GVT-g
  drm/i915/gvt: Adding interface so user space can get the dma-buf

 drivers/gpu/drm/i915/gvt/Makefile  |   3 +-
 drivers/gpu/drm/i915/gvt/display.c |   2 +-
 drivers/gpu/drm/i915/gvt/display.h |   2 +
 drivers/gpu/drm/i915/gvt/dmabuf.c  | 276 +++
 drivers/gpu/drm/i915/gvt/dmabuf.h  |  32 +++
 drivers/gpu/drm/i915/gvt/fb_decoder.c  | 487 +
 drivers/gpu/drm/i915/gvt/fb_decoder.h  | 170 
 drivers/gpu/drm/i915/gvt/gvt.c |   2 +
 drivers/gpu/drm/i915/gvt/gvt.h |   7 +
 drivers/gpu/drm/i915/gvt/kvmgt.c   | 205 +-
 drivers/gpu/drm/i915/gvt/opregion.c|   8 +-
 drivers/gpu/drm/i915/i915_gem.c|   8 +
 drivers/gpu/drm/i915/i915_gem_object.h |   3 +
 include/uapi/linux/vfio.h  |  36 +++
 14 files changed, 1235 insertions(+), 6 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/gvt/dmabuf.c
 create mode 100644 drivers/gpu/drm/i915/gvt/dmabuf.h
 create mode 100644 drivers/gpu/drm/i915/gvt/fb_decoder.c
 create mode 100644 drivers/gpu/drm/i915/gvt/fb_decoder.h

-- 
2.7.4



[PATCH v3 1/5] drm/i915/gvt: Extend the GVT-g architecture to support vfio device region

2017-05-22 Thread Xiaoguang Chen
Signed-off-by: Xiaoguang Chen 
---
 drivers/gpu/drm/i915/gvt/kvmgt.c | 21 ++---
 1 file changed, 18 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
index 1ae0b40..3c6a02b 100644
--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
+++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
@@ -53,11 +53,21 @@ static const struct intel_gvt_ops *intel_gvt_ops;
 #define VFIO_PCI_INDEX_TO_OFFSET(index) ((u64)(index) << VFIO_PCI_OFFSET_SHIFT)
 #define VFIO_PCI_OFFSET_MASK(((u64)(1) << VFIO_PCI_OFFSET_SHIFT) - 1)
 
+struct vfio_region;
+struct intel_vgpu_regops {
+   size_t (*rw)(struct intel_vgpu *vgpu, char *buf,
+   size_t count, loff_t *ppos, bool iswrite);
+   void (*release)(struct intel_vgpu *vgpu,
+   struct vfio_region *region);
+};
+
 struct vfio_region {
u32 type;
u32 subtype;
size_t  size;
u32 flags;
+   const struct intel_vgpu_regops  *ops;
+   void*data;
 };
 
 struct kvmgt_pgfn {
@@ -642,7 +652,7 @@ static ssize_t intel_vgpu_rw(struct mdev_device *mdev, char 
*buf,
int ret = -EINVAL;
 
 
-   if (index >= VFIO_PCI_NUM_REGIONS) {
+   if (index >= VFIO_PCI_NUM_REGIONS + vgpu->vdev.num_regions) {
gvt_vgpu_err("invalid index: %u\n", index);
return -EINVAL;
}
@@ -676,8 +686,11 @@ static ssize_t intel_vgpu_rw(struct mdev_device *mdev, 
char *buf,
case VFIO_PCI_BAR5_REGION_INDEX:
case VFIO_PCI_VGA_REGION_INDEX:
case VFIO_PCI_ROM_REGION_INDEX:
+   break;
default:
-   gvt_vgpu_err("unsupported region: %u\n", index);
+   index -= VFIO_PCI_NUM_REGIONS;
+   return vgpu->vdev.region[index].ops->rw(vgpu, buf, count,
+   ppos, is_write);
}
 
return ret == 0 ? count : ret;
@@ -940,7 +953,8 @@ static long intel_vgpu_ioctl(struct mdev_device *mdev, 
unsigned int cmd,
 
info.flags = VFIO_DEVICE_FLAGS_PCI;
info.flags |= VFIO_DEVICE_FLAGS_RESET;
-   info.num_regions = VFIO_PCI_NUM_REGIONS;
+   info.num_regions = VFIO_PCI_NUM_REGIONS +
+   vgpu->vdev.num_regions;
info.num_irqs = VFIO_PCI_NUM_IRQS;
 
return copy_to_user((void __user *)arg, , minsz) ?
@@ -1061,6 +1075,7 @@ static long intel_vgpu_ioctl(struct mdev_device *mdev, 
unsigned int cmd,
}
 
if (caps.size) {
+   info.flags |= VFIO_REGION_INFO_FLAG_CAPS;
if (info.argsz < sizeof(info) + caps.size) {
info.argsz = sizeof(info) + caps.size;
info.cap_offset = 0;
-- 
2.7.4



[PATCH v3 0/5] drm/i915/gvt: Dma-buf support for GVT-g

2017-05-22 Thread Xiaoguang Chen
v2->v3:
1) add a field gvt_plane_info in the drm_i915_gem_obj structure to save
the decoded plane information to avoid look up while need the plane info.
2) declare a new flag I915_GEM_OBJECT_IS_GVT_DMABUF in drm_i915_gem_object
to represent the gem obj for gvt's dma-buf. The tiling mode, caching mode
and domains can not be changed for this kind of gem object.
3) change dma-buf related information to be more generic. So other vendor
can use the same interface.

v1->v2:
1) create a management fd for dma-buf operations.
2) alloc gem object's backing storage in gem obj's get_pages() callback.

This patch set adds the dma-buf support for intel GVT-g.
dma-buf is a uniform mechanism to share DMA buffers across different
devices and sub-systems.
dma-buf for intel GVT-g is mainly used to share the vgpu's framebuffer
to other users or sub-systems so they can use the dma-buf to show the
desktop of a vm which uses intel vgpu.

The main idea is we create a gem object and set vgpu's framebuffer as
the backing storage of this gem object. And associate this gem obj
to a dma-buf object then export this dma-buf at the meantime
generate a file descriptor for this dma-buf. Finally deliver this file
descriptor to user space. And user can use this dma-buf fd to do render
or other operations.
User need to create a fd(for intel GVT-g dma-buf support it is a:dma-buf
management fd) then user can use this fd to query the plane information
or create a dma-buf. The life cycle of this fd is managed by GVT-g user
do not need to care about that.

We have an example program on how to use the dma-buf. You can download
the program to have a try. Good luck :)
git repo: https://github.com/01org/igvtg-qemu branch:kvmgt_dmabuf_example

Xiaoguang Chen (5):
  drm/i915/gvt: Extend the GVT-g architecture to support vfio device
region
  drm/i915/gvt: OpRegion support for GVT-g
  drm/i915/gvt: Frame buffer decoder support for GVT-g
  drm/i915/gvt: Dmabuf support for GVT-g
  drm/i915/gvt: Adding interface so user space can get the dma-buf

 drivers/gpu/drm/i915/gvt/Makefile  |   3 +-
 drivers/gpu/drm/i915/gvt/display.c |   2 +-
 drivers/gpu/drm/i915/gvt/display.h |   2 +
 drivers/gpu/drm/i915/gvt/dmabuf.c  | 276 +++
 drivers/gpu/drm/i915/gvt/dmabuf.h  |  32 +++
 drivers/gpu/drm/i915/gvt/fb_decoder.c  | 487 +
 drivers/gpu/drm/i915/gvt/fb_decoder.h  | 170 
 drivers/gpu/drm/i915/gvt/gvt.c |   2 +
 drivers/gpu/drm/i915/gvt/gvt.h |   7 +
 drivers/gpu/drm/i915/gvt/kvmgt.c   | 205 +-
 drivers/gpu/drm/i915/gvt/opregion.c|   8 +-
 drivers/gpu/drm/i915/i915_gem.c|   8 +
 drivers/gpu/drm/i915/i915_gem_object.h |   3 +
 include/uapi/linux/vfio.h  |  36 +++
 14 files changed, 1235 insertions(+), 6 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/gvt/dmabuf.c
 create mode 100644 drivers/gpu/drm/i915/gvt/dmabuf.h
 create mode 100644 drivers/gpu/drm/i915/gvt/fb_decoder.c
 create mode 100644 drivers/gpu/drm/i915/gvt/fb_decoder.h

-- 
2.7.4



[PATCH v3 5/5] drm/i915/gvt: Adding interface so user space can get the dma-buf

2017-05-22 Thread Xiaoguang Chen
User space will try to create a management fd for the dma-buf operation.
Using this management fd user can query the plane information and create
a dma-buf fd if necessary.
GVT-g will handle the life cycle of the management fd and will align the
life cycle of the fd with the vfio device.
User space should handle the life cycle of the created dma-buf fd close
the dma-buf fd timely when finishing use.

Signed-off-by: Xiaoguang Chen <xiaoguang.c...@intel.com>
---
 drivers/gpu/drm/i915/gvt/dmabuf.c | 23 ++-
 drivers/gpu/drm/i915/gvt/dmabuf.h | 22 --
 drivers/gpu/drm/i915/gvt/gvt.c|  2 +
 drivers/gpu/drm/i915/gvt/gvt.h|  3 ++
 drivers/gpu/drm/i915/gvt/kvmgt.c  | 87 +++
 include/uapi/linux/vfio.h | 36 
 6 files changed, 140 insertions(+), 33 deletions(-)

diff --git a/drivers/gpu/drm/i915/gvt/dmabuf.c 
b/drivers/gpu/drm/i915/gvt/dmabuf.c
index c9f283c..c74762f 100644
--- a/drivers/gpu/drm/i915/gvt/dmabuf.c
+++ b/drivers/gpu/drm/i915/gvt/dmabuf.c
@@ -29,6 +29,7 @@
 
 #include 
 #include 
+#include 
 
 #include "i915_drv.h"
 #include "gvt.h"
@@ -45,9 +46,9 @@ static struct sg_table *intel_vgpu_gem_get_pages(
int i, ret;
gen8_pte_t __iomem *gtt_entries;
unsigned int fb_gma = 0, fb_size = 0;
-   struct intel_vgpu_plane_info *plane_info;
+   struct plane_info *plane_info;
 
-   plane_info = (struct intel_vgpu_plane_info *)obj->gvt_plane_info;
+   plane_info = (struct plane_info *)obj->gvt_plane_info;
if (WARN_ON(!plane_info))
return ERR_PTR(-EINVAL);
 
@@ -81,9 +82,9 @@ static struct sg_table *intel_vgpu_gem_get_pages(
 static void intel_vgpu_gem_put_pages(struct drm_i915_gem_object *obj,
struct sg_table *pages)
 {
-   struct intel_vgpu_plane_info *plane_info;
+   struct plane_info *plane_info;
 
-   plane_info = (struct intel_vgpu_plane_info *)obj->gvt_plane_info;
+   plane_info = (struct plane_info *)obj->gvt_plane_info;
if (WARN_ON(!plane_info))
return;
 
@@ -98,7 +99,7 @@ static const struct drm_i915_gem_object_ops 
intel_vgpu_gem_ops = {
 };
 
 static struct drm_i915_gem_object *intel_vgpu_create_gem(struct drm_device 
*dev,
-   struct intel_vgpu_plane_info *info)
+   struct plane_info *info)
 {
struct drm_i915_private *pri = dev->dev_private;
struct drm_i915_gem_object *obj;
@@ -141,14 +142,14 @@ static struct drm_i915_gem_object 
*intel_vgpu_create_gem(struct drm_device *dev,
return obj;
 }
 
-static struct intel_vgpu_plane_info *intel_vgpu_get_plane_info(
+static struct plane_info *intel_vgpu_get_plane_info(
struct drm_device *dev,
struct intel_vgpu *vgpu, int plane_id)
 {
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_vgpu_primary_plane_format *p;
struct intel_vgpu_cursor_plane_format *c;
-   struct intel_vgpu_plane_info *info;
+   struct plane_info *info;
 
info = kmalloc(sizeof(*info), GFP_KERNEL);
if (!info)
@@ -225,8 +226,8 @@ static struct intel_vgpu_plane_info 
*intel_vgpu_get_plane_info(
 int intel_vgpu_query_dmabuf(struct intel_vgpu *vgpu, void *args)
 {
struct drm_device *dev = >gvt->dev_priv->drm;
-   struct intel_vgpu_dmabuf *gvt_dmabuf = args;
-   struct intel_vgpu_plane_info *info;
+   struct dmabuf_info *gvt_dmabuf = args;
+   struct plane_info *info;
 
info = intel_vgpu_get_plane_info(dev, vgpu, gvt_dmabuf->plane_id);
if (info == NULL)
@@ -242,8 +243,8 @@ int intel_vgpu_create_dmabuf(struct intel_vgpu *vgpu, void 
*args)
struct dma_buf *dmabuf;
struct drm_i915_gem_object *obj;
struct drm_device *dev = >gvt->dev_priv->drm;
-   struct intel_vgpu_dmabuf *gvt_dmabuf = args;
-   struct intel_vgpu_plane_info *info;
+   struct dmabuf_info *gvt_dmabuf = args;
+   struct plane_info *info;
int ret;
 
info = intel_vgpu_get_plane_info(dev, vgpu, gvt_dmabuf->plane_id);
diff --git a/drivers/gpu/drm/i915/gvt/dmabuf.h 
b/drivers/gpu/drm/i915/gvt/dmabuf.h
index c7ce642..0ddea78 100644
--- a/drivers/gpu/drm/i915/gvt/dmabuf.h
+++ b/drivers/gpu/drm/i915/gvt/dmabuf.h
@@ -26,28 +26,6 @@
 #ifndef _GVT_DMABUF_H_
 #define _GVT_DMABUF_H_
 
-struct intel_vgpu_plane_info {
-   uint32_t drm_format;
-   uint32_t width;
-   uint32_t height;
-   uint32_t stride;
-   uint32_t start;
-   uint32_t x_pos;
-   uint32_t y_pos;
-   uint32_t size;
-   uint64_t drm_format_mod;
-};
-
-#define INTEL_VGPU_QUERY_DMABUF0
-#define INTEL_VGPU_GENERATE_DMABUF 1
-
-struct intel_vgpu_dmabuf {
-   uint32_t plane_id;
-   /* out */
-   uint32_t fd;
-   struct intel_vgpu_plane_info plane_info;
-};
-
 int intel_vgpu_query_dmabuf(struct intel_vgpu *vgpu, void *args

[PATCH v3 4/5] drm/i915/gvt: Dmabuf support for GVT-g

2017-05-22 Thread Xiaoguang Chen
dmabuf for GVT-g can be exported to users who can use the dmabuf to show
the desktop of vm which use intel vgpu.

Currently we provide query and create new dmabuf operations.

Users of dmabuf can cache some created dmabufs and related information
such as the framebuffer's address, size, tiling mode, width, height etc.
When refresh the screen first query the currnet vgpu's frambuffer and
compare with the cached ones(address, size, tiling, width, height etc)
if found one then reuse the found dmabuf to gain performance improvment.

If there is no dmabuf created yet or not found in the cached dmabufs then
need to create a new dmabuf. To create a dmabuf first a gem object will
be created and the backing storage of this gem object is the vgpu's
framebuffer(primary/cursor). Then associate this gem object to a dmabuf
and export this dmabuf. A file descriptor will be generated for this
dmabuf and this file descriptor can be sent to user space to do display.

Signed-off-by: Xiaoguang Chen <xiaoguang.c...@intel.com>
---
 drivers/gpu/drm/i915/gvt/Makefile  |   2 +-
 drivers/gpu/drm/i915/gvt/dmabuf.c  | 275 +
 drivers/gpu/drm/i915/gvt/dmabuf.h  |  54 +++
 drivers/gpu/drm/i915/gvt/gvt.h |   3 +
 drivers/gpu/drm/i915/i915_gem.c|   8 +
 drivers/gpu/drm/i915/i915_gem_object.h |   3 +
 6 files changed, 344 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/i915/gvt/dmabuf.c
 create mode 100644 drivers/gpu/drm/i915/gvt/dmabuf.h

diff --git a/drivers/gpu/drm/i915/gvt/Makefile 
b/drivers/gpu/drm/i915/gvt/Makefile
index 192ca26..e480f7d 100644
--- a/drivers/gpu/drm/i915/gvt/Makefile
+++ b/drivers/gpu/drm/i915/gvt/Makefile
@@ -2,7 +2,7 @@ GVT_DIR := gvt
 GVT_SOURCE := gvt.o aperture_gm.o handlers.o vgpu.o trace_points.o firmware.o \
interrupt.o gtt.o cfg_space.o opregion.o mmio.o display.o edid.o \
execlist.o scheduler.o sched_policy.o render.o cmd_parser.o \
-   fb_decoder.o
+   fb_decoder.o dmabuf.o
 
 ccflags-y  += -I$(src) -I$(src)/$(GVT_DIR) -Wall
 i915-y += $(addprefix $(GVT_DIR)/, 
$(GVT_SOURCE))
diff --git a/drivers/gpu/drm/i915/gvt/dmabuf.c 
b/drivers/gpu/drm/i915/gvt/dmabuf.c
new file mode 100644
index 000..c9f283c
--- /dev/null
+++ b/drivers/gpu/drm/i915/gvt/dmabuf.c
@@ -0,0 +1,275 @@
+/*
+ * Copyright 2017 Intel Corporation. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *Zhiyuan Lv <zhiyuan...@intel.com>
+ *
+ * Contributors:
+ *Xiaoguang Chen <xiaoguang.c...@intel.com>
+ */
+
+#include 
+#include 
+
+#include "i915_drv.h"
+#include "gvt.h"
+
+#define GEN8_DECODE_PTE(pte) \
+   ((dma_addr_t)(u64)pte) >> 12) & 0x7ffULL) << 12))
+
+static struct sg_table *intel_vgpu_gem_get_pages(
+   struct drm_i915_gem_object *obj)
+{
+   struct drm_i915_private *dev_priv = to_i915(obj->base.dev);
+   struct sg_table *st;
+   struct scatterlist *sg;
+   int i, ret;
+   gen8_pte_t __iomem *gtt_entries;
+   unsigned int fb_gma = 0, fb_size = 0;
+   struct intel_vgpu_plane_info *plane_info;
+
+   plane_info = (struct intel_vgpu_plane_info *)obj->gvt_plane_info;
+   if (WARN_ON(!plane_info))
+   return ERR_PTR(-EINVAL);
+
+   fb_gma = plane_info->start;
+   fb_size = plane_info->size;
+
+   st = kmalloc(sizeof(*st), GFP_KERNEL);
+   if (!st) {
+   ret = -ENOMEM;
+   return ERR_PTR(ret);
+   }
+
+   ret = sg_alloc_table(st, fb_size, GFP_KERNEL);
+   if (ret) {
+   kfree(st);
+   return ERR_PTR(ret);
+   }
+   gtt_entries = (gen8_pte_t __iomem *)dev_priv->ggtt.gsm +
+   (fb_gma >> PAGE_SHIFT);
+   fo

[PATCH v3 5/5] drm/i915/gvt: Adding interface so user space can get the dma-buf

2017-05-22 Thread Xiaoguang Chen
User space will try to create a management fd for the dma-buf operation.
Using this management fd user can query the plane information and create
a dma-buf fd if necessary.
GVT-g will handle the life cycle of the management fd and will align the
life cycle of the fd with the vfio device.
User space should handle the life cycle of the created dma-buf fd close
the dma-buf fd timely when finishing use.

Signed-off-by: Xiaoguang Chen 
---
 drivers/gpu/drm/i915/gvt/dmabuf.c | 23 ++-
 drivers/gpu/drm/i915/gvt/dmabuf.h | 22 --
 drivers/gpu/drm/i915/gvt/gvt.c|  2 +
 drivers/gpu/drm/i915/gvt/gvt.h|  3 ++
 drivers/gpu/drm/i915/gvt/kvmgt.c  | 87 +++
 include/uapi/linux/vfio.h | 36 
 6 files changed, 140 insertions(+), 33 deletions(-)

diff --git a/drivers/gpu/drm/i915/gvt/dmabuf.c 
b/drivers/gpu/drm/i915/gvt/dmabuf.c
index c9f283c..c74762f 100644
--- a/drivers/gpu/drm/i915/gvt/dmabuf.c
+++ b/drivers/gpu/drm/i915/gvt/dmabuf.c
@@ -29,6 +29,7 @@
 
 #include 
 #include 
+#include 
 
 #include "i915_drv.h"
 #include "gvt.h"
@@ -45,9 +46,9 @@ static struct sg_table *intel_vgpu_gem_get_pages(
int i, ret;
gen8_pte_t __iomem *gtt_entries;
unsigned int fb_gma = 0, fb_size = 0;
-   struct intel_vgpu_plane_info *plane_info;
+   struct plane_info *plane_info;
 
-   plane_info = (struct intel_vgpu_plane_info *)obj->gvt_plane_info;
+   plane_info = (struct plane_info *)obj->gvt_plane_info;
if (WARN_ON(!plane_info))
return ERR_PTR(-EINVAL);
 
@@ -81,9 +82,9 @@ static struct sg_table *intel_vgpu_gem_get_pages(
 static void intel_vgpu_gem_put_pages(struct drm_i915_gem_object *obj,
struct sg_table *pages)
 {
-   struct intel_vgpu_plane_info *plane_info;
+   struct plane_info *plane_info;
 
-   plane_info = (struct intel_vgpu_plane_info *)obj->gvt_plane_info;
+   plane_info = (struct plane_info *)obj->gvt_plane_info;
if (WARN_ON(!plane_info))
return;
 
@@ -98,7 +99,7 @@ static const struct drm_i915_gem_object_ops 
intel_vgpu_gem_ops = {
 };
 
 static struct drm_i915_gem_object *intel_vgpu_create_gem(struct drm_device 
*dev,
-   struct intel_vgpu_plane_info *info)
+   struct plane_info *info)
 {
struct drm_i915_private *pri = dev->dev_private;
struct drm_i915_gem_object *obj;
@@ -141,14 +142,14 @@ static struct drm_i915_gem_object 
*intel_vgpu_create_gem(struct drm_device *dev,
return obj;
 }
 
-static struct intel_vgpu_plane_info *intel_vgpu_get_plane_info(
+static struct plane_info *intel_vgpu_get_plane_info(
struct drm_device *dev,
struct intel_vgpu *vgpu, int plane_id)
 {
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_vgpu_primary_plane_format *p;
struct intel_vgpu_cursor_plane_format *c;
-   struct intel_vgpu_plane_info *info;
+   struct plane_info *info;
 
info = kmalloc(sizeof(*info), GFP_KERNEL);
if (!info)
@@ -225,8 +226,8 @@ static struct intel_vgpu_plane_info 
*intel_vgpu_get_plane_info(
 int intel_vgpu_query_dmabuf(struct intel_vgpu *vgpu, void *args)
 {
struct drm_device *dev = >gvt->dev_priv->drm;
-   struct intel_vgpu_dmabuf *gvt_dmabuf = args;
-   struct intel_vgpu_plane_info *info;
+   struct dmabuf_info *gvt_dmabuf = args;
+   struct plane_info *info;
 
info = intel_vgpu_get_plane_info(dev, vgpu, gvt_dmabuf->plane_id);
if (info == NULL)
@@ -242,8 +243,8 @@ int intel_vgpu_create_dmabuf(struct intel_vgpu *vgpu, void 
*args)
struct dma_buf *dmabuf;
struct drm_i915_gem_object *obj;
struct drm_device *dev = >gvt->dev_priv->drm;
-   struct intel_vgpu_dmabuf *gvt_dmabuf = args;
-   struct intel_vgpu_plane_info *info;
+   struct dmabuf_info *gvt_dmabuf = args;
+   struct plane_info *info;
int ret;
 
info = intel_vgpu_get_plane_info(dev, vgpu, gvt_dmabuf->plane_id);
diff --git a/drivers/gpu/drm/i915/gvt/dmabuf.h 
b/drivers/gpu/drm/i915/gvt/dmabuf.h
index c7ce642..0ddea78 100644
--- a/drivers/gpu/drm/i915/gvt/dmabuf.h
+++ b/drivers/gpu/drm/i915/gvt/dmabuf.h
@@ -26,28 +26,6 @@
 #ifndef _GVT_DMABUF_H_
 #define _GVT_DMABUF_H_
 
-struct intel_vgpu_plane_info {
-   uint32_t drm_format;
-   uint32_t width;
-   uint32_t height;
-   uint32_t stride;
-   uint32_t start;
-   uint32_t x_pos;
-   uint32_t y_pos;
-   uint32_t size;
-   uint64_t drm_format_mod;
-};
-
-#define INTEL_VGPU_QUERY_DMABUF0
-#define INTEL_VGPU_GENERATE_DMABUF 1
-
-struct intel_vgpu_dmabuf {
-   uint32_t plane_id;
-   /* out */
-   uint32_t fd;
-   struct intel_vgpu_plane_info plane_info;
-};
-
 int intel_vgpu_query_dmabuf(struct intel_vgpu *vgpu, void *args);
 int intel_vgpu_create_dmabuf(struct

[PATCH v3 4/5] drm/i915/gvt: Dmabuf support for GVT-g

2017-05-22 Thread Xiaoguang Chen
dmabuf for GVT-g can be exported to users who can use the dmabuf to show
the desktop of vm which use intel vgpu.

Currently we provide query and create new dmabuf operations.

Users of dmabuf can cache some created dmabufs and related information
such as the framebuffer's address, size, tiling mode, width, height etc.
When refresh the screen first query the currnet vgpu's frambuffer and
compare with the cached ones(address, size, tiling, width, height etc)
if found one then reuse the found dmabuf to gain performance improvment.

If there is no dmabuf created yet or not found in the cached dmabufs then
need to create a new dmabuf. To create a dmabuf first a gem object will
be created and the backing storage of this gem object is the vgpu's
framebuffer(primary/cursor). Then associate this gem object to a dmabuf
and export this dmabuf. A file descriptor will be generated for this
dmabuf and this file descriptor can be sent to user space to do display.

Signed-off-by: Xiaoguang Chen 
---
 drivers/gpu/drm/i915/gvt/Makefile  |   2 +-
 drivers/gpu/drm/i915/gvt/dmabuf.c  | 275 +
 drivers/gpu/drm/i915/gvt/dmabuf.h  |  54 +++
 drivers/gpu/drm/i915/gvt/gvt.h |   3 +
 drivers/gpu/drm/i915/i915_gem.c|   8 +
 drivers/gpu/drm/i915/i915_gem_object.h |   3 +
 6 files changed, 344 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/i915/gvt/dmabuf.c
 create mode 100644 drivers/gpu/drm/i915/gvt/dmabuf.h

diff --git a/drivers/gpu/drm/i915/gvt/Makefile 
b/drivers/gpu/drm/i915/gvt/Makefile
index 192ca26..e480f7d 100644
--- a/drivers/gpu/drm/i915/gvt/Makefile
+++ b/drivers/gpu/drm/i915/gvt/Makefile
@@ -2,7 +2,7 @@ GVT_DIR := gvt
 GVT_SOURCE := gvt.o aperture_gm.o handlers.o vgpu.o trace_points.o firmware.o \
interrupt.o gtt.o cfg_space.o opregion.o mmio.o display.o edid.o \
execlist.o scheduler.o sched_policy.o render.o cmd_parser.o \
-   fb_decoder.o
+   fb_decoder.o dmabuf.o
 
 ccflags-y  += -I$(src) -I$(src)/$(GVT_DIR) -Wall
 i915-y += $(addprefix $(GVT_DIR)/, 
$(GVT_SOURCE))
diff --git a/drivers/gpu/drm/i915/gvt/dmabuf.c 
b/drivers/gpu/drm/i915/gvt/dmabuf.c
new file mode 100644
index 000..c9f283c
--- /dev/null
+++ b/drivers/gpu/drm/i915/gvt/dmabuf.c
@@ -0,0 +1,275 @@
+/*
+ * Copyright 2017 Intel Corporation. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *Zhiyuan Lv 
+ *
+ * Contributors:
+ *Xiaoguang Chen 
+ */
+
+#include 
+#include 
+
+#include "i915_drv.h"
+#include "gvt.h"
+
+#define GEN8_DECODE_PTE(pte) \
+   ((dma_addr_t)(u64)pte) >> 12) & 0x7ffULL) << 12))
+
+static struct sg_table *intel_vgpu_gem_get_pages(
+   struct drm_i915_gem_object *obj)
+{
+   struct drm_i915_private *dev_priv = to_i915(obj->base.dev);
+   struct sg_table *st;
+   struct scatterlist *sg;
+   int i, ret;
+   gen8_pte_t __iomem *gtt_entries;
+   unsigned int fb_gma = 0, fb_size = 0;
+   struct intel_vgpu_plane_info *plane_info;
+
+   plane_info = (struct intel_vgpu_plane_info *)obj->gvt_plane_info;
+   if (WARN_ON(!plane_info))
+   return ERR_PTR(-EINVAL);
+
+   fb_gma = plane_info->start;
+   fb_size = plane_info->size;
+
+   st = kmalloc(sizeof(*st), GFP_KERNEL);
+   if (!st) {
+   ret = -ENOMEM;
+   return ERR_PTR(ret);
+   }
+
+   ret = sg_alloc_table(st, fb_size, GFP_KERNEL);
+   if (ret) {
+   kfree(st);
+   return ERR_PTR(ret);
+   }
+   gtt_entries = (gen8_pte_t __iomem *)dev_priv->ggtt.gsm +
+   (fb_gma >> PAGE_SHIFT);
+   for_each_sg(st->sgl, sg, fb_size, i) {
+   sg->of

[PATCH v3 3/5] drm/i915/gvt: Frame buffer decoder support for GVT-g

2017-05-22 Thread Xiaoguang Chen
decode frambuffer attributes of primary, cursor and sprite plane

Signed-off-by: Xiaoguang Chen <xiaoguang.c...@intel.com>
---
 drivers/gpu/drm/i915/gvt/Makefile |   3 +-
 drivers/gpu/drm/i915/gvt/display.c|   2 +-
 drivers/gpu/drm/i915/gvt/display.h|   2 +
 drivers/gpu/drm/i915/gvt/fb_decoder.c | 487 ++
 drivers/gpu/drm/i915/gvt/fb_decoder.h | 170 
 drivers/gpu/drm/i915/gvt/gvt.h|   1 +
 6 files changed, 663 insertions(+), 2 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/gvt/fb_decoder.c
 create mode 100644 drivers/gpu/drm/i915/gvt/fb_decoder.h

diff --git a/drivers/gpu/drm/i915/gvt/Makefile 
b/drivers/gpu/drm/i915/gvt/Makefile
index b123c20..192ca26 100644
--- a/drivers/gpu/drm/i915/gvt/Makefile
+++ b/drivers/gpu/drm/i915/gvt/Makefile
@@ -1,7 +1,8 @@
 GVT_DIR := gvt
 GVT_SOURCE := gvt.o aperture_gm.o handlers.o vgpu.o trace_points.o firmware.o \
interrupt.o gtt.o cfg_space.o opregion.o mmio.o display.o edid.o \
-   execlist.o scheduler.o sched_policy.o render.o cmd_parser.o
+   execlist.o scheduler.o sched_policy.o render.o cmd_parser.o \
+   fb_decoder.o
 
 ccflags-y  += -I$(src) -I$(src)/$(GVT_DIR) -Wall
 i915-y += $(addprefix $(GVT_DIR)/, 
$(GVT_SOURCE))
diff --git a/drivers/gpu/drm/i915/gvt/display.c 
b/drivers/gpu/drm/i915/gvt/display.c
index e0261fc..f5f63c5 100644
--- a/drivers/gpu/drm/i915/gvt/display.c
+++ b/drivers/gpu/drm/i915/gvt/display.c
@@ -67,7 +67,7 @@ static int edp_pipe_is_enabled(struct intel_vgpu *vgpu)
return 1;
 }
 
-static int pipe_is_enabled(struct intel_vgpu *vgpu, int pipe)
+int pipe_is_enabled(struct intel_vgpu *vgpu, int pipe)
 {
struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv;
 
diff --git a/drivers/gpu/drm/i915/gvt/display.h 
b/drivers/gpu/drm/i915/gvt/display.h
index d73de22..b46b868 100644
--- a/drivers/gpu/drm/i915/gvt/display.h
+++ b/drivers/gpu/drm/i915/gvt/display.h
@@ -179,4 +179,6 @@ int intel_vgpu_init_display(struct intel_vgpu *vgpu, u64 
resolution);
 void intel_vgpu_reset_display(struct intel_vgpu *vgpu);
 void intel_vgpu_clean_display(struct intel_vgpu *vgpu);
 
+int pipe_is_enabled(struct intel_vgpu *vgpu, int pipe);
+
 #endif
diff --git a/drivers/gpu/drm/i915/gvt/fb_decoder.c 
b/drivers/gpu/drm/i915/gvt/fb_decoder.c
new file mode 100644
index 000..954f047
--- /dev/null
+++ b/drivers/gpu/drm/i915/gvt/fb_decoder.c
@@ -0,0 +1,487 @@
+/*
+ * Copyright(c) 2011-2016 Intel Corporation. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 
THE
+ * SOFTWARE.
+ *
+ * Authors:
+ *Kevin Tian <kevin.t...@intel.com>
+ *
+ * Contributors:
+ *Bing Niu <bing@intel.com>
+ *Xu Han <xu@intel.com>
+ *    Ping Gao <ping.a@intel.com>
+ *Xiaoguang Chen <xiaoguang.c...@intel.com>
+ *Yang Liu <yang2@intel.com>
+ *
+ */
+
+#include 
+#include "i915_drv.h"
+#include "gvt.h"
+
+/* The below definitions are required by guest. */
+// [63:0] x:R:G:B 16:16:16:16 little endian
+#define DRM_FORMAT_XRGB161616_GVT  fourcc_code('X', 'R', '4', '8')
+// [63:0] x:B:G:R 16:16:16:16 little endian
+#define DRM_FORMAT_XBGR161616_GVT  fourcc_code('X', 'B', '4', '8')
+
+#define FORMAT_NUM 16
+struct pixel_format {
+   int drm_format; /* Pixel format in DRM definition */
+   int bpp;/* Bits per pixel, 0 indicates invalid */
+   char *desc; /* The description */
+};
+
+/* non-supported format has bpp default to 0 */
+static struct pixel_format primary_pixel_formats[FORMAT_NUM] = {
+   [0x2] = {DRM_FORMAT_C8, 8, "8-bit Indexed"},
+   [0x5] = {DRM_FORMAT_RGB565, 16, "16-bit BGRX (5:6:5 MSB-R:G:B)"},
+   [0x6] = {DRM_FORMAT_XRGB, 32,
+   "32-bit BG

[PATCH v3 3/5] drm/i915/gvt: Frame buffer decoder support for GVT-g

2017-05-22 Thread Xiaoguang Chen
decode frambuffer attributes of primary, cursor and sprite plane

Signed-off-by: Xiaoguang Chen 
---
 drivers/gpu/drm/i915/gvt/Makefile |   3 +-
 drivers/gpu/drm/i915/gvt/display.c|   2 +-
 drivers/gpu/drm/i915/gvt/display.h|   2 +
 drivers/gpu/drm/i915/gvt/fb_decoder.c | 487 ++
 drivers/gpu/drm/i915/gvt/fb_decoder.h | 170 
 drivers/gpu/drm/i915/gvt/gvt.h|   1 +
 6 files changed, 663 insertions(+), 2 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/gvt/fb_decoder.c
 create mode 100644 drivers/gpu/drm/i915/gvt/fb_decoder.h

diff --git a/drivers/gpu/drm/i915/gvt/Makefile 
b/drivers/gpu/drm/i915/gvt/Makefile
index b123c20..192ca26 100644
--- a/drivers/gpu/drm/i915/gvt/Makefile
+++ b/drivers/gpu/drm/i915/gvt/Makefile
@@ -1,7 +1,8 @@
 GVT_DIR := gvt
 GVT_SOURCE := gvt.o aperture_gm.o handlers.o vgpu.o trace_points.o firmware.o \
interrupt.o gtt.o cfg_space.o opregion.o mmio.o display.o edid.o \
-   execlist.o scheduler.o sched_policy.o render.o cmd_parser.o
+   execlist.o scheduler.o sched_policy.o render.o cmd_parser.o \
+   fb_decoder.o
 
 ccflags-y  += -I$(src) -I$(src)/$(GVT_DIR) -Wall
 i915-y += $(addprefix $(GVT_DIR)/, 
$(GVT_SOURCE))
diff --git a/drivers/gpu/drm/i915/gvt/display.c 
b/drivers/gpu/drm/i915/gvt/display.c
index e0261fc..f5f63c5 100644
--- a/drivers/gpu/drm/i915/gvt/display.c
+++ b/drivers/gpu/drm/i915/gvt/display.c
@@ -67,7 +67,7 @@ static int edp_pipe_is_enabled(struct intel_vgpu *vgpu)
return 1;
 }
 
-static int pipe_is_enabled(struct intel_vgpu *vgpu, int pipe)
+int pipe_is_enabled(struct intel_vgpu *vgpu, int pipe)
 {
struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv;
 
diff --git a/drivers/gpu/drm/i915/gvt/display.h 
b/drivers/gpu/drm/i915/gvt/display.h
index d73de22..b46b868 100644
--- a/drivers/gpu/drm/i915/gvt/display.h
+++ b/drivers/gpu/drm/i915/gvt/display.h
@@ -179,4 +179,6 @@ int intel_vgpu_init_display(struct intel_vgpu *vgpu, u64 
resolution);
 void intel_vgpu_reset_display(struct intel_vgpu *vgpu);
 void intel_vgpu_clean_display(struct intel_vgpu *vgpu);
 
+int pipe_is_enabled(struct intel_vgpu *vgpu, int pipe);
+
 #endif
diff --git a/drivers/gpu/drm/i915/gvt/fb_decoder.c 
b/drivers/gpu/drm/i915/gvt/fb_decoder.c
new file mode 100644
index 000..954f047
--- /dev/null
+++ b/drivers/gpu/drm/i915/gvt/fb_decoder.c
@@ -0,0 +1,487 @@
+/*
+ * Copyright(c) 2011-2016 Intel Corporation. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 
THE
+ * SOFTWARE.
+ *
+ * Authors:
+ *Kevin Tian 
+ *
+ * Contributors:
+ *Bing Niu 
+ *Xu Han 
+ *Ping Gao 
+ *Xiaoguang Chen 
+ *Yang Liu 
+ *
+ */
+
+#include 
+#include "i915_drv.h"
+#include "gvt.h"
+
+/* The below definitions are required by guest. */
+// [63:0] x:R:G:B 16:16:16:16 little endian
+#define DRM_FORMAT_XRGB161616_GVT  fourcc_code('X', 'R', '4', '8')
+// [63:0] x:B:G:R 16:16:16:16 little endian
+#define DRM_FORMAT_XBGR161616_GVT  fourcc_code('X', 'B', '4', '8')
+
+#define FORMAT_NUM 16
+struct pixel_format {
+   int drm_format; /* Pixel format in DRM definition */
+   int bpp;/* Bits per pixel, 0 indicates invalid */
+   char *desc; /* The description */
+};
+
+/* non-supported format has bpp default to 0 */
+static struct pixel_format primary_pixel_formats[FORMAT_NUM] = {
+   [0x2] = {DRM_FORMAT_C8, 8, "8-bit Indexed"},
+   [0x5] = {DRM_FORMAT_RGB565, 16, "16-bit BGRX (5:6:5 MSB-R:G:B)"},
+   [0x6] = {DRM_FORMAT_XRGB, 32,
+   "32-bit BGRX (8:8:8:8 MSB-X:R:G:B)"},
+   [0x8] = {DRM_FORMAT_XBGR2101010, 32,
+   "32-bit RGBX (2:10:10:10 MSB-X:B:G:R)"},
+   [0xa] = {DRM_FORMAT_

[PATCH v3 2/5] drm/i915/gvt: OpRegion support for GVT-g

2017-05-22 Thread Xiaoguang Chen
OpRegion is needed to support display related operation for
intel vgpu.

A vfio device region is added to intel vgpu to deliver the
host OpRegion information to user space so user space can
construct the OpRegion for vgpu.

Signed-off-by: Bing Niu <bing@intel.com>
Signed-off-by: Xiaoguang Chen <xiaoguang.c...@intel.com>
---
 drivers/gpu/drm/i915/gvt/kvmgt.c| 97 +
 drivers/gpu/drm/i915/gvt/opregion.c |  8 ++-
 2 files changed, 104 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
index 3c6a02b..389f072 100644
--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
+++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
@@ -53,6 +53,8 @@ static const struct intel_gvt_ops *intel_gvt_ops;
 #define VFIO_PCI_INDEX_TO_OFFSET(index) ((u64)(index) << VFIO_PCI_OFFSET_SHIFT)
 #define VFIO_PCI_OFFSET_MASK(((u64)(1) << VFIO_PCI_OFFSET_SHIFT) - 1)
 
+#define OPREGION_SIGNATURE "IntelGraphicsMem"
+
 struct vfio_region;
 struct intel_vgpu_regops {
size_t (*rw)(struct intel_vgpu *vgpu, char *buf,
@@ -436,6 +438,92 @@ static void kvmgt_protect_table_del(struct 
kvmgt_guest_info *info,
}
 }
 
+static size_t intel_vgpu_reg_rw_opregion(struct intel_vgpu *vgpu, char *buf,
+   size_t count, loff_t *ppos, bool iswrite)
+{
+   unsigned int i = VFIO_PCI_OFFSET_TO_INDEX(*ppos) -
+   VFIO_PCI_NUM_REGIONS;
+   void *base = vgpu->vdev.region[i].data;
+   loff_t pos = *ppos & VFIO_PCI_OFFSET_MASK;
+
+   if (pos >= vgpu->vdev.region[i].size || iswrite) {
+   gvt_vgpu_err("invalid op or offset for Intel vgpu OpRegion\n");
+   return -EINVAL;
+   }
+   count = min(count, (size_t)(vgpu->vdev.region[i].size - pos));
+   memcpy(buf, base + pos, count);
+
+   return count;
+}
+
+static void intel_vgpu_reg_release_opregion(struct intel_vgpu *vgpu,
+   struct vfio_region *region)
+{
+   memunmap(region->data);
+}
+
+static const struct intel_vgpu_regops intel_vgpu_regops_opregion = {
+   .rw = intel_vgpu_reg_rw_opregion,
+   .release = intel_vgpu_reg_release_opregion,
+};
+
+static int intel_vgpu_register_reg(struct intel_vgpu *vgpu,
+   unsigned int type, unsigned int subtype,
+   const struct intel_vgpu_regops *ops,
+   size_t size, u32 flags, void *data)
+{
+   struct vfio_region *region;
+
+   region = krealloc(vgpu->vdev.region,
+   (vgpu->vdev.num_regions + 1) * sizeof(*region),
+   GFP_KERNEL);
+   if (!region)
+   return -ENOMEM;
+
+   vgpu->vdev.region = region;
+   vgpu->vdev.region[vgpu->vdev.num_regions].type = type;
+   vgpu->vdev.region[vgpu->vdev.num_regions].subtype = subtype;
+   vgpu->vdev.region[vgpu->vdev.num_regions].ops = ops;
+   vgpu->vdev.region[vgpu->vdev.num_regions].size = size;
+   vgpu->vdev.region[vgpu->vdev.num_regions].flags = flags;
+   vgpu->vdev.region[vgpu->vdev.num_regions].data = data;
+   vgpu->vdev.num_regions++;
+
+   return 0;
+}
+
+static int intel_vgpu_reg_init_opregion(struct intel_vgpu *vgpu)
+{
+   unsigned int addr;
+   void *base;
+   int ret;
+
+   addr = vgpu->gvt->opregion.opregion_pa;
+   if (!addr || !(~addr))
+   return -ENODEV;
+
+   base = memremap(addr, OPREGION_SIZE, MEMREMAP_WB);
+   if (!base)
+   return -ENOMEM;
+
+   if (memcmp(base, OPREGION_SIGNATURE, 16)) {
+   memunmap(base);
+   return -EINVAL;
+   }
+
+   ret = intel_vgpu_register_reg(vgpu,
+   PCI_VENDOR_ID_INTEL | VFIO_REGION_TYPE_PCI_VENDOR_TYPE,
+   VFIO_REGION_SUBTYPE_INTEL_IGD_OPREGION,
+   _vgpu_regops_opregion, OPREGION_SIZE,
+   VFIO_REGION_INFO_FLAG_READ, base);
+   if (ret) {
+   memunmap(base);
+   return ret;
+   }
+
+   return ret;
+}
+
 static int intel_vgpu_create(struct kobject *kobj, struct mdev_device *mdev)
 {
struct intel_vgpu *vgpu = NULL;
@@ -467,6 +555,15 @@ static int intel_vgpu_create(struct kobject *kobj, struct 
mdev_device *mdev)
vgpu->vdev.mdev = mdev;
mdev_set_drvdata(mdev, vgpu);
 
+   ret = intel_vgpu_reg_init_opregion(vgpu);
+   if (ret) {
+   gvt_vgpu_err("create OpRegion failed\n");
+   goto out;
+   }
+
+   gvt_dbg_core("create OpRegion succeeded for mdev:%s\n",
+   dev_name(mdev_dev(mdev)));
+
gvt_dbg_core("intel_vgpu_create succeeded for mdev: %s\n",
 dev_name(mdev_dev(mdev)));
ret = 0;
diff --git a/drivers/gpu/drm/i915/gvt/opregion.c 
b/drivers/gpu/drm/i915/gvt/opregion.c
index 3117991.

[PATCH v3 2/5] drm/i915/gvt: OpRegion support for GVT-g

2017-05-22 Thread Xiaoguang Chen
OpRegion is needed to support display related operation for
intel vgpu.

A vfio device region is added to intel vgpu to deliver the
host OpRegion information to user space so user space can
construct the OpRegion for vgpu.

Signed-off-by: Bing Niu 
Signed-off-by: Xiaoguang Chen 
---
 drivers/gpu/drm/i915/gvt/kvmgt.c| 97 +
 drivers/gpu/drm/i915/gvt/opregion.c |  8 ++-
 2 files changed, 104 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
index 3c6a02b..389f072 100644
--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
+++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
@@ -53,6 +53,8 @@ static const struct intel_gvt_ops *intel_gvt_ops;
 #define VFIO_PCI_INDEX_TO_OFFSET(index) ((u64)(index) << VFIO_PCI_OFFSET_SHIFT)
 #define VFIO_PCI_OFFSET_MASK(((u64)(1) << VFIO_PCI_OFFSET_SHIFT) - 1)
 
+#define OPREGION_SIGNATURE "IntelGraphicsMem"
+
 struct vfio_region;
 struct intel_vgpu_regops {
size_t (*rw)(struct intel_vgpu *vgpu, char *buf,
@@ -436,6 +438,92 @@ static void kvmgt_protect_table_del(struct 
kvmgt_guest_info *info,
}
 }
 
+static size_t intel_vgpu_reg_rw_opregion(struct intel_vgpu *vgpu, char *buf,
+   size_t count, loff_t *ppos, bool iswrite)
+{
+   unsigned int i = VFIO_PCI_OFFSET_TO_INDEX(*ppos) -
+   VFIO_PCI_NUM_REGIONS;
+   void *base = vgpu->vdev.region[i].data;
+   loff_t pos = *ppos & VFIO_PCI_OFFSET_MASK;
+
+   if (pos >= vgpu->vdev.region[i].size || iswrite) {
+   gvt_vgpu_err("invalid op or offset for Intel vgpu OpRegion\n");
+   return -EINVAL;
+   }
+   count = min(count, (size_t)(vgpu->vdev.region[i].size - pos));
+   memcpy(buf, base + pos, count);
+
+   return count;
+}
+
+static void intel_vgpu_reg_release_opregion(struct intel_vgpu *vgpu,
+   struct vfio_region *region)
+{
+   memunmap(region->data);
+}
+
+static const struct intel_vgpu_regops intel_vgpu_regops_opregion = {
+   .rw = intel_vgpu_reg_rw_opregion,
+   .release = intel_vgpu_reg_release_opregion,
+};
+
+static int intel_vgpu_register_reg(struct intel_vgpu *vgpu,
+   unsigned int type, unsigned int subtype,
+   const struct intel_vgpu_regops *ops,
+   size_t size, u32 flags, void *data)
+{
+   struct vfio_region *region;
+
+   region = krealloc(vgpu->vdev.region,
+   (vgpu->vdev.num_regions + 1) * sizeof(*region),
+   GFP_KERNEL);
+   if (!region)
+   return -ENOMEM;
+
+   vgpu->vdev.region = region;
+   vgpu->vdev.region[vgpu->vdev.num_regions].type = type;
+   vgpu->vdev.region[vgpu->vdev.num_regions].subtype = subtype;
+   vgpu->vdev.region[vgpu->vdev.num_regions].ops = ops;
+   vgpu->vdev.region[vgpu->vdev.num_regions].size = size;
+   vgpu->vdev.region[vgpu->vdev.num_regions].flags = flags;
+   vgpu->vdev.region[vgpu->vdev.num_regions].data = data;
+   vgpu->vdev.num_regions++;
+
+   return 0;
+}
+
+static int intel_vgpu_reg_init_opregion(struct intel_vgpu *vgpu)
+{
+   unsigned int addr;
+   void *base;
+   int ret;
+
+   addr = vgpu->gvt->opregion.opregion_pa;
+   if (!addr || !(~addr))
+   return -ENODEV;
+
+   base = memremap(addr, OPREGION_SIZE, MEMREMAP_WB);
+   if (!base)
+   return -ENOMEM;
+
+   if (memcmp(base, OPREGION_SIGNATURE, 16)) {
+   memunmap(base);
+   return -EINVAL;
+   }
+
+   ret = intel_vgpu_register_reg(vgpu,
+   PCI_VENDOR_ID_INTEL | VFIO_REGION_TYPE_PCI_VENDOR_TYPE,
+   VFIO_REGION_SUBTYPE_INTEL_IGD_OPREGION,
+   _vgpu_regops_opregion, OPREGION_SIZE,
+   VFIO_REGION_INFO_FLAG_READ, base);
+   if (ret) {
+   memunmap(base);
+   return ret;
+   }
+
+   return ret;
+}
+
 static int intel_vgpu_create(struct kobject *kobj, struct mdev_device *mdev)
 {
struct intel_vgpu *vgpu = NULL;
@@ -467,6 +555,15 @@ static int intel_vgpu_create(struct kobject *kobj, struct 
mdev_device *mdev)
vgpu->vdev.mdev = mdev;
mdev_set_drvdata(mdev, vgpu);
 
+   ret = intel_vgpu_reg_init_opregion(vgpu);
+   if (ret) {
+   gvt_vgpu_err("create OpRegion failed\n");
+   goto out;
+   }
+
+   gvt_dbg_core("create OpRegion succeeded for mdev:%s\n",
+   dev_name(mdev_dev(mdev)));
+
gvt_dbg_core("intel_vgpu_create succeeded for mdev: %s\n",
 dev_name(mdev_dev(mdev)));
ret = 0;
diff --git a/drivers/gpu/drm/i915/gvt/opregion.c 
b/drivers/gpu/drm/i915/gvt/opregion.c
index 3117991..5c7496d 100644
--- a/drivers/gpu/drm/i915

[PATCH v2 4/5] drm/i915/gvt: Dmabuf support for GVT-g

2017-05-18 Thread Xiaoguang Chen
dmabuf for GVT-g can be exported to users who can use the dmabuf to show
the desktop of vm which use intel vgpu.

Currently we provide query and create new dmabuf operations.

Users of dmabuf can cache some created dmabufs and related information
such as the framebuffer's address, size, tiling mode, width, height etc.
When refresh the screen first query the currnet vgpu's frambuffer and
compare with the cached ones(address, size, tiling, width, height etc)
if found one then reuse the found dmabuf to gain performance improvment.

If there is no dmabuf created yet or not found in the cached dmabufs then
need to create a new dmabuf. To create a dmabuf first a gem object will
be created and the backing storage of this gem object is the vgpu's
framebuffer(primary/cursor). Then associate this gem object to a dmabuf
and export this dmabuf. A file descriptor will be generated for this
dmabuf and this file descriptor can be sent to user space to do display.

Signed-off-by: Xiaoguang Chen <xiaoguang.c...@intel.com>
---
 drivers/gpu/drm/i915/gvt/Makefile |   2 +-
 drivers/gpu/drm/i915/gvt/dmabuf.c | 321 ++
 drivers/gpu/drm/i915/gvt/dmabuf.h |  44 ++
 drivers/gpu/drm/i915/gvt/gvt.h|   3 +
 include/uapi/drm/i915_drm.h   |  21 +++
 5 files changed, 390 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/i915/gvt/dmabuf.c
 create mode 100644 drivers/gpu/drm/i915/gvt/dmabuf.h

diff --git a/drivers/gpu/drm/i915/gvt/Makefile 
b/drivers/gpu/drm/i915/gvt/Makefile
index 192ca26..e480f7d 100644
--- a/drivers/gpu/drm/i915/gvt/Makefile
+++ b/drivers/gpu/drm/i915/gvt/Makefile
@@ -2,7 +2,7 @@ GVT_DIR := gvt
 GVT_SOURCE := gvt.o aperture_gm.o handlers.o vgpu.o trace_points.o firmware.o \
interrupt.o gtt.o cfg_space.o opregion.o mmio.o display.o edid.o \
execlist.o scheduler.o sched_policy.o render.o cmd_parser.o \
-   fb_decoder.o
+   fb_decoder.o dmabuf.o
 
 ccflags-y  += -I$(src) -I$(src)/$(GVT_DIR) -Wall
 i915-y += $(addprefix $(GVT_DIR)/, 
$(GVT_SOURCE))
diff --git a/drivers/gpu/drm/i915/gvt/dmabuf.c 
b/drivers/gpu/drm/i915/gvt/dmabuf.c
new file mode 100644
index 000..3358e6f
--- /dev/null
+++ b/drivers/gpu/drm/i915/gvt/dmabuf.c
@@ -0,0 +1,321 @@
+/*
+ * Copyright 2017 Intel Corporation. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *Zhiyuan Lv <zhiyuan...@intel.com>
+ *
+ * Contributors:
+ *Xiaoguang Chen <xiaoguang.c...@intel.com>
+ */
+
+#include 
+#include 
+
+#include "i915_drv.h"
+#include "gvt.h"
+
+#define GEN8_DECODE_PTE(pte) \
+   ((dma_addr_t)(u64)pte) >> 12) & 0x7ffULL) << 12))
+
+static struct sg_table *intel_vgpu_gem_get_pages(
+   struct drm_i915_gem_object *obj)
+{
+   struct drm_i915_private *dev_priv = to_i915(obj->base.dev);
+   struct intel_gvt *gvt = dev_priv->gvt;
+   struct sg_table *st;
+   struct scatterlist *sg;
+   int i, ret;
+   gen8_pte_t __iomem *gtt_entries;
+   struct intel_vgpu *vgpu;
+   unsigned int fb_gma = 0, fb_size = 0;
+   bool found = false;
+
+   mutex_lock(>lock);
+   for_each_active_vgpu(gvt, vgpu, i) {
+   if (vgpu->obj_dmabuf == obj) {
+   fb_gma = vgpu->plane_info->start;
+   fb_size = vgpu->plane_info->size;
+   found = true;
+   break;
+   }
+   }
+   mutex_unlock(>lock);
+
+   if (!found) {
+   gvt_vgpu_err("no vgpu found\n");
+   return NULL;
+   }
+
+   st = kmalloc(sizeof(*st), GFP_KERNEL);
+   if (!st) {
+   ret = -ENOMEM;
+   return ERR_PTR(ret);

[PATCH v2 4/5] drm/i915/gvt: Dmabuf support for GVT-g

2017-05-18 Thread Xiaoguang Chen
dmabuf for GVT-g can be exported to users who can use the dmabuf to show
the desktop of vm which use intel vgpu.

Currently we provide query and create new dmabuf operations.

Users of dmabuf can cache some created dmabufs and related information
such as the framebuffer's address, size, tiling mode, width, height etc.
When refresh the screen first query the currnet vgpu's frambuffer and
compare with the cached ones(address, size, tiling, width, height etc)
if found one then reuse the found dmabuf to gain performance improvment.

If there is no dmabuf created yet or not found in the cached dmabufs then
need to create a new dmabuf. To create a dmabuf first a gem object will
be created and the backing storage of this gem object is the vgpu's
framebuffer(primary/cursor). Then associate this gem object to a dmabuf
and export this dmabuf. A file descriptor will be generated for this
dmabuf and this file descriptor can be sent to user space to do display.

Signed-off-by: Xiaoguang Chen 
---
 drivers/gpu/drm/i915/gvt/Makefile |   2 +-
 drivers/gpu/drm/i915/gvt/dmabuf.c | 321 ++
 drivers/gpu/drm/i915/gvt/dmabuf.h |  44 ++
 drivers/gpu/drm/i915/gvt/gvt.h|   3 +
 include/uapi/drm/i915_drm.h   |  21 +++
 5 files changed, 390 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/i915/gvt/dmabuf.c
 create mode 100644 drivers/gpu/drm/i915/gvt/dmabuf.h

diff --git a/drivers/gpu/drm/i915/gvt/Makefile 
b/drivers/gpu/drm/i915/gvt/Makefile
index 192ca26..e480f7d 100644
--- a/drivers/gpu/drm/i915/gvt/Makefile
+++ b/drivers/gpu/drm/i915/gvt/Makefile
@@ -2,7 +2,7 @@ GVT_DIR := gvt
 GVT_SOURCE := gvt.o aperture_gm.o handlers.o vgpu.o trace_points.o firmware.o \
interrupt.o gtt.o cfg_space.o opregion.o mmio.o display.o edid.o \
execlist.o scheduler.o sched_policy.o render.o cmd_parser.o \
-   fb_decoder.o
+   fb_decoder.o dmabuf.o
 
 ccflags-y  += -I$(src) -I$(src)/$(GVT_DIR) -Wall
 i915-y += $(addprefix $(GVT_DIR)/, 
$(GVT_SOURCE))
diff --git a/drivers/gpu/drm/i915/gvt/dmabuf.c 
b/drivers/gpu/drm/i915/gvt/dmabuf.c
new file mode 100644
index 000..3358e6f
--- /dev/null
+++ b/drivers/gpu/drm/i915/gvt/dmabuf.c
@@ -0,0 +1,321 @@
+/*
+ * Copyright 2017 Intel Corporation. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *Zhiyuan Lv 
+ *
+ * Contributors:
+ *Xiaoguang Chen 
+ */
+
+#include 
+#include 
+
+#include "i915_drv.h"
+#include "gvt.h"
+
+#define GEN8_DECODE_PTE(pte) \
+   ((dma_addr_t)(u64)pte) >> 12) & 0x7ffULL) << 12))
+
+static struct sg_table *intel_vgpu_gem_get_pages(
+   struct drm_i915_gem_object *obj)
+{
+   struct drm_i915_private *dev_priv = to_i915(obj->base.dev);
+   struct intel_gvt *gvt = dev_priv->gvt;
+   struct sg_table *st;
+   struct scatterlist *sg;
+   int i, ret;
+   gen8_pte_t __iomem *gtt_entries;
+   struct intel_vgpu *vgpu;
+   unsigned int fb_gma = 0, fb_size = 0;
+   bool found = false;
+
+   mutex_lock(>lock);
+   for_each_active_vgpu(gvt, vgpu, i) {
+   if (vgpu->obj_dmabuf == obj) {
+   fb_gma = vgpu->plane_info->start;
+   fb_size = vgpu->plane_info->size;
+   found = true;
+   break;
+   }
+   }
+   mutex_unlock(>lock);
+
+   if (!found) {
+   gvt_vgpu_err("no vgpu found\n");
+   return NULL;
+   }
+
+   st = kmalloc(sizeof(*st), GFP_KERNEL);
+   if (!st) {
+   ret = -ENOMEM;
+   return ERR_PTR(ret);
+   }
+
+   ret = sg_alloc_table(st, fb_size, GFP_KERNEL);
+   if (ret) {
+   kfree(

[PATCH v2 2/5] drm/i915/gvt: OpRegion support for GVT-g

2017-05-18 Thread Xiaoguang Chen
OpRegion is needed to support display related operation for
intel vgpu.

A vfio device region is added to intel vgpu to deliver the
host OpRegion information to user space so user space can
construct the OpRegion for vgpu.

Signed-off-by: Bing Niu <bing@intel.com>
Signed-off-by: Xiaoguang Chen <xiaoguang.c...@intel.com>
---
 drivers/gpu/drm/i915/gvt/kvmgt.c| 97 +
 drivers/gpu/drm/i915/gvt/opregion.c | 12 -
 2 files changed, 107 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
index 3c6a02b..389f072 100644
--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
+++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
@@ -53,6 +53,8 @@
 #define VFIO_PCI_INDEX_TO_OFFSET(index) ((u64)(index) << VFIO_PCI_OFFSET_SHIFT)
 #define VFIO_PCI_OFFSET_MASK(((u64)(1) << VFIO_PCI_OFFSET_SHIFT) - 1)
 
+#define OPREGION_SIGNATURE "IntelGraphicsMem"
+
 struct vfio_region;
 struct intel_vgpu_regops {
size_t (*rw)(struct intel_vgpu *vgpu, char *buf,
@@ -436,6 +438,92 @@ static void kvmgt_protect_table_del(struct 
kvmgt_guest_info *info,
}
 }
 
+static size_t intel_vgpu_reg_rw_opregion(struct intel_vgpu *vgpu, char *buf,
+   size_t count, loff_t *ppos, bool iswrite)
+{
+   unsigned int i = VFIO_PCI_OFFSET_TO_INDEX(*ppos) -
+   VFIO_PCI_NUM_REGIONS;
+   void *base = vgpu->vdev.region[i].data;
+   loff_t pos = *ppos & VFIO_PCI_OFFSET_MASK;
+
+   if (pos >= vgpu->vdev.region[i].size || iswrite) {
+   gvt_vgpu_err("invalid op or offset for Intel vgpu OpRegion\n");
+   return -EINVAL;
+   }
+   count = min(count, (size_t)(vgpu->vdev.region[i].size - pos));
+   memcpy(buf, base + pos, count);
+
+   return count;
+}
+
+static void intel_vgpu_reg_release_opregion(struct intel_vgpu *vgpu,
+   struct vfio_region *region)
+{
+   memunmap(region->data);
+}
+
+static const struct intel_vgpu_regops intel_vgpu_regops_opregion = {
+   .rw = intel_vgpu_reg_rw_opregion,
+   .release = intel_vgpu_reg_release_opregion,
+};
+
+static int intel_vgpu_register_reg(struct intel_vgpu *vgpu,
+   unsigned int type, unsigned int subtype,
+   const struct intel_vgpu_regops *ops,
+   size_t size, u32 flags, void *data)
+{
+   struct vfio_region *region;
+
+   region = krealloc(vgpu->vdev.region,
+   (vgpu->vdev.num_regions + 1) * sizeof(*region),
+   GFP_KERNEL);
+   if (!region)
+   return -ENOMEM;
+
+   vgpu->vdev.region = region;
+   vgpu->vdev.region[vgpu->vdev.num_regions].type = type;
+   vgpu->vdev.region[vgpu->vdev.num_regions].subtype = subtype;
+   vgpu->vdev.region[vgpu->vdev.num_regions].ops = ops;
+   vgpu->vdev.region[vgpu->vdev.num_regions].size = size;
+   vgpu->vdev.region[vgpu->vdev.num_regions].flags = flags;
+   vgpu->vdev.region[vgpu->vdev.num_regions].data = data;
+   vgpu->vdev.num_regions++;
+
+   return 0;
+}
+
+static int intel_vgpu_reg_init_opregion(struct intel_vgpu *vgpu)
+{
+   unsigned int addr;
+   void *base;
+   int ret;
+
+   addr = vgpu->gvt->opregion.opregion_pa;
+   if (!addr || !(~addr))
+   return -ENODEV;
+
+   base = memremap(addr, OPREGION_SIZE, MEMREMAP_WB);
+   if (!base)
+   return -ENOMEM;
+
+   if (memcmp(base, OPREGION_SIGNATURE, 16)) {
+   memunmap(base);
+   return -EINVAL;
+   }
+
+   ret = intel_vgpu_register_reg(vgpu,
+   PCI_VENDOR_ID_INTEL | VFIO_REGION_TYPE_PCI_VENDOR_TYPE,
+   VFIO_REGION_SUBTYPE_INTEL_IGD_OPREGION,
+   _vgpu_regops_opregion, OPREGION_SIZE,
+   VFIO_REGION_INFO_FLAG_READ, base);
+   if (ret) {
+   memunmap(base);
+   return ret;
+   }
+
+   return ret;
+}
+
 static int intel_vgpu_create(struct kobject *kobj, struct mdev_device *mdev)
 {
struct intel_vgpu *vgpu = NULL;
@@ -467,6 +555,15 @@ static int intel_vgpu_create(struct kobject *kobj, struct 
mdev_device *mdev)
vgpu->vdev.mdev = mdev;
mdev_set_drvdata(mdev, vgpu);
 
+   ret = intel_vgpu_reg_init_opregion(vgpu);
+   if (ret) {
+   gvt_vgpu_err("create OpRegion failed\n");
+   goto out;
+   }
+
+   gvt_dbg_core("create OpRegion succeeded for mdev:%s\n",
+   dev_name(mdev_dev(mdev)));
+
gvt_dbg_core("intel_vgpu_create succeeded for mdev: %s\n",
 dev_name(mdev_dev(mdev)));
ret = 0;
diff --git a/drivers/gpu/drm/i915/gvt/opregion.c 
b/drivers/gpu/drm/i915/gvt/opregion.c
index 3117991..99591bc 100644
--- a/drivers/gpu/drm/i915/gvt/

[PATCH v2 2/5] drm/i915/gvt: OpRegion support for GVT-g

2017-05-18 Thread Xiaoguang Chen
OpRegion is needed to support display related operation for
intel vgpu.

A vfio device region is added to intel vgpu to deliver the
host OpRegion information to user space so user space can
construct the OpRegion for vgpu.

Signed-off-by: Bing Niu 
Signed-off-by: Xiaoguang Chen 
---
 drivers/gpu/drm/i915/gvt/kvmgt.c| 97 +
 drivers/gpu/drm/i915/gvt/opregion.c | 12 -
 2 files changed, 107 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
index 3c6a02b..389f072 100644
--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
+++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
@@ -53,6 +53,8 @@
 #define VFIO_PCI_INDEX_TO_OFFSET(index) ((u64)(index) << VFIO_PCI_OFFSET_SHIFT)
 #define VFIO_PCI_OFFSET_MASK(((u64)(1) << VFIO_PCI_OFFSET_SHIFT) - 1)
 
+#define OPREGION_SIGNATURE "IntelGraphicsMem"
+
 struct vfio_region;
 struct intel_vgpu_regops {
size_t (*rw)(struct intel_vgpu *vgpu, char *buf,
@@ -436,6 +438,92 @@ static void kvmgt_protect_table_del(struct 
kvmgt_guest_info *info,
}
 }
 
+static size_t intel_vgpu_reg_rw_opregion(struct intel_vgpu *vgpu, char *buf,
+   size_t count, loff_t *ppos, bool iswrite)
+{
+   unsigned int i = VFIO_PCI_OFFSET_TO_INDEX(*ppos) -
+   VFIO_PCI_NUM_REGIONS;
+   void *base = vgpu->vdev.region[i].data;
+   loff_t pos = *ppos & VFIO_PCI_OFFSET_MASK;
+
+   if (pos >= vgpu->vdev.region[i].size || iswrite) {
+   gvt_vgpu_err("invalid op or offset for Intel vgpu OpRegion\n");
+   return -EINVAL;
+   }
+   count = min(count, (size_t)(vgpu->vdev.region[i].size - pos));
+   memcpy(buf, base + pos, count);
+
+   return count;
+}
+
+static void intel_vgpu_reg_release_opregion(struct intel_vgpu *vgpu,
+   struct vfio_region *region)
+{
+   memunmap(region->data);
+}
+
+static const struct intel_vgpu_regops intel_vgpu_regops_opregion = {
+   .rw = intel_vgpu_reg_rw_opregion,
+   .release = intel_vgpu_reg_release_opregion,
+};
+
+static int intel_vgpu_register_reg(struct intel_vgpu *vgpu,
+   unsigned int type, unsigned int subtype,
+   const struct intel_vgpu_regops *ops,
+   size_t size, u32 flags, void *data)
+{
+   struct vfio_region *region;
+
+   region = krealloc(vgpu->vdev.region,
+   (vgpu->vdev.num_regions + 1) * sizeof(*region),
+   GFP_KERNEL);
+   if (!region)
+   return -ENOMEM;
+
+   vgpu->vdev.region = region;
+   vgpu->vdev.region[vgpu->vdev.num_regions].type = type;
+   vgpu->vdev.region[vgpu->vdev.num_regions].subtype = subtype;
+   vgpu->vdev.region[vgpu->vdev.num_regions].ops = ops;
+   vgpu->vdev.region[vgpu->vdev.num_regions].size = size;
+   vgpu->vdev.region[vgpu->vdev.num_regions].flags = flags;
+   vgpu->vdev.region[vgpu->vdev.num_regions].data = data;
+   vgpu->vdev.num_regions++;
+
+   return 0;
+}
+
+static int intel_vgpu_reg_init_opregion(struct intel_vgpu *vgpu)
+{
+   unsigned int addr;
+   void *base;
+   int ret;
+
+   addr = vgpu->gvt->opregion.opregion_pa;
+   if (!addr || !(~addr))
+   return -ENODEV;
+
+   base = memremap(addr, OPREGION_SIZE, MEMREMAP_WB);
+   if (!base)
+   return -ENOMEM;
+
+   if (memcmp(base, OPREGION_SIGNATURE, 16)) {
+   memunmap(base);
+   return -EINVAL;
+   }
+
+   ret = intel_vgpu_register_reg(vgpu,
+   PCI_VENDOR_ID_INTEL | VFIO_REGION_TYPE_PCI_VENDOR_TYPE,
+   VFIO_REGION_SUBTYPE_INTEL_IGD_OPREGION,
+   _vgpu_regops_opregion, OPREGION_SIZE,
+   VFIO_REGION_INFO_FLAG_READ, base);
+   if (ret) {
+   memunmap(base);
+   return ret;
+   }
+
+   return ret;
+}
+
 static int intel_vgpu_create(struct kobject *kobj, struct mdev_device *mdev)
 {
struct intel_vgpu *vgpu = NULL;
@@ -467,6 +555,15 @@ static int intel_vgpu_create(struct kobject *kobj, struct 
mdev_device *mdev)
vgpu->vdev.mdev = mdev;
mdev_set_drvdata(mdev, vgpu);
 
+   ret = intel_vgpu_reg_init_opregion(vgpu);
+   if (ret) {
+   gvt_vgpu_err("create OpRegion failed\n");
+   goto out;
+   }
+
+   gvt_dbg_core("create OpRegion succeeded for mdev:%s\n",
+   dev_name(mdev_dev(mdev)));
+
gvt_dbg_core("intel_vgpu_create succeeded for mdev: %s\n",
 dev_name(mdev_dev(mdev)));
ret = 0;
diff --git a/drivers/gpu/drm/i915/gvt/opregion.c 
b/drivers/gpu/drm/i915/gvt/opregion.c
index 3117991..99591bc 100644
--- a/drivers/gpu/drm/i915/gvt/opregion.c
+++ b/drivers/gpu/drm/i915/gvt/opregion.c
@@ -28

[PATCH v2 5/5] drm/i915/gvt: Adding interface so user space can get the dma-buf

2017-05-18 Thread Xiaoguang Chen
User space will try to create a management fd for the dma-buf operation.
Using this management fd user can query the plane information and create
a dma-buf fd if necessary.
GVT-g will handle the life cycle of the management fd and will align the
life cycle of the fd with the vfio device.
User space should handle the life cycle of the created dma-buf fd close
the dma-buf fd timely when finishing use.

Signed-off-by: Xiaoguang Chen <xiaoguang.c...@intel.com>
---
 drivers/gpu/drm/i915/gvt/gvt.c   |  2 +
 drivers/gpu/drm/i915/gvt/gvt.h   |  3 ++
 drivers/gpu/drm/i915/gvt/kvmgt.c | 89 
 include/uapi/drm/i915_drm.h  |  2 +
 include/uapi/linux/vfio.h| 12 ++
 5 files changed, 108 insertions(+)

diff --git a/drivers/gpu/drm/i915/gvt/gvt.c b/drivers/gpu/drm/i915/gvt/gvt.c
index 2032917..48e04e6 100644
--- a/drivers/gpu/drm/i915/gvt/gvt.c
+++ b/drivers/gpu/drm/i915/gvt/gvt.c
@@ -54,6 +54,8 @@
.vgpu_reset = intel_gvt_reset_vgpu,
.vgpu_activate = intel_gvt_activate_vgpu,
.vgpu_deactivate = intel_gvt_deactivate_vgpu,
+   .vgpu_query_dmabuf = intel_vgpu_query_dmabuf,
+   .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 a553120..b7fdfd5 100644
--- a/drivers/gpu/drm/i915/gvt/gvt.h
+++ b/drivers/gpu/drm/i915/gvt/gvt.h
@@ -185,6 +185,7 @@ struct intel_vgpu {
struct kvm *kvm;
struct work_struct release_work;
atomic_t released;
+   struct vfio_device *vfio_device;
} vdev;
 #endif
struct intel_vgpu_plane_info *plane_info;
@@ -469,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_dmabuf)(struct intel_vgpu *, void *);
+   int (*vgpu_create_dmabuf)(struct intel_vgpu *, void *);
 };
 
 
diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
index 389f072..9a663df 100644
--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
+++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
@@ -41,6 +41,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "i915_drv.h"
 #include "gvt.h"
@@ -524,6 +525,66 @@ static int intel_vgpu_reg_init_opregion(struct intel_vgpu 
*vgpu)
return ret;
 }
 
+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;
+
+   if (vgpu->vdev.vfio_device != NULL)
+   vfio_device_put(vgpu->vdev.vfio_device);
+   else
+   gvt_vgpu_err("intel vgpu dmabuf mgr fd is in a wrong state\n");
+
+   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;
+   struct intel_vgpu_dmabuf dmabuf;
+   int ret;
+   struct fd f;
+
+   minsz = offsetofend(struct intel_vgpu_dmabuf, tiled);
+   if (copy_from_user(, (void __user *)arg, minsz))
+   return -EFAULT;
+
+   f = fdget(dmabuf.fd);
+
+   if (ioctl == INTEL_VGPU_QUERY_DMABUF)
+   ret = intel_gvt_ops->vgpu_query_dmabuf(vgpu, );
+   else if (ioctl == INTEL_VGPU_GENERATE_DMABUF)
+   ret = intel_gvt_ops->vgpu_create_dmabuf(vgpu, );
+   else {
+   fdput(f);
+   gvt_vgpu_err("unsupported dmabuf operation\n");
+   return -EINVAL;
+   }
+
+   if (ret != 0) {
+   fdput(f);
+   gvt_vgpu_err("gvt-g get dmabuf failed:%d\n", ret);
+   return -EINVAL;
+   }
+   fdput(f);
+
+   return copy_to_user((void __user *)arg, , minsz) ? -EFAULT : 0;
+}
+
+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 +1320,34 @@ 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;
+   struct vfio_device *device;
+
+   if (copy_from_user(, (void __user *)arg, sizeof(type)))
+  

[PATCH v2 5/5] drm/i915/gvt: Adding interface so user space can get the dma-buf

2017-05-18 Thread Xiaoguang Chen
User space will try to create a management fd for the dma-buf operation.
Using this management fd user can query the plane information and create
a dma-buf fd if necessary.
GVT-g will handle the life cycle of the management fd and will align the
life cycle of the fd with the vfio device.
User space should handle the life cycle of the created dma-buf fd close
the dma-buf fd timely when finishing use.

Signed-off-by: Xiaoguang Chen 
---
 drivers/gpu/drm/i915/gvt/gvt.c   |  2 +
 drivers/gpu/drm/i915/gvt/gvt.h   |  3 ++
 drivers/gpu/drm/i915/gvt/kvmgt.c | 89 
 include/uapi/drm/i915_drm.h  |  2 +
 include/uapi/linux/vfio.h| 12 ++
 5 files changed, 108 insertions(+)

diff --git a/drivers/gpu/drm/i915/gvt/gvt.c b/drivers/gpu/drm/i915/gvt/gvt.c
index 2032917..48e04e6 100644
--- a/drivers/gpu/drm/i915/gvt/gvt.c
+++ b/drivers/gpu/drm/i915/gvt/gvt.c
@@ -54,6 +54,8 @@
.vgpu_reset = intel_gvt_reset_vgpu,
.vgpu_activate = intel_gvt_activate_vgpu,
.vgpu_deactivate = intel_gvt_deactivate_vgpu,
+   .vgpu_query_dmabuf = intel_vgpu_query_dmabuf,
+   .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 a553120..b7fdfd5 100644
--- a/drivers/gpu/drm/i915/gvt/gvt.h
+++ b/drivers/gpu/drm/i915/gvt/gvt.h
@@ -185,6 +185,7 @@ struct intel_vgpu {
struct kvm *kvm;
struct work_struct release_work;
atomic_t released;
+   struct vfio_device *vfio_device;
} vdev;
 #endif
struct intel_vgpu_plane_info *plane_info;
@@ -469,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_dmabuf)(struct intel_vgpu *, void *);
+   int (*vgpu_create_dmabuf)(struct intel_vgpu *, void *);
 };
 
 
diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
index 389f072..9a663df 100644
--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
+++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
@@ -41,6 +41,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "i915_drv.h"
 #include "gvt.h"
@@ -524,6 +525,66 @@ static int intel_vgpu_reg_init_opregion(struct intel_vgpu 
*vgpu)
return ret;
 }
 
+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;
+
+   if (vgpu->vdev.vfio_device != NULL)
+   vfio_device_put(vgpu->vdev.vfio_device);
+   else
+   gvt_vgpu_err("intel vgpu dmabuf mgr fd is in a wrong state\n");
+
+   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;
+   struct intel_vgpu_dmabuf dmabuf;
+   int ret;
+   struct fd f;
+
+   minsz = offsetofend(struct intel_vgpu_dmabuf, tiled);
+   if (copy_from_user(, (void __user *)arg, minsz))
+   return -EFAULT;
+
+   f = fdget(dmabuf.fd);
+
+   if (ioctl == INTEL_VGPU_QUERY_DMABUF)
+   ret = intel_gvt_ops->vgpu_query_dmabuf(vgpu, );
+   else if (ioctl == INTEL_VGPU_GENERATE_DMABUF)
+   ret = intel_gvt_ops->vgpu_create_dmabuf(vgpu, );
+   else {
+   fdput(f);
+   gvt_vgpu_err("unsupported dmabuf operation\n");
+   return -EINVAL;
+   }
+
+   if (ret != 0) {
+   fdput(f);
+   gvt_vgpu_err("gvt-g get dmabuf failed:%d\n", ret);
+   return -EINVAL;
+   }
+   fdput(f);
+
+   return copy_to_user((void __user *)arg, , minsz) ? -EFAULT : 0;
+}
+
+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 +1320,34 @@ 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;
+   struct vfio_device *device;
+
+   if (copy_from_user(, (void __user *)arg, sizeof(type)))
+   return -EINVAL;
+   if (type != INTEL_VGPU_

  1   2   >