diff options
author | Andreas Herrmann <andreas.herrmann@calxeda.com> | 2013-10-01 08:39:07 -0400 |
---|---|---|
committer | Will Deacon <will.deacon@arm.com> | 2013-10-09 09:14:40 -0400 |
commit | 44a08de2aaf7f4cf86dfcf04bee32536e4a2b5b8 (patch) | |
tree | fc1702688b2a1858d18ae2db0bab740030fa9ea6 | |
parent | c55af7f719cbb0f0b28f42b3f98f662278f063c2 (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.c | 9 |
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); |