aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
diff options
context:
space:
mode:
authorChristian König <christian.koenig@amd.com>2018-01-25 12:36:15 -0500
committerAlex Deucher <alexander.deucher@amd.com>2018-02-19 14:18:55 -0500
commit4584312d387f758534a51d7dd0a8c0f3b23ccc6e (patch)
tree0db511c7e473a3175e0cb71e6df1d9e654f91a94 /drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
parent44e1baeb6321fb4ce1dbc50c4cb895b671b2fbf9 (diff)
drm/amdgpu: fill only the lower range with ATS entries v2
At least on x86-64 the upper range is purely used by the kernel, avoid creating any ATS mappings there as security precaution and to allow proper page fault reporting in the upper range. v2: remove unused variable Signed-off-by: Christian König <christian.koenig@amd.com> Reviewed-by: Felix Kuehling <Felix.Kuehling@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c')
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c82
1 files changed, 53 insertions, 29 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
index e584c203c357..61cf93867b8e 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
@@ -267,24 +267,33 @@ bool amdgpu_vm_ready(struct amdgpu_vm *vm)
267 * Root PD needs to be reserved when calling this. 267 * Root PD needs to be reserved when calling this.
268 */ 268 */
269static int amdgpu_vm_clear_bo(struct amdgpu_device *adev, 269static int amdgpu_vm_clear_bo(struct amdgpu_device *adev,
270 struct amdgpu_vm *vm, 270 struct amdgpu_vm *vm, struct amdgpu_bo *bo,
271 struct amdgpu_bo *bo, 271 unsigned level, bool pte_support_ats)
272 unsigned level)
273{ 272{
274 struct ttm_operation_ctx ctx = { true, false }; 273 struct ttm_operation_ctx ctx = { true, false };
275 struct dma_fence *fence = NULL; 274 struct dma_fence *fence = NULL;
276 uint64_t addr, init_value; 275 unsigned entries, ats_entries;
277 struct amdgpu_ring *ring; 276 struct amdgpu_ring *ring;
278 struct amdgpu_job *job; 277 struct amdgpu_job *job;
279 unsigned entries; 278 uint64_t addr;
280 int r; 279 int r;
281 280
282 if (vm->pte_support_ats) { 281 addr = amdgpu_bo_gpu_offset(bo);
283 init_value = AMDGPU_PTE_DEFAULT_ATC; 282 entries = amdgpu_bo_size(bo) / 8;
284 if (level != AMDGPU_VM_PTB) 283
285 init_value |= AMDGPU_PDE_PTE; 284 if (pte_support_ats) {
285 if (level == adev->vm_manager.root_level) {
286 ats_entries = amdgpu_vm_level_shift(adev, level);
287 ats_entries += AMDGPU_GPU_PAGE_SHIFT;
288 ats_entries = AMDGPU_VA_HOLE_START >> ats_entries;
289 ats_entries = min(ats_entries, entries);
290 entries -= ats_entries;
291 } else {
292 ats_entries = entries;
293 entries = 0;
294 }
286 } else { 295 } else {
287 init_value = 0; 296 ats_entries = 0;
288 } 297 }
289 298
290 ring = container_of(vm->entity.sched, struct amdgpu_ring, sched); 299 ring = container_of(vm->entity.sched, struct amdgpu_ring, sched);
@@ -297,15 +306,26 @@ static int amdgpu_vm_clear_bo(struct amdgpu_device *adev,
297 if (r) 306 if (r)
298 goto error; 307 goto error;
299 308
300 addr = amdgpu_bo_gpu_offset(bo);
301 entries = amdgpu_bo_size(bo) / 8;
302
303 r = amdgpu_job_alloc_with_ib(adev, 64, &job); 309 r = amdgpu_job_alloc_with_ib(adev, 64, &job);
304 if (r) 310 if (r)
305 goto error; 311 goto error;
306 312
307 amdgpu_vm_set_pte_pde(adev, &job->ibs[0], addr, 0, 313 if (ats_entries) {
308 entries, 0, init_value); 314 uint64_t ats_value;
315
316 ats_value = AMDGPU_PTE_DEFAULT_ATC;
317 if (level != AMDGPU_VM_PTB)
318 ats_value |= AMDGPU_PDE_PTE;
319
320 amdgpu_vm_set_pte_pde(adev, &job->ibs[0], addr, 0,
321 ats_entries, 0, ats_value);
322 addr += ats_entries * 8;
323 }
324
325 if (entries)
326 amdgpu_vm_set_pte_pde(adev, &job->ibs[0], addr, 0,
327 entries, 0, 0);
328
309 amdgpu_ring_pad_ib(ring, &job->ibs[0]); 329 amdgpu_ring_pad_ib(ring, &job->ibs[0]);
310 330
311 WARN_ON(job->ibs[0].length_dw > 64); 331 WARN_ON(job->ibs[0].length_dw > 64);
@@ -339,7 +359,7 @@ static int amdgpu_vm_alloc_levels(struct amdgpu_device *adev,
339 struct amdgpu_vm *vm, 359 struct amdgpu_vm *vm,
340 struct amdgpu_vm_pt *parent, 360 struct amdgpu_vm_pt *parent,
341 uint64_t saddr, uint64_t eaddr, 361 uint64_t saddr, uint64_t eaddr,
342 unsigned level) 362 unsigned level, bool ats)
343{ 363{
344 unsigned shift = amdgpu_vm_level_shift(adev, level); 364 unsigned shift = amdgpu_vm_level_shift(adev, level);
345 unsigned pt_idx, from, to; 365 unsigned pt_idx, from, to;
@@ -389,7 +409,7 @@ static int amdgpu_vm_alloc_levels(struct amdgpu_device *adev,
389 if (r) 409 if (r)
390 return r; 410 return r;
391 411
392 r = amdgpu_vm_clear_bo(adev, vm, pt, level); 412 r = amdgpu_vm_clear_bo(adev, vm, pt, level, ats);
393 if (r) { 413 if (r) {
394 amdgpu_bo_unref(&pt); 414 amdgpu_bo_unref(&pt);
395 return r; 415 return r;
@@ -421,7 +441,7 @@ static int amdgpu_vm_alloc_levels(struct amdgpu_device *adev,
421 uint64_t sub_eaddr = (pt_idx == to) ? eaddr : 441 uint64_t sub_eaddr = (pt_idx == to) ? eaddr :
422 ((1 << shift) - 1); 442 ((1 << shift) - 1);
423 r = amdgpu_vm_alloc_levels(adev, vm, entry, sub_saddr, 443 r = amdgpu_vm_alloc_levels(adev, vm, entry, sub_saddr,
424 sub_eaddr, level); 444 sub_eaddr, level, ats);
425 if (r) 445 if (r)
426 return r; 446 return r;
427 } 447 }
@@ -444,26 +464,29 @@ int amdgpu_vm_alloc_pts(struct amdgpu_device *adev,
444 struct amdgpu_vm *vm, 464 struct amdgpu_vm *vm,
445 uint64_t saddr, uint64_t size) 465 uint64_t saddr, uint64_t size)
446{ 466{
447 uint64_t last_pfn;
448 uint64_t eaddr; 467 uint64_t eaddr;
468 bool ats = false;
449 469
450 /* validate the parameters */ 470 /* validate the parameters */
451 if (saddr & AMDGPU_GPU_PAGE_MASK || size & AMDGPU_GPU_PAGE_MASK) 471 if (saddr & AMDGPU_GPU_PAGE_MASK || size & AMDGPU_GPU_PAGE_MASK)
452 return -EINVAL; 472 return -EINVAL;
453 473
454 eaddr = saddr + size - 1; 474 eaddr = saddr + size - 1;
455 last_pfn = eaddr / AMDGPU_GPU_PAGE_SIZE; 475
456 if (last_pfn >= adev->vm_manager.max_pfn) { 476 if (vm->pte_support_ats)
457 dev_err(adev->dev, "va above limit (0x%08llX >= 0x%08llX)\n", 477 ats = saddr < AMDGPU_VA_HOLE_START;
458 last_pfn, adev->vm_manager.max_pfn);
459 return -EINVAL;
460 }
461 478
462 saddr /= AMDGPU_GPU_PAGE_SIZE; 479 saddr /= AMDGPU_GPU_PAGE_SIZE;
463 eaddr /= AMDGPU_GPU_PAGE_SIZE; 480 eaddr /= AMDGPU_GPU_PAGE_SIZE;
464 481
482 if (eaddr >= adev->vm_manager.max_pfn) {
483 dev_err(adev->dev, "va above limit (0x%08llX >= 0x%08llX)\n",
484 eaddr, adev->vm_manager.max_pfn);
485 return -EINVAL;
486 }
487
465 return amdgpu_vm_alloc_levels(adev, vm, &vm->root, saddr, eaddr, 488 return amdgpu_vm_alloc_levels(adev, vm, &vm->root, saddr, eaddr,
466 adev->vm_manager.root_level); 489 adev->vm_manager.root_level, ats);
467} 490}
468 491
469/** 492/**
@@ -1660,16 +1683,16 @@ int amdgpu_vm_clear_freed(struct amdgpu_device *adev,
1660 struct dma_fence **fence) 1683 struct dma_fence **fence)
1661{ 1684{
1662 struct amdgpu_bo_va_mapping *mapping; 1685 struct amdgpu_bo_va_mapping *mapping;
1686 uint64_t init_pte_value = 0;
1663 struct dma_fence *f = NULL; 1687 struct dma_fence *f = NULL;
1664 int r; 1688 int r;
1665 uint64_t init_pte_value = 0;
1666 1689
1667 while (!list_empty(&vm->freed)) { 1690 while (!list_empty(&vm->freed)) {
1668 mapping = list_first_entry(&vm->freed, 1691 mapping = list_first_entry(&vm->freed,
1669 struct amdgpu_bo_va_mapping, list); 1692 struct amdgpu_bo_va_mapping, list);
1670 list_del(&mapping->list); 1693 list_del(&mapping->list);
1671 1694
1672 if (vm->pte_support_ats) 1695 if (vm->pte_support_ats && mapping->start < AMDGPU_VA_HOLE_START)
1673 init_pte_value = AMDGPU_PTE_DEFAULT_ATC; 1696 init_pte_value = AMDGPU_PTE_DEFAULT_ATC;
1674 1697
1675 r = amdgpu_vm_bo_update_mapping(adev, NULL, NULL, vm, 1698 r = amdgpu_vm_bo_update_mapping(adev, NULL, NULL, vm,
@@ -2362,7 +2385,8 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm,
2362 goto error_free_root; 2385 goto error_free_root;
2363 2386
2364 r = amdgpu_vm_clear_bo(adev, vm, vm->root.base.bo, 2387 r = amdgpu_vm_clear_bo(adev, vm, vm->root.base.bo,
2365 adev->vm_manager.root_level); 2388 adev->vm_manager.root_level,
2389 vm->pte_support_ats);
2366 if (r) 2390 if (r)
2367 goto error_unreserve; 2391 goto error_unreserve;
2368 2392