aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Herrmann <andreas.herrmann@calxeda.com>2013-10-01 08:39:07 -0400
committerWill Deacon <will.deacon@arm.com>2013-10-09 09:14:40 -0400
commit44a08de2aaf7f4cf86dfcf04bee32536e4a2b5b8 (patch)
treefc1702688b2a1858d18ae2db0bab740030fa9ea6
parentc55af7f719cbb0f0b28f42b3f98f662278f063c2 (diff)
iommu/arm-smmu: Check for num_context_irqs > 0 to avoid divide by zero exception
With the right (or wrong;-) definition of v1 SMMU node in DTB it is possible to trigger a division by zero in arm_smmu_init_domain_context (if number of context irqs is 0): if (smmu->version == 1) { root_cfg->irptndx = atomic_inc_return(&smmu->irptndx); => root_cfg->irptndx %= smmu->num_context_irqs; } else { Avoid this by checking for num_context_irqs > 0 when probing for SMMU devices. Signed-off-by: Andreas Herrmann <andreas.herrmann@calxeda.com> [will: changed to dev_err on probe failure path] Signed-off-by: Will Deacon <will.deacon@arm.com>
-rw-r--r--drivers/iommu/arm-smmu.c9
1 files changed, 4 insertions, 5 deletions
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 1f79daa5f4b1..e4693cee5f2c 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -1798,12 +1798,11 @@ static int arm_smmu_device_dt_probe(struct platform_device *pdev)
1798 smmu->num_context_irqs++; 1798 smmu->num_context_irqs++;
1799 } 1799 }
1800 1800
1801 if (num_irqs < smmu->num_global_irqs) { 1801 if (!smmu->num_context_irqs) {
1802 dev_warn(dev, "found %d interrupts but expected at least %d\n", 1802 dev_err(dev, "found %d interrupts but expected at least %d\n",
1803 num_irqs, smmu->num_global_irqs); 1803 num_irqs, smmu->num_global_irqs + 1);
1804 smmu->num_global_irqs = num_irqs; 1804 return -ENODEV;
1805 } 1805 }
1806 smmu->num_context_irqs = num_irqs - smmu->num_global_irqs;
1807 1806
1808 smmu->irqs = devm_kzalloc(dev, sizeof(*smmu->irqs) * num_irqs, 1807 smmu->irqs = devm_kzalloc(dev, sizeof(*smmu->irqs) * num_irqs,
1809 GFP_KERNEL); 1808 GFP_KERNEL);