summaryrefslogtreecommitdiff
path: root/drivers/iommu/msm_iommu_sec.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/iommu/msm_iommu_sec.c')
-rw-r--r--drivers/iommu/msm_iommu_sec.c23
1 files changed, 13 insertions, 10 deletions
diff --git a/drivers/iommu/msm_iommu_sec.c b/drivers/iommu/msm_iommu_sec.c
index 4657009d81f1..ed15c25f2e79 100644
--- a/drivers/iommu/msm_iommu_sec.c
+++ b/drivers/iommu/msm_iommu_sec.c
@@ -143,11 +143,9 @@ static int msm_iommu_dump_fault_regs(int smmu_id, int cb_num,
return ret;
}
-#define EXTRACT_DUMP_REG_KEY(addr, ctx) (addr & ((1 << CTX_SHIFT) - 1))
-
static int msm_iommu_reg_dump_to_regs(
struct msm_iommu_context_reg ctx_regs[],
- struct msm_scm_fault_regs_dump *dump, int cb_num)
+ struct msm_scm_fault_regs_dump *dump, struct msm_iommu_drvdata *drvdata)
{
int i, j, ret = 0;
const uint32_t nvals = (dump->dump_size / sizeof(uint32_t));
@@ -155,21 +153,27 @@ static int msm_iommu_reg_dump_to_regs(
const uint32_t * const end = ((uint32_t *) dump) + nvals;
for (i = 1; it < end; it += 2, i += 2) {
+ unsigned long reg_offset;
uint32_t addr = *it;
uint32_t val = *(it + 1);
struct msm_iommu_context_reg *reg = NULL;
+ if (drvdata->phys_base > addr) {
+ pr_err("Bogus-looking register (0x%x) for Iommu with base at %pa. Skipping.\n",
+ addr, &drvdata->phys_base);
+ continue;
+ }
+ reg_offset = addr - drvdata->phys_base;
for (j = 0; j < MAX_DUMP_REGS; ++j) {
- if (dump_regs_tbl[j].key ==
- EXTRACT_DUMP_REG_KEY(addr, cb_num)) {
+ if (dump_regs_tbl[j].reg_offset == reg_offset) {
reg = &ctx_regs[j];
break;
}
}
if (reg == NULL) {
- pr_debug("Unknown register in secure CB dump: %x (%x)\n",
- addr, EXTRACT_DUMP_REG_KEY(addr, cb_num));
+ pr_debug("Unknown register in secure CB dump: %x\n",
+ addr);
continue;
}
@@ -194,7 +198,7 @@ static int msm_iommu_reg_dump_to_regs(
if (dump_regs_tbl[i].must_be_present) {
pr_err("Register missing from dump: %s, %lx\n",
dump_regs_tbl[i].name,
- dump_regs_tbl[i].key);
+ dump_regs_tbl[i].reg_offset);
ret = 1;
}
ctx_regs[i].val = 0;
@@ -253,8 +257,7 @@ irqreturn_t msm_iommu_secure_fault_handler_v2(int irq, void *dev_id)
} else {
struct msm_iommu_context_reg ctx_regs[MAX_DUMP_REGS];
memset(ctx_regs, 0, sizeof(ctx_regs));
- tmp = msm_iommu_reg_dump_to_regs(ctx_regs, regs,
- ctx_drvdata->num);
+ tmp = msm_iommu_reg_dump_to_regs(ctx_regs, regs, drvdata);
if (!tmp && ctx_regs[DUMP_REG_FSR].val) {
if (!ctx_drvdata->attached_domain) {
pr_err("Bad domain in interrupt handler\n");