This patch is to handle ppgtt PV_CMD_BIND_GGTT and PV_CMD_UNBIND_GGTT for pv ggtt, it is operated (bind/unbind) per vma instead of per ggtt entry mmio update to improve efficiency Signed-off-by: Xiaolin Zhang <xiaolin.zhang@xxxxxxxxx> --- drivers/gpu/drm/i915/gvt/gtt.c | 83 +++++++++++++++++++++++++++++++++++++ drivers/gpu/drm/i915/gvt/handlers.c | 4 ++ drivers/gpu/drm/i915/gvt/vgpu.c | 2 +- 3 files changed, 88 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/gvt/gtt.c b/drivers/gpu/drm/i915/gvt/gtt.c index c2b7527..7dcd427 100644 --- a/drivers/gpu/drm/i915/gvt/gtt.c +++ b/drivers/gpu/drm/i915/gvt/gtt.c @@ -2734,6 +2734,83 @@ static void intel_vgpu_pv_ppgtt_unbind(struct intel_vgpu *vgpu, } } +static int intel_vgpu_pv_ggtt_bind(struct intel_vgpu *vgpu, + struct intel_vgpu_pv_vma *vma, u64 *gpas) +{ + u64 off = (vma->start / I915_GTT_PAGE_SIZE) << 3; + u32 size = vma->size; + struct intel_vgpu_mm *ggtt_mm = vgpu->gtt.ggtt_mm; + struct intel_gvt_gtt_pte_ops *ops = vgpu->gvt->gtt.pte_ops; + unsigned long g_gtt_index = off >> 3; + struct intel_gvt_gtt_entry e = {.val64 = 0, .type = GTT_TYPE_GGTT_PTE}; + struct intel_gvt_gtt_entry m = {.val64 = 0, .type = GTT_TYPE_GGTT_PTE}; + int ret = 0; + int i; + u64 gfn; + dma_addr_t dma_addr; + + for (i = 0; i < size; i++) { + e.val64 = gpas[i]; + if (!ops->test_present(&e)) { + ops->set_pfn(&m, vgpu->gvt->gtt.scratch_mfn); + ops->clear_present(&m); + goto out; + } + + gfn = ops->get_pfn(&e); + m.val64 = e.val64; + ret = intel_gvt_hypervisor_dma_map_guest_page(vgpu, gfn, + PAGE_SIZE, &dma_addr); + if (ret) { + gvt_vgpu_err("failed to map guest ggtt entry\n"); + ops->set_pfn(&m, vgpu->gvt->gtt.scratch_mfn); + } else { + ops->set_pfn(&m, dma_addr >> PAGE_SHIFT); + } +out: + g_gtt_index = off >> 3; + 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); + off += 8; + } + + ggtt_invalidate(vgpu->gvt->gt); + return ret; +} + +static int intel_vgpu_pv_ggtt_unbind(struct intel_vgpu *vgpu, + struct intel_vgpu_pv_vma *vma, u64 *gpas) +{ + u64 off = (vma->start / I915_GTT_PAGE_SIZE) << 3; + u32 size = vma->size; + struct intel_vgpu_mm *ggtt_mm = vgpu->gtt.ggtt_mm; + struct intel_gvt_gtt_pte_ops *ops = vgpu->gvt->gtt.pte_ops; + unsigned long g_gtt_index = off >> 3; + struct intel_gvt_gtt_entry e = {.val64 = 0, .type = GTT_TYPE_GGTT_PTE}; + struct intel_gvt_gtt_entry m = {.val64 = 0, .type = GTT_TYPE_GGTT_PTE}; + int ret = 0; + int i; + + for (i = 0; i < size; i++) { + g_gtt_index = off >> 3; + e.val64 = gpas[i]; + ggtt_invalidate_pte(vgpu, &e); + ops->clear_present(&e); + ggtt_set_guest_entry(ggtt_mm, &e, g_gtt_index); + ops->set_pfn(&m, vgpu->gvt->gtt.scratch_mfn); + ops->clear_present(&m); + ggtt_get_host_entry(ggtt_mm, &e, g_gtt_index); + ggtt_set_host_entry(ggtt_mm, &m, g_gtt_index); + off += 8; + } + + ggtt_invalidate(vgpu->gvt->gt); + + return ret; +} + int intel_vgpu_handle_pv_vma(struct intel_vgpu *vgpu, struct intel_vgpu_mm *mm, u32 cmd, u32 data[]) { @@ -2771,6 +2848,12 @@ int intel_vgpu_handle_pv_vma(struct intel_vgpu *vgpu, case PV_CMD_BIND_PPGTT: intel_vgpu_pv_ppgtt_bind(vgpu, mm, vma, dma_addrs); break; + case PV_CMD_BIND_GGTT: + ret = intel_vgpu_pv_ggtt_bind(vgpu, vma, dma_addrs); + break; + case PV_CMD_UNBIND_GGTT: + ret = intel_vgpu_pv_ggtt_unbind(vgpu, vma, dma_addrs); + break; default: break; } diff --git a/drivers/gpu/drm/i915/gvt/handlers.c b/drivers/gpu/drm/i915/gvt/handlers.c index 732b4ed..7f83b77 100644 --- a/drivers/gpu/drm/i915/gvt/handlers.c +++ b/drivers/gpu/drm/i915/gvt/handlers.c @@ -1348,6 +1348,10 @@ static int handle_pv_commands(struct intel_vgpu *vgpu) } ret = intel_vgpu_handle_pv_vma(vgpu, mm, cmd, data); break; + case PV_CMD_BIND_GGTT: + case PV_CMD_UNBIND_GGTT: + ret = intel_vgpu_handle_pv_vma(vgpu, NULL, cmd, data); + break; default: break; } diff --git a/drivers/gpu/drm/i915/gvt/vgpu.c b/drivers/gpu/drm/i915/gvt/vgpu.c index bf70e5517..c1e2f82 100644 --- a/drivers/gpu/drm/i915/gvt/vgpu.c +++ b/drivers/gpu/drm/i915/gvt/vgpu.c @@ -50,7 +50,7 @@ void populate_pvinfo_page(struct intel_vgpu *vgpu) vgpu_vreg_t(vgpu, vgtif_reg(vgt_caps)) |= VGT_CAPS_HUGE_GTT; vgpu_vreg_t(vgpu, vgtif_reg(vgt_caps)) |= VGT_CAPS_PV; - vgpu_vreg_t(vgpu, vgtif_reg(pv_caps)) = PV_PPGTT; + vgpu_vreg_t(vgpu, vgtif_reg(pv_caps)) = PV_PPGTT | PV_GGTT; vgpu_vreg_t(vgpu, vgtif_reg(avail_rs.mappable_gmadr.base)) = vgpu_aperture_gmadr_base(vgpu); -- 2.7.4 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/intel-gfx