diff options
author | Bjorn Andersson <bjorn.andersson@linaro.org> | 2019-05-10 20:11:50 -0700 |
---|---|---|
committer | Bjorn Andersson <bjorn.andersson@linaro.org> | 2019-05-30 09:40:33 -0700 |
commit | f29fc8e41ca60ec7006f91ad597dd479eb5c6468 (patch) | |
tree | 07294253056b39e9a38b7f96e7e7a4813bf9b747 | |
parent | 8e0efaf57b2537251d05110f38b3a07d0dba1eb5 (diff) |
iommu: arm-smmu: Don't blindly use first SMR to calculate mask
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
-rw-r--r-- | drivers/iommu/arm-smmu.c | 20 |
1 files changed, 16 insertions, 4 deletions
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index 88d757c8cf4e..3f3a2b47670a 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c @@ -1211,23 +1211,35 @@ static void arm_smmu_test_smr_masks(struct arm_smmu_device *smmu) { void __iomem *gr0_base = ARM_SMMU_GR0(smmu); u32 smr; + int idx; if (!smmu->smrs) return; + for (idx = 0; idx < smmu->num_mapping_groups; idx++) { + smr = readl_relaxed(gr0_base + ARM_SMMU_GR0_SMR(idx)); + if (!(smr & SMR_VALID)) + break; + } + + if (idx == smmu->num_mapping_groups) { + dev_err(smmu->dev, "Unable to compute streamid_mask\n"); + return; + } + /* * SMR.ID bits may not be preserved if the corresponding MASK * bits are set, so check each one separately. We can reject * masters later if they try to claim IDs outside these masks. */ smr = smmu->streamid_mask << SMR_ID_SHIFT; - writel_relaxed(smr, gr0_base + ARM_SMMU_GR0_SMR(0)); - smr = readl_relaxed(gr0_base + ARM_SMMU_GR0_SMR(0)); + writel_relaxed(smr, gr0_base + ARM_SMMU_GR0_SMR(idx)); + smr = readl_relaxed(gr0_base + ARM_SMMU_GR0_SMR(idx)); smmu->streamid_mask = smr >> SMR_ID_SHIFT; smr = smmu->streamid_mask << SMR_MASK_SHIFT; - writel_relaxed(smr, gr0_base + ARM_SMMU_GR0_SMR(0)); - smr = readl_relaxed(gr0_base + ARM_SMMU_GR0_SMR(0)); + writel_relaxed(smr, gr0_base + ARM_SMMU_GR0_SMR(idx)); + smr = readl_relaxed(gr0_base + ARM_SMMU_GR0_SMR(idx)); smmu->smr_mask_mask = smr >> SMR_MASK_SHIFT; } |