blob: 6e5dfad30b06f4ce1869382958d6687e686407ab [file] [log] [blame]
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