[v1,2/4] iommu/tegra: gart: Check whether page is already mapped

Message ID a19ba1ca835aa2526d2c0492e6b0d0b35889596a.1499270277.git.digetx@gmail.com
State New
Headers show

Commit Message

Dmitry Osipenko July 5, 2017, 4:29 p.m.
Due to a bug, multiple devices may try to map the same IOVA region. We can
catch that case by checking that 'VALID' bit of the GART's page entry is
unset prior to mapping of the page.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/iommu/tegra-gart.c | 7 +++++++
 1 file changed, 7 insertions(+)

Patch

diff --git a/drivers/iommu/tegra-gart.c b/drivers/iommu/tegra-gart.c
index 1557a6a9a438..54699e341110 100644
--- a/drivers/iommu/tegra-gart.c
+++ b/drivers/iommu/tegra-gart.c
@@ -271,6 +271,7 @@  static int gart_iommu_map(struct iommu_domain *domain, unsigned long iova,
 	struct gart_device *gart = gart_domain->gart;
 	unsigned long flags;
 	unsigned long pfn;
+	unsigned long pte;
 
 	if (!gart_iova_range_valid(gart, iova, bytes))
 		return -EINVAL;
@@ -282,6 +283,12 @@  static int gart_iommu_map(struct iommu_domain *domain, unsigned long iova,
 		spin_unlock_irqrestore(&gart->pte_lock, flags);
 		return -EINVAL;
 	}
+	pte = gart_read_pte(gart, iova);
+	if (pte & GART_ENTRY_PHYS_ADDR_VALID) {
+		spin_unlock_irqrestore(&gart->pte_lock, flags);
+		dev_err(gart->dev, "Page entry is used already\n");
+		return -EBUSY;
+	}
 	gart_set_pte(gart, iova, GART_PTE(pfn));
 	FLUSH_GART_REGS(gart);
 	spin_unlock_irqrestore(&gart->pte_lock, flags);