aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/iommu/arm-smmu.c
diff options
context:
space:
mode:
authorOlav Haugan <ohaugan@codeaurora.org>2014-08-22 20:12:32 -0400
committerWill Deacon <will.deacon@arm.com>2014-09-02 05:04:42 -0400
commit3c8766d0ca9618a406b0a1ecc29147820e93d984 (patch)
treecdfa0bbf78fcc231e758ea9cd0d097bb2468b107 /drivers/iommu/arm-smmu.c
parent43b412bedb782e27a8771b61870dd45a24975266 (diff)
iommu/arm-smmu: Do not access non-existing S2CR registers
The number of S2CR registers is not properly set when stream matching is not supported. Fix this and add check that we do not try to access outside of the number of S2CR regisrers. Signed-off-by: Olav Haugan <ohaugan@codeaurora.org> [will: added missing NUMSIDB_* definitions] Signed-off-by: Will Deacon <will.deacon@arm.com>
Diffstat (limited to 'drivers/iommu/arm-smmu.c')
-rw-r--r--drivers/iommu/arm-smmu.c28
1 files changed, 21 insertions, 7 deletions
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index b7cd5d07d6fb..ba9d7e52ed1a 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -146,6 +146,8 @@
146#define ID0_CTTW (1 << 14) 146#define ID0_CTTW (1 << 14)
147#define ID0_NUMIRPT_SHIFT 16 147#define ID0_NUMIRPT_SHIFT 16
148#define ID0_NUMIRPT_MASK 0xff 148#define ID0_NUMIRPT_MASK 0xff
149#define ID0_NUMSIDB_SHIFT 9
150#define ID0_NUMSIDB_MASK 0xf
149#define ID0_NUMSMRG_SHIFT 0 151#define ID0_NUMSMRG_SHIFT 0
150#define ID0_NUMSMRG_MASK 0xff 152#define ID0_NUMSMRG_MASK 0xff
151 153
@@ -524,9 +526,18 @@ static int register_smmu_master(struct arm_smmu_device *smmu,
524 master->of_node = masterspec->np; 526 master->of_node = masterspec->np;
525 master->cfg.num_streamids = masterspec->args_count; 527 master->cfg.num_streamids = masterspec->args_count;
526 528
527 for (i = 0; i < master->cfg.num_streamids; ++i) 529 for (i = 0; i < master->cfg.num_streamids; ++i) {
528 master->cfg.streamids[i] = masterspec->args[i]; 530 u16 streamid = masterspec->args[i];
529 531
532 if (!(smmu->features & ARM_SMMU_FEAT_STREAM_MATCH) &&
533 (streamid >= smmu->num_mapping_groups)) {
534 dev_err(dev,
535 "stream ID for master device %s greater than maximum allowed (%d)\n",
536 masterspec->np->name, smmu->num_mapping_groups);
537 return -ERANGE;
538 }
539 master->cfg.streamids[i] = streamid;
540 }
530 return insert_smmu_master(smmu, master); 541 return insert_smmu_master(smmu, master);
531} 542}
532 543
@@ -1624,7 +1635,7 @@ static void arm_smmu_device_reset(struct arm_smmu_device *smmu)
1624 1635
1625 /* Mark all SMRn as invalid and all S2CRn as bypass */ 1636 /* Mark all SMRn as invalid and all S2CRn as bypass */
1626 for (i = 0; i < smmu->num_mapping_groups; ++i) { 1637 for (i = 0; i < smmu->num_mapping_groups; ++i) {
1627 writel_relaxed(~SMR_VALID, gr0_base + ARM_SMMU_GR0_SMR(i)); 1638 writel_relaxed(0, gr0_base + ARM_SMMU_GR0_SMR(i));
1628 writel_relaxed(S2CR_TYPE_BYPASS, 1639 writel_relaxed(S2CR_TYPE_BYPASS,
1629 gr0_base + ARM_SMMU_GR0_S2CR(i)); 1640 gr0_base + ARM_SMMU_GR0_S2CR(i));
1630 } 1641 }
@@ -1759,6 +1770,9 @@ static int arm_smmu_device_cfg_probe(struct arm_smmu_device *smmu)
1759 dev_notice(smmu->dev, 1770 dev_notice(smmu->dev,
1760 "\tstream matching with %u register groups, mask 0x%x", 1771 "\tstream matching with %u register groups, mask 0x%x",
1761 smmu->num_mapping_groups, mask); 1772 smmu->num_mapping_groups, mask);
1773 } else {
1774 smmu->num_mapping_groups = (id >> ID0_NUMSIDB_SHIFT) &
1775 ID0_NUMSIDB_MASK;
1762 } 1776 }
1763 1777
1764 /* ID1 */ 1778 /* ID1 */
@@ -1887,6 +1901,10 @@ static int arm_smmu_device_dt_probe(struct platform_device *pdev)
1887 smmu->irqs[i] = irq; 1901 smmu->irqs[i] = irq;
1888 } 1902 }
1889 1903
1904 err = arm_smmu_device_cfg_probe(smmu);
1905 if (err)
1906 return err;
1907
1890 i = 0; 1908 i = 0;
1891 smmu->masters = RB_ROOT; 1909 smmu->masters = RB_ROOT;
1892 while (!of_parse_phandle_with_args(dev->of_node, "mmu-masters", 1910 while (!of_parse_phandle_with_args(dev->of_node, "mmu-masters",
@@ -1903,10 +1921,6 @@ static int arm_smmu_device_dt_probe(struct platform_device *pdev)
1903 } 1921 }
1904 dev_notice(dev, "registered %d master devices\n", i); 1922 dev_notice(dev, "registered %d master devices\n", i);
1905 1923
1906 err = arm_smmu_device_cfg_probe(smmu);
1907 if (err)
1908 goto out_put_masters;
1909
1910 parse_driver_options(smmu); 1924 parse_driver_options(smmu);
1911 1925
1912 if (smmu->version > 1 && 1926 if (smmu->version > 1 &&