From 8a697c767b2f532109ea95b48b83437947f9fb5d Mon Sep 17 00:00:00 2001 From: Hiroshi Doyu Date: Mon, 6 May 2013 12:27:18 +0300 Subject: 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 Reviewed-on: http://git-master/r/234123 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Krishna Reddy --- drivers/iommu/tegra-smmu.c | 16 +++++++++++++--- 1 file 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); -- cgit v1.2.3