diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index b2c53de88b03..9552e5b6a3d1 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c @@ -1453,7 +1453,9 @@ static void arm_smmu_init_context_bank(struct arm_smmu_domain *smmu_domain, } /* SCTLR */ - reg = SCTLR_CFCFG | SCTLR_CFIE | SCTLR_CFRE | SCTLR_M | SCTLR_EAE_SBOP; + reg = SCTLR_CFCFG | SCTLR_CFIE | SCTLR_CFRE | SCTLR_EAE_SBOP; + if (!stage1 || !(smmu_domain->attributes & DOMAIN_ATTR_S1_BYPASS)) + reg |= SCTLR_M; if (stage1) reg |= SCTLR_S1_ASIDPNE; #ifdef __BIG_ENDIAN @@ -2898,6 +2900,11 @@ static int arm_smmu_domain_get_attr(struct iommu_domain *domain, & (1 << DOMAIN_ATTR_NON_FATAL_FAULTS)); ret = 0; break; + case DOMAIN_ATTR_S1_BYPASS: + *((int *)data) = !!(smmu_domain->attributes + & (1 << DOMAIN_ATTR_S1_BYPASS)); + ret = 0; + break; default: ret = -ENODEV; break; @@ -3009,6 +3016,18 @@ static int arm_smmu_domain_set_attr(struct iommu_domain *domain, smmu_domain->non_fatal_faults = *((int *)data); ret = 0; break; + case DOMAIN_ATTR_S1_BYPASS: { + int bypass = *((int *)data); + + if (bypass) + smmu_domain->attributes |= 1 << DOMAIN_ATTR_S1_BYPASS; + else + smmu_domain->attributes &= + ~(1 << DOMAIN_ATTR_S1_BYPASS); + + ret = 0; + break; + } default: ret = -ENODEV; break;