diff options
author | Christian König <christian.koenig@amd.com> | 2016-10-25 15:52:28 +0200 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2017-03-29 23:55:27 -0400 |
commit | 4e2cb640c2efbf86058cffd2785307690ebefe20 (patch) | |
tree | ae90fa23d9b36e1daa1354dbdde7b122286e5a2f /drivers/gpu/drm/amd | |
parent | 194d2161131b35f9cd4cf3e355f2d7cd3b296898 (diff) | |
download | op-kernel-dev-4e2cb640c2efbf86058cffd2785307690ebefe20.zip op-kernel-dev-4e2cb640c2efbf86058cffd2785307690ebefe20.tar.gz |
drm/amdgpu: handle multi level PD during PT updates
Not the best solution, but good enough for now.
Signed-off-by: Christian König <christian.koenig@amd.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 39 |
1 files changed, 34 insertions, 5 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index e3c6ffa..c9f5f10 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c @@ -880,6 +880,32 @@ int amdgpu_vm_update_directories(struct amdgpu_device *adev, } /** + * amdgpu_vm_find_pt - find the page table for an address + * + * @p: see amdgpu_pte_update_params definition + * @addr: virtual address in question + * + * Find the page table BO for a virtual address, return NULL when none found. + */ +static struct amdgpu_bo *amdgpu_vm_get_pt(struct amdgpu_pte_update_params *p, + uint64_t addr) +{ + struct amdgpu_vm_pt *entry = &p->vm->root; + unsigned idx, level = p->adev->vm_manager.num_level; + + while (entry->entries) { + idx = addr >> (amdgpu_vm_block_size * level--); + idx %= amdgpu_bo_size(entry->bo) / 8; + entry = &entry->entries[idx]; + } + + if (level) + return NULL; + + return entry->bo; +} + +/** * amdgpu_vm_update_ptes - make sure that page tables are valid * * @params: see amdgpu_pte_update_params definition @@ -899,15 +925,16 @@ static void amdgpu_vm_update_ptes(struct amdgpu_pte_update_params *params, uint64_t cur_pe_start, cur_nptes, cur_dst; uint64_t addr; /* next GPU address to be updated */ - uint64_t pt_idx; struct amdgpu_bo *pt; unsigned nptes; /* next number of ptes to be updated */ uint64_t next_pe_start; /* initialize the variables */ addr = start; - pt_idx = addr >> amdgpu_vm_block_size; - pt = params->vm->root.entries[pt_idx].bo; + pt = amdgpu_vm_get_pt(params, addr); + if (!pt) + return; + if (params->shadow) { if (!pt->shadow) return; @@ -929,8 +956,10 @@ 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 = params->vm->root.entries[pt_idx].bo; + pt = amdgpu_vm_get_pt(params, addr); + if (!pt) + return; + if (params->shadow) { if (!pt->shadow) return; |