aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoerg Roedel <joerg.roedel@amd.com>2010-09-23 16:12:48 +0200
committerGreg Kroah-Hartman <gregkh@suse.de>2010-10-28 21:43:56 -0700
commita294ba6d5420b899e03daa18eb2dc5c25807e2ce (patch)
treef6be429a1a10eab953e5d30054650b4790978fb8
parent2fa4db60e3c6a305c4f46826c3226dae7947ac92 (diff)
x86/amd-iommu: Fix rounding-bug in __unmap_single
commit 04e0463e088b41060c08c255eb0d3278a504f094 upstream. In the __unmap_single function the dma_addr is rounded down to a page boundary before the dma pages are unmapped. The address is later also used to flush the TLB entries for that mapping. But without the offset into the dma page the amount of pages to flush might be miscalculated in the TLB flushing path. This patch fixes this bug by using the original address to flush the TLB. Signed-off-by: Joerg Roedel <joerg.roedel@amd.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--arch/x86/kernel/amd_iommu.c4
1 files changed, 3 insertions, 1 deletions
diff --git a/arch/x86/kernel/amd_iommu.c b/arch/x86/kernel/amd_iommu.c
index f0fa7a1782d..7cd33f75a69 100644
--- a/arch/x86/kernel/amd_iommu.c
+++ b/arch/x86/kernel/amd_iommu.c
@@ -1688,6 +1688,7 @@ static void __unmap_single(struct amd_iommu *iommu,
size_t size,
int dir)
{
+ dma_addr_t flush_addr;
dma_addr_t i, start;
unsigned int pages;
@@ -1695,6 +1696,7 @@ static void __unmap_single(struct amd_iommu *iommu,
(dma_addr + size > dma_dom->aperture_size))
return;
+ flush_addr = dma_addr;
pages = iommu_num_pages(dma_addr, size, PAGE_SIZE);
dma_addr &= PAGE_MASK;
start = dma_addr;
@@ -1709,7 +1711,7 @@ static void __unmap_single(struct amd_iommu *iommu,
dma_ops_free_addresses(dma_dom, dma_addr, pages);
if (amd_iommu_unmap_flush || dma_dom->need_flush) {
- iommu_flush_pages(iommu, dma_dom->domain.id, dma_addr, size);
+ iommu_flush_pages(iommu, dma_dom->domain.id, flush_addr, size);
dma_dom->need_flush = false;
}
}