table_freed will be always true when mapping a memory with size bigger than 2MB. Using a check of turnning valid PDE into PTE will resolve the issue. Signed-off-by: Eric Huang <jinhuieric.huang@xxxxxxx> --- drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index 0dee2e8797c7..b1bdc89cb5d1 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c @@ -1553,6 +1553,21 @@ static int amdgpu_vm_update_ptes(struct amdgpu_vm_update_params *params, */ nptes = max(nptes, 1u); + /* Fix a page fault in a corner case of + * turning valid PDE entry to PTE entry + * for huge page mapping + */ + if (cursor.level < AMDGPU_VM_PTB) { + int i; + for (i = 0; i < nptes; i++) { + uint64_t value = 0; + vm->update_funcs->get_pt_entry(pt, + pe_start + (i * 8), &value); + if (value & AMDGPU_PTE_VALID) + params->table_freed = true; + } + } + trace_amdgpu_vm_update_ptes(params, frag_start, upd_end, nptes, dst, incr, upd_flags, vm->task_info.pid, @@ -1584,7 +1599,6 @@ static int amdgpu_vm_update_ptes(struct amdgpu_vm_update_params *params, while (cursor.pfn < frag_start) { amdgpu_vm_free_pts(adev, params->vm, &cursor); amdgpu_vm_pt_next(adev, &cursor); - params->table_freed = true; } } else if (frag >= shift) { -- 2.25.1 _______________________________________________ amd-gfx mailing list amd-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/amd-gfx