Change-Id: I9957e726576289448911f5fb2ff7bcb9311a1906 Signed-off-by: Chunming Zhou <David1.Zhou at amd.com> --- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 2 + drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 77 ++++++++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index a7951aa..1f941c4a 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -1000,6 +1000,8 @@ int amdgpu_vm_bo_unmap(struct amdgpu_device *adev, uint64_t addr); void amdgpu_vm_bo_rmv(struct amdgpu_device *adev, struct amdgpu_bo_va *bo_va); +int amdgpu_vm_recover_page_table_from_shadow(struct amdgpu_device *adev, + struct amdgpu_vm *vm); /* * context related structures diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index fb8a7ab..4f95dc4 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c @@ -700,6 +700,83 @@ error_free: return r; } +static int amdgpu_vm_recover_bo_from_shadow(struct amdgpu_device *adev, + struct amdgpu_bo *bo, + struct amdgpu_bo *bo_shadow, + struct reservation_object *resv) + +{ + struct amdgpu_ring *ring = adev->mman.buffer_funcs_ring; + struct fence *fence; + int r; + uint64_t vram_addr, gtt_addr; + + r = amdgpu_bo_pin(bo, AMDGPU_GEM_DOMAIN_VRAM, &vram_addr); + if (r) { + DRM_ERROR("Failed to pin bo object\n"); + goto err1; + } + r = amdgpu_bo_pin(bo_shadow, AMDGPU_GEM_DOMAIN_GTT, >t_addr); + if (r) { + DRM_ERROR("Failed to pin bo shadow object\n"); + goto err2; + } + + r = reservation_object_reserve_shared(bo->tbo.resv); + if (r) + goto err3; + + r = amdgpu_copy_buffer(ring, gtt_addr, vram_addr, + amdgpu_bo_size(bo), resv, &fence); + if (!r) + amdgpu_bo_fence(bo, fence, true); + +err3: + amdgpu_bo_unpin(bo_shadow); +err2: + amdgpu_bo_unpin(bo); +err1: + + return r; +} + +int amdgpu_vm_recover_page_table_from_shadow(struct amdgpu_device *adev, + struct amdgpu_vm *vm) +{ + uint64_t pt_idx; + int r; + + /* bo and shadow use same resv, so reverve one time */ + r = amdgpu_bo_reserve(vm->page_directory, false); + if (unlikely(r != 0)) + return r; + + r = amdgpu_vm_recover_bo_from_shadow(adev, vm->page_directory, + vm->page_directory->shadow, + NULL); + if (r) { + DRM_ERROR("recover page table failed!\n"); + goto err; + } + + for (pt_idx = 0; pt_idx <= vm->max_pde_used; ++pt_idx) { + struct amdgpu_bo *bo = vm->page_tables[pt_idx].entry.robj; + struct amdgpu_bo *bo_shadow = vm->page_tables[pt_idx].entry_shadow.robj; + + if (!bo || !bo_shadow) + continue; + r = amdgpu_vm_recover_bo_from_shadow(adev, bo, bo_shadow, + NULL); + if (r) { + DRM_ERROR("recover page table failed!\n"); + goto err; + } + } + +err: + amdgpu_bo_unreserve(vm->page_directory); + return r; +} /** * amdgpu_vm_update_pdes - make sure that page directory is valid * -- 1.9.1