From: Arbel Moshe arbel.moshe@oracle.com
This reverts commit 3c3a3fa6522f ("mptable: Don't describe pci-to-pci bridges.”)
The reverted commit removed the description of non-root PCI busses from the MPTable in claim they are not necessary.
However, it seems that some guests rely on this information in order to correclty configure IOAPIC redirection-table entries for interrupts originated from PCI devices on non-root PCI busses.
One such guest is "Extreme Networks OS". We observed that if this guest is setup with an E1000 NIC behind a PCI bridge, the OS wouldn't configure the IOAPIC redirection-table entry for the IRQ that the E1000 PIN is connected to. Therefore, interrupts from the NIC were not delivered to OS which caused guest to not have network connectivity.
Fixes: 3c3a3fa6522f ("mptable: Don't describe pci-to-pci bridges.”)
Reviewed-by: Liran Alon liran.alon@oracle.com Reviewed-by: Mark Kanda mark.kanda@oracle.com Signed-off-by: Arbel Moshe arbel.moshe@oracle.com --- src/fw/mptable.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-)
diff --git a/src/fw/mptable.c b/src/fw/mptable.c index 47385cc5d32d..27686369e98c 100644 --- a/src/fw/mptable.c +++ b/src/fw/mptable.c @@ -72,25 +72,30 @@ mptable_setup(void) } int entrycount = cpu - cpus;
- // PCI bus + // PCI buses struct mpt_bus *buses = (void*)cpu, *bus = buses; - if (!hlist_empty(&PCIDevices)) { + int lastbus = -1; + struct pci_device *pci; + foreachpci(pci) { + int curbus = pci_bdf_to_bus(pci->bdf); + if (curbus == lastbus) + continue; + lastbus = curbus; memset(bus, 0, sizeof(*bus)); bus->type = MPT_TYPE_BUS; - bus->busid = 0; + bus->busid = curbus; memcpy(bus->bustype, "PCI ", sizeof(bus->bustype)); bus++; - entrycount++; }
/* isa bus */ - int isabusid = bus - buses; + int isabusid; memset(bus, 0, sizeof(*bus)); bus->type = MPT_TYPE_BUS; - bus->busid = isabusid; + isabusid = bus->busid = lastbus + 1; memcpy(bus->bustype, "ISA ", sizeof(bus->bustype)); bus++; - entrycount++; + entrycount += bus - buses;
/* ioapic */ u8 ioapic_id = BUILD_IOAPIC_ID; @@ -108,11 +113,8 @@ mptable_setup(void) int dev = -1; unsigned short pinmask = 0;
- struct pci_device *pci; foreachpci(pci) { u16 bdf = pci->bdf; - if (pci_bdf_to_bus(bdf) != 0) - break; int pin = pci_config_readb(bdf, PCI_INTERRUPT_PIN); int irq = pci_config_readb(bdf, PCI_INTERRUPT_LINE); if (pin == 0)