summaryrefslogtreecommitdiffstats
path: root/usr.sbin/bhyve/mptbl.c
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2014-07-19 20:13:01 +0000
committerjhb <jhb@FreeBSD.org>2014-07-19 20:13:01 +0000
commitba55949ac368dc3605b73d26161b12730d968366 (patch)
tree14ce13f86ce1c95121b57eb76e4eff1c81e7c80e /usr.sbin/bhyve/mptbl.c
parent86c94c699f2cd2707dc9074cbcd07956fe44394b (diff)
downloadFreeBSD-src-ba55949ac368dc3605b73d26161b12730d968366.zip
FreeBSD-src-ba55949ac368dc3605b73d26161b12730d968366.tar.gz
MFC 261904,261905,262143,262184,264921,265211,267169,267292,267294:
Various PCI fixes: - Allow PCI devices to be configured on all valid bus numbers from 0 to 255. - Tweak the handling of PCI capabilities in emulated devices to remove the non-standard zero capability list terminator. - Add a check to validate that memory BARs of passthru devices are 4KB aligned. - Respect and track the enable bit in the PCI configuration address word. - Handle quad-word access to 32-bit register pairs.
Diffstat (limited to 'usr.sbin/bhyve/mptbl.c')
-rw-r--r--usr.sbin/bhyve/mptbl.c35
1 files changed, 28 insertions, 7 deletions
diff --git a/usr.sbin/bhyve/mptbl.c b/usr.sbin/bhyve/mptbl.c
index 3608efa..4c2167e 100644
--- a/usr.sbin/bhyve/mptbl.c
+++ b/usr.sbin/bhyve/mptbl.c
@@ -196,16 +196,21 @@ mpt_build_ioapic_entries(io_apic_entry_ptr mpei, int id)
static int
mpt_count_ioint_entries(void)
{
+ int bus, count;
+
+ count = 0;
+ for (bus = 0; bus <= PCI_BUSMAX; bus++)
+ count += pci_count_lintr(bus);
/*
* Always include entries for the first 16 pins along with a entry
* for each active PCI INTx pin.
*/
- return (16 + pci_count_lintr());
+ return (16 + count);
}
static void
-mpt_generate_pci_int(int slot, int pin, int ioapic_irq, void *arg)
+mpt_generate_pci_int(int bus, int slot, int pin, int ioapic_irq, void *arg)
{
int_entry_ptr *mpiep, mpie;
@@ -219,7 +224,7 @@ mpt_generate_pci_int(int slot, int pin, int ioapic_irq, void *arg)
*/
mpie->type = MPCT_ENTRY_INT;
mpie->int_type = INTENTRY_TYPE_INT;
- mpie->src_bus_id = 0;
+ mpie->src_bus_id = bus;
mpie->src_bus_irq = slot << 2 | (pin - 1);
mpie->dst_apic_id = mpie[-1].dst_apic_id;
mpie->dst_apic_int = ioapic_irq;
@@ -230,7 +235,7 @@ mpt_generate_pci_int(int slot, int pin, int ioapic_irq, void *arg)
static void
mpt_build_ioint_entries(int_entry_ptr mpie, int id)
{
- int pin;
+ int pin, bus;
/*
* The following config is taken from kernel mptable.c
@@ -277,7 +282,8 @@ mpt_build_ioint_entries(int_entry_ptr mpie, int id)
}
/* Next, generate entries for any PCI INTx interrupts. */
- pci_walk_lintr(mpt_generate_pci_int, &mpie);
+ for (bus = 0; bus <= PCI_BUSMAX; bus++)
+ pci_walk_lintr(bus, mpt_generate_pci_int, &mpie);
}
void
@@ -297,16 +303,31 @@ mptable_build(struct vmctx *ctx, int ncpu)
proc_entry_ptr mpep;
mpfps_t mpfp;
int_entry_ptr mpie;
- int ioints;
+ int ioints, bus;
char *curraddr;
char *startaddr;
startaddr = paddr_guest2host(ctx, MPTABLE_BASE, MPTABLE_MAX_LENGTH);
if (startaddr == NULL) {
- printf("mptable requires mapped mem\n");
+ fprintf(stderr, "mptable requires mapped mem\n");
return (ENOMEM);
}
+ /*
+ * There is no way to advertise multiple PCI hierarchies via MPtable
+ * so require that there is no PCI hierarchy with a non-zero bus
+ * number.
+ */
+ for (bus = 1; bus <= PCI_BUSMAX; bus++) {
+ if (pci_bus_configured(bus)) {
+ fprintf(stderr, "MPtable is incompatible with "
+ "multiple PCI hierarchies.\r\n");
+ fprintf(stderr, "MPtable generation can be disabled "
+ "by passing the -Y option to bhyve(8).\r\n");
+ return (EINVAL);
+ }
+ }
+
curraddr = startaddr;
mpfp = (mpfps_t)curraddr;
mpt_build_mpfp(mpfp, MPTABLE_BASE);
OpenPOWER on IntegriCloud