Patch "iommu/vt-d: Fix scatterlist offset handling" has been added to the 4.14-stable tree
Subsystems (2)
This is a note to let you know that I've just added the patch titled
iommu/vt-d: Fix scatterlist offset handling
to the 4.14-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
iommu-vt-d-fix-scatterlist-offset-handling.patch
and it can be found in the queue-4.14 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
29a90b70893817e2f2bb3cea40a29f5308e21b21Mon Sep 17 00:00:00 2001
From: Robin Murphy <[email protected]>
Date: Thu, 28 Sep 2017 15:14:01 +0100
Subject: iommu/vt-d: Fix scatterlist offset handling
From: Robin Murphy <[email protected]>
commit 29a90b70893817e2f2bb3cea40a29f5308e21b21 upstream.
The intel-iommu DMA ops fail to correctly handle scatterlists where sg->offset is greater than PAGE_SIZE - the IOVA allocation is computed appropriately based on the page-aligned portion of the offset, but the mapping is set up relative to sg->page, which means it fails to actually cover the whole buffer (and in the worst case doesn't cover it at all):
(sg->dma_address + sg->dma_len) ----+
sg->dma_address ---------+ |
iov_pfn------+ | |
| | |
v v v
iova: a b c d e f
|--------|--------|--------|--------|--------|
<...calculated....>
[_____mapped______]
pfn: 0 1 2 3 4 5
|--------|--------|--------|--------|--------|
^ ^ ^
| | |
sg->page ----+ | |
sg->offset --------------+ |
(sg->offset + sg->length) ----------+As a result, the caller ends up overrunning the mapping into whatever lies beyond, which usually goes badly:
[ 429.645492] DMAR: DRHD: handling fault status reg 2 [ 429.650847] DMAR: [DMA Write] Request device [02:00.4] fault addr f2682000 ...
Whilst this is a fairly rare occurrence, it can happen from the result of intermediate scatterlist processing such as scatterwalk_ffwd() in the crypto layer. Whilst that particular site could be fixed up, it still seems worthwhile to bring intel-iommu in line with other DMA API implementations in handling this robustly.
To that end, fix the intel_map_sg() path to line up the mapping correctly (in units of MM pages rather than VT-d pages to match the aligned_nrpages() calculation) regardless of the offset, and use sg_phys() consistently for clarity.
Reviewed by: Ashok Raj <[email protected]>
Tested by: Jacob Pan <[email protected]>
--- drivers/iommu/intel-iommu.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
drivers/iommu/intel-iommu.c +5 -3
@@ -2254,10 +2254,12 @@ static int __domain_mapping(struct dmar_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 ; }
@@ -3790,7 +3792,7 @@ static int intel_nontranslate_map_sg(strfor_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;
Patches currently in stable-queue which might be from [email protected] are
queue-4.14/iommu-vt-d-fix-scatterlist-offset-handling.patch