aboutsummaryrefslogtreecommitdiff
path: root/usr.sbin/bhyve
diff options
context:
space:
mode:
authorNeel Natu <neel@FreeBSD.org>2014-05-02 04:51:31 +0000
committerNeel Natu <neel@FreeBSD.org>2014-05-02 04:51:31 +0000
commitb100acf254bfe7f5003e82da2578bd1f2f84cdbf (patch)
treeaae235f673e52c713a898487b927d4f39717a21a /usr.sbin/bhyve
parente625c10b2fd07fd8ad45a118cbe14448b8beff98 (diff)
downloadsrc-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.82
-rw-r--r--usr.sbin/bhyve/bhyverun.c15
-rw-r--r--usr.sbin/bhyve/mptbl.c19
-rw-r--r--usr.sbin/bhyve/pci_emul.c7
-rw-r--r--usr.sbin/bhyve/pci_emul.h1
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)