diff options
author | Jiang Liu <jiang.liu@linux.intel.com> | 2014-04-08 22:20:39 -0400 |
---|---|---|
committer | David Woodhouse <David.Woodhouse@intel.com> | 2014-04-13 08:07:56 -0400 |
commit | adeb25905c644350baf1f446bcd856517e58060e (patch) | |
tree | 1ce3d39a0761c3cf12c562128c605af7bb3cbb8f /drivers/iommu/intel-iommu.c | |
parent | 7713ec066ae8adc49dd8daa02a73e6b60af6ee5f (diff) |
iommu/vt-d: fix memory leakage caused by commit ea8ea46
Commit ea8ea46 "iommu/vt-d: Clean up and fix page table clear/free
behaviour" introduces possible leakage of DMA page tables due to:
for (pte = page_address(pg); !first_pte_in_page(pte); pte++) {
if (dma_pte_present(pte) && !dma_pte_superpage(pte))
freelist = dma_pte_list_pagetables(domain, level - 1,
pte, freelist);
}
For the first pte in a page, first_pte_in_page(pte) will always be true,
thus dma_pte_list_pagetables() will never be called and leak DMA page
tables if level is bigger than 1.
Signed-off-by: Jiang Liu <jiang.liu@linux.intel.com>
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Diffstat (limited to 'drivers/iommu/intel-iommu.c')
-rw-r--r-- | drivers/iommu/intel-iommu.c | 6 |
1 files changed, 4 insertions, 2 deletions
diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c index 69fa7da5e48b..13dc2318e17a 100644 --- a/drivers/iommu/intel-iommu.c +++ b/drivers/iommu/intel-iommu.c | |||
@@ -1009,11 +1009,13 @@ static struct page *dma_pte_list_pagetables(struct dmar_domain *domain, | |||
1009 | if (level == 1) | 1009 | if (level == 1) |
1010 | return freelist; | 1010 | return freelist; |
1011 | 1011 | ||
1012 | for (pte = page_address(pg); !first_pte_in_page(pte); pte++) { | 1012 | pte = page_address(pg); |
1013 | do { | ||
1013 | if (dma_pte_present(pte) && !dma_pte_superpage(pte)) | 1014 | if (dma_pte_present(pte) && !dma_pte_superpage(pte)) |
1014 | freelist = dma_pte_list_pagetables(domain, level - 1, | 1015 | freelist = dma_pte_list_pagetables(domain, level - 1, |
1015 | pte, freelist); | 1016 | pte, freelist); |
1016 | } | 1017 | pte++; |
1018 | } while (!first_pte_in_page(pte)); | ||
1017 | 1019 | ||
1018 | return freelist; | 1020 | return freelist; |
1019 | } | 1021 | } |