Commit 1ea5440e authored by Thierry Reding's avatar Thierry Reding Committed by Joerg Roedel

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: default avatarThierry Reding <treding@nvidia.com>
Link: https://lore.kernel.org/r/20200806155404.3936074-4-thierry.reding@gmail.comSigned-off-by: default avatarJoerg Roedel <jroedel@suse.de>
parent 5b30fbfa
......@@ -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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment