summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMitchel Humpherys <mitchelh@codeaurora.org>2015-03-10 14:37:07 -0700
committerDavid Keitel <dkeitel@codeaurora.org>2016-03-22 11:11:49 -0700
commit25252ab2ab8cc183a20f81c868f6355d7ade301a (patch)
treec6df1c1d61a64488c9b8a6dce900c73c7692cba3
parent6864dee3f0252b5c08a0741e55d9d714a4e8987f (diff)
iommu/arm-smmu: convert domain spinlock to a mutex
We'd like to use the domain lock to protect against a race condition where the domain's device pointer is used after the domain has been detached from the device. In order to prepare for this, change the domain lock to a mutex, since we'll be holding during times where we need to do non-atomic operations (like enabling clocks). Change-Id: Ib57812851487c0f0c4833c65f0b1c63e010385bf Signed-off-by: Mitchel Humpherys <mitchelh@codeaurora.org>
-rw-r--r--drivers/iommu/arm-smmu.c16
1 files changed, 7 insertions, 9 deletions
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 07546313f5b9..ea12303942ec 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -483,7 +483,7 @@ struct arm_smmu_cfg {
struct arm_smmu_domain {
struct arm_smmu_device *smmu;
struct arm_smmu_cfg cfg;
- spinlock_t lock;
+ struct mutex lock;
u32 attributes;
};
@@ -1164,11 +1164,10 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain,
struct arm_smmu_device *smmu)
{
int irq, start, ret = 0;
- unsigned long flags;
struct arm_smmu_domain *smmu_domain = domain->priv;
struct arm_smmu_cfg *cfg = &smmu_domain->cfg;
- spin_lock_irqsave(&smmu_domain->lock, flags);
+ mutex_lock(&smmu_domain->lock);
if (smmu_domain->smmu)
goto out_unlock;
@@ -1202,7 +1201,7 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain,
ACCESS_ONCE(smmu_domain->smmu) = smmu;
arm_smmu_init_context_bank(smmu_domain);
- spin_unlock_irqrestore(&smmu_domain->lock, flags);
+ mutex_unlock(&smmu_domain->lock);
irq = smmu->irqs[smmu->num_global_irqs + cfg->irptndx];
ret = request_threaded_irq(irq, NULL, arm_smmu_context_fault,
@@ -1217,7 +1216,7 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain,
return 0;
out_unlock:
- spin_unlock_irqrestore(&smmu_domain->lock, flags);
+ mutex_unlock(&smmu_domain->lock);
return ret;
}
@@ -1267,7 +1266,7 @@ static int arm_smmu_domain_init(struct iommu_domain *domain)
goto out_free_domain;
smmu_domain->cfg.pgd = pgd;
- spin_lock_init(&smmu_domain->lock);
+ mutex_init(&smmu_domain->lock);
domain->priv = smmu_domain;
return 0;
@@ -1799,7 +1798,6 @@ static int arm_smmu_handle_mapping(struct arm_smmu_domain *smmu_domain,
struct arm_smmu_device *smmu = smmu_domain->smmu;
struct arm_smmu_cfg *cfg = &smmu_domain->cfg;
pgd_t *pgd = cfg->pgd;
- unsigned long flags;
/* some extra sanity checks for attached domains */
if (smmu) {
@@ -1827,7 +1825,7 @@ static int arm_smmu_handle_mapping(struct arm_smmu_domain *smmu_domain,
if (size & ~PAGE_MASK)
return -EINVAL;
- spin_lock_irqsave(&smmu_domain->lock, flags);
+ mutex_lock(&smmu_domain->lock);
pgd += pgd_index(iova);
end = iova + size;
do {
@@ -1843,7 +1841,7 @@ static int arm_smmu_handle_mapping(struct arm_smmu_domain *smmu_domain,
} while (pgd++, iova != end);
out_unlock:
- spin_unlock_irqrestore(&smmu_domain->lock, flags);
+ mutex_unlock(&smmu_domain->lock);
return ret;
}