diff options
author | Christian König <christian.koenig@amd.com> | 2015-09-28 06:31:26 -0400 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2015-10-14 16:16:40 -0400 |
commit | d9c13156a628cc9f8f062f2c10e2bff55b92aaab (patch) | |
tree | 9324e82899a044032cfe1be0800786942fbee398 /drivers/gpu/drm/amd/amdgpu | |
parent | ce0c6bcda6d0d9fc9df65dccb46a68b79ba6f018 (diff) |
drm/amdgpu: add option to stop on VM fault
Signed-off-by: Christian König <christian.koenig@amd.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu.h | 6 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c | 40 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c | 36 |
4 files changed, 80 insertions, 6 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index afc984806c4c..a3dbbd1fc060 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h | |||
@@ -79,6 +79,7 @@ extern int amdgpu_bapm; | |||
79 | extern int amdgpu_deep_color; | 79 | extern int amdgpu_deep_color; |
80 | extern int amdgpu_vm_size; | 80 | extern int amdgpu_vm_size; |
81 | extern int amdgpu_vm_block_size; | 81 | extern int amdgpu_vm_block_size; |
82 | extern int amdgpu_vm_fault_stop; | ||
82 | extern int amdgpu_enable_scheduler; | 83 | extern int amdgpu_enable_scheduler; |
83 | extern int amdgpu_sched_jobs; | 84 | extern int amdgpu_sched_jobs; |
84 | extern int amdgpu_sched_hw_submission; | 85 | extern int amdgpu_sched_hw_submission; |
@@ -960,6 +961,11 @@ struct amdgpu_ring { | |||
960 | #define AMDGPU_PTE_FRAG_64KB (4 << 7) | 961 | #define AMDGPU_PTE_FRAG_64KB (4 << 7) |
961 | #define AMDGPU_LOG2_PAGES_PER_FRAG 4 | 962 | #define AMDGPU_LOG2_PAGES_PER_FRAG 4 |
962 | 963 | ||
964 | /* How to programm VM fault handling */ | ||
965 | #define AMDGPU_VM_FAULT_STOP_NEVER 0 | ||
966 | #define AMDGPU_VM_FAULT_STOP_FIRST 1 | ||
967 | #define AMDGPU_VM_FAULT_STOP_ALWAYS 2 | ||
968 | |||
963 | struct amdgpu_vm_pt { | 969 | struct amdgpu_vm_pt { |
964 | struct amdgpu_bo *bo; | 970 | struct amdgpu_bo *bo; |
965 | uint64_t addr; | 971 | uint64_t addr; |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c index c183772de7c1..bec091632194 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | |||
@@ -75,6 +75,7 @@ int amdgpu_bapm = -1; | |||
75 | int amdgpu_deep_color = 0; | 75 | int amdgpu_deep_color = 0; |
76 | int amdgpu_vm_size = 8; | 76 | int amdgpu_vm_size = 8; |
77 | int amdgpu_vm_block_size = -1; | 77 | int amdgpu_vm_block_size = -1; |
78 | int amdgpu_vm_fault_stop = 0; | ||
78 | int amdgpu_exp_hw_support = 0; | 79 | int amdgpu_exp_hw_support = 0; |
79 | int amdgpu_enable_scheduler = 1; | 80 | int amdgpu_enable_scheduler = 1; |
80 | int amdgpu_sched_jobs = 16; | 81 | int amdgpu_sched_jobs = 16; |
@@ -141,6 +142,9 @@ module_param_named(vm_size, amdgpu_vm_size, int, 0444); | |||
141 | MODULE_PARM_DESC(vm_block_size, "VM page table size in bits (default depending on vm_size)"); | 142 | MODULE_PARM_DESC(vm_block_size, "VM page table size in bits (default depending on vm_size)"); |
142 | module_param_named(vm_block_size, amdgpu_vm_block_size, int, 0444); | 143 | module_param_named(vm_block_size, amdgpu_vm_block_size, int, 0444); |
143 | 144 | ||
145 | MODULE_PARM_DESC(vm_fault_stop, "Stop on VM fault (0 = never (default), 1 = print first, 2 = always)"); | ||
146 | module_param_named(vm_fault_stop, amdgpu_vm_fault_stop, int, 0444); | ||
147 | |||
144 | MODULE_PARM_DESC(exp_hw_support, "experimental hw support (1 = enable, 0 = disable (default))"); | 148 | MODULE_PARM_DESC(exp_hw_support, "experimental hw support (1 = enable, 0 = disable (default))"); |
145 | module_param_named(exp_hw_support, amdgpu_exp_hw_support, int, 0444); | 149 | module_param_named(exp_hw_support, amdgpu_exp_hw_support, int, 0444); |
146 | 150 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c index fab5471d25d7..488348272c4d 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c | |||
@@ -436,6 +436,33 @@ static int gmc_v7_0_gart_set_pte_pde(struct amdgpu_device *adev, | |||
436 | } | 436 | } |
437 | 437 | ||
438 | /** | 438 | /** |
439 | * gmc_v8_0_set_fault_enable_default - update VM fault handling | ||
440 | * | ||
441 | * @adev: amdgpu_device pointer | ||
442 | * @value: true redirects VM faults to the default page | ||
443 | */ | ||
444 | static void gmc_v7_0_set_fault_enable_default(struct amdgpu_device *adev, | ||
445 | bool value) | ||
446 | { | ||
447 | u32 tmp; | ||
448 | |||
449 | tmp = RREG32(mmVM_CONTEXT1_CNTL); | ||
450 | tmp = REG_SET_FIELD(tmp, VM_CONTEXT1_CNTL, | ||
451 | RANGE_PROTECTION_FAULT_ENABLE_DEFAULT, value); | ||
452 | tmp = REG_SET_FIELD(tmp, VM_CONTEXT1_CNTL, | ||
453 | DUMMY_PAGE_PROTECTION_FAULT_ENABLE_DEFAULT, value); | ||
454 | tmp = REG_SET_FIELD(tmp, VM_CONTEXT1_CNTL, | ||
455 | PDE0_PROTECTION_FAULT_ENABLE_DEFAULT, value); | ||
456 | tmp = REG_SET_FIELD(tmp, VM_CONTEXT1_CNTL, | ||
457 | VALID_PROTECTION_FAULT_ENABLE_DEFAULT, value); | ||
458 | tmp = REG_SET_FIELD(tmp, VM_CONTEXT1_CNTL, | ||
459 | READ_PROTECTION_FAULT_ENABLE_DEFAULT, value); | ||
460 | tmp = REG_SET_FIELD(tmp, VM_CONTEXT1_CNTL, | ||
461 | WRITE_PROTECTION_FAULT_ENABLE_DEFAULT, value); | ||
462 | WREG32(mmVM_CONTEXT1_CNTL, tmp); | ||
463 | } | ||
464 | |||
465 | /** | ||
439 | * gmc_v7_0_gart_enable - gart enable | 466 | * gmc_v7_0_gart_enable - gart enable |
440 | * | 467 | * |
441 | * @adev: amdgpu_device pointer | 468 | * @adev: amdgpu_device pointer |
@@ -523,15 +550,13 @@ static int gmc_v7_0_gart_enable(struct amdgpu_device *adev) | |||
523 | tmp = RREG32(mmVM_CONTEXT1_CNTL); | 550 | tmp = RREG32(mmVM_CONTEXT1_CNTL); |
524 | tmp = REG_SET_FIELD(tmp, VM_CONTEXT1_CNTL, ENABLE_CONTEXT, 1); | 551 | tmp = REG_SET_FIELD(tmp, VM_CONTEXT1_CNTL, ENABLE_CONTEXT, 1); |
525 | tmp = REG_SET_FIELD(tmp, VM_CONTEXT1_CNTL, PAGE_TABLE_DEPTH, 1); | 552 | tmp = REG_SET_FIELD(tmp, VM_CONTEXT1_CNTL, PAGE_TABLE_DEPTH, 1); |
526 | tmp = REG_SET_FIELD(tmp, VM_CONTEXT1_CNTL, RANGE_PROTECTION_FAULT_ENABLE_DEFAULT, 1); | ||
527 | tmp = REG_SET_FIELD(tmp, VM_CONTEXT1_CNTL, DUMMY_PAGE_PROTECTION_FAULT_ENABLE_DEFAULT, 1); | ||
528 | tmp = REG_SET_FIELD(tmp, VM_CONTEXT1_CNTL, PDE0_PROTECTION_FAULT_ENABLE_DEFAULT, 1); | ||
529 | tmp = REG_SET_FIELD(tmp, VM_CONTEXT1_CNTL, VALID_PROTECTION_FAULT_ENABLE_DEFAULT, 1); | ||
530 | tmp = REG_SET_FIELD(tmp, VM_CONTEXT1_CNTL, READ_PROTECTION_FAULT_ENABLE_DEFAULT, 1); | ||
531 | tmp = REG_SET_FIELD(tmp, VM_CONTEXT1_CNTL, WRITE_PROTECTION_FAULT_ENABLE_DEFAULT, 1); | ||
532 | tmp = REG_SET_FIELD(tmp, VM_CONTEXT1_CNTL, PAGE_TABLE_BLOCK_SIZE, | 553 | tmp = REG_SET_FIELD(tmp, VM_CONTEXT1_CNTL, PAGE_TABLE_BLOCK_SIZE, |
533 | amdgpu_vm_block_size - 9); | 554 | amdgpu_vm_block_size - 9); |
534 | WREG32(mmVM_CONTEXT1_CNTL, tmp); | 555 | WREG32(mmVM_CONTEXT1_CNTL, tmp); |
556 | if (amdgpu_vm_fault_stop == AMDGPU_VM_FAULT_STOP_ALWAYS) | ||
557 | gmc_v7_0_set_fault_enable_default(adev, false); | ||
558 | else | ||
559 | gmc_v7_0_set_fault_enable_default(adev, true); | ||
535 | 560 | ||
536 | if (adev->asic_type == CHIP_KAVERI) { | 561 | if (adev->asic_type == CHIP_KAVERI) { |
537 | tmp = RREG32(mmCHUB_CONTROL); | 562 | tmp = RREG32(mmCHUB_CONTROL); |
@@ -1268,6 +1293,9 @@ static int gmc_v7_0_process_interrupt(struct amdgpu_device *adev, | |||
1268 | if (!addr && !status) | 1293 | if (!addr && !status) |
1269 | return 0; | 1294 | return 0; |
1270 | 1295 | ||
1296 | if (amdgpu_vm_fault_stop == AMDGPU_VM_FAULT_STOP_FIRST) | ||
1297 | gmc_v7_0_set_fault_enable_default(adev, false); | ||
1298 | |||
1271 | dev_err(adev->dev, "GPU fault detected: %d 0x%08x\n", | 1299 | dev_err(adev->dev, "GPU fault detected: %d 0x%08x\n", |
1272 | entry->src_id, entry->src_data); | 1300 | entry->src_id, entry->src_data); |
1273 | dev_err(adev->dev, " VM_CONTEXT1_PROTECTION_FAULT_ADDR 0x%08X\n", | 1301 | dev_err(adev->dev, " VM_CONTEXT1_PROTECTION_FAULT_ADDR 0x%08X\n", |
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c index 7bc9e9fcf3d2..42b5ff827055 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c | |||
@@ -550,6 +550,35 @@ static int gmc_v8_0_gart_set_pte_pde(struct amdgpu_device *adev, | |||
550 | } | 550 | } |
551 | 551 | ||
552 | /** | 552 | /** |
553 | * gmc_v8_0_set_fault_enable_default - update VM fault handling | ||
554 | * | ||
555 | * @adev: amdgpu_device pointer | ||
556 | * @value: true redirects VM faults to the default page | ||
557 | */ | ||
558 | static void gmc_v8_0_set_fault_enable_default(struct amdgpu_device *adev, | ||
559 | bool value) | ||
560 | { | ||
561 | u32 tmp; | ||
562 | |||
563 | tmp = RREG32(mmVM_CONTEXT1_CNTL); | ||
564 | tmp = REG_SET_FIELD(tmp, VM_CONTEXT1_CNTL, | ||
565 | RANGE_PROTECTION_FAULT_ENABLE_DEFAULT, value); | ||
566 | tmp = REG_SET_FIELD(tmp, VM_CONTEXT1_CNTL, | ||
567 | DUMMY_PAGE_PROTECTION_FAULT_ENABLE_DEFAULT, value); | ||
568 | tmp = REG_SET_FIELD(tmp, VM_CONTEXT1_CNTL, | ||
569 | PDE0_PROTECTION_FAULT_ENABLE_DEFAULT, value); | ||
570 | tmp = REG_SET_FIELD(tmp, VM_CONTEXT1_CNTL, | ||
571 | VALID_PROTECTION_FAULT_ENABLE_DEFAULT, value); | ||
572 | tmp = REG_SET_FIELD(tmp, VM_CONTEXT1_CNTL, | ||
573 | READ_PROTECTION_FAULT_ENABLE_DEFAULT, value); | ||
574 | tmp = REG_SET_FIELD(tmp, VM_CONTEXT1_CNTL, | ||
575 | WRITE_PROTECTION_FAULT_ENABLE_DEFAULT, value); | ||
576 | tmp = REG_SET_FIELD(tmp, VM_CONTEXT1_CNTL, | ||
577 | EXECUTE_PROTECTION_FAULT_ENABLE_DEFAULT, value); | ||
578 | WREG32(mmVM_CONTEXT1_CNTL, tmp); | ||
579 | } | ||
580 | |||
581 | /** | ||
553 | * gmc_v8_0_gart_enable - gart enable | 582 | * gmc_v8_0_gart_enable - gart enable |
554 | * | 583 | * |
555 | * @adev: amdgpu_device pointer | 584 | * @adev: amdgpu_device pointer |
@@ -663,6 +692,10 @@ static int gmc_v8_0_gart_enable(struct amdgpu_device *adev) | |||
663 | tmp = REG_SET_FIELD(tmp, VM_CONTEXT1_CNTL, PAGE_TABLE_BLOCK_SIZE, | 692 | tmp = REG_SET_FIELD(tmp, VM_CONTEXT1_CNTL, PAGE_TABLE_BLOCK_SIZE, |
664 | amdgpu_vm_block_size - 9); | 693 | amdgpu_vm_block_size - 9); |
665 | WREG32(mmVM_CONTEXT1_CNTL, tmp); | 694 | WREG32(mmVM_CONTEXT1_CNTL, tmp); |
695 | if (amdgpu_vm_fault_stop == AMDGPU_VM_FAULT_STOP_ALWAYS) | ||
696 | gmc_v8_0_set_fault_enable_default(adev, false); | ||
697 | else | ||
698 | gmc_v8_0_set_fault_enable_default(adev, true); | ||
666 | 699 | ||
667 | gmc_v8_0_gart_flush_gpu_tlb(adev, 0); | 700 | gmc_v8_0_gart_flush_gpu_tlb(adev, 0); |
668 | DRM_INFO("PCIE GART of %uM enabled (table at 0x%016llX).\n", | 701 | DRM_INFO("PCIE GART of %uM enabled (table at 0x%016llX).\n", |
@@ -1268,6 +1301,9 @@ static int gmc_v8_0_process_interrupt(struct amdgpu_device *adev, | |||
1268 | if (!addr && !status) | 1301 | if (!addr && !status) |
1269 | return 0; | 1302 | return 0; |
1270 | 1303 | ||
1304 | if (amdgpu_vm_fault_stop == AMDGPU_VM_FAULT_STOP_FIRST) | ||
1305 | gmc_v8_0_set_fault_enable_default(adev, false); | ||
1306 | |||
1271 | dev_err(adev->dev, "GPU fault detected: %d 0x%08x\n", | 1307 | dev_err(adev->dev, "GPU fault detected: %d 0x%08x\n", |
1272 | entry->src_id, entry->src_data); | 1308 | entry->src_id, entry->src_data); |
1273 | dev_err(adev->dev, " VM_CONTEXT1_PROTECTION_FAULT_ADDR 0x%08X\n", | 1309 | dev_err(adev->dev, " VM_CONTEXT1_PROTECTION_FAULT_ADDR 0x%08X\n", |