WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] PCI multi-seg: Pass-through adjustments

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] PCI multi-seg: Pass-through adjustments
From: Xen patchbot-unstable <patchbot@xxxxxxx>
Date: Wed, 28 Sep 2011 02:55:12 +0100
Delivery-date: Tue, 27 Sep 2011 18:55:32 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Jan Beulich <jbeulich@xxxxxxxx>
# Date 1316712518 -3600
# Node ID 314b147d524d8a9fbf7fdebbb1648845b8c02379
# Parent  9e0259239822535680b88ab81cd9084238a29efb
PCI multi-seg: Pass-through adjustments

Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
---


diff -r 9e0259239822 -r 314b147d524d xen/drivers/passthrough/amd/pci_amd_iommu.c
--- a/xen/drivers/passthrough/amd/pci_amd_iommu.c       Thu Sep 22 18:28:03 
2011 +0100
+++ b/xen/drivers/passthrough/amd/pci_amd_iommu.c       Thu Sep 22 18:28:38 
2011 +0100
@@ -123,35 +123,17 @@
     spin_unlock_irqrestore(&iommu->lock, flags);
 }
 
-static void __init amd_iommu_setup_dom0_devices(struct domain *d)
+static void __init amd_iommu_setup_dom0_device(struct pci_dev *pdev)
 {
-    struct amd_iommu *iommu;
-    struct pci_dev *pdev;
-    int bus, devfn, bdf;
+    int bdf = (pdev->bus << 8) | pdev->devfn;
+    struct amd_iommu *iommu = find_iommu_for_device(pdev->seg, bdf);
 
-    spin_lock(&pcidevs_lock);
-    for ( bus = 0; bus < 256; bus++ )
-    {
-        for ( devfn = 0; devfn < 256; devfn++ )
-        {
-            pdev = pci_get_pdev(0, bus, devfn);
-            if ( !pdev )
-                continue;
-
-            pdev->domain = d;
-            list_add(&pdev->domain_list, &d->arch.pdev_list);
-
-            bdf = (bus << 8) | devfn;
-            iommu = find_iommu_for_device(pdev->seg, bdf);
-
-            if ( likely(iommu != NULL) )
-                amd_iommu_setup_domain_device(d, iommu, bdf);
-            else
-                AMD_IOMMU_DEBUG("No iommu for device %02x:%02x.%x\n",
-                                bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
-        }
-    }
-    spin_unlock(&pcidevs_lock);
+    if ( likely(iommu != NULL) )
+        amd_iommu_setup_domain_device(pdev->domain, iommu, bdf);
+    else
+        AMD_IOMMU_DEBUG("No iommu for device %04x:%02x:%02x.%u\n",
+                        pdev->seg, pdev->bus,
+                        PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn));
 }
 
 int __init amd_iov_detect(void)
@@ -279,7 +261,7 @@
         }
     }
 
-    amd_iommu_setup_dom0_devices(d);
+    setup_dom0_pci_devices(d, amd_iommu_setup_dom0_device);
 }
 
 static void amd_iommu_disable_domain_device(
diff -r 9e0259239822 -r 314b147d524d xen/drivers/passthrough/pci.c
--- a/xen/drivers/passthrough/pci.c     Thu Sep 22 18:28:03 2011 +0100
+++ b/xen/drivers/passthrough/pci.c     Thu Sep 22 18:28:38 2011 +0100
@@ -202,9 +202,7 @@
 void pci_enable_acs(struct pci_dev *pdev)
 {
     int pos;
-    u16 cap;
-    u16 ctrl;
-
+    u16 cap, ctrl, seg = pdev->seg;
     u8 bus = pdev->bus;
     u8 dev = PCI_SLOT(pdev->devfn);
     u8 func = PCI_FUNC(pdev->devfn);
@@ -212,7 +210,7 @@
     if ( !iommu_enabled )
         return;
 
-    pos = pci_find_ext_capability(0, bus, pdev->devfn, PCI_EXT_CAP_ID_ACS);
+    pos = pci_find_ext_capability(seg, bus, pdev->devfn, PCI_EXT_CAP_ID_ACS);
     if (!pos)
         return;
 
@@ -453,7 +451,7 @@
 
 #define PCI_CLASS_BRIDGE_PCI     0x0604
 
-int pdev_type(u8 bus, u8 devfn)
+int pdev_type(u16 seg, u8 bus, u8 devfn)
 {
     u16 class_device;
     u16 status, creg;
@@ -488,9 +486,9 @@
  * return 1: find PCIe-to-PCI/PCIX bridge or PCI legacy bridge
  * return -1: fail
  */
-int find_upstream_bridge(u8 *bus, u8 *devfn, u8 *secbus)
+int find_upstream_bridge(u16 seg, u8 *bus, u8 *devfn, u8 *secbus)
 {
-    struct pci_seg *pseg = get_pseg(0);
+    struct pci_seg *pseg = get_pseg(seg);
     int ret = 0;
     int cnt = 0;
 
@@ -525,7 +523,7 @@
 /*
  * detect pci device, return 0 if it exists, or return 0
  */
-int __init pci_device_detect(u8 bus, u8 dev, u8 func)
+int __init pci_device_detect(u16 seg, u8 bus, u8 dev, u8 func)
 {
     u32 vendor;
 
@@ -554,7 +552,7 @@
         {
             for ( func = 0; func < 8; func++ )
             {
-                if ( pci_device_detect(bus, dev, func) == 0 )
+                if ( pci_device_detect(pseg->nr, bus, dev, func) == 0 )
                     continue;
 
                 pdev = alloc_pdev(pseg, bus, PCI_DEVFN(dev, func));
@@ -565,7 +563,7 @@
                 }
 
                 /* build bus2bridge */
-                type = pdev_type(bus, PCI_DEVFN(dev, func));
+                type = pdev_type(pseg->nr, bus, PCI_DEVFN(dev, func));
                 switch ( type )
                 {
                     case DEV_TYPE_PCIe_BRIDGE:
@@ -594,8 +592,8 @@
                         break;
 
                     default:
-                        printk("%s: unknown type: bdf = %x:%x.%x\n",
-                               __func__, bus, dev, func);
+                        printk("%s: unknown type: %04x:%02x:%02x.%u\n",
+                               __func__, pseg->nr, bus, dev, func);
                         return -EINVAL;
                 }
 
@@ -620,6 +618,44 @@
     return ret;
 }
 
+struct setup_dom0 {
+    struct domain *d;
+    void (*handler)(struct pci_dev *);
+};
+
+static int __init _setup_dom0_pci_devices(struct pci_seg *pseg, void *arg)
+{
+    struct setup_dom0 *ctxt = arg;
+    int bus, devfn;
+
+    for ( bus = 0; bus < 256; bus++ )
+    {
+        for ( devfn = 0; devfn < 256; devfn++ )
+        {
+            struct pci_dev *pdev = pci_get_pdev(pseg->nr, bus, devfn);
+
+            if ( !pdev )
+                continue;
+
+            pdev->domain = ctxt->d;
+            list_add(&pdev->domain_list, &ctxt->d->arch.pdev_list);
+            ctxt->handler(pdev);
+        }
+    }
+
+    return 0;
+}
+
+void __init setup_dom0_pci_devices(
+    struct domain *d, void (*handler)(struct pci_dev *))
+{
+    struct setup_dom0 ctxt = { .d = d, .handler = handler };
+
+    spin_lock(&pcidevs_lock);
+    pci_segments_iterate(_setup_dom0_pci_devices, &ctxt);
+    spin_unlock(&pcidevs_lock);
+}
+
 /* Disconnect all PCI devices from the PCI buses. From the PCI spec:
  *   "When a 0 is written to [the COMMAND] register, the device is
  *    logically disconnected from the PCI bus for all accesses except
@@ -654,8 +690,9 @@
 
     list_for_each_entry ( pdev, &pseg->alldevs_list, alldevs_list )
     {
-        printk("%02x:%02x.%x - dom %-3d - MSIs < ",
-               pdev->bus, PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn),
+        printk("%04x:%02x:%02x.%u - dom %-3d - MSIs < ",
+               pseg->nr, pdev->bus,
+               PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn),
                pdev->domain ? pdev->domain->domain_id : -1);
         list_for_each_entry ( msi, &pdev->msi_list, list )
                printk("%d ", msi->irq);
diff -r 9e0259239822 -r 314b147d524d xen/drivers/passthrough/vtd/dmar.c
--- a/xen/drivers/passthrough/vtd/dmar.c        Thu Sep 22 18:28:03 2011 +0100
+++ b/xen/drivers/passthrough/vtd/dmar.c        Thu Sep 22 18:28:38 2011 +0100
@@ -457,11 +457,11 @@
             d = PCI_SLOT(dmaru->scope.devices[i]);
             f = PCI_FUNC(dmaru->scope.devices[i]);
 
-            if ( pci_device_detect(b, d, f) == 0 )
+            if ( pci_device_detect(drhd->segment, b, d, f) == 0 )
             {
                 dprintk(XENLOG_WARNING VTDPREFIX,
-                    "  Non-existent device (%x:%x.%x) is reported "
-                    "in this DRHD's scope!\n", b, d, f);
+                        " Non-existent device (%04x:%02x:%02x.%u) is reported"
+                        " in this DRHD's scope!\n", drhd->segment, b, d, f);
                 invalid_cnt++;
             }
         }
@@ -556,12 +556,13 @@
             d = PCI_SLOT(rmrru->scope.devices[i]);
             f = PCI_FUNC(rmrru->scope.devices[i]);
 
-            if ( pci_device_detect(b, d, f) == 0 )
+            if ( pci_device_detect(rmrr->segment, b, d, f) == 0 )
             {
                 dprintk(XENLOG_WARNING VTDPREFIX,
-                    "  Non-existent device (%x:%x.%x) is reported "
-                    "in RMRR (%"PRIx64", %"PRIx64")'s scope!\n",
-                    b, d, f, rmrru->base_address, rmrru->end_address);
+                        " Non-existent device (%04x:%02x:%02x.%u) is reported"
+                        " in RMRR (%"PRIx64", %"PRIx64")'s scope!\n",
+                        rmrr->segment, b, d, f,
+                        rmrru->base_address, rmrru->end_address);
                 ignore = 1;
             }
             else
diff -r 9e0259239822 -r 314b147d524d xen/drivers/passthrough/vtd/intremap.c
--- a/xen/drivers/passthrough/vtd/intremap.c    Thu Sep 22 18:28:03 2011 +0100
+++ b/xen/drivers/passthrough/vtd/intremap.c    Thu Sep 22 18:28:38 2011 +0100
@@ -448,15 +448,17 @@
 static void set_msi_source_id(struct pci_dev *pdev, struct iremap_entry *ire)
 {
     int type;
+    u16 seg;
     u8 bus, devfn, secbus;
     int ret;
 
     if ( !pdev || !ire )
         return;
 
+    seg = pdev->seg;
     bus = pdev->bus;
     devfn = pdev->devfn;
-    type = pdev_type(bus, devfn);
+    type = pdev_type(seg, bus, devfn);
     switch ( type )
     {
     case DEV_TYPE_PCIe_BRIDGE:
@@ -469,7 +471,7 @@
         break;
 
     case DEV_TYPE_PCI:
-        ret = find_upstream_bridge(&bus, &devfn, &secbus);
+        ret = find_upstream_bridge(seg, &bus, &devfn, &secbus);
         if ( ret == 0 ) /* integrated PCI device */
         {
             set_ire_sid(ire, SVT_VERIFY_SID_SQ, SQ_ALL_16,
@@ -477,19 +479,20 @@
         }
         else if ( ret == 1 ) /* find upstream bridge */
         {
-            if ( pdev_type(bus, devfn) == DEV_TYPE_PCIe2PCI_BRIDGE )
+            if ( pdev_type(seg, bus, devfn) == DEV_TYPE_PCIe2PCI_BRIDGE )
                 set_ire_sid(ire, SVT_VERIFY_BUS, SQ_ALL_16,
                             (bus << 8) | pdev->bus);
-            else if ( pdev_type(bus, devfn) == DEV_TYPE_LEGACY_PCI_BRIDGE )
+            else if ( pdev_type(seg, bus, devfn) == DEV_TYPE_LEGACY_PCI_BRIDGE 
)
                 set_ire_sid(ire, SVT_VERIFY_BUS, SQ_ALL_16,
                             PCI_BDF2(bus, devfn));
         }
         break;
 
     default:
-        dprintk(XENLOG_WARNING VTDPREFIX, "d%d: unknown(%u): bdf = %x:%x.%x\n",
+        dprintk(XENLOG_WARNING VTDPREFIX,
+                "d%d: unknown(%u): %04x:%02x:%02x.%u\n",
                 pdev->domain->domain_id, type,
-                bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
+                seg, bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
         break;
    }
 }
diff -r 9e0259239822 -r 314b147d524d xen/drivers/passthrough/vtd/iommu.c
--- a/xen/drivers/passthrough/vtd/iommu.c       Thu Sep 22 18:28:03 2011 +0100
+++ b/xen/drivers/passthrough/vtd/iommu.c       Thu Sep 22 18:28:38 2011 +0100
@@ -50,7 +50,7 @@
 
 int nr_iommus;
 
-static void setup_dom0_devices(struct domain *d);
+static void setup_dom0_device(struct pci_dev *);
 static void setup_dom0_rmrr(struct domain *d);
 
 static int domain_iommu_domid(struct domain *d,
@@ -1234,7 +1234,7 @@
         iommu_set_dom0_mapping(d);
     }
 
-    setup_dom0_devices(d);
+    setup_dom0_pci_devices(d, setup_dom0_device);
     setup_dom0_rmrr(d);
 
     iommu_flush_all();
@@ -1402,7 +1402,7 @@
 
     ASSERT(spin_is_locked(&pcidevs_lock));
 
-    type = pdev_type(bus, devfn);
+    type = pdev_type(seg, bus, devfn);
     switch ( type )
     {
     case DEV_TYPE_PCIe_BRIDGE:
@@ -1431,7 +1431,7 @@
         if ( ret )
             break;
 
-        if ( find_upstream_bridge(&bus, &devfn, &secbus) < 1 )
+        if ( find_upstream_bridge(seg, &bus, &devfn, &secbus) < 1 )
             break;
 
         ret = domain_context_mapping_one(domain, drhd->iommu, bus, devfn);
@@ -1441,7 +1441,7 @@
          * requester-id. It may originate from devfn=0 on the secondary bus
          * behind the bridge. Map that id as well if we didn't already.
          */
-        if ( !ret && pdev_type(bus, devfn) == DEV_TYPE_PCIe2PCI_BRIDGE &&
+        if ( !ret && pdev_type(seg, bus, devfn) == DEV_TYPE_PCIe2PCI_BRIDGE &&
              (secbus != pdev->bus || pdev->devfn != 0) )
             ret = domain_context_mapping_one(domain, drhd->iommu, secbus, 0);
 
@@ -1533,7 +1533,7 @@
         return -ENODEV;
     iommu = drhd->iommu;
 
-    type = pdev_type(bus, devfn);
+    type = pdev_type(seg, bus, devfn);
     switch ( type )
     {
     case DEV_TYPE_PCIe_BRIDGE:
@@ -1562,11 +1562,11 @@
 
         tmp_bus = bus;
         tmp_devfn = devfn;
-        if ( find_upstream_bridge(&tmp_bus, &tmp_devfn, &secbus) < 1 )
+        if ( find_upstream_bridge(seg, &tmp_bus, &tmp_devfn, &secbus) < 1 )
             break;
 
         /* PCIe to PCI/PCIx bridge */
-        if ( pdev_type(tmp_bus, tmp_devfn) == DEV_TYPE_PCIe2PCI_BRIDGE )
+        if ( pdev_type(seg, tmp_bus, tmp_devfn) == DEV_TYPE_PCIe2PCI_BRIDGE )
         {
             ret = domain_context_unmap_one(domain, iommu, tmp_bus, tmp_devfn);
             if ( ret )
@@ -1939,28 +1939,11 @@
                                 pdev->devfn);
 }
 
-static void __init setup_dom0_devices(struct domain *d)
+static void __init setup_dom0_device(struct pci_dev *pdev)
 {
-    struct pci_dev *pdev;
-    int bus, devfn;
-
-    spin_lock(&pcidevs_lock);
-    for ( bus = 0; bus < 256; bus++ )
-    {
-        for ( devfn = 0; devfn < 256; devfn++ )
-        {
-            pdev = pci_get_pdev(0, bus, devfn);
-            if ( !pdev )
-                continue;
-
-            pdev->domain = d;
-            list_add(&pdev->domain_list, &d->arch.pdev_list);
-            domain_context_mapping(d, pdev->seg, pdev->bus, pdev->devfn);
-            pci_enable_acs(pdev);
-            pci_vtd_quirk(pdev);
-        }
-    }
-    spin_unlock(&pcidevs_lock);
+    domain_context_mapping(pdev->domain, pdev->seg, pdev->bus, pdev->devfn);
+    pci_enable_acs(pdev);
+    pci_vtd_quirk(pdev);
 }
 
 void clear_fault_bits(struct iommu *iommu)
@@ -2227,7 +2210,7 @@
 static int intel_iommu_group_id(u16 seg, u8 bus, u8 devfn)
 {
     u8 secbus;
-    if ( find_upstream_bridge(&bus, &devfn, &secbus) < 0 )
+    if ( find_upstream_bridge(seg, &bus, &devfn, &secbus) < 0 )
         return -1;
     else
         return PCI_BDF2(bus, devfn);
diff -r 9e0259239822 -r 314b147d524d xen/include/xen/pci.h
--- a/xen/include/xen/pci.h     Thu Sep 22 18:28:03 2011 +0100
+++ b/xen/include/xen/pci.h     Thu Sep 22 18:28:38 2011 +0100
@@ -82,13 +82,15 @@
     DEV_TYPE_PCI,
 };
 
-int pci_device_detect(u8 bus, u8 dev, u8 func);
+int pci_device_detect(u16 seg, u8 bus, u8 dev, u8 func);
 int scan_pci_devices(void);
-int pdev_type(u8 bus, u8 devfn);
-int find_upstream_bridge(u8 *bus, u8 *devfn, u8 *secbus);
-struct pci_dev *pci_lock_pdev(int bus, int devfn);
-struct pci_dev *pci_lock_domain_pdev(struct domain *d, int bus, int devfn);
+int pdev_type(u16 seg, u8 bus, u8 devfn);
+int find_upstream_bridge(u16 seg, u8 *bus, u8 *devfn, u8 *secbus);
+struct pci_dev *pci_lock_pdev(int seg, int bus, int devfn);
+struct pci_dev *pci_lock_domain_pdev(
+    struct domain *, int seg, int bus, int devfn);
 
+void setup_dom0_pci_devices(struct domain *, void (*)(struct pci_dev *));
 void pci_release_devices(struct domain *d);
 int pci_add_segment(u16 seg);
 int pci_add_device(u16 seg, u8 bus, u8 devfn, const struct pci_dev_info *);

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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] PCI multi-seg: Pass-through adjustments, Xen patchbot-unstable <=