From: Arbel Moshe <arbel.moshe(a)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(a)oracle.com>
Reviewed-by: Mark Kanda <mark.kanda(a)oracle.com>
Signed-off-by: Arbel Moshe <arbel.moshe(a)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)
--
2.16.1