All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFCv2 PATCH 00/14] gvt: Hacking i915 for GVT context requirement
@ 2016-02-18 11:42 Zhi Wang
  2016-02-18 11:42 ` [RFCv2 01/14] drm/i915: factor out i915_pvinfo.h Zhi Wang
                   ` (15 more replies)
  0 siblings, 16 replies; 46+ messages in thread
From: Zhi Wang @ 2016-02-18 11:42 UTC (permalink / raw)
  To: intel-gfx, igvt-g; +Cc: daniel.vetter, david.j.cowperthwaite, zhiyuan.lv

This patchset is used to discuss and finalize the i915 changes required by
GVT context. Previously we have discussed about how to hack i915 to meet
GVT context requirement, and thanks for the idea and comments.

In this patchset, mostly it refactors the existing i915 APIs, spliting the
hard-coded assumptions from its core logic, keep these assumptions in the
high level wrapper and make the core logic much more flexible and config-
urable, which is able to be used by GVT context creation and submission.

Mostly it based on Daniel's and Kevin's idea here:

http://www.spinics.net/lists/intel-gfx/msg87750.html
http://www.spinics.net/lists/intel-gfx/msg87745.html

And also it incldues the two v2 patches which have addresses the comments
from Joonas

Previous patches reviewed here:

drm/i915/gvt: Introduce the basic architecture of GVT-g:

http://www.spinics.net/lists/intel-gfx/msg86739.html

drm/i915: Introduce host graphics memory/fence partition for GVT-g

http://www.spinics.net/lists/intel-gfx/msg87132.html

Acknowledgment
---------------

iGVT-g implementation is several years effort and many people
contributed to the code. There names are not here yet. In later formal
patchset we will reflect individual's contribution.

Meanwhile, in the previous iGVT-g related discussion, Daniel, Chris
and Joonas ever gave very good inputs. We appreciate them and look
forward to more comments/suggestions from community.

We are trying to get more familiar with i915 and willing to adopt
suggestions to keep improving. We hope to work with community together
to make iGVT-g a great component in i915 to support graphics 
virtualization. Thanks!

Bing Niu (1):
  drm/i915: Introduce host graphics memory/fence partition for GVT-g

Zhi Wang (13):
  drm/i915: factor out i915_pvinfo.h
  drm/i915/gvt: Introduce the basic architecture of GVT-g
  drm/i915: factor out alloc_context_idr() and
    __i915_gem_create_context()
  drm/i915: factor out __create_legacy_hw_context()
  drm/i915: let __i915_gem_context_create() takes context creation
    params
  drm/i915: factor out __intel_lr_context_deferred_alloc()
  drm/i915: Support per-PPGTT address space mode
  drm/i915: generate address mode bit from PPGTT instance
  drm/i915: update PDPs by condition when submit the LRC context
  drm/i915: Introduce execlist context status change notification
  drm/i915: factor out execlists_i915_pick_requests()
  drm/i915: Support context single submission when GVT is active
  drm/i915: Introduce GVT context creation API

 drivers/gpu/drm/i915/Kconfig            |  15 ++
 drivers/gpu/drm/i915/Makefile           |   2 +
 drivers/gpu/drm/i915/gvt/Makefile       |   5 +
 drivers/gpu/drm/i915/gvt/debug.h        |  57 +++++
 drivers/gpu/drm/i915/gvt/gvt.c          | 397 ++++++++++++++++++++++++++++++++
 drivers/gpu/drm/i915/gvt/gvt.h          | 100 ++++++++
 drivers/gpu/drm/i915/gvt/hypercall.h    |  30 +++
 drivers/gpu/drm/i915/gvt/mpt.h          |  34 +++
 drivers/gpu/drm/i915/gvt/params.c       |  44 ++++
 drivers/gpu/drm/i915/gvt/params.h       |  37 +++
 drivers/gpu/drm/i915/gvt/reg.h          |  34 +++
 drivers/gpu/drm/i915/i915_dma.c         |  14 ++
 drivers/gpu/drm/i915/i915_drv.h         |  52 +++++
 drivers/gpu/drm/i915/i915_gem.c         |   4 +-
 drivers/gpu/drm/i915/i915_gem_context.c | 204 +++++++++++-----
 drivers/gpu/drm/i915/i915_gem_gtt.c     |  85 ++++---
 drivers/gpu/drm/i915/i915_gem_gtt.h     |   3 +
 drivers/gpu/drm/i915/i915_gvt.c         |  93 ++++++++
 drivers/gpu/drm/i915/i915_gvt.h         |  49 ++++
 drivers/gpu/drm/i915/i915_pvinfo.h      | 113 +++++++++
 drivers/gpu/drm/i915/i915_vgpu.c        |  21 +-
 drivers/gpu/drm/i915/i915_vgpu.h        |  86 +------
 drivers/gpu/drm/i915/intel_lrc.c        | 225 +++++++++++++-----
 drivers/gpu/drm/i915/intel_lrc.h        |  15 ++
 24 files changed, 1477 insertions(+), 242 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/gvt/Makefile
 create mode 100644 drivers/gpu/drm/i915/gvt/debug.h
 create mode 100644 drivers/gpu/drm/i915/gvt/gvt.c
 create mode 100644 drivers/gpu/drm/i915/gvt/gvt.h
 create mode 100644 drivers/gpu/drm/i915/gvt/hypercall.h
 create mode 100644 drivers/gpu/drm/i915/gvt/mpt.h
 create mode 100644 drivers/gpu/drm/i915/gvt/params.c
 create mode 100644 drivers/gpu/drm/i915/gvt/params.h
 create mode 100644 drivers/gpu/drm/i915/gvt/reg.h
 create mode 100644 drivers/gpu/drm/i915/i915_gvt.c
 create mode 100644 drivers/gpu/drm/i915/i915_gvt.h
 create mode 100644 drivers/gpu/drm/i915/i915_pvinfo.h

-- 
1.9.1

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

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [RFCv2 01/14] drm/i915: factor out i915_pvinfo.h
  2016-02-18 11:42 [RFCv2 PATCH 00/14] gvt: Hacking i915 for GVT context requirement Zhi Wang
@ 2016-02-18 11:42 ` Zhi Wang
  2016-02-22 13:23   ` Joonas Lahtinen
  2016-02-18 11:42 ` [RFCv2 02/14] drm/i915/gvt: Introduce the basic architecture of GVT-g Zhi Wang
                   ` (14 subsequent siblings)
  15 siblings, 1 reply; 46+ messages in thread
From: Zhi Wang @ 2016-02-18 11:42 UTC (permalink / raw)
  To: intel-gfx, igvt-g; +Cc: daniel.vetter, david.j.cowperthwaite, zhiyuan.lv

As the PVINFO page definition is used by both GVT-g guest (vGPU) and GVT-g
host (GVT-g kernel device model), factor it out for better code structure.

Signed-off-by: Zhi Wang <zhi.a.wang@intel.com>
---
 drivers/gpu/drm/i915/i915_pvinfo.h | 113 +++++++++++++++++++++++++++++++++++++
 drivers/gpu/drm/i915/i915_vgpu.h   |  86 +---------------------------
 2 files changed, 114 insertions(+), 85 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/i915_pvinfo.h

diff --git a/drivers/gpu/drm/i915/i915_pvinfo.h b/drivers/gpu/drm/i915/i915_pvinfo.h
new file mode 100644
index 0000000..68bdf60
--- /dev/null
+++ b/drivers/gpu/drm/i915/i915_pvinfo.h
@@ -0,0 +1,113 @@
+/*
+ * 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.
+ */
+
+#ifndef _I915_PVINFO_H_
+#define _I915_PVINFO_H_
+
+/* The MMIO offset of the shared info between guest and host emulator */
+#define VGT_PVINFO_PAGE	0x78000
+#define VGT_PVINFO_SIZE	0x1000
+
+/*
+ * The following structure pages are defined in GEN MMIO space
+ * for virtualization. (One page for now)
+ */
+#define VGT_MAGIC         0x4776544776544776ULL	/* 'vGTvGTvG' */
+#define VGT_VERSION_MAJOR 1
+#define VGT_VERSION_MINOR 0
+
+#define INTEL_VGT_IF_VERSION_ENCODE(major, minor) ((major) << 16 | (minor))
+#define INTEL_VGT_IF_VERSION \
+	INTEL_VGT_IF_VERSION_ENCODE(VGT_VERSION_MAJOR, VGT_VERSION_MINOR)
+
+/*
+ * notifications from guest to vgpu device model
+ */
+enum vgt_g2v_type {
+	VGT_G2V_PPGTT_L3_PAGE_TABLE_CREATE = 2,
+	VGT_G2V_PPGTT_L3_PAGE_TABLE_DESTROY,
+	VGT_G2V_PPGTT_L4_PAGE_TABLE_CREATE,
+	VGT_G2V_PPGTT_L4_PAGE_TABLE_DESTROY,
+	VGT_G2V_EXECLIST_CONTEXT_CREATE,
+	VGT_G2V_EXECLIST_CONTEXT_DESTROY,
+	VGT_G2V_MAX,
+};
+
+struct vgt_if {
+	uint64_t magic;		/* VGT_MAGIC */
+	uint16_t version_major;
+	uint16_t version_minor;
+	uint32_t vgt_id;	/* ID of vGT instance */
+	uint32_t rsv1[12];	/* pad to offset 0x40 */
+	/*
+	 *  Data structure to describe the balooning info of resources.
+	 *  Each VM can only have one portion of continuous area for now.
+	 *  (May support scattered resource in future)
+	 *  (starting from offset 0x40)
+	 */
+	struct {
+		/* Aperture register balooning */
+		struct {
+			uint32_t base;
+			uint32_t size;
+		} mappable_gmadr;	/* aperture */
+		/* GMADR register balooning */
+		struct {
+			uint32_t base;
+			uint32_t size;
+		} nonmappable_gmadr;	/* non aperture */
+		/* allowed fence registers */
+		uint32_t fence_num;
+		uint32_t rsv2[3];
+	} avail_rs;		/* available/assigned resource */
+	uint32_t rsv3[0x200 - 24];	/* pad to half page */
+	/*
+	 * The bottom half page is for response from Gfx driver to hypervisor.
+	 */
+	uint32_t rsv4;
+	uint32_t display_ready;	/* ready for display owner switch */
+
+	uint32_t rsv5[4];
+
+	uint32_t g2v_notify;
+	uint32_t rsv6[7];
+
+	struct {
+		uint32_t lo;
+		uint32_t hi;
+	} pdp[4];
+
+	uint32_t execlist_context_descriptor_lo;
+	uint32_t execlist_context_descriptor_hi;
+
+	uint32_t  rsv7[0x200 - 24];    /* pad to one page */
+} __packed;
+
+#define vgtif_reg(x) \
+	_MMIO((VGT_PVINFO_PAGE + (long)&((struct vgt_if *)NULL)->x))
+
+/* vGPU display status to be used by the host side */
+#define VGT_DRV_DISPLAY_NOT_READY 0
+#define VGT_DRV_DISPLAY_READY     1  /* ready for display switch */
+
+#endif /* _I915_PVINFO_H_ */
diff --git a/drivers/gpu/drm/i915/i915_vgpu.h b/drivers/gpu/drm/i915/i915_vgpu.h
index 3c83b47..a3b06f3 100644
--- a/drivers/gpu/drm/i915/i915_vgpu.h
+++ b/drivers/gpu/drm/i915/i915_vgpu.h
@@ -24,91 +24,7 @@
 #ifndef _I915_VGPU_H_
 #define _I915_VGPU_H_
 
-/* The MMIO offset of the shared info between guest and host emulator */
-#define VGT_PVINFO_PAGE	0x78000
-#define VGT_PVINFO_SIZE	0x1000
-
-/*
- * The following structure pages are defined in GEN MMIO space
- * for virtualization. (One page for now)
- */
-#define VGT_MAGIC         0x4776544776544776ULL	/* 'vGTvGTvG' */
-#define VGT_VERSION_MAJOR 1
-#define VGT_VERSION_MINOR 0
-
-#define INTEL_VGT_IF_VERSION_ENCODE(major, minor) ((major) << 16 | (minor))
-#define INTEL_VGT_IF_VERSION \
-	INTEL_VGT_IF_VERSION_ENCODE(VGT_VERSION_MAJOR, VGT_VERSION_MINOR)
-
-/*
- * notifications from guest to vgpu device model
- */
-enum vgt_g2v_type {
-	VGT_G2V_PPGTT_L3_PAGE_TABLE_CREATE = 2,
-	VGT_G2V_PPGTT_L3_PAGE_TABLE_DESTROY,
-	VGT_G2V_PPGTT_L4_PAGE_TABLE_CREATE,
-	VGT_G2V_PPGTT_L4_PAGE_TABLE_DESTROY,
-	VGT_G2V_EXECLIST_CONTEXT_CREATE,
-	VGT_G2V_EXECLIST_CONTEXT_DESTROY,
-	VGT_G2V_MAX,
-};
-
-struct vgt_if {
-	uint64_t magic;		/* VGT_MAGIC */
-	uint16_t version_major;
-	uint16_t version_minor;
-	uint32_t vgt_id;	/* ID of vGT instance */
-	uint32_t rsv1[12];	/* pad to offset 0x40 */
-	/*
-	 *  Data structure to describe the balooning info of resources.
-	 *  Each VM can only have one portion of continuous area for now.
-	 *  (May support scattered resource in future)
-	 *  (starting from offset 0x40)
-	 */
-	struct {
-		/* Aperture register balooning */
-		struct {
-			uint32_t base;
-			uint32_t size;
-		} mappable_gmadr;	/* aperture */
-		/* GMADR register balooning */
-		struct {
-			uint32_t base;
-			uint32_t size;
-		} nonmappable_gmadr;	/* non aperture */
-		/* allowed fence registers */
-		uint32_t fence_num;
-		uint32_t rsv2[3];
-	} avail_rs;		/* available/assigned resource */
-	uint32_t rsv3[0x200 - 24];	/* pad to half page */
-	/*
-	 * The bottom half page is for response from Gfx driver to hypervisor.
-	 */
-	uint32_t rsv4;
-	uint32_t display_ready;	/* ready for display owner switch */
-
-	uint32_t rsv5[4];
-
-	uint32_t g2v_notify;
-	uint32_t rsv6[7];
-
-	struct {
-		uint32_t lo;
-		uint32_t hi;
-	} pdp[4];
-
-	uint32_t execlist_context_descriptor_lo;
-	uint32_t execlist_context_descriptor_hi;
-
-	uint32_t  rsv7[0x200 - 24];    /* pad to one page */
-} __packed;
-
-#define vgtif_reg(x) \
-	_MMIO((VGT_PVINFO_PAGE + (long)&((struct vgt_if *)NULL)->x))
-
-/* vGPU display status to be used by the host side */
-#define VGT_DRV_DISPLAY_NOT_READY 0
-#define VGT_DRV_DISPLAY_READY     1  /* ready for display switch */
+#include "i915_pvinfo.h"
 
 extern void i915_check_vgpu(struct drm_device *dev);
 extern int intel_vgt_balloon(struct drm_device *dev);
-- 
1.9.1

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

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [RFCv2 02/14] drm/i915/gvt: Introduce the basic architecture of GVT-g
  2016-02-18 11:42 [RFCv2 PATCH 00/14] gvt: Hacking i915 for GVT context requirement Zhi Wang
  2016-02-18 11:42 ` [RFCv2 01/14] drm/i915: factor out i915_pvinfo.h Zhi Wang
@ 2016-02-18 11:42 ` Zhi Wang
  2016-02-23 12:42   ` Joonas Lahtinen
                     ` (2 more replies)
  2016-02-18 11:42 ` [RFCv2 03/14] drm/i915: Introduce host graphics memory/fence partition for GVT-g Zhi Wang
                   ` (13 subsequent siblings)
  15 siblings, 3 replies; 46+ messages in thread
From: Zhi Wang @ 2016-02-18 11:42 UTC (permalink / raw)
  To: intel-gfx, igvt-g; +Cc: daniel.vetter, david.j.cowperthwaite, zhiyuan.lv

This patch introduces the very basic framework of GVT-g device model,
includes basic prototypes, definitions, initialization.

v2:
- Introduce i915_gvt.c.
It's necessary to introduce the stubs between i915 driver and GVT-g host,
as GVT-g components is configurable in kernel config. When disabled, the
stubs here do nothing.

Take Joonas's comments:
- Replace boolean return value with int.
- Replace customized info/warn/debug macros with DRM macros.
- Document all non-static functions like i915.
- Remove empty and unused functions.
- Replace magic number with marcos.
- Set GVT-g in kernel config to "n" by default.

Signed-off-by: Zhi Wang <zhi.a.wang@intel.com>
---
 drivers/gpu/drm/i915/Kconfig         |  15 ++
 drivers/gpu/drm/i915/Makefile        |   2 +
 drivers/gpu/drm/i915/gvt/Makefile    |   5 +
 drivers/gpu/drm/i915/gvt/debug.h     |  57 +++++
 drivers/gpu/drm/i915/gvt/gvt.c       | 393 +++++++++++++++++++++++++++++++++++
 drivers/gpu/drm/i915/gvt/gvt.h       | 100 +++++++++
 drivers/gpu/drm/i915/gvt/hypercall.h |  30 +++
 drivers/gpu/drm/i915/gvt/mpt.h       |  34 +++
 drivers/gpu/drm/i915/gvt/params.c    |  32 +++
 drivers/gpu/drm/i915/gvt/params.h    |  34 +++
 drivers/gpu/drm/i915/gvt/reg.h       |  34 +++
 drivers/gpu/drm/i915/i915_dma.c      |  14 ++
 drivers/gpu/drm/i915/i915_drv.h      |  12 ++
 drivers/gpu/drm/i915/i915_gvt.c      |  93 +++++++++
 drivers/gpu/drm/i915/i915_gvt.h      |  49 +++++
 15 files changed, 904 insertions(+)
 create mode 100644 drivers/gpu/drm/i915/gvt/Makefile
 create mode 100644 drivers/gpu/drm/i915/gvt/debug.h
 create mode 100644 drivers/gpu/drm/i915/gvt/gvt.c
 create mode 100644 drivers/gpu/drm/i915/gvt/gvt.h
 create mode 100644 drivers/gpu/drm/i915/gvt/hypercall.h
 create mode 100644 drivers/gpu/drm/i915/gvt/mpt.h
 create mode 100644 drivers/gpu/drm/i915/gvt/params.c
 create mode 100644 drivers/gpu/drm/i915/gvt/params.h
 create mode 100644 drivers/gpu/drm/i915/gvt/reg.h
 create mode 100644 drivers/gpu/drm/i915/i915_gvt.c
 create mode 100644 drivers/gpu/drm/i915/i915_gvt.h

diff --git a/drivers/gpu/drm/i915/Kconfig b/drivers/gpu/drm/i915/Kconfig
index 4c59793..082e77d 100644
--- a/drivers/gpu/drm/i915/Kconfig
+++ b/drivers/gpu/drm/i915/Kconfig
@@ -45,3 +45,18 @@ config DRM_I915_PRELIMINARY_HW_SUPPORT
 	  option changes the default for that module option.
 
 	  If in doubt, say "N".
+
+config DRM_I915_GVT
+        tristate "GVT-g host driver"
+        depends on DRM_I915
+        default n
+        help
+          Enabling GVT-g mediated graphics passthrough technique for Intel i915
+          based integrated graphics card. With GVT-g, it's possible to have one
+          integrated i915 device shared by multiple VMs. Performance critical
+          opterations such as apperture accesses and ring buffer operations
+          are pass-throughed to VM, with a minimal set of conflicting resources
+          (e.g. display settings) mediated by vGT driver. The benefit of vGT
+          is on both the performance, given that each VM could directly operate
+          its aperture space and submit commands like running on native, and
+          the feature completeness, given that a true GEN hardware is exposed.
diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 0851de07..c65026c 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -91,6 +91,8 @@ i915-y += dvo_ch7017.o \
 	  intel_sdvo.o \
 	  intel_tv.o
 
+obj-$(CONFIG_DRM_I915_GVT)  += i915_gvt.o gvt/
+
 # virtual gpu code
 i915-y += i915_vgpu.o
 
diff --git a/drivers/gpu/drm/i915/gvt/Makefile b/drivers/gpu/drm/i915/gvt/Makefile
new file mode 100644
index 0000000..959305f
--- /dev/null
+++ b/drivers/gpu/drm/i915/gvt/Makefile
@@ -0,0 +1,5 @@
+GVT_SOURCE := gvt.o params.o
+
+ccflags-y                      += -I$(src) -I$(src)/.. -Wall -Werror -Wno-unused-function
+i915_gvt-y                     := $(GVT_SOURCE)
+obj-$(CONFIG_DRM_I915_GVT)     += i915_gvt.o
diff --git a/drivers/gpu/drm/i915/gvt/debug.h b/drivers/gpu/drm/i915/gvt/debug.h
new file mode 100644
index 0000000..0747f28
--- /dev/null
+++ b/drivers/gpu/drm/i915/gvt/debug.h
@@ -0,0 +1,57 @@
+/*
+ * 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.
+ */
+
+#ifndef __GVT_DEBUG_H__
+#define __GVT_DEBUG_H__
+
+#define gvt_info(fmt, args...) \
+	DRM_INFO("gvt: "fmt"\n", ##args)
+
+#define gvt_err(fmt, args...) \
+	DRM_ERROR("gvt: "fmt"\n", ##args)
+
+#define gvt_warn(condition, fmt, args...) \
+	WARN((condition), "gvt: "fmt"\n", ##args)
+
+#define gvt_warn_once(condition, fmt, args...) \
+	WARN_ONCE((condition), "gvt: "fmt"\n", ##args)
+
+#define gvt_dbg(level, fmt, args...) \
+	DRM_DEBUG_DRIVER("gvt: "fmt"\n", ##args)
+
+enum {
+	GVT_DBG_CORE = (1 << 0),
+	GVT_DBG_MM = (1 << 1),
+	GVT_DBG_IRQ = (1 << 2),
+};
+
+#define gvt_dbg_core(fmt, args...) \
+	gvt_dbg(GVT_DBG_CORE, fmt, ##args)
+
+#define gvt_dbg_mm(fmt, args...) \
+	gvt_dbg(GVT_DBG_MM, fmt, ##args)
+
+#define gvt_dbg_irq(fmt, args...) \
+	gvt_dbg(GVT_DBG_IRQ, fmt, ##args)
+
+#endif
diff --git a/drivers/gpu/drm/i915/gvt/gvt.c b/drivers/gpu/drm/i915/gvt/gvt.c
new file mode 100644
index 0000000..52cfa32
--- /dev/null
+++ b/drivers/gpu/drm/i915/gvt/gvt.c
@@ -0,0 +1,393 @@
+/*
+ * 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.
+ */
+
+#include <linux/types.h>
+#include <xen/xen.h>
+#include <linux/kthread.h>
+
+#include "gvt.h"
+
+struct gvt_host gvt_host;
+
+static const char * const supported_hypervisors[] = {
+	[GVT_HYPERVISOR_TYPE_XEN] = "Xen Hypervisor",
+	[GVT_HYPERVISOR_TYPE_KVM] = "KVM",
+};
+
+static int gvt_init_host(void)
+{
+	struct gvt_host *host = &gvt_host;
+
+	if (!gvt.enable) {
+		gvt_dbg_core("GVT-g has been disabled by kernel parameter");
+		return -EINVAL;
+	}
+
+	if (host->initialized) {
+		gvt_err("GVT-g has already been initialized!");
+		return -EINVAL;
+	}
+
+	/* Xen DOM U */
+	if (xen_domain() && !xen_initial_domain())
+		return -ENODEV;
+
+	if (xen_initial_domain()) {
+		/* Xen Dom0 */
+		host->kdm = try_then_request_module(
+				symbol_get(xengt_kdm), "xengt");
+		host->hypervisor_type = GVT_HYPERVISOR_TYPE_XEN;
+	} else {
+		/* not in Xen. Try KVMGT */
+		host->kdm = try_then_request_module(
+				symbol_get(kvmgt_kdm), "kvm");
+		host->hypervisor_type = GVT_HYPERVISOR_TYPE_KVM;
+	}
+
+	if (!host->kdm)
+		return -EINVAL;
+
+	if (!hypervisor_detect_host())
+		return -ENODEV;
+
+	gvt_info("Running with hypervisor %s in host mode",
+			supported_hypervisors[host->hypervisor_type]);
+
+	idr_init(&host->device_idr);
+	mutex_init(&host->device_idr_lock);
+
+	host->initialized = true;
+	return 0;
+}
+
+static int init_device_info(struct pgt_device *pdev)
+{
+	struct gvt_device_info *info = &pdev->device_info;
+
+	if (!IS_BROADWELL(pdev->dev_priv)) {
+		DRM_DEBUG_DRIVER("Unsupported GEN device");
+		return -ENODEV;
+	}
+
+	if (IS_BROADWELL(pdev->dev_priv)) {
+		info->max_gtt_gm_sz = (1ULL << 32); /* 4GB */
+		/*
+		 * The layout of BAR0 in BDW:
+		 * |< - MMIO 2MB ->|<- Reserved 6MB ->|<- MAX GTT 8MB->|
+		 *
+		 * GTT offset in BAR0 starts from 8MB to 16MB, and
+		 * Whatever GTT size is configured in BIOS,
+		 * the size of BAR0 is always 16MB. The actual configured
+		 * GTT size can be found in GMCH_CTRL.
+		 */
+		info->gtt_start_offset = (1UL << 23); /* 8MB */
+		info->max_gtt_size = (1UL << 23); /* 8MB */
+		info->gtt_entry_size = 8;
+		info->gtt_entry_size_shift = 3;
+		info->gmadr_bytes_in_cmd = 8;
+		info->mmio_size = 2 * 1024 * 1024; /* 2MB */
+	}
+
+	return 0;
+}
+
+static void init_initial_cfg_space_state(struct pgt_device *pdev)
+{
+	struct pci_dev *pci_dev = pdev->dev_priv->dev->pdev;
+	int i;
+
+	gvt_dbg_core("init initial cfg space, id %d", pdev->id);
+
+	for (i = 0; i < GVT_CFG_SPACE_SZ; i += 4)
+		pci_read_config_dword(pci_dev, i,
+				(u32 *)&pdev->initial_cfg_space[i]);
+
+	for (i = 0; i < GVT_BAR_NUM; i++) {
+		pdev->bar_size[i] = pci_resource_len(pci_dev, i * 2);
+		gvt_dbg_core("bar %d size: %llx", i, pdev->bar_size[i]);
+	}
+}
+
+static void clean_initial_mmio_state(struct pgt_device *pdev)
+{
+	if (pdev->gttmmio_va) {
+		iounmap(pdev->gttmmio_va);
+		pdev->gttmmio_va = NULL;
+	}
+
+	if (pdev->gmadr_va) {
+		iounmap(pdev->gmadr_va);
+		pdev->gmadr_va = NULL;
+	}
+}
+
+static int init_initial_mmio_state(struct pgt_device *pdev)
+{
+	struct gvt_device_info *info = &pdev->device_info;
+
+	u64 bar0, bar1;
+	int rc;
+
+	gvt_dbg_core("init initial mmio state, id %d", pdev->id);
+
+	bar0 = *(u64 *)&pdev->initial_cfg_space[GVT_REG_CFG_SPACE_BAR0];
+	bar1 = *(u64 *)&pdev->initial_cfg_space[GVT_REG_CFG_SPACE_BAR1];
+
+	pdev->gttmmio_base = bar0 & ~0xf;
+	pdev->reg_num = info->mmio_size / 4;
+	pdev->gmadr_base = bar1 & ~0xf;
+
+	pdev->gttmmio_va = ioremap(pdev->gttmmio_base, pdev->bar_size[0]);
+	if (!pdev->gttmmio_va) {
+		gvt_err("fail to map GTTMMIO BAR.");
+		return -EFAULT;
+	}
+
+	pdev->gmadr_va = ioremap(pdev->gmadr_base, pdev->bar_size[2]);
+	if (!pdev->gmadr_va) {
+		gvt_err("fail to map GMADR BAR.");
+		rc = -EFAULT;
+		goto err;
+	}
+
+	gvt_dbg_core("bar0: 0x%llx, bar1: 0x%llx", bar0, bar1);
+	gvt_dbg_core("mmio size: %x", pdev->mmio_size);
+	gvt_dbg_core("gttmmio: 0x%llx, gmadr: 0x%llx", pdev->gttmmio_base,
+			pdev->gmadr_base);
+	gvt_dbg_core("gttmmio_va: %p", pdev->gttmmio_va);
+	gvt_dbg_core("gmadr_va: %p", pdev->gmadr_va);
+
+	return 0;
+err:
+	clean_initial_mmio_state(pdev);
+	return rc;
+}
+
+static int gvt_service_thread(void *data)
+{
+	struct pgt_device *pdev = (struct pgt_device *)data;
+	int r;
+
+	gvt_dbg_core("service thread start, pgt %d", pdev->id);
+
+	while (!kthread_should_stop()) {
+		r = wait_event_interruptible(pdev->service_thread_wq,
+				kthread_should_stop() || pdev->service_request);
+
+		if (kthread_should_stop())
+			break;
+
+		if (gvt_warn_once(r,
+			"service thread is waken up by unexpected signal."))
+			continue;
+	}
+
+	return 0;
+}
+
+static void clean_service_thread(struct pgt_device *pdev)
+{
+	if (pdev->service_thread) {
+		kthread_stop(pdev->service_thread);
+		pdev->service_thread = NULL;
+	}
+}
+
+static int init_service_thread(struct pgt_device *pdev)
+{
+	init_waitqueue_head(&pdev->service_thread_wq);
+
+	pdev->service_thread = kthread_run(gvt_service_thread,
+			pdev, "gvt_service_thread%d", pdev->id);
+
+	if (!pdev->service_thread) {
+		gvt_err("fail to start service thread.");
+		return -ENOSPC;
+	}
+
+	return 0;
+}
+
+static void clean_pgt_device(struct pgt_device *pdev)
+{
+	clean_service_thread(pdev);
+	clean_initial_mmio_state(pdev);
+}
+
+static int init_pgt_device(struct pgt_device *pdev,
+	struct drm_i915_private *dev_priv)
+{
+	int rc;
+
+	rc = init_device_info(pdev);
+	if (rc)
+		return rc;
+
+	init_initial_cfg_space_state(pdev);
+
+	rc = init_initial_mmio_state(pdev);
+	if (rc)
+		goto err;
+
+	rc = init_service_thread(pdev);
+	if (rc)
+		goto err;
+
+	return 0;
+err:
+	clean_pgt_device(pdev);
+	return rc;
+}
+
+static int post_init_pgt_device(struct pgt_device *pdev)
+{
+	return 0;
+}
+
+static void free_pgt_device(struct pgt_device *pdev)
+{
+	struct gvt_host *host = &gvt_host;
+
+	mutex_lock(&host->device_idr_lock);
+	idr_remove(&host->device_idr, pdev->id);
+	mutex_unlock(&host->device_idr_lock);
+
+	vfree(pdev);
+}
+
+static struct pgt_device *alloc_pgt_device(struct drm_i915_private *dev_priv)
+{
+	struct gvt_host *host = &gvt_host;
+	struct pgt_device *pdev = NULL;
+
+	pdev = vzalloc(sizeof(*pdev));
+	if (!pdev)
+		return NULL;
+
+	mutex_lock(&host->device_idr_lock);
+	pdev->id = idr_alloc(&host->device_idr, pdev, 0, 0, GFP_KERNEL);
+	mutex_unlock(&host->device_idr_lock);
+
+	if (pdev->id < 0) {
+		gvt_err("fail to allocate pgt device id.");
+		goto err;
+	}
+
+	mutex_init(&pdev->lock);
+	pdev->dev_priv = dev_priv;
+	idr_init(&pdev->instance_idr);
+
+	return pdev;
+err:
+	free_pgt_device(pdev);
+	return NULL;
+}
+
+void gvt_destroy_pgt_device(void *private_data)
+{
+	struct pgt_device *pdev = (struct pgt_device *)private_data;
+
+	clean_pgt_device(pdev);
+	free_pgt_device(pdev);
+}
+
+/**
+ * gvt_create_pgt_device - create a GVT physical device
+ * @dev: drm device
+ *
+ * This function is called at the initialization stage, to create a physical
+ * GVT device and initialize necessary GVT components for it.
+ *
+ * Returns:
+ * pointer to the pgt_device structure, NULL if failed.
+ */
+void *gvt_create_pgt_device(struct drm_i915_private *dev_priv)
+{
+	struct pgt_device *pdev = NULL;
+	struct gvt_host *host = &gvt_host;
+	int rc;
+
+	if (!host->initialized && !gvt_init_host()) {
+		gvt_err("gvt_init_host fail");
+		return NULL;
+	}
+
+	gvt_dbg_core("create new pgt device, i915 dev_priv: %p", dev_priv);
+
+	pdev = alloc_pgt_device(dev_priv);
+	if (!pdev) {
+		gvt_err("fail to allocate memory for pgt device.");
+		goto err;
+	}
+
+	gvt_dbg_core("init pgt device, id %d", pdev->id);
+
+	rc = init_pgt_device(pdev, dev_priv);
+	if (rc) {
+		gvt_err("fail to init physical device state.");
+		goto err;
+	}
+
+	gvt_dbg_core("pgt device creation done, id %d", pdev->id);
+
+	return pdev;
+err:
+	if (pdev) {
+		gvt_destroy_pgt_device(pdev);
+		pdev = NULL;
+	}
+	return NULL;
+}
+
+/**
+ * gvt_post_init_pgt_device - post init a GVT physical device
+ * @dev: drm device
+ *
+ * This function is called at the end of the initialization stage, to
+ * post-initialize a physical GVT device and initialize necessary
+ * GVT components rely on i915 components.
+ *
+ * Returns:
+ * zero on success, non-zero if failed.
+ */
+int gvt_post_init_pgt_device(void *private_data)
+{
+	struct pgt_device *pdev = (struct pgt_device *)private_data;
+	struct gvt_host *host = &gvt_host;
+	int rc;
+
+	if (!host->initialized) {
+		gvt_err("gvt_host haven't been initialized.");
+		return -ENODEV;
+	}
+
+	gvt_dbg_core("post init pgt device %d", pdev->id);
+
+	rc = post_init_pgt_device(pdev);
+	if (rc) {
+		gvt_err("fail to post init physical device state.");
+		return rc;
+	}
+
+	return 0;
+}
diff --git a/drivers/gpu/drm/i915/gvt/gvt.h b/drivers/gpu/drm/i915/gvt/gvt.h
new file mode 100644
index 0000000..d450198
--- /dev/null
+++ b/drivers/gpu/drm/i915/gvt/gvt.h
@@ -0,0 +1,100 @@
+/*
+ * 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.
+ */
+
+#ifndef _GVT_H_
+#define _GVT_H_
+
+#include "i915_drv.h"
+#include "i915_vgpu.h"
+
+#include "debug.h"
+#include "params.h"
+#include "reg.h"
+#include "hypercall.h"
+#include "mpt.h"
+
+#define GVT_MAX_VGPU 8
+
+enum {
+	GVT_HYPERVISOR_TYPE_XEN = 0,
+	GVT_HYPERVISOR_TYPE_KVM,
+};
+
+struct gvt_host {
+	bool initialized;
+	int hypervisor_type;
+	struct mutex device_idr_lock;
+	struct idr device_idr;
+	struct gvt_kernel_dm *kdm;
+};
+
+extern struct gvt_host gvt_host;
+extern struct gvt_kernel_dm xengt_kdm;
+extern struct gvt_kernel_dm kvmgt_kdm;
+
+/* Describe the limitation of HW.*/
+struct gvt_device_info {
+	u64 max_gtt_gm_sz;
+	u32 gtt_start_offset;
+	u32 gtt_end_offset;
+	u32 max_gtt_size;
+	u32 gtt_entry_size;
+	u32 gtt_entry_size_shift;
+	u32 gmadr_bytes_in_cmd;
+	u32 mmio_size;
+};
+
+struct vgt_device {
+	int id;
+	int vm_id;
+	struct pgt_device *pdev;
+	bool warn_untrack;
+};
+
+struct pgt_device {
+	struct mutex lock;
+	int id;
+
+	struct drm_i915_private *dev_priv;
+	struct idr instance_idr;
+
+	struct gvt_device_info device_info;
+
+	u8 initial_cfg_space[GVT_CFG_SPACE_SZ];
+	u64 bar_size[GVT_BAR_NUM];
+
+	u64 gttmmio_base;
+	void *gttmmio_va;
+
+	u64 gmadr_base;
+	void *gmadr_va;
+
+	u32 mmio_size;
+	u32 reg_num;
+
+	wait_queue_head_t service_thread_wq;
+	struct task_struct *service_thread;
+	unsigned long service_request;
+};
+
+#endif
diff --git a/drivers/gpu/drm/i915/gvt/hypercall.h b/drivers/gpu/drm/i915/gvt/hypercall.h
new file mode 100644
index 0000000..0a41874
--- /dev/null
+++ b/drivers/gpu/drm/i915/gvt/hypercall.h
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ */
+
+#ifndef _GVT_HYPERCALL_H_
+#define _GVT_HYPERCALL_H_
+
+struct gvt_kernel_dm {
+};
+
+#endif /* _GVT_HYPERCALL_H_ */
diff --git a/drivers/gpu/drm/i915/gvt/mpt.h b/drivers/gpu/drm/i915/gvt/mpt.h
new file mode 100644
index 0000000..e594bb8
--- /dev/null
+++ b/drivers/gpu/drm/i915/gvt/mpt.h
@@ -0,0 +1,34 @@
+/*
+ * 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.
+ */
+
+#ifndef _GVT_MPT_H_
+#define _GVT_MPT_H_
+
+struct vgt_device;
+
+static inline bool hypervisor_detect_host(void)
+{
+	return false;
+}
+
+#endif /* _GVT_MPT_H_ */
diff --git a/drivers/gpu/drm/i915/gvt/params.c b/drivers/gpu/drm/i915/gvt/params.c
new file mode 100644
index 0000000..d381d17
--- /dev/null
+++ b/drivers/gpu/drm/i915/gvt/params.c
@@ -0,0 +1,32 @@
+/*
+ * 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.
+ */
+
+#include "gvt.h"
+
+struct gvt_kernel_params gvt = {
+	.enable = false,
+	.debug = 0,
+};
+
+module_param_named(gvt_enable, gvt.enable, bool, 0600);
+MODULE_PARM_DESC(gvt_enable, "Enable Intel GVT-g host support");
diff --git a/drivers/gpu/drm/i915/gvt/params.h b/drivers/gpu/drm/i915/gvt/params.h
new file mode 100644
index 0000000..d2955b9
--- /dev/null
+++ b/drivers/gpu/drm/i915/gvt/params.h
@@ -0,0 +1,34 @@
+/*
+ * 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.
+ */
+
+#ifndef _GVT_PARAMS_H_
+#define _GVT_PARAMS_H_
+
+struct gvt_kernel_params {
+	bool enable;
+	int debug;
+};
+
+extern struct gvt_kernel_params gvt;
+
+#endif
diff --git a/drivers/gpu/drm/i915/gvt/reg.h b/drivers/gpu/drm/i915/gvt/reg.h
new file mode 100644
index 0000000..d363b74
--- /dev/null
+++ b/drivers/gpu/drm/i915/gvt/reg.h
@@ -0,0 +1,34 @@
+/*
+ * 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.
+ */
+
+#ifndef _GVT_REG_H
+#define _GVT_REG_H
+
+#define GVT_CFG_SPACE_SZ	256
+#define GVT_BAR_NUM		4
+
+#define GVT_REG_CFG_SPACE_BAR0	0x10
+#define GVT_REG_CFG_SPACE_BAR1	0x18
+#define GVT_REG_CFG_SPACE_BAR2	0x20
+
+#endif
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index 1c6d227..f3bed37 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -35,6 +35,7 @@
 #include "intel_drv.h"
 #include <drm/i915_drm.h>
 #include "i915_drv.h"
+#include "i915_gvt.h"
 #include "i915_vgpu.h"
 #include "i915_trace.h"
 #include <linux/pci.h>
@@ -1045,6 +1046,10 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
 
 	intel_uncore_init(dev);
 
+	ret = intel_gvt_init(dev);
+	if (ret)
+		goto out_uncore_fini;
+
 	ret = i915_gem_gtt_init(dev);
 	if (ret)
 		goto out_uncore_fini;
@@ -1135,6 +1140,12 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
 		goto out_power_well;
 	}
 
+	ret = intel_gvt_post_init(dev);
+	if (ret) {
+		DRM_ERROR("failed to post init pgt device\n");
+		goto out_power_well;
+	}
+
 	/*
 	 * Notify a valid surface after modesetting,
 	 * when running inside a VM.
@@ -1177,6 +1188,7 @@ out_gem_unload:
 out_gtt:
 	i915_global_gtt_cleanup(dev);
 out_uncore_fini:
+	intel_gvt_cleanup(dev);
 	intel_uncore_fini(dev);
 	i915_mmio_cleanup(dev);
 put_bridge:
@@ -1223,6 +1235,8 @@ int i915_driver_unload(struct drm_device *dev)
 
 	intel_modeset_cleanup(dev);
 
+	intel_gvt_cleanup(dev);
+
 	/*
 	 * free the memory space allocated for the child device
 	 * config parsed from VBT
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 20d9dbd..2f897c3 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1705,6 +1705,10 @@ struct i915_workarounds {
 	u32 hw_whitelist_count[I915_NUM_RINGS];
 };
 
+struct i915_gvt {
+	void *pgt_device;
+};
+
 struct i915_virtual_gpu {
 	bool active;
 };
@@ -1744,6 +1748,8 @@ struct drm_i915_private {
 
 	struct i915_virtual_gpu vgpu;
 
+	struct i915_gvt gvt;
+
 	struct intel_guc guc;
 
 	struct intel_csr csr;
@@ -2780,6 +2786,12 @@ void intel_uncore_forcewake_get__locked(struct drm_i915_private *dev_priv,
 void intel_uncore_forcewake_put__locked(struct drm_i915_private *dev_priv,
 					enum forcewake_domains domains);
 void assert_forcewakes_inactive(struct drm_i915_private *dev_priv);
+
+static inline bool intel_gvt_active(struct drm_device *dev)
+{
+	return to_i915(dev)->gvt.pgt_device ? true : false;
+}
+
 static inline bool intel_vgpu_active(struct drm_device *dev)
 {
 	return to_i915(dev)->vgpu.active;
diff --git a/drivers/gpu/drm/i915/i915_gvt.c b/drivers/gpu/drm/i915/i915_gvt.c
new file mode 100644
index 0000000..3ca7232
--- /dev/null
+++ b/drivers/gpu/drm/i915/i915_gvt.c
@@ -0,0 +1,93 @@
+/*
+ * 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.
+ */
+
+#include "i915_drv.h"
+#include "i915_gvt.h"
+
+/**
+ * DOC: Intel GVT-g host support
+ *
+ * Intel GVT-g is a graphics virtualization technology which shares the
+ * GPU among multiple virtual machines on a time-sharing basis. Each
+ * virtual machine is presented a virtual GPU (vGPU), which has equivalent
+ * features as the underlying physical GPU (pGPU), so i915 driver can run
+ * seamlessly in a virtual machine. This file provides the englightments
+ * of GVT and the necessary components used by GVT in i915 driver.
+ */
+
+/**
+ * intel_gvt_init - initialize GVT components at the beginning of i915
+ * driver loading.
+ * @dev: drm device *
+ *
+ * This function is called at the beginning of the initialization stage,
+ * to initialize the GVT components that have to be initialized
+ * before HW gets touched by other i915 components.
+ */
+int intel_gvt_init(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = to_i915(dev);
+
+	dev_priv->gvt.pgt_device = gvt_create_pgt_device(dev_priv);
+	if (intel_gvt_active(dev))
+		DRM_DEBUG_DRIVER("GVT-g is running in host mode\n");
+
+	return 0;
+}
+
+/**
+ * intel_gvt_post_init - initialize GVT components at the end of i915
+ * driver loading.
+ * @dev: drm device *
+ *
+ * This function is called at the end of the initialization stage,
+ * to initialize the GVT components that have to be initialized after
+ * other i915 components are ready.
+ */
+int intel_gvt_post_init(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = to_i915(dev);
+
+	if (!intel_gvt_active(dev))
+		return 0;
+
+	return gvt_post_init_pgt_device(dev_priv->gvt.pgt_device);
+}
+
+/**
+ * intel_gvt_cleanup - cleanup GVT components when i915 driver is unloading
+ * @dev: drm device *
+ *
+ * This function is called at the i915 driver unloading stage, to shutdown
+ * GVT components and release the related resources.
+ */
+void intel_gvt_cleanup(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = to_i915(dev);
+
+	if (!intel_gvt_active(dev))
+		return;
+
+	gvt_destroy_pgt_device(dev_priv->gvt.pgt_device);
+	dev_priv->gvt.pgt_device = NULL;
+}
diff --git a/drivers/gpu/drm/i915/i915_gvt.h b/drivers/gpu/drm/i915/i915_gvt.h
new file mode 100644
index 0000000..30cc207
--- /dev/null
+++ b/drivers/gpu/drm/i915/i915_gvt.h
@@ -0,0 +1,49 @@
+/*
+ * 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.
+ */
+
+#ifndef _I915_GVT_H_
+#define _I915_GVT_H_
+
+#ifdef CONFIG_DRM_I915_GVT
+extern void *gvt_create_pgt_device(struct drm_i915_private *dev_priv);
+extern int gvt_post_init_pgt_device(void *data);
+extern void gvt_destroy_pgt_device(void *data);
+
+extern int intel_gvt_init(struct drm_device *dev);
+extern int intel_gvt_post_init(struct drm_device *dev);
+extern void intel_gvt_cleanup(struct drm_device *dev);
+#else
+extern int intel_gvt_init(struct drm_device *dev)
+{
+	return 0;
+}
+extern int intel_gvt_post_init(struct drm_device *dev)
+{
+	return 0;
+}
+extern void intel_gvt_cleanup(struct drm_device *dev)
+{
+}
+#endif
+
+#endif /* _I915_GVT_H_ */
-- 
1.9.1

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

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [RFCv2 03/14] drm/i915: Introduce host graphics memory/fence partition for GVT-g
  2016-02-18 11:42 [RFCv2 PATCH 00/14] gvt: Hacking i915 for GVT context requirement Zhi Wang
  2016-02-18 11:42 ` [RFCv2 01/14] drm/i915: factor out i915_pvinfo.h Zhi Wang
  2016-02-18 11:42 ` [RFCv2 02/14] drm/i915/gvt: Introduce the basic architecture of GVT-g Zhi Wang
@ 2016-02-18 11:42 ` Zhi Wang
  2016-02-23 13:16   ` Joonas Lahtinen
  2016-02-24  8:22   ` Tian, Kevin
  2016-02-18 11:42 ` [RFCv2 04/14] drm/i915: factor out alloc_context_idr() and __i915_gem_create_context() Zhi Wang
                   ` (12 subsequent siblings)
  15 siblings, 2 replies; 46+ messages in thread
From: Zhi Wang @ 2016-02-18 11:42 UTC (permalink / raw)
  To: intel-gfx, igvt-g; +Cc: daniel.vetter, david.j.cowperthwaite, zhiyuan.lv

From: Bing Niu <bing.niu@intel.com>

This patch introduces host graphics memory/fence partition when GVT-g
is enabled.

Under GVT-g, i915 host driver only owned limited graphics resources,
others are managed by GVT-g resource allocator and kept for other vGPUs.

v2:
- Address all coding-style comments from Joonas previously.
- Fix errors and warnning reported by checkpatch.pl. (Joonas)
- Move the graphs into the header files. (Daniel)

Signed-off-by: Bing Niu <bing.niu@intel.com>
Signed-off-by: Zhi Wang <zhi.a.wang@intel.com>
---
 drivers/gpu/drm/i915/gvt/gvt.c      |  4 ++++
 drivers/gpu/drm/i915/gvt/params.c   | 12 ++++++++++++
 drivers/gpu/drm/i915/gvt/params.h   |  3 +++
 drivers/gpu/drm/i915/i915_drv.h     | 35 +++++++++++++++++++++++++++++++++++
 drivers/gpu/drm/i915/i915_gem.c     |  4 +++-
 drivers/gpu/drm/i915/i915_gem_gtt.c |  4 ++--
 drivers/gpu/drm/i915/i915_vgpu.c    | 21 +++++++++++++++++----
 7 files changed, 76 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/i915/gvt/gvt.c b/drivers/gpu/drm/i915/gvt/gvt.c
index 52cfa32..2099b7e 100644
--- a/drivers/gpu/drm/i915/gvt/gvt.c
+++ b/drivers/gpu/drm/i915/gvt/gvt.c
@@ -348,6 +348,10 @@ void *gvt_create_pgt_device(struct drm_i915_private *dev_priv)
 		goto err;
 	}
 
+	dev_priv->gvt.host_fence_sz = gvt.host_fence_sz;
+	dev_priv->gvt.host_low_gm_sz_in_mb = gvt.host_low_gm_sz;
+	dev_priv->gvt.host_high_gm_sz_in_mb = gvt.host_high_gm_sz;
+
 	gvt_dbg_core("pgt device creation done, id %d", pdev->id);
 
 	return pdev;
diff --git a/drivers/gpu/drm/i915/gvt/params.c b/drivers/gpu/drm/i915/gvt/params.c
index d381d17..75195fd 100644
--- a/drivers/gpu/drm/i915/gvt/params.c
+++ b/drivers/gpu/drm/i915/gvt/params.c
@@ -26,7 +26,19 @@
 struct gvt_kernel_params gvt = {
 	.enable = false,
 	.debug = 0,
+	.host_low_gm_sz = 96,	/* in MB */
+	.host_high_gm_sz = 384, /* in MB */
+	.host_fence_sz = 4,
 };
 
 module_param_named(gvt_enable, gvt.enable, bool, 0600);
 MODULE_PARM_DESC(gvt_enable, "Enable Intel GVT-g host support");
+
+module_param_named(gvt_host_low_gm_sz, gvt.host_low_gm_sz, int, 0600);
+MODULE_PARM_DESC(gvt_host_low_gm_sz, "Amount of aperture size of host (in MB)");
+
+module_param_named(gvt_host_high_gm_sz, gvt.host_high_gm_sz, int, 0600);
+MODULE_PARM_DESC(gvt_host_high_gm_sz, "Amount of high memory size of host (in MB)");
+
+module_param_named(gvt_host_fence_sz, gvt.host_fence_sz, int, 0600);
+MODULE_PARM_DESC(gvt_host_fence_sz, "Amount of fence size of host (in MB)");
diff --git a/drivers/gpu/drm/i915/gvt/params.h b/drivers/gpu/drm/i915/gvt/params.h
index d2955b9..f4e9356 100644
--- a/drivers/gpu/drm/i915/gvt/params.h
+++ b/drivers/gpu/drm/i915/gvt/params.h
@@ -27,6 +27,9 @@
 struct gvt_kernel_params {
 	bool enable;
 	int debug;
+	int host_low_gm_sz;
+	int host_high_gm_sz;
+	int host_fence_sz;
 };
 
 extern struct gvt_kernel_params gvt;
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 2f897c3..1fd5575 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1705,8 +1705,43 @@ struct i915_workarounds {
 	u32 hw_whitelist_count[I915_NUM_RINGS];
 };
 
+/*
+ * Under GVT-g, i915 host driver only owned limited graphics resources,
+ * others are managed by GVT-g resource allocator and kept for other vGPUs.
+ *
+ * For graphics memory space partition, a typical layout looks like:
+ *
+ * +-------+-----------------------+------+-----------------------+
+ * |* Host |   *GVT-g Resource     |* Host|   *GVT-g Resource     |
+ * | Owned |   Allocator Managed   | Owned|   Allocator Managed   |
+ * |       |                       |      |                       |
+ * +---------------+-------+----------------------+-------+-------+
+ * |       |       |       |       |      |       |       |       |
+ * | i915  | vm 1  | vm 2  | vm 3  | i915 | vm 1  | vm 2  | vm 3  |
+ * |       |       |       |       |      |       |       |       |
+ * +-------+-------+-------+--------------+-------+-------+-------+
+ * |           Aperture            |            Hidden            |
+ * +-------------------------------+------------------------------+
+ * |                       GGTT memory space                      |
+ * +--------------------------------------------------------------+
+ *
+ * Similar with fence registers partition:
+ *
+ * +------ +-----------------------+
+ * | * Host|    GVT-g Resource     |
+ * | Owned |   Allocator Managed   +
+ * 0       |                       31
+ * +---------------+-------+-------+
+ * |       |       |       |       |
+ * | i915  | vm 1  | vm 2  | vm 3  |
+ * |       |       |       |       |
+ * +-------+-------+-------+-------+
+ */
 struct i915_gvt {
 	void *pgt_device;
+	u32 host_low_gm_sz_in_mb;
+	u32 host_high_gm_sz_in_mb;
+	int host_fence_sz;
 };
 
 struct i915_virtual_gpu {
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index f68f346..1c0006a 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -5078,7 +5078,9 @@ i915_gem_load_init(struct drm_device *dev)
 	else
 		dev_priv->num_fence_regs = 8;
 
-	if (intel_vgpu_active(dev))
+	if (intel_gvt_active(dev))
+		dev_priv->num_fence_regs = dev_priv->gvt.host_fence_sz;
+	else if (intel_vgpu_active(dev))
 		dev_priv->num_fence_regs =
 				I915_READ(vgtif_reg(avail_rs.fence_num));
 
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 9127f8f..de09dd4 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -2734,7 +2734,7 @@ static int i915_gem_setup_global_gtt(struct drm_device *dev,
 	i915_address_space_init(ggtt_vm, dev_priv);
 	ggtt_vm->total += PAGE_SIZE;
 
-	if (intel_vgpu_active(dev)) {
+	if (intel_vgpu_active(dev) || intel_gvt_active(dev)) {
 		ret = intel_vgt_balloon(dev);
 		if (ret)
 			return ret;
@@ -2833,7 +2833,7 @@ void i915_global_gtt_cleanup(struct drm_device *dev)
 	i915_gem_cleanup_stolen(dev);
 
 	if (drm_mm_initialized(&vm->mm)) {
-		if (intel_vgpu_active(dev))
+		if (intel_vgpu_active(dev) || intel_gvt_active(dev))
 			intel_vgt_deballoon();
 
 		drm_mm_takedown(&vm->mm);
diff --git a/drivers/gpu/drm/i915/i915_vgpu.c b/drivers/gpu/drm/i915/i915_vgpu.c
index dea7429..7be1435 100644
--- a/drivers/gpu/drm/i915/i915_vgpu.c
+++ b/drivers/gpu/drm/i915/i915_vgpu.c
@@ -188,10 +188,23 @@ int intel_vgt_balloon(struct drm_device *dev)
 	unsigned long unmappable_base, unmappable_size, unmappable_end;
 	int ret;
 
-	mappable_base = I915_READ(vgtif_reg(avail_rs.mappable_gmadr.base));
-	mappable_size = I915_READ(vgtif_reg(avail_rs.mappable_gmadr.size));
-	unmappable_base = I915_READ(vgtif_reg(avail_rs.nonmappable_gmadr.base));
-	unmappable_size = I915_READ(vgtif_reg(avail_rs.nonmappable_gmadr.size));
+	if (intel_gvt_active(dev)) {
+		mappable_base = 0;
+		mappable_size = dev_priv->gvt.host_low_gm_sz_in_mb << 20;
+		unmappable_base = dev_priv->gtt.mappable_end;
+		unmappable_size = dev_priv->gvt.host_high_gm_sz_in_mb << 20;
+	} else if (intel_vgpu_active(dev)) {
+		mappable_base = I915_READ(
+			vgtif_reg(avail_rs.mappable_gmadr.base));
+		mappable_size = I915_READ(
+			vgtif_reg(avail_rs.mappable_gmadr.size));
+		unmappable_base = I915_READ(
+			vgtif_reg(avail_rs.nonmappable_gmadr.base));
+		unmappable_size = I915_READ(
+			vgtif_reg(avail_rs.nonmappable_gmadr.size));
+	} else {
+		return -ENODEV;
+	}
 
 	mappable_end = mappable_base + mappable_size;
 	unmappable_end = unmappable_base + unmappable_size;
-- 
1.9.1

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

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [RFCv2 04/14] drm/i915: factor out alloc_context_idr() and __i915_gem_create_context()
  2016-02-18 11:42 [RFCv2 PATCH 00/14] gvt: Hacking i915 for GVT context requirement Zhi Wang
                   ` (2 preceding siblings ...)
  2016-02-18 11:42 ` [RFCv2 03/14] drm/i915: Introduce host graphics memory/fence partition for GVT-g Zhi Wang
@ 2016-02-18 11:42 ` Zhi Wang
  2016-02-24  8:27   ` Tian, Kevin
  2016-02-18 11:42 ` [RFCv2 05/14] drm/i915: factor out __create_legacy_hw_context() Zhi Wang
                   ` (11 subsequent siblings)
  15 siblings, 1 reply; 46+ messages in thread
From: Zhi Wang @ 2016-02-18 11:42 UTC (permalink / raw)
  To: intel-gfx, igvt-g; +Cc: daniel.vetter, david.j.cowperthwaite, zhiyuan.lv

For flexible GEM context creation, we factor out __i915_gem_create_context
as the core logic of creation a GEM context. After the refactor, it more
likesa context creation servcie, which is able to create context by
explicit requirement of upper level components, not by the assumptions of
incoming parameters.

For the assumptions in original implementation, we keep them in the upper
level wrapper: i915_gem_create_context().

alloc_context_idr() is another function factored out to setup a IDR for
ordinary GEM context. Some context, e.g. GVT context, maybe more than one
kernel context in furture (currently there is only one kernel context: the
default context) doesn't need a IDR. So we make it an option in context
creation.

Signed-off-by: Zhi Wang <zhi.a.wang@intel.com>
---
 drivers/gpu/drm/i915/i915_gem_context.c | 62 ++++++++++++++++++++++++---------
 1 file changed, 45 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c
index 4be2ce9..38e9fe1 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/i915_gem_context.c
@@ -235,17 +235,7 @@ __create_hw_context(struct drm_device *dev,
 		ctx->legacy_hw_ctx.rcs_state = obj;
 	}
 
-	/* Default context will never have a file_priv */
-	if (file_priv != NULL) {
-		ret = idr_alloc(&file_priv->context_idr, ctx,
-				DEFAULT_CONTEXT_HANDLE, 0, GFP_KERNEL);
-		if (ret < 0)
-			goto err_out;
-	} else
-		ret = DEFAULT_CONTEXT_HANDLE;
-
 	ctx->file_priv = file_priv;
-	ctx->user_handle = ret;
 	/* NB: Mark all slices as needing a remap so that when the context first
 	 * loads it will restore whatever remap state already exists. If there
 	 * is no remap info, it will be a NOP. */
@@ -260,13 +250,8 @@ err_out:
 	return ERR_PTR(ret);
 }
 
-/**
- * The default context needs to exist per ring that uses contexts. It stores the
- * context state of the GPU for applications that don't utilize HW contexts, as
- * well as an idle case.
- */
 static struct intel_context *
-i915_gem_create_context(struct drm_device *dev,
+__i915_gem_create_context(struct drm_device *dev,
 			struct drm_i915_file_private *file_priv)
 {
 	const bool is_global_default_ctx = file_priv == NULL;
@@ -316,11 +301,54 @@ err_unpin:
 	if (is_global_default_ctx && ctx->legacy_hw_ctx.rcs_state)
 		i915_gem_object_ggtt_unpin(ctx->legacy_hw_ctx.rcs_state);
 err_destroy:
-	idr_remove(&file_priv->context_idr, ctx->user_handle);
 	i915_gem_context_unreference(ctx);
 	return ERR_PTR(ret);
 }
 
+static inline int alloc_context_idr(struct drm_device *dev,
+	struct intel_context *ctx)
+{
+	int ret;
+
+	/* Default context will never have a file_priv */
+	if (ctx->file_priv != NULL) {
+		ret = idr_alloc(&ctx->file_priv->context_idr, ctx,
+				DEFAULT_CONTEXT_HANDLE, 0, GFP_KERNEL);
+		if (ret < 0)
+			return ret;
+	} else {
+		ret = DEFAULT_CONTEXT_HANDLE;
+	}
+
+	ctx->user_handle = ret;
+	return 0;
+}
+
+/**
+ * The default context needs to exist per ring that uses contexts. It stores the
+ * context state of the GPU for applications that don't utilize HW contexts, as
+ * well as an idle case.
+ */
+static struct intel_context *
+i915_gem_create_context(struct drm_device *dev,
+		struct drm_i915_file_private *file_priv)
+{
+	struct intel_context *ctx;
+	int ret;
+
+	ctx = __i915_gem_create_context(dev, file_priv);
+	if (IS_ERR(ctx))
+		return ctx;
+
+	ret = alloc_context_idr(dev, ctx);
+	if (ret < 0) {
+		i915_gem_context_unreference(ctx);
+		return ERR_PTR(ret);
+	}
+
+	return ctx;
+}
+
 static void i915_gem_context_unpin(struct intel_context *ctx,
 				   struct intel_engine_cs *engine)
 {
-- 
1.9.1

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

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [RFCv2 05/14] drm/i915: factor out __create_legacy_hw_context()
  2016-02-18 11:42 [RFCv2 PATCH 00/14] gvt: Hacking i915 for GVT context requirement Zhi Wang
                   ` (3 preceding siblings ...)
  2016-02-18 11:42 ` [RFCv2 04/14] drm/i915: factor out alloc_context_idr() and __i915_gem_create_context() Zhi Wang
@ 2016-02-18 11:42 ` Zhi Wang
  2016-02-18 11:42 ` [RFCv2 06/14] drm/i915: let __i915_gem_context_create() takes context creation params Zhi Wang
                   ` (10 subsequent siblings)
  15 siblings, 0 replies; 46+ messages in thread
From: Zhi Wang @ 2016-02-18 11:42 UTC (permalink / raw)
  To: intel-gfx, igvt-g; +Cc: daniel.vetter, david.j.cowperthwaite, zhiyuan.lv

As creating the legacy HW context has become into an option in GEM context
creating service (__i915_gem_create_context()), we factor out __create_
legacy_hw_context() from the __create_hw_context().

After the re-factor, the __create_hw_context() is only responsible for
allocating and initializing the basic members of intel_context data
structure, like list head... in addition to these very basic members, the
legacy context alloction is moved into __create_legacy_hw_context(), which
becomes a function block of the GEM context creating service.

Signed-off-by: Zhi Wang <zhi.a.wang@intel.com>
---
 drivers/gpu/drm/i915/i915_gem_context.c | 43 ++++++++++++++++++---------------
 1 file changed, 24 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c
index 38e9fe1..5516346 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/i915_gem_context.c
@@ -209,13 +209,26 @@ i915_gem_alloc_context_obj(struct drm_device *dev, size_t size)
 	return obj;
 }
 
+static int __create_legacy_hw_context(struct drm_device *dev,
+		struct intel_context *ctx)
+{
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	struct drm_i915_gem_object *obj =
+		i915_gem_alloc_context_obj(dev, dev_priv->hw_context_size);
+
+	if (IS_ERR(obj))
+		return PTR_ERR(obj);
+
+	ctx->legacy_hw_ctx.rcs_state = obj;
+	return 0;
+}
+
 static struct intel_context *
 __create_hw_context(struct drm_device *dev,
 		    struct drm_i915_file_private *file_priv)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_context *ctx;
-	int ret;
 
 	ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
 	if (ctx == NULL)
@@ -224,37 +237,23 @@ __create_hw_context(struct drm_device *dev,
 	kref_init(&ctx->ref);
 	list_add_tail(&ctx->link, &dev_priv->context_list);
 	ctx->i915 = dev_priv;
-
-	if (dev_priv->hw_context_size) {
-		struct drm_i915_gem_object *obj =
-				i915_gem_alloc_context_obj(dev, dev_priv->hw_context_size);
-		if (IS_ERR(obj)) {
-			ret = PTR_ERR(obj);
-			goto err_out;
-		}
-		ctx->legacy_hw_ctx.rcs_state = obj;
-	}
-
 	ctx->file_priv = file_priv;
 	/* NB: Mark all slices as needing a remap so that when the context first
 	 * loads it will restore whatever remap state already exists. If there
 	 * is no remap info, it will be a NOP. */
 	ctx->remap_slice = (1 << NUM_L3_SLICES(dev)) - 1;
-
 	ctx->hang_stats.ban_period_seconds = DRM_I915_CTX_BAN_PERIOD;
 
 	return ctx;
-
-err_out:
-	i915_gem_context_unreference(ctx);
-	return ERR_PTR(ret);
 }
 
 static struct intel_context *
 __i915_gem_create_context(struct drm_device *dev,
 			struct drm_i915_file_private *file_priv)
 {
+	struct drm_i915_private *dev_priv = to_i915(dev);
 	const bool is_global_default_ctx = file_priv == NULL;
+	const bool is_legacy_ctx = !!dev_priv->hw_context_size;
 	struct intel_context *ctx;
 	int ret = 0;
 
@@ -264,7 +263,13 @@ __i915_gem_create_context(struct drm_device *dev,
 	if (IS_ERR(ctx))
 		return ctx;
 
-	if (is_global_default_ctx && ctx->legacy_hw_ctx.rcs_state) {
+	if (is_legacy_ctx) {
+		ret = __create_legacy_hw_context(dev, ctx);
+		if (ret)
+			goto err_destroy;
+	}
+
+	if (is_global_default_ctx && is_legacy_ctx) {
 		/* We may need to do things with the shrinker which
 		 * require us to immediately switch back to the default
 		 * context. This can cause a problem as pinning the
@@ -298,7 +303,7 @@ __i915_gem_create_context(struct drm_device *dev,
 	return ctx;
 
 err_unpin:
-	if (is_global_default_ctx && ctx->legacy_hw_ctx.rcs_state)
+	if (is_global_default_ctx && is_legacy_ctx)
 		i915_gem_object_ggtt_unpin(ctx->legacy_hw_ctx.rcs_state);
 err_destroy:
 	i915_gem_context_unreference(ctx);
-- 
1.9.1

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

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [RFCv2 06/14] drm/i915: let __i915_gem_context_create() takes context creation params
  2016-02-18 11:42 [RFCv2 PATCH 00/14] gvt: Hacking i915 for GVT context requirement Zhi Wang
                   ` (4 preceding siblings ...)
  2016-02-18 11:42 ` [RFCv2 05/14] drm/i915: factor out __create_legacy_hw_context() Zhi Wang
@ 2016-02-18 11:42 ` Zhi Wang
  2016-02-24  8:35   ` Tian, Kevin
  2016-02-18 11:42 ` [RFCv2 07/14] drm/i915: factor out __intel_lr_context_deferred_alloc() Zhi Wang
                   ` (9 subsequent siblings)
  15 siblings, 1 reply; 46+ messages in thread
From: Zhi Wang @ 2016-02-18 11:42 UTC (permalink / raw)
  To: intel-gfx, igvt-g; +Cc: daniel.vetter, david.j.cowperthwaite, zhiyuan.lv

Let the core logic of context creation service creats the GEM context by
context creation params.

Now it provides following options for context creation:
- Need to create legacy context for this GEM context?
- Need to create PPGTT instance for this GEM context?
- Need to treat this context as the global default context?

And for all the assumptions in the original implementation, we keep them
in the upper-level wrapper.

Signed-off-by: Zhi Wang <zhi.a.wang@intel.com>
---
 drivers/gpu/drm/i915/i915_gem_context.c | 71 ++++++++++++++++++++-------------
 1 file changed, 43 insertions(+), 28 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c
index 5516346..cda09f7 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/i915_gem_context.c
@@ -223,6 +223,13 @@ static int __create_legacy_hw_context(struct drm_device *dev,
 	return 0;
 }
 
+struct i915_gem_context_create_params {
+	struct drm_i915_file_private *file_priv;
+	bool has_legacy_ctx;
+	bool has_ppgtt;
+	bool is_default_ctx;
+};
+
 static struct intel_context *
 __create_hw_context(struct drm_device *dev,
 		    struct drm_i915_file_private *file_priv)
@@ -249,44 +256,43 @@ __create_hw_context(struct drm_device *dev,
 
 static struct intel_context *
 __i915_gem_create_context(struct drm_device *dev,
-			struct drm_i915_file_private *file_priv)
+			struct i915_gem_context_create_params *params)
 {
-	struct drm_i915_private *dev_priv = to_i915(dev);
-	const bool is_global_default_ctx = file_priv == NULL;
-	const bool is_legacy_ctx = !!dev_priv->hw_context_size;
 	struct intel_context *ctx;
 	int ret = 0;
 
 	BUG_ON(!mutex_is_locked(&dev->struct_mutex));
 
-	ctx = __create_hw_context(dev, file_priv);
+	ctx = __create_hw_context(dev, params->file_priv);
 	if (IS_ERR(ctx))
 		return ctx;
 
-	if (is_legacy_ctx) {
+	if (params->has_legacy_ctx) {
 		ret = __create_legacy_hw_context(dev, ctx);
 		if (ret)
 			goto err_destroy;
-	}
 
-	if (is_global_default_ctx && is_legacy_ctx) {
-		/* We may need to do things with the shrinker which
-		 * require us to immediately switch back to the default
-		 * context. This can cause a problem as pinning the
-		 * default context also requires GTT space which may not
-		 * be available. To avoid this we always pin the default
-		 * context.
-		 */
-		ret = i915_gem_obj_ggtt_pin(ctx->legacy_hw_ctx.rcs_state,
-					    get_context_alignment(dev), 0);
-		if (ret) {
-			DRM_DEBUG_DRIVER("Couldn't pin %d\n", ret);
-			goto err_destroy;
+		if (params->is_default_ctx) {
+			/* We may need to do things with the shrinker
+			 * which require us to immediately switch back to
+			 * the default context. This can cause a problem as
+			 * pinning the default context also requires GTT
+			 * space which may not be available. To avoid this
+			 * we always pin the default context.
+			 */
+			ret = i915_gem_obj_ggtt_pin(
+					ctx->legacy_hw_ctx.rcs_state,
+					get_context_alignment(dev), 0);
+			if (ret) {
+				DRM_DEBUG_DRIVER("Couldn't pin %d\n", ret);
+				goto err_destroy;
+			}
 		}
 	}
 
-	if (USES_FULL_PPGTT(dev)) {
-		struct i915_hw_ppgtt *ppgtt = i915_ppgtt_create(dev, file_priv);
+	if (params->has_ppgtt) {
+		struct i915_hw_ppgtt *ppgtt = i915_ppgtt_create(dev,
+			params->file_priv);
 
 		if (IS_ERR_OR_NULL(ppgtt)) {
 			DRM_DEBUG_DRIVER("PPGTT setup failed (%ld)\n",
@@ -303,7 +309,7 @@ __i915_gem_create_context(struct drm_device *dev,
 	return ctx;
 
 err_unpin:
-	if (is_global_default_ctx && is_legacy_ctx)
+	if (params->is_default_ctx && params->has_legacy_ctx)
 		i915_gem_object_ggtt_unpin(ctx->legacy_hw_ctx.rcs_state);
 err_destroy:
 	i915_gem_context_unreference(ctx);
@@ -311,12 +317,12 @@ err_destroy:
 }
 
 static inline int alloc_context_idr(struct drm_device *dev,
-	struct intel_context *ctx)
+	struct intel_context *ctx,
+	struct i915_gem_context_create_params *params)
 {
 	int ret;
 
-	/* Default context will never have a file_priv */
-	if (ctx->file_priv != NULL) {
+	if (params->is_default_ctx) {
 		ret = idr_alloc(&ctx->file_priv->context_idr, ctx,
 				DEFAULT_CONTEXT_HANDLE, 0, GFP_KERNEL);
 		if (ret < 0)
@@ -338,14 +344,23 @@ static struct intel_context *
 i915_gem_create_context(struct drm_device *dev,
 		struct drm_i915_file_private *file_priv)
 {
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	struct i915_gem_context_create_params params;
 	struct intel_context *ctx;
 	int ret;
 
-	ctx = __i915_gem_create_context(dev, file_priv);
+	memset(&params, 0, sizeof(params));
+
+	params.file_priv = file_priv;
+	params.has_legacy_ctx = !!dev_priv->hw_context_size;
+	params.has_ppgtt = USES_FULL_PPGTT(dev);
+	params.is_default_ctx = (file_priv == NULL);
+
+	ctx = __i915_gem_create_context(dev, &params);
 	if (IS_ERR(ctx))
 		return ctx;
 
-	ret = alloc_context_idr(dev, ctx);
+	ret = alloc_context_idr(dev, ctx, &params);
 	if (ret < 0) {
 		i915_gem_context_unreference(ctx);
 		return ERR_PTR(ret);
-- 
1.9.1

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

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [RFCv2 07/14] drm/i915: factor out __intel_lr_context_deferred_alloc()
  2016-02-18 11:42 [RFCv2 PATCH 00/14] gvt: Hacking i915 for GVT context requirement Zhi Wang
                   ` (5 preceding siblings ...)
  2016-02-18 11:42 ` [RFCv2 06/14] drm/i915: let __i915_gem_context_create() takes context creation params Zhi Wang
@ 2016-02-18 11:42 ` Zhi Wang
  2016-02-24  8:37   ` Tian, Kevin
  2016-02-18 11:42 ` [RFCv2 08/14] drm/i915: Support per-PPGTT address space mode Zhi Wang
                   ` (8 subsequent siblings)
  15 siblings, 1 reply; 46+ messages in thread
From: Zhi Wang @ 2016-02-18 11:42 UTC (permalink / raw)
  To: intel-gfx, igvt-g; +Cc: daniel.vetter, david.j.cowperthwaite, zhiyuan.lv

For flexible LRC context creation, we factor out the core logic of LRC
context creation as __intel_lr_context_deferred_alloc().

For the hard-coded LRC context configurations, we keep them in the
upper-level function intel_lr_context_deferred_alloc().

Signed-off-by: Zhi Wang <zhi.a.wang@intel.com>
---
 drivers/gpu/drm/i915/intel_lrc.c | 46 ++++++++++++++++++++++++++++++----------
 drivers/gpu/drm/i915/intel_lrc.h |  8 +++++++
 2 files changed, 43 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index 3a03646..599687f 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -2525,22 +2525,19 @@ static void lrc_setup_hardware_status_page(struct intel_engine_cs *ring,
 }
 
 /**
- * intel_lr_context_deferred_alloc() - create the LRC specific bits of a context
+ * __intel_lr_context_deferred_alloc() - core logic of creating a LRC context
  * @ctx: LR context to create.
- * @ring: engine to be used with the context.
+ * @params: parameters to specify configurable options of the context.
  *
- * This function can be called more than once, with different engines, if we plan
- * to use the context with them. The context backing objects and the ringbuffers
- * (specially the ringbuffer backing objects) suck a lot of memory up, and that's why
- * the creation is a deferred call: it's better to make sure first that we need to use
- * a given ring with the context.
+ * This function is the core logic of creating and initializing a LRC context
  *
  * Return: non-zero on error.
  */
 
-int intel_lr_context_deferred_alloc(struct intel_context *ctx,
-				    struct intel_engine_cs *ring)
+int __intel_lr_context_deferred_alloc(struct intel_context *ctx,
+	struct intel_lr_context_alloc_params *params)
 {
+	struct intel_engine_cs *ring = params->ring;
 	struct drm_device *dev = ring->dev;
 	struct drm_i915_gem_object *ctx_obj;
 	uint32_t context_size;
@@ -2561,7 +2558,7 @@ int intel_lr_context_deferred_alloc(struct intel_context *ctx,
 		return -ENOMEM;
 	}
 
-	ringbuf = intel_engine_create_ringbuffer(ring, 4 * PAGE_SIZE);
+	ringbuf = intel_engine_create_ringbuffer(ring, params->ringbuffer_size);
 	if (IS_ERR(ringbuf)) {
 		ret = PTR_ERR(ringbuf);
 		goto error_deref_obj;
@@ -2576,7 +2573,7 @@ int intel_lr_context_deferred_alloc(struct intel_context *ctx,
 	ctx->engine[ring->id].ringbuf = ringbuf;
 	ctx->engine[ring->id].state = ctx_obj;
 
-	if (ctx != ctx->i915->kernel_context && ring->init_context) {
+	if (params->ctx_needs_init && ring->init_context) {
 		struct drm_i915_gem_request *req;
 
 		req = i915_gem_request_alloc(ring, ctx);
@@ -2606,6 +2603,33 @@ error_deref_obj:
 	return ret;
 }
 
+/**
+ * intel_lr_context_deferred_alloc() - create the LRC specific bits of a context
+ * @ctx: LR context to create.
+ * @ring: engine to be used with the context.
+ *
+ * This function can be called more than once, with different engines, if we
+ * plan to use the context with them. The context backing objects and the
+ * ringbuffers (specially the ringbuffer backing objects) suck a lot of memory
+ * up, and that's why the creation is a deferred call: it's better to make sure
+ * firstthat we need to use a given ring with the context.
+ *
+ * Return: non-zero on error.
+ */
+int intel_lr_context_deferred_alloc(struct intel_context *ctx,
+				    struct intel_engine_cs *ring)
+{
+	struct intel_lr_context_alloc_params params;
+
+	memset(&params, 0, sizeof(params));
+
+	params.ring = ring;
+	params.ringbuffer_size = 4 * PAGE_SIZE;
+	params.ctx_needs_init = (ctx != ctx->i915->kernel_context);
+
+	return __intel_lr_context_deferred_alloc(ctx, &params);
+}
+
 void intel_lr_context_reset(struct drm_device *dev,
 			struct intel_context *ctx)
 {
diff --git a/drivers/gpu/drm/i915/intel_lrc.h b/drivers/gpu/drm/i915/intel_lrc.h
index e6cda3e..528c4fb 100644
--- a/drivers/gpu/drm/i915/intel_lrc.h
+++ b/drivers/gpu/drm/i915/intel_lrc.h
@@ -97,10 +97,18 @@ static inline void intel_logical_ring_emit_reg(struct intel_ringbuffer *ringbuf,
 #define LRC_PPHWSP_PN	(LRC_GUCSHR_PN + 1)
 #define LRC_STATE_PN	(LRC_PPHWSP_PN + 1)
 
+struct intel_lr_context_alloc_params {
+	struct intel_engine_cs *ring;
+	u32 ringbuffer_size;
+	bool ctx_needs_init;
+};
+
 void intel_lr_context_free(struct intel_context *ctx);
 uint32_t intel_lr_context_size(struct intel_engine_cs *ring);
 int intel_lr_context_deferred_alloc(struct intel_context *ctx,
 				    struct intel_engine_cs *ring);
+int __intel_lr_context_deferred_alloc(struct intel_context *ctx,
+			struct intel_lr_context_alloc_params *params);
 void intel_lr_context_unpin(struct intel_context *ctx,
 			    struct intel_engine_cs *engine);
 void intel_lr_context_reset(struct drm_device *dev,
-- 
1.9.1

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

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [RFCv2 08/14] drm/i915: Support per-PPGTT address space mode
  2016-02-18 11:42 [RFCv2 PATCH 00/14] gvt: Hacking i915 for GVT context requirement Zhi Wang
                   ` (6 preceding siblings ...)
  2016-02-18 11:42 ` [RFCv2 07/14] drm/i915: factor out __intel_lr_context_deferred_alloc() Zhi Wang
@ 2016-02-18 11:42 ` Zhi Wang
  2016-02-24  8:47   ` Tian, Kevin
  2016-02-18 11:42 ` [RFCv2 09/14] drm/i915: generate address mode bit from PPGTT instance Zhi Wang
                   ` (7 subsequent siblings)
  15 siblings, 1 reply; 46+ messages in thread
From: Zhi Wang @ 2016-02-18 11:42 UTC (permalink / raw)
  To: intel-gfx, igvt-g; +Cc: daniel.vetter, david.j.cowperthwaite, zhiyuan.lv

Previously the address space mode of each PPGTT instance is hard-coded to
host system configuration, e.g. if the host system is configured to use
48bit full PPGTT, then address space mode of all PPGTT instances is 48bit.

Per Daniel and Kevin's advice, GVT-g will leverage i915 PPGTT interface to
populate its shadow PPGTT page table. Under GVT-g the address space mode
of PPGTT instances could be various, some guest may use 32bit, some guest
may use 48bit.

We store the address space mode into i915_hw_ppgtt, and let i915 page
table manipulation routines / LRC context population routines read the
address space mode from it instead of the system configuration.

Signed-off-by: Zhi Wang <zhi.a.wang@intel.com>
---
 drivers/gpu/drm/i915/i915_gem_gtt.c | 81 ++++++++++++++++++++-----------------
 drivers/gpu/drm/i915/i915_gem_gtt.h |  3 ++
 drivers/gpu/drm/i915/intel_lrc.c    |  6 +--
 3 files changed, 51 insertions(+), 39 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
index de09dd4..7f043f5 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -564,22 +564,22 @@ static void __pdp_fini(struct i915_page_directory_pointer *pdp)
 }
 
 static struct
-i915_page_directory_pointer *alloc_pdp(struct drm_device *dev)
+i915_page_directory_pointer *alloc_pdp(struct i915_hw_ppgtt *ppgtt)
 {
 	struct i915_page_directory_pointer *pdp;
 	int ret = -ENOMEM;
 
-	WARN_ON(!USES_FULL_48BIT_PPGTT(dev));
+	WARN_ON(!IS_48BIT_PPGTT(ppgtt));
 
 	pdp = kzalloc(sizeof(*pdp), GFP_KERNEL);
 	if (!pdp)
 		return ERR_PTR(-ENOMEM);
 
-	ret = __pdp_init(dev, pdp);
+	ret = __pdp_init(ppgtt->base.dev, pdp);
 	if (ret)
 		goto fail_bitmap;
 
-	ret = setup_px(dev, pdp);
+	ret = setup_px(ppgtt->base.dev, pdp);
 	if (ret)
 		goto fail_page_m;
 
@@ -593,12 +593,12 @@ fail_bitmap:
 	return ERR_PTR(ret);
 }
 
-static void free_pdp(struct drm_device *dev,
+static void free_pdp(struct i915_hw_ppgtt *ppgtt,
 		     struct i915_page_directory_pointer *pdp)
 {
 	__pdp_fini(pdp);
-	if (USES_FULL_48BIT_PPGTT(dev)) {
-		cleanup_px(dev, pdp);
+	if (IS_48BIT_PPGTT(ppgtt)) {
+		cleanup_px(ppgtt->base.dev, pdp);
 		kfree(pdp);
 	}
 }
@@ -632,7 +632,7 @@ gen8_setup_page_directory(struct i915_hw_ppgtt *ppgtt,
 {
 	gen8_ppgtt_pdpe_t *page_directorypo;
 
-	if (!USES_FULL_48BIT_PPGTT(ppgtt->base.dev))
+	if (!IS_48BIT_PPGTT(ppgtt))
 		return;
 
 	page_directorypo = kmap_px(pdp);
@@ -648,7 +648,7 @@ gen8_setup_page_directory_pointer(struct i915_hw_ppgtt *ppgtt,
 {
 	gen8_ppgtt_pml4e_t *pagemap = kmap_px(pml4);
 
-	WARN_ON(!USES_FULL_48BIT_PPGTT(ppgtt->base.dev));
+	WARN_ON(!IS_48BIT_PPGTT(ppgtt));
 	pagemap[index] = gen8_pml4e_encode(px_dma(pdp), I915_CACHE_LLC);
 	kunmap_px(ppgtt, pagemap);
 }
@@ -767,7 +767,7 @@ static void gen8_ppgtt_clear_range(struct i915_address_space *vm,
 	gen8_pte_t scratch_pte = gen8_pte_encode(px_dma(vm->scratch_page),
 						 I915_CACHE_LLC, use_scratch);
 
-	if (!USES_FULL_48BIT_PPGTT(vm->dev)) {
+	if (!IS_48BIT_PPGTT(ppgtt)) {
 		gen8_ppgtt_clear_pte_range(vm, &ppgtt->pdp, start, length,
 					   scratch_pte);
 	} else {
@@ -835,7 +835,7 @@ static void gen8_ppgtt_insert_entries(struct i915_address_space *vm,
 
 	__sg_page_iter_start(&sg_iter, pages->sgl, sg_nents(pages->sgl), 0);
 
-	if (!USES_FULL_48BIT_PPGTT(vm->dev)) {
+	if (!IS_48BIT_PPGTT(ppgtt)) {
 		gen8_ppgtt_insert_pte_entries(vm, &ppgtt->pdp, &sg_iter, start,
 					      cache_level);
 	} else {
@@ -869,6 +869,8 @@ static void gen8_free_page_tables(struct drm_device *dev,
 
 static int gen8_init_scratch(struct i915_address_space *vm)
 {
+	struct i915_hw_ppgtt *ppgtt =
+		container_of(vm, struct i915_hw_ppgtt, base);
 	struct drm_device *dev = vm->dev;
 
 	vm->scratch_page = alloc_scratch_page(dev);
@@ -888,8 +890,8 @@ static int gen8_init_scratch(struct i915_address_space *vm)
 		return PTR_ERR(vm->scratch_pd);
 	}
 
-	if (USES_FULL_48BIT_PPGTT(dev)) {
-		vm->scratch_pdp = alloc_pdp(dev);
+	if (IS_48BIT_PPGTT(ppgtt)) {
+		vm->scratch_pdp = alloc_pdp(ppgtt);
 		if (IS_ERR(vm->scratch_pdp)) {
 			free_pd(dev, vm->scratch_pd);
 			free_pt(dev, vm->scratch_pt);
@@ -900,7 +902,7 @@ static int gen8_init_scratch(struct i915_address_space *vm)
 
 	gen8_initialize_pt(vm, vm->scratch_pt);
 	gen8_initialize_pd(vm, vm->scratch_pd);
-	if (USES_FULL_48BIT_PPGTT(dev))
+	if (IS_48BIT_PPGTT(ppgtt))
 		gen8_initialize_pdp(vm, vm->scratch_pdp);
 
 	return 0;
@@ -913,7 +915,7 @@ static int gen8_ppgtt_notify_vgt(struct i915_hw_ppgtt *ppgtt, bool create)
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	int i;
 
-	if (USES_FULL_48BIT_PPGTT(dev)) {
+	if (IS_48BIT_PPGTT(ppgtt)) {
 		u64 daddr = px_dma(&ppgtt->pml4);
 
 		I915_WRITE(vgtif_reg(pdp[0].lo), lower_32_bits(daddr));
@@ -942,14 +944,17 @@ static void gen8_free_scratch(struct i915_address_space *vm)
 {
 	struct drm_device *dev = vm->dev;
 
-	if (USES_FULL_48BIT_PPGTT(dev))
-		free_pdp(dev, vm->scratch_pdp);
+	struct i915_hw_ppgtt *ppgtt =
+		container_of(vm, struct i915_hw_ppgtt, base);
+
+	if (IS_48BIT_PPGTT(ppgtt))
+		free_pdp(ppgtt, vm->scratch_pdp);
 	free_pd(dev, vm->scratch_pd);
 	free_pt(dev, vm->scratch_pt);
 	free_scratch_page(dev, vm->scratch_page);
 }
 
-static void gen8_ppgtt_cleanup_3lvl(struct drm_device *dev,
+static void gen8_ppgtt_cleanup_3lvl(struct i915_hw_ppgtt *ppgtt,
 				    struct i915_page_directory_pointer *pdp)
 {
 	int i;
@@ -958,11 +963,11 @@ static void gen8_ppgtt_cleanup_3lvl(struct drm_device *dev,
 		if (WARN_ON(!pdp->page_directory[i]))
 			continue;
 
-		gen8_free_page_tables(dev, pdp->page_directory[i]);
-		free_pd(dev, pdp->page_directory[i]);
+		gen8_free_page_tables(ppgtt->base.dev, pdp->page_directory[i]);
+		free_pd(ppgtt->base.dev, pdp->page_directory[i]);
 	}
 
-	free_pdp(dev, pdp);
+	free_pdp(ppgtt, pdp);
 }
 
 static void gen8_ppgtt_cleanup_4lvl(struct i915_hw_ppgtt *ppgtt)
@@ -973,7 +978,7 @@ static void gen8_ppgtt_cleanup_4lvl(struct i915_hw_ppgtt *ppgtt)
 		if (WARN_ON(!ppgtt->pml4.pdps[i]))
 			continue;
 
-		gen8_ppgtt_cleanup_3lvl(ppgtt->base.dev, ppgtt->pml4.pdps[i]);
+		gen8_ppgtt_cleanup_3lvl(ppgtt, ppgtt->pml4.pdps[i]);
 	}
 
 	cleanup_px(ppgtt->base.dev, &ppgtt->pml4);
@@ -987,8 +992,8 @@ static void gen8_ppgtt_cleanup(struct i915_address_space *vm)
 	if (intel_vgpu_active(vm->dev))
 		gen8_ppgtt_notify_vgt(ppgtt, false);
 
-	if (!USES_FULL_48BIT_PPGTT(ppgtt->base.dev))
-		gen8_ppgtt_cleanup_3lvl(ppgtt->base.dev, &ppgtt->pdp);
+	if (!IS_48BIT_PPGTT(ppgtt))
+		gen8_ppgtt_cleanup_3lvl(ppgtt, &ppgtt->pdp);
 	else
 		gen8_ppgtt_cleanup_4lvl(ppgtt);
 
@@ -1133,7 +1138,8 @@ gen8_ppgtt_alloc_page_dirpointers(struct i915_address_space *vm,
 				  uint64_t length,
 				  unsigned long *new_pdps)
 {
-	struct drm_device *dev = vm->dev;
+	struct i915_hw_ppgtt *ppgtt =
+		container_of(vm, struct i915_hw_ppgtt, base);
 	struct i915_page_directory_pointer *pdp;
 	uint32_t pml4e;
 
@@ -1141,7 +1147,7 @@ gen8_ppgtt_alloc_page_dirpointers(struct i915_address_space *vm,
 
 	gen8_for_each_pml4e(pdp, pml4, start, length, pml4e) {
 		if (!test_bit(pml4e, pml4->used_pml4es)) {
-			pdp = alloc_pdp(dev);
+			pdp = alloc_pdp(ppgtt);
 			if (IS_ERR(pdp))
 				goto unwind_out;
 
@@ -1159,7 +1165,7 @@ gen8_ppgtt_alloc_page_dirpointers(struct i915_address_space *vm,
 
 unwind_out:
 	for_each_set_bit(pml4e, new_pdps, GEN8_PML4ES_PER_PML4)
-		free_pdp(dev, pml4->pdps[pml4e]);
+		free_pdp(ppgtt, pml4->pdps[pml4e]);
 
 	return -ENOMEM;
 }
@@ -1368,7 +1374,7 @@ static int gen8_alloc_va_range_4lvl(struct i915_address_space *vm,
 
 err_out:
 	for_each_set_bit(pml4e, new_pdps, GEN8_PML4ES_PER_PML4)
-		gen8_ppgtt_cleanup_3lvl(vm->dev, pml4->pdps[pml4e]);
+		gen8_ppgtt_cleanup_3lvl(ppgtt, pml4->pdps[pml4e]);
 
 	return ret;
 }
@@ -1379,7 +1385,7 @@ static int gen8_alloc_va_range(struct i915_address_space *vm,
 	struct i915_hw_ppgtt *ppgtt =
 		container_of(vm, struct i915_hw_ppgtt, base);
 
-	if (USES_FULL_48BIT_PPGTT(vm->dev))
+	if (IS_48BIT_PPGTT(ppgtt))
 		return gen8_alloc_va_range_4lvl(vm, &ppgtt->pml4, start, length);
 	else
 		return gen8_alloc_va_range_3lvl(vm, &ppgtt->pdp, start, length);
@@ -1450,7 +1456,7 @@ static void gen8_dump_ppgtt(struct i915_hw_ppgtt *ppgtt, struct seq_file *m)
 	gen8_pte_t scratch_pte = gen8_pte_encode(px_dma(vm->scratch_page),
 						 I915_CACHE_LLC, true);
 
-	if (!USES_FULL_48BIT_PPGTT(vm->dev)) {
+	if (!IS_48BIT_PPGTT(ppgtt)) {
 		gen8_dump_pdp(&ppgtt->pdp, start, length, scratch_pte, m);
 	} else {
 		uint64_t pml4e;
@@ -1501,7 +1507,7 @@ static int gen8_preallocate_top_level_pdps(struct i915_hw_ppgtt *ppgtt)
  * space.
  *
  */
-static int gen8_ppgtt_init(struct i915_hw_ppgtt *ppgtt)
+static int gen8_ppgtt_init(struct i915_hw_ppgtt *ppgtt, int address_space_mode)
 {
 	int ret;
 
@@ -1518,7 +1524,7 @@ static int gen8_ppgtt_init(struct i915_hw_ppgtt *ppgtt)
 	ppgtt->base.bind_vma = ppgtt_bind_vma;
 	ppgtt->debug_dump = gen8_dump_ppgtt;
 
-	if (USES_FULL_48BIT_PPGTT(ppgtt->base.dev)) {
+	if (address_space_mode == 48) {
 		ret = setup_px(ppgtt->base.dev, &ppgtt->pml4);
 		if (ret)
 			goto free_scratch;
@@ -1545,6 +1551,8 @@ static int gen8_ppgtt_init(struct i915_hw_ppgtt *ppgtt)
 		}
 	}
 
+	ppgtt->address_space_mode = address_space_mode;
+
 	if (intel_vgpu_active(ppgtt->base.dev))
 		gen8_ppgtt_notify_vgt(ppgtt, true);
 
@@ -2112,14 +2120,15 @@ static int gen6_ppgtt_init(struct i915_hw_ppgtt *ppgtt)
 	return 0;
 }
 
-static int __hw_ppgtt_init(struct drm_device *dev, struct i915_hw_ppgtt *ppgtt)
+static int __hw_ppgtt_init(struct drm_device *dev,
+		struct i915_hw_ppgtt *ppgtt, int address_space_mode)
 {
 	ppgtt->base.dev = dev;
 
 	if (INTEL_INFO(dev)->gen < 8)
 		return gen6_ppgtt_init(ppgtt);
 	else
-		return gen8_ppgtt_init(ppgtt);
+		return gen8_ppgtt_init(ppgtt, address_space_mode);
 }
 
 static void i915_address_space_init(struct i915_address_space *vm,
@@ -2156,7 +2165,7 @@ int i915_ppgtt_init(struct drm_device *dev, struct i915_hw_ppgtt *ppgtt)
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	int ret = 0;
 
-	ret = __hw_ppgtt_init(dev, ppgtt);
+	ret = __hw_ppgtt_init(dev, ppgtt, USES_FULL_48BIT_PPGTT(dev) ? 48 : 32);
 	if (ret == 0) {
 		kref_init(&ppgtt->ref);
 		i915_address_space_init(&ppgtt->base, dev_priv);
@@ -2779,7 +2788,7 @@ static int i915_gem_setup_global_gtt(struct drm_device *dev,
 		if (!ppgtt)
 			return -ENOMEM;
 
-		ret = __hw_ppgtt_init(dev, ppgtt);
+		ret = __hw_ppgtt_init(dev, ppgtt, 32);
 		if (ret) {
 			ppgtt->base.cleanup(&ppgtt->base);
 			kfree(ppgtt);
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h b/drivers/gpu/drm/i915/i915_gem_gtt.h
index 66a6da2..03ef921 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.h
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.h
@@ -110,6 +110,7 @@ typedef uint64_t gen8_ppgtt_pml4e_t;
 
 #define I915_PDPES_PER_PDP(dev) (USES_FULL_48BIT_PPGTT(dev) ?\
 				 GEN8_PML4ES_PER_PML4 : GEN8_LEGACY_PDPES)
+#define IS_48BIT_PPGTT(ppgtt)	((ppgtt) && ((ppgtt)->address_space_mode == 48))
 
 #define PPAT_UNCACHED_INDEX		(_PAGE_PWT | _PAGE_PCD)
 #define PPAT_CACHED_PDE_INDEX		0 /* WB LLC */
@@ -372,6 +373,8 @@ struct i915_hw_ppgtt {
 		struct i915_page_directory pd;		/* GEN6-7 */
 	};
 
+	int address_space_mode;
+
 	struct drm_i915_file_private *file_priv;
 
 	gen6_pte_t __iomem *pd_addr;
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index 599687f..62158af 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -395,7 +395,7 @@ static int execlists_update_context(struct drm_i915_gem_request *rq)
 
 	reg_state[CTX_RING_TAIL+1] = rq->tail;
 
-	if (ppgtt && !USES_FULL_48BIT_PPGTT(ppgtt->base.dev)) {
+	if (ppgtt && !IS_48BIT_PPGTT(ppgtt)) {
 		/* True 32b PPGTT with dynamic page allocation: update PDP
 		 * registers and point the unallocated PDPs to scratch page.
 		 * PML4 is allocated during ppgtt init, so this is not needed
@@ -1674,7 +1674,7 @@ static int gen8_emit_bb_start(struct drm_i915_gem_request *req,
 	 * not needed in 48-bit.*/
 	if (req->ctx->ppgtt &&
 	    (intel_ring_flag(req->ring) & req->ctx->ppgtt->pd_dirty_rings)) {
-		if (!USES_FULL_48BIT_PPGTT(req->i915) &&
+		if (!IS_48BIT_PPGTT(req->ctx->ppgtt) &&
 		    !intel_vgpu_active(req->i915->dev)) {
 			ret = intel_logical_ring_emit_pdps(req);
 			if (ret)
@@ -2408,7 +2408,7 @@ populate_lr_context(struct intel_context *ctx, struct drm_i915_gem_object *ctx_o
 	ASSIGN_CTX_REG(reg_state, CTX_PDP0_UDW, GEN8_RING_PDP_UDW(ring, 0), 0);
 	ASSIGN_CTX_REG(reg_state, CTX_PDP0_LDW, GEN8_RING_PDP_LDW(ring, 0), 0);
 
-	if (USES_FULL_48BIT_PPGTT(ppgtt->base.dev)) {
+	if (IS_48BIT_PPGTT(ppgtt)) {
 		/* 64b PPGTT (48bit canonical)
 		 * PDP0_DESCRIPTOR contains the base address to PML4 and
 		 * other PDP Descriptors are ignored.
-- 
1.9.1

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

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [RFCv2 09/14] drm/i915: generate address mode bit from PPGTT instance
  2016-02-18 11:42 [RFCv2 PATCH 00/14] gvt: Hacking i915 for GVT context requirement Zhi Wang
                   ` (7 preceding siblings ...)
  2016-02-18 11:42 ` [RFCv2 08/14] drm/i915: Support per-PPGTT address space mode Zhi Wang
@ 2016-02-18 11:42 ` Zhi Wang
  2016-02-18 11:42 ` [RFCv2 10/14] drm/i915: update PDPs by condition when submit the LRC context Zhi Wang
                   ` (6 subsequent siblings)
  15 siblings, 0 replies; 46+ messages in thread
From: Zhi Wang @ 2016-02-18 11:42 UTC (permalink / raw)
  To: intel-gfx, igvt-g; +Cc: daniel.vetter, david.j.cowperthwaite, zhiyuan.lv

After the per-PPGTT address mode gets support, the LRC submission should
generate the address mode bit from PPGTT instance, instead of the
hard-coded system configuration.

Signed-off-by: Zhi Wang <zhi.a.wang@intel.com>
---
 drivers/gpu/drm/i915/intel_lrc.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index 62158af..01ea99c2 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -213,7 +213,7 @@ enum {
 	LEGACY_64B_CONTEXT
 };
 #define GEN8_CTX_ADDRESSING_MODE_SHIFT 3
-#define GEN8_CTX_ADDRESSING_MODE(dev)  (USES_FULL_48BIT_PPGTT(dev) ?\
+#define GEN8_CTX_ADDRESSING_MODE(ppgtt) (IS_48BIT_PPGTT(ppgtt) ? \
 		LEGACY_64B_CONTEXT :\
 		LEGACY_32B_CONTEXT)
 enum {
@@ -274,8 +274,6 @@ logical_ring_init_platform_invariants(struct intel_engine_cs *ring)
 					(ring->id == VCS || ring->id == VCS2);
 
 	ring->ctx_desc_template = GEN8_CTX_VALID;
-	ring->ctx_desc_template |= GEN8_CTX_ADDRESSING_MODE(dev) <<
-				   GEN8_CTX_ADDRESSING_MODE_SHIFT;
 	if (IS_GEN8(dev))
 		ring->ctx_desc_template |= GEN8_CTX_L3LLC_COHERENT;
 	ring->ctx_desc_template |= GEN8_CTX_PRIVILEGE;
@@ -318,6 +316,8 @@ intel_lr_context_descriptor_update(struct intel_context *ctx,
 	       LRC_PPHWSP_PN * PAGE_SIZE;
 
 	desc = ring->ctx_desc_template;			   /* bits  0-11 */
+	desc |= GEN8_CTX_ADDRESSING_MODE(ctx->ppgtt) <<	   /* bits  3-4 */
+			GEN8_CTX_ADDRESSING_MODE_SHIFT;
 	desc |= lrca;					   /* bits 12-31 */
 	desc |= (lrca >> PAGE_SHIFT) << GEN8_CTX_ID_SHIFT; /* bits 32-51 */
 
-- 
1.9.1

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

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [RFCv2 10/14] drm/i915: update PDPs by condition when submit the LRC context
  2016-02-18 11:42 [RFCv2 PATCH 00/14] gvt: Hacking i915 for GVT context requirement Zhi Wang
                   ` (8 preceding siblings ...)
  2016-02-18 11:42 ` [RFCv2 09/14] drm/i915: generate address mode bit from PPGTT instance Zhi Wang
@ 2016-02-18 11:42 ` Zhi Wang
  2016-02-24  8:49   ` Tian, Kevin
  2016-02-18 11:42 ` [RFCv2 11/14] drm/i915: Introduce execlist context status change notification Zhi Wang
                   ` (5 subsequent siblings)
  15 siblings, 1 reply; 46+ messages in thread
From: Zhi Wang @ 2016-02-18 11:42 UTC (permalink / raw)
  To: intel-gfx, igvt-g; +Cc: daniel.vetter, david.j.cowperthwaite, zhiyuan.lv

Previously the PDPs inside the ring context are updated at:

- When populate a LRC context
- Before submitting a LRC context (only for 32 bit PPGTT, as the amount
of used PDPs may change)

This patch postpones the PDPs upgrade to submission time, and will update
it by condition if the PPGTT is 48b. Under GVT-g, one GVT context will be
used by different guest, the PPGTT instance related to the context might
be changed before the submission time. And this patch gives GVT context
a chance to load the new PPGTT instance into an initialized context.

[ Behavior Change ]

Before applying this patch:
- Populate PDPs when populating a LRC context
- Update PDPs if the PPGTT is 32b in the submission time

After applying this patch:
- Update PDPs if the PPGTT is 32b or the root_pointer_dirty flag is set
in the submission time.
- The root_pointer_dirty will be set when populating a LRC context

GVT-g benefit
- The root_pointer_dirty will be set when GVT reloading a new PPGTT
instance into an existing GVT context.

Signed-off-by: Zhi Wang <zhi.a.wang@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h  |  1 +
 drivers/gpu/drm/i915/intel_lrc.c | 53 +++++++++++++++++++---------------------
 2 files changed, 26 insertions(+), 28 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 1fd5575..86a5646 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -888,6 +888,7 @@ struct intel_context {
 		u64 lrc_desc;
 		uint32_t *lrc_reg_state;
 	} engine[I915_NUM_RINGS];
+	bool root_pointer_dirty;
 
 	struct list_head link;
 };
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index 01ea99c2..e0ab5b3 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -391,22 +391,39 @@ static int execlists_update_context(struct drm_i915_gem_request *rq)
 {
 	struct intel_engine_cs *ring = rq->ring;
 	struct i915_hw_ppgtt *ppgtt = rq->ctx->ppgtt;
+	struct drm_i915_private *dev_priv = to_i915(ring->dev);
+
 	uint32_t *reg_state = rq->ctx->engine[ring->id].lrc_reg_state;
 
 	reg_state[CTX_RING_TAIL+1] = rq->tail;
 
-	if (ppgtt && !IS_48BIT_PPGTT(ppgtt)) {
-		/* True 32b PPGTT with dynamic page allocation: update PDP
-		 * registers and point the unallocated PDPs to scratch page.
-		 * PML4 is allocated during ppgtt init, so this is not needed
-		 * in 48-bit mode.
+	if (!ppgtt)
+		ppgtt = dev_priv->mm.aliasing_ppgtt;
+
+	/* Update root pointers for 32b PPGTT in every submission */
+	if (!rq->ctx->root_pointer_dirty && !IS_48BIT_PPGTT(ppgtt))
+		return 0;
+
+	if (!IS_48BIT_PPGTT(ppgtt)) {
+		/* 32b PPGTT
+		 * PDP*_DESCRIPTOR contains the base address of space
+		 * supported. With dynamic page allocation, PDPs may
+		 * not be allocated at this point. Point the unallocated
+		 * PDPs to the scratch page
 		 */
 		ASSIGN_CTX_PDP(ppgtt, reg_state, 3);
 		ASSIGN_CTX_PDP(ppgtt, reg_state, 2);
 		ASSIGN_CTX_PDP(ppgtt, reg_state, 1);
 		ASSIGN_CTX_PDP(ppgtt, reg_state, 0);
+	} else {
+		/* 64b PPGTT (48bit canonical)
+		 * PDP0_DESCRIPTOR contains the base address to PML4
+		 * and other PDP Descriptors are ignored.
+		 */
+		ASSIGN_CTX_PML4(ppgtt, reg_state);
 	}
 
+	rq->ctx->root_pointer_dirty = false;
 	return 0;
 }
 
@@ -2322,15 +2339,10 @@ populate_lr_context(struct intel_context *ctx, struct drm_i915_gem_object *ctx_o
 		    struct intel_engine_cs *ring, struct intel_ringbuffer *ringbuf)
 {
 	struct drm_device *dev = ring->dev;
-	struct drm_i915_private *dev_priv = dev->dev_private;
-	struct i915_hw_ppgtt *ppgtt = ctx->ppgtt;
 	struct page *page;
 	uint32_t *reg_state;
 	int ret;
 
-	if (!ppgtt)
-		ppgtt = dev_priv->mm.aliasing_ppgtt;
-
 	ret = i915_gem_object_set_to_cpu_domain(ctx_obj, true);
 	if (ret) {
 		DRM_DEBUG_DRIVER("Could not set to CPU domain\n");
@@ -2408,24 +2420,6 @@ populate_lr_context(struct intel_context *ctx, struct drm_i915_gem_object *ctx_o
 	ASSIGN_CTX_REG(reg_state, CTX_PDP0_UDW, GEN8_RING_PDP_UDW(ring, 0), 0);
 	ASSIGN_CTX_REG(reg_state, CTX_PDP0_LDW, GEN8_RING_PDP_LDW(ring, 0), 0);
 
-	if (IS_48BIT_PPGTT(ppgtt)) {
-		/* 64b PPGTT (48bit canonical)
-		 * PDP0_DESCRIPTOR contains the base address to PML4 and
-		 * other PDP Descriptors are ignored.
-		 */
-		ASSIGN_CTX_PML4(ppgtt, reg_state);
-	} else {
-		/* 32b PPGTT
-		 * PDP*_DESCRIPTOR contains the base address of space supported.
-		 * With dynamic page allocation, PDPs may not be allocated at
-		 * this point. Point the unallocated PDPs to the scratch page
-		 */
-		ASSIGN_CTX_PDP(ppgtt, reg_state, 3);
-		ASSIGN_CTX_PDP(ppgtt, reg_state, 2);
-		ASSIGN_CTX_PDP(ppgtt, reg_state, 1);
-		ASSIGN_CTX_PDP(ppgtt, reg_state, 0);
-	}
-
 	if (ring->id == RCS) {
 		reg_state[CTX_LRI_HEADER_2] = MI_LOAD_REGISTER_IMM(1);
 		ASSIGN_CTX_REG(reg_state, CTX_R_PWR_CLK_STATE, GEN8_R_PWR_CLK_STATE,
@@ -2435,6 +2429,9 @@ populate_lr_context(struct intel_context *ctx, struct drm_i915_gem_object *ctx_o
 	kunmap_atomic(reg_state);
 	i915_gem_object_unpin_pages(ctx_obj);
 
+	/* PDPs inside the ring context need to be updated */
+	ctx->root_pointer_dirty = true;
+
 	return 0;
 }
 
-- 
1.9.1

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

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [RFCv2 11/14] drm/i915: Introduce execlist context status change notification
  2016-02-18 11:42 [RFCv2 PATCH 00/14] gvt: Hacking i915 for GVT context requirement Zhi Wang
                   ` (9 preceding siblings ...)
  2016-02-18 11:42 ` [RFCv2 10/14] drm/i915: update PDPs by condition when submit the LRC context Zhi Wang
@ 2016-02-18 11:42 ` Zhi Wang
  2016-02-18 11:42 ` [RFCv2 12/14] drm/i915: factor out execlists_i915_pick_requests() Zhi Wang
                   ` (4 subsequent siblings)
  15 siblings, 0 replies; 46+ messages in thread
From: Zhi Wang @ 2016-02-18 11:42 UTC (permalink / raw)
  To: intel-gfx, igvt-g; +Cc: daniel.vetter, david.j.cowperthwaite, zhiyuan.lv

This patch introduces an approach for clients to aware the execlist context
status change.

For a GVT context, GVT-g kernel device model uses it as the "shadow
context", its contents will be copied back to guest after the context is
idle. So GVT-g kernel device model has to know the status of the execlist
context, also it will switch the render registers when the context is
schedued-in/out.

This function is configurable as a parameter in the context creation
service. Currently, Only GVT-g will create the "status-change-notification"
enabled GEM context.

Signed-off-by: Zhi Wang <zhi.a.wang@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h  |  2 ++
 drivers/gpu/drm/i915/intel_lrc.c | 28 ++++++++++++++++++++++++++++
 drivers/gpu/drm/i915/intel_lrc.h |  6 ++++++
 3 files changed, 36 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 86a5646..1f94df2 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -887,6 +887,8 @@ struct intel_context {
 		struct i915_vma *lrc_vma;
 		u64 lrc_desc;
 		uint32_t *lrc_reg_state;
+		bool need_status_change_notification;
+		struct atomic_notifier_head notifier_head;
 	} engine[I915_NUM_RINGS];
 	bool root_pointer_dirty;
 
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index e0ab5b3..07aa5da 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -438,6 +438,18 @@ static void execlists_submit_requests(struct drm_i915_gem_request *rq0,
 	execlists_elsp_write(rq0, rq1);
 }
 
+static inline void execlists_context_status_change(
+		struct intel_context *ctx,
+		struct intel_engine_cs *ring,
+		unsigned long status)
+{
+	if (!ctx->engine[ring->id].need_status_change_notification)
+		return;
+
+	atomic_notifier_call_chain(&ctx->engine[ring->id].notifier_head,
+			status, NULL);
+}
+
 static void execlists_context_unqueue(struct intel_engine_cs *ring)
 {
 	struct drm_i915_gem_request *req0 = NULL, *req1 = NULL;
@@ -494,6 +506,13 @@ static void execlists_context_unqueue(struct intel_engine_cs *ring)
 
 	WARN_ON(req1 && req1->elsp_submitted);
 
+	execlists_context_status_change(req0->ctx, ring, CONTEXT_SCHEDULE_IN);
+
+	if (req1) {
+		execlists_context_status_change(req1->ctx,
+			ring, CONTEXT_SCHEDULE_IN);
+	}
+
 	execlists_submit_requests(req0, req1);
 }
 
@@ -514,6 +533,8 @@ static bool execlists_check_remove_request(struct intel_engine_cs *ring,
 			     "Never submitted head request\n");
 
 			if (--head_req->elsp_submitted <= 0) {
+				execlists_context_status_change(head_req->ctx,
+					ring, CONTEXT_SCHEDULE_OUT);
 				list_move_tail(&head_req->execlist_link,
 					       &ring->execlist_retired_req_list);
 				return true;
@@ -2589,6 +2610,13 @@ int __intel_lr_context_deferred_alloc(struct intel_context *ctx,
 		}
 		i915_add_request_no_flush(req);
 	}
+
+	if (params->ctx_needs_status_change_notification) {
+		ctx->engine[ring->id].need_status_change_notification = true;
+		ATOMIC_INIT_NOTIFIER_HEAD(
+			&ctx->engine[ring->id].notifier_head);
+	}
+
 	return 0;
 
 error_ringbuf:
diff --git a/drivers/gpu/drm/i915/intel_lrc.h b/drivers/gpu/drm/i915/intel_lrc.h
index 528c4fb..15791d4 100644
--- a/drivers/gpu/drm/i915/intel_lrc.h
+++ b/drivers/gpu/drm/i915/intel_lrc.h
@@ -54,6 +54,11 @@
 #define GEN8_CSB_READ_PTR(csb_status) \
 	(((csb_status) & GEN8_CSB_READ_PTR_MASK) >> 8)
 
+enum {
+	CONTEXT_SCHEDULE_IN = 0,
+	CONTEXT_SCHEDULE_OUT,
+};
+
 /* Logical Rings */
 int intel_logical_ring_alloc_request_extras(struct drm_i915_gem_request *request);
 int intel_logical_ring_reserve_space(struct drm_i915_gem_request *request);
@@ -101,6 +106,7 @@ struct intel_lr_context_alloc_params {
 	struct intel_engine_cs *ring;
 	u32 ringbuffer_size;
 	bool ctx_needs_init;
+	bool ctx_needs_status_change_notification;
 };
 
 void intel_lr_context_free(struct intel_context *ctx);
-- 
1.9.1

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

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [RFCv2 12/14] drm/i915: factor out execlists_i915_pick_requests()
  2016-02-18 11:42 [RFCv2 PATCH 00/14] gvt: Hacking i915 for GVT context requirement Zhi Wang
                   ` (10 preceding siblings ...)
  2016-02-18 11:42 ` [RFCv2 11/14] drm/i915: Introduce execlist context status change notification Zhi Wang
@ 2016-02-18 11:42 ` Zhi Wang
  2016-02-18 11:42 ` [RFCv2 13/14] drm/i915: Support context single submission when GVT is active Zhi Wang
                   ` (3 subsequent siblings)
  15 siblings, 0 replies; 46+ messages in thread
From: Zhi Wang @ 2016-02-18 11:42 UTC (permalink / raw)
  To: intel-gfx, igvt-g; +Cc: daniel.vetter, david.j.cowperthwaite, zhiyuan.lv

This patch factors out the request picking logics from
execlists_context_unqueue(), with some fixes to makes checkpatch.pl happy.

No logic is changed.

Signed-off-by: Zhi Wang <zhi.a.wang@intel.com>
---
 drivers/gpu/drm/i915/intel_lrc.c | 50 +++++++++++++++++++++++++---------------
 1 file changed, 31 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index 07aa5da..1c0366a 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -450,10 +450,38 @@ static inline void execlists_context_status_change(
 			status, NULL);
 }
 
+static void execlists_i915_pick_requests(struct intel_engine_cs *ring,
+		struct drm_i915_gem_request **req0,
+		struct drm_i915_gem_request **req1)
+{
+	struct drm_i915_gem_request *cursor, *tmp;
+
+	*req0 = *req1 = NULL;
+
+	/* Try to read in pairs */
+	list_for_each_entry_safe(cursor, tmp, &ring->execlist_queue,
+			execlist_link) {
+		if (!*req0) {
+			*req0 = cursor;
+		} else if ((*req0)->ctx == cursor->ctx) {
+			/*
+			 * Same ctx: ignore first request, as second request
+			 * will update tail past first request's workload
+			 */
+			cursor->elsp_submitted = (*req0)->elsp_submitted;
+			list_move_tail(&(*req0)->execlist_link,
+					&ring->execlist_retired_req_list);
+			*req0 = cursor;
+		} else {
+			*req1 = cursor;
+			break;
+		}
+	}
+}
+
 static void execlists_context_unqueue(struct intel_engine_cs *ring)
 {
-	struct drm_i915_gem_request *req0 = NULL, *req1 = NULL;
-	struct drm_i915_gem_request *cursor = NULL, *tmp = NULL;
+	struct drm_i915_gem_request *req0, *req1;
 
 	assert_spin_locked(&ring->execlist_lock);
 
@@ -466,23 +494,7 @@ static void execlists_context_unqueue(struct intel_engine_cs *ring)
 	if (list_empty(&ring->execlist_queue))
 		return;
 
-	/* Try to read in pairs */
-	list_for_each_entry_safe(cursor, tmp, &ring->execlist_queue,
-				 execlist_link) {
-		if (!req0) {
-			req0 = cursor;
-		} else if (req0->ctx == cursor->ctx) {
-			/* Same ctx: ignore first request, as second request
-			 * will update tail past first request's workload */
-			cursor->elsp_submitted = req0->elsp_submitted;
-			list_move_tail(&req0->execlist_link,
-				       &ring->execlist_retired_req_list);
-			req0 = cursor;
-		} else {
-			req1 = cursor;
-			break;
-		}
-	}
+	execlists_i915_pick_requests(ring, &req0, &req1);
 
 	if (IS_GEN8(ring->dev) || IS_GEN9(ring->dev)) {
 		/*
-- 
1.9.1

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

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [RFCv2 13/14] drm/i915: Support context single submission when GVT is active
  2016-02-18 11:42 [RFCv2 PATCH 00/14] gvt: Hacking i915 for GVT context requirement Zhi Wang
                   ` (11 preceding siblings ...)
  2016-02-18 11:42 ` [RFCv2 12/14] drm/i915: factor out execlists_i915_pick_requests() Zhi Wang
@ 2016-02-18 11:42 ` Zhi Wang
  2016-02-24  8:52   ` Tian, Kevin
  2016-02-18 11:42 ` [RFCv2 14/14] drm/i915: Introduce GVT context creation API Zhi Wang
                   ` (2 subsequent siblings)
  15 siblings, 1 reply; 46+ messages in thread
From: Zhi Wang @ 2016-02-18 11:42 UTC (permalink / raw)
  To: intel-gfx, igvt-g; +Cc: daniel.vetter, david.j.cowperthwaite, zhiyuan.lv

This patch introduces a new request picking logic to support the single-
submission context. As GVT context may comes from different guests, which
requires different configuration of render registers configuration. It
can't be combined in a dual ELSP submission combo.

We make this function as a context feature in context creation service.
Only GVT-g will create this kinds of GEM context currently, which only
allows to be single submitted.

Signed-off-by: Zhi Wang <zhi.a.wang@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h  |  1 +
 drivers/gpu/drm/i915/intel_lrc.c | 42 +++++++++++++++++++++++++++++++++++++++-
 drivers/gpu/drm/i915/intel_lrc.h |  1 +
 3 files changed, 43 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 1f94df2..0850b35 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -890,6 +890,7 @@ struct intel_context {
 		bool need_status_change_notification;
 		struct atomic_notifier_head notifier_head;
 	} engine[I915_NUM_RINGS];
+	bool single_submission;
 	bool root_pointer_dirty;
 
 	struct list_head link;
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index 1c0366a..2a6d6fe 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -479,6 +479,40 @@ static void execlists_i915_pick_requests(struct intel_engine_cs *ring,
 	}
 }
 
+static void execlists_gvt_pick_requests(struct intel_engine_cs *ring,
+		struct drm_i915_gem_request **req0,
+		struct drm_i915_gem_request **req1)
+{
+	struct drm_i915_gem_request *cursor, *tmp;
+
+	*req0 = *req1 = NULL;
+
+	/* Try to read in pairs */
+	list_for_each_entry_safe(cursor, tmp, &ring->execlist_queue,
+			execlist_link) {
+		if (!*req0) {
+			*req0 = cursor;
+			/* single submission */
+			if ((*req0)->ctx->single_submission)
+				break;
+		} else if ((*req0)->ctx == cursor->ctx) {
+			/*
+			 * Same ctx: ignore first request, as second request
+			 * will update tail past first request's workload
+			 */
+			cursor->elsp_submitted = (*req0)->elsp_submitted;
+			list_move_tail(&(*req0)->execlist_link,
+					&ring->execlist_retired_req_list);
+			*req0 = cursor;
+		} else {
+			/* single submission */
+			if (!cursor->ctx->single_submission)
+				*req1 = cursor;
+			break;
+		}
+	}
+}
+
 static void execlists_context_unqueue(struct intel_engine_cs *ring)
 {
 	struct drm_i915_gem_request *req0, *req1;
@@ -494,7 +528,10 @@ static void execlists_context_unqueue(struct intel_engine_cs *ring)
 	if (list_empty(&ring->execlist_queue))
 		return;
 
-	execlists_i915_pick_requests(ring, &req0, &req1);
+	if (!intel_gvt_active(ring->dev))
+		execlists_i915_pick_requests(ring, &req0, &req1);
+	else
+		execlists_gvt_pick_requests(ring, &req0, &req1);
 
 	if (IS_GEN8(ring->dev) || IS_GEN9(ring->dev)) {
 		/*
@@ -2629,6 +2666,9 @@ int __intel_lr_context_deferred_alloc(struct intel_context *ctx,
 			&ctx->engine[ring->id].notifier_head);
 	}
 
+	if (params->ctx_needs_single_submission)
+		ctx->single_submission = true;
+
 	return 0;
 
 error_ringbuf:
diff --git a/drivers/gpu/drm/i915/intel_lrc.h b/drivers/gpu/drm/i915/intel_lrc.h
index 15791d4..4873dd8 100644
--- a/drivers/gpu/drm/i915/intel_lrc.h
+++ b/drivers/gpu/drm/i915/intel_lrc.h
@@ -107,6 +107,7 @@ struct intel_lr_context_alloc_params {
 	u32 ringbuffer_size;
 	bool ctx_needs_init;
 	bool ctx_needs_status_change_notification;
+	bool ctx_needs_single_submission;
 };
 
 void intel_lr_context_free(struct intel_context *ctx);
-- 
1.9.1

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

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [RFCv2 14/14] drm/i915: Introduce GVT context creation API
  2016-02-18 11:42 [RFCv2 PATCH 00/14] gvt: Hacking i915 for GVT context requirement Zhi Wang
                   ` (12 preceding siblings ...)
  2016-02-18 11:42 ` [RFCv2 13/14] drm/i915: Support context single submission when GVT is active Zhi Wang
@ 2016-02-18 11:42 ` Zhi Wang
  2016-02-18 12:02 ` ✗ Fi.CI.BAT: failure for gvt: Hacking i915 for GVT context requirement Patchwork
  2016-02-24  8:55 ` [RFCv2 PATCH 00/14] " Tian, Kevin
  15 siblings, 0 replies; 46+ messages in thread
From: Zhi Wang @ 2016-02-18 11:42 UTC (permalink / raw)
  To: intel-gfx, igvt-g; +Cc: daniel.vetter, david.j.cowperthwaite, zhiyuan.lv

GVT workload scheduler needs special host LRC contexts, the so called
"shadow LRC context" to submit guest workload to host i915. During the
guest workload submission, GVT fills the shadow LRC context with the
content of guest LRC context: engine context is copied without changes,
ring context is mostly owned by host i915.

The GVT-g workload scheduler flow:

         +-----------+                   +-----------+
         | GVT Guest |                   | GVT Guest |
         +-+-----^---+                   +-+-----^---+
           |     |                         |     |
           |     | GVT-g                   |     | GVT-g
vELSP write|     | emulates     vELSP write|     | emulates
           |     | Execlist/CSB            |     | Execlist/CSB
           |     | Status                  |     | Status
           |     |                         |     |
    +------v-----+-------------------------v-----+---------+
    |           GVT Virtual Execlist Submission            |
    +------+-------------------------------+---------------+
           |                               |
           | Per-VM/Ring Workoad Q         | Per-VM/Ring Workload Q
   +---------------------+--+      +------------------------+
       +---v--------+    ^             +---v--------+
       |GVT Workload|... |             |GVT Workload|...
       +------------+    |             +------------+
                         |
                         | Pick Workload from Q
    +--------------------+---------------------------------+
    |                GVT Workload Scheduler                |
    +--------------------+---------------------------------+
                         |         * Shadow guest LRC context
                  +------v------+  * Shadow guest ring buffer
                  | GVT Context |  * Scan/Patch guest RB instructions
                  +------+------+
                         |
                         v
              Host i915 GEM Submission

v2:

Mostly based on Daniel's idea. Call the refactored core logic of GEM
context creation service and LRC context creation service to create the GVT
context.

Signed-off-by: Zhi Wang <zhi.a.wang@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h         |  1 +
 drivers/gpu/drm/i915/i915_gem_context.c | 52 +++++++++++++++++++++++++++++++++
 2 files changed, 53 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 0850b35..fa31680 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -3278,6 +3278,7 @@ i915_gem_context_get(struct drm_i915_file_private *file_priv, u32 id);
 void i915_gem_context_free(struct kref *ctx_ref);
 struct drm_i915_gem_object *
 i915_gem_alloc_context_obj(struct drm_device *dev, size_t size);
+struct intel_context *i915_gem_create_gvt_context(struct drm_device *dev);
 static inline void i915_gem_context_reference(struct intel_context *ctx)
 {
 	kref_get(&ctx->ref);
diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c
index cda09f7..65f78c6 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/i915_gem_context.c
@@ -369,6 +369,58 @@ i915_gem_create_context(struct drm_device *dev,
 	return ctx;
 }
 
+/**
+ * i915_i915_gem_create_gvt_context - create a GVT GEM context
+ * @dev: drm device *
+ *
+ * This function is used to create a GVT specific GEM context.
+ *
+ * Returns:
+ * pointer to intel_context on success, NULL if failed
+ *
+ */
+struct intel_context *
+i915_gem_create_gvt_context(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	struct i915_gem_context_create_params params;
+	struct intel_lr_context_alloc_params alloc_params;
+	struct intel_context *ctx;
+	int i, ret;
+
+	memset(&params, 0, sizeof(params));
+	memset(&alloc_params, 0, sizeof(params));
+
+	params.file_priv = NULL;
+	params.has_legacy_ctx = false;
+	params.has_ppgtt = false;
+	params.is_default_ctx = false;
+
+	alloc_params.ctx_needs_init = false;
+	alloc_params.ctx_needs_status_change_notification = true;
+	alloc_params.ctx_needs_single_submission = true;
+	alloc_params.ringbuffer_size = 512 * PAGE_SIZE;
+
+	mutex_lock(&dev->struct_mutex);
+
+	ctx = __i915_gem_create_context(dev, &params);
+	if (IS_ERR(ctx))
+		return ctx;
+
+	for (i = 0; i < I915_NUM_RINGS; i++) {
+		alloc_params.ring = &dev_priv->ring[i];
+		ret = __intel_lr_context_deferred_alloc(ctx, &alloc_params);
+		if (ret) {
+			i915_gem_context_unreference(ctx);
+			ctx = NULL;
+			goto out;
+		}
+	}
+out:
+	mutex_unlock(&dev->struct_mutex);
+	return ctx;
+}
+
 static void i915_gem_context_unpin(struct intel_context *ctx,
 				   struct intel_engine_cs *engine)
 {
-- 
1.9.1

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

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* ✗ Fi.CI.BAT: failure for gvt: Hacking i915 for GVT context requirement
  2016-02-18 11:42 [RFCv2 PATCH 00/14] gvt: Hacking i915 for GVT context requirement Zhi Wang
                   ` (13 preceding siblings ...)
  2016-02-18 11:42 ` [RFCv2 14/14] drm/i915: Introduce GVT context creation API Zhi Wang
@ 2016-02-18 12:02 ` Patchwork
  2016-02-24  8:55 ` [RFCv2 PATCH 00/14] " Tian, Kevin
  15 siblings, 0 replies; 46+ messages in thread
From: Patchwork @ 2016-02-18 12:02 UTC (permalink / raw)
  To: Wang, Zhi A; +Cc: intel-gfx

== Summary ==

Series 3576v1 gvt: Hacking i915 for GVT context requirement
2016-02-18T11:45:34.820959 http://patchwork.freedesktop.org/api/1.0/series/3576/revisions/1/mbox/
Applying: drm/i915: factor out i915_pvinfo.h
Applying: drm/i915/gvt: Introduce the basic architecture of GVT-g
Using index info to reconstruct a base tree...
M	drivers/gpu/drm/i915/Kconfig
M	drivers/gpu/drm/i915/i915_drv.h
Falling back to patching base and 3-way merge...
Auto-merging drivers/gpu/drm/i915/i915_drv.h
Auto-merging drivers/gpu/drm/i915/Kconfig
CONFLICT (content): Merge conflict in drivers/gpu/drm/i915/Kconfig
Patch failed at 0002 drm/i915/gvt: Introduce the basic architecture of GVT-g

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

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [RFCv2 01/14] drm/i915: factor out i915_pvinfo.h
  2016-02-18 11:42 ` [RFCv2 01/14] drm/i915: factor out i915_pvinfo.h Zhi Wang
@ 2016-02-22 13:23   ` Joonas Lahtinen
  2016-02-23  2:40     ` Zhi Wang
  0 siblings, 1 reply; 46+ messages in thread
From: Joonas Lahtinen @ 2016-02-22 13:23 UTC (permalink / raw)
  To: Zhi Wang, intel-gfx, igvt-g
  Cc: daniel.vetter, david.j.cowperthwaite, zhiyuan.lv

Hi,

On to, 2016-02-18 at 19:42 +0800, Zhi Wang wrote:
> As the PVINFO page definition is used by both GVT-g guest (vGPU) and GVT-g
> host (GVT-g kernel device model), factor it out for better code structure.
> 
> Signed-off-by: Zhi Wang <zhi.a.wang@intel.com>
> ---
>  drivers/gpu/drm/i915/i915_pvinfo.h | 113 +++++++++++++++++++++++++++++++++++++
>  drivers/gpu/drm/i915/i915_vgpu.h   |  86 +---------------------------
>  2 files changed, 114 insertions(+), 85 deletions(-)
>  create mode 100644 drivers/gpu/drm/i915/i915_pvinfo.h
> 
> diff --git a/drivers/gpu/drm/i915/i915_pvinfo.h b/drivers/gpu/drm/i915/i915_pvinfo.h
> new file mode 100644
> index 0000000..68bdf60
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/i915_pvinfo.h
> @@ -0,0 +1,113 @@
> +/*
> + * 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.
> + */
> +
> +#ifndef _I915_PVINFO_H_
> +#define _I915_PVINFO_H_
> +
> +/* The MMIO offset of the shared info between guest and host emulator */
> +#define VGT_PVINFO_PAGE	0x78000
> +#define VGT_PVINFO_SIZE	0x1000
> +
> +/*
> + * The following structure pages are defined in GEN MMIO space
> + * for virtualization. (One page for now)
> + */
> +#define VGT_MAGIC         0x4776544776544776ULL	/* 'vGTvGTvG' */
> +#define VGT_VERSION_MAJOR 1
> +#define VGT_VERSION_MINOR 0
> +
> +#define INTEL_VGT_IF_VERSION_ENCODE(major, minor) ((major) << 16 | (minor))
> +#define INTEL_VGT_IF_VERSION \
> +	INTEL_VGT_IF_VERSION_ENCODE(VGT_VERSION_MAJOR, VGT_VERSION_MINOR)
> +
> +/*
> + * notifications from guest to vgpu device model
> + */
> +enum vgt_g2v_type {
> +	VGT_G2V_PPGTT_L3_PAGE_TABLE_CREATE = 2,
> +	VGT_G2V_PPGTT_L3_PAGE_TABLE_DESTROY,
> +	VGT_G2V_PPGTT_L4_PAGE_TABLE_CREATE,
> +	VGT_G2V_PPGTT_L4_PAGE_TABLE_DESTROY,
> +	VGT_G2V_EXECLIST_CONTEXT_CREATE,
> +	VGT_G2V_EXECLIST_CONTEXT_DESTROY,
> +	VGT_G2V_MAX,
> +};
> +
> +struct vgt_if {
> +	uint64_t magic;		/* VGT_MAGIC */
> +	uint16_t version_major;
> +	uint16_t version_minor;
> +	uint32_t vgt_id;	/* ID of vGT instance */
> +	uint32_t rsv1[12];	/* pad to offset 0x40 */
> +	/*
> +	 *  Data structure to describe the balooning info of resources.
> +	 *  Each VM can only have one portion of continuous area for now.
> +	 *  (May support scattered resource in future)
> +	 *  (starting from offset 0x40)
> +	 */
> +	struct {
> +		/* Aperture register balooning */
> +		struct {
> +			uint32_t base;
> +			uint32_t size;
> +		} mappable_gmadr;	/* aperture */
> +		/* GMADR register balooning */
> +		struct {
> +			uint32_t base;
> +			uint32_t size;
> +		} nonmappable_gmadr;	/* non aperture */
> +		/* allowed fence registers */
> +		uint32_t fence_num;
> +		uint32_t rsv2[3];
> +	} avail_rs;		/* available/assigned resource */
> +	uint32_t rsv3[0x200 - 24];	/* pad to half page */
> +	/*
> +	 * The bottom half page is for response from Gfx driver to hypervisor.
> +	 */
> +	uint32_t rsv4;
> +	uint32_t display_ready;	/* ready for display owner switch */
> +
> +	uint32_t rsv5[4];
> +
> +	uint32_t g2v_notify;
> +	uint32_t rsv6[7];
> +
> +	struct {
> +		uint32_t lo;
> +		uint32_t hi;
> +	} pdp[4];
> +
> +	uint32_t execlist_context_descriptor_lo;
> +	uint32_t execlist_context_descriptor_hi;
> +
> +	uint32_t  rsv7[0x200 - 24];    /* pad to one page */
> +} __packed;
> +
> +#define vgtif_reg(x) \
> +	_MMIO((VGT_PVINFO_PAGE + (long)&((struct vgt_if *)NULL)->x))

I realize this is code-motion patch, but why does not this use
offsetof?

> +
> +/* vGPU display status to be used by the host side */
> +#define VGT_DRV_DISPLAY_NOT_READY 0
> +#define VGT_DRV_DISPLAY_READY     1  /* ready for display switch */
> +
> +#endif /* _I915_PVINFO_H_ */
> diff --git a/drivers/gpu/drm/i915/i915_vgpu.h b/drivers/gpu/drm/i915/i915_vgpu.h
> index 3c83b47..a3b06f3 100644
> --- a/drivers/gpu/drm/i915/i915_vgpu.h
> +++ b/drivers/gpu/drm/i915/i915_vgpu.h
> @@ -24,91 +24,7 @@
>  #ifndef _I915_VGPU_H_
>  #define _I915_VGPU_H_
>  
> -/* The MMIO offset of the shared info between guest and host emulator */
> -#define VGT_PVINFO_PAGE	0x78000
> -#define VGT_PVINFO_SIZE	0x1000
> -
> -/*
> - * The following structure pages are defined in GEN MMIO space
> - * for virtualization. (One page for now)
> - */
> -#define VGT_MAGIC         0x4776544776544776ULL	/* 'vGTvGTvG' */
> -#define VGT_VERSION_MAJOR 1
> -#define VGT_VERSION_MINOR 0
> -
> -#define INTEL_VGT_IF_VERSION_ENCODE(major, minor) ((major) << 16 | (minor))
> -#define INTEL_VGT_IF_VERSION \
> -	INTEL_VGT_IF_VERSION_ENCODE(VGT_VERSION_MAJOR, VGT_VERSION_MINOR)
> -
> -/*
> - * notifications from guest to vgpu device model
> - */
> -enum vgt_g2v_type {
> -	VGT_G2V_PPGTT_L3_PAGE_TABLE_CREATE = 2,
> -	VGT_G2V_PPGTT_L3_PAGE_TABLE_DESTROY,
> -	VGT_G2V_PPGTT_L4_PAGE_TABLE_CREATE,
> -	VGT_G2V_PPGTT_L4_PAGE_TABLE_DESTROY,
> -	VGT_G2V_EXECLIST_CONTEXT_CREATE,
> -	VGT_G2V_EXECLIST_CONTEXT_DESTROY,
> -	VGT_G2V_MAX,
> -};
> -
> -struct vgt_if {
> -	uint64_t magic;		/* VGT_MAGIC */
> -	uint16_t version_major;
> -	uint16_t version_minor;
> -	uint32_t vgt_id;	/* ID of vGT instance */
> -	uint32_t rsv1[12];	/* pad to offset 0x40 */
> -	/*
> -	 *  Data structure to describe the balooning info of resources.
> -	 *  Each VM can only have one portion of continuous area for now.
> -	 *  (May support scattered resource in future)
> -	 *  (starting from offset 0x40)
> -	 */
> -	struct {
> -		/* Aperture register balooning */
> -		struct {
> -			uint32_t base;
> -			uint32_t size;
> -		} mappable_gmadr;	/* aperture */
> -		/* GMADR register balooning */
> -		struct {
> -			uint32_t base;
> -			uint32_t size;
> -		} nonmappable_gmadr;	/* non aperture */
> -		/* allowed fence registers */
> -		uint32_t fence_num;
> -		uint32_t rsv2[3];
> -	} avail_rs;		/* available/assigned resource */
> -	uint32_t rsv3[0x200 - 24];	/* pad to half page */
> -	/*
> -	 * The bottom half page is for response from Gfx driver to hypervisor.
> -	 */
> -	uint32_t rsv4;
> -	uint32_t display_ready;	/* ready for display owner switch */
> -
> -	uint32_t rsv5[4];
> -
> -	uint32_t g2v_notify;
> -	uint32_t rsv6[7];
> -
> -	struct {
> -		uint32_t lo;
> -		uint32_t hi;
> -	} pdp[4];
> -
> -	uint32_t execlist_context_descriptor_lo;
> -	uint32_t execlist_context_descriptor_hi;
> -
> -	uint32_t  rsv7[0x200 - 24];    /* pad to one page */
> -} __packed;
> -
> -#define vgtif_reg(x) \
> -	_MMIO((VGT_PVINFO_PAGE + (long)&((struct vgt_if *)NULL)->x))
> -
> -/* vGPU display status to be used by the host side */
> -#define VGT_DRV_DISPLAY_NOT_READY 0
> -#define VGT_DRV_DISPLAY_READY     1  /* ready for display switch */
> +#include "i915_pvinfo.h"
>  
>  extern void i915_check_vgpu(struct drm_device *dev);
>  extern int intel_vgt_balloon(struct drm_device *dev);
-- 
Joonas Lahtinen
Open Source Technology Center
Intel Corporation
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [RFCv2 01/14] drm/i915: factor out i915_pvinfo.h
  2016-02-22 13:23   ` Joonas Lahtinen
@ 2016-02-23  2:40     ` Zhi Wang
  0 siblings, 0 replies; 46+ messages in thread
From: Zhi Wang @ 2016-02-23  2:40 UTC (permalink / raw)
  To: Joonas Lahtinen, intel-gfx, igvt-g
  Cc: daniel.vetter, david.j.cowperthwaite, zhiyuan.lv

Hi Joonas:
     Thanks for the comments! Let me cook a patch to improve it 
immediately. :)

Thanks,
Zhi.

On 02/22/16 21:23, Joonas Lahtinen wrote:
> Hi,
>
> On to, 2016-02-18 at 19:42 +0800, Zhi Wang wrote:
>> As the PVINFO page definition is used by both GVT-g guest (vGPU) and GVT-g
>> host (GVT-g kernel device model), factor it out for better code structure.
>>
>> Signed-off-by: Zhi Wang <zhi.a.wang@intel.com>
>> ---
>>   drivers/gpu/drm/i915/i915_pvinfo.h | 113 +++++++++++++++++++++++++++++++++++++
>>   drivers/gpu/drm/i915/i915_vgpu.h   |  86 +---------------------------
>>   2 files changed, 114 insertions(+), 85 deletions(-)
>>   create mode 100644 drivers/gpu/drm/i915/i915_pvinfo.h
>>
>> diff --git a/drivers/gpu/drm/i915/i915_pvinfo.h b/drivers/gpu/drm/i915/i915_pvinfo.h
>> new file mode 100644
>> index 0000000..68bdf60
>> --- /dev/null
>> +++ b/drivers/gpu/drm/i915/i915_pvinfo.h
>> @@ -0,0 +1,113 @@
>> +/*
>> + * 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.
>> + */
>> +
>> +#ifndef _I915_PVINFO_H_
>> +#define _I915_PVINFO_H_
>> +
>> +/* The MMIO offset of the shared info between guest and host emulator */
>> +#define VGT_PVINFO_PAGE	0x78000
>> +#define VGT_PVINFO_SIZE	0x1000
>> +
>> +/*
>> + * The following structure pages are defined in GEN MMIO space
>> + * for virtualization. (One page for now)
>> + */
>> +#define VGT_MAGIC         0x4776544776544776ULL	/* 'vGTvGTvG' */
>> +#define VGT_VERSION_MAJOR 1
>> +#define VGT_VERSION_MINOR 0
>> +
>> +#define INTEL_VGT_IF_VERSION_ENCODE(major, minor) ((major) << 16 | (minor))
>> +#define INTEL_VGT_IF_VERSION \
>> +	INTEL_VGT_IF_VERSION_ENCODE(VGT_VERSION_MAJOR, VGT_VERSION_MINOR)
>> +
>> +/*
>> + * notifications from guest to vgpu device model
>> + */
>> +enum vgt_g2v_type {
>> +	VGT_G2V_PPGTT_L3_PAGE_TABLE_CREATE = 2,
>> +	VGT_G2V_PPGTT_L3_PAGE_TABLE_DESTROY,
>> +	VGT_G2V_PPGTT_L4_PAGE_TABLE_CREATE,
>> +	VGT_G2V_PPGTT_L4_PAGE_TABLE_DESTROY,
>> +	VGT_G2V_EXECLIST_CONTEXT_CREATE,
>> +	VGT_G2V_EXECLIST_CONTEXT_DESTROY,
>> +	VGT_G2V_MAX,
>> +};
>> +
>> +struct vgt_if {
>> +	uint64_t magic;		/* VGT_MAGIC */
>> +	uint16_t version_major;
>> +	uint16_t version_minor;
>> +	uint32_t vgt_id;	/* ID of vGT instance */
>> +	uint32_t rsv1[12];	/* pad to offset 0x40 */
>> +	/*
>> +	 *  Data structure to describe the balooning info of resources.
>> +	 *  Each VM can only have one portion of continuous area for now.
>> +	 *  (May support scattered resource in future)
>> +	 *  (starting from offset 0x40)
>> +	 */
>> +	struct {
>> +		/* Aperture register balooning */
>> +		struct {
>> +			uint32_t base;
>> +			uint32_t size;
>> +		} mappable_gmadr;	/* aperture */
>> +		/* GMADR register balooning */
>> +		struct {
>> +			uint32_t base;
>> +			uint32_t size;
>> +		} nonmappable_gmadr;	/* non aperture */
>> +		/* allowed fence registers */
>> +		uint32_t fence_num;
>> +		uint32_t rsv2[3];
>> +	} avail_rs;		/* available/assigned resource */
>> +	uint32_t rsv3[0x200 - 24];	/* pad to half page */
>> +	/*
>> +	 * The bottom half page is for response from Gfx driver to hypervisor.
>> +	 */
>> +	uint32_t rsv4;
>> +	uint32_t display_ready;	/* ready for display owner switch */
>> +
>> +	uint32_t rsv5[4];
>> +
>> +	uint32_t g2v_notify;
>> +	uint32_t rsv6[7];
>> +
>> +	struct {
>> +		uint32_t lo;
>> +		uint32_t hi;
>> +	} pdp[4];
>> +
>> +	uint32_t execlist_context_descriptor_lo;
>> +	uint32_t execlist_context_descriptor_hi;
>> +
>> +	uint32_t  rsv7[0x200 - 24];    /* pad to one page */
>> +} __packed;
>> +
>> +#define vgtif_reg(x) \
>> +	_MMIO((VGT_PVINFO_PAGE + (long)&((struct vgt_if *)NULL)->x))
>
> I realize this is code-motion patch, but why does not this use
> offsetof?
>
>> +
>> +/* vGPU display status to be used by the host side */
>> +#define VGT_DRV_DISPLAY_NOT_READY 0
>> +#define VGT_DRV_DISPLAY_READY     1  /* ready for display switch */
>> +
>> +#endif /* _I915_PVINFO_H_ */
>> diff --git a/drivers/gpu/drm/i915/i915_vgpu.h b/drivers/gpu/drm/i915/i915_vgpu.h
>> index 3c83b47..a3b06f3 100644
>> --- a/drivers/gpu/drm/i915/i915_vgpu.h
>> +++ b/drivers/gpu/drm/i915/i915_vgpu.h
>> @@ -24,91 +24,7 @@
>>   #ifndef _I915_VGPU_H_
>>   #define _I915_VGPU_H_
>>
>> -/* The MMIO offset of the shared info between guest and host emulator */
>> -#define VGT_PVINFO_PAGE	0x78000
>> -#define VGT_PVINFO_SIZE	0x1000
>> -
>> -/*
>> - * The following structure pages are defined in GEN MMIO space
>> - * for virtualization. (One page for now)
>> - */
>> -#define VGT_MAGIC         0x4776544776544776ULL	/* 'vGTvGTvG' */
>> -#define VGT_VERSION_MAJOR 1
>> -#define VGT_VERSION_MINOR 0
>> -
>> -#define INTEL_VGT_IF_VERSION_ENCODE(major, minor) ((major) << 16 | (minor))
>> -#define INTEL_VGT_IF_VERSION \
>> -	INTEL_VGT_IF_VERSION_ENCODE(VGT_VERSION_MAJOR, VGT_VERSION_MINOR)
>> -
>> -/*
>> - * notifications from guest to vgpu device model
>> - */
>> -enum vgt_g2v_type {
>> -	VGT_G2V_PPGTT_L3_PAGE_TABLE_CREATE = 2,
>> -	VGT_G2V_PPGTT_L3_PAGE_TABLE_DESTROY,
>> -	VGT_G2V_PPGTT_L4_PAGE_TABLE_CREATE,
>> -	VGT_G2V_PPGTT_L4_PAGE_TABLE_DESTROY,
>> -	VGT_G2V_EXECLIST_CONTEXT_CREATE,
>> -	VGT_G2V_EXECLIST_CONTEXT_DESTROY,
>> -	VGT_G2V_MAX,
>> -};
>> -
>> -struct vgt_if {
>> -	uint64_t magic;		/* VGT_MAGIC */
>> -	uint16_t version_major;
>> -	uint16_t version_minor;
>> -	uint32_t vgt_id;	/* ID of vGT instance */
>> -	uint32_t rsv1[12];	/* pad to offset 0x40 */
>> -	/*
>> -	 *  Data structure to describe the balooning info of resources.
>> -	 *  Each VM can only have one portion of continuous area for now.
>> -	 *  (May support scattered resource in future)
>> -	 *  (starting from offset 0x40)
>> -	 */
>> -	struct {
>> -		/* Aperture register balooning */
>> -		struct {
>> -			uint32_t base;
>> -			uint32_t size;
>> -		} mappable_gmadr;	/* aperture */
>> -		/* GMADR register balooning */
>> -		struct {
>> -			uint32_t base;
>> -			uint32_t size;
>> -		} nonmappable_gmadr;	/* non aperture */
>> -		/* allowed fence registers */
>> -		uint32_t fence_num;
>> -		uint32_t rsv2[3];
>> -	} avail_rs;		/* available/assigned resource */
>> -	uint32_t rsv3[0x200 - 24];	/* pad to half page */
>> -	/*
>> -	 * The bottom half page is for response from Gfx driver to hypervisor.
>> -	 */
>> -	uint32_t rsv4;
>> -	uint32_t display_ready;	/* ready for display owner switch */
>> -
>> -	uint32_t rsv5[4];
>> -
>> -	uint32_t g2v_notify;
>> -	uint32_t rsv6[7];
>> -
>> -	struct {
>> -		uint32_t lo;
>> -		uint32_t hi;
>> -	} pdp[4];
>> -
>> -	uint32_t execlist_context_descriptor_lo;
>> -	uint32_t execlist_context_descriptor_hi;
>> -
>> -	uint32_t  rsv7[0x200 - 24];    /* pad to one page */
>> -} __packed;
>> -
>> -#define vgtif_reg(x) \
>> -	_MMIO((VGT_PVINFO_PAGE + (long)&((struct vgt_if *)NULL)->x))
>> -
>> -/* vGPU display status to be used by the host side */
>> -#define VGT_DRV_DISPLAY_NOT_READY 0
>> -#define VGT_DRV_DISPLAY_READY     1  /* ready for display switch */
>> +#include "i915_pvinfo.h"
>>
>>   extern void i915_check_vgpu(struct drm_device *dev);
>>   extern int intel_vgt_balloon(struct drm_device *dev);
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [RFCv2 02/14] drm/i915/gvt: Introduce the basic architecture of GVT-g
  2016-02-18 11:42 ` [RFCv2 02/14] drm/i915/gvt: Introduce the basic architecture of GVT-g Zhi Wang
@ 2016-02-23 12:42   ` Joonas Lahtinen
  2016-02-24  7:45     ` Tian, Kevin
  2016-02-26  5:58     ` Zhi Wang
  2016-02-23 12:53   ` Joonas Lahtinen
  2016-02-24  8:08   ` Tian, Kevin
  2 siblings, 2 replies; 46+ messages in thread
From: Joonas Lahtinen @ 2016-02-23 12:42 UTC (permalink / raw)
  To: Zhi Wang, intel-gfx, igvt-g
  Cc: daniel.vetter, david.j.cowperthwaite, zhiyuan.lv

Hi,

Code is looking a lot better.

A general question still; why you seem to be preferring multi-stage
alloc and destroy?

Are there going to be scenarios when things will be allocated but not
initialized? I don't see a such use scenario.

I wouldn't split the init functions down as much as you currently do
because that'll require a lot of boilerplate code to propagate the
errors up, which is currently not done. The boilerplate for propagation
becomes necessary when the teardown function is complex, but currently
the teardown itself is less lines of code than the function
boilerplate.

So just squash those into gvt_device_create() and gvt_device_destroy()
where _create() will propagate any lower level errors up and tear down
a partially initialized struct. _destroy() can then expect to just tear
the whole struct down with no ifs.

Regards, Joonas

On to, 2016-02-18 at 19:42 +0800, Zhi Wang wrote:
> This patch introduces the very basic framework of GVT-g device model,
> includes basic prototypes, definitions, initialization.
> 
> v2:
> - Introduce i915_gvt.c.
> It's necessary to introduce the stubs between i915 driver and GVT-g host,
> as GVT-g components is configurable in kernel config. When disabled, the
> stubs here do nothing.
> 
> Take Joonas's comments:
> - Replace boolean return value with int.
> - Replace customized info/warn/debug macros with DRM macros.
> - Document all non-static functions like i915.
> - Remove empty and unused functions.
> - Replace magic number with marcos.
> - Set GVT-g in kernel config to "n" by default.
> 
> Signed-off-by: Zhi Wang <zhi.a.wang@intel.com>
> ---
>  drivers/gpu/drm/i915/Kconfig         |  15 ++
>  drivers/gpu/drm/i915/Makefile        |   2 +
>  drivers/gpu/drm/i915/gvt/Makefile    |   5 +
>  drivers/gpu/drm/i915/gvt/debug.h     |  57 +++++
>  drivers/gpu/drm/i915/gvt/gvt.c       | 393 +++++++++++++++++++++++++++++++++++
>  drivers/gpu/drm/i915/gvt/gvt.h       | 100 +++++++++
>  drivers/gpu/drm/i915/gvt/hypercall.h |  30 +++
>  drivers/gpu/drm/i915/gvt/mpt.h       |  34 +++
>  drivers/gpu/drm/i915/gvt/params.c    |  32 +++
>  drivers/gpu/drm/i915/gvt/params.h    |  34 +++
>  drivers/gpu/drm/i915/gvt/reg.h       |  34 +++
>  drivers/gpu/drm/i915/i915_dma.c      |  14 ++
>  drivers/gpu/drm/i915/i915_drv.h      |  12 ++
>  drivers/gpu/drm/i915/i915_gvt.c      |  93 +++++++++
>  drivers/gpu/drm/i915/i915_gvt.h      |  49 +++++
>  15 files changed, 904 insertions(+)
>  create mode 100644 drivers/gpu/drm/i915/gvt/Makefile
>  create mode 100644 drivers/gpu/drm/i915/gvt/debug.h
>  create mode 100644 drivers/gpu/drm/i915/gvt/gvt.c
>  create mode 100644 drivers/gpu/drm/i915/gvt/gvt.h
>  create mode 100644 drivers/gpu/drm/i915/gvt/hypercall.h
>  create mode 100644 drivers/gpu/drm/i915/gvt/mpt.h
>  create mode 100644 drivers/gpu/drm/i915/gvt/params.c
>  create mode 100644 drivers/gpu/drm/i915/gvt/params.h
>  create mode 100644 drivers/gpu/drm/i915/gvt/reg.h
>  create mode 100644 drivers/gpu/drm/i915/i915_gvt.c
>  create mode 100644 drivers/gpu/drm/i915/i915_gvt.h
> 
> diff --git a/drivers/gpu/drm/i915/Kconfig b/drivers/gpu/drm/i915/Kconfig
> index 4c59793..082e77d 100644
> --- a/drivers/gpu/drm/i915/Kconfig
> +++ b/drivers/gpu/drm/i915/Kconfig
> @@ -45,3 +45,18 @@ config DRM_I915_PRELIMINARY_HW_SUPPORT
>  	  option changes the default for that module option.
>  
>  	  If in doubt, say "N".
> +
> +config DRM_I915_GVT
> +        tristate "GVT-g host driver"
> +        depends on DRM_I915
> +        default n
> +        help
> +          Enabling GVT-g mediated graphics passthrough technique for Intel i915
> +          based integrated graphics card. With GVT-g, it's possible to have one
> +          integrated i915 device shared by multiple VMs. Performance critical
> +          opterations such as apperture accesses and ring buffer operations
> +          are pass-throughed to VM, with a minimal set of conflicting resources
> +          (e.g. display settings) mediated by vGT driver. The benefit of vGT
> +          is on both the performance, given that each VM could directly operate
> +          its aperture space and submit commands like running on native, and
> +          the feature completeness, given that a true GEN hardware is exposed.
> diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
> index 0851de07..c65026c 100644
> --- a/drivers/gpu/drm/i915/Makefile
> +++ b/drivers/gpu/drm/i915/Makefile
> @@ -91,6 +91,8 @@ i915-y += dvo_ch7017.o \
>  	  intel_sdvo.o \
>  	  intel_tv.o
>  
> +obj-$(CONFIG_DRM_I915_GVT)  += i915_gvt.o gvt/
> +
>  # virtual gpu code
>  i915-y += i915_vgpu.o
>  
> diff --git a/drivers/gpu/drm/i915/gvt/Makefile b/drivers/gpu/drm/i915/gvt/Makefile
> new file mode 100644
> index 0000000..959305f
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/gvt/Makefile
> @@ -0,0 +1,5 @@
> +GVT_SOURCE := gvt.o params.o
> +
> +ccflags-y                      += -I$(src) -I$(src)/.. -Wall -Werror -Wno-unused-function
> +i915_gvt-y                     := $(GVT_SOURCE)
> +obj-$(CONFIG_DRM_I915_GVT)     += i915_gvt.o
> diff --git a/drivers/gpu/drm/i915/gvt/debug.h b/drivers/gpu/drm/i915/gvt/debug.h
> new file mode 100644
> index 0000000..0747f28
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/gvt/debug.h
> @@ -0,0 +1,57 @@
> +/*
> + * 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.
> + */
> +
> +#ifndef __GVT_DEBUG_H__
> +#define __GVT_DEBUG_H__
> +
> +#define gvt_info(fmt, args...) \
> +	DRM_INFO("gvt: "fmt"\n", ##args)
> +

Just;

	DRM_INFO("gvt: " fmt, ##args)

Do not automatically add newlines, it will confuse developers. Applies
to all printing.

> +#define gvt_err(fmt, args...) \
> +	DRM_ERROR("gvt: "fmt"\n", ##args)
> +

Same here.

> +#define gvt_warn(condition, fmt, args...) \
> +	WARN((condition), "gvt: "fmt"\n", ##args)
> +
> +#define gvt_warn_once(condition, fmt, args...) \
> +	WARN_ONCE((condition), "gvt: "fmt"\n", ##args)

WARN and WARN_ONCE will include backtrace so prefixing is unnecessary.
I would not prefix them at all. Just use what i915 kernel module
already uses. If needed, split them to their own file first,
i915_debug.h.
> +
> +#define gvt_dbg(level, fmt, args...) \
> +	DRM_DEBUG_DRIVER("gvt: "fmt"\n", ##args)
> +
> +enum {
> +	GVT_DBG_CORE = (1 << 0),
> +	GVT_DBG_MM = (1 << 1),
> +	GVT_DBG_IRQ = (1 << 2),
> +};

This enum is not of use.

> +
> +#define gvt_dbg_core(fmt, args...) \
> +	gvt_dbg(GVT_DBG_CORE, fmt, ##args)
> +

Rahter like this (not to lose the topic)?
	gvt_dbg("core: " fmt, ##args)

> +#define gvt_dbg_mm(fmt, args...) \
> +	gvt_dbg(GVT_DBG_MM, fmt, ##args)
> +
> +#define gvt_dbg_irq(fmt, args...) \
> +	gvt_dbg(GVT_DBG_IRQ, fmt, ##args)
> +
> +#endif
> diff --git a/drivers/gpu/drm/i915/gvt/gvt.c b/drivers/gpu/drm/i915/gvt/gvt.c
> new file mode 100644
> index 0000000..52cfa32
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/gvt/gvt.c
> @@ -0,0 +1,393 @@
> +/*
> + * 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.
> + */
> +
> +#include 
> +#include 
> +#include 
> +
> +#include "gvt.h"
> +
> +struct gvt_host gvt_host;
> +
> +static const char * const supported_hypervisors[] = {
> +	[GVT_HYPERVISOR_TYPE_XEN] = "Xen Hypervisor",
> +	[GVT_HYPERVISOR_TYPE_KVM] = "KVM",
> +};
> +
> +static int gvt_init_host(void)
> +{
> +	struct gvt_host *host = &gvt_host;
> +

Is it really that much more to write gvt_host.initialized? Counting the
"->" vs "." it's three letters...

> +	if (!gvt.enable) {
> +		gvt_dbg_core("GVT-g has been disabled by kernel parameter");
> +		return -EINVAL;
> +	}
> +
> +	if (host->initialized) {
> +		gvt_err("GVT-g has already been initialized!");
> +		return -EINVAL;
> +	}
> +
> +	/* Xen DOM U */
> +	if (xen_domain() && !xen_initial_domain())
> +		return -ENODEV;
> +
> +	if (xen_initial_domain()) {
> +		/* Xen Dom0 */
> +		host->kdm = try_then_request_module(
> +				symbol_get(xengt_kdm), "xengt");
> +		host->hypervisor_type = GVT_HYPERVISOR_TYPE_XEN;
> +	} else {
> +		/* not in Xen. Try KVMGT */
> +		host->kdm = try_then_request_module(
> +				symbol_get(kvmgt_kdm), "kvm");
> +		host->hypervisor_type = GVT_HYPERVISOR_TYPE_KVM;
> +	}
> +
> +	if (!host->kdm)
> +		return -EINVAL;

I think this error should be reported, to aid detecting problems in
module loading.

> +
> +	if (!hypervisor_detect_host())
> +		return -ENODEV;
> +

This func should be prefixed gvt_, as it is not local to this file.

> +	gvt_info("Running with hypervisor %s in host mode",
> +			supported_hypervisors[host->hypervisor_type]);
> +
> +	idr_init(&host->device_idr);
> +	mutex_init(&host->device_idr_lock);
> +
> +	host->initialized = true;
> +	return 0;
> +}
> +
> +static int init_device_info(struct pgt_device *pdev)
> +{
> +	struct gvt_device_info *info = &pdev->device_info;
> +
> +	if (!IS_BROADWELL(pdev->dev_priv)) {
> +		DRM_DEBUG_DRIVER("Unsupported GEN device");
> +		return -ENODEV;
> +	}

This could be "else" clause on the next if and will allow easier adding
of future platforms.

> +
> +	if (IS_BROADWELL(pdev->dev_priv)) {
> +		info->max_gtt_gm_sz = (1ULL << 32); /* 4GB */
> +		/*
> +		 * The layout of BAR0 in BDW:
> +		 * |< - MMIO 2MB ->|<- Reserved 6MB ->|<- MAX GTT 8MB->|
> +		 *
> +		 * GTT offset in BAR0 starts from 8MB to 16MB, and
> +		 * Whatever GTT size is configured in BIOS,
> +		 * the size of BAR0 is always 16MB. The actual configured
> +		 * GTT size can be found in GMCH_CTRL.
> +		 */
> +		info->gtt_start_offset = (1UL << 23); /* 8MB */
> +		info->max_gtt_size = (1UL << 23); /* 8MB */
> +		info->gtt_entry_size = 8;
> +		info->gtt_entry_size_shift = 3;
> +		info->gmadr_bytes_in_cmd = 8;
> +		info->mmio_size = 2 * 1024 * 1024; /* 2MB */
> +	}
> +
> +	return 0;
> +}
> +
> +static void init_initial_cfg_space_state(struct pgt_device *pdev)
> +{
> +	struct pci_dev *pci_dev = pdev->dev_priv->dev->pdev;
> +	int i;
> +
> +	gvt_dbg_core("init initial cfg space, id %d", pdev->id);
> +
> +	for (i = 0; i < GVT_CFG_SPACE_SZ; i += 4)
> +		pci_read_config_dword(pci_dev, i,
> +				(u32 *)&pdev->initial_cfg_space[i]);
> +
> +	for (i = 0; i < GVT_BAR_NUM; i++) {
> +		pdev->bar_size[i] = pci_resource_len(pci_dev, i * 2);
> +		gvt_dbg_core("bar %d size: %llx", i, pdev->bar_size[i]);
> +	}
> +}
> +
> +static void clean_initial_mmio_state(struct pgt_device *pdev)
> +{
> +	if (pdev->gttmmio_va) {
> +		iounmap(pdev->gttmmio_va);
> +		pdev->gttmmio_va = NULL;
> +	}
> +
> +	if (pdev->gmadr_va) {
> +		iounmap(pdev->gmadr_va);
> +		pdev->gmadr_va = NULL;
> +	}
> +}
> +
> +static int init_initial_mmio_state(struct pgt_device *pdev)
> +{
> +	struct gvt_device_info *info = &pdev->device_info;
> +
> +	u64 bar0, bar1;
> +	int rc;
> +
> +	gvt_dbg_core("init initial mmio state, id %d", pdev->id);
> +
> +	bar0 = *(u64 *)&pdev->initial_cfg_space[GVT_REG_CFG_SPACE_BAR0];
> +	bar1 = *(u64 *)&pdev->initial_cfg_space[GVT_REG_CFG_SPACE_BAR1];
> +
> +	pdev->gttmmio_base = bar0 & ~0xf;
> +	pdev->reg_num = info->mmio_size / 4;
> +	pdev->gmadr_base = bar1 & ~0xf;

Magic numbers still.

> +
> +	pdev->gttmmio_va = ioremap(pdev->gttmmio_base, pdev->bar_size[0]);
> +	if (!pdev->gttmmio_va) {
> +		gvt_err("fail to map GTTMMIO BAR.");
> +		return -EFAULT;
> +	}
> +
> +	pdev->gmadr_va = ioremap(pdev->gmadr_base, pdev->bar_size[2]);
> +	if (!pdev->gmadr_va) {
> +		gvt_err("fail to map GMADR BAR.");
> +		rc = -EFAULT;
> +		goto err;
> +	}
> +
> +	gvt_dbg_core("bar0: 0x%llx, bar1: 0x%llx", bar0, bar1);
> +	gvt_dbg_core("mmio size: %x", pdev->mmio_size);
> +	gvt_dbg_core("gttmmio: 0x%llx, gmadr: 0x%llx", pdev->gttmmio_base,
> +			pdev->gmadr_base);
> +	gvt_dbg_core("gttmmio_va: %p", pdev->gttmmio_va);
> +	gvt_dbg_core("gmadr_va: %p", pdev->gmadr_va);
> +
> +	return 0;
> +err:
> +	clean_initial_mmio_state(pdev);
> +	return rc;
> +}
> +
> +static int gvt_service_thread(void *data)
> +{
> +	struct pgt_device *pdev = (struct pgt_device *)data;
> +	int r;
> +
> +	gvt_dbg_core("service thread start, pgt %d", pdev->id);
> +
> +	while (!kthread_should_stop()) {
> +		r = wait_event_interruptible(pdev->service_thread_wq,
> +				kthread_should_stop() || pdev->service_request);
> +
> +		if (kthread_should_stop())
> +			break;
> +
> +		if (gvt_warn_once(r,
> +			"service thread is waken up by unexpected signal."))
> +			continue;
> +	}
> +
> +	return 0;
> +}
> +
> +static void clean_service_thread(struct pgt_device *pdev)
> +{
> +	if (pdev->service_thread) {
> +		kthread_stop(pdev->service_thread);
> +		pdev->service_thread = NULL;
> +	}
> +}
> +
> +static int init_service_thread(struct pgt_device *pdev)
> +{
> +	init_waitqueue_head(&pdev->service_thread_wq);
> +
> +	pdev->service_thread = kthread_run(gvt_service_thread,
> +			pdev, "gvt_service_thread%d", pdev->id);
> +
> +	if (!pdev->service_thread) {
> +		gvt_err("fail to start service thread.");
> +		return -ENOSPC;
> +	}
> +
> +	return 0;
> +}
> +
> +static void clean_pgt_device(struct pgt_device *pdev)
> +{
> +	clean_service_thread(pdev);
> +	clean_initial_mmio_state(pdev);
> +}
> +
> +static int init_pgt_device(struct pgt_device *pdev,
> +	struct drm_i915_private *dev_priv)
> +{
> +	int rc;

	int ret;

> +
> +	rc = init_device_info(pdev);
> +	if (rc)
> +		return rc;
> +
> +	init_initial_cfg_space_state(pdev);
> +
> +	rc = init_initial_mmio_state(pdev);
> +	if (rc)
> +		goto err;
> +
> +	rc = init_service_thread(pdev);
> +	if (rc)
> +		goto err;
> +
> +	return 0;
> +err:
> +	clean_pgt_device(pdev);

Add teardown path, see below.

> +	return rc;
> +}
> +
> +static int post_init_pgt_device(struct pgt_device *pdev)
> +{
> +	return 0;
> +}
> +
> +static void free_pgt_device(struct pgt_device *pdev)
> +{
> +	struct gvt_host *host = &gvt_host;
> +
> +	mutex_lock(&host->device_idr_lock);
> +	idr_remove(&host->device_idr, pdev->id);
> +	mutex_unlock(&host->device_idr_lock);
> +
> +	vfree(pdev);
> +}
> +
> +static struct pgt_device *alloc_pgt_device(struct drm_i915_private *dev_priv)
> +{
> +	struct gvt_host *host = &gvt_host;
> +	struct pgt_device *pdev = NULL;
> +
> +	pdev = vzalloc(sizeof(*pdev));
> +	if (!pdev)
> +		return NULL;

This is a memory error, would like to see this propagated up as

	return ERR_PTR(-ENOMEM);

> +
> +	mutex_lock(&host->device_idr_lock);
> +	pdev->id = idr_alloc(&host->device_idr, pdev, 0, 0, GFP_KERNEL);
> +	mutex_unlock(&host->device_idr_lock);
> +
> +	if (pdev->id < 0) {
> +		gvt_err("fail to allocate pgt device id.");
> +		goto err;
> +	}
> +

Same here, propagate the error.

> +	mutex_init(&pdev->lock);
> +	pdev->dev_priv = dev_priv;
> +	idr_init(&pdev->instance_idr);
> +
> +	return pdev;
> +err:
> +	free_pgt_device(pdev);

I'd like to see a teardown path here. Then free_pgt_device() (or rather
destroy_pgt_device() can expect everything to be initialized and when
it it is called, it doesn't need ifs. This makes the driver code more
robust.

Or are we expecting only partially initialized structs for some reason?

> +	return NULL;
> +}
> +
> +void gvt_destroy_pgt_device(void *private_data)
> +{
> +	struct pgt_device *pdev = (struct pgt_device *)private_data;
> +
> +	clean_pgt_device(pdev);
> +	free_pgt_device(pdev);

Why multiple calls to destroy a device, there's only one alloc still?

> +}
> +
> +/**
> + * gvt_create_pgt_device - create a GVT physical device
> + * @dev: drm device
> + *
> + * This function is called at the initialization stage, to create a physical
> + * GVT device and initialize necessary GVT components for it.
> + *
> + * Returns:
> + * pointer to the pgt_device structure, NULL if failed.
> + */
> +void *gvt_create_pgt_device(struct drm_i915_private *dev_priv)
> +{
> +	struct pgt_device *pdev = NULL;
> +	struct gvt_host *host = &gvt_host;
> +	int rc;
> +
> +	if (!host->initialized && !gvt_init_host()) {
> +		gvt_err("gvt_init_host fail");
> +		return NULL;
> +	}
> +
> +	gvt_dbg_core("create new pgt device, i915 dev_priv: %p", dev_priv);
> +
> +	pdev = alloc_pgt_device(dev_priv);
> +	if (!pdev) {
> +		gvt_err("fail to allocate memory for pgt device.");
> +		goto err;
> +	}
> +
> +	gvt_dbg_core("init pgt device, id %d", pdev->id);
> +
> +	rc = init_pgt_device(pdev, dev_priv);
> +	if (rc) {

Just call the return value variable ret like everywhere.

> +		gvt_err("fail to init physical device state.");
> +		goto err;
> +	}
> +
> +	gvt_dbg_core("pgt device creation done, id %d", pdev->id);
> +
> +	return pdev;
> +err:
> +	if (pdev) {
> +		gvt_destroy_pgt_device(pdev);
> +		pdev = NULL;
> +	}

Proper goto label based teardown path should be used.

err_destroy_pgt:
	gvt_destroy_pgt_device(pdev);
err:
> +	return NULL;
> +}
> +
> +/**
> + * gvt_post_init_pgt_device - post init a GVT physical device
> + * @dev: drm device

Double check the kerneldocs to be correct per arguments of function.

> + *
> + * This function is called at the end of the initialization stage, to
> + * post-initialize a physical GVT device and initialize necessary
> + * GVT components rely on i915 components.
> + *
> + * Returns:
> + * zero on success, non-zero if failed.
> + */
> +int gvt_post_init_pgt_device(void *private_data)
> +{
> +	struct pgt_device *pdev = (struct pgt_device *)private_data;
> +	struct gvt_host *host = &gvt_host;
> +	int rc;
> +
> +	if (!host->initialized) {
> +		gvt_err("gvt_host haven't been initialized.");
> +		return -ENODEV;
> +	}
> +
> +	gvt_dbg_core("post init pgt device %d", pdev->id);
> +
> +	rc = post_init_pgt_device(pdev);
> +	if (rc) {
> +		gvt_err("fail to post init physical device state.");
> +		return rc;
> +	}
> +
> +	return 0;
> +}
> diff --git a/drivers/gpu/drm/i915/gvt/gvt.h b/drivers/gpu/drm/i915/gvt/gvt.h
> new file mode 100644
> index 0000000..d450198
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/gvt/gvt.h
> @@ -0,0 +1,100 @@
> +/*
> + * 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.
> + */
> +
> +#ifndef _GVT_H_
> +#define _GVT_H_
> +
> +#include "i915_drv.h"
> +#include "i915_vgpu.h"
> +
> +#include "debug.h"
> +#include "params.h"
> +#include "reg.h"
> +#include "hypercall.h"
> +#include "mpt.h"
> +
> +#define GVT_MAX_VGPU 8
> +
> +enum {
> +	GVT_HYPERVISOR_TYPE_XEN = 0,
> +	GVT_HYPERVISOR_TYPE_KVM,
> +};
> +
> +struct gvt_host {
> +	bool initialized;
> +	int hypervisor_type;
> +	struct mutex device_idr_lock;
> +	struct idr device_idr;
> +	struct gvt_kernel_dm *kdm;
> +};
> +
> +extern struct gvt_host gvt_host;

-->

> +extern struct gvt_kernel_dm xengt_kdm;
> +extern struct gvt_kernel_dm kvmgt_kdm;

<-- These should likely be declared somewhere in include/ rather than
here.

> +
> +/* Describe the limitation of HW.*/
> +struct gvt_device_info {
> +	u64 max_gtt_gm_sz;
> +	u32 gtt_start_offset;
> +	u32 gtt_end_offset;
> +	u32 max_gtt_size;
> +	u32 gtt_entry_size;
> +	u32 gtt_entry_size_shift;
> +	u32 gmadr_bytes_in_cmd;
> +	u32 mmio_size;
> +};
> +
> +struct vgt_device {
> +	int id;
> +	int vm_id;
> +	struct pgt_device *pdev;
> +	bool warn_untrack;
> +};
> +
> +struct pgt_device {

Comments to this and other structs about what the memebers are.

> +	struct mutex lock;
> +	int id;
> +
> +	struct drm_i915_private *dev_priv;
> +	struct idr instance_idr;
> +
> +	struct gvt_device_info device_info;
> +
> +	u8 initial_cfg_space[GVT_CFG_SPACE_SZ];
> +	u64 bar_size[GVT_BAR_NUM];
> +
> +	u64 gttmmio_base;
> +	void *gttmmio_va;
> +
> +	u64 gmadr_base;
> +	void *gmadr_va;
> +
> +	u32 mmio_size;
> +	u32 reg_num;
> +
> +	wait_queue_head_t service_thread_wq;
> +	struct task_struct *service_thread;
> +	unsigned long service_request;
> +};
> +
> +#endif
> diff --git a/drivers/gpu/drm/i915/gvt/hypercall.h b/drivers/gpu/drm/i915/gvt/hypercall.h
> new file mode 100644
> index 0000000..0a41874
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/gvt/hypercall.h
> @@ -0,0 +1,30 @@
> +/*
> + * 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.
> + */
> +
> +#ifndef _GVT_HYPERCALL_H_
> +#define _GVT_HYPERCALL_H_
> +
> +struct gvt_kernel_dm {
> +};

I would prefer more code introduced here in the initial patch, or this
can be introduced later in the series as whole.

It unnecessarily complicates the review if some files and calls are
introduced with no documentation and implementation and only later
their implementation is added.

I can't really review if using a structure is a good idea if I can't
see the context or implementation of their use.

> +
> +#endif /* _GVT_HYPERCALL_H_ */
> diff --git a/drivers/gpu/drm/i915/gvt/mpt.h b/drivers/gpu/drm/i915/gvt/mpt.h
> new file mode 100644
> index 0000000..e594bb8
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/gvt/mpt.h
> @@ -0,0 +1,34 @@
> +/*
> + * 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.
> + */
> +
> +#ifndef _GVT_MPT_H_
> +#define _GVT_MPT_H_
> +
> +struct vgt_device;
> +
> +static inline bool hypervisor_detect_host(void)
> +{
> +	return false;
> +}

This is also not very reviewable and there's an unnecessary forward
declaration.

> +
> +#endif /* _GVT_MPT_H_ */
> diff --git a/drivers/gpu/drm/i915/gvt/params.c b/drivers/gpu/drm/i915/gvt/params.c
> new file mode 100644
> index 0000000..d381d17
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/gvt/params.c
> @@ -0,0 +1,32 @@
> +/*
> + * 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.
> + */
> +
> +#include "gvt.h"
> +
> +struct gvt_kernel_params gvt = {
> +	.enable = false,
> +	.debug = 0,
> +};
> +
> +module_param_named(gvt_enable, gvt.enable, bool, 0600);

This should just be

	module_param_named(enable, gvt.enable, bool, ...)

otherwise parameter has to be passed at boot time like this:
	
	gvt.gvt_enable=1

Where we want

	gvt.enable=1

Right?

> +MODULE_PARM_DESC(gvt_enable, "Enable Intel GVT-g host support");
> diff --git a/drivers/gpu/drm/i915/gvt/params.h b/drivers/gpu/drm/i915/gvt/params.h
> new file mode 100644
> index 0000000..d2955b9
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/gvt/params.h
> @@ -0,0 +1,34 @@
> +/*
> + * 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.
> + */
> +
> +#ifndef _GVT_PARAMS_H_
> +#define _GVT_PARAMS_H_
> +
> +struct gvt_kernel_params {
> +	bool enable;
> +	int debug;

This member is unused currently, can be dropped.

> +};
> +
> +extern struct gvt_kernel_params gvt;
> +
> +#endif
> diff --git a/drivers/gpu/drm/i915/gvt/reg.h b/drivers/gpu/drm/i915/gvt/reg.h
> new file mode 100644
> index 0000000..d363b74
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/gvt/reg.h
> @@ -0,0 +1,34 @@
> +/*
> + * 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.
> + */
> +
> +#ifndef _GVT_REG_H
> +#define _GVT_REG_H
> +
> +#define GVT_CFG_SPACE_SZ	256
> +#define GVT_BAR_NUM		4
> +
> +#define GVT_REG_CFG_SPACE_BAR0	0x10
> +#define GVT_REG_CFG_SPACE_BAR1	0x18
> +#define GVT_REG_CFG_SPACE_BAR2	0x20

Some documentation here would be great.

> +
> +#endif
> diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
> index 1c6d227..f3bed37 100644
> --- a/drivers/gpu/drm/i915/i915_dma.c
> +++ b/drivers/gpu/drm/i915/i915_dma.c
> @@ -35,6 +35,7 @@
>  #include "intel_drv.h"
>  #include 
>  #include "i915_drv.h"
> +#include "i915_gvt.h"
>  #include "i915_vgpu.h"
>  #include "i915_trace.h"
>  #include 
> @@ -1045,6 +1046,10 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
>  
>  	intel_uncore_init(dev);
>  
> +	ret = intel_gvt_init(dev);
> +	if (ret)
> +		goto out_uncore_fini;
> +
>  	ret = i915_gem_gtt_init(dev);
>  	if (ret)
>  		goto out_uncore_fini;

This needs to become "goto out_gvt_cleanup;"

> @@ -1135,6 +1140,12 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
>  		goto out_power_well;
>  	}
>  
> +	ret = intel_gvt_post_init(dev);
> +	if (ret) {
> +		DRM_ERROR("failed to post init pgt device\n");
> +		goto out_power_well;
> +	}
> +
>  	/*
>  	 * Notify a valid surface after modesetting,
>  	 * when running inside a VM.
> @@ -1177,6 +1188,7 @@ out_gem_unload:
>  out_gtt:
>  	i915_global_gtt_cleanup(dev);

out_gvt_cleanup:

>  out_uncore_fini:
> 
> +	intel_gvt_cleanup(dev);

This needs to be lifted up to its own label ensure proper teardown if
i915_gem_gtt_init() fails.

>  	intel_uncore_fini(dev);
>  	i915_mmio_cleanup(dev);
>  put_bridge:
> @@ -1223,6 +1235,8 @@ int i915_driver_unload(struct drm_device *dev)
>  
>  	intel_modeset_cleanup(dev);
>  
> +	intel_gvt_cleanup(dev);
> +
>  	/*
>  	 * free the memory space allocated for the child device
>  	 * config parsed from VBT
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 20d9dbd..2f897c3 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -1705,6 +1705,10 @@ struct i915_workarounds {
>  	u32 hw_whitelist_count[I915_NUM_RINGS];
>  };
>  
> +struct i915_gvt {
> +	void *pgt_device;
> +};
> +
>  struct i915_virtual_gpu {
>  	bool active;
>  };
> @@ -1744,6 +1748,8 @@ struct drm_i915_private {
>  
>  	struct i915_virtual_gpu vgpu;
>  
> +	struct i915_gvt gvt;
> +
>  	struct intel_guc guc;
>  
>  	struct intel_csr csr;
> @@ -2780,6 +2786,12 @@ void intel_uncore_forcewake_get__locked(struct drm_i915_private *dev_priv,
>  void intel_uncore_forcewake_put__locked(struct drm_i915_private *dev_priv,
>  					enum forcewake_domains domains);
>  void assert_forcewakes_inactive(struct drm_i915_private *dev_priv);
> +
> +static inline bool intel_gvt_active(struct drm_device *dev)
> +{
> +	return to_i915(dev)->gvt.pgt_device ? true : false;
> +}
> +
>  static inline bool intel_vgpu_active(struct drm_device *dev)
>  {
>  	return to_i915(dev)->vgpu.active;
> diff --git a/drivers/gpu/drm/i915/i915_gvt.c b/drivers/gpu/drm/i915/i915_gvt.c
> new file mode 100644
> index 0000000..3ca7232
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/i915_gvt.c
> @@ -0,0 +1,93 @@
> +/*
> + * 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.
> + */
> +
> +#include "i915_drv.h"
> +#include "i915_gvt.h"
> +
> +/**
> + * DOC: Intel GVT-g host support
> + *
> + * Intel GVT-g is a graphics virtualization technology which shares the
> + * GPU among multiple virtual machines on a time-sharing basis. Each
> + * virtual machine is presented a virtual GPU (vGPU), which has equivalent
> + * features as the underlying physical GPU (pGPU), so i915 driver can run
> + * seamlessly in a virtual machine. This file provides the englightments
> + * of GVT and the necessary components used by GVT in i915 driver.
> + */
> +
> +/**
> + * intel_gvt_init - initialize GVT components at the beginning of i915
> + * driver loading.
> + * @dev: drm device *
> + *
> + * This function is called at the beginning of the initialization stage,
> + * to initialize the GVT components that have to be initialized
> + * before HW gets touched by other i915 components.
> + */
> +int intel_gvt_init(struct drm_device *dev)
> +{
> +	struct drm_i915_private *dev_priv = to_i915(dev);
> +
> +	dev_priv->gvt.pgt_device = gvt_create_pgt_device(dev_priv);
> +	if (intel_gvt_active(dev))
> +		DRM_DEBUG_DRIVER("GVT-g is running in host mode\n");
> +
> +	return 0;
> +}
> +
> +/**
> + * intel_gvt_post_init - initialize GVT components at the end of i915
> + * driver loading.
> + * @dev: drm device *
> + *
> + * This function is called at the end of the initialization stage,
> + * to initialize the GVT components that have to be initialized after
> + * other i915 components are ready.
> + */
> +int intel_gvt_post_init(struct drm_device *dev)
> +{
> +	struct drm_i915_private *dev_priv = to_i915(dev);
> +
> +	if (!intel_gvt_active(dev))
> +		return 0;
> +
> +	return gvt_post_init_pgt_device(dev_priv->gvt.pgt_device);
> +}
> +
> +/**
> + * intel_gvt_cleanup - cleanup GVT components when i915 driver is unloading
> + * @dev: drm device *
> + *
> + * This function is called at the i915 driver unloading stage, to shutdown
> + * GVT components and release the related resources.
> + */
> +void intel_gvt_cleanup(struct drm_device *dev)
> +{
> +	struct drm_i915_private *dev_priv = to_i915(dev);
> +
> +	if (!intel_gvt_active(dev))
> +		return;
> +
> +	gvt_destroy_pgt_device(dev_priv->gvt.pgt_device);
> +	dev_priv->gvt.pgt_device = NULL;
> +}
> diff --git a/drivers/gpu/drm/i915/i915_gvt.h b/drivers/gpu/drm/i915/i915_gvt.h
> new file mode 100644
> index 0000000..30cc207
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/i915_gvt.h
> @@ -0,0 +1,49 @@
> +/*
> + * 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.
> + */
> +
> +#ifndef _I915_GVT_H_
> +#define _I915_GVT_H_

I think this file could be intel_gvt.h (all remaining functions are
intel_gvt), and have respective intel_gvt.c file.

> +
> +#ifdef CONFIG_DRM_I915_GVT

Starting here --->

> +extern void *gvt_create_pgt_device(struct drm_i915_private *dev_priv);
> +extern int gvt_post_init_pgt_device(void *data);
> +extern void gvt_destroy_pgt_device(void *data);
> +

<-- to here, these should go to their own include file at
include/drm/i915_gvt.h For an example, see include/drm/i915_drm.h

The respective export symbols then need to be exported, For an example
see;

	EXPORT_SYMBOL_GPL(i915_gpu_raise);

> +extern int intel_gvt_init(struct drm_device *dev);
> +extern int intel_gvt_post_init(struct drm_device *dev);
> +extern void intel_gvt_cleanup(struct drm_device *dev);
> +#else
> +extern int intel_gvt_init(struct drm_device *dev)

These should, by convention, rather be static inline;

static inline int intel_gvt_init(...)

> +{
> +	return 0;
> +}
> +extern int intel_gvt_post_init(struct drm_device *dev)
> +{
> +	return 0;
> +}
> +extern void intel_gvt_cleanup(struct drm_device *dev)
> +{
> +}
> +#endif
> +
> +#endif /* _I915_GVT_H_ */
-- 
Joonas Lahtinen
Open Source Technology Center
Intel Corporation
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [RFCv2 02/14] drm/i915/gvt: Introduce the basic architecture of GVT-g
  2016-02-18 11:42 ` [RFCv2 02/14] drm/i915/gvt: Introduce the basic architecture of GVT-g Zhi Wang
  2016-02-23 12:42   ` Joonas Lahtinen
@ 2016-02-23 12:53   ` Joonas Lahtinen
  2016-02-24  7:50     ` Tian, Kevin
  2016-02-24  8:08   ` Tian, Kevin
  2 siblings, 1 reply; 46+ messages in thread
From: Joonas Lahtinen @ 2016-02-23 12:53 UTC (permalink / raw)
  To: Zhi Wang, intel-gfx, igvt-g
  Cc: daniel.vetter, david.j.cowperthwaite, zhiyuan.lv

A one more note below.

On to, 2016-02-18 at 19:42 +0800, Zhi Wang wrote:
> This patch introduces the very basic framework of GVT-g device model,
> includes basic prototypes, definitions, initialization.
> 
> v2:
> - Introduce i915_gvt.c.
> It's necessary to introduce the stubs between i915 driver and GVT-g host,
> as GVT-g components is configurable in kernel config. When disabled, the
> stubs here do nothing.
> 
> Take Joonas's comments:
> - Replace boolean return value with int.
> - Replace customized info/warn/debug macros with DRM macros.
> - Document all non-static functions like i915.
> - Remove empty and unused functions.
> - Replace magic number with marcos.
> - Set GVT-g in kernel config to "n" by default.
> 
> Signed-off-by: Zhi Wang <zhi.a.wang@intel.com>
> ---
>  drivers/gpu/drm/i915/Kconfig         |  15 ++
>  drivers/gpu/drm/i915/Makefile        |   2 +
>  drivers/gpu/drm/i915/gvt/Makefile    |   5 +
>  drivers/gpu/drm/i915/gvt/debug.h     |  57 +++++
>  drivers/gpu/drm/i915/gvt/gvt.c       | 393 +++++++++++++++++++++++++++++++++++
>  drivers/gpu/drm/i915/gvt/gvt.h       | 100 +++++++++
>  drivers/gpu/drm/i915/gvt/hypercall.h |  30 +++
>  drivers/gpu/drm/i915/gvt/mpt.h       |  34 +++
>  drivers/gpu/drm/i915/gvt/params.c    |  32 +++
>  drivers/gpu/drm/i915/gvt/params.h    |  34 +++
>  drivers/gpu/drm/i915/gvt/reg.h       |  34 +++
>  drivers/gpu/drm/i915/i915_dma.c      |  14 ++
>  drivers/gpu/drm/i915/i915_drv.h      |  12 ++
>  drivers/gpu/drm/i915/i915_gvt.c      |  93 +++++++++
>  drivers/gpu/drm/i915/i915_gvt.h      |  49 +++++
>  15 files changed, 904 insertions(+)
>  create mode 100644 drivers/gpu/drm/i915/gvt/Makefile
>  create mode 100644 drivers/gpu/drm/i915/gvt/debug.h
>  create mode 100644 drivers/gpu/drm/i915/gvt/gvt.c
>  create mode 100644 drivers/gpu/drm/i915/gvt/gvt.h
>  create mode 100644 drivers/gpu/drm/i915/gvt/hypercall.h
>  create mode 100644 drivers/gpu/drm/i915/gvt/mpt.h
>  create mode 100644 drivers/gpu/drm/i915/gvt/params.c
>  create mode 100644 drivers/gpu/drm/i915/gvt/params.h
>  create mode 100644 drivers/gpu/drm/i915/gvt/reg.h
>  create mode 100644 drivers/gpu/drm/i915/i915_gvt.c
>  create mode 100644 drivers/gpu/drm/i915/i915_gvt.h
> 
> diff --git a/drivers/gpu/drm/i915/Kconfig b/drivers/gpu/drm/i915/Kconfig
> index 4c59793..082e77d 100644
> --- a/drivers/gpu/drm/i915/Kconfig
> +++ b/drivers/gpu/drm/i915/Kconfig
> @@ -45,3 +45,18 @@ config DRM_I915_PRELIMINARY_HW_SUPPORT
>  	  option changes the default for that module option.
>  
>  	  If in doubt, say "N".
> +
> +config DRM_I915_GVT
> +        tristate "GVT-g host driver"
> +        depends on DRM_I915
> +        default n
> +        help
> +          Enabling GVT-g mediated graphics passthrough technique for Intel i915
> +          based integrated graphics card. With GVT-g, it's possible to have one
> +          integrated i915 device shared by multiple VMs. Performance critical
> +          opterations such as apperture accesses and ring buffer operations
> +          are pass-throughed to VM, with a minimal set of conflicting resources
> +          (e.g. display settings) mediated by vGT driver. The benefit of vGT
> +          is on both the performance, given that each VM could directly operate
> +          its aperture space and submit commands like running on native, and
> +          the feature completeness, given that a true GEN hardware is exposed.
> diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
> index 0851de07..c65026c 100644
> --- a/drivers/gpu/drm/i915/Makefile
> +++ b/drivers/gpu/drm/i915/Makefile
> @@ -91,6 +91,8 @@ i915-y += dvo_ch7017.o \
>  	  intel_sdvo.o \
>  	  intel_tv.o
>  
> +obj-$(CONFIG_DRM_I915_GVT)  += i915_gvt.o gvt/
> +
>  # virtual gpu code
>  i915-y += i915_vgpu.o
>  
> diff --git a/drivers/gpu/drm/i915/gvt/Makefile b/drivers/gpu/drm/i915/gvt/Makefile
> new file mode 100644
> index 0000000..959305f
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/gvt/Makefile
> @@ -0,0 +1,5 @@
> +GVT_SOURCE := gvt.o params.o
> +
> +ccflags-y                      += -I$(src) -I$(src)/.. -Wall -Werror -Wno-unused-function
> +i915_gvt-y                     := $(GVT_SOURCE)

(This name conflicts with upper level i915_gvt, which I suggested
renaming to intel_gvt.c. A one more reason more so this can be kept as
is).

As the module will be called i915_gvt, I bet the debug prefix should be
changed to reflect that.

So it should look like;

${WHATEVER_DRM_PRINTS} i915-gvt: core: Core debug
${WHATEVER_DRM_PRINTS} i915-gvt: mm: Memory debug

Regards, Joonas

> +obj-$(CONFIG_DRM_I915_GVT)     += i915_gvt.o
> diff --git a/drivers/gpu/drm/i915/gvt/debug.h b/drivers/gpu/drm/i915/gvt/debug.h
> new file mode 100644
> index 0000000..0747f28
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/gvt/debug.h
> @@ -0,0 +1,57 @@
> +/*
> + * 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.
> + */
> +
> +#ifndef __GVT_DEBUG_H__
> +#define __GVT_DEBUG_H__
> +
> +#define gvt_info(fmt, args...) \
> +	DRM_INFO("gvt: "fmt"\n", ##args)
> +
> +#define gvt_err(fmt, args...) \
> +	DRM_ERROR("gvt: "fmt"\n", ##args)
> +
> +#define gvt_warn(condition, fmt, args...) \
> +	WARN((condition), "gvt: "fmt"\n", ##args)
> +
> +#define gvt_warn_once(condition, fmt, args...) \
> +	WARN_ONCE((condition), "gvt: "fmt"\n", ##args)
> +
> +#define gvt_dbg(level, fmt, args...) \
> +	DRM_DEBUG_DRIVER("gvt: "fmt"\n", ##args)
> +
> +enum {
> +	GVT_DBG_CORE = (1 << 0),
> +	GVT_DBG_MM = (1 << 1),
> +	GVT_DBG_IRQ = (1 << 2),
> +};
> +
> +#define gvt_dbg_core(fmt, args...) \
> +	gvt_dbg(GVT_DBG_CORE, fmt, ##args)
> +
> +#define gvt_dbg_mm(fmt, args...) \
> +	gvt_dbg(GVT_DBG_MM, fmt, ##args)
> +
> +#define gvt_dbg_irq(fmt, args...) \
> +	gvt_dbg(GVT_DBG_IRQ, fmt, ##args)
> +
> +#endif
> diff --git a/drivers/gpu/drm/i915/gvt/gvt.c b/drivers/gpu/drm/i915/gvt/gvt.c
> new file mode 100644
> index 0000000..52cfa32
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/gvt/gvt.c
> @@ -0,0 +1,393 @@
> +/*
> + * 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.
> + */
> +
> +#include 
> +#include 
> +#include 
> +
> +#include "gvt.h"
> +
> +struct gvt_host gvt_host;
> +
> +static const char * const supported_hypervisors[] = {
> +	[GVT_HYPERVISOR_TYPE_XEN] = "Xen Hypervisor",
> +	[GVT_HYPERVISOR_TYPE_KVM] = "KVM",
> +};
> +
> +static int gvt_init_host(void)
> +{
> +	struct gvt_host *host = &gvt_host;
> +
> +	if (!gvt.enable) {
> +		gvt_dbg_core("GVT-g has been disabled by kernel parameter");
> +		return -EINVAL;
> +	}
> +
> +	if (host->initialized) {
> +		gvt_err("GVT-g has already been initialized!");
> +		return -EINVAL;
> +	}
> +
> +	/* Xen DOM U */
> +	if (xen_domain() && !xen_initial_domain())
> +		return -ENODEV;
> +
> +	if (xen_initial_domain()) {
> +		/* Xen Dom0 */
> +		host->kdm = try_then_request_module(
> +				symbol_get(xengt_kdm), "xengt");
> +		host->hypervisor_type = GVT_HYPERVISOR_TYPE_XEN;
> +	} else {
> +		/* not in Xen. Try KVMGT */
> +		host->kdm = try_then_request_module(
> +				symbol_get(kvmgt_kdm), "kvm");
> +		host->hypervisor_type = GVT_HYPERVISOR_TYPE_KVM;
> +	}
> +
> +	if (!host->kdm)
> +		return -EINVAL;
> +
> +	if (!hypervisor_detect_host())
> +		return -ENODEV;
> +
> +	gvt_info("Running with hypervisor %s in host mode",
> +			supported_hypervisors[host->hypervisor_type]);
> +
> +	idr_init(&host->device_idr);
> +	mutex_init(&host->device_idr_lock);
> +
> +	host->initialized = true;
> +	return 0;
> +}
> +
> +static int init_device_info(struct pgt_device *pdev)
> +{
> +	struct gvt_device_info *info = &pdev->device_info;
> +
> +	if (!IS_BROADWELL(pdev->dev_priv)) {
> +		DRM_DEBUG_DRIVER("Unsupported GEN device");
> +		return -ENODEV;
> +	}
> +
> +	if (IS_BROADWELL(pdev->dev_priv)) {
> +		info->max_gtt_gm_sz = (1ULL << 32); /* 4GB */
> +		/*
> +		 * The layout of BAR0 in BDW:
> +		 * |< - MMIO 2MB ->|<- Reserved 6MB ->|<- MAX GTT 8MB->|
> +		 *
> +		 * GTT offset in BAR0 starts from 8MB to 16MB, and
> +		 * Whatever GTT size is configured in BIOS,
> +		 * the size of BAR0 is always 16MB. The actual configured
> +		 * GTT size can be found in GMCH_CTRL.
> +		 */
> +		info->gtt_start_offset = (1UL << 23); /* 8MB */
> +		info->max_gtt_size = (1UL << 23); /* 8MB */
> +		info->gtt_entry_size = 8;
> +		info->gtt_entry_size_shift = 3;
> +		info->gmadr_bytes_in_cmd = 8;
> +		info->mmio_size = 2 * 1024 * 1024; /* 2MB */
> +	}
> +
> +	return 0;
> +}
> +
> +static void init_initial_cfg_space_state(struct pgt_device *pdev)
> +{
> +	struct pci_dev *pci_dev = pdev->dev_priv->dev->pdev;
> +	int i;
> +
> +	gvt_dbg_core("init initial cfg space, id %d", pdev->id);
> +
> +	for (i = 0; i < GVT_CFG_SPACE_SZ; i += 4)
> +		pci_read_config_dword(pci_dev, i,
> +				(u32 *)&pdev->initial_cfg_space[i]);
> +
> +	for (i = 0; i < GVT_BAR_NUM; i++) {
> +		pdev->bar_size[i] = pci_resource_len(pci_dev, i * 2);
> +		gvt_dbg_core("bar %d size: %llx", i, pdev->bar_size[i]);
> +	}
> +}
> +
> +static void clean_initial_mmio_state(struct pgt_device *pdev)
> +{
> +	if (pdev->gttmmio_va) {
> +		iounmap(pdev->gttmmio_va);
> +		pdev->gttmmio_va = NULL;
> +	}
> +
> +	if (pdev->gmadr_va) {
> +		iounmap(pdev->gmadr_va);
> +		pdev->gmadr_va = NULL;
> +	}
> +}
> +
> +static int init_initial_mmio_state(struct pgt_device *pdev)
> +{
> +	struct gvt_device_info *info = &pdev->device_info;
> +
> +	u64 bar0, bar1;
> +	int rc;
> +
> +	gvt_dbg_core("init initial mmio state, id %d", pdev->id);
> +
> +	bar0 = *(u64 *)&pdev->initial_cfg_space[GVT_REG_CFG_SPACE_BAR0];
> +	bar1 = *(u64 *)&pdev->initial_cfg_space[GVT_REG_CFG_SPACE_BAR1];
> +
> +	pdev->gttmmio_base = bar0 & ~0xf;
> +	pdev->reg_num = info->mmio_size / 4;
> +	pdev->gmadr_base = bar1 & ~0xf;
> +
> +	pdev->gttmmio_va = ioremap(pdev->gttmmio_base, pdev->bar_size[0]);
> +	if (!pdev->gttmmio_va) {
> +		gvt_err("fail to map GTTMMIO BAR.");
> +		return -EFAULT;
> +	}
> +
> +	pdev->gmadr_va = ioremap(pdev->gmadr_base, pdev->bar_size[2]);
> +	if (!pdev->gmadr_va) {
> +		gvt_err("fail to map GMADR BAR.");
> +		rc = -EFAULT;
> +		goto err;
> +	}
> +
> +	gvt_dbg_core("bar0: 0x%llx, bar1: 0x%llx", bar0, bar1);
> +	gvt_dbg_core("mmio size: %x", pdev->mmio_size);
> +	gvt_dbg_core("gttmmio: 0x%llx, gmadr: 0x%llx", pdev->gttmmio_base,
> +			pdev->gmadr_base);
> +	gvt_dbg_core("gttmmio_va: %p", pdev->gttmmio_va);
> +	gvt_dbg_core("gmadr_va: %p", pdev->gmadr_va);
> +
> +	return 0;
> +err:
> +	clean_initial_mmio_state(pdev);
> +	return rc;
> +}
> +
> +static int gvt_service_thread(void *data)
> +{
> +	struct pgt_device *pdev = (struct pgt_device *)data;
> +	int r;
> +
> +	gvt_dbg_core("service thread start, pgt %d", pdev->id);
> +
> +	while (!kthread_should_stop()) {
> +		r = wait_event_interruptible(pdev->service_thread_wq,
> +				kthread_should_stop() || pdev->service_request);
> +
> +		if (kthread_should_stop())
> +			break;
> +
> +		if (gvt_warn_once(r,
> +			"service thread is waken up by unexpected signal."))
> +			continue;
> +	}
> +
> +	return 0;
> +}
> +
> +static void clean_service_thread(struct pgt_device *pdev)
> +{
> +	if (pdev->service_thread) {
> +		kthread_stop(pdev->service_thread);
> +		pdev->service_thread = NULL;
> +	}
> +}
> +
> +static int init_service_thread(struct pgt_device *pdev)
> +{
> +	init_waitqueue_head(&pdev->service_thread_wq);
> +
> +	pdev->service_thread = kthread_run(gvt_service_thread,
> +			pdev, "gvt_service_thread%d", pdev->id);
> +
> +	if (!pdev->service_thread) {
> +		gvt_err("fail to start service thread.");
> +		return -ENOSPC;
> +	}
> +
> +	return 0;
> +}
> +
> +static void clean_pgt_device(struct pgt_device *pdev)
> +{
> +	clean_service_thread(pdev);
> +	clean_initial_mmio_state(pdev);
> +}
> +
> +static int init_pgt_device(struct pgt_device *pdev,
> +	struct drm_i915_private *dev_priv)
> +{
> +	int rc;
> +
> +	rc = init_device_info(pdev);
> +	if (rc)
> +		return rc;
> +
> +	init_initial_cfg_space_state(pdev);
> +
> +	rc = init_initial_mmio_state(pdev);
> +	if (rc)
> +		goto err;
> +
> +	rc = init_service_thread(pdev);
> +	if (rc)
> +		goto err;
> +
> +	return 0;
> +err:
> +	clean_pgt_device(pdev);
> +	return rc;
> +}
> +
> +static int post_init_pgt_device(struct pgt_device *pdev)
> +{
> +	return 0;
> +}
> +
> +static void free_pgt_device(struct pgt_device *pdev)
> +{
> +	struct gvt_host *host = &gvt_host;
> +
> +	mutex_lock(&host->device_idr_lock);
> +	idr_remove(&host->device_idr, pdev->id);
> +	mutex_unlock(&host->device_idr_lock);
> +
> +	vfree(pdev);
> +}
> +
> +static struct pgt_device *alloc_pgt_device(struct drm_i915_private *dev_priv)
> +{
> +	struct gvt_host *host = &gvt_host;
> +	struct pgt_device *pdev = NULL;
> +
> +	pdev = vzalloc(sizeof(*pdev));
> +	if (!pdev)
> +		return NULL;
> +
> +	mutex_lock(&host->device_idr_lock);
> +	pdev->id = idr_alloc(&host->device_idr, pdev, 0, 0, GFP_KERNEL);
> +	mutex_unlock(&host->device_idr_lock);
> +
> +	if (pdev->id < 0) {
> +		gvt_err("fail to allocate pgt device id.");
> +		goto err;
> +	}
> +
> +	mutex_init(&pdev->lock);
> +	pdev->dev_priv = dev_priv;
> +	idr_init(&pdev->instance_idr);
> +
> +	return pdev;
> +err:
> +	free_pgt_device(pdev);
> +	return NULL;
> +}
> +
> +void gvt_destroy_pgt_device(void *private_data)
> +{
> +	struct pgt_device *pdev = (struct pgt_device *)private_data;
> +
> +	clean_pgt_device(pdev);
> +	free_pgt_device(pdev);
> +}
> +
> +/**
> + * gvt_create_pgt_device - create a GVT physical device
> + * @dev: drm device
> + *
> + * This function is called at the initialization stage, to create a physical
> + * GVT device and initialize necessary GVT components for it.
> + *
> + * Returns:
> + * pointer to the pgt_device structure, NULL if failed.
> + */
> +void *gvt_create_pgt_device(struct drm_i915_private *dev_priv)
> +{
> +	struct pgt_device *pdev = NULL;
> +	struct gvt_host *host = &gvt_host;
> +	int rc;
> +
> +	if (!host->initialized && !gvt_init_host()) {
> +		gvt_err("gvt_init_host fail");
> +		return NULL;
> +	}
> +
> +	gvt_dbg_core("create new pgt device, i915 dev_priv: %p", dev_priv);
> +
> +	pdev = alloc_pgt_device(dev_priv);
> +	if (!pdev) {
> +		gvt_err("fail to allocate memory for pgt device.");
> +		goto err;
> +	}
> +
> +	gvt_dbg_core("init pgt device, id %d", pdev->id);
> +
> +	rc = init_pgt_device(pdev, dev_priv);
> +	if (rc) {
> +		gvt_err("fail to init physical device state.");
> +		goto err;
> +	}
> +
> +	gvt_dbg_core("pgt device creation done, id %d", pdev->id);
> +
> +	return pdev;
> +err:
> +	if (pdev) {
> +		gvt_destroy_pgt_device(pdev);
> +		pdev = NULL;
> +	}
> +	return NULL;
> +}
> +
> +/**
> + * gvt_post_init_pgt_device - post init a GVT physical device
> + * @dev: drm device
> + *
> + * This function is called at the end of the initialization stage, to
> + * post-initialize a physical GVT device and initialize necessary
> + * GVT components rely on i915 components.
> + *
> + * Returns:
> + * zero on success, non-zero if failed.
> + */
> +int gvt_post_init_pgt_device(void *private_data)
> +{
> +	struct pgt_device *pdev = (struct pgt_device *)private_data;
> +	struct gvt_host *host = &gvt_host;
> +	int rc;
> +
> +	if (!host->initialized) {
> +		gvt_err("gvt_host haven't been initialized.");
> +		return -ENODEV;
> +	}
> +
> +	gvt_dbg_core("post init pgt device %d", pdev->id);
> +
> +	rc = post_init_pgt_device(pdev);
> +	if (rc) {
> +		gvt_err("fail to post init physical device state.");
> +		return rc;
> +	}
> +
> +	return 0;
> +}
> diff --git a/drivers/gpu/drm/i915/gvt/gvt.h b/drivers/gpu/drm/i915/gvt/gvt.h
> new file mode 100644
> index 0000000..d450198
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/gvt/gvt.h
> @@ -0,0 +1,100 @@
> +/*
> + * 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.
> + */
> +
> +#ifndef _GVT_H_
> +#define _GVT_H_
> +
> +#include "i915_drv.h"
> +#include "i915_vgpu.h"
> +
> +#include "debug.h"
> +#include "params.h"
> +#include "reg.h"
> +#include "hypercall.h"
> +#include "mpt.h"
> +
> +#define GVT_MAX_VGPU 8
> +
> +enum {
> +	GVT_HYPERVISOR_TYPE_XEN = 0,
> +	GVT_HYPERVISOR_TYPE_KVM,
> +};
> +
> +struct gvt_host {
> +	bool initialized;
> +	int hypervisor_type;
> +	struct mutex device_idr_lock;
> +	struct idr device_idr;
> +	struct gvt_kernel_dm *kdm;
> +};
> +
> +extern struct gvt_host gvt_host;
> +extern struct gvt_kernel_dm xengt_kdm;
> +extern struct gvt_kernel_dm kvmgt_kdm;
> +
> +/* Describe the limitation of HW.*/
> +struct gvt_device_info {
> +	u64 max_gtt_gm_sz;
> +	u32 gtt_start_offset;
> +	u32 gtt_end_offset;
> +	u32 max_gtt_size;
> +	u32 gtt_entry_size;
> +	u32 gtt_entry_size_shift;
> +	u32 gmadr_bytes_in_cmd;
> +	u32 mmio_size;
> +};
> +
> +struct vgt_device {
> +	int id;
> +	int vm_id;
> +	struct pgt_device *pdev;
> +	bool warn_untrack;
> +};
> +
> +struct pgt_device {
> +	struct mutex lock;
> +	int id;
> +
> +	struct drm_i915_private *dev_priv;
> +	struct idr instance_idr;
> +
> +	struct gvt_device_info device_info;
> +
> +	u8 initial_cfg_space[GVT_CFG_SPACE_SZ];
> +	u64 bar_size[GVT_BAR_NUM];
> +
> +	u64 gttmmio_base;
> +	void *gttmmio_va;
> +
> +	u64 gmadr_base;
> +	void *gmadr_va;
> +
> +	u32 mmio_size;
> +	u32 reg_num;
> +
> +	wait_queue_head_t service_thread_wq;
> +	struct task_struct *service_thread;
> +	unsigned long service_request;
> +};
> +
> +#endif
> diff --git a/drivers/gpu/drm/i915/gvt/hypercall.h b/drivers/gpu/drm/i915/gvt/hypercall.h
> new file mode 100644
> index 0000000..0a41874
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/gvt/hypercall.h
> @@ -0,0 +1,30 @@
> +/*
> + * 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.
> + */
> +
> +#ifndef _GVT_HYPERCALL_H_
> +#define _GVT_HYPERCALL_H_
> +
> +struct gvt_kernel_dm {
> +};
> +
> +#endif /* _GVT_HYPERCALL_H_ */
> diff --git a/drivers/gpu/drm/i915/gvt/mpt.h b/drivers/gpu/drm/i915/gvt/mpt.h
> new file mode 100644
> index 0000000..e594bb8
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/gvt/mpt.h
> @@ -0,0 +1,34 @@
> +/*
> + * 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.
> + */
> +
> +#ifndef _GVT_MPT_H_
> +#define _GVT_MPT_H_
> +
> +struct vgt_device;
> +
> +static inline bool hypervisor_detect_host(void)
> +{
> +	return false;
> +}
> +
> +#endif /* _GVT_MPT_H_ */
> diff --git a/drivers/gpu/drm/i915/gvt/params.c b/drivers/gpu/drm/i915/gvt/params.c
> new file mode 100644
> index 0000000..d381d17
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/gvt/params.c
> @@ -0,0 +1,32 @@
> +/*
> + * 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.
> + */
> +
> +#include "gvt.h"
> +
> +struct gvt_kernel_params gvt = {
> +	.enable = false,
> +	.debug = 0,
> +};
> +
> +module_param_named(gvt_enable, gvt.enable, bool, 0600);
> +MODULE_PARM_DESC(gvt_enable, "Enable Intel GVT-g host support");
> diff --git a/drivers/gpu/drm/i915/gvt/params.h b/drivers/gpu/drm/i915/gvt/params.h
> new file mode 100644
> index 0000000..d2955b9
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/gvt/params.h
> @@ -0,0 +1,34 @@
> +/*
> + * 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.
> + */
> +
> +#ifndef _GVT_PARAMS_H_
> +#define _GVT_PARAMS_H_
> +
> +struct gvt_kernel_params {
> +	bool enable;
> +	int debug;
> +};
> +
> +extern struct gvt_kernel_params gvt;
> +
> +#endif
> diff --git a/drivers/gpu/drm/i915/gvt/reg.h b/drivers/gpu/drm/i915/gvt/reg.h
> new file mode 100644
> index 0000000..d363b74
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/gvt/reg.h
> @@ -0,0 +1,34 @@
> +/*
> + * 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.
> + */
> +
> +#ifndef _GVT_REG_H
> +#define _GVT_REG_H
> +
> +#define GVT_CFG_SPACE_SZ	256
> +#define GVT_BAR_NUM		4
> +
> +#define GVT_REG_CFG_SPACE_BAR0	0x10
> +#define GVT_REG_CFG_SPACE_BAR1	0x18
> +#define GVT_REG_CFG_SPACE_BAR2	0x20
> +
> +#endif
> diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
> index 1c6d227..f3bed37 100644
> --- a/drivers/gpu/drm/i915/i915_dma.c
> +++ b/drivers/gpu/drm/i915/i915_dma.c
> @@ -35,6 +35,7 @@
>  #include "intel_drv.h"
>  #include 
>  #include "i915_drv.h"
> +#include "i915_gvt.h"
>  #include "i915_vgpu.h"
>  #include "i915_trace.h"
>  #include 
> @@ -1045,6 +1046,10 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
>  
>  	intel_uncore_init(dev);
>  
> +	ret = intel_gvt_init(dev);
> +	if (ret)
> +		goto out_uncore_fini;
> +
>  	ret = i915_gem_gtt_init(dev);
>  	if (ret)
>  		goto out_uncore_fini;
> @@ -1135,6 +1140,12 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
>  		goto out_power_well;
>  	}
>  
> +	ret = intel_gvt_post_init(dev);
> +	if (ret) {
> +		DRM_ERROR("failed to post init pgt device\n");
> +		goto out_power_well;
> +	}
> +
>  	/*
>  	 * Notify a valid surface after modesetting,
>  	 * when running inside a VM.
> @@ -1177,6 +1188,7 @@ out_gem_unload:
>  out_gtt:
>  	i915_global_gtt_cleanup(dev);
>  out_uncore_fini:
> +	intel_gvt_cleanup(dev);
>  	intel_uncore_fini(dev);
>  	i915_mmio_cleanup(dev);
>  put_bridge:
> @@ -1223,6 +1235,8 @@ int i915_driver_unload(struct drm_device *dev)
>  
>  	intel_modeset_cleanup(dev);
>  
> +	intel_gvt_cleanup(dev);
> +
>  	/*
>  	 * free the memory space allocated for the child device
>  	 * config parsed from VBT
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 20d9dbd..2f897c3 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -1705,6 +1705,10 @@ struct i915_workarounds {
>  	u32 hw_whitelist_count[I915_NUM_RINGS];
>  };
>  
> +struct i915_gvt {
> +	void *pgt_device;
> +};
> +
>  struct i915_virtual_gpu {
>  	bool active;
>  };
> @@ -1744,6 +1748,8 @@ struct drm_i915_private {
>  
>  	struct i915_virtual_gpu vgpu;
>  
> +	struct i915_gvt gvt;
> +
>  	struct intel_guc guc;
>  
>  	struct intel_csr csr;
> @@ -2780,6 +2786,12 @@ void intel_uncore_forcewake_get__locked(struct drm_i915_private *dev_priv,
>  void intel_uncore_forcewake_put__locked(struct drm_i915_private *dev_priv,
>  					enum forcewake_domains domains);
>  void assert_forcewakes_inactive(struct drm_i915_private *dev_priv);
> +
> +static inline bool intel_gvt_active(struct drm_device *dev)
> +{
> +	return to_i915(dev)->gvt.pgt_device ? true : false;
> +}
> +
>  static inline bool intel_vgpu_active(struct drm_device *dev)
>  {
>  	return to_i915(dev)->vgpu.active;
> diff --git a/drivers/gpu/drm/i915/i915_gvt.c b/drivers/gpu/drm/i915/i915_gvt.c
> new file mode 100644
> index 0000000..3ca7232
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/i915_gvt.c
> @@ -0,0 +1,93 @@
> +/*
> + * 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.
> + */
> +
> +#include "i915_drv.h"
> +#include "i915_gvt.h"
> +
> +/**
> + * DOC: Intel GVT-g host support
> + *
> + * Intel GVT-g is a graphics virtualization technology which shares the
> + * GPU among multiple virtual machines on a time-sharing basis. Each
> + * virtual machine is presented a virtual GPU (vGPU), which has equivalent
> + * features as the underlying physical GPU (pGPU), so i915 driver can run
> + * seamlessly in a virtual machine. This file provides the englightments
> + * of GVT and the necessary components used by GVT in i915 driver.
> + */
> +
> +/**
> + * intel_gvt_init - initialize GVT components at the beginning of i915
> + * driver loading.
> + * @dev: drm device *
> + *
> + * This function is called at the beginning of the initialization stage,
> + * to initialize the GVT components that have to be initialized
> + * before HW gets touched by other i915 components.
> + */
> +int intel_gvt_init(struct drm_device *dev)
> +{
> +	struct drm_i915_private *dev_priv = to_i915(dev);
> +
> +	dev_priv->gvt.pgt_device = gvt_create_pgt_device(dev_priv);
> +	if (intel_gvt_active(dev))
> +		DRM_DEBUG_DRIVER("GVT-g is running in host mode\n");
> +
> +	return 0;
> +}
> +
> +/**
> + * intel_gvt_post_init - initialize GVT components at the end of i915
> + * driver loading.
> + * @dev: drm device *
> + *
> + * This function is called at the end of the initialization stage,
> + * to initialize the GVT components that have to be initialized after
> + * other i915 components are ready.
> + */
> +int intel_gvt_post_init(struct drm_device *dev)
> +{
> +	struct drm_i915_private *dev_priv = to_i915(dev);
> +
> +	if (!intel_gvt_active(dev))
> +		return 0;
> +
> +	return gvt_post_init_pgt_device(dev_priv->gvt.pgt_device);
> +}
> +
> +/**
> + * intel_gvt_cleanup - cleanup GVT components when i915 driver is unloading
> + * @dev: drm device *
> + *
> + * This function is called at the i915 driver unloading stage, to shutdown
> + * GVT components and release the related resources.
> + */
> +void intel_gvt_cleanup(struct drm_device *dev)
> +{
> +	struct drm_i915_private *dev_priv = to_i915(dev);
> +
> +	if (!intel_gvt_active(dev))
> +		return;
> +
> +	gvt_destroy_pgt_device(dev_priv->gvt.pgt_device);
> +	dev_priv->gvt.pgt_device = NULL;
> +}
> diff --git a/drivers/gpu/drm/i915/i915_gvt.h b/drivers/gpu/drm/i915/i915_gvt.h
> new file mode 100644
> index 0000000..30cc207
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/i915_gvt.h
> @@ -0,0 +1,49 @@
> +/*
> + * 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.
> + */
> +
> +#ifndef _I915_GVT_H_
> +#define _I915_GVT_H_
> +
> +#ifdef CONFIG_DRM_I915_GVT
> +extern void *gvt_create_pgt_device(struct drm_i915_private *dev_priv);
> +extern int gvt_post_init_pgt_device(void *data);
> +extern void gvt_destroy_pgt_device(void *data);
> +
> +extern int intel_gvt_init(struct drm_device *dev);
> +extern int intel_gvt_post_init(struct drm_device *dev);
> +extern void intel_gvt_cleanup(struct drm_device *dev);
> +#else
> +extern int intel_gvt_init(struct drm_device *dev)
> +{
> +	return 0;
> +}
> +extern int intel_gvt_post_init(struct drm_device *dev)
> +{
> +	return 0;
> +}
> +extern void intel_gvt_cleanup(struct drm_device *dev)
> +{
> +}
> +#endif
> +
> +#endif /* _I915_GVT_H_ */
-- 
Joonas Lahtinen
Open Source Technology Center
Intel Corporation
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [RFCv2 03/14] drm/i915: Introduce host graphics memory/fence partition for GVT-g
  2016-02-18 11:42 ` [RFCv2 03/14] drm/i915: Introduce host graphics memory/fence partition for GVT-g Zhi Wang
@ 2016-02-23 13:16   ` Joonas Lahtinen
  2016-02-23 13:23     ` Zhi Wang
  2016-02-23 13:26     ` Joonas Lahtinen
  2016-02-24  8:22   ` Tian, Kevin
  1 sibling, 2 replies; 46+ messages in thread
From: Joonas Lahtinen @ 2016-02-23 13:16 UTC (permalink / raw)
  To: Zhi Wang, intel-gfx, igvt-g
  Cc: daniel.vetter, david.j.cowperthwaite, zhiyuan.lv

On to, 2016-02-18 at 19:42 +0800, Zhi Wang wrote:
> From: Bing Niu <bing.niu@intel.com>
> 
> This patch introduces host graphics memory/fence partition when GVT-g
> is enabled.
> 
> Under GVT-g, i915 host driver only owned limited graphics resources,
> others are managed by GVT-g resource allocator and kept for other vGPUs.
> 
> v2:
> - Address all coding-style comments from Joonas previously.
> - Fix errors and warnning reported by checkpatch.pl. (Joonas)
> - Move the graphs into the header files. (Daniel)
> 
> Signed-off-by: Bing Niu <bing.niu@intel.com>
> Signed-off-by: Zhi Wang <zhi.a.wang@intel.com>
> ---
>  drivers/gpu/drm/i915/gvt/gvt.c      |  4 ++++
>  drivers/gpu/drm/i915/gvt/params.c   | 12 ++++++++++++
>  drivers/gpu/drm/i915/gvt/params.h   |  3 +++
>  drivers/gpu/drm/i915/i915_drv.h     | 35 +++++++++++++++++++++++++++++++++++
>  drivers/gpu/drm/i915/i915_gem.c     |  4 +++-
>  drivers/gpu/drm/i915/i915_gem_gtt.c |  4 ++--
>  drivers/gpu/drm/i915/i915_vgpu.c    | 21 +++++++++++++++++----
>  7 files changed, 76 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/gvt/gvt.c b/drivers/gpu/drm/i915/gvt/gvt.c
> index 52cfa32..2099b7e 100644
> --- a/drivers/gpu/drm/i915/gvt/gvt.c
> +++ b/drivers/gpu/drm/i915/gvt/gvt.c
> @@ -348,6 +348,10 @@ void *gvt_create_pgt_device(struct drm_i915_private *dev_priv)
>  		goto err;
>  	}
>  
> +	dev_priv->gvt.host_fence_sz = gvt.host_fence_sz;
> +	dev_priv->gvt.host_low_gm_sz_in_mb = gvt.host_low_gm_sz;
> +	dev_priv->gvt.host_high_gm_sz_in_mb = gvt.host_high_gm_sz;

I'm thinking, could we expose the pgt_device struct (at least
partially, and then have a PIMPL pattern), to avoid this kind of
duplication of declarations and unnecessary copies between i915 and
i915_gvt modules?

It's little rough that the gvt driver writes to i915_private struct.
I'd rather see that gvt.host_fence_sz and other variables get sanitized
and then written to pgt_device (maybe the public part would be
i915_pgt_device) and used by gvt and i915 code.

Was this ever considered?

> +
>  	gvt_dbg_core("pgt device creation done, id %d", pdev->id);
>  
>  	return pdev;
> diff --git a/drivers/gpu/drm/i915/gvt/params.c b/drivers/gpu/drm/i915/gvt/params.c
> index d381d17..75195fd 100644
> --- a/drivers/gpu/drm/i915/gvt/params.c
> +++ b/drivers/gpu/drm/i915/gvt/params.c
> @@ -26,7 +26,19 @@
>  struct gvt_kernel_params gvt = {
>  	.enable = false,
>  	.debug = 0,
> +	.host_low_gm_sz = 96,	/* in MB */
> +	.host_high_gm_sz = 384, /* in MB */
> +	.host_fence_sz = 4,
>  };
>  
>  module_param_named(gvt_enable, gvt.enable, bool, 0600);
>  MODULE_PARM_DESC(gvt_enable, "Enable Intel GVT-g host support");
> +
> +module_param_named(gvt_host_low_gm_sz, gvt.host_low_gm_sz, int, 0600);
> +MODULE_PARM_DESC(gvt_host_low_gm_sz, "Amount of aperture size of host (in MB)");

As i915_gvt will be the host module, "gvt_host" can be removed so the
module parameters become;

i915_gvt.low_gm_sz instead of i915_gvt.gvt_host_low_gm_sz

Also should these be _unsafe parameters because I bet they can make the
machine go crazy if wrong?

> +
> +module_param_named(gvt_host_high_gm_sz, gvt.host_high_gm_sz, int, 0600);
> +MODULE_PARM_DESC(gvt_host_high_gm_sz, "Amount of high memory size of host (in MB)");
> +
> +module_param_named(gvt_host_fence_sz, gvt.host_fence_sz, int, 0600);
> +MODULE_PARM_DESC(gvt_host_fence_sz, "Amount of fence size of host (in MB)");
> diff --git a/drivers/gpu/drm/i915/gvt/params.h b/drivers/gpu/drm/i915/gvt/params.h
> index d2955b9..f4e9356 100644
> --- a/drivers/gpu/drm/i915/gvt/params.h
> +++ b/drivers/gpu/drm/i915/gvt/params.h
> @@ -27,6 +27,9 @@
>  struct gvt_kernel_params {
>  	bool enable;
>  	int debug;
> +	int host_low_gm_sz;
> +	int host_high_gm_sz;
> +	int host_fence_sz;
>  };
>  
>  extern struct gvt_kernel_params gvt;
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 2f897c3..1fd5575 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -1705,8 +1705,43 @@ struct i915_workarounds {
>  	u32 hw_whitelist_count[I915_NUM_RINGS];
>  };
>  
> +/*
> + * Under GVT-g, i915 host driver only owned limited graphics resources,
> + * others are managed by GVT-g resource allocator and kept for other vGPUs.
> + *
> + * For graphics memory space partition, a typical layout looks like:
> + *
> + * +-------+-----------------------+------+-----------------------+
> + * |* Host |   *GVT-g Resource     |* Host|   *GVT-g Resource     |
> + * | Owned |   Allocator Managed   | Owned|   Allocator Managed   |
> + * |       |                       |      |                       |
> + * +---------------+-------+----------------------+-------+-------+
> + * |       |       |       |       |      |       |       |       |
> + * | i915  | vm 1  | vm 2  | vm 3  | i915 | vm 1  | vm 2  | vm 3  |
> + * |       |       |       |       |      |       |       |       |
> + * +-------+-------+-------+--------------+-------+-------+-------+
> + * |           Aperture            |            Hidden            |
> + * +-------------------------------+------------------------------+
> + * |                       GGTT memory space                      |
> + * +--------------------------------------------------------------+
> + *
> + * Similar with fence registers partition:
> + *
> + * +------ +-----------------------+
> + * | * Host|    GVT-g Resource     |
> + * | Owned |   Allocator Managed   +
> + * 0       |                       31
> + * +---------------+-------+-------+
> + * |       |       |       |       |
> + * | i915  | vm 1  | vm 2  | vm 3  |
> + * |       |       |       |       |
> + * +-------+-------+-------+-------+
> + */
>  struct i915_gvt {
>  	void *pgt_device;
> +	u32 host_low_gm_sz_in_mb;
> +	u32 host_high_gm_sz_in_mb;
> +	int host_fence_sz;
>  };
>  
>  struct i915_virtual_gpu {
> diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
> index f68f346..1c0006a 100644
> --- a/drivers/gpu/drm/i915/i915_gem.c
> +++ b/drivers/gpu/drm/i915/i915_gem.c
> @@ -5078,7 +5078,9 @@ i915_gem_load_init(struct drm_device *dev)
>  	else
>  		dev_priv->num_fence_regs = 8;
>  
> -	if (intel_vgpu_active(dev))
> +	if (intel_gvt_active(dev))
> +		dev_priv->num_fence_regs = dev_priv->gvt.host_fence_sz;
> +	else if (intel_vgpu_active(dev))
>  		dev_priv->num_fence_regs =
>  				I915_READ(vgtif_reg(avail_rs.fence_num));
>  
> diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
> index 9127f8f..de09dd4 100644
> --- a/drivers/gpu/drm/i915/i915_gem_gtt.c
> +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
> @@ -2734,7 +2734,7 @@ static int i915_gem_setup_global_gtt(struct drm_device *dev,
>  	i915_address_space_init(ggtt_vm, dev_priv);
>  	ggtt_vm->total += PAGE_SIZE;
>  
> -	if (intel_vgpu_active(dev)) {
> +	if (intel_vgpu_active(dev) || intel_gvt_active(dev)) {
>  		ret = intel_vgt_balloon(dev);
>  		if (ret)
>  			return ret;
> @@ -2833,7 +2833,7 @@ void i915_global_gtt_cleanup(struct drm_device *dev)
>  	i915_gem_cleanup_stolen(dev);
>  
>  	if (drm_mm_initialized(&vm->mm)) {
> -		if (intel_vgpu_active(dev))
> +		if (intel_vgpu_active(dev) || intel_gvt_active(dev))
>  			intel_vgt_deballoon();
>  
>  		drm_mm_takedown(&vm->mm);
> diff --git a/drivers/gpu/drm/i915/i915_vgpu.c b/drivers/gpu/drm/i915/i915_vgpu.c
> index dea7429..7be1435 100644
> --- a/drivers/gpu/drm/i915/i915_vgpu.c
> +++ b/drivers/gpu/drm/i915/i915_vgpu.c
> @@ -188,10 +188,23 @@ int intel_vgt_balloon(struct drm_device *dev)
>  	unsigned long unmappable_base, unmappable_size, unmappable_end;
>  	int ret;
>  
> -	mappable_base = I915_READ(vgtif_reg(avail_rs.mappable_gmadr.base));
> -	mappable_size = I915_READ(vgtif_reg(avail_rs.mappable_gmadr.size));
> -	unmappable_base = I915_READ(vgtif_reg(avail_rs.nonmappable_gmadr.base));
> -	unmappable_size = I915_READ(vgtif_reg(avail_rs.nonmappable_gmadr.size));
> +	if (intel_gvt_active(dev)) {
> +		mappable_base = 0;
> +		mappable_size = dev_priv->gvt.host_low_gm_sz_in_mb << 20;
> +		unmappable_base = dev_priv->gtt.mappable_end;
> +		unmappable_size = dev_priv->gvt.host_high_gm_sz_in_mb << 20;
> +	} else if (intel_vgpu_active(dev)) {
> +		mappable_base = I915_READ(
> +			vgtif_reg(avail_rs.mappable_gmadr.base));
> +		mappable_size = I915_READ(
> +			vgtif_reg(avail_rs.mappable_gmadr.size));
> +		unmappable_base = I915_READ(
> +			vgtif_reg(avail_rs.nonmappable_gmadr.base));
> +		unmappable_size = I915_READ(
> +			vgtif_reg(avail_rs.nonmappable_gmadr.size));
> +	} else {
> +		return -ENODEV;
> +	}
>  
>  	mappable_end = mappable_base + mappable_size;
>  	unmappable_end = unmappable_base + unmappable_size;
-- 
Joonas Lahtinen
Open Source Technology Center
Intel Corporation
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [RFCv2 03/14] drm/i915: Introduce host graphics memory/fence partition for GVT-g
  2016-02-23 13:16   ` Joonas Lahtinen
@ 2016-02-23 13:23     ` Zhi Wang
  2016-02-24  7:42       ` Tian, Kevin
  2016-02-23 13:26     ` Joonas Lahtinen
  1 sibling, 1 reply; 46+ messages in thread
From: Zhi Wang @ 2016-02-23 13:23 UTC (permalink / raw)
  To: Joonas Lahtinen, intel-gfx, igvt-g
  Cc: daniel.vetter, david.j.cowperthwaite, zhiyuan.lv



On 02/23/16 21:16, Joonas Lahtinen wrote:
> On to, 2016-02-18 at 19:42 +0800, Zhi Wang wrote:
>> From: Bing Niu <bing.niu@intel.com>
>>
>> This patch introduces host graphics memory/fence partition when GVT-g
>> is enabled.
>>
>> Under GVT-g, i915 host driver only owned limited graphics resources,
>> others are managed by GVT-g resource allocator and kept for other vGPUs.
>>
>> v2:
>> - Address all coding-style comments from Joonas previously.
>> - Fix errors and warnning reported by checkpatch.pl. (Joonas)
>> - Move the graphs into the header files. (Daniel)
>>
>> Signed-off-by: Bing Niu <bing.niu@intel.com>
>> Signed-off-by: Zhi Wang <zhi.a.wang@intel.com>
>> ---
>>   drivers/gpu/drm/i915/gvt/gvt.c      |  4 ++++
>>   drivers/gpu/drm/i915/gvt/params.c   | 12 ++++++++++++
>>   drivers/gpu/drm/i915/gvt/params.h   |  3 +++
>>   drivers/gpu/drm/i915/i915_drv.h     | 35 +++++++++++++++++++++++++++++++++++
>>   drivers/gpu/drm/i915/i915_gem.c     |  4 +++-
>>   drivers/gpu/drm/i915/i915_gem_gtt.c |  4 ++--
>>   drivers/gpu/drm/i915/i915_vgpu.c    | 21 +++++++++++++++++----
>>   7 files changed, 76 insertions(+), 7 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/gvt/gvt.c b/drivers/gpu/drm/i915/gvt/gvt.c
>> index 52cfa32..2099b7e 100644
>> --- a/drivers/gpu/drm/i915/gvt/gvt.c
>> +++ b/drivers/gpu/drm/i915/gvt/gvt.c
>> @@ -348,6 +348,10 @@ void *gvt_create_pgt_device(struct drm_i915_private *dev_priv)
>>   		goto err;
>>   	}
>>
>> +	dev_priv->gvt.host_fence_sz = gvt.host_fence_sz;
>> +	dev_priv->gvt.host_low_gm_sz_in_mb = gvt.host_low_gm_sz;
>> +	dev_priv->gvt.host_high_gm_sz_in_mb = gvt.host_high_gm_sz;
>
> I'm thinking, could we expose the pgt_device struct (at least
> partially, and then have a PIMPL pattern), to avoid this kind of
> duplication of declarations and unnecessary copies between i915 and
> i915_gvt modules?
>
> It's little rough that the gvt driver writes to i915_private struct.
> I'd rather see that gvt.host_fence_sz and other variables get sanitized
> and then written to pgt_device (maybe the public part would be
> i915_pgt_device) and used by gvt and i915 code.
>
> Was this ever considered?
>
The previous version do something similar like that, both i915 and gvt 
reads GVT module kernel parameter but considered that GVT modules could 
be configured as "n" in kernel configuration, probably we should let 
i915 to store this information and GVT to configure it if GVT is active?
>> +
>>   	gvt_dbg_core("pgt device creation done, id %d", pdev->id);
>>
>>   	return pdev;
>> diff --git a/drivers/gpu/drm/i915/gvt/params.c b/drivers/gpu/drm/i915/gvt/params.c
>> index d381d17..75195fd 100644
>> --- a/drivers/gpu/drm/i915/gvt/params.c
>> +++ b/drivers/gpu/drm/i915/gvt/params.c
>> @@ -26,7 +26,19 @@
>>   struct gvt_kernel_params gvt = {
>>   	.enable = false,
>>   	.debug = 0,
>> +	.host_low_gm_sz = 96,	/* in MB */
>> +	.host_high_gm_sz = 384, /* in MB */
>> +	.host_fence_sz = 4,
>>   };
>>
>>   module_param_named(gvt_enable, gvt.enable, bool, 0600);
>>   MODULE_PARM_DESC(gvt_enable, "Enable Intel GVT-g host support");
>> +
>> +module_param_named(gvt_host_low_gm_sz, gvt.host_low_gm_sz, int, 0600);
>> +MODULE_PARM_DESC(gvt_host_low_gm_sz, "Amount of aperture size of host (in MB)");
>
> As i915_gvt will be the host module, "gvt_host" can be removed so the
> module parameters become;
>
> i915_gvt.low_gm_sz instead of i915_gvt.gvt_host_low_gm_sz
>
> Also should these be _unsafe parameters because I bet they can make the
> machine go crazy if wrong?
>
Yes, the params need to be checked, indeed.
>> +
>> +module_param_named(gvt_host_high_gm_sz, gvt.host_high_gm_sz, int, 0600);
>> +MODULE_PARM_DESC(gvt_host_high_gm_sz, "Amount of high memory size of host (in MB)");
>> +
>> +module_param_named(gvt_host_fence_sz, gvt.host_fence_sz, int, 0600);
>> +MODULE_PARM_DESC(gvt_host_fence_sz, "Amount of fence size of host (in MB)");
>> diff --git a/drivers/gpu/drm/i915/gvt/params.h b/drivers/gpu/drm/i915/gvt/params.h
>> index d2955b9..f4e9356 100644
>> --- a/drivers/gpu/drm/i915/gvt/params.h
>> +++ b/drivers/gpu/drm/i915/gvt/params.h
>> @@ -27,6 +27,9 @@
>>   struct gvt_kernel_params {
>>   	bool enable;
>>   	int debug;
>> +	int host_low_gm_sz;
>> +	int host_high_gm_sz;
>> +	int host_fence_sz;
>>   };
>>
>>   extern struct gvt_kernel_params gvt;
>> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
>> index 2f897c3..1fd5575 100644
>> --- a/drivers/gpu/drm/i915/i915_drv.h
>> +++ b/drivers/gpu/drm/i915/i915_drv.h
>> @@ -1705,8 +1705,43 @@ struct i915_workarounds {
>>   	u32 hw_whitelist_count[I915_NUM_RINGS];
>>   };
>>
>> +/*
>> + * Under GVT-g, i915 host driver only owned limited graphics resources,
>> + * others are managed by GVT-g resource allocator and kept for other vGPUs.
>> + *
>> + * For graphics memory space partition, a typical layout looks like:
>> + *
>> + * +-------+-----------------------+------+-----------------------+
>> + * |* Host |   *GVT-g Resource     |* Host|   *GVT-g Resource     |
>> + * | Owned |   Allocator Managed   | Owned|   Allocator Managed   |
>> + * |       |                       |      |                       |
>> + * +---------------+-------+----------------------+-------+-------+
>> + * |       |       |       |       |      |       |       |       |
>> + * | i915  | vm 1  | vm 2  | vm 3  | i915 | vm 1  | vm 2  | vm 3  |
>> + * |       |       |       |       |      |       |       |       |
>> + * +-------+-------+-------+--------------+-------+-------+-------+
>> + * |           Aperture            |            Hidden            |
>> + * +-------------------------------+------------------------------+
>> + * |                       GGTT memory space                      |
>> + * +--------------------------------------------------------------+
>> + *
>> + * Similar with fence registers partition:
>> + *
>> + * +------ +-----------------------+
>> + * | * Host|    GVT-g Resource     |
>> + * | Owned |   Allocator Managed   +
>> + * 0       |                       31
>> + * +---------------+-------+-------+
>> + * |       |       |       |       |
>> + * | i915  | vm 1  | vm 2  | vm 3  |
>> + * |       |       |       |       |
>> + * +-------+-------+-------+-------+
>> + */
>>   struct i915_gvt {
>>   	void *pgt_device;
>> +	u32 host_low_gm_sz_in_mb;
>> +	u32 host_high_gm_sz_in_mb;
>> +	int host_fence_sz;
>>   };
>>
>>   struct i915_virtual_gpu {
>> diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
>> index f68f346..1c0006a 100644
>> --- a/drivers/gpu/drm/i915/i915_gem.c
>> +++ b/drivers/gpu/drm/i915/i915_gem.c
>> @@ -5078,7 +5078,9 @@ i915_gem_load_init(struct drm_device *dev)
>>   	else
>>   		dev_priv->num_fence_regs = 8;
>>
>> -	if (intel_vgpu_active(dev))
>> +	if (intel_gvt_active(dev))
>> +		dev_priv->num_fence_regs = dev_priv->gvt.host_fence_sz;
>> +	else if (intel_vgpu_active(dev))
>>   		dev_priv->num_fence_regs =
>>   				I915_READ(vgtif_reg(avail_rs.fence_num));
>>
>> diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
>> index 9127f8f..de09dd4 100644
>> --- a/drivers/gpu/drm/i915/i915_gem_gtt.c
>> +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
>> @@ -2734,7 +2734,7 @@ static int i915_gem_setup_global_gtt(struct drm_device *dev,
>>   	i915_address_space_init(ggtt_vm, dev_priv);
>>   	ggtt_vm->total += PAGE_SIZE;
>>
>> -	if (intel_vgpu_active(dev)) {
>> +	if (intel_vgpu_active(dev) || intel_gvt_active(dev)) {
>>   		ret = intel_vgt_balloon(dev);
>>   		if (ret)
>>   			return ret;
>> @@ -2833,7 +2833,7 @@ void i915_global_gtt_cleanup(struct drm_device *dev)
>>   	i915_gem_cleanup_stolen(dev);
>>
>>   	if (drm_mm_initialized(&vm->mm)) {
>> -		if (intel_vgpu_active(dev))
>> +		if (intel_vgpu_active(dev) || intel_gvt_active(dev))
>>   			intel_vgt_deballoon();
>>
>>   		drm_mm_takedown(&vm->mm);
>> diff --git a/drivers/gpu/drm/i915/i915_vgpu.c b/drivers/gpu/drm/i915/i915_vgpu.c
>> index dea7429..7be1435 100644
>> --- a/drivers/gpu/drm/i915/i915_vgpu.c
>> +++ b/drivers/gpu/drm/i915/i915_vgpu.c
>> @@ -188,10 +188,23 @@ int intel_vgt_balloon(struct drm_device *dev)
>>   	unsigned long unmappable_base, unmappable_size, unmappable_end;
>>   	int ret;
>>
>> -	mappable_base = I915_READ(vgtif_reg(avail_rs.mappable_gmadr.base));
>> -	mappable_size = I915_READ(vgtif_reg(avail_rs.mappable_gmadr.size));
>> -	unmappable_base = I915_READ(vgtif_reg(avail_rs.nonmappable_gmadr.base));
>> -	unmappable_size = I915_READ(vgtif_reg(avail_rs.nonmappable_gmadr.size));
>> +	if (intel_gvt_active(dev)) {
>> +		mappable_base = 0;
>> +		mappable_size = dev_priv->gvt.host_low_gm_sz_in_mb << 20;
>> +		unmappable_base = dev_priv->gtt.mappable_end;
>> +		unmappable_size = dev_priv->gvt.host_high_gm_sz_in_mb << 20;
>> +	} else if (intel_vgpu_active(dev)) {
>> +		mappable_base = I915_READ(
>> +			vgtif_reg(avail_rs.mappable_gmadr.base));
>> +		mappable_size = I915_READ(
>> +			vgtif_reg(avail_rs.mappable_gmadr.size));
>> +		unmappable_base = I915_READ(
>> +			vgtif_reg(avail_rs.nonmappable_gmadr.base));
>> +		unmappable_size = I915_READ(
>> +			vgtif_reg(avail_rs.nonmappable_gmadr.size));
>> +	} else {
>> +		return -ENODEV;
>> +	}
>>
>>   	mappable_end = mappable_base + mappable_size;
>>   	unmappable_end = unmappable_base + unmappable_size;
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [RFCv2 03/14] drm/i915: Introduce host graphics memory/fence partition for GVT-g
  2016-02-23 13:16   ` Joonas Lahtinen
  2016-02-23 13:23     ` Zhi Wang
@ 2016-02-23 13:26     ` Joonas Lahtinen
  1 sibling, 0 replies; 46+ messages in thread
From: Joonas Lahtinen @ 2016-02-23 13:26 UTC (permalink / raw)
  To: Zhi Wang, intel-gfx, igvt-g
  Cc: daniel.vetter, david.j.cowperthwaite, zhiyuan.lv

On ti, 2016-02-23 at 15:16 +0200, Joonas Lahtinen wrote:
> > 
> > On to, 2016-02-18 at 19:42 +0800, Zhi Wang wrote:
> > From: Bing Niu <bing.niu@intel.com>
> > 
> > This patch introduces host graphics memory/fence partition when GVT-g
> > is enabled.
> > 
> > Under GVT-g, i915 host driver only owned limited graphics resources,
> > others are managed by GVT-g resource allocator and kept for other vGPUs.
> > 
> > v2:
> > - Address all coding-style comments from Joonas previously.
> > - Fix errors and warnning reported by checkpatch.pl. (Joonas)
> > - Move the graphs into the header files. (Daniel)
> > 
> > Signed-off-by: Bing Niu <bing.niu@intel.com>
> > Signed-off-by: Zhi Wang <zhi.a.wang@intel.com>
> > ---
> >  drivers/gpu/drm/i915/gvt/gvt.c      |  4 ++++
> >  drivers/gpu/drm/i915/gvt/params.c   | 12 ++++++++++++
> >  drivers/gpu/drm/i915/gvt/params.h   |  3 +++
> >  drivers/gpu/drm/i915/i915_drv.h     | 35 +++++++++++++++++++++++++++++++++++
> >  drivers/gpu/drm/i915/i915_gem.c     |  4 +++-
> >  drivers/gpu/drm/i915/i915_gem_gtt.c |  4 ++--
> >  drivers/gpu/drm/i915/i915_vgpu.c    | 21 +++++++++++++++++----
> >  7 files changed, 76 insertions(+), 7 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/gvt/gvt.c b/drivers/gpu/drm/i915/gvt/gvt.c
> > index 52cfa32..2099b7e 100644
> > --- a/drivers/gpu/drm/i915/gvt/gvt.c
> > +++ b/drivers/gpu/drm/i915/gvt/gvt.c
> > @@ -348,6 +348,10 @@ void *gvt_create_pgt_device(struct drm_i915_private *dev_priv)
> >  		goto err;
> >  	}
> >  
> > +	dev_priv->gvt.host_fence_sz = gvt.host_fence_sz;
> > +	dev_priv->gvt.host_low_gm_sz_in_mb = gvt.host_low_gm_sz;
> > +	dev_priv->gvt.host_high_gm_sz_in_mb = gvt.host_high_gm_sz;
> 
> I'm thinking, could we expose the pgt_device struct (at least
> partially, and then have a PIMPL pattern), to avoid this kind of
> duplication of declarations and unnecessary copies between i915 and
> i915_gvt modules?
> 
> It's little rough that the gvt driver writes to i915_private struct.
> I'd rather see that gvt.host_fence_sz and other variables get sanitized
> and then written to pgt_device (maybe the public part would be
> i915_pgt_device) and used by gvt and i915 code.
> 

Also, using memparse to handle all kernel memory size parameters is a
good idea (see parse_highmem() or related function). That is what users
expect.

> Was this ever considered?
> 

<SNIP>

> > diff --git a/drivers/gpu/drm/i915/i915_vgpu.c b/drivers/gpu/drm/i915/i915_vgpu.c
> > index dea7429..7be1435 100644
> > --- a/drivers/gpu/drm/i915/i915_vgpu.c
> > +++ b/drivers/gpu/drm/i915/i915_vgpu.c
> > @@ -188,10 +188,23 @@ int intel_vgt_balloon(struct drm_device *dev)
> >  	unsigned long unmappable_base, unmappable_size, unmappable_end;
> >  	int ret;
> >  
> > -	mappable_base = I915_READ(vgtif_reg(avail_rs.mappable_gmadr.base));
> > -	mappable_size = I915_READ(vgtif_reg(avail_rs.mappable_gmadr.size));
> > -	unmappable_base = I915_READ(vgtif_reg(avail_rs.nonmappable_gmadr.base));
> > -	unmappable_size = I915_READ(vgtif_reg(avail_rs.nonmappable_gmadr.size));
> > +	if (intel_gvt_active(dev)) {
> > +		mappable_base = 0;
> > +		mappable_size = dev_priv->gvt.host_low_gm_sz_in_mb << 20;
> > +		unmappable_base = dev_priv->gtt.mappable_end;
> > +		unmappable_size = dev_priv->gvt.host_high_gm_sz_in_mb << 20;

This could be avoided too.

> > +	} else if (intel_vgpu_active(dev)) {
> > +		mappable_base = I915_READ(
> > +			vgtif_reg(avail_rs.mappable_gmadr.base));
> > +		mappable_size = I915_READ(
> > +			vgtif_reg(avail_rs.mappable_gmadr.size));
> > +		unmappable_base = I915_READ(
> > +			vgtif_reg(avail_rs.nonmappable_gmadr.base));
> > +		unmappable_size = I915_READ(
> > +			vgtif_reg(avail_rs.nonmappable_gmadr.size));
> > +	} else {
> > +		return -ENODEV;
> > +	}
> >  
> >  	mappable_end = mappable_base + mappable_size;
> >  	unmappable_end = unmappable_base + unmappable_size;
-- 
Joonas Lahtinen
Open Source Technology Center
Intel Corporation
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [RFCv2 03/14] drm/i915: Introduce host graphics memory/fence partition for GVT-g
  2016-02-23 13:23     ` Zhi Wang
@ 2016-02-24  7:42       ` Tian, Kevin
  2016-02-25 13:13         ` Joonas Lahtinen
  2016-02-26  5:21         ` Zhi Wang
  0 siblings, 2 replies; 46+ messages in thread
From: Tian, Kevin @ 2016-02-24  7:42 UTC (permalink / raw)
  To: Wang, Zhi A, Joonas Lahtinen, intel-gfx, igvt-g
  Cc: daniel.vetter, Cowperthwaite, David J, Lv, Zhiyuan

> From: Wang, Zhi A
> Sent: Tuesday, February 23, 2016 9:23 PM
> >> --- a/drivers/gpu/drm/i915/gvt/gvt.c
> >> +++ b/drivers/gpu/drm/i915/gvt/gvt.c
> >> @@ -348,6 +348,10 @@ void *gvt_create_pgt_device(struct drm_i915_private
> *dev_priv)
> >>   		goto err;
> >>   	}
> >>
> >> +	dev_priv->gvt.host_fence_sz = gvt.host_fence_sz;
> >> +	dev_priv->gvt.host_low_gm_sz_in_mb = gvt.host_low_gm_sz;
> >> +	dev_priv->gvt.host_high_gm_sz_in_mb = gvt.host_high_gm_sz;
> >
> > I'm thinking, could we expose the pgt_device struct (at least
> > partially, and then have a PIMPL pattern), to avoid this kind of
> > duplication of declarations and unnecessary copies between i915 and
> > i915_gvt modules?
> >
> > It's little rough that the gvt driver writes to i915_private struct.
> > I'd rather see that gvt.host_fence_sz and other variables get sanitized
> > and then written to pgt_device (maybe the public part would be
> > i915_pgt_device) and used by gvt and i915 code.
> >
> > Was this ever considered?
> >
> The previous version do something similar like that, both i915 and gvt
> reads GVT module kernel parameter but considered that GVT modules could
> be configured as "n" in kernel configuration, probably we should let
> i915 to store this information and GVT to configure it if GVT is active?

Agree with Joonas. We don't need another gvt wrap. Let's just expose
pgt_device directly. I believe all other information can be encapsulated
under pgt_device.

btw to match other description in the code, is it clear to rename pgt_device
to gvt_device?

Another minor thing needs Joonas' feedback. Is it usual to capture
all module parameters belonging to one feature structurized together
(like 'gvt' in this patch), or just to leave them directly exposed?

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

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [RFCv2 02/14] drm/i915/gvt: Introduce the basic architecture of GVT-g
  2016-02-23 12:42   ` Joonas Lahtinen
@ 2016-02-24  7:45     ` Tian, Kevin
  2016-02-25 11:24       ` Joonas Lahtinen
  2016-02-26  5:58     ` Zhi Wang
  1 sibling, 1 reply; 46+ messages in thread
From: Tian, Kevin @ 2016-02-24  7:45 UTC (permalink / raw)
  To: Joonas Lahtinen, Wang, Zhi A, intel-gfx, igvt-g
  Cc: daniel.vetter, Cowperthwaite, David J, Lv, Zhiyuan

> From: Joonas Lahtinen [mailto:joonas.lahtinen@linux.intel.com]
> Sent: Tuesday, February 23, 2016 8:42 PM
> 
> Hi,
> 
> Code is looking a lot better.
> 
> A general question still; why you seem to be preferring multi-stage
> alloc and destroy?

One reason for multi-stage, IMO, is that GVT needs to do a snapshot
of initial MMIO state before i915 driver does actual initialization. That
snapshot will be presented to each VM which can then observe same
state as it would observe on a bare metal. Then the majority of
initialization needs to wait after i915 driver completes initialization. 
Zhi can correct me here.

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

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [RFCv2 02/14] drm/i915/gvt: Introduce the basic architecture of GVT-g
  2016-02-23 12:53   ` Joonas Lahtinen
@ 2016-02-24  7:50     ` Tian, Kevin
  0 siblings, 0 replies; 46+ messages in thread
From: Tian, Kevin @ 2016-02-24  7:50 UTC (permalink / raw)
  To: Joonas Lahtinen, Wang, Zhi A, intel-gfx, igvt-g
  Cc: daniel.vetter, Cowperthwaite, David J, Lv, Zhiyuan

> From: Joonas Lahtinen [mailto:joonas.lahtinen@linux.intel.com]
> Sent: Tuesday, February 23, 2016 8:54 PM
> > diff --git a/drivers/gpu/drm/i915/gvt/Makefile b/drivers/gpu/drm/i915/gvt/Makefile
> > new file mode 100644
> > index 0000000..959305f
> > --- /dev/null
> > +++ b/drivers/gpu/drm/i915/gvt/Makefile
> > @@ -0,0 +1,5 @@
> > +GVT_SOURCE := gvt.o params.o
> > +
> > +ccflags-y                      += -I$(src) -I$(src)/.. -Wall -Werror -Wno-unused-function
> > +i915_gvt-y                     := $(GVT_SOURCE)
> 
> (This name conflicts with upper level i915_gvt, which I suggested
> renaming to intel_gvt.c. A one more reason more so this can be kept as
> is).
> 

Curious what's the criteria whether a file should be called i915_xxx or intel_xxx?

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

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [RFCv2 02/14] drm/i915/gvt: Introduce the basic architecture of GVT-g
  2016-02-18 11:42 ` [RFCv2 02/14] drm/i915/gvt: Introduce the basic architecture of GVT-g Zhi Wang
  2016-02-23 12:42   ` Joonas Lahtinen
  2016-02-23 12:53   ` Joonas Lahtinen
@ 2016-02-24  8:08   ` Tian, Kevin
  2016-02-26  5:38     ` Zhi Wang
  2 siblings, 1 reply; 46+ messages in thread
From: Tian, Kevin @ 2016-02-24  8:08 UTC (permalink / raw)
  To: Wang, Zhi A, intel-gfx, igvt-g
  Cc: daniel.vetter, Cowperthwaite, David J, Lv, Zhiyuan

> From: Wang, Zhi A
> Sent: Thursday, February 18, 2016 7:42 PM
> diff --git a/drivers/gpu/drm/i915/gvt/gvt.c b/drivers/gpu/drm/i915/gvt/gvt.c
> new file mode 100644
> index 0000000..52cfa32
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/gvt/gvt.c
[...]
> +
> +#include <linux/types.h>
> +#include <xen/xen.h>

would this inclusion lead to a dependency on Xen?

> +#include <linux/kthread.h>
> +
> +#include "gvt.h"
> +
> +struct gvt_host gvt_host;
> +
> +static const char * const supported_hypervisors[] = {
> +	[GVT_HYPERVISOR_TYPE_XEN] = "Xen Hypervisor",
> +	[GVT_HYPERVISOR_TYPE_KVM] = "KVM",
> +};
> +
> +static int gvt_init_host(void)
> +{
> +	struct gvt_host *host = &gvt_host;
> +
> +	if (!gvt.enable) {
> +		gvt_dbg_core("GVT-g has been disabled by kernel parameter");
> +		return -EINVAL;
> +	}
> +
> +	if (host->initialized) {
> +		gvt_err("GVT-g has already been initialized!");
> +		return -EINVAL;
> +	}
> +
> +	/* Xen DOM U */
> +	if (xen_domain() && !xen_initial_domain())
> +		return -ENODEV;
> +
> +	if (xen_initial_domain()) {
> +		/* Xen Dom0 */
> +		host->kdm = try_then_request_module(
> +				symbol_get(xengt_kdm), "xengt");
> +		host->hypervisor_type = GVT_HYPERVISOR_TYPE_XEN;
> +	} else {
> +		/* not in Xen. Try KVMGT */
> +		host->kdm = try_then_request_module(
> +				symbol_get(kvmgt_kdm), "kvm");
> +		host->hypervisor_type = GVT_HYPERVISOR_TYPE_KVM;
> +	}

It'd be clearer to add a comment here that above is only a short-term
solution. It's supposed to have a general registration framework in 
the future so any hypervisor (Xen or KVM) can register their callbacks
at run-time, then we'll not need such direct Xen/KVM references or
hard assumption in driver code. That framework is now still under
discussion with Xen/KVM community. It doesn't prevent reviewing of
other bits, but better to document it clear here.

> +static int init_device_info(struct pgt_device *pdev)
> +{
> +	struct gvt_device_info *info = &pdev->device_info;
> +
> +	if (!IS_BROADWELL(pdev->dev_priv)) {
> +		DRM_DEBUG_DRIVER("Unsupported GEN device");
> +		return -ENODEV;
> +	}
> +
> +	if (IS_BROADWELL(pdev->dev_priv)) {
> +		info->max_gtt_gm_sz = (1ULL << 32); /* 4GB */
> +		/*
> +		 * The layout of BAR0 in BDW:
> +		 * |< - MMIO 2MB ->|<- Reserved 6MB ->|<- MAX GTT 8MB->|
> +		 *
> +		 * GTT offset in BAR0 starts from 8MB to 16MB, and
> +		 * Whatever GTT size is configured in BIOS,
> +		 * the size of BAR0 is always 16MB. The actual configured
> +		 * GTT size can be found in GMCH_CTRL.
> +		 */
> +		info->gtt_start_offset = (1UL << 23); /* 8MB */
> +		info->max_gtt_size = (1UL << 23); /* 8MB */
> +		info->gtt_entry_size = 8;
> +		info->gtt_entry_size_shift = 3;
> +		info->gmadr_bytes_in_cmd = 8;
> +		info->mmio_size = 2 * 1024 * 1024; /* 2MB */

Above are pure device info. Joonas, do you think whether it makes
sense to make them to drm_i915_private, though gvt is the only
user today?

> +	}
> +
> +	return 0;
> +}
> +
> +static void init_initial_cfg_space_state(struct pgt_device *pdev)

'init' -> 'setup'

> +{
> +	struct pci_dev *pci_dev = pdev->dev_priv->dev->pdev;
> +	int i;
> +
> +	gvt_dbg_core("init initial cfg space, id %d", pdev->id);
> +
> +	for (i = 0; i < GVT_CFG_SPACE_SZ; i += 4)
> +		pci_read_config_dword(pci_dev, i,
> +				(u32 *)&pdev->initial_cfg_space[i]);
> +
> +	for (i = 0; i < GVT_BAR_NUM; i++) {
> +		pdev->bar_size[i] = pci_resource_len(pci_dev, i * 2);
> +		gvt_dbg_core("bar %d size: %llx", i, pdev->bar_size[i]);
> +	}
> +}
> +
> +static void clean_initial_mmio_state(struct pgt_device *pdev)
> +{
> +	if (pdev->gttmmio_va) {
> +		iounmap(pdev->gttmmio_va);
> +		pdev->gttmmio_va = NULL;
> +	}
> +
> +	if (pdev->gmadr_va) {
> +		iounmap(pdev->gmadr_va);
> +		pdev->gmadr_va = NULL;
> +	}

Can we reuse existing mapping in i915?

> +}
> +
> +static int init_initial_mmio_state(struct pgt_device *pdev)
> +{

'init' -> 'setup'

> +	struct gvt_device_info *info = &pdev->device_info;
> +
> +	u64 bar0, bar1;
> +	int rc;
> +
> +	gvt_dbg_core("init initial mmio state, id %d", pdev->id);
> +
> +	bar0 = *(u64 *)&pdev->initial_cfg_space[GVT_REG_CFG_SPACE_BAR0];
> +	bar1 = *(u64 *)&pdev->initial_cfg_space[GVT_REG_CFG_SPACE_BAR1];
> +
> +	pdev->gttmmio_base = bar0 & ~0xf;
> +	pdev->reg_num = info->mmio_size / 4;
> +	pdev->gmadr_base = bar1 & ~0xf;
> +
> +	pdev->gttmmio_va = ioremap(pdev->gttmmio_base, pdev->bar_size[0]);
> +	if (!pdev->gttmmio_va) {
> +		gvt_err("fail to map GTTMMIO BAR.");
> +		return -EFAULT;
> +	}
> +
> +	pdev->gmadr_va = ioremap(pdev->gmadr_base, pdev->bar_size[2]);
> +	if (!pdev->gmadr_va) {
> +		gvt_err("fail to map GMADR BAR.");
> +		rc = -EFAULT;
> +		goto err;
> +	}
> +
> +	gvt_dbg_core("bar0: 0x%llx, bar1: 0x%llx", bar0, bar1);
> +	gvt_dbg_core("mmio size: %x", pdev->mmio_size);
> +	gvt_dbg_core("gttmmio: 0x%llx, gmadr: 0x%llx", pdev->gttmmio_base,
> +			pdev->gmadr_base);
> +	gvt_dbg_core("gttmmio_va: %p", pdev->gttmmio_va);
> +	gvt_dbg_core("gmadr_va: %p", pdev->gmadr_va);
> +

since you called 'initial_mmio_state', suppose we should do a MMIO snapshot
here.

 [...]
> +
> +static struct pgt_device *alloc_pgt_device(struct drm_i915_private *dev_priv)
> +{
> +	struct gvt_host *host = &gvt_host;
> +	struct pgt_device *pdev = NULL;
> +
> +	pdev = vzalloc(sizeof(*pdev));
> +	if (!pdev)
> +		return NULL;
> +
> +	mutex_lock(&host->device_idr_lock);
> +	pdev->id = idr_alloc(&host->device_idr, pdev, 0, 0, GFP_KERNEL);

curious what such ID help here? We already have either dev_priv or
pgt_device pointer passed around. Isn't it enough to mark a device?

[...]
> +
> +/**
> + * gvt_create_pgt_device - create a GVT physical device
> + * @dev: drm device
> + *
> + * This function is called at the initialization stage, to create a physical
> + * GVT device and initialize necessary GVT components for it.
> + *
> + * Returns:
> + * pointer to the pgt_device structure, NULL if failed.
> + */
> +void *gvt_create_pgt_device(struct drm_i915_private *dev_priv)

should we remove 'pgt' completely? We can always use 'gvt_device'
as reference to the object, and then above can be gvt_create_device
or gvt_create_physical_device, or if 'create' is a bit misleading maybe
gvt_initialize_device is cleaner?

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

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [RFCv2 03/14] drm/i915: Introduce host graphics memory/fence partition for GVT-g
  2016-02-18 11:42 ` [RFCv2 03/14] drm/i915: Introduce host graphics memory/fence partition for GVT-g Zhi Wang
  2016-02-23 13:16   ` Joonas Lahtinen
@ 2016-02-24  8:22   ` Tian, Kevin
  2016-02-26  5:29     ` Zhi Wang
  1 sibling, 1 reply; 46+ messages in thread
From: Tian, Kevin @ 2016-02-24  8:22 UTC (permalink / raw)
  To: Wang, Zhi A, intel-gfx, igvt-g
  Cc: daniel.vetter, Cowperthwaite, David J, Lv, Zhiyuan

> From: Wang, Zhi A
> Sent: Thursday, February 18, 2016 7:42 PM
> diff --git a/drivers/gpu/drm/i915/gvt/gvt.c b/drivers/gpu/drm/i915/gvt/gvt.c
> index 52cfa32..2099b7e 100644
> --- a/drivers/gpu/drm/i915/gvt/gvt.c
> +++ b/drivers/gpu/drm/i915/gvt/gvt.c
> @@ -348,6 +348,10 @@ void *gvt_create_pgt_device(struct drm_i915_private
> *dev_priv)
>  		goto err;
>  	}
> 
> +	dev_priv->gvt.host_fence_sz = gvt.host_fence_sz;
> +	dev_priv->gvt.host_low_gm_sz_in_mb = gvt.host_low_gm_sz;
> +	dev_priv->gvt.host_high_gm_sz_in_mb = gvt.host_high_gm_sz;

Do we need hard limiting fence number for host usage here? There is no
continuity requirement as seen for graphics memory, since we do translate
fence# between guest view and host view. So we could make it flexible
as an on-demand allocation when creating a vGPU. Daniel even mentioned
, iirc, that today i915 can dynamically grab a fence register away from 
an application, which could be useful even when host fence usage is high
(not a typical case in server virtualization which runs few applications in host).

> diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c
> b/drivers/gpu/drm/i915/i915_gem_gtt.c
> index 9127f8f..de09dd4 100644
> --- a/drivers/gpu/drm/i915/i915_gem_gtt.c
> +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
> @@ -2734,7 +2734,7 @@ static int i915_gem_setup_global_gtt(struct drm_device *dev,
>  	i915_address_space_init(ggtt_vm, dev_priv);
>  	ggtt_vm->total += PAGE_SIZE;
> 
> -	if (intel_vgpu_active(dev)) {
> +	if (intel_vgpu_active(dev) || intel_gvt_active(dev)) {

above two conditions are bit confusing for others not familiar with 
this technology. vgpu_active is for driver running in a VM, while
gvt_active is for driver running in host. Could we introduce a better 
name, or at least wrap them into a more meaningful macro like
intel_ballooning_required?

>  		ret = intel_vgt_balloon(dev);

I saw several comments whether ballooning is a right term here,
since we only do static reservation so far. How about renaming it
to intel_reserve_gm_resource to be more clear? In the future even
when we want to add true dynamic ballooning feature, it will be
largely refactored anyway. :-)

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

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [RFCv2 04/14] drm/i915: factor out alloc_context_idr() and __i915_gem_create_context()
  2016-02-18 11:42 ` [RFCv2 04/14] drm/i915: factor out alloc_context_idr() and __i915_gem_create_context() Zhi Wang
@ 2016-02-24  8:27   ` Tian, Kevin
  0 siblings, 0 replies; 46+ messages in thread
From: Tian, Kevin @ 2016-02-24  8:27 UTC (permalink / raw)
  To: Wang, Zhi A, intel-gfx, igvt-g
  Cc: daniel.vetter, Cowperthwaite, David J, Lv, Zhiyuan

> From: Wang, Zhi A
> Sent: Thursday, February 18, 2016 7:42 PM
> 
> For flexible GEM context creation, we factor out __i915_gem_create_context
> as the core logic of creation a GEM context. After the refactor, it more
> likesa context creation servcie, which is able to create context by
> explicit requirement of upper level components, not by the assumptions of
> incoming parameters.
> 
> For the assumptions in original implementation, we keep them in the upper
> level wrapper: i915_gem_create_context().

IMO combining 5/6/7 is clearer to give a full picture how create_context
is refactored, but will leave to i915 guys to comment the preferred style.

> 
> alloc_context_idr() is another function factored out to setup a IDR for
> ordinary GEM context. Some context, e.g. GVT context, maybe more than one
> kernel context in furture (currently there is only one kernel context: the
> default context) doesn't need a IDR. So we make it an option in context
> creation.
> 

Could you elaborate why IDR cannot be used for GVT context. Even
if it is not used, keeping it can reduce the code divergence as long as
no function is impacted...

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

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [RFCv2 06/14] drm/i915: let __i915_gem_context_create() takes context creation params
  2016-02-18 11:42 ` [RFCv2 06/14] drm/i915: let __i915_gem_context_create() takes context creation params Zhi Wang
@ 2016-02-24  8:35   ` Tian, Kevin
  0 siblings, 0 replies; 46+ messages in thread
From: Tian, Kevin @ 2016-02-24  8:35 UTC (permalink / raw)
  To: Wang, Zhi A, intel-gfx, igvt-g
  Cc: daniel.vetter, Cowperthwaite, David J, Lv, Zhiyuan

> From: Wang, Zhi A
> Sent: Thursday, February 18, 2016 7:42 PM
> 
> Let the core logic of context creation service creats the GEM context by
> context creation params.
> 
> Now it provides following options for context creation:
> - Need to create legacy context for this GEM context?
> - Need to create PPGTT instance for this GEM context?
> - Need to treat this context as the global default context?
> 
> And for all the assumptions in the original implementation, we keep them
> in the upper-level wrapper.
> 
> Signed-off-by: Zhi Wang <zhi.a.wang@intel.com>
> ---
>  drivers/gpu/drm/i915/i915_gem_context.c | 71
> ++++++++++++++++++++-------------
>  1 file changed, 43 insertions(+), 28 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_gem_context.c
> b/drivers/gpu/drm/i915/i915_gem_context.c
> index 5516346..cda09f7 100644
> --- a/drivers/gpu/drm/i915/i915_gem_context.c
> +++ b/drivers/gpu/drm/i915/i915_gem_context.c
> @@ -223,6 +223,13 @@ static int __create_legacy_hw_context(struct drm_device *dev,
>  	return 0;
>  }
> 
> +struct i915_gem_context_create_params {
> +	struct drm_i915_file_private *file_priv;
> +	bool has_legacy_ctx;

'has_legacy_ctx" means slightly different from 'is_legacy_ctx' in
original place. :-)

> +	bool has_ppgtt;

similarly 'has_ppgtt' has different meaning from original 
USE_FULL_PPGTT... from your purpose looks it is for indicating
whether a new ppgtt should be created here, then a clearer
name is required.

> +	bool is_default_ctx;

You abandoned 'global' from original name. Any reason?

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

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [RFCv2 07/14] drm/i915: factor out __intel_lr_context_deferred_alloc()
  2016-02-18 11:42 ` [RFCv2 07/14] drm/i915: factor out __intel_lr_context_deferred_alloc() Zhi Wang
@ 2016-02-24  8:37   ` Tian, Kevin
  0 siblings, 0 replies; 46+ messages in thread
From: Tian, Kevin @ 2016-02-24  8:37 UTC (permalink / raw)
  To: Wang, Zhi A, intel-gfx, igvt-g
  Cc: daniel.vetter, Cowperthwaite, David J, Lv, Zhiyuan

> From: Wang, Zhi A
> Sent: Thursday, February 18, 2016 7:42 PM
> diff --git a/drivers/gpu/drm/i915/intel_lrc.h b/drivers/gpu/drm/i915/intel_lrc.h
> index e6cda3e..528c4fb 100644
> --- a/drivers/gpu/drm/i915/intel_lrc.h
> +++ b/drivers/gpu/drm/i915/intel_lrc.h
> @@ -97,10 +97,18 @@ static inline void intel_logical_ring_emit_reg(struct intel_ringbuffer
> *ringbuf,
>  #define LRC_PPHWSP_PN	(LRC_GUCSHR_PN + 1)
>  #define LRC_STATE_PN	(LRC_PPHWSP_PN + 1)
> 
> +struct intel_lr_context_alloc_params {
> +	struct intel_engine_cs *ring;
> +	u32 ringbuffer_size;
> +	bool ctx_needs_init;

'ctx_initialized'?

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

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [RFCv2 08/14] drm/i915: Support per-PPGTT address space mode
  2016-02-18 11:42 ` [RFCv2 08/14] drm/i915: Support per-PPGTT address space mode Zhi Wang
@ 2016-02-24  8:47   ` Tian, Kevin
  0 siblings, 0 replies; 46+ messages in thread
From: Tian, Kevin @ 2016-02-24  8:47 UTC (permalink / raw)
  To: Wang, Zhi A, intel-gfx, igvt-g
  Cc: daniel.vetter, Cowperthwaite, David J, Lv, Zhiyuan

> From: Wang, Zhi A
> Sent: Thursday, February 18, 2016 7:42 PM
> -static int gen8_ppgtt_init(struct i915_hw_ppgtt *ppgtt)
> +static int gen8_ppgtt_init(struct i915_hw_ppgtt *ppgtt, int address_space_mode)

address_space_mode -> address_bits?

>  {
>  	int ret;
> 
> @@ -1518,7 +1524,7 @@ static int gen8_ppgtt_init(struct i915_hw_ppgtt *ppgtt)
>  	ppgtt->base.bind_vma = ppgtt_bind_vma;
>  	ppgtt->debug_dump = gen8_dump_ppgtt;
> 
> -	if (USES_FULL_48BIT_PPGTT(ppgtt->base.dev)) {
> +	if (address_space_mode == 48) {

IS_48BIT_PPGTT

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

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [RFCv2 10/14] drm/i915: update PDPs by condition when submit the LRC context
  2016-02-18 11:42 ` [RFCv2 10/14] drm/i915: update PDPs by condition when submit the LRC context Zhi Wang
@ 2016-02-24  8:49   ` Tian, Kevin
  2016-02-25 15:02     ` Wang, Zhi A
  0 siblings, 1 reply; 46+ messages in thread
From: Tian, Kevin @ 2016-02-24  8:49 UTC (permalink / raw)
  To: Wang, Zhi A, intel-gfx, igvt-g
  Cc: daniel.vetter, Cowperthwaite, David J, Lv, Zhiyuan

> From: Wang, Zhi A
> Sent: Thursday, February 18, 2016 7:42 PM
> 
> Previously the PDPs inside the ring context are updated at:
> 
> - When populate a LRC context
> - Before submitting a LRC context (only for 32 bit PPGTT, as the amount
> of used PDPs may change)
> 
> This patch postpones the PDPs upgrade to submission time, and will update
> it by condition if the PPGTT is 48b. Under GVT-g, one GVT context will be
> used by different guest, the PPGTT instance related to the context might
> be changed before the submission time. And this patch gives GVT context
> a chance to load the new PPGTT instance into an initialized context.

Could you elaborate why we share one GVT context across different guest?
A natural thought is that we'll create one GVT context per every guest
context...

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

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [RFCv2 13/14] drm/i915: Support context single submission when GVT is active
  2016-02-18 11:42 ` [RFCv2 13/14] drm/i915: Support context single submission when GVT is active Zhi Wang
@ 2016-02-24  8:52   ` Tian, Kevin
  0 siblings, 0 replies; 46+ messages in thread
From: Tian, Kevin @ 2016-02-24  8:52 UTC (permalink / raw)
  To: Wang, Zhi A, intel-gfx, igvt-g
  Cc: daniel.vetter, Cowperthwaite, David J, Lv, Zhiyuan

> From: Wang, Zhi A
> Sent: Thursday, February 18, 2016 7:42 PM
> diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
> index 1c0366a..2a6d6fe 100644
> --- a/drivers/gpu/drm/i915/intel_lrc.c
> +++ b/drivers/gpu/drm/i915/intel_lrc.c
> @@ -479,6 +479,40 @@ static void execlists_i915_pick_requests(struct intel_engine_cs
> *ring,
>  	}
>  }
> 
> +static void execlists_gvt_pick_requests(struct intel_engine_cs *ring,
> +		struct drm_i915_gem_request **req0,
> +		struct drm_i915_gem_request **req1)

not read carefully, but if single submission itself has nothing tied to GVT,
better to make it generic since there may be other users in the future...

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

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [RFCv2 PATCH 00/14] gvt: Hacking i915 for GVT context requirement
  2016-02-18 11:42 [RFCv2 PATCH 00/14] gvt: Hacking i915 for GVT context requirement Zhi Wang
                   ` (14 preceding siblings ...)
  2016-02-18 12:02 ` ✗ Fi.CI.BAT: failure for gvt: Hacking i915 for GVT context requirement Patchwork
@ 2016-02-24  8:55 ` Tian, Kevin
  2016-02-24  9:18   ` Wang, Zhi A
  15 siblings, 1 reply; 46+ messages in thread
From: Tian, Kevin @ 2016-02-24  8:55 UTC (permalink / raw)
  To: Wang, Zhi A, intel-gfx, igvt-g
  Cc: daniel.vetter, Cowperthwaite, David J, Lv, Zhiyuan

> From: Wang, Zhi A
> Sent: Thursday, February 18, 2016 7:42 PM
> 
> This patchset is used to discuss and finalize the i915 changes required by
> GVT context. Previously we have discussed about how to hack i915 to meet
> GVT context requirement, and thanks for the idea and comments.
> 
> In this patchset, mostly it refactors the existing i915 APIs, spliting the
> hard-coded assumptions from its core logic, keep these assumptions in the
> high level wrapper and make the core logic much more flexible and config-
> urable, which is able to be used by GVT context creation and submission.

It would be good to note that this patch series is not the only change required
for GVT context management. It addresses creation/submission. We also 
need some specific change in context switch time. Do you want to include them
together in next version to compose a full picture?

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

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [RFCv2 PATCH 00/14] gvt: Hacking i915 for GVT context requirement
  2016-02-24  8:55 ` [RFCv2 PATCH 00/14] " Tian, Kevin
@ 2016-02-24  9:18   ` Wang, Zhi A
  2016-02-24  9:38     ` Tian, Kevin
  0 siblings, 1 reply; 46+ messages in thread
From: Wang, Zhi A @ 2016-02-24  9:18 UTC (permalink / raw)
  To: Tian, Kevin, intel-gfx, igvt-g
  Cc: daniel.vetter, Cowperthwaite, David J, Lv, Zhiyuan

Hi Kevin:
	Now our context switch is covered by context status change notification handler. In the status change handler we will save render registers. As GVT context will be a single submission context we will restore the render registers when the GVT context is scheduled-out by HW.

> -----Original Message-----
> From: Tian, Kevin
> Sent: Wednesday, February 24, 2016 4:56 PM
> To: Wang, Zhi A; intel-gfx@lists.freedesktop.org; igvt-g@lists.01.org
> Cc: Lv, Zhiyuan; Niu, Bing; Song, Jike; daniel.vetter@ffwll.ch; Cowperthwaite,
> David J; chris@chris-wilson.co.uk; joonas.lahtinen@linux.intel.com
> Subject: RE: [RFCv2 PATCH 00/14] gvt: Hacking i915 for GVT context
> requirement
> 
> > From: Wang, Zhi A
> > Sent: Thursday, February 18, 2016 7:42 PM
> >
> > This patchset is used to discuss and finalize the i915 changes
> > required by GVT context. Previously we have discussed about how to
> > hack i915 to meet GVT context requirement, and thanks for the idea and
> comments.
> >
> > In this patchset, mostly it refactors the existing i915 APIs, spliting
> > the hard-coded assumptions from its core logic, keep these assumptions
> > in the high level wrapper and make the core logic much more flexible
> > and config- urable, which is able to be used by GVT context creation and
> submission.
> 
> It would be good to note that this patch series is not the only change required
> for GVT context management. It addresses creation/submission. We also need
> some specific change in context switch time. Do you want to include them
> together in next version to compose a full picture?
> 
> Thanks
> Kevin
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [RFCv2 PATCH 00/14] gvt: Hacking i915 for GVT context requirement
  2016-02-24  9:18   ` Wang, Zhi A
@ 2016-02-24  9:38     ` Tian, Kevin
  0 siblings, 0 replies; 46+ messages in thread
From: Tian, Kevin @ 2016-02-24  9:38 UTC (permalink / raw)
  To: Wang, Zhi A, intel-gfx, igvt-g
  Cc: daniel.vetter, Cowperthwaite, David J, Lv, Zhiyuan

> From: Wang, Zhi A
> Sent: Wednesday, February 24, 2016 5:19 PM
> 
> Hi Kevin:
> 	Now our context switch is covered by context status change notification handler. In the
> status change handler we will save render registers. As GVT context will be a single
> submission context we will restore the render registers when the GVT context is
> scheduled-out by HW.

Thanks for explanation. It's fine then.

> 
> > -----Original Message-----
> > From: Tian, Kevin
> > Sent: Wednesday, February 24, 2016 4:56 PM
> > To: Wang, Zhi A; intel-gfx@lists.freedesktop.org; igvt-g@lists.01.org
> > Cc: Lv, Zhiyuan; Niu, Bing; Song, Jike; daniel.vetter@ffwll.ch; Cowperthwaite,
> > David J; chris@chris-wilson.co.uk; joonas.lahtinen@linux.intel.com
> > Subject: RE: [RFCv2 PATCH 00/14] gvt: Hacking i915 for GVT context
> > requirement
> >
> > > From: Wang, Zhi A
> > > Sent: Thursday, February 18, 2016 7:42 PM
> > >
> > > This patchset is used to discuss and finalize the i915 changes
> > > required by GVT context. Previously we have discussed about how to
> > > hack i915 to meet GVT context requirement, and thanks for the idea and
> > comments.
> > >
> > > In this patchset, mostly it refactors the existing i915 APIs, spliting
> > > the hard-coded assumptions from its core logic, keep these assumptions
> > > in the high level wrapper and make the core logic much more flexible
> > > and config- urable, which is able to be used by GVT context creation and
> > submission.
> >
> > It would be good to note that this patch series is not the only change required
> > for GVT context management. It addresses creation/submission. We also need
> > some specific change in context switch time. Do you want to include them
> > together in next version to compose a full picture?
> >
> > Thanks
> > Kevin
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [RFCv2 02/14] drm/i915/gvt: Introduce the basic architecture of GVT-g
  2016-02-24  7:45     ` Tian, Kevin
@ 2016-02-25 11:24       ` Joonas Lahtinen
  0 siblings, 0 replies; 46+ messages in thread
From: Joonas Lahtinen @ 2016-02-25 11:24 UTC (permalink / raw)
  To: Tian, Kevin, Wang, Zhi A, intel-gfx, igvt-g
  Cc: daniel.vetter, Cowperthwaite, David J, Lv, Zhiyuan

On ke, 2016-02-24 at 07:45 +0000, Tian, Kevin wrote:
> > From: Joonas Lahtinen [mailto:joonas.lahtinen@linux.intel.com]
> > Sent: Tuesday, February 23, 2016 8:42 PM
> > 
> > Hi,
> > 
> > Code is looking a lot better.
> > 
> > A general question still; why you seem to be preferring multi-stage
> > alloc and destroy?
> 
> One reason for multi-stage, IMO, is that GVT needs to do a snapshot
> of initial MMIO state before i915 driver does actual initialization. That
> snapshot will be presented to each VM which can then observe same
> state as it would observe on a bare metal. Then the majority of
> initialization needs to wait after i915 driver completes initialization. 
> Zhi can correct me here.
> 

Sorry for being unclear, I was referring to pgt_device initialization.

Regards, Joonas

> Thanks
> Kevin
-- 
Joonas Lahtinen
Open Source Technology Center
Intel Corporation
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [RFCv2 03/14] drm/i915: Introduce host graphics memory/fence partition for GVT-g
  2016-02-24  7:42       ` Tian, Kevin
@ 2016-02-25 13:13         ` Joonas Lahtinen
  2016-02-26  5:21         ` Zhi Wang
  1 sibling, 0 replies; 46+ messages in thread
From: Joonas Lahtinen @ 2016-02-25 13:13 UTC (permalink / raw)
  To: Tian, Kevin, Wang, Zhi A, intel-gfx, igvt-g
  Cc: daniel.vetter, Cowperthwaite, David J, Lv, Zhiyuan

On ke, 2016-02-24 at 07:42 +0000, Tian, Kevin wrote:
> > From: Wang, Zhi A
> > Sent: Tuesday, February 23, 2016 9:23 PM
> > > > --- a/drivers/gpu/drm/i915/gvt/gvt.c
> > > > +++ b/drivers/gpu/drm/i915/gvt/gvt.c
> > > > @@ -348,6 +348,10 @@ void *gvt_create_pgt_device(struct drm_i915_private
> > *dev_priv)
> > > >   		goto err;
> > > >   	}
> > > > 
> > > > +	dev_priv->gvt.host_fence_sz = gvt.host_fence_sz;
> > > > +	dev_priv->gvt.host_low_gm_sz_in_mb = gvt.host_low_gm_sz;
> > > > +	dev_priv->gvt.host_high_gm_sz_in_mb = gvt.host_high_gm_sz;
> > > 
> > > I'm thinking, could we expose the pgt_device struct (at least
> > > partially, and then have a PIMPL pattern), to avoid this kind of
> > > duplication of declarations and unnecessary copies between i915 and
> > > i915_gvt modules?
> > > 
> > > It's little rough that the gvt driver writes to i915_private struct.
> > > I'd rather see that gvt.host_fence_sz and other variables get sanitized
> > > and then written to pgt_device (maybe the public part would be
> > > i915_pgt_device) and used by gvt and i915 code.
> > > 
> > > Was this ever considered?
> > > 
> > The previous version do something similar like that, both i915 and gvt
> > reads GVT module kernel parameter but considered that GVT modules could
> > be configured as "n" in kernel configuration, probably we should let
> > i915 to store this information and GVT to configure it if GVT is active?
> 
> Agree with Joonas. We don't need another gvt wrap. Let's just expose
> pgt_device directly. I believe all other information can be encapsulated
> under pgt_device.
> 
> btw to match other description in the code, is it clear to rename pgt_device
> to gvt_device?
> 
> Another minor thing needs Joonas' feedback. Is it usual to capture
> all module parameters belonging to one feature structurized together
> (like 'gvt' in this patch), or just to leave them directly exposed?
> 

I think it's a good idea to group them as they're currently grouped.

Regards, Joonas

> Thanks
> Kevin
-- 
Joonas Lahtinen
Open Source Technology Center
Intel Corporation
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [RFCv2 10/14] drm/i915: update PDPs by condition when submit the LRC context
  2016-02-24  8:49   ` Tian, Kevin
@ 2016-02-25 15:02     ` Wang, Zhi A
  2016-02-26 13:49       ` Joonas Lahtinen
  0 siblings, 1 reply; 46+ messages in thread
From: Wang, Zhi A @ 2016-02-25 15:02 UTC (permalink / raw)
  To: Tian, Kevin, intel-gfx, igvt-g
  Cc: daniel.vetter, Cowperthwaite, David J, Lv, Zhiyuan



-----Original Message-----
From: Tian, Kevin 
Sent: Wednesday, February 24, 2016 4:50 PM
To: Wang, Zhi A; intel-gfx@lists.freedesktop.org; igvt-g@lists.01.org
Cc: Lv, Zhiyuan; Niu, Bing; Song, Jike; daniel.vetter@ffwll.ch; Cowperthwaite, David J; chris@chris-wilson.co.uk; joonas.lahtinen@linux.intel.com
Subject: RE: [RFCv2 10/14] drm/i915: update PDPs by condition when submit the LRC context

> From: Wang, Zhi A
> Sent: Thursday, February 18, 2016 7:42 PM
> 
> Previously the PDPs inside the ring context are updated at:
> 
> - When populate a LRC context
> - Before submitting a LRC context (only for 32 bit PPGTT, as the amount
> of used PDPs may change)
> 
> This patch postpones the PDPs upgrade to submission time, and will update
> it by condition if the PPGTT is 48b. Under GVT-g, one GVT context will be
> used by different guest, the PPGTT instance related to the context might
> be changed before the submission time. And this patch gives GVT context
> a chance to load the new PPGTT instance into an initialized context.

Could you elaborate why we share one GVT context across different guest?
A natural thought is that we'll create one GVT context per every guest
context...

[Zhi] We don't have context creation/destroy notification in guest i915 driver.
Because in our implementation we need an unique context id to anchor the
relationship between shadow context and guest context, while i915 uses GGTT
address as context id. In each context pin/unpin, the context id may be changes.

So it's not necessary to allocate multiple GVT context here. 

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

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [RFCv2 03/14] drm/i915: Introduce host graphics memory/fence partition for GVT-g
  2016-02-24  7:42       ` Tian, Kevin
  2016-02-25 13:13         ` Joonas Lahtinen
@ 2016-02-26  5:21         ` Zhi Wang
  2016-02-26 13:54           ` Joonas Lahtinen
  1 sibling, 1 reply; 46+ messages in thread
From: Zhi Wang @ 2016-02-26  5:21 UTC (permalink / raw)
  To: Tian, Kevin, Joonas Lahtinen, intel-gfx, igvt-g
  Cc: daniel.vetter, Cowperthwaite, David J, Lv, Zhiyuan



On 02/24/16 15:42, Tian, Kevin wrote:
>> From: Wang, Zhi A
>> Sent: Tuesday, February 23, 2016 9:23 PM
>>>> --- a/drivers/gpu/drm/i915/gvt/gvt.c
>>>> +++ b/drivers/gpu/drm/i915/gvt/gvt.c
>>>> @@ -348,6 +348,10 @@ void *gvt_create_pgt_device(struct drm_i915_private
>> *dev_priv)
>>>>    		goto err;
>>>>    	}
>>>>
>>>> +	dev_priv->gvt.host_fence_sz = gvt.host_fence_sz;
>>>> +	dev_priv->gvt.host_low_gm_sz_in_mb = gvt.host_low_gm_sz;
>>>> +	dev_priv->gvt.host_high_gm_sz_in_mb = gvt.host_high_gm_sz;
>>>
>>> I'm thinking, could we expose the pgt_device struct (at least
>>> partially, and then have a PIMPL pattern), to avoid this kind of
>>> duplication of declarations and unnecessary copies between i915 and
>>> i915_gvt modules?
>>>
>>> It's little rough that the gvt driver writes to i915_private struct.
>>> I'd rather see that gvt.host_fence_sz and other variables get sanitized
>>> and then written to pgt_device (maybe the public part would be
>>> i915_pgt_device) and used by gvt and i915 code.
>>>
>>> Was this ever considered?
>>>
>> The previous version do something similar like that, both i915 and gvt
>> reads GVT module kernel parameter but considered that GVT modules could
>> be configured as "n" in kernel configuration, probably we should let
>> i915 to store this information and GVT to configure it if GVT is active?
>
> Agree with Joonas. We don't need another gvt wrap. Let's just expose
> pgt_device directly. I believe all other information can be encapsulated
> under pgt_device.
>
How about this scheme:

1. Move GVT kernel parameter into intel_gvt.{h, c}
2. Sanitize the partition configuration for host in intel_gvt.c
3. If CONFIG_DRM_I915_GVT = y, write the configuration into pgt_device 
to inform GVT resource allocator ranges owned by host

> btw to match other description in the code, is it clear to rename pgt_device
> to gvt_device?
>

For the name of GVT physical device, if we use "gvt_device", it looks a 
bit weird when both "gvt_device" and "vgt_device"(vGPU instance) 
appeared in our code? :( And "pgpu" and "vgpu" also looks weird...

> Another minor thing needs Joonas' feedback. Is it usual to capture
> all module parameters belonging to one feature structurized together
> (like 'gvt' in this patch), or just to leave them directly exposed?
>


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

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [RFCv2 03/14] drm/i915: Introduce host graphics memory/fence partition for GVT-g
  2016-02-24  8:22   ` Tian, Kevin
@ 2016-02-26  5:29     ` Zhi Wang
  0 siblings, 0 replies; 46+ messages in thread
From: Zhi Wang @ 2016-02-26  5:29 UTC (permalink / raw)
  To: Tian, Kevin, intel-gfx, igvt-g
  Cc: daniel.vetter, Cowperthwaite, David J, Lv, Zhiyuan



On 02/24/16 16:22, Tian, Kevin wrote:
>> From: Wang, Zhi A
>> Sent: Thursday, February 18, 2016 7:42 PM
>> diff --git a/drivers/gpu/drm/i915/gvt/gvt.c b/drivers/gpu/drm/i915/gvt/gvt.c
>> index 52cfa32..2099b7e 100644
>> --- a/drivers/gpu/drm/i915/gvt/gvt.c
>> +++ b/drivers/gpu/drm/i915/gvt/gvt.c
>> @@ -348,6 +348,10 @@ void *gvt_create_pgt_device(struct drm_i915_private
>> *dev_priv)
>>   		goto err;
>>   	}
>>
>> +	dev_priv->gvt.host_fence_sz = gvt.host_fence_sz;
>> +	dev_priv->gvt.host_low_gm_sz_in_mb = gvt.host_low_gm_sz;
>> +	dev_priv->gvt.host_high_gm_sz_in_mb = gvt.host_high_gm_sz;
>
> Do we need hard limiting fence number for host usage here? There is no
> continuity requirement as seen for graphics memory, since we do translate
> fence# between guest view and host view. So we could make it flexible
> as an on-demand allocation when creating a vGPU. Daniel even mentioned
> , iirc, that today i915 can dynamically grab a fence register away from
> an application, which could be useful even when host fence usage is high
> (not a typical case in server virtualization which runs few applications in host).
>
Yes. They steal fence in aperture mapping fault handler. We could steal 
the fence registers from i915 as well. Let me see the effort here. :)

>> diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c
>> b/drivers/gpu/drm/i915/i915_gem_gtt.c
>> index 9127f8f..de09dd4 100644
>> --- a/drivers/gpu/drm/i915/i915_gem_gtt.c
>> +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
>> @@ -2734,7 +2734,7 @@ static int i915_gem_setup_global_gtt(struct drm_device *dev,
>>   	i915_address_space_init(ggtt_vm, dev_priv);
>>   	ggtt_vm->total += PAGE_SIZE;
>>
>> -	if (intel_vgpu_active(dev)) {
>> +	if (intel_vgpu_active(dev) || intel_gvt_active(dev)) {
>
> above two conditions are bit confusing for others not familiar with
> this technology. vgpu_active is for driver running in a VM, while
> gvt_active is for driver running in host. Could we introduce a better
> name, or at least wrap them into a more meaningful macro like
> intel_ballooning_required?
>
>>   		ret = intel_vgt_balloon(dev);
>
> I saw several comments whether ballooning is a right term here,
> since we only do static reservation so far. How about renaming it
> to intel_reserve_gm_resource to be more clear? In the future even
> when we want to add true dynamic ballooning feature, it will be
> largely refactored anyway. :-)
>
Sure, will do that.
> Thanks
> Kevin
>
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [RFCv2 02/14] drm/i915/gvt: Introduce the basic architecture of GVT-g
  2016-02-24  8:08   ` Tian, Kevin
@ 2016-02-26  5:38     ` Zhi Wang
  0 siblings, 0 replies; 46+ messages in thread
From: Zhi Wang @ 2016-02-26  5:38 UTC (permalink / raw)
  To: Tian, Kevin, intel-gfx, igvt-g
  Cc: daniel.vetter, Cowperthwaite, David J, Lv, Zhiyuan



On 02/24/16 16:08, Tian, Kevin wrote:
>> From: Wang, Zhi A
>> Sent: Thursday, February 18, 2016 7:42 PM
>> diff --git a/drivers/gpu/drm/i915/gvt/gvt.c b/drivers/gpu/drm/i915/gvt/gvt.c
>> new file mode 100644
>> index 0000000..52cfa32
>> --- /dev/null
>> +++ b/drivers/gpu/drm/i915/gvt/gvt.c
> [...]
>> +
>> +#include <linux/types.h>
>> +#include <xen/xen.h>
>
> would this inclusion lead to a dependency on Xen?
>
>> +#include <linux/kthread.h>
>> +
>> +#include "gvt.h"
>> +
>> +struct gvt_host gvt_host;
>> +
>> +static const char * const supported_hypervisors[] = {
>> +	[GVT_HYPERVISOR_TYPE_XEN] = "Xen Hypervisor",
>> +	[GVT_HYPERVISOR_TYPE_KVM] = "KVM",
>> +};
>> +
>> +static int gvt_init_host(void)
>> +{
>> +	struct gvt_host *host = &gvt_host;
>> +
>> +	if (!gvt.enable) {
>> +		gvt_dbg_core("GVT-g has been disabled by kernel parameter");
>> +		return -EINVAL;
>> +	}
>> +
>> +	if (host->initialized) {
>> +		gvt_err("GVT-g has already been initialized!");
>> +		return -EINVAL;
>> +	}
>> +
>> +	/* Xen DOM U */
>> +	if (xen_domain() && !xen_initial_domain())
>> +		return -ENODEV;
>> +
>> +	if (xen_initial_domain()) {
>> +		/* Xen Dom0 */
>> +		host->kdm = try_then_request_module(
>> +				symbol_get(xengt_kdm), "xengt");
>> +		host->hypervisor_type = GVT_HYPERVISOR_TYPE_XEN;
>> +	} else {
>> +		/* not in Xen. Try KVMGT */
>> +		host->kdm = try_then_request_module(
>> +				symbol_get(kvmgt_kdm), "kvm");
>> +		host->hypervisor_type = GVT_HYPERVISOR_TYPE_KVM;
>> +	}
>
> It'd be clearer to add a comment here that above is only a short-term
> solution. It's supposed to have a general registration framework in
> the future so any hypervisor (Xen or KVM) can register their callbacks
> at run-time, then we'll not need such direct Xen/KVM references or
> hard assumption in driver code. That framework is now still under
> discussion with Xen/KVM community. It doesn't prevent reviewing of
> other bits, but better to document it clear here.
>
I'm keeping thinking if we should split this patch into much smaller 
patches and just push some basic definitions and functions for GVT 
context patch review here before MPT framework is finally figured out 
with RH guys?

>> +static int init_device_info(struct pgt_device *pdev)
>> +{
>> +	struct gvt_device_info *info = &pdev->device_info;
>> +
>> +	if (!IS_BROADWELL(pdev->dev_priv)) {
>> +		DRM_DEBUG_DRIVER("Unsupported GEN device");
>> +		return -ENODEV;
>> +	}
>> +
>> +	if (IS_BROADWELL(pdev->dev_priv)) {
>> +		info->max_gtt_gm_sz = (1ULL << 32); /* 4GB */
>> +		/*
>> +		 * The layout of BAR0 in BDW:
>> +		 * |< - MMIO 2MB ->|<- Reserved 6MB ->|<- MAX GTT 8MB->|
>> +		 *
>> +		 * GTT offset in BAR0 starts from 8MB to 16MB, and
>> +		 * Whatever GTT size is configured in BIOS,
>> +		 * the size of BAR0 is always 16MB. The actual configured
>> +		 * GTT size can be found in GMCH_CTRL.
>> +		 */
>> +		info->gtt_start_offset = (1UL << 23); /* 8MB */
>> +		info->max_gtt_size = (1UL << 23); /* 8MB */
>> +		info->gtt_entry_size = 8;
>> +		info->gtt_entry_size_shift = 3;
>> +		info->gmadr_bytes_in_cmd = 8;
>> +		info->mmio_size = 2 * 1024 * 1024; /* 2MB */
>
> Above are pure device info. Joonas, do you think whether it makes
> sense to make them to drm_i915_private, though gvt is the only
> user today?
>
>> +	}
>> +
>> +	return 0;
>> +}
>> +
>> +static void init_initial_cfg_space_state(struct pgt_device *pdev)
>
> 'init' -> 'setup'
>
>> +{
>> +	struct pci_dev *pci_dev = pdev->dev_priv->dev->pdev;
>> +	int i;
>> +
>> +	gvt_dbg_core("init initial cfg space, id %d", pdev->id);
>> +
>> +	for (i = 0; i < GVT_CFG_SPACE_SZ; i += 4)
>> +		pci_read_config_dword(pci_dev, i,
>> +				(u32 *)&pdev->initial_cfg_space[i]);
>> +
>> +	for (i = 0; i < GVT_BAR_NUM; i++) {
>> +		pdev->bar_size[i] = pci_resource_len(pci_dev, i * 2);
>> +		gvt_dbg_core("bar %d size: %llx", i, pdev->bar_size[i]);
>> +	}
>> +}
>> +
>> +static void clean_initial_mmio_state(struct pgt_device *pdev)
>> +{
>> +	if (pdev->gttmmio_va) {
>> +		iounmap(pdev->gttmmio_va);
>> +		pdev->gttmmio_va = NULL;
>> +	}
>> +
>> +	if (pdev->gmadr_va) {
>> +		iounmap(pdev->gmadr_va);
>> +		pdev->gmadr_va = NULL;
>> +	}
>
> Can we reuse existing mapping in i915?
>
Yes, but we have to flush the tlb stuffs like i915, as i915 maps GTT 
MMIOs as WC...

>> +}
>> +
>> +static int init_initial_mmio_state(struct pgt_device *pdev)
>> +{
>
> 'init' -> 'setup'
>
>> +	struct gvt_device_info *info = &pdev->device_info;
>> +
>> +	u64 bar0, bar1;
>> +	int rc;
>> +
>> +	gvt_dbg_core("init initial mmio state, id %d", pdev->id);
>> +
>> +	bar0 = *(u64 *)&pdev->initial_cfg_space[GVT_REG_CFG_SPACE_BAR0];
>> +	bar1 = *(u64 *)&pdev->initial_cfg_space[GVT_REG_CFG_SPACE_BAR1];
>> +
>> +	pdev->gttmmio_base = bar0 & ~0xf;
>> +	pdev->reg_num = info->mmio_size / 4;
>> +	pdev->gmadr_base = bar1 & ~0xf;
>> +
>> +	pdev->gttmmio_va = ioremap(pdev->gttmmio_base, pdev->bar_size[0]);
>> +	if (!pdev->gttmmio_va) {
>> +		gvt_err("fail to map GTTMMIO BAR.");
>> +		return -EFAULT;
>> +	}
>> +
>> +	pdev->gmadr_va = ioremap(pdev->gmadr_base, pdev->bar_size[2]);
>> +	if (!pdev->gmadr_va) {
>> +		gvt_err("fail to map GMADR BAR.");
>> +		rc = -EFAULT;
>> +		goto err;
>> +	}
>> +
>> +	gvt_dbg_core("bar0: 0x%llx, bar1: 0x%llx", bar0, bar1);
>> +	gvt_dbg_core("mmio size: %x", pdev->mmio_size);
>> +	gvt_dbg_core("gttmmio: 0x%llx, gmadr: 0x%llx", pdev->gttmmio_base,
>> +			pdev->gmadr_base);
>> +	gvt_dbg_core("gttmmio_va: %p", pdev->gttmmio_va);
>> +	gvt_dbg_core("gmadr_va: %p", pdev->gmadr_va);
>> +
>
> since you called 'initial_mmio_state', suppose we should do a MMIO snapshot
> here.
>
Or we move these code into basic mmio emulation patch? :)
>   [...]
>> +
>> +static struct pgt_device *alloc_pgt_device(struct drm_i915_private *dev_priv)
>> +{
>> +	struct gvt_host *host = &gvt_host;
>> +	struct pgt_device *pdev = NULL;
>> +
>> +	pdev = vzalloc(sizeof(*pdev));
>> +	if (!pdev)
>> +		return NULL;
>> +
>> +	mutex_lock(&host->device_idr_lock);
>> +	pdev->id = idr_alloc(&host->device_idr, pdev, 0, 0, GFP_KERNEL);
>
> curious what such ID help here? We already have either dev_priv or
> pgt_device pointer passed around. Isn't it enough to mark a device?
>
This code piece comes from our pgt device list. currently seems there is 
no for_each_pgt_device() requirement, will remove it in the next version
> [...]
>> +
>> +/**
>> + * gvt_create_pgt_device - create a GVT physical device
>> + * @dev: drm device
>> + *
>> + * This function is called at the initialization stage, to create a physical
>> + * GVT device and initialize necessary GVT components for it.
>> + *
>> + * Returns:
>> + * pointer to the pgt_device structure, NULL if failed.
>> + */
>> +void *gvt_create_pgt_device(struct drm_i915_private *dev_priv)
>
> should we remove 'pgt' completely? We can always use 'gvt_device'
> as reference to the object, and then above can be gvt_create_device
> or gvt_create_physical_device, or if 'create' is a bit misleading maybe
> gvt_initialize_device is cleaner?
>
OK. :)
> Thanks
> Kevin
>
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [RFCv2 02/14] drm/i915/gvt: Introduce the basic architecture of GVT-g
  2016-02-23 12:42   ` Joonas Lahtinen
  2016-02-24  7:45     ` Tian, Kevin
@ 2016-02-26  5:58     ` Zhi Wang
  1 sibling, 0 replies; 46+ messages in thread
From: Zhi Wang @ 2016-02-26  5:58 UTC (permalink / raw)
  To: Joonas Lahtinen, intel-gfx, igvt-g
  Cc: daniel.vetter, david.j.cowperthwaite, zhiyuan.lv

Hi Joonas:

Thanks for you time and comments. :) See my replies below.

On 02/23/16 20:42, Joonas Lahtinen wrote:
> Hi,
>
> Code is looking a lot better.
>
> A general question still; why you seem to be preferring multi-stage
> alloc and destroy?
>
> Are there going to be scenarios when things will be allocated but not
> initialized? I don't see a such use scenario.
>
> I wouldn't split the init functions down as much as you currently do
> because that'll require a lot of boilerplate code to propagate the
> errors up, which is currently not done. The boilerplate for propagation
> becomes necessary when the teardown function is complex, but currently
> the teardown itself is less lines of code than the function
> boilerplate.
>
> So just squash those into gvt_device_create() and gvt_device_destroy()
> where _create() will propagate any lower level errors up and tear down
> a partially initialized struct. _destroy() can then expect to just tear
> the whole struct down with no ifs.
>
OK. Sure no problem.
> Regards, Joonas
>
> On to, 2016-02-18 at 19:42 +0800, Zhi Wang wrote:
>> This patch introduces the very basic framework of GVT-g device model,
>> includes basic prototypes, definitions, initialization.
>>
>> v2:
>> - Introduce i915_gvt.c.
>> It's necessary to introduce the stubs between i915 driver and GVT-g host,
>> as GVT-g components is configurable in kernel config. When disabled, the
>> stubs here do nothing.
>>
>> Take Joonas's comments:
>> - Replace boolean return value with int.
>> - Replace customized info/warn/debug macros with DRM macros.
>> - Document all non-static functions like i915.
>> - Remove empty and unused functions.
>> - Replace magic number with marcos.
>> - Set GVT-g in kernel config to "n" by default.
>>
>> Signed-off-by: Zhi Wang <zhi.a.wang@intel.com>
>> ---
>>   drivers/gpu/drm/i915/Kconfig         |  15 ++
>>   drivers/gpu/drm/i915/Makefile        |   2 +
>>   drivers/gpu/drm/i915/gvt/Makefile    |   5 +
>>   drivers/gpu/drm/i915/gvt/debug.h     |  57 +++++
>>   drivers/gpu/drm/i915/gvt/gvt.c       | 393 +++++++++++++++++++++++++++++++++++
>>   drivers/gpu/drm/i915/gvt/gvt.h       | 100 +++++++++
>>   drivers/gpu/drm/i915/gvt/hypercall.h |  30 +++
>>   drivers/gpu/drm/i915/gvt/mpt.h       |  34 +++
>>   drivers/gpu/drm/i915/gvt/params.c    |  32 +++
>>   drivers/gpu/drm/i915/gvt/params.h    |  34 +++
>>   drivers/gpu/drm/i915/gvt/reg.h       |  34 +++
>>   drivers/gpu/drm/i915/i915_dma.c      |  14 ++
>>   drivers/gpu/drm/i915/i915_drv.h      |  12 ++
>>   drivers/gpu/drm/i915/i915_gvt.c      |  93 +++++++++
>>   drivers/gpu/drm/i915/i915_gvt.h      |  49 +++++
>>   15 files changed, 904 insertions(+)
>>   create mode 100644 drivers/gpu/drm/i915/gvt/Makefile
>>   create mode 100644 drivers/gpu/drm/i915/gvt/debug.h
>>   create mode 100644 drivers/gpu/drm/i915/gvt/gvt.c
>>   create mode 100644 drivers/gpu/drm/i915/gvt/gvt.h
>>   create mode 100644 drivers/gpu/drm/i915/gvt/hypercall.h
>>   create mode 100644 drivers/gpu/drm/i915/gvt/mpt.h
>>   create mode 100644 drivers/gpu/drm/i915/gvt/params.c
>>   create mode 100644 drivers/gpu/drm/i915/gvt/params.h
>>   create mode 100644 drivers/gpu/drm/i915/gvt/reg.h
>>   create mode 100644 drivers/gpu/drm/i915/i915_gvt.c
>>   create mode 100644 drivers/gpu/drm/i915/i915_gvt.h
>>
>> diff --git a/drivers/gpu/drm/i915/Kconfig b/drivers/gpu/drm/i915/Kconfig
>> index 4c59793..082e77d 100644
>> --- a/drivers/gpu/drm/i915/Kconfig
>> +++ b/drivers/gpu/drm/i915/Kconfig
>> @@ -45,3 +45,18 @@ config DRM_I915_PRELIMINARY_HW_SUPPORT
>>   	  option changes the default for that module option.
>>
>>   	  If in doubt, say "N".
>> +
>> +config DRM_I915_GVT
>> +        tristate "GVT-g host driver"
>> +        depends on DRM_I915
>> +        default n
>> +        help
>> +          Enabling GVT-g mediated graphics passthrough technique for Intel i915
>> +          based integrated graphics card. With GVT-g, it's possible to have one
>> +          integrated i915 device shared by multiple VMs. Performance critical
>> +          opterations such as apperture accesses and ring buffer operations
>> +          are pass-throughed to VM, with a minimal set of conflicting resources
>> +          (e.g. display settings) mediated by vGT driver. The benefit of vGT
>> +          is on both the performance, given that each VM could directly operate
>> +          its aperture space and submit commands like running on native, and
>> +          the feature completeness, given that a true GEN hardware is exposed.
>> diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
>> index 0851de07..c65026c 100644
>> --- a/drivers/gpu/drm/i915/Makefile
>> +++ b/drivers/gpu/drm/i915/Makefile
>> @@ -91,6 +91,8 @@ i915-y += dvo_ch7017.o \
>>   	  intel_sdvo.o \
>>   	  intel_tv.o
>>
>> +obj-$(CONFIG_DRM_I915_GVT)  += i915_gvt.o gvt/
>> +
>>   # virtual gpu code
>>   i915-y += i915_vgpu.o
>>
>> diff --git a/drivers/gpu/drm/i915/gvt/Makefile b/drivers/gpu/drm/i915/gvt/Makefile
>> new file mode 100644
>> index 0000000..959305f
>> --- /dev/null
>> +++ b/drivers/gpu/drm/i915/gvt/Makefile
>> @@ -0,0 +1,5 @@
>> +GVT_SOURCE := gvt.o params.o
>> +
>> +ccflags-y                      += -I$(src) -I$(src)/.. -Wall -Werror -Wno-unused-function
>> +i915_gvt-y                     := $(GVT_SOURCE)
>> +obj-$(CONFIG_DRM_I915_GVT)     += i915_gvt.o
>> diff --git a/drivers/gpu/drm/i915/gvt/debug.h b/drivers/gpu/drm/i915/gvt/debug.h
>> new file mode 100644
>> index 0000000..0747f28
>> --- /dev/null
>> +++ b/drivers/gpu/drm/i915/gvt/debug.h
>> @@ -0,0 +1,57 @@
>> +/*
>> + * 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.
>> + */
>> +
>> +#ifndef __GVT_DEBUG_H__
>> +#define __GVT_DEBUG_H__
>> +
>> +#define gvt_info(fmt, args...) \
>> +	DRM_INFO("gvt: "fmt"\n", ##args)
>> +
>
> Just;
>
> 	DRM_INFO("gvt: " fmt, ##args)
>
> Do not automatically add newlines, it will confuse developers. Applies
> to all printing.
>
OK. Will improve that in the next version
>> +#define gvt_err(fmt, args...) \
>> +	DRM_ERROR("gvt: "fmt"\n", ##args)
>> +
>
> Same here.
>
>> +#define gvt_warn(condition, fmt, args...) \
>> +	WARN((condition), "gvt: "fmt"\n", ##args)
>> +
>> +#define gvt_warn_once(condition, fmt, args...) \
>> +	WARN_ONCE((condition), "gvt: "fmt"\n", ##args)
>
> WARN and WARN_ONCE will include backtrace so prefixing is unnecessary.
> I would not prefix them at all. Just use what i915 kernel module
> already uses. If needed, split them to their own file first,
> i915_debug.h.
OK. Thanks.:)
>> +
>> +#define gvt_dbg(level, fmt, args...) \
>> +	DRM_DEBUG_DRIVER("gvt: "fmt"\n", ##args)
>> +
>> +enum {
>> +	GVT_DBG_CORE = (1 << 0),
>> +	GVT_DBG_MM = (1 << 1),
>> +	GVT_DBG_IRQ = (1 << 2),
>> +};
>
> This enum is not of use.
>
>> +
>> +#define gvt_dbg_core(fmt, args...) \
>> +	gvt_dbg(GVT_DBG_CORE, fmt, ##args)
>> +
>
> Rahter like this (not to lose the topic)?
> 	gvt_dbg("core: " fmt, ##args)
>
Thanks for the idea. It's adorable. :)
>> +#define gvt_dbg_mm(fmt, args...) \
>> +	gvt_dbg(GVT_DBG_MM, fmt, ##args)
>> +
>> +#define gvt_dbg_irq(fmt, args...) \
>> +	gvt_dbg(GVT_DBG_IRQ, fmt, ##args)
>> +
>> +#endif
>> diff --git a/drivers/gpu/drm/i915/gvt/gvt.c b/drivers/gpu/drm/i915/gvt/gvt.c
>> new file mode 100644
>> index 0000000..52cfa32
>> --- /dev/null
>> +++ b/drivers/gpu/drm/i915/gvt/gvt.c
>> @@ -0,0 +1,393 @@
>> +/*
>> + * 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.
>> + */
>> +
>> +#include
>> +#include
>> +#include
>> +
>> +#include "gvt.h"
>> +
>> +struct gvt_host gvt_host;
>> +
>> +static const char * const supported_hypervisors[] = {
>> +	[GVT_HYPERVISOR_TYPE_XEN] = "Xen Hypervisor",
>> +	[GVT_HYPERVISOR_TYPE_KVM] = "KVM",
>> +};
>> +
>> +static int gvt_init_host(void)
>> +{
>> +	struct gvt_host *host = &gvt_host;
>> +
>
> Is it really that much more to write gvt_host.initialized? Counting the
> "->" vs "." it's three letters...
>
>> +	if (!gvt.enable) {
>> +		gvt_dbg_core("GVT-g has been disabled by kernel parameter");
>> +		return -EINVAL;
>> +	}
>> +
>> +	if (host->initialized) {
>> +		gvt_err("GVT-g has already been initialized!");
>> +		return -EINVAL;
>> +	}
>> +
>> +	/* Xen DOM U */
>> +	if (xen_domain() && !xen_initial_domain())
>> +		return -ENODEV;
>> +
>> +	if (xen_initial_domain()) {
>> +		/* Xen Dom0 */
>> +		host->kdm = try_then_request_module(
>> +				symbol_get(xengt_kdm), "xengt");
>> +		host->hypervisor_type = GVT_HYPERVISOR_TYPE_XEN;
>> +	} else {
>> +		/* not in Xen. Try KVMGT */
>> +		host->kdm = try_then_request_module(
>> +				symbol_get(kvmgt_kdm), "kvm");
>> +		host->hypervisor_type = GVT_HYPERVISOR_TYPE_KVM;
>> +	}
>> +
>> +	if (!host->kdm)
>> +		return -EINVAL;
>
> I think this error should be reported, to aid detecting problems in
> module loading.
>
Sure.
>> +
>> +	if (!hypervisor_detect_host())
>> +		return -ENODEV;
>> +
>
> This func should be prefixed gvt_, as it is not local to this file.
>
Will improve that.
>> +	gvt_info("Running with hypervisor %s in host mode",
>> +			supported_hypervisors[host->hypervisor_type]);
>> +
>> +	idr_init(&host->device_idr);
>> +	mutex_init(&host->device_idr_lock);
>> +
>> +	host->initialized = true;
>> +	return 0;
>> +}
>> +
>> +static int init_device_info(struct pgt_device *pdev)
>> +{
>> +	struct gvt_device_info *info = &pdev->device_info;
>> +
>> +	if (!IS_BROADWELL(pdev->dev_priv)) {
>> +		DRM_DEBUG_DRIVER("Unsupported GEN device");
>> +		return -ENODEV;
>> +	}
>
> This could be "else" clause on the next if and will allow easier adding
> of future platforms.
>
Will refine it into dedicated functions. :)
>> +
>> +	if (IS_BROADWELL(pdev->dev_priv)) {
>> +		info->max_gtt_gm_sz = (1ULL << 32); /* 4GB */
>> +		/*
>> +		 * The layout of BAR0 in BDW:
>> +		 * |< - MMIO 2MB ->|<- Reserved 6MB ->|<- MAX GTT 8MB->|
>> +		 *
>> +		 * GTT offset in BAR0 starts from 8MB to 16MB, and
>> +		 * Whatever GTT size is configured in BIOS,
>> +		 * the size of BAR0 is always 16MB. The actual configured
>> +		 * GTT size can be found in GMCH_CTRL.
>> +		 */
>> +		info->gtt_start_offset = (1UL << 23); /* 8MB */
>> +		info->max_gtt_size = (1UL << 23); /* 8MB */
>> +		info->gtt_entry_size = 8;
>> +		info->gtt_entry_size_shift = 3;
>> +		info->gmadr_bytes_in_cmd = 8;
>> +		info->mmio_size = 2 * 1024 * 1024; /* 2MB */
>> +	}
>> +
>> +	return 0;
>> +}
>> +
>> +static void init_initial_cfg_space_state(struct pgt_device *pdev)
>> +{
>> +	struct pci_dev *pci_dev = pdev->dev_priv->dev->pdev;
>> +	int i;
>> +
>> +	gvt_dbg_core("init initial cfg space, id %d", pdev->id);
>> +
>> +	for (i = 0; i < GVT_CFG_SPACE_SZ; i += 4)
>> +		pci_read_config_dword(pci_dev, i,
>> +				(u32 *)&pdev->initial_cfg_space[i]);
>> +
>> +	for (i = 0; i < GVT_BAR_NUM; i++) {
>> +		pdev->bar_size[i] = pci_resource_len(pci_dev, i * 2);
>> +		gvt_dbg_core("bar %d size: %llx", i, pdev->bar_size[i]);
>> +	}
>> +}
>> +
>> +static void clean_initial_mmio_state(struct pgt_device *pdev)
>> +{
>> +	if (pdev->gttmmio_va) {
>> +		iounmap(pdev->gttmmio_va);
>> +		pdev->gttmmio_va = NULL;
>> +	}
>> +
>> +	if (pdev->gmadr_va) {
>> +		iounmap(pdev->gmadr_va);
>> +		pdev->gmadr_va = NULL;
>> +	}
>> +}
>> +
>> +static int init_initial_mmio_state(struct pgt_device *pdev)
>> +{
>> +	struct gvt_device_info *info = &pdev->device_info;
>> +
>> +	u64 bar0, bar1;
>> +	int rc;
>> +
>> +	gvt_dbg_core("init initial mmio state, id %d", pdev->id);
>> +
>> +	bar0 = *(u64 *)&pdev->initial_cfg_space[GVT_REG_CFG_SPACE_BAR0];
>> +	bar1 = *(u64 *)&pdev->initial_cfg_space[GVT_REG_CFG_SPACE_BAR1];
>> +
>> +	pdev->gttmmio_base = bar0 & ~0xf;
>> +	pdev->reg_num = info->mmio_size / 4;
>> +	pdev->gmadr_base = bar1 & ~0xf;
>
> Magic numbers still.
>
My bad. :)
>> +
>> +	pdev->gttmmio_va = ioremap(pdev->gttmmio_base, pdev->bar_size[0]);
>> +	if (!pdev->gttmmio_va) {
>> +		gvt_err("fail to map GTTMMIO BAR.");
>> +		return -EFAULT;
>> +	}
>> +
>> +	pdev->gmadr_va = ioremap(pdev->gmadr_base, pdev->bar_size[2]);
>> +	if (!pdev->gmadr_va) {
>> +		gvt_err("fail to map GMADR BAR.");
>> +		rc = -EFAULT;
>> +		goto err;
>> +	}
>> +
>> +	gvt_dbg_core("bar0: 0x%llx, bar1: 0x%llx", bar0, bar1);
>> +	gvt_dbg_core("mmio size: %x", pdev->mmio_size);
>> +	gvt_dbg_core("gttmmio: 0x%llx, gmadr: 0x%llx", pdev->gttmmio_base,
>> +			pdev->gmadr_base);
>> +	gvt_dbg_core("gttmmio_va: %p", pdev->gttmmio_va);
>> +	gvt_dbg_core("gmadr_va: %p", pdev->gmadr_va);
>> +
>> +	return 0;
>> +err:
>> +	clean_initial_mmio_state(pdev);
>> +	return rc;
>> +}
>> +
>> +static int gvt_service_thread(void *data)
>> +{
>> +	struct pgt_device *pdev = (struct pgt_device *)data;
>> +	int r;
>> +
>> +	gvt_dbg_core("service thread start, pgt %d", pdev->id);
>> +
>> +	while (!kthread_should_stop()) {
>> +		r = wait_event_interruptible(pdev->service_thread_wq,
>> +				kthread_should_stop() || pdev->service_request);
>> +
>> +		if (kthread_should_stop())
>> +			break;
>> +
>> +		if (gvt_warn_once(r,
>> +			"service thread is waken up by unexpected signal."))
>> +			continue;
>> +	}
>> +
>> +	return 0;
>> +}
>> +
>> +static void clean_service_thread(struct pgt_device *pdev)
>> +{
>> +	if (pdev->service_thread) {
>> +		kthread_stop(pdev->service_thread);
>> +		pdev->service_thread = NULL;
>> +	}
>> +}
>> +
>> +static int init_service_thread(struct pgt_device *pdev)
>> +{
>> +	init_waitqueue_head(&pdev->service_thread_wq);
>> +
>> +	pdev->service_thread = kthread_run(gvt_service_thread,
>> +			pdev, "gvt_service_thread%d", pdev->id);
>> +
>> +	if (!pdev->service_thread) {
>> +		gvt_err("fail to start service thread.");
>> +		return -ENOSPC;
>> +	}
>> +
>> +	return 0;
>> +}
>> +
>> +static void clean_pgt_device(struct pgt_device *pdev)
>> +{
>> +	clean_service_thread(pdev);
>> +	clean_initial_mmio_state(pdev);
>> +}
>> +
>> +static int init_pgt_device(struct pgt_device *pdev,
>> +	struct drm_i915_private *dev_priv)
>> +{
>> +	int rc;
>
> 	int ret;
>
>> +
>> +	rc = init_device_info(pdev);
>> +	if (rc)
>> +		return rc;
>> +
>> +	init_initial_cfg_space_state(pdev);
>> +
>> +	rc = init_initial_mmio_state(pdev);
>> +	if (rc)
>> +		goto err;
>> +
>> +	rc = init_service_thread(pdev);
>> +	if (rc)
>> +		goto err;
>> +
>> +	return 0;
>> +err:
>> +	clean_pgt_device(pdev);
>
> Add teardown path, see below.
>
>> +	return rc;
>> +}
>> +
>> +static int post_init_pgt_device(struct pgt_device *pdev)
>> +{
>> +	return 0;
>> +}
>> +
>> +static void free_pgt_device(struct pgt_device *pdev)
>> +{
>> +	struct gvt_host *host = &gvt_host;
>> +
>> +	mutex_lock(&host->device_idr_lock);
>> +	idr_remove(&host->device_idr, pdev->id);
>> +	mutex_unlock(&host->device_idr_lock);
>> +
>> +	vfree(pdev);
>> +}
>> +
>> +static struct pgt_device *alloc_pgt_device(struct drm_i915_private *dev_priv)
>> +{
>> +	struct gvt_host *host = &gvt_host;
>> +	struct pgt_device *pdev = NULL;
>> +
>> +	pdev = vzalloc(sizeof(*pdev));
>> +	if (!pdev)
>> +		return NULL;
>
> This is a memory error, would like to see this propagated up as
>
> 	return ERR_PTR(-ENOMEM);
>
>> +
>> +	mutex_lock(&host->device_idr_lock);
>> +	pdev->id = idr_alloc(&host->device_idr, pdev, 0, 0, GFP_KERNEL);
>> +	mutex_unlock(&host->device_idr_lock);
>> +
>> +	if (pdev->id < 0) {
>> +		gvt_err("fail to allocate pgt device id.");
>> +		goto err;
>> +	}
>> +
>
> Same here, propagate the error.
>
>> +	mutex_init(&pdev->lock);
>> +	pdev->dev_priv = dev_priv;
>> +	idr_init(&pdev->instance_idr);
>> +
>> +	return pdev;
>> +err:
>> +	free_pgt_device(pdev);
>
> I'd like to see a teardown path here. Then free_pgt_device() (or rather
> destroy_pgt_device() can expect everything to be initialized and when
> it it is called, it doesn't need ifs. This makes the driver code more
> robust.
>
> Or are we expecting only partially initialized structs for some reason?
>
The idea here is to prevent teardown path maintain burden in future, 
usually during the development, the teardown path is easy to be broken.

Sure, I will follow your idea. :)
>> +	return NULL;
>> +}
>> +
>> +void gvt_destroy_pgt_device(void *private_data)
>> +{
>> +	struct pgt_device *pdev = (struct pgt_device *)private_data;
>> +
>> +	clean_pgt_device(pdev);
>> +	free_pgt_device(pdev);
>
> Why multiple calls to destroy a device, there's only one alloc still?
>
clean_pgt_device() will call the clena_xxx() function of each 
sub-components. Each sub-components will stop and release the resource 
it's using. and free_pgt_device() will free the "pgt device" remove it 
from the IDR pool. :)
>> +}
>> +
>> +/**
>> + * gvt_create_pgt_device - create a GVT physical device
>> + * @dev: drm device
>> + *
>> + * This function is called at the initialization stage, to create a physical
>> + * GVT device and initialize necessary GVT components for it.
>> + *
>> + * Returns:
>> + * pointer to the pgt_device structure, NULL if failed.
>> + */
>> +void *gvt_create_pgt_device(struct drm_i915_private *dev_priv)
>> +{
>> +	struct pgt_device *pdev = NULL;
>> +	struct gvt_host *host = &gvt_host;
>> +	int rc;
>> +
>> +	if (!host->initialized && !gvt_init_host()) {
>> +		gvt_err("gvt_init_host fail");
>> +		return NULL;
>> +	}
>> +
>> +	gvt_dbg_core("create new pgt device, i915 dev_priv: %p", dev_priv);
>> +
>> +	pdev = alloc_pgt_device(dev_priv);
>> +	if (!pdev) {
>> +		gvt_err("fail to allocate memory for pgt device.");
>> +		goto err;
>> +	}
>> +
>> +	gvt_dbg_core("init pgt device, id %d", pdev->id);
>> +
>> +	rc = init_pgt_device(pdev, dev_priv);
>> +	if (rc) {
>
> Just call the return value variable ret like everywhere.
>
Sure. Good idea.
>> +		gvt_err("fail to init physical device state.");
>> +		goto err;
>> +	}
>> +
>> +	gvt_dbg_core("pgt device creation done, id %d", pdev->id);
>> +
>> +	return pdev;
>> +err:
>> +	if (pdev) {
>> +		gvt_destroy_pgt_device(pdev);
>> +		pdev = NULL;
>> +	}
>
> Proper goto label based teardown path should be used.
>
Thanks. will change all error label like that.
> err_destroy_pgt:
> 	gvt_destroy_pgt_device(pdev);
> err:
>> +	return NULL;
>> +}
>> +
>> +/**
>> + * gvt_post_init_pgt_device - post init a GVT physical device
>> + * @dev: drm device
>
> Double check the kerneldocs to be correct per arguments of function.
>
Will correct it. :)
>> + *
>> + * This function is called at the end of the initialization stage, to
>> + * post-initialize a physical GVT device and initialize necessary
>> + * GVT components rely on i915 components.
>> + *
>> + * Returns:
>> + * zero on success, non-zero if failed.
>> + */
>> +int gvt_post_init_pgt_device(void *private_data)
>> +{
>> +	struct pgt_device *pdev = (struct pgt_device *)private_data;
>> +	struct gvt_host *host = &gvt_host;
>> +	int rc;
>> +
>> +	if (!host->initialized) {
>> +		gvt_err("gvt_host haven't been initialized.");
>> +		return -ENODEV;
>> +	}
>> +
>> +	gvt_dbg_core("post init pgt device %d", pdev->id);
>> +
>> +	rc = post_init_pgt_device(pdev);
>> +	if (rc) {
>> +		gvt_err("fail to post init physical device state.");
>> +		return rc;
>> +	}
>> +
>> +	return 0;
>> +}
>> diff --git a/drivers/gpu/drm/i915/gvt/gvt.h b/drivers/gpu/drm/i915/gvt/gvt.h
>> new file mode 100644
>> index 0000000..d450198
>> --- /dev/null
>> +++ b/drivers/gpu/drm/i915/gvt/gvt.h
>> @@ -0,0 +1,100 @@
>> +/*
>> + * 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.
>> + */
>> +
>> +#ifndef _GVT_H_
>> +#define _GVT_H_
>> +
>> +#include "i915_drv.h"
>> +#include "i915_vgpu.h"
>> +
>> +#include "debug.h"
>> +#include "params.h"
>> +#include "reg.h"
>> +#include "hypercall.h"
>> +#include "mpt.h"
>> +
>> +#define GVT_MAX_VGPU 8
>> +
>> +enum {
>> +	GVT_HYPERVISOR_TYPE_XEN = 0,
>> +	GVT_HYPERVISOR_TYPE_KVM,
>> +};
>> +
>> +struct gvt_host {
>> +	bool initialized;
>> +	int hypervisor_type;
>> +	struct mutex device_idr_lock;
>> +	struct idr device_idr;
>> +	struct gvt_kernel_dm *kdm;
>> +};
>> +
>> +extern struct gvt_host gvt_host;
>
> -->
>
>> +extern struct gvt_kernel_dm xengt_kdm;
>> +extern struct gvt_kernel_dm kvmgt_kdm;
>
> <-- These should likely be declared somewhere in include/ rather than
> here.
>
Will check how i915 does. :)
>> +
>> +/* Describe the limitation of HW.*/
>> +struct gvt_device_info {
>> +	u64 max_gtt_gm_sz;
>> +	u32 gtt_start_offset;
>> +	u32 gtt_end_offset;
>> +	u32 max_gtt_size;
>> +	u32 gtt_entry_size;
>> +	u32 gtt_entry_size_shift;
>> +	u32 gmadr_bytes_in_cmd;
>> +	u32 mmio_size;
>> +};
>> +
>> +struct vgt_device {
>> +	int id;
>> +	int vm_id;
>> +	struct pgt_device *pdev;
>> +	bool warn_untrack;
>> +};
>> +
>> +struct pgt_device {
>
> Comments to this and other structs about what the memebers are.
>
>> +	struct mutex lock;
>> +	int id;
>> +
>> +	struct drm_i915_private *dev_priv;
>> +	struct idr instance_idr;
>> +
>> +	struct gvt_device_info device_info;
>> +
>> +	u8 initial_cfg_space[GVT_CFG_SPACE_SZ];
>> +	u64 bar_size[GVT_BAR_NUM];
>> +
>> +	u64 gttmmio_base;
>> +	void *gttmmio_va;
>> +
>> +	u64 gmadr_base;
>> +	void *gmadr_va;
>> +
>> +	u32 mmio_size;
>> +	u32 reg_num;
>> +
>> +	wait_queue_head_t service_thread_wq;
>> +	struct task_struct *service_thread;
>> +	unsigned long service_request;
>> +};
>> +
>> +#endif
>> diff --git a/drivers/gpu/drm/i915/gvt/hypercall.h b/drivers/gpu/drm/i915/gvt/hypercall.h
>> new file mode 100644
>> index 0000000..0a41874
>> --- /dev/null
>> +++ b/drivers/gpu/drm/i915/gvt/hypercall.h
>> @@ -0,0 +1,30 @@
>> +/*
>> + * 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.
>> + */
>> +
>> +#ifndef _GVT_HYPERCALL_H_
>> +#define _GVT_HYPERCALL_H_
>> +
>> +struct gvt_kernel_dm {
>> +};
>
My bad. :)
> I would prefer more code introduced here in the initial patch, or this
> can be introduced later in the series as whole.
>
> It unnecessarily complicates the review if some files and calls are
> introduced with no documentation and implementation and only later
> their implementation is added.
>
> I can't really review if using a structure is a good idea if I can't
> see the context or implementation of their use.
>
>> +
>> +#endif /* _GVT_HYPERCALL_H_ */
>> diff --git a/drivers/gpu/drm/i915/gvt/mpt.h b/drivers/gpu/drm/i915/gvt/mpt.h
>> new file mode 100644
>> index 0000000..e594bb8
>> --- /dev/null
>> +++ b/drivers/gpu/drm/i915/gvt/mpt.h
>> @@ -0,0 +1,34 @@
>> +/*
>> + * 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.
>> + */
>> +
>> +#ifndef _GVT_MPT_H_
>> +#define _GVT_MPT_H_
>> +
>> +struct vgt_device;
>> +
>> +static inline bool hypervisor_detect_host(void)
>> +{
>> +	return false;
>> +}
>
> This is also not very reviewable and there's an unnecessary forward
> declaration.
>
>> +
>> +#endif /* _GVT_MPT_H_ */
>> diff --git a/drivers/gpu/drm/i915/gvt/params.c b/drivers/gpu/drm/i915/gvt/params.c
>> new file mode 100644
>> index 0000000..d381d17
>> --- /dev/null
>> +++ b/drivers/gpu/drm/i915/gvt/params.c
>> @@ -0,0 +1,32 @@
>> +/*
>> + * 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.
>> + */
>> +
>> +#include "gvt.h"
>> +
>> +struct gvt_kernel_params gvt = {
>> +	.enable = false,
>> +	.debug = 0,
>> +};
>> +
>> +module_param_named(gvt_enable, gvt.enable, bool, 0600);
>
> This should just be
>
> 	module_param_named(enable, gvt.enable, bool, ...)
>
> otherwise parameter has to be passed at boot time like this:
> 	
> 	gvt.gvt_enable=1
>
> Where we want
>
> 	gvt.enable=1
>
> Right?
>
Yes. Will move these params into intel_gvt.c

>> +MODULE_PARM_DESC(gvt_enable, "Enable Intel GVT-g host support");
>> diff --git a/drivers/gpu/drm/i915/gvt/params.h b/drivers/gpu/drm/i915/gvt/params.h
>> new file mode 100644
>> index 0000000..d2955b9
>> --- /dev/null
>> +++ b/drivers/gpu/drm/i915/gvt/params.h
>> @@ -0,0 +1,34 @@
>> +/*
>> + * 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.
>> + */
>> +
>> +#ifndef _GVT_PARAMS_H_
>> +#define _GVT_PARAMS_H_
>> +
>> +struct gvt_kernel_params {
>> +	bool enable;
>> +	int debug;
>
> This member is unused currently, can be dropped.
>
Will remove that.
>> +};
>> +
>> +extern struct gvt_kernel_params gvt;
>> +
>> +#endif
>> diff --git a/drivers/gpu/drm/i915/gvt/reg.h b/drivers/gpu/drm/i915/gvt/reg.h
>> new file mode 100644
>> index 0000000..d363b74
>> --- /dev/null
>> +++ b/drivers/gpu/drm/i915/gvt/reg.h
>> @@ -0,0 +1,34 @@
>> +/*
>> + * 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.
>> + */
>> +
>> +#ifndef _GVT_REG_H
>> +#define _GVT_REG_H
>> +
>> +#define GVT_CFG_SPACE_SZ	256
>> +#define GVT_BAR_NUM		4
>> +
>> +#define GVT_REG_CFG_SPACE_BAR0	0x10
>> +#define GVT_REG_CFG_SPACE_BAR1	0x18
>> +#define GVT_REG_CFG_SPACE_BAR2	0x20
>
> Some documentation here would be great.
>
>> +
>> +#endif
>> diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
>> index 1c6d227..f3bed37 100644
>> --- a/drivers/gpu/drm/i915/i915_dma.c
>> +++ b/drivers/gpu/drm/i915/i915_dma.c
>> @@ -35,6 +35,7 @@
>>   #include "intel_drv.h"
>>   #include
>>   #include "i915_drv.h"
>> +#include "i915_gvt.h"
>>   #include "i915_vgpu.h"
>>   #include "i915_trace.h"
>>   #include
>> @@ -1045,6 +1046,10 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
>>
>>   	intel_uncore_init(dev);
>>
>> +	ret = intel_gvt_init(dev);
>> +	if (ret)
>> +		goto out_uncore_fini;
>> +
>>   	ret = i915_gem_gtt_init(dev);
>>   	if (ret)
>>   		goto out_uncore_fini;
>
> This needs to become "goto out_gvt_cleanup;"
>
Good idea. :)
>> @@ -1135,6 +1140,12 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
>>   		goto out_power_well;
>>   	}
>>
>> +	ret = intel_gvt_post_init(dev);
>> +	if (ret) {
>> +		DRM_ERROR("failed to post init pgt device\n");
>> +		goto out_power_well;
>> +	}
>> +
>>   	/*
>>   	 * Notify a valid surface after modesetting,
>>   	 * when running inside a VM.
>> @@ -1177,6 +1188,7 @@ out_gem_unload:
>>   out_gtt:
>>   	i915_global_gtt_cleanup(dev);
>
> out_gvt_cleanup:
>
>>   out_uncore_fini:
>>
>> +	intel_gvt_cleanup(dev);
>
> This needs to be lifted up to its own label ensure proper teardown if
> i915_gem_gtt_init() fails.
>
>>   	intel_uncore_fini(dev);
>>   	i915_mmio_cleanup(dev);
>>   put_bridge:
>> @@ -1223,6 +1235,8 @@ int i915_driver_unload(struct drm_device *dev)
>>
>>   	intel_modeset_cleanup(dev);
>>
>> +	intel_gvt_cleanup(dev);
>> +
>>   	/*
>>   	 * free the memory space allocated for the child device
>>   	 * config parsed from VBT
>> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
>> index 20d9dbd..2f897c3 100644
>> --- a/drivers/gpu/drm/i915/i915_drv.h
>> +++ b/drivers/gpu/drm/i915/i915_drv.h
>> @@ -1705,6 +1705,10 @@ struct i915_workarounds {
>>   	u32 hw_whitelist_count[I915_NUM_RINGS];
>>   };
>>
>> +struct i915_gvt {
>> +	void *pgt_device;
>> +};
>> +
>>   struct i915_virtual_gpu {
>>   	bool active;
>>   };
>> @@ -1744,6 +1748,8 @@ struct drm_i915_private {
>>
>>   	struct i915_virtual_gpu vgpu;
>>
>> +	struct i915_gvt gvt;
>> +
>>   	struct intel_guc guc;
>>
>>   	struct intel_csr csr;
>> @@ -2780,6 +2786,12 @@ void intel_uncore_forcewake_get__locked(struct drm_i915_private *dev_priv,
>>   void intel_uncore_forcewake_put__locked(struct drm_i915_private *dev_priv,
>>   					enum forcewake_domains domains);
>>   void assert_forcewakes_inactive(struct drm_i915_private *dev_priv);
>> +
>> +static inline bool intel_gvt_active(struct drm_device *dev)
>> +{
>> +	return to_i915(dev)->gvt.pgt_device ? true : false;
>> +}
>> +
>>   static inline bool intel_vgpu_active(struct drm_device *dev)
>>   {
>>   	return to_i915(dev)->vgpu.active;
>> diff --git a/drivers/gpu/drm/i915/i915_gvt.c b/drivers/gpu/drm/i915/i915_gvt.c
>> new file mode 100644
>> index 0000000..3ca7232
>> --- /dev/null
>> +++ b/drivers/gpu/drm/i915/i915_gvt.c
>> @@ -0,0 +1,93 @@
>> +/*
>> + * 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.
>> + */
>> +
>> +#include "i915_drv.h"
>> +#include "i915_gvt.h"
>> +
>> +/**
>> + * DOC: Intel GVT-g host support
>> + *
>> + * Intel GVT-g is a graphics virtualization technology which shares the
>> + * GPU among multiple virtual machines on a time-sharing basis. Each
>> + * virtual machine is presented a virtual GPU (vGPU), which has equivalent
>> + * features as the underlying physical GPU (pGPU), so i915 driver can run
>> + * seamlessly in a virtual machine. This file provides the englightments
>> + * of GVT and the necessary components used by GVT in i915 driver.
>> + */
>> +
>> +/**
>> + * intel_gvt_init - initialize GVT components at the beginning of i915
>> + * driver loading.
>> + * @dev: drm device *
>> + *
>> + * This function is called at the beginning of the initialization stage,
>> + * to initialize the GVT components that have to be initialized
>> + * before HW gets touched by other i915 components.
>> + */
>> +int intel_gvt_init(struct drm_device *dev)
>> +{
>> +	struct drm_i915_private *dev_priv = to_i915(dev);
>> +
>> +	dev_priv->gvt.pgt_device = gvt_create_pgt_device(dev_priv);
>> +	if (intel_gvt_active(dev))
>> +		DRM_DEBUG_DRIVER("GVT-g is running in host mode\n");
>> +
>> +	return 0;
>> +}
>> +
>> +/**
>> + * intel_gvt_post_init - initialize GVT components at the end of i915
>> + * driver loading.
>> + * @dev: drm device *
>> + *
>> + * This function is called at the end of the initialization stage,
>> + * to initialize the GVT components that have to be initialized after
>> + * other i915 components are ready.
>> + */
>> +int intel_gvt_post_init(struct drm_device *dev)
>> +{
>> +	struct drm_i915_private *dev_priv = to_i915(dev);
>> +
>> +	if (!intel_gvt_active(dev))
>> +		return 0;
>> +
>> +	return gvt_post_init_pgt_device(dev_priv->gvt.pgt_device);
>> +}
>> +
>> +/**
>> + * intel_gvt_cleanup - cleanup GVT components when i915 driver is unloading
>> + * @dev: drm device *
>> + *
>> + * This function is called at the i915 driver unloading stage, to shutdown
>> + * GVT components and release the related resources.
>> + */
>> +void intel_gvt_cleanup(struct drm_device *dev)
>> +{
>> +	struct drm_i915_private *dev_priv = to_i915(dev);
>> +
>> +	if (!intel_gvt_active(dev))
>> +		return;
>> +
>> +	gvt_destroy_pgt_device(dev_priv->gvt.pgt_device);
>> +	dev_priv->gvt.pgt_device = NULL;
>> +}
>> diff --git a/drivers/gpu/drm/i915/i915_gvt.h b/drivers/gpu/drm/i915/i915_gvt.h
>> new file mode 100644
>> index 0000000..30cc207
>> --- /dev/null
>> +++ b/drivers/gpu/drm/i915/i915_gvt.h
>> @@ -0,0 +1,49 @@
>> +/*
>> + * 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.
>> + */
>> +
>> +#ifndef _I915_GVT_H_
>> +#define _I915_GVT_H_
>
> I think this file could be intel_gvt.h (all remaining functions are
> intel_gvt), and have respective intel_gvt.c file.
>
>> +
>> +#ifdef CONFIG_DRM_I915_GVT
>
> Starting here --->
>
>> +extern void *gvt_create_pgt_device(struct drm_i915_private *dev_priv);
>> +extern int gvt_post_init_pgt_device(void *data);
>> +extern void gvt_destroy_pgt_device(void *data);
>> +
>
> <-- to here, these should go to their own include file at
> include/drm/i915_gvt.h For an example, see include/drm/i915_drm.h
>
> The respective export symbols then need to be exported, For an example
> see;
>
> 	EXPORT_SYMBOL_GPL(i915_gpu_raise);
>
>> +extern int intel_gvt_init(struct drm_device *dev);
>> +extern int intel_gvt_post_init(struct drm_device *dev);
>> +extern void intel_gvt_cleanup(struct drm_device *dev);
>> +#else
>> +extern int intel_gvt_init(struct drm_device *dev)
>
> These should, by convention, rather be static inline;
>
> static inline int intel_gvt_init(...)
>
Sorry I miss to check them here. Surely should be static inline.....
>> +{
>> +	return 0;
>> +}
>> +extern int intel_gvt_post_init(struct drm_device *dev)
>> +{
>> +	return 0;
>> +}
>> +extern void intel_gvt_cleanup(struct drm_device *dev)
>> +{
>> +}
>> +#endif
>> +
>> +#endif /* _I915_GVT_H_ */
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [RFCv2 10/14] drm/i915: update PDPs by condition when submit the LRC context
  2016-02-25 15:02     ` Wang, Zhi A
@ 2016-02-26 13:49       ` Joonas Lahtinen
  0 siblings, 0 replies; 46+ messages in thread
From: Joonas Lahtinen @ 2016-02-26 13:49 UTC (permalink / raw)
  To: Wang, Zhi A, Tian, Kevin, intel-gfx, igvt-g
  Cc: daniel.vetter, Cowperthwaite, David J, Lv, Zhiyuan

Hi,

On to, 2016-02-25 at 15:02 +0000, Wang, Zhi A wrote:
> 
> -----Original Message-----
> From: Tian, Kevin 
> Sent: Wednesday, February 24, 2016 4:50 PM
> To: Wang, Zhi A; intel-gfx@lists.freedesktop.org; igvt-g@lists.01.org
> Cc: Lv, Zhiyuan; Niu, Bing; Song, Jike; daniel.vetter@ffwll.ch; Cowperthwaite, David J; chris@chris-wilson.co.uk; joonas.lahtinen@linux.intel.com
> Subject: RE: [RFCv2 10/14] drm/i915: update PDPs by condition when submit the LRC context
> 
> > 
> > From: Wang, Zhi A
> > Sent: Thursday, February 18, 2016 7:42 PM
> > 
> > Previously the PDPs inside the ring context are updated at:
> > 
> > - When populate a LRC context
> > - Before submitting a LRC context (only for 32 bit PPGTT, as the amount
> > of used PDPs may change)
> > 
> > This patch postpones the PDPs upgrade to submission time, and will update
> > it by condition if the PPGTT is 48b. Under GVT-g, one GVT context will be
> > used by different guest, the PPGTT instance related to the context might
> > be changed before the submission time. And this patch gives GVT context
> > a chance to load the new PPGTT instance into an initialized context.
> Could you elaborate why we share one GVT context across different guest?
> A natural thought is that we'll create one GVT context per every guest
> context...
> 
> [Zhi] We don't have context creation/destroy notification in guest i915 driver.
> Because in our implementation we need an unique context id to anchor the
> relationship between shadow context and guest context, while i915 uses GGTT
> address as context id. In each context pin/unpin, the context id may be changes.

Does not this lead to plenty of unnecessary storing and restoring of
the context parameters?

I would imagine this to destroy performance.

Regards, Joonas

> 
> So it's not necessary to allocate multiple GVT context here. 
> 
> Thanks
> Kevin
-- 
Joonas Lahtinen
Open Source Technology Center
Intel Corporation
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [RFCv2 03/14] drm/i915: Introduce host graphics memory/fence partition for GVT-g
  2016-02-26  5:21         ` Zhi Wang
@ 2016-02-26 13:54           ` Joonas Lahtinen
  0 siblings, 0 replies; 46+ messages in thread
From: Joonas Lahtinen @ 2016-02-26 13:54 UTC (permalink / raw)
  To: Zhi Wang, Tian, Kevin, intel-gfx, igvt-g
  Cc: daniel.vetter, Cowperthwaite, David J, Lv, Zhiyuan

Hi,

On pe, 2016-02-26 at 13:21 +0800, Zhi Wang wrote:
> 
> On 02/24/16 15:42, Tian, Kevin wrote:
> > 
> > > 
> > > From: Wang, Zhi A
> > > Sent: Tuesday, February 23, 2016 9:23 PM
> > > > 
> > > > > 
> > > > > --- a/drivers/gpu/drm/i915/gvt/gvt.c
> > > > > +++ b/drivers/gpu/drm/i915/gvt/gvt.c
> > > > > @@ -348,6 +348,10 @@ void *gvt_create_pgt_device(struct drm_i915_private
> > > *dev_priv)
> > > > 
> > > > > 
> > > > >    		goto err;
> > > > >    	}
> > > > > 
> > > > > +	dev_priv->gvt.host_fence_sz = gvt.host_fence_sz;
> > > > > +	dev_priv->gvt.host_low_gm_sz_in_mb = gvt.host_low_gm_sz;
> > > > > +	dev_priv->gvt.host_high_gm_sz_in_mb = gvt.host_high_gm_sz;
> > > > I'm thinking, could we expose the pgt_device struct (at least
> > > > partially, and then have a PIMPL pattern), to avoid this kind of
> > > > duplication of declarations and unnecessary copies between i915 and
> > > > i915_gvt modules?
> > > > 
> > > > It's little rough that the gvt driver writes to i915_private struct.
> > > > I'd rather see that gvt.host_fence_sz and other variables get sanitized
> > > > and then written to pgt_device (maybe the public part would be
> > > > i915_pgt_device) and used by gvt and i915 code.
> > > > 
> > > > Was this ever considered?
> > > > 
> > > The previous version do something similar like that, both i915 and gvt
> > > reads GVT module kernel parameter but considered that GVT modules could
> > > be configured as "n" in kernel configuration, probably we should let
> > > i915 to store this information and GVT to configure it if GVT is active?
> > Agree with Joonas. We don't need another gvt wrap. Let's just expose
> > pgt_device directly. I believe all other information can be encapsulated
> > under pgt_device.
> > 
> How about this scheme:
> 
> 1. Move GVT kernel parameter into intel_gvt.{h, c}
> 2. Sanitize the partition configuration for host in intel_gvt.c
> 3. If CONFIG_DRM_I915_GVT = y, write the configuration into pgt_device 
> to inform GVT resource allocator ranges owned by host
> 

This sounds fine, if i915 driver wants to know about the gvt driver, it
will read its structure (if gvt was enabled), instead of gvt driver
pushing information to i915.

> > 
> > btw to match other description in the code, is it clear to rename pgt_device
> > to gvt_device?
> > 
> For the name of GVT physical device, if we use "gvt_device", it looks a 
> bit weird when both "gvt_device" and "vgt_device"(vGPU instance) 
> appeared in our code? :( And "pgpu" and "vgpu" also looks weird...
> 

The naming conventions are indeed very confusing, it would help if all
host related stuff was named gvt_* and client vgpu_*

Regards, Joonas

> > 
> > Another minor thing needs Joonas' feedback. Is it usual to capture
> > all module parameters belonging to one feature structurized together
> > (like 'gvt' in this patch), or just to leave them directly exposed?
> > 
> 
> > 
> > Thanks
> > Kevin
> > 
-- 
Joonas Lahtinen
Open Source Technology Center
Intel Corporation
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 46+ messages in thread

end of thread, other threads:[~2016-02-26 13:54 UTC | newest]

Thread overview: 46+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-02-18 11:42 [RFCv2 PATCH 00/14] gvt: Hacking i915 for GVT context requirement Zhi Wang
2016-02-18 11:42 ` [RFCv2 01/14] drm/i915: factor out i915_pvinfo.h Zhi Wang
2016-02-22 13:23   ` Joonas Lahtinen
2016-02-23  2:40     ` Zhi Wang
2016-02-18 11:42 ` [RFCv2 02/14] drm/i915/gvt: Introduce the basic architecture of GVT-g Zhi Wang
2016-02-23 12:42   ` Joonas Lahtinen
2016-02-24  7:45     ` Tian, Kevin
2016-02-25 11:24       ` Joonas Lahtinen
2016-02-26  5:58     ` Zhi Wang
2016-02-23 12:53   ` Joonas Lahtinen
2016-02-24  7:50     ` Tian, Kevin
2016-02-24  8:08   ` Tian, Kevin
2016-02-26  5:38     ` Zhi Wang
2016-02-18 11:42 ` [RFCv2 03/14] drm/i915: Introduce host graphics memory/fence partition for GVT-g Zhi Wang
2016-02-23 13:16   ` Joonas Lahtinen
2016-02-23 13:23     ` Zhi Wang
2016-02-24  7:42       ` Tian, Kevin
2016-02-25 13:13         ` Joonas Lahtinen
2016-02-26  5:21         ` Zhi Wang
2016-02-26 13:54           ` Joonas Lahtinen
2016-02-23 13:26     ` Joonas Lahtinen
2016-02-24  8:22   ` Tian, Kevin
2016-02-26  5:29     ` Zhi Wang
2016-02-18 11:42 ` [RFCv2 04/14] drm/i915: factor out alloc_context_idr() and __i915_gem_create_context() Zhi Wang
2016-02-24  8:27   ` Tian, Kevin
2016-02-18 11:42 ` [RFCv2 05/14] drm/i915: factor out __create_legacy_hw_context() Zhi Wang
2016-02-18 11:42 ` [RFCv2 06/14] drm/i915: let __i915_gem_context_create() takes context creation params Zhi Wang
2016-02-24  8:35   ` Tian, Kevin
2016-02-18 11:42 ` [RFCv2 07/14] drm/i915: factor out __intel_lr_context_deferred_alloc() Zhi Wang
2016-02-24  8:37   ` Tian, Kevin
2016-02-18 11:42 ` [RFCv2 08/14] drm/i915: Support per-PPGTT address space mode Zhi Wang
2016-02-24  8:47   ` Tian, Kevin
2016-02-18 11:42 ` [RFCv2 09/14] drm/i915: generate address mode bit from PPGTT instance Zhi Wang
2016-02-18 11:42 ` [RFCv2 10/14] drm/i915: update PDPs by condition when submit the LRC context Zhi Wang
2016-02-24  8:49   ` Tian, Kevin
2016-02-25 15:02     ` Wang, Zhi A
2016-02-26 13:49       ` Joonas Lahtinen
2016-02-18 11:42 ` [RFCv2 11/14] drm/i915: Introduce execlist context status change notification Zhi Wang
2016-02-18 11:42 ` [RFCv2 12/14] drm/i915: factor out execlists_i915_pick_requests() Zhi Wang
2016-02-18 11:42 ` [RFCv2 13/14] drm/i915: Support context single submission when GVT is active Zhi Wang
2016-02-24  8:52   ` Tian, Kevin
2016-02-18 11:42 ` [RFCv2 14/14] drm/i915: Introduce GVT context creation API Zhi Wang
2016-02-18 12:02 ` ✗ Fi.CI.BAT: failure for gvt: Hacking i915 for GVT context requirement Patchwork
2016-02-24  8:55 ` [RFCv2 PATCH 00/14] " Tian, Kevin
2016-02-24  9:18   ` Wang, Zhi A
2016-02-24  9:38     ` Tian, Kevin

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.