Skip to content

Commit

Permalink
drm/i915/gvt: factor out tlb and mocs register offset table
Browse files Browse the repository at this point in the history
Factor out tlb and mocs register offset table to fix the issues reported
by klocwork, torvalds#512 and torvalds#550. Mostly, the reason why the klocwork reports
these problems is because there can be possbilities for platforms, which
have more rings than the ring offset table, to take the dirty data from
the stack as the register offset. It results to a random HW register
offset writting in this scenairo when doing context switch between vGPUs.

After the factoring, the ring offset table of TLB and MOCS should be per
platform.

v2:

- Enable TLB register switch for GEN8. (Zhenyu)

Reviewed-by: Zhenyu Wang <zhenyuw@linux.intel.com>
Signed-off-by: Zhi Wang <zhi.a.wang@intel.com>
Signed-off-by: Zhenyu Wang <zhenyuw@linux.intel.com>
  • Loading branch information
zhiwang1 authored and zhenyw committed Aug 13, 2019
1 parent f8871ec commit 8cfbca7
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 18 deletions.
4 changes: 4 additions & 0 deletions drivers/gpu/drm/i915/gvt/gvt.h
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,10 @@ struct intel_gvt {
struct {
struct engine_mmio *mmio;
int ctx_mmio_count[I915_NUM_ENGINES];
u32 *tlb_mmio_offset_list;
u32 tlb_mmio_offset_list_cnt;
u32 *mocs_mmio_offset_list;
u32 mocs_mmio_offset_list_cnt;
} engine_mmio_list;

struct dentry *debugfs_root;
Expand Down
57 changes: 39 additions & 18 deletions drivers/gpu/drm/i915/gvt/mmio_context.c
Original file line number Diff line number Diff line change
Expand Up @@ -148,19 +148,27 @@ static struct {
u32 l3cc_table[GEN9_MOCS_SIZE / 2];
} gen9_render_mocs;

static u32 gen9_mocs_mmio_offset_list[] = {
[RCS0] = 0xc800,
[VCS0] = 0xc900,
[VCS1] = 0xca00,
[BCS0] = 0xcc00,
[VECS0] = 0xcb00,
};

static void load_render_mocs(struct drm_i915_private *dev_priv)
{
struct intel_gvt *gvt = dev_priv->gvt;
i915_reg_t offset;
u32 regs[] = {
[RCS0] = 0xc800,
[VCS0] = 0xc900,
[VCS1] = 0xca00,
[BCS0] = 0xcc00,
[VECS0] = 0xcb00,
};
u32 cnt = gvt->engine_mmio_list.mocs_mmio_offset_list_cnt;
u32 *regs = gvt->engine_mmio_list.mocs_mmio_offset_list;
int ring_id, i;

for (ring_id = 0; ring_id < ARRAY_SIZE(regs); ring_id++) {
/* Platform doesn't have mocs mmios. */
if (!regs)
return;

for (ring_id = 0; ring_id < cnt; ring_id++) {
if (!HAS_ENGINE(dev_priv, ring_id))
continue;
offset.reg = regs[ring_id];
Expand Down Expand Up @@ -327,22 +335,28 @@ int intel_vgpu_restore_inhibit_context(struct intel_vgpu *vgpu,
return ret;
}

static u32 gen8_tlb_mmio_offset_list[] = {
[RCS0] = 0x4260,
[VCS0] = 0x4264,
[VCS1] = 0x4268,
[BCS0] = 0x426c,
[VECS0] = 0x4270,
};

static void handle_tlb_pending_event(struct intel_vgpu *vgpu, int ring_id)
{
struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv;
struct intel_uncore *uncore = &dev_priv->uncore;
struct intel_vgpu_submission *s = &vgpu->submission;
u32 *regs = vgpu->gvt->engine_mmio_list.tlb_mmio_offset_list;
u32 cnt = vgpu->gvt->engine_mmio_list.tlb_mmio_offset_list_cnt;
enum forcewake_domains fw;
i915_reg_t reg;
u32 regs[] = {
[RCS0] = 0x4260,
[VCS0] = 0x4264,
[VCS1] = 0x4268,
[BCS0] = 0x426c,
[VECS0] = 0x4270,
};

if (WARN_ON(ring_id >= ARRAY_SIZE(regs)))
if (!regs)
return;

if (WARN_ON(ring_id >= cnt))
return;

if (!test_and_clear_bit(ring_id, (void *)s->tlb_handle_pending))
Expand Down Expand Up @@ -565,10 +579,17 @@ void intel_gvt_init_engine_mmio_context(struct intel_gvt *gvt)
{
struct engine_mmio *mmio;

if (INTEL_GEN(gvt->dev_priv) >= 9)
if (INTEL_GEN(gvt->dev_priv) >= 9) {
gvt->engine_mmio_list.mmio = gen9_engine_mmio_list;
else
gvt->engine_mmio_list.tlb_mmio_offset_list = gen8_tlb_mmio_offset_list;
gvt->engine_mmio_list.tlb_mmio_offset_list_cnt = ARRAY_SIZE(gen8_tlb_mmio_offset_list);
gvt->engine_mmio_list.mocs_mmio_offset_list = gen9_mocs_mmio_offset_list;
gvt->engine_mmio_list.mocs_mmio_offset_list_cnt = ARRAY_SIZE(gen9_mocs_mmio_offset_list);
} else {
gvt->engine_mmio_list.mmio = gen8_engine_mmio_list;
gvt->engine_mmio_list.tlb_mmio_offset_list = gen8_tlb_mmio_offset_list;
gvt->engine_mmio_list.tlb_mmio_offset_list_cnt = ARRAY_SIZE(gen8_tlb_mmio_offset_list);
}

for (mmio = gvt->engine_mmio_list.mmio;
i915_mmio_reg_valid(mmio->reg); mmio++) {
Expand Down

0 comments on commit 8cfbca7

Please sign in to comment.