aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoerg Roedel <joro@8bytes.org>2014-02-20 06:19:08 -0500
committerJoerg Roedel <joro@8bytes.org>2014-02-20 07:04:47 -0500
commit972157cac528f6cfd1f7e640139287951066106e (patch)
treed9515e0f258045d451ffd627057672070b887781
parent15eeb2e925c091b999195d0102ac39a271dbcb7e (diff)
arm/smmu: Use irqsafe spinlock for domain lock
As the lock might be used through DMA-API which is allowed in interrupt context. Signed-off-by: Joerg Roedel <joro@8bytes.org> Acked-by: Will Deacon <will.deacon@arm.com>
-rw-r--r--drivers/iommu/arm-smmu.c12
1 files changed, 7 insertions, 5 deletions
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 6fe7922ecc1d..1d9ab39af29f 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -1159,6 +1159,7 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
1159 struct arm_smmu_domain *smmu_domain = domain->priv; 1159 struct arm_smmu_domain *smmu_domain = domain->priv;
1160 struct arm_smmu_device *device_smmu = dev->archdata.iommu; 1160 struct arm_smmu_device *device_smmu = dev->archdata.iommu;
1161 struct arm_smmu_master *master; 1161 struct arm_smmu_master *master;
1162 unsigned long flags;
1162 1163
1163 if (!device_smmu) { 1164 if (!device_smmu) {
1164 dev_err(dev, "cannot attach to SMMU, is it on the same bus?\n"); 1165 dev_err(dev, "cannot attach to SMMU, is it on the same bus?\n");
@@ -1169,7 +1170,7 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
1169 * Sanity check the domain. We don't currently support domains 1170 * Sanity check the domain. We don't currently support domains
1170 * that cross between different SMMU chains. 1171 * that cross between different SMMU chains.
1171 */ 1172 */
1172 spin_lock(&smmu_domain->lock); 1173 spin_lock_irqsave(&smmu_domain->lock, flags);
1173 if (!smmu_domain->leaf_smmu) { 1174 if (!smmu_domain->leaf_smmu) {
1174 /* Now that we have a master, we can finalise the domain */ 1175 /* Now that we have a master, we can finalise the domain */
1175 ret = arm_smmu_init_domain_context(domain, dev); 1176 ret = arm_smmu_init_domain_context(domain, dev);
@@ -1184,7 +1185,7 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
1184 dev_name(device_smmu->dev)); 1185 dev_name(device_smmu->dev));
1185 goto err_unlock; 1186 goto err_unlock;
1186 } 1187 }
1187 spin_unlock(&smmu_domain->lock); 1188 spin_unlock_irqrestore(&smmu_domain->lock, flags);
1188 1189
1189 /* Looks ok, so add the device to the domain */ 1190 /* Looks ok, so add the device to the domain */
1190 master = find_smmu_master(smmu_domain->leaf_smmu, dev->of_node); 1191 master = find_smmu_master(smmu_domain->leaf_smmu, dev->of_node);
@@ -1194,7 +1195,7 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
1194 return arm_smmu_domain_add_master(smmu_domain, master); 1195 return arm_smmu_domain_add_master(smmu_domain, master);
1195 1196
1196err_unlock: 1197err_unlock:
1197 spin_unlock(&smmu_domain->lock); 1198 spin_unlock_irqrestore(&smmu_domain->lock, flags);
1198 return ret; 1199 return ret;
1199} 1200}
1200 1201
@@ -1396,6 +1397,7 @@ static int arm_smmu_handle_mapping(struct arm_smmu_domain *smmu_domain,
1396 struct arm_smmu_cfg *root_cfg = &smmu_domain->root_cfg; 1397 struct arm_smmu_cfg *root_cfg = &smmu_domain->root_cfg;
1397 pgd_t *pgd = root_cfg->pgd; 1398 pgd_t *pgd = root_cfg->pgd;
1398 struct arm_smmu_device *smmu = root_cfg->smmu; 1399 struct arm_smmu_device *smmu = root_cfg->smmu;
1400 unsigned long irqflags;
1399 1401
1400 if (root_cfg->cbar == CBAR_TYPE_S2_TRANS) { 1402 if (root_cfg->cbar == CBAR_TYPE_S2_TRANS) {
1401 stage = 2; 1403 stage = 2;
@@ -1418,7 +1420,7 @@ static int arm_smmu_handle_mapping(struct arm_smmu_domain *smmu_domain,
1418 if (paddr & ~output_mask) 1420 if (paddr & ~output_mask)
1419 return -ERANGE; 1421 return -ERANGE;
1420 1422
1421 spin_lock(&smmu_domain->lock); 1423 spin_lock_irqsave(&smmu_domain->lock, irqflags);
1422 pgd += pgd_index(iova); 1424 pgd += pgd_index(iova);
1423 end = iova + size; 1425 end = iova + size;
1424 do { 1426 do {
@@ -1434,7 +1436,7 @@ static int arm_smmu_handle_mapping(struct arm_smmu_domain *smmu_domain,
1434 } while (pgd++, iova != end); 1436 } while (pgd++, iova != end);
1435 1437
1436out_unlock: 1438out_unlock:
1437 spin_unlock(&smmu_domain->lock); 1439 spin_unlock_irqrestore(&smmu_domain->lock, irqflags);
1438 1440
1439 return ret; 1441 return ret;
1440} 1442}