summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/amd
diff options
context:
space:
mode:
authorChristian König <christian.koenig@amd.com>2016-10-25 15:52:28 +0200
committerAlex Deucher <alexander.deucher@amd.com>2017-03-29 23:55:27 -0400
commit4e2cb640c2efbf86058cffd2785307690ebefe20 (patch)
treeae90fa23d9b36e1daa1354dbdde7b122286e5a2f /drivers/gpu/drm/amd
parent194d2161131b35f9cd4cf3e355f2d7cd3b296898 (diff)
downloadop-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.c39
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;
OpenPOWER on IntegriCloud