summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMitchel Humpherys <mitchelh@codeaurora.org>2015-09-25 17:29:27 -0700
committerDavid Keitel <dkeitel@codeaurora.org>2016-03-22 11:14:26 -0700
commit8387b734ea3dca2166db165f5ff5ab7ad0adf42e (patch)
tree6599b16e9c56df055b5c2b3f22f263213a662303
parent5ee33ef836b9ed469833bdf55c4a08d62b6bb39c (diff)
iommu/arm-smmu: Implement DOMAIN_ATTR_NON_FATAL_FAULTS
Unhandled context faults should be fatal unless explicitly requested otherwise by the client. Implement the DOMAIN_ATTR_NON_FATAL_FAULTS attribute for this purpose. Change-Id: I414fcc6000a6c47b3cbf77b1098c8b7895cbb20d Signed-off-by: Mitchel Humpherys <mitchelh@codeaurora.org>
-rw-r--r--drivers/iommu/arm-smmu.c16
1 files changed, 16 insertions, 0 deletions
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index eb84f2fdbf8a..2337ad9900e1 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -449,6 +449,7 @@ struct arm_smmu_domain {
struct list_head unassign_list;
struct mutex assign_lock;
struct list_head secure_pool_list;
+ bool non_fatal_faults;
};
static struct iommu_ops arm_smmu_ops;
@@ -1162,6 +1163,7 @@ static irqreturn_t arm_smmu_context_fault(int irq, void *dev)
void __iomem *gr1_base;
phys_addr_t phys_soft;
u32 frsynra;
+ bool non_fatal_fault = smmu_domain->non_fatal_faults;
static DEFINE_RATELIMIT_STATE(_rs,
DEFAULT_RATELIMIT_INTERVAL,
@@ -1256,6 +1258,11 @@ static irqreturn_t arm_smmu_context_fault(int irq, void *dev)
}
ret = IRQ_NONE;
resume = RESUME_TERMINATE;
+ if (!non_fatal_fault) {
+ dev_err(smmu->dev,
+ "Unhandled context faults are fatal on this domain. Going down now...\n");
+ BUG();
+ }
}
/*
@@ -2667,6 +2674,11 @@ static int arm_smmu_domain_get_attr(struct iommu_domain *domain,
& (1 << DOMAIN_ATTR_DYNAMIC));
ret = 0;
break;
+ case DOMAIN_ATTR_NON_FATAL_FAULTS:
+ *((int *)data) = !!(smmu_domain->attributes
+ & (1 << DOMAIN_ATTR_NON_FATAL_FAULTS));
+ ret = 0;
+ break;
default:
ret = -ENODEV;
break;
@@ -2774,6 +2786,10 @@ static int arm_smmu_domain_set_attr(struct iommu_domain *domain,
smmu_domain->cfg.cbndx = *((unsigned int *)data);
ret = 0;
break;
+ case DOMAIN_ATTR_NON_FATAL_FAULTS:
+ smmu_domain->non_fatal_faults = *((int *)data);
+ ret = 0;
+ break;
default:
ret = -ENODEV;
break;