Просмотр исходного кода

Merge tag 'gvt-next-fix-2016-10-20' of https://github.com/01org/gvt-linux into drm-intel-next-queued

gvt-next-fix-2016-10-20

This contains fix for first pull request.
- clean up header mess between i915 core and gvt
- new MAINTAINERS item
- new kernel-doc section
- fix compiling warnings
- gvt gem fix series from Chris
- fix for i915 intel_engine_cs change
- some sparse fixes from Changbin

Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Daniel Vetter 9 лет назад
Родитель
Сommit
41842d6bab

+ 9 - 0
Documentation/gpu/i915.rst

@@ -49,6 +49,15 @@ Intel GVT-g Guest Support(vGPU)
 .. kernel-doc:: drivers/gpu/drm/i915/i915_vgpu.c
 .. kernel-doc:: drivers/gpu/drm/i915/i915_vgpu.c
    :internal:
    :internal:
 
 
+Intel GVT-g Host Support(vGPU device model)
+-------------------------------------------
+
+.. kernel-doc:: drivers/gpu/drm/i915/intel_gvt.c
+   :doc: Intel GVT-g host support
+
+.. kernel-doc:: drivers/gpu/drm/i915/intel_gvt.c
+   :internal:
+
 Display Hardware Handling
 Display Hardware Handling
 =========================
 =========================
 
 

+ 10 - 0
MAINTAINERS

@@ -4009,6 +4009,16 @@ F:	include/drm/i915*
 F:	include/uapi/drm/i915_drm.h
 F:	include/uapi/drm/i915_drm.h
 F:	Documentation/gpu/i915.rst
 F:	Documentation/gpu/i915.rst
 
 
+INTEL GVT-g DRIVERS (Intel GPU Virtualization)
+M:      Zhenyu Wang <zhenyuw@linux.intel.com>
+M:      Zhi Wang <zhi.a.wang@intel.com>
+L:      igvt-g-dev@lists.01.org
+L:      intel-gfx@lists.freedesktop.org
+W:      https://01.org/igvt-g
+T:      git https://github.com/01org/gvt-linux.git
+S:      Supported
+F:      drivers/gpu/drm/i915/gvt/
+
 DRM DRIVERS FOR ATMEL HLCDC
 DRM DRIVERS FOR ATMEL HLCDC
 M:	Boris Brezillon <boris.brezillon@free-electrons.com>
 M:	Boris Brezillon <boris.brezillon@free-electrons.com>
 L:	dri-devel@lists.freedesktop.org
 L:	dri-devel@lists.freedesktop.org

+ 11 - 0
drivers/gpu/drm/i915/gvt/aperture_gm.c

@@ -35,6 +35,7 @@
  */
  */
 
 
 #include "i915_drv.h"
 #include "i915_drv.h"
+#include "gvt.h"
 
 
 #define MB_TO_BYTES(mb) ((mb) << 20ULL)
 #define MB_TO_BYTES(mb) ((mb) << 20ULL)
 #define BYTES_TO_MB(b) ((b) >> 20ULL)
 #define BYTES_TO_MB(b) ((b) >> 20ULL)
@@ -144,6 +145,8 @@ void intel_vgpu_write_fence(struct intel_vgpu *vgpu,
 	struct drm_i915_fence_reg *reg;
 	struct drm_i915_fence_reg *reg;
 	i915_reg_t fence_reg_lo, fence_reg_hi;
 	i915_reg_t fence_reg_lo, fence_reg_hi;
 
 
+	assert_rpm_wakelock_held(dev_priv);
+
 	if (WARN_ON(fence > vgpu_fence_sz(vgpu)))
 	if (WARN_ON(fence > vgpu_fence_sz(vgpu)))
 		return;
 		return;
 
 
@@ -172,6 +175,8 @@ static void free_vgpu_fence(struct intel_vgpu *vgpu)
 	if (WARN_ON(!vgpu_fence_sz(vgpu)))
 	if (WARN_ON(!vgpu_fence_sz(vgpu)))
 		return;
 		return;
 
 
+	intel_runtime_pm_get(dev_priv);
+
 	mutex_lock(&dev_priv->drm.struct_mutex);
 	mutex_lock(&dev_priv->drm.struct_mutex);
 	for (i = 0; i < vgpu_fence_sz(vgpu); i++) {
 	for (i = 0; i < vgpu_fence_sz(vgpu); i++) {
 		reg = vgpu->fence.regs[i];
 		reg = vgpu->fence.regs[i];
@@ -180,6 +185,8 @@ static void free_vgpu_fence(struct intel_vgpu *vgpu)
 			      &dev_priv->mm.fence_list);
 			      &dev_priv->mm.fence_list);
 	}
 	}
 	mutex_unlock(&dev_priv->drm.struct_mutex);
 	mutex_unlock(&dev_priv->drm.struct_mutex);
+
+	intel_runtime_pm_put(dev_priv);
 }
 }
 
 
 static int alloc_vgpu_fence(struct intel_vgpu *vgpu)
 static int alloc_vgpu_fence(struct intel_vgpu *vgpu)
@@ -190,6 +197,8 @@ static int alloc_vgpu_fence(struct intel_vgpu *vgpu)
 	int i;
 	int i;
 	struct list_head *pos, *q;
 	struct list_head *pos, *q;
 
 
+	intel_runtime_pm_get(dev_priv);
+
 	/* Request fences from host */
 	/* Request fences from host */
 	mutex_lock(&dev_priv->drm.struct_mutex);
 	mutex_lock(&dev_priv->drm.struct_mutex);
 	i = 0;
 	i = 0;
@@ -207,6 +216,7 @@ static int alloc_vgpu_fence(struct intel_vgpu *vgpu)
 		goto out_free_fence;
 		goto out_free_fence;
 
 
 	mutex_unlock(&dev_priv->drm.struct_mutex);
 	mutex_unlock(&dev_priv->drm.struct_mutex);
+	intel_runtime_pm_put(dev_priv);
 	return 0;
 	return 0;
 out_free_fence:
 out_free_fence:
 	/* Return fences to host, if fail */
 	/* Return fences to host, if fail */
@@ -218,6 +228,7 @@ out_free_fence:
 			      &dev_priv->mm.fence_list);
 			      &dev_priv->mm.fence_list);
 	}
 	}
 	mutex_unlock(&dev_priv->drm.struct_mutex);
 	mutex_unlock(&dev_priv->drm.struct_mutex);
+	intel_runtime_pm_put(dev_priv);
 	return -ENOSPC;
 	return -ENOSPC;
 }
 }
 
 

+ 1 - 0
drivers/gpu/drm/i915/gvt/cfg_space.c

@@ -32,6 +32,7 @@
  */
  */
 
 
 #include "i915_drv.h"
 #include "i915_drv.h"
+#include "gvt.h"
 
 
 enum {
 enum {
 	INTEL_GVT_PCI_BAR_GTTMMIO = 0,
 	INTEL_GVT_PCI_BAR_GTTMMIO = 0,

+ 44 - 91
drivers/gpu/drm/i915/gvt/cmd_parser.c

@@ -36,6 +36,8 @@
 
 
 #include <linux/slab.h>
 #include <linux/slab.h>
 #include "i915_drv.h"
 #include "i915_drv.h"
+#include "gvt.h"
+#include "i915_pvinfo.h"
 #include "trace.h"
 #include "trace.h"
 
 
 #define INVALID_OP    (~0U)
 #define INVALID_OP    (~0U)
@@ -478,8 +480,8 @@ struct parser_exec_state {
 #define gmadr_dw_number(s)	\
 #define gmadr_dw_number(s)	\
 	(s->vgpu->gvt->device_info.gmadr_bytes_in_cmd >> 2)
 	(s->vgpu->gvt->device_info.gmadr_bytes_in_cmd >> 2)
 
 
-unsigned long bypass_scan_mask = 0;
-bool bypass_batch_buffer_scan = true;
+static unsigned long bypass_scan_mask = 0;
+static bool bypass_batch_buffer_scan = true;
 
 
 /* ring ALL, type = 0 */
 /* ring ALL, type = 0 */
 static struct sub_op_bits sub_op_mi[] = {
 static struct sub_op_bits sub_op_mi[] = {
@@ -958,7 +960,7 @@ struct cmd_interrupt_event {
 	int mi_user_interrupt;
 	int mi_user_interrupt;
 };
 };
 
 
-struct cmd_interrupt_event cmd_interrupt_events[] = {
+static struct cmd_interrupt_event cmd_interrupt_events[] = {
 	[RCS] = {
 	[RCS] = {
 		.pipe_control_notify = RCS_PIPE_CONTROL,
 		.pipe_control_notify = RCS_PIPE_CONTROL,
 		.mi_flush_dw = INTEL_GVT_EVENT_RESERVED,
 		.mi_flush_dw = INTEL_GVT_EVENT_RESERVED,
@@ -1581,44 +1583,6 @@ static uint32_t find_bb_size(struct parser_exec_state *s)
 	return bb_size;
 	return bb_size;
 }
 }
 
 
-static u32 *vmap_batch(struct drm_i915_gem_object *obj,
-		       unsigned int start, unsigned int len)
-{
-	int i;
-	void *addr = NULL;
-	struct sg_page_iter sg_iter;
-	int first_page = start >> PAGE_SHIFT;
-	int last_page = (len + start + 4095) >> PAGE_SHIFT;
-	int npages = last_page - first_page;
-	struct page **pages;
-
-	pages = drm_malloc_ab(npages, sizeof(*pages));
-	if (pages == NULL) {
-		DRM_DEBUG_DRIVER("Failed to get space for pages\n");
-		goto finish;
-	}
-
-	i = 0;
-	for_each_sg_page(obj->pages->sgl, &sg_iter, obj->pages->nents,
-			 first_page) {
-		pages[i++] = sg_page_iter_page(&sg_iter);
-		if (i == npages)
-			break;
-	}
-
-	addr = vmap(pages, i, 0, PAGE_KERNEL);
-	if (addr == NULL) {
-		DRM_DEBUG_DRIVER("Failed to vmap pages\n");
-		goto finish;
-	}
-
-finish:
-	if (pages)
-		drm_free_large(pages);
-	return (u32 *)addr;
-}
-
-
 static int perform_bb_shadow(struct parser_exec_state *s)
 static int perform_bb_shadow(struct parser_exec_state *s)
 {
 {
 	struct intel_shadow_bb_entry *entry_obj;
 	struct intel_shadow_bb_entry *entry_obj;
@@ -1638,25 +1602,20 @@ static int perform_bb_shadow(struct parser_exec_state *s)
 	if (entry_obj == NULL)
 	if (entry_obj == NULL)
 		return -ENOMEM;
 		return -ENOMEM;
 
 
-	entry_obj->obj = i915_gem_object_create(&(s->vgpu->gvt->dev_priv->drm),
-		round_up(bb_size, PAGE_SIZE));
-	if (entry_obj->obj == NULL)
-		return -ENOMEM;
+	entry_obj->obj =
+		i915_gem_object_create(&(s->vgpu->gvt->dev_priv->drm),
+				       roundup(bb_size, PAGE_SIZE));
+	if (IS_ERR(entry_obj->obj)) {
+		ret = PTR_ERR(entry_obj->obj);
+		goto free_entry;
+	}
 	entry_obj->len = bb_size;
 	entry_obj->len = bb_size;
 	INIT_LIST_HEAD(&entry_obj->list);
 	INIT_LIST_HEAD(&entry_obj->list);
 
 
-	ret = i915_gem_object_get_pages(entry_obj->obj);
-	if (ret)
-		return ret;
-
-	i915_gem_object_pin_pages(entry_obj->obj);
-
-	/* get the va of the shadow batch buffer */
-	dst = (void *)vmap_batch(entry_obj->obj, 0, bb_size);
-	if (!dst) {
-		gvt_err("failed to vmap shadow batch\n");
-		ret = -ENOMEM;
-		goto unpin_src;
+	dst = i915_gem_object_pin_map(entry_obj->obj, I915_MAP_WB);
+	if (IS_ERR(dst)) {
+		ret = PTR_ERR(dst);
+		goto put_obj;
 	}
 	}
 
 
 	ret = i915_gem_object_set_to_cpu_domain(entry_obj->obj, false);
 	ret = i915_gem_object_set_to_cpu_domain(entry_obj->obj, false);
@@ -1670,10 +1629,11 @@ static int perform_bb_shadow(struct parser_exec_state *s)
 
 
 	/* copy batch buffer to shadow batch buffer*/
 	/* copy batch buffer to shadow batch buffer*/
 	ret = copy_gma_to_hva(s->vgpu, s->vgpu->gtt.ggtt_mm,
 	ret = copy_gma_to_hva(s->vgpu, s->vgpu->gtt.ggtt_mm,
-				gma, gma + bb_size, dst);
+			      gma, gma + bb_size,
+			      dst);
 	if (ret) {
 	if (ret) {
 		gvt_err("fail to copy guest ring buffer\n");
 		gvt_err("fail to copy guest ring buffer\n");
-		return ret;
+		goto unmap_src;
 	}
 	}
 
 
 	list_add(&entry_obj->list, &s->workload->shadow_bb);
 	list_add(&entry_obj->list, &s->workload->shadow_bb);
@@ -1691,10 +1651,11 @@ static int perform_bb_shadow(struct parser_exec_state *s)
 	return 0;
 	return 0;
 
 
 unmap_src:
 unmap_src:
-	vunmap(dst);
-unpin_src:
-	i915_gem_object_unpin_pages(entry_obj->obj);
-
+	i915_gem_object_unpin_map(entry_obj->obj);
+put_obj:
+	i915_gem_object_put(entry_obj->obj);
+free_entry:
+	kfree(entry_obj);
 	return ret;
 	return ret;
 }
 }
 
 
@@ -2707,55 +2668,47 @@ static int shadow_indirect_ctx(struct intel_shadow_wa_ctx *wa_ctx)
 	struct drm_device *dev = &wa_ctx->workload->vgpu->gvt->dev_priv->drm;
 	struct drm_device *dev = &wa_ctx->workload->vgpu->gvt->dev_priv->drm;
 	int ctx_size = wa_ctx->indirect_ctx.size;
 	int ctx_size = wa_ctx->indirect_ctx.size;
 	unsigned long guest_gma = wa_ctx->indirect_ctx.guest_gma;
 	unsigned long guest_gma = wa_ctx->indirect_ctx.guest_gma;
+	struct drm_i915_gem_object *obj;
 	int ret = 0;
 	int ret = 0;
-	void *dest = NULL;
-
-	wa_ctx->indirect_ctx.obj = i915_gem_object_create(dev,
-			round_up(ctx_size + CACHELINE_BYTES, PAGE_SIZE));
-	if (wa_ctx->indirect_ctx.obj == NULL)
-		return -ENOMEM;
+	void *map;
 
 
-	ret = i915_gem_object_get_pages(wa_ctx->indirect_ctx.obj);
-	if (ret)
-		return ret;
-
-	i915_gem_object_pin_pages(wa_ctx->indirect_ctx.obj);
+	obj = i915_gem_object_create(dev,
+				     roundup(ctx_size + CACHELINE_BYTES,
+					     PAGE_SIZE));
+	if (IS_ERR(obj))
+		return PTR_ERR(obj);
 
 
 	/* get the va of the shadow batch buffer */
 	/* get the va of the shadow batch buffer */
-	dest = (void *)vmap_batch(wa_ctx->indirect_ctx.obj, 0,
-			ctx_size + CACHELINE_BYTES);
-	if (!dest) {
+	map = i915_gem_object_pin_map(obj, I915_MAP_WB);
+	if (IS_ERR(map)) {
 		gvt_err("failed to vmap shadow indirect ctx\n");
 		gvt_err("failed to vmap shadow indirect ctx\n");
-		ret = -ENOMEM;
-		goto unpin_src;
+		ret = PTR_ERR(map);
+		goto put_obj;
 	}
 	}
 
 
-	ret = i915_gem_object_set_to_cpu_domain(wa_ctx->indirect_ctx.obj,
-			false);
+	ret = i915_gem_object_set_to_cpu_domain(obj, false);
 	if (ret) {
 	if (ret) {
 		gvt_err("failed to set shadow indirect ctx to CPU\n");
 		gvt_err("failed to set shadow indirect ctx to CPU\n");
 		goto unmap_src;
 		goto unmap_src;
 	}
 	}
 
 
-	wa_ctx->indirect_ctx.shadow_va = dest;
-
-	memset(dest, 0, round_up(ctx_size + CACHELINE_BYTES, PAGE_SIZE));
-
 	ret = copy_gma_to_hva(wa_ctx->workload->vgpu,
 	ret = copy_gma_to_hva(wa_ctx->workload->vgpu,
 				wa_ctx->workload->vgpu->gtt.ggtt_mm,
 				wa_ctx->workload->vgpu->gtt.ggtt_mm,
-				guest_gma, guest_gma + ctx_size, dest);
+				guest_gma, guest_gma + ctx_size,
+				map);
 	if (ret) {
 	if (ret) {
 		gvt_err("fail to copy guest indirect ctx\n");
 		gvt_err("fail to copy guest indirect ctx\n");
-		return ret;
+		goto unmap_src;
 	}
 	}
 
 
+	wa_ctx->indirect_ctx.obj = obj;
+	wa_ctx->indirect_ctx.shadow_va = map;
 	return 0;
 	return 0;
 
 
 unmap_src:
 unmap_src:
-	vunmap(dest);
-unpin_src:
-	i915_gem_object_unpin_pages(wa_ctx->indirect_ctx.obj);
-
+	i915_gem_object_unpin_map(obj);
+put_obj:
+	i915_gem_object_put(wa_ctx->indirect_ctx.obj);
 	return ret;
 	return ret;
 }
 }
 
 

+ 2 - 1
drivers/gpu/drm/i915/gvt/display.c

@@ -33,6 +33,7 @@
  */
  */
 
 
 #include "i915_drv.h"
 #include "i915_drv.h"
+#include "gvt.h"
 
 
 static int get_edp_pipe(struct intel_vgpu *vgpu)
 static int get_edp_pipe(struct intel_vgpu *vgpu)
 {
 {
@@ -119,7 +120,7 @@ static unsigned char virtual_dp_monitor_edid[] = {
 
 
 #define DPCD_HEADER_SIZE        0xb
 #define DPCD_HEADER_SIZE        0xb
 
 
-u8 dpcd_fix_data[DPCD_HEADER_SIZE] = {
+static u8 dpcd_fix_data[DPCD_HEADER_SIZE] = {
 	0x11, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
 	0x11, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
 };
 };
 
 

+ 1 - 0
drivers/gpu/drm/i915/gvt/edid.c

@@ -33,6 +33,7 @@
  */
  */
 
 
 #include "i915_drv.h"
 #include "i915_drv.h"
+#include "gvt.h"
 
 
 #define GMBUS1_TOTAL_BYTES_SHIFT 16
 #define GMBUS1_TOTAL_BYTES_SHIFT 16
 #define GMBUS1_TOTAL_BYTES_MASK 0x1ff
 #define GMBUS1_TOTAL_BYTES_MASK 0x1ff

+ 28 - 20
drivers/gpu/drm/i915/gvt/execlist.c

@@ -33,6 +33,7 @@
  */
  */
 
 
 #include "i915_drv.h"
 #include "i915_drv.h"
+#include "gvt.h"
 
 
 #define _EL_OFFSET_STATUS       0x234
 #define _EL_OFFSET_STATUS       0x234
 #define _EL_OFFSET_STATUS_BUF   0x370
 #define _EL_OFFSET_STATUS_BUF   0x370
@@ -385,8 +386,6 @@ static int set_gma_to_bb_cmd(struct intel_shadow_bb_entry *entry_obj,
 static void prepare_shadow_batch_buffer(struct intel_vgpu_workload *workload)
 static void prepare_shadow_batch_buffer(struct intel_vgpu_workload *workload)
 {
 {
 	int gmadr_bytes = workload->vgpu->gvt->device_info.gmadr_bytes_in_cmd;
 	int gmadr_bytes = workload->vgpu->gvt->device_info.gmadr_bytes_in_cmd;
-	struct i915_vma *vma;
-	unsigned long gma;
 
 
 	/* pin the gem object to ggtt */
 	/* pin the gem object to ggtt */
 	if (!list_empty(&workload->shadow_bb)) {
 	if (!list_empty(&workload->shadow_bb)) {
@@ -398,18 +397,24 @@ static void prepare_shadow_batch_buffer(struct intel_vgpu_workload *workload)
 
 
 		list_for_each_entry_safe(entry_obj, temp, &workload->shadow_bb,
 		list_for_each_entry_safe(entry_obj, temp, &workload->shadow_bb,
 				list) {
 				list) {
+			struct i915_vma *vma;
+
 			vma = i915_gem_object_ggtt_pin(entry_obj->obj, NULL, 0,
 			vma = i915_gem_object_ggtt_pin(entry_obj->obj, NULL, 0,
-					0, 0);
+						       4, 0);
 			if (IS_ERR(vma)) {
 			if (IS_ERR(vma)) {
 				gvt_err("Cannot pin\n");
 				gvt_err("Cannot pin\n");
 				return;
 				return;
 			}
 			}
-			i915_gem_object_unpin_pages(entry_obj->obj);
+
+			/* FIXME: we are not tracking our pinned VMA leaving it
+			 * up to the core to fix up the stray pin_count upon
+			 * free.
+			 */
 
 
 			/* update the relocate gma with shadow batch buffer*/
 			/* update the relocate gma with shadow batch buffer*/
-			gma = i915_gem_object_ggtt_offset(entry_obj->obj, NULL);
-			WARN_ON(!IS_ALIGNED(gma, 4));
-			set_gma_to_bb_cmd(entry_obj, gma, gmadr_bytes);
+			set_gma_to_bb_cmd(entry_obj,
+					  i915_ggtt_offset(vma),
+					  gmadr_bytes);
 		}
 		}
 	}
 	}
 }
 }
@@ -441,7 +446,6 @@ static int update_wa_ctx_2_shadow_ctx(struct intel_shadow_wa_ctx *wa_ctx)
 static void prepare_shadow_wa_ctx(struct intel_shadow_wa_ctx *wa_ctx)
 static void prepare_shadow_wa_ctx(struct intel_shadow_wa_ctx *wa_ctx)
 {
 {
 	struct i915_vma *vma;
 	struct i915_vma *vma;
-	unsigned long gma;
 	unsigned char *per_ctx_va =
 	unsigned char *per_ctx_va =
 		(unsigned char *)wa_ctx->indirect_ctx.shadow_va +
 		(unsigned char *)wa_ctx->indirect_ctx.shadow_va +
 		wa_ctx->indirect_ctx.size;
 		wa_ctx->indirect_ctx.size;
@@ -449,16 +453,19 @@ static void prepare_shadow_wa_ctx(struct intel_shadow_wa_ctx *wa_ctx)
 	if (wa_ctx->indirect_ctx.size == 0)
 	if (wa_ctx->indirect_ctx.size == 0)
 		return;
 		return;
 
 
-	vma = i915_gem_object_ggtt_pin(wa_ctx->indirect_ctx.obj, NULL, 0, 0, 0);
+	vma = i915_gem_object_ggtt_pin(wa_ctx->indirect_ctx.obj, NULL,
+				       0, CACHELINE_BYTES, 0);
 	if (IS_ERR(vma)) {
 	if (IS_ERR(vma)) {
 		gvt_err("Cannot pin indirect ctx obj\n");
 		gvt_err("Cannot pin indirect ctx obj\n");
 		return;
 		return;
 	}
 	}
-	i915_gem_object_unpin_pages(wa_ctx->indirect_ctx.obj);
 
 
-	gma = i915_gem_object_ggtt_offset(wa_ctx->indirect_ctx.obj, NULL);
-	WARN_ON(!IS_ALIGNED(gma, CACHELINE_BYTES));
-	wa_ctx->indirect_ctx.shadow_gma = gma;
+	/* FIXME: we are not tracking our pinned VMA leaving it
+	 * up to the core to fix up the stray pin_count upon
+	 * free.
+	 */
+
+	wa_ctx->indirect_ctx.shadow_gma = i915_ggtt_offset(vma);
 
 
 	wa_ctx->per_ctx.shadow_gma = *((unsigned int *)per_ctx_va + 1);
 	wa_ctx->per_ctx.shadow_gma = *((unsigned int *)per_ctx_va + 1);
 	memset(per_ctx_va, 0, CACHELINE_BYTES);
 	memset(per_ctx_va, 0, CACHELINE_BYTES);
@@ -498,8 +505,8 @@ static void release_shadow_batch_buffer(struct intel_vgpu_workload *workload)
 
 
 		list_for_each_entry_safe(entry_obj, temp, &workload->shadow_bb,
 		list_for_each_entry_safe(entry_obj, temp, &workload->shadow_bb,
 					 list) {
 					 list) {
-			drm_gem_object_unreference(&(entry_obj->obj->base));
-			kvfree(entry_obj->va);
+			i915_gem_object_unpin_map(entry_obj->obj);
+			i915_gem_object_put(entry_obj->obj);
 			list_del(&entry_obj->list);
 			list_del(&entry_obj->list);
 			kfree(entry_obj);
 			kfree(entry_obj);
 		}
 		}
@@ -511,8 +518,8 @@ static void release_shadow_wa_ctx(struct intel_shadow_wa_ctx *wa_ctx)
 	if (wa_ctx->indirect_ctx.size == 0)
 	if (wa_ctx->indirect_ctx.size == 0)
 		return;
 		return;
 
 
-	drm_gem_object_unreference(&(wa_ctx->indirect_ctx.obj->base));
-	kvfree(wa_ctx->indirect_ctx.shadow_va);
+	i915_gem_object_unpin_map(wa_ctx->indirect_ctx.obj);
+	i915_gem_object_put(wa_ctx->indirect_ctx.obj);
 }
 }
 
 
 static int complete_execlist_workload(struct intel_vgpu_workload *workload)
 static int complete_execlist_workload(struct intel_vgpu_workload *workload)
@@ -616,7 +623,7 @@ static int prepare_mm(struct intel_vgpu_workload *workload)
 	(list_empty(q) ? NULL : container_of(q->prev, \
 	(list_empty(q) ? NULL : container_of(q->prev, \
 	struct intel_vgpu_workload, list))
 	struct intel_vgpu_workload, list))
 
 
-bool submit_context(struct intel_vgpu *vgpu, int ring_id,
+static int submit_context(struct intel_vgpu *vgpu, int ring_id,
 		struct execlist_ctx_descriptor_format *desc,
 		struct execlist_ctx_descriptor_format *desc,
 		bool emulate_schedule_in)
 		bool emulate_schedule_in)
 {
 {
@@ -810,10 +817,11 @@ void intel_vgpu_clean_execlist(struct intel_vgpu *vgpu)
 
 
 int intel_vgpu_init_execlist(struct intel_vgpu *vgpu)
 int intel_vgpu_init_execlist(struct intel_vgpu *vgpu)
 {
 {
-	int i;
+	enum intel_engine_id i;
+	struct intel_engine_cs *engine;
 
 
 	/* each ring has a virtual execlist engine */
 	/* each ring has a virtual execlist engine */
-	for (i = 0; i < I915_NUM_ENGINES; i++) {
+	for_each_engine(engine, vgpu->gvt->dev_priv, i) {
 		init_vgpu_execlist(vgpu, i);
 		init_vgpu_execlist(vgpu, i);
 		INIT_LIST_HEAD(&vgpu->workload_q_head[i]);
 		INIT_LIST_HEAD(&vgpu->workload_q_head[i]);
 	}
 	}

+ 7 - 3
drivers/gpu/drm/i915/gvt/firmware.c

@@ -32,6 +32,8 @@
 #include <linux/crc32.h>
 #include <linux/crc32.h>
 
 
 #include "i915_drv.h"
 #include "i915_drv.h"
+#include "gvt.h"
+#include "i915_pvinfo.h"
 
 
 #define FIRMWARE_VERSION (0x0)
 #define FIRMWARE_VERSION (0x0)
 
 
@@ -49,7 +51,7 @@ struct gvt_firmware_header {
 #define RD(offset) (readl(mmio + offset.reg))
 #define RD(offset) (readl(mmio + offset.reg))
 #define WR(v, offset) (writel(v, mmio + offset.reg))
 #define WR(v, offset) (writel(v, mmio + offset.reg))
 
 
-static void bdw_forcewake_get(void *mmio)
+static void bdw_forcewake_get(void __iomem *mmio)
 {
 {
 	WR(_MASKED_BIT_DISABLE(0xffff), FORCEWAKE_MT);
 	WR(_MASKED_BIT_DISABLE(0xffff), FORCEWAKE_MT);
 
 
@@ -89,7 +91,8 @@ static struct bin_attribute firmware_attr = {
 	.mmap = NULL,
 	.mmap = NULL,
 };
 };
 
 
-static int expose_firmware_sysfs(struct intel_gvt *gvt, void *mmio)
+static int expose_firmware_sysfs(struct intel_gvt *gvt,
+					void __iomem *mmio)
 {
 {
 	struct intel_gvt_device_info *info = &gvt->device_info;
 	struct intel_gvt_device_info *info = &gvt->device_info;
 	struct pci_dev *pdev = gvt->dev_priv->drm.pdev;
 	struct pci_dev *pdev = gvt->dev_priv->drm.pdev;
@@ -232,7 +235,8 @@ int intel_gvt_load_firmware(struct intel_gvt *gvt)
 	struct gvt_firmware_header *h;
 	struct gvt_firmware_header *h;
 	const struct firmware *fw;
 	const struct firmware *fw;
 	char *path;
 	char *path;
-	void *mmio, *mem;
+	void __iomem *mmio;
+	void *mem;
 	int ret;
 	int ret;
 
 
 	path = kmalloc(PATH_MAX, GFP_KERNEL);
 	path = kmalloc(PATH_MAX, GFP_KERNEL);

+ 8 - 7
drivers/gpu/drm/i915/gvt/gtt.c

@@ -34,6 +34,8 @@
  */
  */
 
 
 #include "i915_drv.h"
 #include "i915_drv.h"
+#include "gvt.h"
+#include "i915_pvinfo.h"
 #include "trace.h"
 #include "trace.h"
 
 
 static bool enable_out_of_sync = false;
 static bool enable_out_of_sync = false;
@@ -267,7 +269,7 @@ static inline int get_pse_type(int type)
 
 
 static u64 read_pte64(struct drm_i915_private *dev_priv, unsigned long index)
 static u64 read_pte64(struct drm_i915_private *dev_priv, unsigned long index)
 {
 {
-	void *addr = (u64 *)dev_priv->ggtt.gsm + index;
+	void __iomem *addr = (gen8_pte_t __iomem *)dev_priv->ggtt.gsm + index;
 	u64 pte;
 	u64 pte;
 
 
 #ifdef readq
 #ifdef readq
@@ -282,7 +284,7 @@ static u64 read_pte64(struct drm_i915_private *dev_priv, unsigned long index)
 static void write_pte64(struct drm_i915_private *dev_priv,
 static void write_pte64(struct drm_i915_private *dev_priv,
 		unsigned long index, u64 pte)
 		unsigned long index, u64 pte)
 {
 {
-	void *addr = (u64 *)dev_priv->ggtt.gsm + index;
+	void __iomem *addr = (gen8_pte_t __iomem *)dev_priv->ggtt.gsm + index;
 
 
 #ifdef writeq
 #ifdef writeq
 	writeq(pte, addr);
 	writeq(pte, addr);
@@ -1919,7 +1921,7 @@ int intel_vgpu_emulate_gtt_mmio_write(struct intel_vgpu *vgpu, unsigned int off,
 	return ret;
 	return ret;
 }
 }
 
 
-bool intel_gvt_create_scratch_page(struct intel_vgpu *vgpu)
+static int create_scratch_page(struct intel_vgpu *vgpu)
 {
 {
 	struct intel_vgpu_gtt *gtt = &vgpu->gtt;
 	struct intel_vgpu_gtt *gtt = &vgpu->gtt;
 	void *p;
 	void *p;
@@ -1953,7 +1955,7 @@ bool intel_gvt_create_scratch_page(struct intel_vgpu *vgpu)
 	return 0;
 	return 0;
 }
 }
 
 
-void intel_gvt_release_scratch_page(struct intel_vgpu *vgpu)
+static void release_scratch_page(struct intel_vgpu *vgpu)
 {
 {
 	if (vgpu->gtt.scratch_page != NULL) {
 	if (vgpu->gtt.scratch_page != NULL) {
 		__free_page(vgpu->gtt.scratch_page);
 		__free_page(vgpu->gtt.scratch_page);
@@ -1993,8 +1995,7 @@ int intel_vgpu_init_gtt(struct intel_vgpu *vgpu)
 
 
 	gtt->ggtt_mm = ggtt_mm;
 	gtt->ggtt_mm = ggtt_mm;
 
 
-	intel_gvt_create_scratch_page(vgpu);
-	return 0;
+	return create_scratch_page(vgpu);
 }
 }
 
 
 /**
 /**
@@ -2013,7 +2014,7 @@ void intel_vgpu_clean_gtt(struct intel_vgpu *vgpu)
 	struct intel_vgpu_mm *mm;
 	struct intel_vgpu_mm *mm;
 
 
 	ppgtt_free_all_shadow_page(vgpu);
 	ppgtt_free_all_shadow_page(vgpu);
-	intel_gvt_release_scratch_page(vgpu);
+	release_scratch_page(vgpu);
 
 
 	list_for_each_safe(pos, n, &vgpu->gtt.mm_list_head) {
 	list_for_each_safe(pos, n, &vgpu->gtt.mm_list_head) {
 		mm = container_of(pos, struct intel_vgpu_mm, list);
 		mm = container_of(pos, struct intel_vgpu_mm, list);

+ 13 - 6
drivers/gpu/drm/i915/gvt/gvt.c

@@ -35,6 +35,7 @@
 #include <linux/kthread.h>
 #include <linux/kthread.h>
 
 
 #include "i915_drv.h"
 #include "i915_drv.h"
+#include "gvt.h"
 
 
 struct intel_gvt_host intel_gvt_host;
 struct intel_gvt_host intel_gvt_host;
 
 
@@ -173,9 +174,9 @@ static int init_service_thread(struct intel_gvt *gvt)
  */
  */
 void intel_gvt_clean_device(struct drm_i915_private *dev_priv)
 void intel_gvt_clean_device(struct drm_i915_private *dev_priv)
 {
 {
-	struct intel_gvt *gvt = &dev_priv->gvt;
+	struct intel_gvt *gvt = to_gvt(dev_priv);
 
 
-	if (WARN_ON(!gvt->initialized))
+	if (WARN_ON(!gvt))
 		return;
 		return;
 
 
 	clean_service_thread(gvt);
 	clean_service_thread(gvt);
@@ -188,7 +189,8 @@ void intel_gvt_clean_device(struct drm_i915_private *dev_priv)
 	intel_gvt_clean_mmio_info(gvt);
 	intel_gvt_clean_mmio_info(gvt);
 	intel_gvt_free_firmware(gvt);
 	intel_gvt_free_firmware(gvt);
 
 
-	gvt->initialized = false;
+	kfree(dev_priv->gvt);
+	dev_priv->gvt = NULL;
 }
 }
 
 
 /**
 /**
@@ -204,7 +206,7 @@ void intel_gvt_clean_device(struct drm_i915_private *dev_priv)
  */
  */
 int intel_gvt_init_device(struct drm_i915_private *dev_priv)
 int intel_gvt_init_device(struct drm_i915_private *dev_priv)
 {
 {
-	struct intel_gvt *gvt = &dev_priv->gvt;
+	struct intel_gvt *gvt;
 	int ret;
 	int ret;
 
 
 	/*
 	/*
@@ -214,9 +216,13 @@ int intel_gvt_init_device(struct drm_i915_private *dev_priv)
 	if (WARN_ON(!intel_gvt_host.initialized))
 	if (WARN_ON(!intel_gvt_host.initialized))
 		return -EINVAL;
 		return -EINVAL;
 
 
-	if (WARN_ON(gvt->initialized))
+	if (WARN_ON(dev_priv->gvt))
 		return -EEXIST;
 		return -EEXIST;
 
 
+	gvt = kzalloc(sizeof(struct intel_gvt), GFP_KERNEL);
+	if (!gvt)
+		return -ENOMEM;
+
 	gvt_dbg_core("init gvt device\n");
 	gvt_dbg_core("init gvt device\n");
 
 
 	mutex_init(&gvt->lock);
 	mutex_init(&gvt->lock);
@@ -261,7 +267,7 @@ int intel_gvt_init_device(struct drm_i915_private *dev_priv)
 		goto out_clean_cmd_parser;
 		goto out_clean_cmd_parser;
 
 
 	gvt_dbg_core("gvt device creation is done\n");
 	gvt_dbg_core("gvt device creation is done\n");
-	gvt->initialized = true;
+	dev_priv->gvt = gvt;
 	return 0;
 	return 0;
 
 
 out_clean_cmd_parser:
 out_clean_cmd_parser:
@@ -280,5 +286,6 @@ out_free_firmware:
 	intel_gvt_free_firmware(gvt);
 	intel_gvt_free_firmware(gvt);
 out_clean_mmio_info:
 out_clean_mmio_info:
 	intel_gvt_clean_mmio_info(gvt);
 	intel_gvt_clean_mmio_info(gvt);
+	kfree(gvt);
 	return ret;
 	return ret;
 }
 }

+ 6 - 3
drivers/gpu/drm/i915/gvt/gvt.h

@@ -186,14 +186,12 @@ struct intel_gvt_firmware {
 };
 };
 
 
 struct intel_gvt_opregion {
 struct intel_gvt_opregion {
-	void *opregion_va;
+	void __iomem *opregion_va;
 	u32 opregion_pa;
 	u32 opregion_pa;
 };
 };
 
 
 struct intel_gvt {
 struct intel_gvt {
 	struct mutex lock;
 	struct mutex lock;
-	bool initialized;
-
 	struct drm_i915_private *dev_priv;
 	struct drm_i915_private *dev_priv;
 	struct idr vgpu_idr;	/* vGPU IDR pool */
 	struct idr vgpu_idr;	/* vGPU IDR pool */
 
 
@@ -213,6 +211,11 @@ struct intel_gvt {
 	unsigned long service_request;
 	unsigned long service_request;
 };
 };
 
 
+static inline struct intel_gvt *to_gvt(struct drm_i915_private *i915)
+{
+	return i915->gvt;
+}
+
 enum {
 enum {
 	INTEL_GVT_REQUEST_EMULATE_VBLANK = 0,
 	INTEL_GVT_REQUEST_EMULATE_VBLANK = 0,
 };
 };

+ 8 - 5
drivers/gpu/drm/i915/gvt/handlers.c

@@ -37,6 +37,8 @@
  */
  */
 
 
 #include "i915_drv.h"
 #include "i915_drv.h"
+#include "gvt.h"
+#include "i915_pvinfo.h"
 
 
 /* XXX FIXME i915 has changed PP_XXX definition */
 /* XXX FIXME i915 has changed PP_XXX definition */
 #define PCH_PP_STATUS  _MMIO(0xc7200)
 #define PCH_PP_STATUS  _MMIO(0xc7200)
@@ -130,12 +132,13 @@ static int new_mmio_info(struct intel_gvt *gvt,
 
 
 static int render_mmio_to_ring_id(struct intel_gvt *gvt, unsigned int reg)
 static int render_mmio_to_ring_id(struct intel_gvt *gvt, unsigned int reg)
 {
 {
-	int i;
+	enum intel_engine_id id;
+	struct intel_engine_cs *engine;
 
 
 	reg &= ~GENMASK(11, 0);
 	reg &= ~GENMASK(11, 0);
-	for (i = 0; i < I915_NUM_ENGINES; i++) {
-		if (gvt->dev_priv->engine[i]->mmio_base == reg)
-			return i;
+	for_each_engine(engine, gvt->dev_priv, id) {
+		if (engine->mmio_base == reg)
+			return id;
 	}
 	}
 	return -1;
 	return -1;
 }
 }
@@ -1304,7 +1307,7 @@ static int elsp_mmio_write(struct intel_vgpu *vgpu, unsigned int offset,
 	u32 data = *(u32 *)p_data;
 	u32 data = *(u32 *)p_data;
 	int ret;
 	int ret;
 
 
-	if (WARN_ON(ring_id < 0))
+	if (WARN_ON(ring_id < 0 || ring_id > I915_NUM_ENGINES - 1))
 		return -EINVAL;
 		return -EINVAL;
 
 
 	execlist = &vgpu->execlist[ring_id];
 	execlist = &vgpu->execlist[ring_id];

+ 2 - 1
drivers/gpu/drm/i915/gvt/interrupt.c

@@ -30,6 +30,7 @@
  */
  */
 
 
 #include "i915_drv.h"
 #include "i915_drv.h"
+#include "gvt.h"
 
 
 /* common offset among interrupt control registers */
 /* common offset among interrupt control registers */
 #define regbase_to_isr(base)	(base)
 #define regbase_to_isr(base)	(base)
@@ -49,7 +50,7 @@
 static void update_upstream_irq(struct intel_vgpu *vgpu,
 static void update_upstream_irq(struct intel_vgpu *vgpu,
 		struct intel_gvt_irq_info *info);
 		struct intel_gvt_irq_info *info);
 
 
-const char * const irq_name[INTEL_GVT_EVENT_MAX] = {
+static const char * const irq_name[INTEL_GVT_EVENT_MAX] = {
 	[RCS_MI_USER_INTERRUPT] = "Render CS MI USER INTERRUPT",
 	[RCS_MI_USER_INTERRUPT] = "Render CS MI USER INTERRUPT",
 	[RCS_DEBUG] = "Render EU debug from SVG",
 	[RCS_DEBUG] = "Render EU debug from SVG",
 	[RCS_MMIO_SYNC_FLUSH] = "Render MMIO sync flush status",
 	[RCS_MMIO_SYNC_FLUSH] = "Render MMIO sync flush status",

+ 1 - 0
drivers/gpu/drm/i915/gvt/mmio.c

@@ -34,6 +34,7 @@
  */
  */
 
 
 #include "i915_drv.h"
 #include "i915_drv.h"
+#include "gvt.h"
 
 
 /**
 /**
  * intel_vgpu_gpa_to_mmio_offset - translate a GPA to MMIO offset
  * intel_vgpu_gpa_to_mmio_offset - translate a GPA to MMIO offset

+ 2 - 1
drivers/gpu/drm/i915/gvt/opregion.c

@@ -23,10 +23,11 @@
 
 
 #include <linux/acpi.h>
 #include <linux/acpi.h>
 #include "i915_drv.h"
 #include "i915_drv.h"
+#include "gvt.h"
 
 
 static int init_vgpu_opregion(struct intel_vgpu *vgpu, u32 gpa)
 static int init_vgpu_opregion(struct intel_vgpu *vgpu, u32 gpa)
 {
 {
-	void *host_va = vgpu->gvt->opregion.opregion_va;
+	void __iomem *host_va = vgpu->gvt->opregion.opregion_va;
 	u8 *buf;
 	u8 *buf;
 	int i;
 	int i;
 
 

+ 1 - 0
drivers/gpu/drm/i915/gvt/render.c

@@ -34,6 +34,7 @@
  */
  */
 
 
 #include "i915_drv.h"
 #include "i915_drv.h"
+#include "gvt.h"
 
 
 struct render_mmio {
 struct render_mmio {
 	int ring_id;
 	int ring_id;

+ 9 - 6
drivers/gpu/drm/i915/gvt/sched_policy.c

@@ -32,13 +32,15 @@
  */
  */
 
 
 #include "i915_drv.h"
 #include "i915_drv.h"
+#include "gvt.h"
 
 
 static bool vgpu_has_pending_workload(struct intel_vgpu *vgpu)
 static bool vgpu_has_pending_workload(struct intel_vgpu *vgpu)
 {
 {
 	struct intel_vgpu_execlist *execlist;
 	struct intel_vgpu_execlist *execlist;
-	int i;
+	enum intel_engine_id i;
+	struct intel_engine_cs *engine;
 
 
-	for (i = 0; i < I915_NUM_ENGINES; i++) {
+	for_each_engine(engine, vgpu->gvt->dev_priv, i) {
 		execlist = &vgpu->execlist[i];
 		execlist = &vgpu->execlist[i];
 		if (!list_empty(workload_q_head(vgpu, i)))
 		if (!list_empty(workload_q_head(vgpu, i)))
 			return true;
 			return true;
@@ -50,7 +52,8 @@ static bool vgpu_has_pending_workload(struct intel_vgpu *vgpu)
 static void try_to_schedule_next_vgpu(struct intel_gvt *gvt)
 static void try_to_schedule_next_vgpu(struct intel_gvt *gvt)
 {
 {
 	struct intel_gvt_workload_scheduler *scheduler = &gvt->scheduler;
 	struct intel_gvt_workload_scheduler *scheduler = &gvt->scheduler;
-	int i;
+	enum intel_engine_id i;
+	struct intel_engine_cs *engine;
 
 
 	/* no target to schedule */
 	/* no target to schedule */
 	if (!scheduler->next_vgpu)
 	if (!scheduler->next_vgpu)
@@ -66,7 +69,7 @@ static void try_to_schedule_next_vgpu(struct intel_gvt *gvt)
 	scheduler->need_reschedule = true;
 	scheduler->need_reschedule = true;
 
 
 	/* still have uncompleted workload? */
 	/* still have uncompleted workload? */
-	for (i = 0; i < I915_NUM_ENGINES; i++) {
+	for_each_engine(engine, gvt->dev_priv, i) {
 		if (scheduler->current_workload[i]) {
 		if (scheduler->current_workload[i]) {
 			gvt_dbg_sched("still have running workload\n");
 			gvt_dbg_sched("still have running workload\n");
 			return;
 			return;
@@ -83,7 +86,7 @@ static void try_to_schedule_next_vgpu(struct intel_gvt *gvt)
 	scheduler->need_reschedule = false;
 	scheduler->need_reschedule = false;
 
 
 	/* wake up workload dispatch thread */
 	/* wake up workload dispatch thread */
-	for (i = 0; i < I915_NUM_ENGINES; i++)
+	for_each_engine(engine, gvt->dev_priv, i)
 		wake_up(&scheduler->waitq[i]);
 		wake_up(&scheduler->waitq[i]);
 }
 }
 
 
@@ -233,7 +236,7 @@ static void tbs_sched_stop_schedule(struct intel_vgpu *vgpu)
 	list_del_init(&vgpu_data->list);
 	list_del_init(&vgpu_data->list);
 }
 }
 
 
-struct intel_gvt_sched_policy_ops tbs_schedule_ops = {
+static struct intel_gvt_sched_policy_ops tbs_schedule_ops = {
 	.init = tbs_sched_init,
 	.init = tbs_sched_init,
 	.clean = tbs_sched_clean,
 	.clean = tbs_sched_clean,
 	.init_vgpu = tbs_sched_init_vgpu,
 	.init_vgpu = tbs_sched_init_vgpu,

+ 34 - 28
drivers/gpu/drm/i915/gvt/scheduler.c

@@ -33,14 +33,16 @@
  *
  *
  */
  */
 
 
-#include "i915_drv.h"
-
 #include <linux/kthread.h>
 #include <linux/kthread.h>
 
 
+#include "i915_drv.h"
+#include "gvt.h"
+
 #define RING_CTX_OFF(x) \
 #define RING_CTX_OFF(x) \
 	offsetof(struct execlist_ring_context, x)
 	offsetof(struct execlist_ring_context, x)
 
 
-void set_context_pdp_root_pointer(struct execlist_ring_context *ring_context,
+static void set_context_pdp_root_pointer(
+		struct execlist_ring_context *ring_context,
 		u32 pdp[8])
 		u32 pdp[8])
 {
 {
 	struct execlist_mmio_pair *pdp_pair = &ring_context->pdp3_UDW;
 	struct execlist_mmio_pair *pdp_pair = &ring_context->pdp3_UDW;
@@ -163,6 +165,7 @@ static int dispatch_workload(struct intel_vgpu_workload *workload)
 	int ring_id = workload->ring_id;
 	int ring_id = workload->ring_id;
 	struct i915_gem_context *shadow_ctx = workload->vgpu->shadow_ctx;
 	struct i915_gem_context *shadow_ctx = workload->vgpu->shadow_ctx;
 	struct drm_i915_private *dev_priv = workload->vgpu->gvt->dev_priv;
 	struct drm_i915_private *dev_priv = workload->vgpu->gvt->dev_priv;
+	struct drm_i915_gem_request *rq;
 	int ret;
 	int ret;
 
 
 	gvt_dbg_sched("ring id %d prepare to dispatch workload %p\n",
 	gvt_dbg_sched("ring id %d prepare to dispatch workload %p\n",
@@ -171,17 +174,16 @@ static int dispatch_workload(struct intel_vgpu_workload *workload)
 	shadow_ctx->desc_template = workload->ctx_desc.addressing_mode <<
 	shadow_ctx->desc_template = workload->ctx_desc.addressing_mode <<
 				    GEN8_CTX_ADDRESSING_MODE_SHIFT;
 				    GEN8_CTX_ADDRESSING_MODE_SHIFT;
 
 
-	workload->req = i915_gem_request_alloc(dev_priv->engine[ring_id],
-					       shadow_ctx);
-	if (IS_ERR_OR_NULL(workload->req)) {
+	rq = i915_gem_request_alloc(dev_priv->engine[ring_id], shadow_ctx);
+	if (IS_ERR(rq)) {
 		gvt_err("fail to allocate gem request\n");
 		gvt_err("fail to allocate gem request\n");
-		workload->status = PTR_ERR(workload->req);
-		workload->req = NULL;
+		workload->status = PTR_ERR(rq);
 		return workload->status;
 		return workload->status;
 	}
 	}
 
 
-	gvt_dbg_sched("ring id %d get i915 gem request %p\n",
-			ring_id, workload->req);
+	gvt_dbg_sched("ring id %d get i915 gem request %p\n", ring_id, rq);
+
+	workload->req = i915_gem_request_get(rq);
 
 
 	mutex_lock(&gvt->lock);
 	mutex_lock(&gvt->lock);
 
 
@@ -208,16 +210,15 @@ static int dispatch_workload(struct intel_vgpu_workload *workload)
 	gvt_dbg_sched("ring id %d submit workload to i915 %p\n",
 	gvt_dbg_sched("ring id %d submit workload to i915 %p\n",
 			ring_id, workload->req);
 			ring_id, workload->req);
 
 
-	i915_add_request_no_flush(workload->req);
-
+	i915_add_request_no_flush(rq);
 	workload->dispatched = true;
 	workload->dispatched = true;
 	return 0;
 	return 0;
 err:
 err:
 	workload->status = ret;
 	workload->status = ret;
-	if (workload->req)
-		workload->req = NULL;
 
 
 	mutex_unlock(&gvt->lock);
 	mutex_unlock(&gvt->lock);
+
+	i915_add_request_no_flush(rq);
 	return ret;
 	return ret;
 }
 }
 
 
@@ -390,6 +391,8 @@ struct workload_thread_param {
 	int ring_id;
 	int ring_id;
 };
 };
 
 
+static DEFINE_MUTEX(scheduler_mutex);
+
 static int workload_thread(void *priv)
 static int workload_thread(void *priv)
 {
 {
 	struct workload_thread_param *p = (struct workload_thread_param *)priv;
 	struct workload_thread_param *p = (struct workload_thread_param *)priv;
@@ -414,22 +417,14 @@ static int workload_thread(void *priv)
 		if (kthread_should_stop())
 		if (kthread_should_stop())
 			break;
 			break;
 
 
+		mutex_lock(&scheduler_mutex);
+
 		gvt_dbg_sched("ring id %d next workload %p vgpu %d\n",
 		gvt_dbg_sched("ring id %d next workload %p vgpu %d\n",
 				workload->ring_id, workload,
 				workload->ring_id, workload,
 				workload->vgpu->id);
 				workload->vgpu->id);
 
 
 		intel_runtime_pm_get(gvt->dev_priv);
 		intel_runtime_pm_get(gvt->dev_priv);
 
 
-		/*
-		 * Always take i915 big lock first
-		 */
-		ret = i915_mutex_lock_interruptible(&gvt->dev_priv->drm);
-		if (ret < 0) {
-			gvt_err("i915 submission is not available, retry\n");
-			schedule_timeout(1);
-			continue;
-		}
-
 		gvt_dbg_sched("ring id %d will dispatch workload %p\n",
 		gvt_dbg_sched("ring id %d will dispatch workload %p\n",
 				workload->ring_id, workload);
 				workload->ring_id, workload);
 
 
@@ -437,7 +432,10 @@ static int workload_thread(void *priv)
 			intel_uncore_forcewake_get(gvt->dev_priv,
 			intel_uncore_forcewake_get(gvt->dev_priv,
 					FORCEWAKE_ALL);
 					FORCEWAKE_ALL);
 
 
+		mutex_lock(&gvt->dev_priv->drm.struct_mutex);
 		ret = dispatch_workload(workload);
 		ret = dispatch_workload(workload);
+		mutex_unlock(&gvt->dev_priv->drm.struct_mutex);
+
 		if (ret) {
 		if (ret) {
 			gvt_err("fail to dispatch workload, skip\n");
 			gvt_err("fail to dispatch workload, skip\n");
 			goto complete;
 			goto complete;
@@ -447,8 +445,7 @@ static int workload_thread(void *priv)
 				workload->ring_id, workload);
 				workload->ring_id, workload);
 
 
 		workload->status = i915_wait_request(workload->req,
 		workload->status = i915_wait_request(workload->req,
-						     I915_WAIT_INTERRUPTIBLE | I915_WAIT_LOCKED,
-						     NULL, NULL);
+						     0, NULL, NULL);
 		if (workload->status != 0)
 		if (workload->status != 0)
 			gvt_err("fail to wait workload, skip\n");
 			gvt_err("fail to wait workload, skip\n");
 
 
@@ -456,15 +453,20 @@ complete:
 		gvt_dbg_sched("will complete workload %p\n, status: %d\n",
 		gvt_dbg_sched("will complete workload %p\n, status: %d\n",
 				workload, workload->status);
 				workload, workload->status);
 
 
+		mutex_lock(&gvt->dev_priv->drm.struct_mutex);
 		complete_current_workload(gvt, ring_id);
 		complete_current_workload(gvt, ring_id);
+		mutex_unlock(&gvt->dev_priv->drm.struct_mutex);
+
+		i915_gem_request_put(fetch_and_zero(&workload->req));
 
 
 		if (need_force_wake)
 		if (need_force_wake)
 			intel_uncore_forcewake_put(gvt->dev_priv,
 			intel_uncore_forcewake_put(gvt->dev_priv,
 					FORCEWAKE_ALL);
 					FORCEWAKE_ALL);
 
 
-		mutex_unlock(&gvt->dev_priv->drm.struct_mutex);
-
 		intel_runtime_pm_put(gvt->dev_priv);
 		intel_runtime_pm_put(gvt->dev_priv);
+
+		mutex_unlock(&scheduler_mutex);
+
 	}
 	}
 	return 0;
 	return 0;
 }
 }
@@ -509,6 +511,10 @@ int intel_gvt_init_workload_scheduler(struct intel_gvt *gvt)
 	init_waitqueue_head(&scheduler->workload_complete_wq);
 	init_waitqueue_head(&scheduler->workload_complete_wq);
 
 
 	for (i = 0; i < I915_NUM_ENGINES; i++) {
 	for (i = 0; i < I915_NUM_ENGINES; i++) {
+		/* check ring mask at init time */
+		if (!HAS_ENGINE(gvt->dev_priv, i))
+			continue;
+
 		init_waitqueue_head(&scheduler->waitq[i]);
 		init_waitqueue_head(&scheduler->waitq[i]);
 
 
 		param = kzalloc(sizeof(*param), GFP_KERNEL);
 		param = kzalloc(sizeof(*param), GFP_KERNEL);

+ 2 - 0
drivers/gpu/drm/i915/gvt/vgpu.c

@@ -32,6 +32,8 @@
  */
  */
 
 
 #include "i915_drv.h"
 #include "i915_drv.h"
+#include "gvt.h"
+#include "i915_pvinfo.h"
 
 
 static void clean_vgpu_mmio(struct intel_vgpu *vgpu)
 static void clean_vgpu_mmio(struct intel_vgpu *vgpu)
 {
 {

+ 2 - 2
drivers/gpu/drm/i915/i915_drv.h

@@ -1777,7 +1777,7 @@ struct drm_i915_private {
 
 
 	struct i915_virtual_gpu vgpu;
 	struct i915_virtual_gpu vgpu;
 
 
-	struct intel_gvt gvt;
+	struct intel_gvt *gvt;
 
 
 	struct intel_guc guc;
 	struct intel_guc guc;
 
 
@@ -2993,7 +2993,7 @@ int intel_wait_for_register_fw(struct drm_i915_private *dev_priv,
 
 
 static inline bool intel_gvt_active(struct drm_i915_private *dev_priv)
 static inline bool intel_gvt_active(struct drm_i915_private *dev_priv)
 {
 {
-	return dev_priv->gvt.initialized;
+	return dev_priv->gvt;
 }
 }
 
 
 static inline bool intel_vgpu_active(struct drm_i915_private *dev_priv)
 static inline bool intel_vgpu_active(struct drm_i915_private *dev_priv)

+ 6 - 2
drivers/gpu/drm/i915/intel_gvt.c

@@ -31,8 +31,12 @@
  * GPU among multiple virtual machines on a time-sharing basis. Each
  * GPU among multiple virtual machines on a time-sharing basis. Each
  * virtual machine is presented a virtual GPU (vGPU), which has equivalent
  * virtual machine is presented a virtual GPU (vGPU), which has equivalent
  * features as the underlying physical GPU (pGPU), so i915 driver can run
  * 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.
+ * seamlessly in a virtual machine.
+ *
+ * To virtualize GPU resources GVT-g driver depends on hypervisor technology
+ * e.g KVM/VFIO/mdev, Xen, etc. to provide resource access trapping capability
+ * and be virtualized within GVT-g device module. More architectural design
+ * doc is available on https://01.org/group/2230/documentation-list.
  */
  */
 
 
 static bool is_supported_device(struct drm_i915_private *dev_priv)
 static bool is_supported_device(struct drm_i915_private *dev_priv)

+ 1 - 2
drivers/gpu/drm/i915/intel_gvt.h

@@ -24,8 +24,7 @@
 #ifndef _INTEL_GVT_H_
 #ifndef _INTEL_GVT_H_
 #define _INTEL_GVT_H_
 #define _INTEL_GVT_H_
 
 
-#include "i915_pvinfo.h"
-#include "gvt/gvt.h"
+struct intel_gvt;
 
 
 #ifdef CONFIG_DRM_I915_GVT
 #ifdef CONFIG_DRM_I915_GVT
 int intel_gvt_init(struct drm_i915_private *dev_priv);
 int intel_gvt_init(struct drm_i915_private *dev_priv);