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@
This commit is contained in:
parent
e625c10b2f
commit
b100acf254
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=265211
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -1260,6 +1260,13 @@ pci_write_dsdt(void)
|
||||
pci_bus_write_dsdt(bus);
|
||||
}
|
||||
|
||||
int
|
||||
pci_bus_configured(int bus)
|
||||
{
|
||||
assert(bus >= 0 && bus < MAXBUSES);
|
||||
return (pci_businfo[bus] != NULL);
|
||||
}
|
||||
|
||||
int
|
||||
pci_msi_enabled(struct pci_devinst *pi)
|
||||
{
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user