summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMitchel Humpherys <mitchelh@codeaurora.org>2015-03-04 15:13:52 -0800
committerDavid Keitel <dkeitel@codeaurora.org>2016-03-22 11:11:45 -0700
commit9c66ec14770fd39646f63d887607c7d56a126f94 (patch)
treec012a51e8d0bea913f5ffd768c097477a5ea63ba
parent93684aed807d277efef77b6e638b69010e8ebde5 (diff)
iommu/arm-smmu: fix leak in arm_smmu_flush_pgtable
We're currently mapping a page in arm_smmu_flush_pgtable without ever unmapping it. Fix this by calling dma_unmap_page on the returned dma address. Since the only reason we're calling dma_map_page is to make sure it actually gets flushed out to RAM, we can just call dma_unmap_page immediately following the map. Without this, eventually swiotlb runs out of memory and starts printing things like: arm-smmu d00000.arm,smmu: swiotlb buffer is full (sz: 128 bytes) Change-Id: I69421de6e2189a16cd88f225e2698cd88d669dff Signed-off-by: Mitchel Humpherys <mitchelh@codeaurora.org>
-rw-r--r--drivers/iommu/arm-smmu.c17
1 files changed, 13 insertions, 4 deletions
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index e11fefb4e19f..9389e1e8f531 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -978,11 +978,20 @@ static void arm_smmu_flush_pgtable(struct arm_smmu_domain *smmu_domain,
* recursion here as the SMMU table walker will not be wired
* through another SMMU.
*/
- if (smmu)
- dma_map_page(smmu->dev, virt_to_page(addr),
- offset, size, DMA_TO_DEVICE);
- else
+ if (smmu) {
+ dma_addr_t handle =
+ dma_map_page(smmu->dev, virt_to_page(addr),
+ offset, size, DMA_TO_DEVICE);
+ if (handle == DMA_ERROR_CODE)
+ dev_err(smmu->dev,
+ "Couldn't flush page tables at %p!\n",
+ addr);
+ else
+ dma_unmap_page(smmu->dev, handle, size,
+ DMA_TO_DEVICE);
+ } else {
dmac_clean_range(addr, addr + size);
+ }
}
}