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

[Xen-changelog] [xen-unstable] passthrough: update bus2bridge mapping as PCI devices get added/removed



# HG changeset patch
# User Jan Beulich <jbeulich@xxxxxxxx>
# Date 1318231292 -7200
# Node ID 0b81515b8e982e8012c28e5f8d9e965c63b6503d
# Parent  0c2bfd1f9c6822fbd23af0043f83d93be976323c
passthrough: update bus2bridge mapping as PCI devices get added/removed

This deals with two limitations at once: On device removal, the
mapping did not get updated so far at all, and hotplugged devices as
well as such not discoverable by Xen's initial bus scan (including the
case where a non-zero PCI segment wasn't accessible during Xen boot,
but became accessible after Dom0 validated access information against
ACPI data) wouldn't cause updates to the mapping either.

Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
Acked-by: "Kay, Allen M" <allen.m.kay@xxxxxxxxx>
---


diff -r 0c2bfd1f9c68 -r 0b81515b8e98 xen/drivers/passthrough/pci.c
--- a/xen/drivers/passthrough/pci.c     Fri Oct 07 17:57:07 2011 +0200
+++ b/xen/drivers/passthrough/pci.c     Mon Oct 10 09:21:32 2011 +0200
@@ -132,11 +132,67 @@
     list_add(&pdev->alldevs_list, &pseg->alldevs_list);
     spin_lock_init(&pdev->msix_table_lock);
 
+    /* update bus2bridge */
+    switch ( pdev_type(pseg->nr, bus, devfn) )
+    {
+        u8 sec_bus, sub_bus;
+
+        case DEV_TYPE_PCIe_BRIDGE:
+            break;
+
+        case DEV_TYPE_PCIe2PCI_BRIDGE:
+        case DEV_TYPE_LEGACY_PCI_BRIDGE:
+            sec_bus = pci_conf_read8(pseg->nr, bus, PCI_SLOT(devfn),
+                                     PCI_FUNC(devfn), PCI_SECONDARY_BUS);
+            sub_bus = pci_conf_read8(pseg->nr, bus, PCI_SLOT(devfn),
+                                     PCI_FUNC(devfn), PCI_SUBORDINATE_BUS);
+
+            spin_lock(&pseg->bus2bridge_lock);
+            for ( ; sec_bus <= sub_bus; sec_bus++ )
+            {
+                pseg->bus2bridge[sec_bus].map = 1;
+                pseg->bus2bridge[sec_bus].bus = bus;
+                pseg->bus2bridge[sec_bus].devfn = devfn;
+            }
+            spin_unlock(&pseg->bus2bridge_lock);
+            break;
+
+        case DEV_TYPE_PCIe_ENDPOINT:
+        case DEV_TYPE_PCI:
+            break;
+
+        default:
+            printk(XENLOG_WARNING "%s: unknown type: %04x:%02x:%02x.%u\n",
+                   __func__, pseg->nr, bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
+            break;
+    }
+
     return pdev;
 }
 
-static void free_pdev(struct pci_dev *pdev)
+static void free_pdev(struct pci_seg *pseg, struct pci_dev *pdev)
 {
+    /* update bus2bridge */
+    switch ( pdev_type(pseg->nr, pdev->bus, pdev->devfn) )
+    {
+        u8 dev, func, sec_bus, sub_bus;
+
+        case DEV_TYPE_PCIe2PCI_BRIDGE:
+        case DEV_TYPE_LEGACY_PCI_BRIDGE:
+            dev = PCI_SLOT(pdev->devfn);
+            func = PCI_FUNC(pdev->devfn);
+            sec_bus = pci_conf_read8(pseg->nr, pdev->bus, dev, func,
+                                     PCI_SECONDARY_BUS);
+            sub_bus = pci_conf_read8(pseg->nr, pdev->bus, dev, func,
+                                     PCI_SUBORDINATE_BUS);
+
+            spin_lock(&pseg->bus2bridge_lock);
+            for ( ; sec_bus <= sub_bus; sec_bus++ )
+                pseg->bus2bridge[sec_bus] = pseg->bus2bridge[pdev->bus];
+            spin_unlock(&pseg->bus2bridge_lock);
+            break;
+    }
+
     list_del(&pdev->alldevs_list);
     xfree(pdev);
 }
@@ -380,7 +436,7 @@
             if ( pdev->domain )
                 list_del(&pdev->domain_list);
             pci_cleanup_msi(pdev);
-            free_pdev(pdev);
+            free_pdev(pseg, pdev);
             printk(XENLOG_DEBUG "PCI remove device %04x:%02x:%02x.%u\n",
                    seg, bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
             break;
@@ -548,8 +604,6 @@
 {
     struct pci_dev *pdev;
     int bus, dev, func;
-    u8 sec_bus, sub_bus;
-    int type;
 
     for ( bus = 0; bus < 256; bus++ )
     {
@@ -567,41 +621,6 @@
                     return -ENOMEM;
                 }
 
-                /* build bus2bridge */
-                type = pdev_type(pseg->nr, bus, PCI_DEVFN(dev, func));
-                switch ( type )
-                {
-                    case DEV_TYPE_PCIe_BRIDGE:
-                        break;
-
-                    case DEV_TYPE_PCIe2PCI_BRIDGE:
-                    case DEV_TYPE_LEGACY_PCI_BRIDGE:
-                        sec_bus = pci_conf_read8(pseg->nr, bus, dev, func,
-                                                 PCI_SECONDARY_BUS);
-                        sub_bus = pci_conf_read8(pseg->nr, bus, dev, func,
-                                                 PCI_SUBORDINATE_BUS);
-
-                        spin_lock(&pseg->bus2bridge_lock);
-                        for ( sub_bus &= 0xff; sec_bus <= sub_bus; sec_bus++ )
-                        {
-                            pseg->bus2bridge[sec_bus].map = 1;
-                            pseg->bus2bridge[sec_bus].bus = bus;
-                            pseg->bus2bridge[sec_bus].devfn =
-                                PCI_DEVFN(dev, func);
-                        }
-                        spin_unlock(&pseg->bus2bridge_lock);
-                        break;
-
-                    case DEV_TYPE_PCIe_ENDPOINT:
-                    case DEV_TYPE_PCI:
-                        break;
-
-                    default:
-                        printk("%s: unknown type: %04x:%02x:%02x.%u\n",
-                               __func__, pseg->nr, bus, dev, func);
-                        return -EINVAL;
-                }
-
                 if ( !func && !(pci_conf_read8(pseg->nr, bus, dev, func,
                                                PCI_HEADER_TYPE) & 0x80) )
                     break;

_______________________________________________
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®.