Merge "iommu: arm-smmu: Introduce a new mutex in arm_smmu_device structure"
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index a836169..491f9d7 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -460,7 +460,7 @@
struct arm_smmu_smr *smrs;
struct arm_smmu_s2cr *s2crs;
struct mutex stream_map_mutex;
-
+ struct mutex iommu_group_mutex;
unsigned long va_size;
unsigned long ipa_size;
unsigned long pa_size;
@@ -2308,6 +2308,7 @@
struct iommu_group *group;
int i, idx, ret;
+ mutex_lock(&smmu->iommu_group_mutex);
mutex_lock(&smmu->stream_map_mutex);
/* Figure out a viable stream map entry allocation */
for_each_cfg_sme(fwspec, i, idx) {
@@ -2316,12 +2317,12 @@
if (idx != INVALID_SMENDX) {
ret = -EEXIST;
- goto out_err;
+ goto sme_err;
}
ret = arm_smmu_find_sme(smmu, sid, mask);
if (ret < 0)
- goto out_err;
+ goto sme_err;
idx = ret;
if (smrs && smmu->s2crs[idx].count == 0) {
@@ -2332,13 +2333,14 @@
smmu->s2crs[idx].count++;
cfg->smendx[i] = (s16)idx;
}
+ mutex_unlock(&smmu->stream_map_mutex);
group = iommu_group_get_for_dev(dev);
if (!group)
group = ERR_PTR(-ENOMEM);
if (IS_ERR(group)) {
ret = PTR_ERR(group);
- goto out_err;
+ goto iommu_group_err;
}
iommu_group_put(group);
@@ -2346,15 +2348,19 @@
for_each_cfg_sme(fwspec, i, idx)
smmu->s2crs[idx].group = group;
- mutex_unlock(&smmu->stream_map_mutex);
+ mutex_unlock(&smmu->iommu_group_mutex);
return 0;
-out_err:
+iommu_group_err:
+ mutex_lock(&smmu->stream_map_mutex);
+
+sme_err:
while (i--) {
arm_smmu_free_sme(smmu, cfg->smendx[i]);
cfg->smendx[i] = INVALID_SMENDX;
}
mutex_unlock(&smmu->stream_map_mutex);
+ mutex_unlock(&smmu->iommu_group_mutex);
return ret;
}
@@ -4480,6 +4486,7 @@
smmu->num_mapping_groups = size;
mutex_init(&smmu->stream_map_mutex);
+ mutex_init(&smmu->iommu_group_mutex);
if (smmu->version < ARM_SMMU_V2 || !(id & ID0_PTFS_NO_AARCH32)) {
smmu->features |= ARM_SMMU_FEAT_FMT_AARCH32_L;