From 1ea5440e36a792d01aae0b22159e0a13b33589fe Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Thu, 6 Aug 2020 17:54:04 +0200 Subject: iommu/tegra-smmu: Prune IOMMU group when it is released In order to share groups between multiple devices we keep track of them in a per-SMMU list. When an IOMMU group is released, a dangling pointer to it stays around in that list. Fix this by implementing an IOMMU data release callback for groups where the dangling pointer can be removed. Signed-off-by: Thierry Reding Link: https://lore.kernel.org/r/20200806155404.3936074-4-thierry.reding@gmail.com Signed-off-by: Joerg Roedel --- drivers/iommu/tegra-smmu.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'drivers/iommu/tegra-smmu.c') diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c index c439c0929ef8..2574e716086b 100644 --- a/drivers/iommu/tegra-smmu.c +++ b/drivers/iommu/tegra-smmu.c @@ -19,6 +19,7 @@ struct tegra_smmu_group { struct list_head list; + struct tegra_smmu *smmu; const struct tegra_smmu_group_soc *soc; struct iommu_group *group; }; @@ -813,6 +814,16 @@ tegra_smmu_find_group(struct tegra_smmu *smmu, unsigned int swgroup) return NULL; } +static void tegra_smmu_group_release(void *iommu_data) +{ + struct tegra_smmu_group *group = iommu_data; + struct tegra_smmu *smmu = group->smmu; + + mutex_lock(&smmu->lock); + list_del(&group->list); + mutex_unlock(&smmu->lock); +} + static struct iommu_group *tegra_smmu_group_get(struct tegra_smmu *smmu, unsigned int swgroup) { @@ -840,6 +851,7 @@ static struct iommu_group *tegra_smmu_group_get(struct tegra_smmu *smmu, } INIT_LIST_HEAD(&group->list); + group->smmu = smmu; group->soc = soc; group->group = iommu_group_alloc(); @@ -849,6 +861,7 @@ static struct iommu_group *tegra_smmu_group_get(struct tegra_smmu *smmu, return NULL; } + iommu_group_set_iommudata(group->group, group, tegra_smmu_group_release); iommu_group_set_name(group->group, soc->name); list_add_tail(&group->list, &smmu->groups); mutex_unlock(&smmu->lock); -- cgit v1.2.3