diff options
| author | Mitchel Humpherys <mitchelh@codeaurora.org> | 2015-03-10 14:37:07 -0700 |
|---|---|---|
| committer | David Keitel <dkeitel@codeaurora.org> | 2016-03-22 11:11:49 -0700 |
| commit | 25252ab2ab8cc183a20f81c868f6355d7ade301a (patch) | |
| tree | c6df1c1d61a64488c9b8a6dce900c73c7692cba3 | |
| parent | 6864dee3f0252b5c08a0741e55d9d714a4e8987f (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.c | 16 |
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; } |
