| From 2606db2c3131278ddf9747b4c0c897a5a8994e41 Mon Sep 17 00:00:00 2001 |
| From: Rob Clark <robdclark@chromium.org> |
| Date: Tue, 5 Oct 2021 08:16:27 -0700 |
| Subject: [PATCH] FROMLIST: drm/msm: Extend gpu devcore dumps with pgtbl info |
| |
| In the case of iova fault triggered devcore dumps, include additional |
| debug information based on what we think is the current page tables, |
| including the TTBR0 value (which should match what we have in |
| adreno_smmu_fault_info unless things have gone horribly wrong), and |
| the pagetable entries traversed in the process of resolving the |
| faulting iova. |
| |
| Signed-off-by: Rob Clark <robdclark@chromium.org> |
| (am from https://patchwork.freedesktop.org/patch/457542/) |
| (also found at https://lore.kernel.org/r/20211005151633.1738878-4-robdclark@gmail.com) |
| |
| BUG=b:201293781 |
| TEST=boot coachz |
| |
| Change-Id: I7d466dc9fa767109b44cadef334be8da5b8177ca |
| Disallow-Recycled-Builds: test-failures |
| Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/3252320 |
| Reviewed-by: Sean Paul <seanpaul@chromium.org> |
| Reviewed-by: Kristian H. Kristensen <hoegsberg@chromium.org> |
| Tested-by: Rob Clark <robdclark@chromium.org> |
| Auto-Submit: Rob Clark <robdclark@chromium.org> |
| Commit-Queue: Kristian H. Kristensen <hoegsberg@chromium.org> |
| --- |
| drivers/gpu/drm/msm/adreno/adreno_gpu.c | 10 ++++++++++ |
| drivers/gpu/drm/msm/msm_gpu.c | 10 ++++++++++ |
| drivers/gpu/drm/msm/msm_gpu.h | 8 ++++++++ |
| drivers/gpu/drm/msm/msm_iommu.c | 17 +++++++++++++++++ |
| drivers/gpu/drm/msm/msm_mmu.h | 3 +++ |
| 5 files changed, 48 insertions(+) |
| |
| diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c |
| index afe30998ca044ce374bc8d4de7dc5667a47a2c82..24d2e32b9f62b9e073b981af6998d904914740fb 100644 |
| --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c |
| +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c |
| @@ -813,6 +813,16 @@ void adreno_show(struct msm_gpu *gpu, struct msm_gpu_state *state, |
| drm_printf(p, " - dir: %s\n", info->flags & IOMMU_FAULT_WRITE ? "WRITE" : "READ"); |
| drm_printf(p, " - type: %s\n", info->type); |
| drm_printf(p, " - source: %s\n", info->block); |
| + |
| + /* Information extracted from what we think are the current |
| + * pgtables. Hopefully the TTBR0 matches what we've extracted |
| + * from the SMMU registers in smmu_info! |
| + */ |
| + drm_puts(p, "pgtable-fault-info:\n"); |
| + drm_printf(p, " - ttbr0: %.16llx\n", (u64)info->pgtbl_ttbr0); |
| + drm_printf(p, " - asid: %d\n", info->asid); |
| + drm_printf(p, " - ptes: %.16llx %.16llx %.16llx %.16llx\n", |
| + info->ptes[0], info->ptes[1], info->ptes[2], info->ptes[3]); |
| } |
| |
| drm_printf(p, "rbbm-status: 0x%08x\n", state->rbbm_status); |
| diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c |
| index 30ed45af76ade1de740a1f3bfcc7f00bd09b619e..93590ebd6bd27e292be9dd18c1709dac4dc0cda1 100644 |
| --- a/drivers/gpu/drm/msm/msm_gpu.c |
| +++ b/drivers/gpu/drm/msm/msm_gpu.c |
| @@ -282,6 +282,16 @@ static void msm_gpu_crashstate_capture(struct msm_gpu *gpu, |
| if (submit) { |
| int i; |
| |
| + if (state->fault_info.smmu_info.ttbr0) { |
| + struct msm_gpu_fault_info *info = &state->fault_info; |
| + struct msm_mmu *mmu = submit->aspace->mmu; |
| + |
| + msm_iommu_pagetable_params(mmu, &info->pgtbl_ttbr0, |
| + &info->asid); |
| + msm_iommu_pagetable_walk(mmu, info->iova, info->ptes, |
| + ARRAY_SIZE(info->ptes)); |
| + } |
| + |
| state->bos = kcalloc(submit->nr_bos, |
| sizeof(struct msm_gpu_state_bo), GFP_KERNEL); |
| |
| diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h |
| index 112ac4dd18071a9c4093cfb972a90a6d947fd6fa..59f7d1b70ace3fb30b06985623bffa6e7d207e47 100644 |
| --- a/drivers/gpu/drm/msm/msm_gpu.h |
| +++ b/drivers/gpu/drm/msm/msm_gpu.h |
| @@ -96,6 +96,14 @@ struct msm_gpu_fault_info { |
| int flags; |
| const char *type; |
| const char *block; |
| + |
| + /* Information about what we think/expect is the current SMMU state, |
| + * for example expected_ttbr0 should match smmu_info.ttbr0 which |
| + * was read back from SMMU registers. |
| + */ |
| + phys_addr_t pgtbl_ttbr0; |
| + u64 ptes[4]; |
| + int asid; |
| }; |
| |
| /** |
| diff --git a/drivers/gpu/drm/msm/msm_iommu.c b/drivers/gpu/drm/msm/msm_iommu.c |
| index c2507582ecf3465d471796aa0e494b867a179816..4a7ef4436a5b190c4ebebfd2b8be20553cde6611 100644 |
| --- a/drivers/gpu/drm/msm/msm_iommu.c |
| +++ b/drivers/gpu/drm/msm/msm_iommu.c |
| @@ -193,6 +193,23 @@ struct iommu_domain_geometry *msm_iommu_get_geometry(struct msm_mmu *mmu) |
| return &iommu->domain->geometry; |
| } |
| |
| +int msm_iommu_pagetable_walk(struct msm_mmu *mmu, unsigned long iova, |
| + u64 *ptes, int num_ptes) |
| +{ |
| + struct msm_iommu_pagetable *pagetable; |
| + |
| + if (mmu->type != MSM_MMU_IOMMU_PAGETABLE) |
| + return -EINVAL; |
| + |
| + pagetable = to_pagetable(mmu); |
| + |
| + if (!pagetable->pgtbl_ops->pgtable_walk) |
| + return -EINVAL; |
| + |
| + return pagetable->pgtbl_ops->pgtable_walk(pagetable->pgtbl_ops, iova, |
| + ptes, &num_ptes); |
| +} |
| + |
| static const struct msm_mmu_funcs pagetable_funcs = { |
| .map = msm_iommu_pagetable_map, |
| .unmap = msm_iommu_pagetable_unmap, |
| diff --git a/drivers/gpu/drm/msm/msm_mmu.h b/drivers/gpu/drm/msm/msm_mmu.h |
| index 74cd81e701ffdb6011f4cf2a56b36037849ca561..1986a422f119f9fbb94fff0bd14fdb07198ec6d9 100644 |
| --- a/drivers/gpu/drm/msm/msm_mmu.h |
| +++ b/drivers/gpu/drm/msm/msm_mmu.h |
| @@ -60,4 +60,7 @@ int msm_iommu_pagetable_params(struct msm_mmu *mmu, phys_addr_t *ttbr, |
| int *asid); |
| struct iommu_domain_geometry *msm_iommu_get_geometry(struct msm_mmu *mmu); |
| |
| +int msm_iommu_pagetable_walk(struct msm_mmu *mmu, unsigned long iova, |
| + u64 *ptes, int num_ptes); |
| + |
| #endif /* __MSM_MMU_H__ */ |
| -- |
| 2.39.0.314.g84b9a713c41-goog |
| |