提交 214782da 编写于 作者: J Joonas Lahtinen

Merge tag 'gvt-fixes-2018-11-07' of https://github.com/intel/gvt-linux into drm-intel-fixes

gvt-fixes-2018-11-07

- Fix invalidate of old ggtt entry (Hang)
- Fix partial ggtt entry update in any order (Hang)
- Fix one mask setting for chicken reg (Xinyun)
- Fix eDP warning in guest (Longhe)
Signed-off-by: NJoonas Lahtinen <joonas.lahtinen@linux.intel.com>
From: Zhenyu Wang <zhenyuw@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20181107023137.GO25194@zhen-hp.sh.intel.com
...@@ -1905,7 +1905,6 @@ static struct intel_vgpu_mm *intel_vgpu_create_ggtt_mm(struct intel_vgpu *vgpu) ...@@ -1905,7 +1905,6 @@ static struct intel_vgpu_mm *intel_vgpu_create_ggtt_mm(struct intel_vgpu *vgpu)
vgpu_free_mm(mm); vgpu_free_mm(mm);
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
} }
mm->ggtt_mm.last_partial_off = -1UL;
return mm; return mm;
} }
...@@ -1930,7 +1929,6 @@ void _intel_vgpu_mm_release(struct kref *mm_ref) ...@@ -1930,7 +1929,6 @@ void _intel_vgpu_mm_release(struct kref *mm_ref)
invalidate_ppgtt_mm(mm); invalidate_ppgtt_mm(mm);
} else { } else {
vfree(mm->ggtt_mm.virtual_ggtt); vfree(mm->ggtt_mm.virtual_ggtt);
mm->ggtt_mm.last_partial_off = -1UL;
} }
vgpu_free_mm(mm); vgpu_free_mm(mm);
...@@ -2168,6 +2166,8 @@ static int emulate_ggtt_mmio_write(struct intel_vgpu *vgpu, unsigned int off, ...@@ -2168,6 +2166,8 @@ static int emulate_ggtt_mmio_write(struct intel_vgpu *vgpu, unsigned int off,
struct intel_gvt_gtt_entry e, m; struct intel_gvt_gtt_entry e, m;
dma_addr_t dma_addr; dma_addr_t dma_addr;
int ret; int ret;
struct intel_gvt_partial_pte *partial_pte, *pos, *n;
bool partial_update = false;
if (bytes != 4 && bytes != 8) if (bytes != 4 && bytes != 8)
return -EINVAL; return -EINVAL;
...@@ -2178,68 +2178,57 @@ static int emulate_ggtt_mmio_write(struct intel_vgpu *vgpu, unsigned int off, ...@@ -2178,68 +2178,57 @@ static int emulate_ggtt_mmio_write(struct intel_vgpu *vgpu, unsigned int off,
if (!vgpu_gmadr_is_valid(vgpu, gma)) if (!vgpu_gmadr_is_valid(vgpu, gma))
return 0; return 0;
ggtt_get_guest_entry(ggtt_mm, &e, g_gtt_index); e.type = GTT_TYPE_GGTT_PTE;
memcpy((void *)&e.val64 + (off & (info->gtt_entry_size - 1)), p_data, memcpy((void *)&e.val64 + (off & (info->gtt_entry_size - 1)), p_data,
bytes); bytes);
/* If ggtt entry size is 8 bytes, and it's split into two 4 bytes /* If ggtt entry size is 8 bytes, and it's split into two 4 bytes
* write, we assume the two 4 bytes writes are consecutive. * write, save the first 4 bytes in a list and update virtual
* Otherwise, we abort and report error * PTE. Only update shadow PTE when the second 4 bytes comes.
*/ */
if (bytes < info->gtt_entry_size) { if (bytes < info->gtt_entry_size) {
if (ggtt_mm->ggtt_mm.last_partial_off == -1UL) { bool found = false;
/* the first partial part*/
ggtt_mm->ggtt_mm.last_partial_off = off; list_for_each_entry_safe(pos, n,
ggtt_mm->ggtt_mm.last_partial_data = e.val64; &ggtt_mm->ggtt_mm.partial_pte_list, list) {
return 0; if (g_gtt_index == pos->offset >>
} else if ((g_gtt_index == info->gtt_entry_size_shift) {
(ggtt_mm->ggtt_mm.last_partial_off >> if (off != pos->offset) {
info->gtt_entry_size_shift)) && /* the second partial part*/
(off != ggtt_mm->ggtt_mm.last_partial_off)) { int last_off = pos->offset &
/* the second partial part */
int last_off = ggtt_mm->ggtt_mm.last_partial_off &
(info->gtt_entry_size - 1); (info->gtt_entry_size - 1);
memcpy((void *)&e.val64 + last_off, memcpy((void *)&e.val64 + last_off,
(void *)&ggtt_mm->ggtt_mm.last_partial_data + (void *)&pos->data + last_off,
last_off, bytes); bytes);
ggtt_mm->ggtt_mm.last_partial_off = -1UL;
} else {
int last_offset;
gvt_vgpu_err("failed to populate guest ggtt entry: abnormal ggtt entry write sequence, last_partial_off=%lx, offset=%x, bytes=%d, ggtt entry size=%d\n",
ggtt_mm->ggtt_mm.last_partial_off, off,
bytes, info->gtt_entry_size);
/* set host ggtt entry to scratch page and clear
* virtual ggtt entry as not present for last
* partially write offset
*/
last_offset = ggtt_mm->ggtt_mm.last_partial_off &
(~(info->gtt_entry_size - 1));
ggtt_get_host_entry(ggtt_mm, &m, last_offset);
ggtt_invalidate_pte(vgpu, &m);
ops->set_pfn(&m, gvt->gtt.scratch_mfn);
ops->clear_present(&m);
ggtt_set_host_entry(ggtt_mm, &m, last_offset);
ggtt_invalidate(gvt->dev_priv);
ggtt_get_guest_entry(ggtt_mm, &e, last_offset);
ops->clear_present(&e);
ggtt_set_guest_entry(ggtt_mm, &e, last_offset);
ggtt_mm->ggtt_mm.last_partial_off = off; list_del(&pos->list);
ggtt_mm->ggtt_mm.last_partial_data = e.val64; kfree(pos);
found = true;
break;
}
/* update of the first partial part */
pos->data = e.val64;
ggtt_set_guest_entry(ggtt_mm, &e, g_gtt_index);
return 0; return 0;
} }
} }
if (ops->test_present(&e)) { if (!found) {
/* the first partial part */
partial_pte = kzalloc(sizeof(*partial_pte), GFP_KERNEL);
if (!partial_pte)
return -ENOMEM;
partial_pte->offset = off;
partial_pte->data = e.val64;
list_add_tail(&partial_pte->list,
&ggtt_mm->ggtt_mm.partial_pte_list);
partial_update = true;
}
}
if (!partial_update && (ops->test_present(&e))) {
gfn = ops->get_pfn(&e); gfn = ops->get_pfn(&e);
m = e; m = e;
...@@ -2263,16 +2252,18 @@ static int emulate_ggtt_mmio_write(struct intel_vgpu *vgpu, unsigned int off, ...@@ -2263,16 +2252,18 @@ static int emulate_ggtt_mmio_write(struct intel_vgpu *vgpu, unsigned int off,
} else } else
ops->set_pfn(&m, dma_addr >> PAGE_SHIFT); ops->set_pfn(&m, dma_addr >> PAGE_SHIFT);
} else { } else {
ggtt_get_host_entry(ggtt_mm, &m, g_gtt_index);
ggtt_invalidate_pte(vgpu, &m);
ops->set_pfn(&m, gvt->gtt.scratch_mfn); ops->set_pfn(&m, gvt->gtt.scratch_mfn);
ops->clear_present(&m); ops->clear_present(&m);
} }
out: out:
ggtt_set_guest_entry(ggtt_mm, &e, g_gtt_index);
ggtt_get_host_entry(ggtt_mm, &e, g_gtt_index);
ggtt_invalidate_pte(vgpu, &e);
ggtt_set_host_entry(ggtt_mm, &m, g_gtt_index); ggtt_set_host_entry(ggtt_mm, &m, g_gtt_index);
ggtt_invalidate(gvt->dev_priv); ggtt_invalidate(gvt->dev_priv);
ggtt_set_guest_entry(ggtt_mm, &e, g_gtt_index);
return 0; return 0;
} }
...@@ -2430,6 +2421,8 @@ int intel_vgpu_init_gtt(struct intel_vgpu *vgpu) ...@@ -2430,6 +2421,8 @@ int intel_vgpu_init_gtt(struct intel_vgpu *vgpu)
intel_vgpu_reset_ggtt(vgpu, false); intel_vgpu_reset_ggtt(vgpu, false);
INIT_LIST_HEAD(&gtt->ggtt_mm->ggtt_mm.partial_pte_list);
return create_scratch_page_tree(vgpu); return create_scratch_page_tree(vgpu);
} }
...@@ -2454,6 +2447,14 @@ static void intel_vgpu_destroy_all_ppgtt_mm(struct intel_vgpu *vgpu) ...@@ -2454,6 +2447,14 @@ static void intel_vgpu_destroy_all_ppgtt_mm(struct intel_vgpu *vgpu)
static void intel_vgpu_destroy_ggtt_mm(struct intel_vgpu *vgpu) static void intel_vgpu_destroy_ggtt_mm(struct intel_vgpu *vgpu)
{ {
struct intel_gvt_partial_pte *pos;
list_for_each_entry(pos,
&vgpu->gtt.ggtt_mm->ggtt_mm.partial_pte_list, list) {
gvt_dbg_mm("partial PTE update on hold 0x%lx : 0x%llx\n",
pos->offset, pos->data);
kfree(pos);
}
intel_vgpu_destroy_mm(vgpu->gtt.ggtt_mm); intel_vgpu_destroy_mm(vgpu->gtt.ggtt_mm);
vgpu->gtt.ggtt_mm = NULL; vgpu->gtt.ggtt_mm = NULL;
} }
......
...@@ -132,6 +132,12 @@ enum intel_gvt_mm_type { ...@@ -132,6 +132,12 @@ enum intel_gvt_mm_type {
#define GVT_RING_CTX_NR_PDPS GEN8_3LVL_PDPES #define GVT_RING_CTX_NR_PDPS GEN8_3LVL_PDPES
struct intel_gvt_partial_pte {
unsigned long offset;
u64 data;
struct list_head list;
};
struct intel_vgpu_mm { struct intel_vgpu_mm {
enum intel_gvt_mm_type type; enum intel_gvt_mm_type type;
struct intel_vgpu *vgpu; struct intel_vgpu *vgpu;
...@@ -156,8 +162,7 @@ struct intel_vgpu_mm { ...@@ -156,8 +162,7 @@ struct intel_vgpu_mm {
} ppgtt_mm; } ppgtt_mm;
struct { struct {
void *virtual_ggtt; void *virtual_ggtt;
unsigned long last_partial_off; struct list_head partial_pte_list;
u64 last_partial_data;
} ggtt_mm; } ggtt_mm;
}; };
}; };
......
...@@ -1609,7 +1609,7 @@ static int bxt_gt_disp_pwron_write(struct intel_vgpu *vgpu, ...@@ -1609,7 +1609,7 @@ static int bxt_gt_disp_pwron_write(struct intel_vgpu *vgpu,
return 0; return 0;
} }
static int bxt_edp_psr_imr_iir_write(struct intel_vgpu *vgpu, static int edp_psr_imr_iir_write(struct intel_vgpu *vgpu,
unsigned int offset, void *p_data, unsigned int bytes) unsigned int offset, void *p_data, unsigned int bytes)
{ {
vgpu_vreg(vgpu, offset) = 0; vgpu_vreg(vgpu, offset) = 0;
...@@ -2607,6 +2607,9 @@ static int init_generic_mmio_info(struct intel_gvt *gvt) ...@@ -2607,6 +2607,9 @@ static int init_generic_mmio_info(struct intel_gvt *gvt)
MMIO_DFH(_MMIO(0x1a178), D_BDW_PLUS, F_CMD_ACCESS, NULL, NULL); MMIO_DFH(_MMIO(0x1a178), D_BDW_PLUS, F_CMD_ACCESS, NULL, NULL);
MMIO_DFH(_MMIO(0x1a17c), D_BDW_PLUS, F_CMD_ACCESS, NULL, NULL); MMIO_DFH(_MMIO(0x1a17c), D_BDW_PLUS, F_CMD_ACCESS, NULL, NULL);
MMIO_DFH(_MMIO(0x2217c), D_BDW_PLUS, F_CMD_ACCESS, NULL, NULL); MMIO_DFH(_MMIO(0x2217c), D_BDW_PLUS, F_CMD_ACCESS, NULL, NULL);
MMIO_DH(EDP_PSR_IMR, D_BDW_PLUS, NULL, edp_psr_imr_iir_write);
MMIO_DH(EDP_PSR_IIR, D_BDW_PLUS, NULL, edp_psr_imr_iir_write);
return 0; return 0;
} }
...@@ -3205,9 +3208,6 @@ static int init_bxt_mmio_info(struct intel_gvt *gvt) ...@@ -3205,9 +3208,6 @@ static int init_bxt_mmio_info(struct intel_gvt *gvt)
MMIO_D(HSW_TVIDEO_DIP_GCP(TRANSCODER_B), D_BXT); MMIO_D(HSW_TVIDEO_DIP_GCP(TRANSCODER_B), D_BXT);
MMIO_D(HSW_TVIDEO_DIP_GCP(TRANSCODER_C), D_BXT); MMIO_D(HSW_TVIDEO_DIP_GCP(TRANSCODER_C), D_BXT);
MMIO_DH(EDP_PSR_IMR, D_BXT, NULL, bxt_edp_psr_imr_iir_write);
MMIO_DH(EDP_PSR_IIR, D_BXT, NULL, bxt_edp_psr_imr_iir_write);
MMIO_D(RC6_CTX_BASE, D_BXT); MMIO_D(RC6_CTX_BASE, D_BXT);
MMIO_D(GEN8_PUSHBUS_CONTROL, D_BXT); MMIO_D(GEN8_PUSHBUS_CONTROL, D_BXT);
......
...@@ -131,7 +131,7 @@ static struct engine_mmio gen9_engine_mmio_list[] __cacheline_aligned = { ...@@ -131,7 +131,7 @@ static struct engine_mmio gen9_engine_mmio_list[] __cacheline_aligned = {
{RCS, GAMT_CHKN_BIT_REG, 0x0, false}, /* 0x4ab8 */ {RCS, GAMT_CHKN_BIT_REG, 0x0, false}, /* 0x4ab8 */
{RCS, GEN9_GAMT_ECO_REG_RW_IA, 0x0, false}, /* 0x4ab0 */ {RCS, GEN9_GAMT_ECO_REG_RW_IA, 0x0, false}, /* 0x4ab0 */
{RCS, GEN9_CSFE_CHICKEN1_RCS, 0x0, false}, /* 0x20d4 */ {RCS, GEN9_CSFE_CHICKEN1_RCS, 0xffff, false}, /* 0x20d4 */
{RCS, GEN8_GARBCNTL, 0x0, false}, /* 0xb004 */ {RCS, GEN8_GARBCNTL, 0x0, false}, /* 0xb004 */
{RCS, GEN7_FF_THREAD_MODE, 0x0, false}, /* 0x20a0 */ {RCS, GEN7_FF_THREAD_MODE, 0x0, false}, /* 0x20a0 */
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册