2021-06-10 04:19:46

by Ashish Mhetre

[permalink] [raw]
Subject: [PATCH 0/2] iommu/arm-smmu: Fix races in iommu domain/group creation

Fix races during iommu group/domain creation for devices sharing same SID.

Ashish Mhetre (1):
iommu: Fix race condition during default domain allocation

Krishna Reddy (1):
iommu/arm-smmu: Fix race condition during iommu_group creation

drivers/iommu/arm/arm-smmu/arm-smmu.c | 6 +++++-
drivers/iommu/iommu.c | 2 ++
2 files changed, 7 insertions(+), 1 deletion(-)

--
2.7.4


2021-06-10 04:21:15

by Ashish Mhetre

[permalink] [raw]
Subject: [PATCH 2/2] iommu/arm-smmu: Fix race condition during iommu_group creation

From: Krishna Reddy <[email protected]>

iommu_group is getting created more than once during asynchronous multiple
display heads(devices) probe on Tegra194 SoC. All the display heads share
same SID and are expected to be in same iommu_group.
As arm_smmu_device_group() is not protecting group creation across devices,
it is leading to multiple groups creation across devices with same SID and
subsequent IOMMU faults.
Fix this by protecting group creation with smmu->stream_map_mutex.

Signed-off-by: Krishna Reddy <[email protected]>
---
drivers/iommu/arm/arm-smmu/arm-smmu.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-smmu/arm-smmu.c
index 6f72c4d..21af179 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
@@ -1458,6 +1458,7 @@ static struct iommu_group *arm_smmu_device_group(struct device *dev)
struct iommu_group *group = NULL;
int i, idx;

+ mutex_lock(&smmu->stream_map_mutex);
for_each_cfg_sme(cfg, fwspec, i, idx) {
if (group && smmu->s2crs[idx].group &&
group != smmu->s2crs[idx].group)
@@ -1466,8 +1467,10 @@ static struct iommu_group *arm_smmu_device_group(struct device *dev)
group = smmu->s2crs[idx].group;
}

- if (group)
+ if (group) {
+ mutex_unlock(&smmu->stream_map_mutex);
return iommu_group_ref_get(group);
+ }

if (dev_is_pci(dev))
group = pci_device_group(dev);
@@ -1481,6 +1484,7 @@ static struct iommu_group *arm_smmu_device_group(struct device *dev)
for_each_cfg_sme(cfg, fwspec, i, idx)
smmu->s2crs[idx].group = group;

+ mutex_unlock(&smmu->stream_map_mutex);
return group;
}

--
2.7.4