diff options
author | Joerg Roedel <joro@8bytes.org> | 2014-02-20 06:19:08 -0500 |
---|---|---|
committer | Joerg Roedel <joro@8bytes.org> | 2014-02-20 07:04:47 -0500 |
commit | 972157cac528f6cfd1f7e640139287951066106e (patch) | |
tree | d9515e0f258045d451ffd627057672070b887781 | |
parent | 15eeb2e925c091b999195d0102ac39a271dbcb7e (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.c | 12 |
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 | ||
1196 | err_unlock: | 1197 | err_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 | ||
1436 | out_unlock: | 1438 | out_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 | } |