diff options
author | Dmitry Osipenko <digetx@gmail.com> | 2018-04-09 16:07:19 -0400 |
---|---|---|
committer | Joerg Roedel <jroedel@suse.de> | 2018-05-03 10:30:21 -0400 |
commit | 40c9b882fa74771544b0e41209e99d78685f94be (patch) | |
tree | 67d03a5173c67e8b156af51de4ba6f786d5685ef /drivers/iommu/tegra-gart.c | |
parent | 6da6c0db5316275015e8cc2959f12a17584aeb64 (diff) |
iommu/tegra: gart: Add debugging facility
Page mapping could overwritten by an accident (a bug). We can catch this
case by checking 'VALID' bit of GART's page entry prior to mapping of a
page. Since that check introduces a small performance impact, it should be
enabled explicitly using new GART's kernel module 'debug' parameter.
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/iommu/tegra-gart.c')
-rw-r--r-- | drivers/iommu/tegra-gart.c | 13 |
1 files changed, 13 insertions, 0 deletions
diff --git a/drivers/iommu/tegra-gart.c b/drivers/iommu/tegra-gart.c index b62f790ad1ba..4c0abdcd1ad2 100644 --- a/drivers/iommu/tegra-gart.c +++ b/drivers/iommu/tegra-gart.c | |||
@@ -72,6 +72,8 @@ struct gart_domain { | |||
72 | 72 | ||
73 | static struct gart_device *gart_handle; /* unique for a system */ | 73 | static struct gart_device *gart_handle; /* unique for a system */ |
74 | 74 | ||
75 | static bool gart_debug; | ||
76 | |||
75 | #define GART_PTE(_pfn) \ | 77 | #define GART_PTE(_pfn) \ |
76 | (GART_ENTRY_PHYS_ADDR_VALID | ((_pfn) << PAGE_SHIFT)) | 78 | (GART_ENTRY_PHYS_ADDR_VALID | ((_pfn) << PAGE_SHIFT)) |
77 | 79 | ||
@@ -271,6 +273,7 @@ static int gart_iommu_map(struct iommu_domain *domain, unsigned long iova, | |||
271 | struct gart_device *gart = gart_domain->gart; | 273 | struct gart_device *gart = gart_domain->gart; |
272 | unsigned long flags; | 274 | unsigned long flags; |
273 | unsigned long pfn; | 275 | unsigned long pfn; |
276 | unsigned long pte; | ||
274 | 277 | ||
275 | if (!gart_iova_range_valid(gart, iova, bytes)) | 278 | if (!gart_iova_range_valid(gart, iova, bytes)) |
276 | return -EINVAL; | 279 | return -EINVAL; |
@@ -282,6 +285,14 @@ static int gart_iommu_map(struct iommu_domain *domain, unsigned long iova, | |||
282 | spin_unlock_irqrestore(&gart->pte_lock, flags); | 285 | spin_unlock_irqrestore(&gart->pte_lock, flags); |
283 | return -EINVAL; | 286 | return -EINVAL; |
284 | } | 287 | } |
288 | if (gart_debug) { | ||
289 | pte = gart_read_pte(gart, iova); | ||
290 | if (pte & GART_ENTRY_PHYS_ADDR_VALID) { | ||
291 | spin_unlock_irqrestore(&gart->pte_lock, flags); | ||
292 | dev_err(gart->dev, "Page entry is in-use\n"); | ||
293 | return -EBUSY; | ||
294 | } | ||
295 | } | ||
285 | gart_set_pte(gart, iova, GART_PTE(pfn)); | 296 | gart_set_pte(gart, iova, GART_PTE(pfn)); |
286 | FLUSH_GART_REGS(gart); | 297 | FLUSH_GART_REGS(gart); |
287 | spin_unlock_irqrestore(&gart->pte_lock, flags); | 298 | spin_unlock_irqrestore(&gart->pte_lock, flags); |
@@ -515,7 +526,9 @@ static void __exit tegra_gart_exit(void) | |||
515 | 526 | ||
516 | subsys_initcall(tegra_gart_init); | 527 | subsys_initcall(tegra_gart_init); |
517 | module_exit(tegra_gart_exit); | 528 | module_exit(tegra_gart_exit); |
529 | module_param(gart_debug, bool, 0644); | ||
518 | 530 | ||
531 | MODULE_PARM_DESC(gart_debug, "Enable GART debugging"); | ||
519 | MODULE_DESCRIPTION("IOMMU API for GART in Tegra20"); | 532 | MODULE_DESCRIPTION("IOMMU API for GART in Tegra20"); |
520 | MODULE_AUTHOR("Hiroshi DOYU <hdoyu@nvidia.com>"); | 533 | MODULE_AUTHOR("Hiroshi DOYU <hdoyu@nvidia.com>"); |
521 | MODULE_ALIAS("platform:tegra-gart"); | 534 | MODULE_ALIAS("platform:tegra-gart"); |