summaryrefslogtreecommitdiff
path: root/drivers/iommu/io-pgtable-arm.c
diff options
context:
space:
mode:
authorLiam Mark <lmark@codeaurora.org>2015-08-15 21:58:11 -0700
committerDavid Keitel <dkeitel@codeaurora.org>2016-03-22 11:13:52 -0700
commitbbca324fc5098a3d529dd752c4e7c22660a90c36 (patch)
tree3fe0f66428dbb89b28257899313f65de2d54c3f4 /drivers/iommu/io-pgtable-arm.c
parent837edfc242e8802aabf0c8f33c75aca2b53cdc3b (diff)
iommu/io-pgtable: fix __arm_lpae_free_pgtable leak
When unmapping 2MB mappings, which are 2MB aligned, the smmu driver is leaking the 3rd level page tables. Fix this leak by updating __arm_lpae_free_pgtable so that it no longer leaks leaf table entries. To reproduce this leak simply map and unmap a non-block 2MB mapping which is 2MB aligned. Change-Id: Ibdbdb084ceb8d03ebe0a04e8777e3eb9419e9b87 Signed-off-by: Liam Mark <lmark@codeaurora.org>
Diffstat (limited to 'drivers/iommu/io-pgtable-arm.c')
-rw-r--r--drivers/iommu/io-pgtable-arm.c9
1 files changed, 5 insertions, 4 deletions
diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c
index 556c484951cc..582e858c8cad 100644
--- a/drivers/iommu/io-pgtable-arm.c
+++ b/drivers/iommu/io-pgtable-arm.c
@@ -542,10 +542,6 @@ static void __arm_lpae_free_pgtable(struct arm_lpae_io_pgtable *data, int lvl,
arm_lpae_iopte *start, *end;
unsigned long table_size;
- /* Only leaf entries at the last level */
- if (lvl == ARM_LPAE_MAX_LEVELS - 1)
- return;
-
if (lvl == ARM_LPAE_START_LVL(data))
table_size = data->pgd_size;
else
@@ -554,6 +550,10 @@ static void __arm_lpae_free_pgtable(struct arm_lpae_io_pgtable *data, int lvl,
start = ptep;
end = (void *)ptep + table_size;
+ /* Only leaf entries at the last level */
+ if (lvl == ARM_LPAE_MAX_LEVELS - 1)
+ goto end;
+
while (ptep != end) {
arm_lpae_iopte pte = *ptep++;
@@ -563,6 +563,7 @@ static void __arm_lpae_free_pgtable(struct arm_lpae_io_pgtable *data, int lvl,
__arm_lpae_free_pgtable(data, lvl + 1, iopte_deref(pte, data));
}
+end:
io_pgtable_free_pages_exact(&data->iop.cfg, data->iop.cookie,
start, table_size);
}