summaryrefslogtreecommitdiff
path: root/drivers/iommu
diff options
context:
space:
mode:
authorChintan Pandya <cpandya@codeaurora.org>2014-04-05 00:54:52 +0530
committerChintan Pandya <cpandya@codeaurora.org>2014-04-21 16:49:46 +0530
commit0be30916e61c6c22a23cc73e7d02b6f97009d52f (patch)
treec428f073aad8420708d2994f3390d97359bfd77b /drivers/iommu
parent052f216126c911852836193152befd11727c62ad (diff)
iommu: msm: Verify page table corruption when page fault happens
Page faults often leads to doubt of either page table corruption in DDR or the malfunctioning of the IOMMU. To rule out that, we can walk through the page tables and get actual translation with the faulty VA. If physical address from the page table is expected, we can doubt IOMMU malfunctioning, or otherwise, page table corruption. Change-Id: Icef69e7a50ce3110fc83ca75b4a984057336b5bb Signed-off-by: Chintan Pandya <cpandya@codeaurora.org>
Diffstat (limited to 'drivers/iommu')
-rw-r--r--drivers/iommu/msm_iommu-v1.c18
1 files changed, 16 insertions, 2 deletions
diff --git a/drivers/iommu/msm_iommu-v1.c b/drivers/iommu/msm_iommu-v1.c
index 9691770ee38d..3ff30e5c3aeb 100644
--- a/drivers/iommu/msm_iommu-v1.c
+++ b/drivers/iommu/msm_iommu-v1.c
@@ -1299,6 +1299,9 @@ irqreturn_t msm_iommu_fault_handler_v2(int irq, void *dev_id)
unsigned int fsr;
int ret;
+ phys_addr_t pagetable_phys;
+ u64 faulty_iova = 0;
+
mutex_lock(&msm_iommu_lock);
BUG_ON(!pdev);
@@ -1333,11 +1336,14 @@ irqreturn_t msm_iommu_fault_handler_v2(int irq, void *dev_id)
if (!ctx_drvdata->attached_domain) {
pr_err("Bad domain in interrupt handler\n");
ret = -ENOSYS;
- } else
+ } else {
+ faulty_iova =
+ GET_FAR(drvdata->cb_base, ctx_drvdata->num);
ret = report_iommu_fault(ctx_drvdata->attached_domain,
&ctx_drvdata->pdev->dev,
- GET_FAR(drvdata->cb_base, ctx_drvdata->num), 0);
+ faulty_iova, 0);
+ }
if (ret == -ENOSYS) {
pr_err("Unexpected IOMMU page fault!\n");
pr_err("name = %s\n", drvdata->name);
@@ -1346,6 +1352,14 @@ irqreturn_t msm_iommu_fault_handler_v2(int irq, void *dev_id)
pr_err("Interesting registers:\n");
__print_ctx_regs(drvdata->cb_base,
ctx_drvdata->num, fsr);
+
+ if (ctx_drvdata->attached_domain) {
+ pagetable_phys = msm_iommu_iova_to_phys_soft(
+ ctx_drvdata->attached_domain,
+ faulty_iova);
+ pr_err("Page table in DDR shows PA = %x\n",
+ (unsigned int) pagetable_phys);
+ }
}
if (ret != -EBUSY)