summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHiroshi Doyu <hdoyu@nvidia.com>2013-05-06 12:27:18 +0300
committerHarshada Kale <hkale@nvidia.com>2013-06-10 03:48:51 -0700
commit8a697c767b2f532109ea95b48b83437947f9fb5d (patch)
tree951feb5a674d28d881a539f4b35cc9ec28402185
parent64b0972d3d8d5a9ac0bcb93b35eaf46f33d1231a (diff)
iommu/tegra: smmu: Skip invalid L2 pagetalbe at unmap
Skip invalid L2 pagetalbe at unmap. Unmap can be called against invalide pages. bug 1286500 Change-Id: I70e66eddb57982ae1dd2e0f592d18923676e9171 (cherry picked from commit 56a0bf501f15921bccfc73c3400ce48cb39f36be) Signed-off-by: Hiroshi Doyu <hdoyu@nvidia.com> Reviewed-on: http://git-master/r/234123 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Krishna Reddy <vdumpa@nvidia.com>
-rw-r--r--drivers/iommu/tegra-smmu.c16
1 files changed, 13 insertions, 3 deletions
diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c
index ee31b561982f..5b7fbb9442ce 100644
--- a/drivers/iommu/tegra-smmu.c
+++ b/drivers/iommu/tegra-smmu.c
@@ -691,9 +691,19 @@ static size_t __smmu_iommu_unmap_pages(struct smmu_as *as, dma_addr_t iova,
unsigned long ptn = SMMU_ADDR_TO_PFN(iova);
unsigned long pdn = SMMU_ADDR_TO_PDN(iova);
struct page *page = SMMU_EX_PTBL_PAGE(pdir[pdn]);
- unsigned long *ptbl = page_address(page);
- unsigned long *pte = &ptbl[ptn];
- int count = min_t(unsigned long, SZ_1K - ptn, total);
+ unsigned long *ptbl;
+ unsigned long *pte;
+ int count;
+
+ if (!pfn_valid(page_to_pfn(page))) {
+ total -= SMMU_PDN_TO_ADDR(pdn + 1) - iova;
+ iova = SMMU_PDN_TO_ADDR(pdn + 1);
+ continue;
+ }
+
+ ptbl = page_address(page);
+ pte = &ptbl[ptn];
+ count = min_t(unsigned long, SMMU_PTBL_COUNT - ptn, total);
dev_dbg(as->smmu->dev, "unmapping %d pages at once\n", count);