All of lore.kernel.org
 help / color / mirror / Atom feed
From: Robin Murphy <robin.murphy@arm.com>
To: joro@8bytes.org
Cc: dwmw2@infradead.org, ashok.raj@intel.com, leedom@chelsio.com,
	Harsh@chelsio.com, herbert@gondor.apana.org.au,
	iommu@lists.linux-foundation.org, linux-crypto@vger.kernel.org,
	linux-kernel@vger.kernel.org
Subject: [PATCH] iommu/vt-d: Fix scatterlist offset handling
Date: Thu, 28 Sep 2017 15:14:01 +0100	[thread overview]
Message-ID: <644c3e01654f8bd48d669c36e424959d6ef0e27e.1506607370.git.robin.murphy@arm.com> (raw)

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.

Reported-by: Harsh Jain <Harsh@chelsio.com>
Signed-off-by: Robin Murphy <robin.murphy@arm.com>
---
 drivers/iommu/intel-iommu.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index 6784a05dd6b2..83f3d4831f94 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -2254,10 +2254,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;
 		}
 
@@ -3790,7 +3792,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;
-- 
2.13.4.dirty

             reply	other threads:[~2017-09-28 14:14 UTC|newest]

Thread overview: 33+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-09-28 14:14 Robin Murphy [this message]
2017-09-28 16:17 ` [PATCH] iommu/vt-d: Fix scatterlist offset handling Casey Leedom
2017-09-28 13:29   ` Raj, Ashok
2017-09-28 16:59     ` Robin Murphy
2017-09-28 15:43       ` Raj, Ashok
2017-10-03 19:36         ` Raj, Ashok
2017-09-29  8:14 ` Harsh Jain
     [not found]   ` <fe25071a-18bf-e468-01e7-36515f2110e2-ut6Up61K2wZBDgjK7y7TUQ@public.gmane.org>
2017-09-29 16:18     ` Casey Leedom
2017-09-29 16:18       ` Casey Leedom
     [not found]       ` <MWHPR12MB160034E91A834504FE85C07BC87E0-Gy0DoCVfaSVsWITs4OkDoAdYzm3356FpvxpqHgZTriW3zl9H0oFU5g@public.gmane.org>
2017-10-03 12:22         ` Harsh Jain
2017-10-03 22:22           ` Casey Leedom
     [not found] ` <644c3e01654f8bd48d669c36e424959d6ef0e27e.1506607370.git.robin.murphy-5wv7dgnIgG8@public.gmane.org>
2017-10-03 12:55   ` David Woodhouse
2017-10-03 12:55     ` David Woodhouse
2017-10-03 18:05     ` Robin Murphy
2017-10-03 22:16       ` David Woodhouse
2017-10-04 11:18         ` Robin Murphy
2017-10-06 14:43       ` Joerg Roedel
2017-10-06 12:54         ` Raj, Ashok
     [not found]         ` <20171006144309.GA30803-zLv9SwRftAIdnm+yROfE0A@public.gmane.org>
2017-11-06 18:47           ` Jacob Pan
2017-11-06 18:47             ` Jacob Pan
2017-11-15 23:54             ` Jacob Pan
2017-11-15 23:54               ` Jacob Pan
2017-11-16 21:32               ` Alex Williamson
     [not found]                 ` <20171116143244.2583d044-1yVPhWWZRC1BDLzU/O5InQ@public.gmane.org>
2017-11-16 21:09                   ` Raj, Ashok
2017-11-16 21:09                     ` Raj, Ashok
2017-11-17 16:18                     ` Alex Williamson
2017-11-17 16:18                       ` Alex Williamson
2017-11-17 15:48                       ` Raj, Ashok
2017-11-17 17:44                         ` Casey Leedom
2017-11-17 17:44                           ` Casey Leedom
2017-11-17 17:44                           ` Casey Leedom
     [not found]                           ` <SN1PR12MB035214EF471935B6F4220E36C82F0-z7L1TMIYDg4e2a8M8f4RFAdYzm3356FpvxpqHgZTriW3zl9H0oFU5g@public.gmane.org>
2017-11-17 18:09                             ` Jacob Pan
2017-11-17 18:09                               ` Jacob Pan

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=644c3e01654f8bd48d669c36e424959d6ef0e27e.1506607370.git.robin.murphy@arm.com \
    --to=robin.murphy@arm.com \
    --cc=Harsh@chelsio.com \
    --cc=ashok.raj@intel.com \
    --cc=dwmw2@infradead.org \
    --cc=herbert@gondor.apana.org.au \
    --cc=iommu@lists.linux-foundation.org \
    --cc=joro@8bytes.org \
    --cc=leedom@chelsio.com \
    --cc=linux-crypto@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.