aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/iommu/arm-smmu.c
diff options
context:
space:
mode:
authorRobin Murphy <robin.murphy@arm.com>2016-02-10 09:25:33 -0500
committerWill Deacon <will.deacon@arm.com>2016-02-18 10:02:44 -0500
commit25a1c96cd22c949b50d6f0269c23e1c5cb55e5a5 (patch)
tree95a556472ac169eb8e314f7394ffac56a6ea73d8 /drivers/iommu/arm-smmu.c
parent45bb966d3dc7c6d4f0bd7673b5fe51deebcaf70b (diff)
iommu/arm-smmu: Allow disabling unmatched stream bypass
Borrow the disable_bypass parameter from the SMMUv3 driver as a handy debugging/security feature so that unmatched stream IDs (i.e. devices not attached to an IOMMU domain) may be configured to fault. Rather than introduce unsightly inconsistency, or repeat the existing unnecessary use of module_param_named(), fix that as well in passing. Signed-off-by: Robin Murphy <robin.murphy@arm.com> Signed-off-by: Will Deacon <will.deacon@arm.com>
Diffstat (limited to 'drivers/iommu/arm-smmu.c')
-rw-r--r--drivers/iommu/arm-smmu.c24
1 files changed, 16 insertions, 8 deletions
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index e8e7bcc4540c..7012531abe62 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -261,9 +261,13 @@
261#define FSYNR0_WNR (1 << 4) 261#define FSYNR0_WNR (1 << 4)
262 262
263static int force_stage; 263static int force_stage;
264module_param_named(force_stage, force_stage, int, S_IRUGO); 264module_param(force_stage, int, S_IRUGO);
265MODULE_PARM_DESC(force_stage, 265MODULE_PARM_DESC(force_stage,
266 "Force SMMU mappings to be installed at a particular stage of translation. A value of '1' or '2' forces the corresponding stage. All other values are ignored (i.e. no stage is forced). Note that selecting a specific stage will disable support for nested translation."); 266 "Force SMMU mappings to be installed at a particular stage of translation. A value of '1' or '2' forces the corresponding stage. All other values are ignored (i.e. no stage is forced). Note that selecting a specific stage will disable support for nested translation.");
267static bool disable_bypass;
268module_param(disable_bypass, bool, S_IRUGO);
269MODULE_PARM_DESC(disable_bypass,
270 "Disable bypass streams such that incoming transactions from devices that are not attached to an iommu domain will report an abort back to the device and will not be allowed to pass through the SMMU.");
267 271
268enum arm_smmu_arch_version { 272enum arm_smmu_arch_version {
269 ARM_SMMU_V1 = 1, 273 ARM_SMMU_V1 = 1,
@@ -1119,9 +1123,9 @@ static void arm_smmu_domain_remove_master(struct arm_smmu_domain *smmu_domain,
1119 */ 1123 */
1120 for (i = 0; i < cfg->num_streamids; ++i) { 1124 for (i = 0; i < cfg->num_streamids; ++i) {
1121 u32 idx = cfg->smrs ? cfg->smrs[i].idx : cfg->streamids[i]; 1125 u32 idx = cfg->smrs ? cfg->smrs[i].idx : cfg->streamids[i];
1126 u32 reg = disable_bypass ? S2CR_TYPE_FAULT : S2CR_TYPE_BYPASS;
1122 1127
1123 writel_relaxed(S2CR_TYPE_BYPASS, 1128 writel_relaxed(reg, gr0_base + ARM_SMMU_GR0_S2CR(idx));
1124 gr0_base + ARM_SMMU_GR0_S2CR(idx));
1125 } 1129 }
1126 1130
1127 arm_smmu_master_free_smrs(smmu, cfg); 1131 arm_smmu_master_free_smrs(smmu, cfg);
@@ -1484,11 +1488,11 @@ static void arm_smmu_device_reset(struct arm_smmu_device *smmu)
1484 reg = readl_relaxed(ARM_SMMU_GR0_NS(smmu) + ARM_SMMU_GR0_sGFSR); 1488 reg = readl_relaxed(ARM_SMMU_GR0_NS(smmu) + ARM_SMMU_GR0_sGFSR);
1485 writel(reg, ARM_SMMU_GR0_NS(smmu) + ARM_SMMU_GR0_sGFSR); 1489 writel(reg, ARM_SMMU_GR0_NS(smmu) + ARM_SMMU_GR0_sGFSR);
1486 1490
1487 /* Mark all SMRn as invalid and all S2CRn as bypass */ 1491 /* Mark all SMRn as invalid and all S2CRn as bypass unless overridden */
1492 reg = disable_bypass ? S2CR_TYPE_FAULT : S2CR_TYPE_BYPASS;
1488 for (i = 0; i < smmu->num_mapping_groups; ++i) { 1493 for (i = 0; i < smmu->num_mapping_groups; ++i) {
1489 writel_relaxed(0, gr0_base + ARM_SMMU_GR0_SMR(i)); 1494 writel_relaxed(0, gr0_base + ARM_SMMU_GR0_SMR(i));
1490 writel_relaxed(S2CR_TYPE_BYPASS, 1495 writel_relaxed(reg, gr0_base + ARM_SMMU_GR0_S2CR(i));
1491 gr0_base + ARM_SMMU_GR0_S2CR(i));
1492 } 1496 }
1493 1497
1494 /* Make sure all context banks are disabled and clear CB_FSR */ 1498 /* Make sure all context banks are disabled and clear CB_FSR */
@@ -1510,8 +1514,12 @@ static void arm_smmu_device_reset(struct arm_smmu_device *smmu)
1510 /* Disable TLB broadcasting. */ 1514 /* Disable TLB broadcasting. */
1511 reg |= (sCR0_VMIDPNE | sCR0_PTM); 1515 reg |= (sCR0_VMIDPNE | sCR0_PTM);
1512 1516
1513 /* Enable client access, but bypass when no mapping is found */ 1517 /* Enable client access, handling unmatched streams as appropriate */
1514 reg &= ~(sCR0_CLIENTPD | sCR0_USFCFG); 1518 reg &= ~sCR0_CLIENTPD;
1519 if (disable_bypass)
1520 reg |= sCR0_USFCFG;
1521 else
1522 reg &= ~sCR0_USFCFG;
1515 1523
1516 /* Disable forced broadcasting */ 1524 /* Disable forced broadcasting */
1517 reg &= ~sCR0_FB; 1525 reg &= ~sCR0_FB;