aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/iommu/dma-iommu.c
diff options
context:
space:
mode:
authorRobin Murphy <robin.murphy@arm.com>2016-01-04 11:19:42 -0500
committerJoerg Roedel <jroedel@suse.de>2016-01-07 07:36:41 -0500
commit164afb1d85b872907cfac048b46c094db596d529 (patch)
tree04af5245fdc9d8d565bf443bae484673230b4395 /drivers/iommu/dma-iommu.c
parentf64232eee61906f22942224af2a9fd40e26e592e (diff)
iommu/dma: Use correct offset in map_sg
When mapping a non-page-aligned scatterlist entry, we copy the original offset to the output DMA address before aligning it to hand off to iommu_map_sg(), then later adding the IOVA page address portion to get the final mapped address. However, when the IOVA page size is smaller than the CPU page size, it is the offset within the IOVA page we want, not that within the CPU page, which can easily be larger than an IOVA page and thus result in an incorrect final address. Fix the bug by taking only the IOVA-aligned part of the offset as the basis of the DMA address, not the whole thing. Signed-off-by: Robin Murphy <robin.murphy@arm.com> Signed-off-by: Joerg Roedel <jroedel@suse.de>
Diffstat (limited to 'drivers/iommu/dma-iommu.c')
-rw-r--r--drivers/iommu/dma-iommu.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c
index 2e7417f98116..72d6182666cb 100644
--- a/drivers/iommu/dma-iommu.c
+++ b/drivers/iommu/dma-iommu.c
@@ -458,7 +458,7 @@ int iommu_dma_map_sg(struct device *dev, struct scatterlist *sg,
458 size_t s_offset = iova_offset(iovad, s->offset); 458 size_t s_offset = iova_offset(iovad, s->offset);
459 size_t s_length = s->length; 459 size_t s_length = s->length;
460 460
461 sg_dma_address(s) = s->offset; 461 sg_dma_address(s) = s_offset;
462 sg_dma_len(s) = s_length; 462 sg_dma_len(s) = s_length;
463 s->offset -= s_offset; 463 s->offset -= s_offset;
464 s_length = iova_align(iovad, s_length + s_offset); 464 s_length = iova_align(iovad, s_length + s_offset);