iommu: arm-smmu: Add DOMAIN_ATTR_NO_CFRE

Some bus implementations may enter a bad state if iommu reports an error
on context fault. As context faults are not always fatal, this must be
avoided.

Change-Id: I60d1ccb7cad64dfc9e327967c903befd3fa72877
Signed-off-by: Patrick Daly <pdaly@codeaurora.org>
Signed-off-by: Srinivasarao P <spathi@codeaurora.org>
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index de05de4..004460d 100755
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -1790,6 +1790,8 @@
 		reg &= ~SCTLR_CFCFG;
 		reg |= SCTLR_HUPCF;
 	}
+	if (cb->attributes & (1 << DOMAIN_ATTR_NO_CFRE))
+		reg &= ~SCTLR_CFRE;
 
 	if ((!(cb->attributes & (1 << DOMAIN_ATTR_S1_BYPASS)) &&
 	     !(cb->attributes & (1 << DOMAIN_ATTR_EARLY_MAP))) ||
@@ -3316,6 +3318,11 @@
 			& (1 << DOMAIN_ATTR_CB_STALL_DISABLE));
 		ret = 0;
 		break;
+	case DOMAIN_ATTR_NO_CFRE:
+		*((int *)data) = !!(smmu_domain->attributes
+			& (1 << DOMAIN_ATTR_NO_CFRE));
+		ret = 0;
+		break;
 	case DOMAIN_ATTR_MMU500_ERRATA_MIN_ALIGN:
 		*((int *)data) = smmu_domain->qsmmuv500_errata2_min_align;
 		ret = 0;
@@ -3550,6 +3557,12 @@
 		break;
 	}
 
+	case DOMAIN_ATTR_NO_CFRE:
+		if (*((int *)data))
+			smmu_domain->attributes |=
+				1 << DOMAIN_ATTR_NO_CFRE;
+		ret = 0;
+		break;
 	default:
 		ret = -ENODEV;
 	}
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index acbc605..6785d2e 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -119,6 +119,11 @@
  * DOMAIN_ATTR_FSL_PAMUV1 corresponds to the above mentioned contraints.
  * The caller can invoke iommu_domain_get_attr to check if the underlying
  * iommu implementation supports these constraints.
+ *
+ * DOMAIN_ATTR_NO_CFRE
+ * Some bus implementations may enter a bad state if iommu reports an error
+ * on context fault. As context faults are not always fatal, this must be
+ * avoided.
  */
 
 enum iommu_attr {
@@ -149,6 +154,7 @@
 	DOMAIN_ATTR_UPSTREAM_IOVA_ALLOCATOR,
 	DOMAIN_ATTR_MMU500_ERRATA_MIN_ALIGN,
 	DOMAIN_ATTR_FORCE_IOVA_GUARD_PAGE,
+	DOMAIN_ATTR_NO_CFRE,
 	DOMAIN_ATTR_MAX,
 };