174 lines
5.0 KiB
Diff
174 lines
5.0 KiB
Diff
From 14129866b449232393a42f27b86af972a2f61a10 Mon Sep 17 00:00:00 2001
|
|
From: Ping Gao <ping.a.gao@intel.com>
|
|
Date: Thu, 31 Aug 2017 10:45:05 +0800
|
|
Subject: [PATCH 531/550] drm/i915/gvt: Introduce non-context MMIO check
|
|
routines
|
|
|
|
Guest conformance check can be implemented by verifying whether the
|
|
non-context MMIOs have the same values with host snapshot.
|
|
|
|
This patch introduced some routines, snapshot the host registers values
|
|
and compare when with corresponding vregs by walking the non-context
|
|
MMIO list.
|
|
|
|
Signed-off-by: Ping Gao <ping.a.gao@intel.com>
|
|
Reviewed-by: Kevin Tian <kevin.tian@intel.com>
|
|
Reviewed-by: Singh, Satyeshwar <satyeshwar.singh@intel.com>
|
|
Reviewed-on:
|
|
Reviewed-by: He, Min <min.he@intel.com>
|
|
Reviewed-by: Jiang, Fei <fei.jiang@intel.com>
|
|
Reviewed-by: Dong, Eddie <eddie.dong@intel.com>
|
|
Tested-by: Dong, Eddie <eddie.dong@intel.com>
|
|
|
|
v2: rebase 4.19:
|
|
1. reuse engine_mmio_list->mmio in commit cd7e61b93d06 drm/i915/gvt:
|
|
init mmio by lri command in vgpu inhibit context
|
|
2. split part of code to 2b5955ee506d - drm/i915/gvt: Forbid command to
|
|
access non-context registers
|
|
|
|
Signed-off-by: Xinyun Liu <xinyun.liu@intel.com>
|
|
---
|
|
drivers/gpu/drm/i915/gvt/gvt.h | 6 ++
|
|
drivers/gpu/drm/i915/gvt/handlers.c | 9 +++
|
|
drivers/gpu/drm/i915/gvt/mmio_context.c | 76 +++++++++++++++++++++++++
|
|
3 files changed, 91 insertions(+)
|
|
|
|
diff --git a/drivers/gpu/drm/i915/gvt/gvt.h b/drivers/gpu/drm/i915/gvt/gvt.h
|
|
index 68cc50f75803..708d690b8c4f 100644
|
|
--- a/drivers/gpu/drm/i915/gvt/gvt.h
|
|
+++ b/drivers/gpu/drm/i915/gvt/gvt.h
|
|
@@ -289,10 +289,16 @@ struct intel_gvt_mmio {
|
|
struct gvt_mmio_block *mmio_block;
|
|
unsigned int num_mmio_block;
|
|
|
|
+ void *mmio_host_cache;
|
|
+ bool host_cache_initialized;
|
|
DECLARE_HASHTABLE(mmio_info_table, INTEL_GVT_MMIO_HASH_BITS);
|
|
unsigned long num_tracked_mmio;
|
|
};
|
|
|
|
+/* Macro for easily access host engine mmio cached register */
|
|
+#define gvt_host_reg(gvt, reg) \
|
|
+ (*(u32 *)(gvt->mmio.mmio_host_cache + reg)) \
|
|
+
|
|
struct intel_gvt_firmware {
|
|
void *cfg_space;
|
|
void *mmio;
|
|
diff --git a/drivers/gpu/drm/i915/gvt/handlers.c b/drivers/gpu/drm/i915/gvt/handlers.c
|
|
index ce25433c6d77..f923ca71ab8e 100644
|
|
--- a/drivers/gpu/drm/i915/gvt/handlers.c
|
|
+++ b/drivers/gpu/drm/i915/gvt/handlers.c
|
|
@@ -3435,6 +3435,9 @@ void intel_gvt_clean_mmio_info(struct intel_gvt *gvt)
|
|
|
|
vfree(gvt->mmio.mmio_attribute);
|
|
gvt->mmio.mmio_attribute = NULL;
|
|
+
|
|
+ vfree(gvt->mmio.mmio_host_cache);
|
|
+ gvt->mmio.mmio_host_cache = NULL;
|
|
}
|
|
|
|
/* Special MMIO blocks. */
|
|
@@ -3469,6 +3472,12 @@ int intel_gvt_setup_mmio_info(struct intel_gvt *gvt)
|
|
if (!gvt->mmio.mmio_attribute)
|
|
return -ENOMEM;
|
|
|
|
+ gvt->mmio.mmio_host_cache = vzalloc(info->mmio_size);
|
|
+ if (!gvt->mmio.mmio_host_cache) {
|
|
+ vfree(gvt->mmio.mmio_attribute);
|
|
+ return -ENOMEM;
|
|
+ }
|
|
+
|
|
ret = init_generic_mmio_info(gvt);
|
|
if (ret)
|
|
goto err;
|
|
diff --git a/drivers/gpu/drm/i915/gvt/mmio_context.c b/drivers/gpu/drm/i915/gvt/mmio_context.c
|
|
index 0221e87f34db..99b01ab60dc3 100644
|
|
--- a/drivers/gpu/drm/i915/gvt/mmio_context.c
|
|
+++ b/drivers/gpu/drm/i915/gvt/mmio_context.c
|
|
@@ -567,6 +567,82 @@ void intel_gvt_switch_mmio(struct intel_vgpu *pre,
|
|
intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
|
|
}
|
|
|
|
+#define MMIO_COMPARE(vgpu, reg, mask) ({ \
|
|
+ int ret; \
|
|
+ u32 value = vgpu_vreg(vgpu, reg); \
|
|
+ u32 host_value = gvt_host_reg(vgpu->gvt, reg); \
|
|
+ \
|
|
+ if (mask) { \
|
|
+ value &= mask; \
|
|
+ host_value &= mask; \
|
|
+ } \
|
|
+ if (host_value == value) { \
|
|
+ ret = 0; \
|
|
+ } else { \
|
|
+ gvt_err("vgpu%d unconformance mmio 0x%x:0x%x,0x%x\n", \
|
|
+ vgpu->id, reg, \
|
|
+ vgpu_vreg(vgpu, reg), \
|
|
+ gvt_host_reg(vgpu->gvt, reg)); \
|
|
+ ret = -EINVAL; \
|
|
+ } \
|
|
+ ret; \
|
|
+ })
|
|
+
|
|
+static int noncontext_mmio_compare(struct intel_vgpu *vgpu, int ring_id)
|
|
+{
|
|
+ struct engine_mmio *mmio, *mmio_list;
|
|
+
|
|
+ mmio_list = vgpu->gvt->engine_mmio_list.mmio;
|
|
+
|
|
+ for (mmio = mmio_list; i915_mmio_reg_valid(mmio->reg); mmio++) {
|
|
+ if (mmio->ring_id != ring_id || mmio->in_context)
|
|
+ continue;
|
|
+
|
|
+ if (MMIO_COMPARE(vgpu, mmio->reg.reg, mmio->mask))
|
|
+ return -EINVAL;
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static void get_host_mmio_snapshot(struct intel_gvt *gvt)
|
|
+{
|
|
+ struct drm_i915_private *dev_priv = gvt->dev_priv;
|
|
+ struct engine_mmio *mmio, *mmio_list;
|
|
+
|
|
+ mmio_list = gvt->engine_mmio_list.mmio;
|
|
+
|
|
+ if (!gvt->mmio.host_cache_initialized) {
|
|
+ /* Snapshot all the non-context MMIOs */
|
|
+ for (mmio = mmio_list; i915_mmio_reg_valid(mmio->reg); mmio++) {
|
|
+ if (mmio->in_context)
|
|
+ continue;
|
|
+
|
|
+ gvt_host_reg(gvt, mmio->reg.reg) =
|
|
+ I915_READ_FW(mmio->reg);
|
|
+ if (mmio->mask)
|
|
+ gvt_host_reg(gvt, mmio->reg.reg) &= mmio->mask;
|
|
+ }
|
|
+ gvt->mmio.host_cache_initialized = true;
|
|
+ }
|
|
+}
|
|
+
|
|
+int intel_gvt_vgpu_conformance_check(struct intel_vgpu *vgpu, int ring_id)
|
|
+{
|
|
+ int ret;
|
|
+
|
|
+ get_host_mmio_snapshot(vgpu->gvt);
|
|
+
|
|
+ ret = noncontext_mmio_compare(vgpu, ring_id);
|
|
+ if (ret)
|
|
+ goto err;
|
|
+
|
|
+ return 0;
|
|
+err:
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+
|
|
/**
|
|
* intel_gvt_init_engine_mmio_context - Initiate the engine mmio list
|
|
* @gvt: GVT device
|
|
--
|
|
2.19.1
|
|
|