[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] x86, vt-d: Fail PCI device assignment if device already assigned.



# HG changeset patch
# User Keir Fraser <keir@xxxxxxxxxxxxx>
# Date 1192699490 -3600
# Node ID 46a7c9a15b0f1028105b919a236197db1baa611a
# Parent  2173fe77dcd216dc278a43f59430915a5b53180d
x86, vt-d: Fail PCI device assignment if device already assigned.
Signed-off-by: Weidong Han <weidong.han@xxxxxxxxx>
---
 xen/arch/x86/domctl.c                  |   12 ++++++++----
 xen/arch/x86/hvm/vmx/vtd/intel-iommu.c |   15 +++++++++++++++
 xen/include/asm-x86/iommu.h            |    1 +
 3 files changed, 24 insertions(+), 4 deletions(-)

diff -r 2173fe77dcd2 -r 46a7c9a15b0f xen/arch/x86/domctl.c
--- a/xen/arch/x86/domctl.c     Thu Oct 18 09:59:20 2007 +0100
+++ b/xen/arch/x86/domctl.c     Thu Oct 18 10:24:50 2007 +0100
@@ -531,10 +531,10 @@ long arch_do_domctl(
         struct hvm_iommu *hd;
         u8 bus, devfn;
 
-        if (!vtd_enabled)
-            break;
-
-        ret = -EINVAL;
+        ret = -EINVAL;
+        if ( !vtd_enabled )
+            break;
+
         if ( unlikely((d = get_domain_by_id(domctl->domain)) == NULL) ) {
             gdprintk(XENLOG_ERR,
                 "XEN_DOMCTL_assign_device: get_domain_by_id() failed\n"); 
@@ -543,6 +543,10 @@ long arch_do_domctl(
         hd = domain_hvm_iommu(d);
         bus = (domctl->u.assign_device.machine_bdf >> 16) & 0xff;
         devfn = (domctl->u.assign_device.machine_bdf >> 8) & 0xff;
+
+        if ( device_assigned(bus, devfn) )
+            break;
+
         ret = assign_device(d, bus, devfn);
         gdprintk(XENLOG_ERR, "XEN_DOMCTL_assign_device: bdf = %x:%x:%x\n",
             bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
diff -r 2173fe77dcd2 -r 46a7c9a15b0f xen/arch/x86/hvm/vmx/vtd/intel-iommu.c
--- a/xen/arch/x86/hvm/vmx/vtd/intel-iommu.c    Thu Oct 18 09:59:20 2007 +0100
+++ b/xen/arch/x86/hvm/vmx/vtd/intel-iommu.c    Thu Oct 18 10:24:50 2007 +0100
@@ -1813,6 +1813,21 @@ int iommu_setup(void)
     return -EIO;
 }
 
+/*
+ * If the device isn't owned by dom0, it means it already
+ * has been assigned to other domain, or it's not exist.
+ */
+int device_assigned(u8 bus, u8 devfn)
+{
+    struct pci_dev *pdev;
+
+    for_each_pdev( dom0, pdev )
+        if ( (pdev->bus == bus ) && (pdev->devfn == devfn) )
+            return 0;
+
+    return 1;
+}
+
 int assign_device(struct domain *d, u8 bus, u8 devfn)
 {
     struct hvm_iommu *hd  = domain_hvm_iommu(d);
diff -r 2173fe77dcd2 -r 46a7c9a15b0f xen/include/asm-x86/iommu.h
--- a/xen/include/asm-x86/iommu.h       Thu Oct 18 09:59:20 2007 +0100
+++ b/xen/include/asm-x86/iommu.h       Thu Oct 18 10:24:50 2007 +0100
@@ -69,6 +69,7 @@ int iommu_setup(void);
 int iommu_setup(void);
 int iommu_domain_init(struct domain *d);
 void iommu_domain_destroy(struct domain *d);
+int device_assigned(u8 bus, u8 devfn);
 int assign_device(struct domain *d, u8 bus, u8 devfn);
 int iommu_map_page(struct domain *d, dma_addr_t gfn, dma_addr_t mfn);
 int iommu_unmap_page(struct domain *d, dma_addr_t gfn);

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.