diff options
author | Neel Natu <neel@FreeBSD.org> | 2014-05-02 04:51:31 +0000 |
---|---|---|
committer | Neel Natu <neel@FreeBSD.org> | 2014-05-02 04:51:31 +0000 |
commit | b100acf254bfe7f5003e82da2578bd1f2f84cdbf (patch) | |
tree | aae235f673e52c713a898487b927d4f39717a21a /usr.sbin/bhyve | |
parent | e625c10b2fd07fd8ad45a118cbe14448b8beff98 (diff) | |
download | src-b100acf254bfe7f5003e82da2578bd1f2f84cdbf.tar.gz src-b100acf254bfe7f5003e82da2578bd1f2f84cdbf.zip |
Don't allow MPtable generation if there are multiple PCI hierarchies. This is
because there isn't a standard way to relay this information to the guest OS.
Add a command line option "-Y" to bhyve(8) to inhibit MPtable generation.
If the virtual machine is using PCI devices on buses other than 0 then it can
still use ACPI tables to convey this information to the guest.
Discussed with: grehan@
Notes
Notes:
svn path=/head/; revision=265211
Diffstat (limited to 'usr.sbin/bhyve')
-rw-r--r-- | usr.sbin/bhyve/bhyve.8 | 2 | ||||
-rw-r--r-- | usr.sbin/bhyve/bhyverun.c | 15 | ||||
-rw-r--r-- | usr.sbin/bhyve/mptbl.c | 19 | ||||
-rw-r--r-- | usr.sbin/bhyve/pci_emul.c | 7 | ||||
-rw-r--r-- | usr.sbin/bhyve/pci_emul.h | 1 |
5 files changed, 39 insertions, 5 deletions
diff --git a/usr.sbin/bhyve/bhyve.8 b/usr.sbin/bhyve/bhyve.8 index 88e72142b2ca..98062b7805f5 100644 --- a/usr.sbin/bhyve/bhyve.8 +++ b/usr.sbin/bhyve/bhyve.8 @@ -236,6 +236,8 @@ This is intended for debug purposes. Ignore accesses to unimplemented Model Specific Registers (MSRs). This is intended for debug purposes. .It Fl x The guest's local APIC is configured in x2APIC mode. +.It Fl Y +Disable MPtable generation. .It Fl h Print help message and exit. .It Ar vmname diff --git a/usr.sbin/bhyve/bhyverun.c b/usr.sbin/bhyve/bhyverun.c index b54e7148d943..ede7ab56169d 100644 --- a/usr.sbin/bhyve/bhyverun.c +++ b/usr.sbin/bhyve/bhyverun.c @@ -145,6 +145,7 @@ usage(int code) " -m: memory size in MB\n" " -w: ignore unimplemented MSRs\n" " -x: local apic is in x2APIC mode\n" + " -Y: disable MPtable generation\n" " -U: uuid\n", progname, (int)strlen(progname), ""); @@ -616,7 +617,7 @@ int main(int argc, char *argv[]) { int c, error, gdb_port, err, bvmcons; - int max_vcpus; + int max_vcpus, mptgen; struct vmctx *ctx; uint64_t rip; size_t memsize; @@ -626,8 +627,9 @@ main(int argc, char *argv[]) gdb_port = 0; guest_ncpus = 1; memsize = 256 * MB; + mptgen = 1; - while ((c = getopt(argc, argv, "abehwxAHIPWp:g:c:s:m:l:U:")) != -1) { + while ((c = getopt(argc, argv, "abehwxAHIPWYp:g:c:s:m:l:U:")) != -1) { switch (c) { case 'a': x2apic_mode = 0; @@ -693,6 +695,9 @@ main(int argc, char *argv[]) case 'x': x2apic_mode = 1; break; + case 'Y': + mptgen = 0; + break; case 'h': usage(0); default: @@ -752,7 +757,11 @@ main(int argc, char *argv[]) /* * build the guest tables, MP etc. */ - mptable_build(ctx, guest_ncpus); + if (mptgen) { + error = mptable_build(ctx, guest_ncpus); + if (error) + exit(1); + } error = smbios_build(ctx); assert(error == 0); diff --git a/usr.sbin/bhyve/mptbl.c b/usr.sbin/bhyve/mptbl.c index e8958359adb6..4c2167e98c85 100644 --- a/usr.sbin/bhyve/mptbl.c +++ b/usr.sbin/bhyve/mptbl.c @@ -303,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); diff --git a/usr.sbin/bhyve/pci_emul.c b/usr.sbin/bhyve/pci_emul.c index 15f2fad53485..5b87da7f0604 100644 --- a/usr.sbin/bhyve/pci_emul.c +++ b/usr.sbin/bhyve/pci_emul.c @@ -1261,6 +1261,13 @@ pci_write_dsdt(void) } int +pci_bus_configured(int bus) +{ + assert(bus >= 0 && bus < MAXBUSES); + return (pci_businfo[bus] != NULL); +} + +int pci_msi_enabled(struct pci_devinst *pi) { return (pi->pi_msi.enabled); diff --git a/usr.sbin/bhyve/pci_emul.h b/usr.sbin/bhyve/pci_emul.h index 7ad0a5d1f6b2..e1040a8b715a 100644 --- a/usr.sbin/bhyve/pci_emul.h +++ b/usr.sbin/bhyve/pci_emul.h @@ -233,6 +233,7 @@ uint64_t pci_emul_msix_tread(struct pci_devinst *pi, uint64_t offset, int size); int pci_count_lintr(int bus); void pci_walk_lintr(int bus, pci_lintr_cb cb, void *arg); void pci_write_dsdt(void); +int pci_bus_configured(int bus); static __inline void pci_set_cfgdata8(struct pci_devinst *pi, int offset, uint8_t val) |