From: George Dunlap <george.dunlap@eu.citrix.com>
To: xen-devel@lists.xensource.com
Cc: george.dunlap@eu.citrix.com
Subject: [PATCH] xen, vtd: Fix device check for devices behind PCIe-to-PCI bridges
Date: Thu, 1 Sep 2011 15:20:04 +0100 [thread overview]
Message-ID: <ede81b0552be5b4d1004.1314886804@elijah> (raw)
On some systems, requests devices behind a PCIe-to-PCI bridge all
appear to the IOMMU as though they come from from slot 0, function
0 on that device; so the mapping code much punch a hole for X:0.0
in the IOMMU for such devices. When punching the hole, if that device
has already been mapped once, we simply need to check ownership to
make sure it's legal. To do so, domain_context_mapping_one() will look
up the device for the mapping with pci_get_pdev() and look for the owner.
However, if there is no device in X:0.0, this look up will fail.
Rather than returning -ENODEV in this situation (causing a failure in
mapping the device), try to get the domain ownership from the iommu context
mapping itself.
Signed-off-by: George Dunlap <george.dunlap@eu.citrix.com>
diff -r 4a4882df5649 -r ede81b0552be xen/drivers/passthrough/vtd/iommu.c
--- a/xen/drivers/passthrough/vtd/iommu.c Wed Aug 31 15:23:49 2011 +0100
+++ b/xen/drivers/passthrough/vtd/iommu.c Thu Sep 01 15:18:18 2011 +0100
@@ -113,6 +113,27 @@ static int context_set_domain_id(struct
return 0;
}
+static int context_get_domain_id(struct context_entry *context,
+ struct iommu *iommu)
+{
+ unsigned long dom_index, nr_dom;
+ int domid = -1;
+
+ if (iommu && context)
+ {
+ nr_dom = cap_ndoms(iommu->cap);
+
+ dom_index = context_domain_id(*context);
+
+ if ( dom_index < nr_dom && iommu->domid_map)
+ domid = iommu->domid_map[dom_index];
+ else
+ dprintk(XENLOG_DEBUG VTDPREFIX, "%s: dom_index %lu exceeds nr_dom %lu or iommu has no domid_map\n",
+ __func__, dom_index, nr_dom);
+ }
+ return domid;
+}
+
static struct intel_iommu *__init alloc_intel_iommu(void)
{
struct intel_iommu *intel;
@@ -1237,7 +1258,6 @@ int domain_context_mapping_one(
struct hvm_iommu *hd = domain_hvm_iommu(domain);
struct context_entry *context, *context_entries;
u64 maddr, pgd_maddr;
- struct pci_dev *pdev = NULL;
int agaw;
ASSERT(spin_is_locked(&pcidevs_lock));
@@ -1249,12 +1269,45 @@ int domain_context_mapping_one(
if ( context_present(*context) )
{
int res = 0;
+ struct pci_dev *pdev = NULL;
+ /* First try to get domain ownership from device structure. If that's
+ * not available, try to read it from the context itself. */
pdev = pci_get_pdev(bus, devfn);
- if (!pdev)
- res = -ENODEV;
- else if (pdev->domain != domain)
- res = -EINVAL;
+ if ( pdev )
+ {
+ if ( pdev->domain != domain )
+ {
+ dprintk(XENLOG_INFO VTDPREFIX, "d%d: bdf = %x:%x.%x owned by d%d!",
+ domain->domain_id,
+ bus, PCI_SLOT(devfn), PCI_FUNC(devfn),
+ (pdev->domain)
+ ? pdev->domain->domain_id : -1);
+ res = -EINVAL;
+ }
+ }
+ else
+ {
+ int cdomain;
+ cdomain = context_get_domain_id(context, iommu);
+
+ if ( cdomain < 0 )
+ {
+ dprintk(VTDPREFIX, "d%d: bdf = %x:%x.%x mapped, but can't find owner!\n",
+ domain->domain_id,
+ bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
+ res = -EINVAL;
+ }
+ else if ( cdomain != domain->domain_id )
+ {
+ dprintk(XENLOG_INFO VTDPREFIX, "d%d: bdf = %x:%x.%x already mapped to d%d!",
+ domain->domain_id,
+ bus, PCI_SLOT(devfn), PCI_FUNC(devfn),
+ cdomain);
+ res = -EINVAL;
+ }
+ }
+
unmap_vtd_domain_page(context_entries);
spin_unlock(&iommu->lock);
return res;
next reply other threads:[~2011-09-01 14:20 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-09-01 14:20 George Dunlap [this message]
2011-09-05 12:15 ` [PATCH] xen, vtd: Fix device check for devices behind PCIe-to-PCI bridges Jan Beulich
2011-09-05 14:56 ` George Dunlap
2011-09-05 15:31 ` Jan Beulich
2011-09-06 21:16 ` Kay, Allen M
2011-09-07 9:52 ` George Dunlap
2011-09-13 9:12 ` George Dunlap
2011-09-13 10:53 ` Jan Beulich
2011-09-14 8:48 ` George Dunlap
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=ede81b0552be5b4d1004.1314886804@elijah \
--to=george.dunlap@eu.citrix.com \
--cc=xen-devel@lists.xensource.com \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).