Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/msm: devcoredump iommu fault support

Wire up support to stall the SMMU on iova fault, and collect a devcore-
dump snapshot for easier debugging of faults.

Currently this is a6xx-only, but mostly only because so far it is the
only one using adreno-smmu-priv.

Signed-off-by: Rob Clark <robdclark@chromium.org>
Acked-by: Jordan Crouse <jordan@cosmicpenguin.net>
Link: https://lore.kernel.org/r/20210610214431.539029-6-robdclark@gmail.com
Signed-off-by: Rob Clark <robdclark@chromium.org>

+186 -12
+17 -2
drivers/gpu/drm/msm/adreno/a5xx_gpu.c
··· 1200 1200 struct drm_device *dev = gpu->dev; 1201 1201 struct msm_ringbuffer *ring = gpu->funcs->active_ring(gpu); 1202 1202 1203 + /* 1204 + * If stalled on SMMU fault, we could trip the GPU's hang detection, 1205 + * but the fault handler will trigger the devcore dump, and we want 1206 + * to otherwise resume normally rather than killing the submit, so 1207 + * just bail. 1208 + */ 1209 + if (gpu_read(gpu, REG_A5XX_RBBM_STATUS3) & BIT(24)) 1210 + return; 1211 + 1203 1212 DRM_DEV_ERROR(dev->dev, "gpu fault ring %d fence %x status %8.8X rb %4.4x/%4.4x ib1 %16.16llX/%4.4x ib2 %16.16llX/%4.4x\n", 1204 1213 ring ? ring->id : -1, ring ? ring->seqno : 0, 1205 1214 gpu_read(gpu, REG_A5XX_RBBM_STATUS), ··· 1532 1523 { 1533 1524 struct a5xx_gpu_state *a5xx_state = kzalloc(sizeof(*a5xx_state), 1534 1525 GFP_KERNEL); 1526 + bool stalled = !!(gpu_read(gpu, REG_A5XX_RBBM_STATUS3) & BIT(24)); 1535 1527 1536 1528 if (!a5xx_state) 1537 1529 return ERR_PTR(-ENOMEM); ··· 1545 1535 1546 1536 a5xx_state->base.rbbm_status = gpu_read(gpu, REG_A5XX_RBBM_STATUS); 1547 1537 1548 - /* Get the HLSQ regs with the help of the crashdumper */ 1549 - a5xx_gpu_state_get_hlsq_regs(gpu, a5xx_state); 1538 + /* 1539 + * Get the HLSQ regs with the help of the crashdumper, but only if 1540 + * we are not stalled in an iommu fault (in which case the crashdumper 1541 + * would not have access to memory) 1542 + */ 1543 + if (!stalled) 1544 + a5xx_gpu_state_get_hlsq_regs(gpu, a5xx_state); 1550 1545 1551 1546 a5xx_set_hwcg(gpu, true); 1552 1547
+36 -2
drivers/gpu/drm/msm/adreno/a6xx_gpu.c
··· 1193 1193 struct msm_gpu *gpu = arg; 1194 1194 struct adreno_smmu_fault_info *info = data; 1195 1195 const char *type = "UNKNOWN"; 1196 + const char *block; 1197 + bool do_devcoredump = info && !READ_ONCE(gpu->crashstate); 1198 + 1199 + /* 1200 + * If we aren't going to be resuming later from fault_worker, then do 1201 + * it now. 1202 + */ 1203 + if (!do_devcoredump) { 1204 + gpu->aspace->mmu->funcs->resume_translation(gpu->aspace->mmu); 1205 + } 1196 1206 1197 1207 /* 1198 1208 * Print a default message if we couldn't get the data from the ··· 1226 1216 else if (info->fsr & ARM_SMMU_FSR_EF) 1227 1217 type = "EXTERNAL"; 1228 1218 1219 + block = a6xx_fault_block(gpu, info->fsynr1 & 0xff); 1220 + 1229 1221 pr_warn_ratelimited("*** gpu fault: ttbr0=%.16llx iova=%.16lx dir=%s type=%s source=%s (%u,%u,%u,%u)\n", 1230 1222 info->ttbr0, iova, 1231 - flags & IOMMU_FAULT_WRITE ? "WRITE" : "READ", type, 1232 - a6xx_fault_block(gpu, info->fsynr1 & 0xff), 1223 + flags & IOMMU_FAULT_WRITE ? "WRITE" : "READ", 1224 + type, block, 1233 1225 gpu_read(gpu, REG_A6XX_CP_SCRATCH_REG(4)), 1234 1226 gpu_read(gpu, REG_A6XX_CP_SCRATCH_REG(5)), 1235 1227 gpu_read(gpu, REG_A6XX_CP_SCRATCH_REG(6)), 1236 1228 gpu_read(gpu, REG_A6XX_CP_SCRATCH_REG(7))); 1229 + 1230 + if (do_devcoredump) { 1231 + /* Turn off the hangcheck timer to keep it from bothering us */ 1232 + del_timer(&gpu->hangcheck_timer); 1233 + 1234 + gpu->fault_info.ttbr0 = info->ttbr0; 1235 + gpu->fault_info.iova = iova; 1236 + gpu->fault_info.flags = flags; 1237 + gpu->fault_info.type = type; 1238 + gpu->fault_info.block = block; 1239 + 1240 + kthread_queue_work(gpu->worker, &gpu->fault_work); 1241 + } 1237 1242 1238 1243 return 0; 1239 1244 } ··· 1300 1275 struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); 1301 1276 struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu); 1302 1277 struct msm_ringbuffer *ring = gpu->funcs->active_ring(gpu); 1278 + 1279 + /* 1280 + * If stalled on SMMU fault, we could trip the GPU's hang detection, 1281 + * but the fault handler will trigger the devcore dump, and we want 1282 + * to otherwise resume normally rather than killing the submit, so 1283 + * just bail. 1284 + */ 1285 + if (gpu_read(gpu, REG_A6XX_RBBM_STATUS3) & A6XX_RBBM_STATUS3_SMMU_STALLED_ON_FAULT) 1286 + return; 1303 1287 1304 1288 /* 1305 1289 * Force the GPU to stay on until after we finish
+34 -8
drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c
··· 832 832 a6xx_get_ahb_gpu_registers(gpu, 833 833 a6xx_state, &a6xx_vbif_reglist, 834 834 &a6xx_state->registers[index++]); 835 + if (!dumper) { 836 + /* 837 + * We can't use the crashdumper when the SMMU is stalled, 838 + * because the GPU has no memory access until we resume 839 + * translation (but we don't want to do that until after 840 + * we have captured as much useful GPU state as possible). 841 + * So instead collect registers via the CPU: 842 + */ 843 + for (i = 0; i < ARRAY_SIZE(a6xx_reglist); i++) 844 + a6xx_get_ahb_gpu_registers(gpu, 845 + a6xx_state, &a6xx_reglist[i], 846 + &a6xx_state->registers[index++]); 847 + return; 848 + } 835 849 836 850 for (i = 0; i < ARRAY_SIZE(a6xx_reglist); i++) 837 851 a6xx_get_crashdumper_registers(gpu, ··· 919 905 920 906 struct msm_gpu_state *a6xx_gpu_state_get(struct msm_gpu *gpu) 921 907 { 922 - struct a6xx_crashdumper dumper = { 0 }; 908 + struct a6xx_crashdumper _dumper = { 0 }, *dumper = NULL; 923 909 struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); 924 910 struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu); 925 911 struct a6xx_gpu_state *a6xx_state = kzalloc(sizeof(*a6xx_state), 926 912 GFP_KERNEL); 913 + bool stalled = !!(gpu_read(gpu, REG_A6XX_RBBM_STATUS3) & 914 + A6XX_RBBM_STATUS3_SMMU_STALLED_ON_FAULT); 927 915 928 916 if (!a6xx_state) 929 917 return ERR_PTR(-ENOMEM); ··· 944 928 /* Get the banks of indexed registers */ 945 929 a6xx_get_indexed_registers(gpu, a6xx_state); 946 930 947 - /* Try to initialize the crashdumper */ 948 - if (!a6xx_crashdumper_init(gpu, &dumper)) { 949 - a6xx_get_registers(gpu, a6xx_state, &dumper); 950 - a6xx_get_shaders(gpu, a6xx_state, &dumper); 951 - a6xx_get_clusters(gpu, a6xx_state, &dumper); 952 - a6xx_get_dbgahb_clusters(gpu, a6xx_state, &dumper); 931 + /* 932 + * Try to initialize the crashdumper, if we are not dumping state 933 + * with the SMMU stalled. The crashdumper needs memory access to 934 + * write out GPU state, so we need to skip this when the SMMU is 935 + * stalled in response to an iova fault 936 + */ 937 + if (!stalled && !a6xx_crashdumper_init(gpu, &_dumper)) { 938 + dumper = &_dumper; 939 + } 953 940 954 - msm_gem_kernel_put(dumper.bo, gpu->aspace, true); 941 + a6xx_get_registers(gpu, a6xx_state, dumper); 942 + 943 + if (dumper) { 944 + a6xx_get_shaders(gpu, a6xx_state, dumper); 945 + a6xx_get_clusters(gpu, a6xx_state, dumper); 946 + a6xx_get_dbgahb_clusters(gpu, a6xx_state, dumper); 947 + 948 + msm_gem_kernel_put(dumper->bo, gpu->aspace, true); 955 949 } 956 950 957 951 if (snapshot_debugbus)
+15
drivers/gpu/drm/msm/adreno/adreno_gpu.c
··· 684 684 adreno_gpu->info->revn, adreno_gpu->rev.core, 685 685 adreno_gpu->rev.major, adreno_gpu->rev.minor, 686 686 adreno_gpu->rev.patchid); 687 + /* 688 + * If this is state collected due to iova fault, so fault related info 689 + * 690 + * TTBR0 would not be zero, so this is a good way to distinguish 691 + */ 692 + if (state->fault_info.ttbr0) { 693 + const struct msm_gpu_fault_info *info = &state->fault_info; 694 + 695 + drm_puts(p, "fault-info:\n"); 696 + drm_printf(p, " - ttbr0=%.16llx\n", info->ttbr0); 697 + drm_printf(p, " - iova=%.16lx\n", info->iova); 698 + drm_printf(p, " - dir=%s\n", info->flags & IOMMU_FAULT_WRITE ? "WRITE" : "READ"); 699 + drm_printf(p, " - type=%s\n", info->type); 700 + drm_printf(p, " - source=%s\n", info->block); 701 + } 687 702 688 703 drm_printf(p, "rbbm-status: 0x%08x\n", state->rbbm_status); 689 704
+1
drivers/gpu/drm/msm/msm_gem.h
··· 328 328 struct dma_fence *fence; 329 329 struct msm_gpu_submitqueue *queue; 330 330 struct pid *pid; /* submitting process */ 331 + bool fault_dumped; /* Limit devcoredump dumping to one per submit */ 331 332 bool valid; /* true if no cmdstream patching needed */ 332 333 bool in_rb; /* "sudo" mode, copy cmds into RB */ 333 334 struct msm_ringbuffer *ring;
+1
drivers/gpu/drm/msm/msm_gem_submit.c
··· 50 50 submit->cmd = (void *)&submit->bos[nr_bos]; 51 51 submit->queue = queue; 52 52 submit->ring = gpu->rb[queue->prio]; 53 + submit->fault_dumped = false; 53 54 54 55 /* initially, until copy_from_user() and bo lookup succeeds: */ 55 56 submit->nr_bos = 0;
+48
drivers/gpu/drm/msm/msm_gpu.c
··· 387 387 /* Fill in the additional crash state information */ 388 388 state->comm = kstrdup(comm, GFP_KERNEL); 389 389 state->cmd = kstrdup(cmd, GFP_KERNEL); 390 + state->fault_info = gpu->fault_info; 390 391 391 392 if (submit) { 392 393 int i, nr = 0; ··· 558 557 mutex_unlock(&dev->struct_mutex); 559 558 560 559 msm_gpu_retire(gpu); 560 + } 561 + 562 + static void fault_worker(struct kthread_work *work) 563 + { 564 + struct msm_gpu *gpu = container_of(work, struct msm_gpu, fault_work); 565 + struct drm_device *dev = gpu->dev; 566 + struct msm_gem_submit *submit; 567 + struct msm_ringbuffer *cur_ring = gpu->funcs->active_ring(gpu); 568 + char *comm = NULL, *cmd = NULL; 569 + 570 + mutex_lock(&dev->struct_mutex); 571 + 572 + submit = find_submit(cur_ring, cur_ring->memptrs->fence + 1); 573 + if (submit && submit->fault_dumped) 574 + goto resume_smmu; 575 + 576 + if (submit) { 577 + struct task_struct *task; 578 + 579 + task = get_pid_task(submit->pid, PIDTYPE_PID); 580 + if (task) { 581 + comm = kstrdup(task->comm, GFP_KERNEL); 582 + cmd = kstrdup_quotable_cmdline(task, GFP_KERNEL); 583 + put_task_struct(task); 584 + } 585 + 586 + /* 587 + * When we get GPU iova faults, we can get 1000s of them, 588 + * but we really only want to log the first one. 589 + */ 590 + submit->fault_dumped = true; 591 + } 592 + 593 + /* Record the crash state */ 594 + pm_runtime_get_sync(&gpu->pdev->dev); 595 + msm_gpu_crashstate_capture(gpu, submit, comm, cmd); 596 + pm_runtime_put_sync(&gpu->pdev->dev); 597 + 598 + kfree(cmd); 599 + kfree(comm); 600 + 601 + resume_smmu: 602 + memset(&gpu->fault_info, 0, sizeof(gpu->fault_info)); 603 + gpu->aspace->mmu->funcs->resume_translation(gpu->aspace->mmu); 604 + 605 + mutex_unlock(&dev->struct_mutex); 561 606 } 562 607 563 608 static void hangcheck_timer_reset(struct msm_gpu *gpu) ··· 970 923 INIT_LIST_HEAD(&gpu->active_list); 971 924 kthread_init_work(&gpu->retire_work, retire_worker); 972 925 kthread_init_work(&gpu->recover_work, recover_worker); 926 + kthread_init_work(&gpu->fault_work, fault_worker); 973 927 974 928 timer_setup(&gpu->hangcheck_timer, hangcheck_handler, 0); 975 929
+17
drivers/gpu/drm/msm/msm_gpu.h
··· 71 71 uint32_t (*get_rptr)(struct msm_gpu *gpu, struct msm_ringbuffer *ring); 72 72 }; 73 73 74 + /* Additional state for iommu faults: */ 75 + struct msm_gpu_fault_info { 76 + u64 ttbr0; 77 + unsigned long iova; 78 + int flags; 79 + const char *type; 80 + const char *block; 81 + }; 82 + 74 83 struct msm_gpu { 75 84 const char *name; 76 85 struct drm_device *dev; ··· 133 124 134 125 #define DRM_MSM_HANGCHECK_DEFAULT_PERIOD 500 /* in ms */ 135 126 struct timer_list hangcheck_timer; 127 + 128 + /* Fault info for most recent iova fault: */ 129 + struct msm_gpu_fault_info fault_info; 130 + 131 + /* work for handling GPU ioval faults: */ 132 + struct kthread_work fault_work; 136 133 137 134 /* work for handling GPU recovery: */ 138 135 struct kthread_work recover_work; ··· 246 231 247 232 char *comm; 248 233 char *cmd; 234 + 235 + struct msm_gpu_fault_info fault_info; 249 236 250 237 int nr_bos; 251 238 struct msm_gpu_state_bo *bos;
+5
drivers/gpu/drm/msm/msm_gpummu.c
··· 68 68 return 0; 69 69 } 70 70 71 + static void msm_gpummu_resume_translation(struct msm_mmu *mmu) 72 + { 73 + } 74 + 71 75 static void msm_gpummu_destroy(struct msm_mmu *mmu) 72 76 { 73 77 struct msm_gpummu *gpummu = to_msm_gpummu(mmu); ··· 87 83 .map = msm_gpummu_map, 88 84 .unmap = msm_gpummu_unmap, 89 85 .destroy = msm_gpummu_destroy, 86 + .resume_translation = msm_gpummu_resume_translation, 90 87 }; 91 88 92 89 struct msm_mmu *msm_gpummu_new(struct device *dev, struct msm_gpu *gpu)
+11
drivers/gpu/drm/msm/msm_iommu.c
··· 184 184 * the arm-smmu driver as a trigger to set up TTBR0 185 185 */ 186 186 if (atomic_inc_return(&iommu->pagetables) == 1) { 187 + /* Enable stall on iommu fault: */ 188 + adreno_smmu->set_stall(adreno_smmu->cookie, true); 189 + 187 190 ret = adreno_smmu->set_ttbr0_cfg(adreno_smmu->cookie, &ttbr0_cfg); 188 191 if (ret) { 189 192 free_io_pgtable_ops(pagetable->pgtbl_ops); ··· 227 224 228 225 pr_warn_ratelimited("*** fault: iova=%16lx, flags=%d\n", iova, flags); 229 226 return 0; 227 + } 228 + 229 + static void msm_iommu_resume_translation(struct msm_mmu *mmu) 230 + { 231 + struct adreno_smmu_priv *adreno_smmu = dev_get_drvdata(mmu->dev); 232 + 233 + adreno_smmu->resume_translation(adreno_smmu->cookie, true); 230 234 } 231 235 232 236 static void msm_iommu_detach(struct msm_mmu *mmu) ··· 283 273 .map = msm_iommu_map, 284 274 .unmap = msm_iommu_unmap, 285 275 .destroy = msm_iommu_destroy, 276 + .resume_translation = msm_iommu_resume_translation, 286 277 }; 287 278 288 279 struct msm_mmu *msm_iommu_new(struct device *dev, struct iommu_domain *domain)
+1
drivers/gpu/drm/msm/msm_mmu.h
··· 15 15 size_t len, int prot); 16 16 int (*unmap)(struct msm_mmu *mmu, uint64_t iova, size_t len); 17 17 void (*destroy)(struct msm_mmu *mmu); 18 + void (*resume_translation)(struct msm_mmu *mmu); 18 19 }; 19 20 20 21 enum msm_mmu_type {