Change-Id: Ibc8fb4c5c9be38934ebd6d56f1cbd49cb82d53af Signed-off-by: Chunming Zhou <David1.Zhou at amd.com> --- drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index 215debb..30a1dcc 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c @@ -787,13 +787,15 @@ err: * @end: end of GPU address range * @dst: destination address to map to, the next dst inside the function * @flags: mapping flags + * @shadow: update shadow or not * * Update the page tables in the range @start - @end. */ static void amdgpu_vm_update_ptes(struct amdgpu_pte_update_params *params, struct amdgpu_vm *vm, uint64_t start, uint64_t end, - uint64_t dst, uint32_t flags) + uint64_t dst, uint32_t flags, + bool shadow) { const uint64_t mask = AMDGPU_VM_PTE_COUNT - 1; @@ -807,7 +809,8 @@ static void amdgpu_vm_update_ptes(struct amdgpu_pte_update_params *params, /* initialize the variables */ addr = start; pt_idx = addr >> amdgpu_vm_block_size; - pt = vm->page_tables[pt_idx].entry.robj; + pt = shadow ? vm->page_tables[pt_idx].entry.robj->shadow : + vm->page_tables[pt_idx].entry.robj; if ((addr & ~mask) == (end & ~mask)) nptes = end - addr; @@ -826,7 +829,8 @@ static void amdgpu_vm_update_ptes(struct amdgpu_pte_update_params *params, /* walk over the address space and update the page tables */ while (addr < end) { pt_idx = addr >> amdgpu_vm_block_size; - pt = vm->page_tables[pt_idx].entry.robj; + pt = shadow ? vm->page_tables[pt_idx].entry.robj->shadow : + vm->page_tables[pt_idx].entry.robj; if ((addr & ~mask) == (end & ~mask)) nptes = end - addr; @@ -870,11 +874,13 @@ static void amdgpu_vm_update_ptes(struct amdgpu_pte_update_params *params, * @end: last PTE to handle * @dst: addr those PTEs should point to * @flags: hw mapping flags + * @shadow: update shaow or not */ static void amdgpu_vm_frag_ptes(struct amdgpu_pte_update_params *params, struct amdgpu_vm *vm, uint64_t start, uint64_t end, - uint64_t dst, uint32_t flags) + uint64_t dst, uint32_t flags, + bool shadow) { /** * The MC L1 TLB supports variable sized pages, based on a fragment @@ -906,7 +912,8 @@ static void amdgpu_vm_frag_ptes(struct amdgpu_pte_update_params *params, if (params->src || params->pages_addr || !(flags & AMDGPU_PTE_VALID) || (frag_start >= frag_end)) { - amdgpu_vm_update_ptes(params, vm, start, end, dst, flags); + amdgpu_vm_update_ptes(params, vm, start, end, dst, + flags, shadow); return; } @@ -917,18 +924,19 @@ static void amdgpu_vm_frag_ptes(struct amdgpu_pte_update_params *params, /* handle the 4K area at the beginning */ if (start != frag_start) { amdgpu_vm_update_ptes(params, vm, start, frag_start, - dst, flags); + dst, flags, shadow); dst += (frag_start - start) * AMDGPU_GPU_PAGE_SIZE; } /* handle the area in the middle */ amdgpu_vm_update_ptes(params, vm, frag_start, frag_end, dst, - flags | AMDGPU_PTE_FRAG(frag)); + flags | AMDGPU_PTE_FRAG(frag), shadow); /* handle the 4K area at the end */ if (frag_end != end) { dst += (frag_end - frag_start) * AMDGPU_GPU_PAGE_SIZE; - amdgpu_vm_update_ptes(params, vm, frag_end, end, dst, flags); + amdgpu_vm_update_ptes(params, vm, frag_end, end, dst, + flags, shadow); } } @@ -1007,6 +1015,9 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev, ndw += 2 * 10; } + /* double ndw, since need to update shadow pt bo as well */ + ndw *= 2; + r = amdgpu_job_alloc_with_ib(adev, ndw * 4, &job); if (r) return r; @@ -1026,7 +1037,8 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev, if (r) goto error_free; - amdgpu_vm_frag_ptes(¶ms, vm, start, last + 1, addr, flags); + amdgpu_vm_frag_ptes(¶ms, vm, start, last + 1, addr, flags, true); + amdgpu_vm_frag_ptes(¶ms, vm, start, last + 1, addr, flags, false); amdgpu_ring_pad_ib(ring, params.ib); WARN_ON(params.ib->length_dw > ndw); -- 1.9.1