summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorDmitry Osipenko <digetx@gmail.com>2018-12-12 21:39:02 +0100
committerJoerg Roedel <jroedel@suse.de>2019-01-16 13:54:14 +0100
commit7d849b7b40b9b3f574f50bbf44503b38e319fca5 (patch)
tree9d2e09f357d7e817c2652a88f51c0ae7ccc91507 /drivers
parentiommu/tegra: gart: Fix NULL pointer dereference (diff)
downloadlinux-7d849b7b40b9b3f574f50bbf44503b38e319fca5.tar.xz
linux-7d849b7b40b9b3f574f50bbf44503b38e319fca5.zip
iommu/tegra: gart: Allow only one active domain at a time
GART has a single address space that is shared by all devices, hence only one domain could be active at a time. Signed-off-by: Dmitry Osipenko <digetx@gmail.com> Acked-by: Thierry Reding <treding@nvidia.com> Signed-off-by: Joerg Roedel <jroedel@suse.de>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/iommu/tegra-gart.c9
1 files changed, 9 insertions, 0 deletions
diff --git a/drivers/iommu/tegra-gart.c b/drivers/iommu/tegra-gart.c
index 7fdd8b12efd5..71ff22be9560 100644
--- a/drivers/iommu/tegra-gart.c
+++ b/drivers/iommu/tegra-gart.c
@@ -57,6 +57,7 @@ struct gart_device {
spinlock_t pte_lock; /* for pagetable */
struct list_head client;
spinlock_t client_lock; /* for client list */
+ struct iommu_domain *active_domain; /* current active domain */
struct device *dev;
struct iommu_device iommu; /* IOMMU Core handle */
@@ -186,6 +187,12 @@ static int gart_iommu_attach_dev(struct iommu_domain *domain,
goto fail;
}
}
+ if (gart->active_domain && gart->active_domain != domain) {
+ dev_err(gart->dev, "Only one domain can be active at a time\n");
+ err = -EINVAL;
+ goto fail;
+ }
+ gart->active_domain = domain;
list_add(&client->list, &gart->client);
spin_unlock(&gart->client_lock);
dev_dbg(gart->dev, "Attached %s\n", dev_name(dev));
@@ -208,6 +215,8 @@ static void __gart_iommu_detach_dev(struct iommu_domain *domain,
if (c->dev == dev) {
list_del(&c->list);
devm_kfree(gart->dev, c);
+ if (list_empty(&gart->client))
+ gart->active_domain = NULL;
dev_dbg(gart->dev, "Detached %s\n", dev_name(dev));
return;
}