# 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
|