summary refs log tree commit diff
path: root/drivers/iommu
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-12-06 10:53:02 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2017-12-06 10:53:02 -0800
commite56d565d67ae7dd6b25ce6a331c43e691ff1d247 (patch)
tree1e2b8a5d87c9f05dce459754a2689b06ddd4a784 /drivers/iommu
parentf9efc944474742ad952c15c092a901d88ed83c71 (diff)
parent29a90b70893817e2f2bb3cea40a29f5308e21b21 (diff)
downloadlinux-e56d565d67ae7dd6b25ce6a331c43e691ff1d247.tar.gz
Merge tag 'iommu-v4.15-rc3' of git://github.com/awilliam/linux-vfio
Pull IOMMU fix from Alex Williamson:
 "Fix VT-d handling of scatterlists where sg->offset exceeds PAGE_SIZE"

* tag 'iommu-v4.15-rc3' of git://github.com/awilliam/linux-vfio:
  iommu/vt-d: Fix scatterlist offset handling
Diffstat (limited to 'drivers/iommu')
-rw-r--r--drivers/iommu/intel-iommu.c8
1 files changed, 5 insertions, 3 deletions
diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index a0babdbf7146..4a2de34895ec 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -2250,10 +2250,12 @@ static int __domain_mapping(struct dmar_domain *domain, unsigned long iov_pfn,
 		uint64_t tmp;
 
 		if (!sg_res) {
+			unsigned int pgoff = sg->offset & ~PAGE_MASK;
+
 			sg_res = aligned_nrpages(sg->offset, sg->length);
-			sg->dma_address = ((dma_addr_t)iov_pfn << VTD_PAGE_SHIFT) + sg->offset;
+			sg->dma_address = ((dma_addr_t)iov_pfn << VTD_PAGE_SHIFT) + pgoff;
 			sg->dma_length = sg->length;
-			pteval = page_to_phys(sg_page(sg)) | prot;
+			pteval = (sg_phys(sg) - pgoff) | prot;
 			phys_pfn = pteval >> VTD_PAGE_SHIFT;
 		}
 
@@ -3787,7 +3789,7 @@ static int intel_nontranslate_map_sg(struct device *hddev,
 
 	for_each_sg(sglist, sg, nelems, i) {
 		BUG_ON(!sg_page(sg));
-		sg->dma_address = page_to_phys(sg_page(sg)) + sg->offset;
+		sg->dma_address = sg_phys(sg);
 		sg->dma_length = sg->length;
 	}
 	return nelems;