aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/iommu/dma-iommu.c
diff options
context:
space:
mode:
authorRobin Murphy <robin.murphy@arm.com>2016-03-10 14:28:12 -0500
committerJoerg Roedel <jroedel@suse.de>2016-04-05 09:14:05 -0400
commit07b48ac4bbe527e68cfc555f2b2b206908437141 (patch)
treebfae71ae8421a541afd2f453052f9ce9e48e8671 /drivers/iommu/dma-iommu.c
parentb70bb984489363aadd5ccc94d919629d9e264d36 (diff)
iommu/dma: Restore scatterlist offsets correctly
With the change to stashing just the IOVA-page-aligned remainder of the CPU-page offset rather than the whole thing, the failure path in __invalidate_sg() also needs tweaking to account for that in the case of differing page sizes where the two offsets may not be equivalent. Similarly in __finalise_sg(), lest the architecture-specific wrappers later get the wrong address for cache maintenance on sync or unmap. Fixes: 164afb1d85b8 ("iommu/dma: Use correct offset in map_sg") Reported-by: Magnus Damm <damm+renesas@opensource.se> Signed-off-by: Robin Murphy <robin.murphy@arm.com> Cc: stable@ver.kernel.org # v4.4+ Signed-off-by: Joerg Roedel <jroedel@suse.de>
Diffstat (limited to 'drivers/iommu/dma-iommu.c')
-rw-r--r--drivers/iommu/dma-iommu.c4
1 files changed, 2 insertions, 2 deletions
diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c
index 72d6182666cb..58f2fe687a24 100644
--- a/drivers/iommu/dma-iommu.c
+++ b/drivers/iommu/dma-iommu.c
@@ -403,7 +403,7 @@ static int __finalise_sg(struct device *dev, struct scatterlist *sg, int nents,
403 unsigned int s_length = sg_dma_len(s); 403 unsigned int s_length = sg_dma_len(s);
404 unsigned int s_dma_len = s->length; 404 unsigned int s_dma_len = s->length;
405 405
406 s->offset = s_offset; 406 s->offset += s_offset;
407 s->length = s_length; 407 s->length = s_length;
408 sg_dma_address(s) = dma_addr + s_offset; 408 sg_dma_address(s) = dma_addr + s_offset;
409 dma_addr += s_dma_len; 409 dma_addr += s_dma_len;
@@ -422,7 +422,7 @@ static void __invalidate_sg(struct scatterlist *sg, int nents)
422 422
423 for_each_sg(sg, s, nents, i) { 423 for_each_sg(sg, s, nents, i) {
424 if (sg_dma_address(s) != DMA_ERROR_CODE) 424 if (sg_dma_address(s) != DMA_ERROR_CODE)
425 s->offset = sg_dma_address(s); 425 s->offset += sg_dma_address(s);
426 if (sg_dma_len(s)) 426 if (sg_dma_len(s))
427 s->length = sg_dma_len(s); 427 s->length = sg_dma_len(s);
428 sg_dma_address(s) = DMA_ERROR_CODE; 428 sg_dma_address(s) = DMA_ERROR_CODE;