If intel_gvt_dma_map_guest_page failed, it will call ppgtt_invalidate_spt, which will finally free the spt. But the caller does not notice that, it will free spt again in error path. Fix this by undoing the mapping of DMA address and freeing sub_spt. Fixes: b901b252b6cf ("drm/i915/gvt: Add 2M huge gtt support") Signed-off-by: Zheng Wang <zyytlz.wz@xxxxxxx> --- v4: - fix by undo the mapping of DMA address and free sub_spt suggested by Zhi v3: - correct spelling mistake and remove unused variable suggested by Greg v2: https://lore.kernel.org/all/20221006165845.1735393-1-zyytlz.wz@xxxxxxx/ v1: https://lore.kernel.org/all/20220928033340.1063949-1-zyytlz.wz@xxxxxxx/ --- drivers/gpu/drm/i915/gvt/gtt.c | 58 +++++++++++++++++----------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/drivers/gpu/drm/i915/gvt/gtt.c b/drivers/gpu/drm/i915/gvt/gtt.c index 45271acc5038..b472e021e5a4 100644 --- a/drivers/gpu/drm/i915/gvt/gtt.c +++ b/drivers/gpu/drm/i915/gvt/gtt.c @@ -1209,7 +1209,7 @@ static int split_2MB_gtt_entry(struct intel_vgpu *vgpu, for_each_shadow_entry(sub_spt, &sub_se, sub_index) { ret = intel_gvt_dma_map_guest_page(vgpu, start_gfn + sub_index, PAGE_SIZE, &dma_addr); - if (ret) + if (ret) goto err; sub_se.val64 = se->val64; @@ -1233,34 +1233,34 @@ static int split_2MB_gtt_entry(struct intel_vgpu *vgpu, /* Undone the existing mappings of DMA addr. */ for_each_present_shadow_entry(spt, &e, parent_index) { switch (e.type) { - case GTT_TYPE_PPGTT_PTE_4K_ENTRY: - gvt_vdbg_mm("invalidate 4K entry\n"); - ppgtt_invalidate_pte(spt, &e); - break; - case GTT_TYPE_PPGTT_PTE_64K_ENTRY: - /* We don't setup 64K shadow entry so far. */ - WARN(1, "suspicious 64K gtt entry\n"); - continue; - case GTT_TYPE_PPGTT_PTE_2M_ENTRY: - gvt_vdbg_mm("invalidate 2M entry\n"); - continue; - case GTT_TYPE_PPGTT_PTE_1G_ENTRY: - WARN(1, "GVT doesn't support 1GB page\n"); - continue; - case GTT_TYPE_PPGTT_PML4_ENTRY: - case GTT_TYPE_PPGTT_PDP_ENTRY: - case GTT_TYPE_PPGTT_PDE_ENTRY: - gvt_vdbg_mm("invalidate PMUL4/PDP/PDE entry\n"); - ret1 = ppgtt_invalidate_spt_by_shadow_entry( - spt->vgpu, &e); - if (ret1) { - gvt_vgpu_err("fail: shadow page %p shadow entry 0x%llx type %d\n", - spt, e.val64, e.type); - goto free_spt; - } - break; - default: - GEM_BUG_ON(1); + case GTT_TYPE_PPGTT_PTE_4K_ENTRY: + gvt_vdbg_mm("invalidate 4K entry\n"); + ppgtt_invalidate_pte(spt, &e); + break; + case GTT_TYPE_PPGTT_PTE_64K_ENTRY: + /* We don't setup 64K shadow entry so far. */ + WARN(1, "suspicious 64K gtt entry\n"); + continue; + case GTT_TYPE_PPGTT_PTE_2M_ENTRY: + gvt_vdbg_mm("invalidate 2M entry\n"); + continue; + case GTT_TYPE_PPGTT_PTE_1G_ENTRY: + WARN(1, "GVT doesn't support 1GB page\n"); + continue; + case GTT_TYPE_PPGTT_PML4_ENTRY: + case GTT_TYPE_PPGTT_PDP_ENTRY: + case GTT_TYPE_PPGTT_PDE_ENTRY: + gvt_vdbg_mm("invalidate PMUL4/PDP/PDE entry\n"); + ret1 = ppgtt_invalidate_spt_by_shadow_entry( + spt->vgpu, &e); + if (ret1) { + gvt_vgpu_err("fail: shadow page %p shadow entry 0x%llx type %d\n", + spt, e.val64, e.type); + goto free_spt; + } + break; + default: + GEM_BUG_ON(1); } } /* Release the new alloced apt. */ -- 2.25.1