diff options
author | Robin Murphy <robin.murphy@arm.com> | 2016-03-10 14:28:12 -0500 |
---|---|---|
committer | Joerg Roedel <jroedel@suse.de> | 2016-04-05 09:14:05 -0400 |
commit | 07b48ac4bbe527e68cfc555f2b2b206908437141 (patch) | |
tree | bfae71ae8421a541afd2f453052f9ce9e48e8671 /drivers/iommu/dma-iommu.c | |
parent | b70bb984489363aadd5ccc94d919629d9e264d36 (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.c | 4 |
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; |