On 2022.12.20 17:40:14 +0800, Zheng Wang wrote: > If intel_gvt_dma_map_guest_page failed, it will call > ppgtt_invalidate_spt, which will finally free the spt. But the > caller function ppgtt_populate_spt_by_guest_entry does not notice > that, it will free spt again in its error path. indent > > Fix this by undoing the mapping of DMA address and freeing sub_spt. > Besides, leave the handle of spt destroy to caller function instead of > callee function when error occurs. > > Fixes: b901b252b6cf ("drm/i915/gvt: Add 2M huge gtt support") > Signed-off-by: Zheng Wang > --- > v5: > - remove unnecessary switch-case code for there is only one particular case, > correct the unmap target from parent_spt to sub_spt.add more details in > commit message. All suggested by Zhenyu > > 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@163.com/ > > v1: https://lore.kernel.org/all/20220928033340.1063949-1-zyytlz.wz@163.com/ > --- > drivers/gpu/drm/i915/gvt/gtt.c | 18 ++++++++++++++---- > 1 file changed, 14 insertions(+), 4 deletions(-) > > diff --git a/drivers/gpu/drm/i915/gvt/gtt.c b/drivers/gpu/drm/i915/gvt/gtt.c > index 51e5e8fb505b..4d478a59eb7d 100644 > --- a/drivers/gpu/drm/i915/gvt/gtt.c > +++ b/drivers/gpu/drm/i915/gvt/gtt.c > @@ -1209,10 +1209,8 @@ 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) { > - ppgtt_invalidate_spt(spt); > - return ret; > - } > + if (ret) > + goto err; > sub_se.val64 = se->val64; > > /* Copy the PAT field from PDE. */ > @@ -1231,6 +1229,18 @@ static int split_2MB_gtt_entry(struct intel_vgpu *vgpu, > ops->set_pfn(se, sub_spt->shadow_page.mfn); > ppgtt_set_shadow_entry(spt, se, index); > return 0; > +err: > + /* Undone the existing mappings of DMA addr. */ We need a verb here for Undo. > + for_each_present_shadow_entry(sub_spt, &sub_se, sub_index) { > + gvt_vdbg_mm("invalidate 4K entry\n"); > + ppgtt_invalidate_pte(sub_spt, &sub_se); > + } > + /* Release the new allocated spt. */ > + trace_spt_change(sub_spt->vgpu->id, "release", sub_spt, > + sub_spt->guest_page.gfn, sub_spt->shadow_page.type); > + ppgtt_free_spt(sub_spt); > + sub_spt = NULL; Not need to reset local variable that has no use then. I'll handle these trivial fixes during the merge. Reviewed-by: Zhenyu Wang thanks > + return ret; > } > > static int split_64KB_gtt_entry(struct intel_vgpu *vgpu, > -- > 2.25.1 >