Commit 15e7f52a authored by Xiaolin Zhang's avatar Xiaolin Zhang Committed by Zhenyu Wang

drm/i915/gvt: save RING_HEAD into vreg when vgpu switched out

Save RING_HEAD into vgpu reg when vgpu switched out and report
it's value back to guest.

v6: addressed comment for ring head wrap count support. (Zhenyu)
v5: ring head wrap count support.
v4: updated HEAD/TAIL with guest value, not host value. (Yan Zhao)
v3: save RING HEAD/TAIL vgpu reg in save_ring_hw_state. (Zhenyu Wang)
v2: save RING_TAIL as well during vgpu mmio switch to meet ring_is_idle
condition. (Fred Gao)
v1: based on input from Weinan. (Weinan Li)

[zhenyuw: Include this fix for possible future guest kernel that
would utilize RING_HEAD for hangcheck.]
Reviewed-by: default avatarZhenyu Wang <zhenyuw@linux.intel.com>
Signed-off-by: default avatarXiaolin Zhang <xiaolin.zhang@intel.com>
Signed-off-by: default avatarZhenyu Wang <zhenyuw@linux.intel.com>
parent 3fcb01f8
...@@ -102,6 +102,8 @@ ...@@ -102,6 +102,8 @@
#define FORCEWAKE_ACK_MEDIA_GEN9_REG 0x0D88 #define FORCEWAKE_ACK_MEDIA_GEN9_REG 0x0D88
#define FORCEWAKE_ACK_HSW_REG 0x130044 #define FORCEWAKE_ACK_HSW_REG 0x130044
#define RB_HEAD_WRAP_CNT_MAX ((1 << 11) - 1)
#define RB_HEAD_WRAP_CNT_OFF 21
#define RB_HEAD_OFF_MASK ((1U << 21) - (1U << 2)) #define RB_HEAD_OFF_MASK ((1U << 21) - (1U << 2))
#define RB_TAIL_OFF_MASK ((1U << 21) - (1U << 3)) #define RB_TAIL_OFF_MASK ((1U << 21) - (1U << 3))
#define RB_TAIL_SIZE_MASK ((1U << 21) - (1U << 12)) #define RB_TAIL_SIZE_MASK ((1U << 21) - (1U << 12))
......
...@@ -812,10 +812,31 @@ static void update_guest_context(struct intel_vgpu_workload *workload) ...@@ -812,10 +812,31 @@ static void update_guest_context(struct intel_vgpu_workload *workload)
void *src; void *src;
unsigned long context_gpa, context_page_num; unsigned long context_gpa, context_page_num;
int i; int i;
struct drm_i915_private *dev_priv = gvt->dev_priv;
u32 ring_base;
u32 head, tail;
u16 wrap_count;
gvt_dbg_sched("ring id %d workload lrca %x\n", rq->engine->id, gvt_dbg_sched("ring id %d workload lrca %x\n", rq->engine->id,
workload->ctx_desc.lrca); workload->ctx_desc.lrca);
head = workload->rb_head;
tail = workload->rb_tail;
wrap_count = workload->guest_rb_head >> RB_HEAD_WRAP_CNT_OFF;
if (tail < head) {
if (wrap_count == RB_HEAD_WRAP_CNT_MAX)
wrap_count = 0;
else
wrap_count += 1;
}
head = (wrap_count << RB_HEAD_WRAP_CNT_OFF) | tail;
ring_base = dev_priv->engine[workload->ring_id]->mmio_base;
vgpu_vreg_t(vgpu, RING_TAIL(ring_base)) = tail;
vgpu_vreg_t(vgpu, RING_HEAD(ring_base)) = head;
context_page_num = rq->engine->context_size; context_page_num = rq->engine->context_size;
context_page_num = context_page_num >> PAGE_SHIFT; context_page_num = context_page_num >> PAGE_SHIFT;
...@@ -1415,6 +1436,7 @@ intel_vgpu_create_workload(struct intel_vgpu *vgpu, int ring_id, ...@@ -1415,6 +1436,7 @@ intel_vgpu_create_workload(struct intel_vgpu *vgpu, int ring_id,
struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv; struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv;
u64 ring_context_gpa; u64 ring_context_gpa;
u32 head, tail, start, ctl, ctx_ctl, per_ctx, indirect_ctx; u32 head, tail, start, ctl, ctx_ctl, per_ctx, indirect_ctx;
u32 guest_head;
int ret; int ret;
ring_context_gpa = intel_vgpu_gma_to_gpa(vgpu->gtt.ggtt_mm, ring_context_gpa = intel_vgpu_gma_to_gpa(vgpu->gtt.ggtt_mm,
...@@ -1430,6 +1452,8 @@ intel_vgpu_create_workload(struct intel_vgpu *vgpu, int ring_id, ...@@ -1430,6 +1452,8 @@ intel_vgpu_create_workload(struct intel_vgpu *vgpu, int ring_id,
intel_gvt_hypervisor_read_gpa(vgpu, ring_context_gpa + intel_gvt_hypervisor_read_gpa(vgpu, ring_context_gpa +
RING_CTX_OFF(ring_tail.val), &tail, 4); RING_CTX_OFF(ring_tail.val), &tail, 4);
guest_head = head;
head &= RB_HEAD_OFF_MASK; head &= RB_HEAD_OFF_MASK;
tail &= RB_TAIL_OFF_MASK; tail &= RB_TAIL_OFF_MASK;
...@@ -1462,6 +1486,7 @@ intel_vgpu_create_workload(struct intel_vgpu *vgpu, int ring_id, ...@@ -1462,6 +1486,7 @@ intel_vgpu_create_workload(struct intel_vgpu *vgpu, int ring_id,
workload->ctx_desc = *desc; workload->ctx_desc = *desc;
workload->ring_context_gpa = ring_context_gpa; workload->ring_context_gpa = ring_context_gpa;
workload->rb_head = head; workload->rb_head = head;
workload->guest_rb_head = guest_head;
workload->rb_tail = tail; workload->rb_tail = tail;
workload->rb_start = start; workload->rb_start = start;
workload->rb_ctl = ctl; workload->rb_ctl = ctl;
......
...@@ -100,6 +100,7 @@ struct intel_vgpu_workload { ...@@ -100,6 +100,7 @@ struct intel_vgpu_workload {
struct execlist_ctx_descriptor_format ctx_desc; struct execlist_ctx_descriptor_format ctx_desc;
struct execlist_ring_context *ring_context; struct execlist_ring_context *ring_context;
unsigned long rb_head, rb_tail, rb_ctl, rb_start, rb_len; unsigned long rb_head, rb_tail, rb_ctl, rb_start, rb_len;
unsigned long guest_rb_head;
bool restore_inhibit; bool restore_inhibit;
struct intel_vgpu_elsp_dwords elsp_dwords; struct intel_vgpu_elsp_dwords elsp_dwords;
bool emulate_schedule_in; bool emulate_schedule_in;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment