diff --git a/usr.sbin/bhyve/amd64/bhyverun_machdep.c b/usr.sbin/bhyve/amd64/bhyverun_machdep.c --- a/usr.sbin/bhyve/amd64/bhyverun_machdep.c +++ b/usr.sbin/bhyve/amd64/bhyverun_machdep.c @@ -37,6 +37,7 @@ #include "acpi.h" #include "atkbdc.h" #include "bhyverun.h" +#include "bootrom.h" #include "config.h" #include "debug.h" #include "e820.h" @@ -291,7 +292,7 @@ int error; if (bsp) { - if (lpc_bootrom()) { + if (bootrom_boot()) { error = vm_set_capability(vcpu, VM_CAP_UNRESTRICTED_GUEST, 1); if (error != 0) { @@ -332,6 +333,9 @@ rtc_init(ctx); sci_init(ctx); error = e820_init(ctx); + if (error != 0) + return (error); + error = bootrom_loadrom(ctx); if (error != 0) return (error); @@ -355,7 +359,7 @@ if (error != 0) return (error); - if (lpc_bootrom() && strcmp(lpc_fwcfg(), "bhyve") == 0) + if (bootrom_boot() && strcmp(lpc_fwcfg(), "bhyve") == 0) fwctl_init(); if (get_config_bool("acpi_tables")) { diff --git a/usr.sbin/bhyve/amd64/ioapic.c b/usr.sbin/bhyve/amd64/ioapic.c --- a/usr.sbin/bhyve/amd64/ioapic.c +++ b/usr.sbin/bhyve/amd64/ioapic.c @@ -33,6 +33,7 @@ #include #include +#include "bootrom.h" #include "ioapic.h" #include "pci_emul.h" #include "pci_lpc.h" @@ -72,7 +73,7 @@ if (pci_pins == 0) return (-1); - if (lpc_bootrom()) { + if (bootrom_boot()) { /* For external bootrom use fixed mapping. */ return (16 + (4 + pi->pi_slot + pi->pi_lintr.pin) % 8); } diff --git a/usr.sbin/bhyve/amd64/pci_irq.c b/usr.sbin/bhyve/amd64/pci_irq.c --- a/usr.sbin/bhyve/amd64/pci_irq.c +++ b/usr.sbin/bhyve/amd64/pci_irq.c @@ -38,6 +38,7 @@ #include #include "acpi.h" +#include "bootrom.h" #include "inout.h" #include "ioapic.h" #include "pci_emul.h" @@ -205,7 +206,7 @@ pirq_cold = 0; - if (lpc_bootrom()) { + if (bootrom_boot()) { /* For external bootrom use fixed mapping. */ best_pin = (4 + pi->pi_slot + pi->pi_lintr.pin) % 8; } else { diff --git a/usr.sbin/bhyve/amd64/pci_lpc.h b/usr.sbin/bhyve/amd64/pci_lpc.h --- a/usr.sbin/bhyve/amd64/pci_lpc.h +++ b/usr.sbin/bhyve/amd64/pci_lpc.h @@ -69,7 +69,6 @@ void lpc_print_supported_devices(void); char *lpc_pirq_name(int pin); void lpc_pirq_routed(void); -const char *lpc_bootrom(void); const char *lpc_fwcfg(void); #endif diff --git a/usr.sbin/bhyve/amd64/pci_lpc.c b/usr.sbin/bhyve/amd64/pci_lpc.c --- a/usr.sbin/bhyve/amd64/pci_lpc.c +++ b/usr.sbin/bhyve/amd64/pci_lpc.c @@ -104,7 +104,7 @@ if (romfile == NULL) { errx(4, "invalid bootrom option \"%s\"", opts); } - set_config_value("lpc.bootrom", romfile); + set_config_value("bootrom", romfile); varfile = strsep(&str, ","); if (varfile == NULL) { @@ -112,7 +112,7 @@ goto done; } if (strchr(varfile, '=') == NULL) { - set_config_value("lpc.bootvars", varfile); + set_config_value("bootvars", varfile); } else { /* varfile doesn't exist, it's another config * option */ @@ -182,13 +182,6 @@ printf("%s\n", pctestdev_getname()); } -const char * -lpc_bootrom(void) -{ - - return (get_config_value("lpc.bootrom")); -} - const char * lpc_fwcfg(void) { @@ -256,14 +249,6 @@ const char *backend, *name; char *node_name; int unit, error; - const nvlist_t *nvl; - - nvl = find_config_node("lpc"); - if (nvl != NULL && nvlist_exists(nvl, "bootrom")) { - error = bootrom_loadrom(ctx, nvl); - if (error) - return (error); - } /* COM1 and COM2 */ for (unit = 0; unit < LPC_UART_NUM; unit++) { diff --git a/usr.sbin/bhyve/bhyve_config.5 b/usr.sbin/bhyve/bhyve_config.5 --- a/usr.sbin/bhyve/bhyve_config.5 +++ b/usr.sbin/bhyve/bhyve_config.5 @@ -23,7 +23,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd November 20, 2023 +.Dd May 1, 2024 .Dt BHYVE_CONFIG 5 .Os .Sh NAME @@ -146,6 +146,9 @@ This value only works when loaded with UEFI mode for VNC, and used a VNC client that don't support QEMU Extended Key Event Message (e.g. TightVNC). +.It Va pci.enable_bars Ta bool Ta Ta +Enable and map PCI BARs before executing any guest code. +This setting is false by default on arm64, and true by default on amd64. .It Va tpm.path Ta string Ta Ta Path to the host TPM device. This is typically /dev/tpm0. diff --git a/usr.sbin/bhyve/bhyverun.c b/usr.sbin/bhyve/bhyverun.c --- a/usr.sbin/bhyve/bhyverun.c +++ b/usr.sbin/bhyve/bhyverun.c @@ -524,12 +524,7 @@ reinit = false; -#ifdef __amd64__ - romboot = lpc_bootrom() != NULL; -#else - romboot = true; -#endif - + romboot = bootrom_boot(); error = vm_create(vmname); if (error) { if (errno == EEXIST) { diff --git a/usr.sbin/bhyve/bootrom.h b/usr.sbin/bhyve/bootrom.h --- a/usr.sbin/bhyve/bootrom.h +++ b/usr.sbin/bhyve/bootrom.h @@ -45,6 +45,7 @@ }; int bootrom_alloc(struct vmctx *ctx, size_t len, int prot, int flags, char **region_out, uint64_t *gpa_out); -int bootrom_loadrom(struct vmctx *ctx, const nvlist_t *nvl); +bool bootrom_boot(void); +int bootrom_loadrom(struct vmctx *ctx); #endif diff --git a/usr.sbin/bhyve/bootrom.c b/usr.sbin/bhyve/bootrom.c --- a/usr.sbin/bhyve/bootrom.c +++ b/usr.sbin/bhyve/bootrom.c @@ -192,7 +192,7 @@ } int -bootrom_loadrom(struct vmctx *ctx, const nvlist_t *nvl) +bootrom_loadrom(struct vmctx *ctx) { struct stat sbuf; ssize_t rlen; @@ -204,7 +204,7 @@ rv = -1; varfd = -1; - bootrom = get_config_value_node(nvl, "bootrom"); + bootrom = get_config_value("bootrom"); if (bootrom == NULL) { return (-1); } @@ -235,7 +235,7 @@ rom_size = sbuf.st_size; - varfile = get_config_value_node(nvl, "bootvars"); + varfile = get_config_value("bootvars"); var_size = 0; if (varfile != NULL) { varfd = open(varfile, O_RDWR); @@ -314,3 +314,12 @@ free(romfile); return (rv); } + +/* + * Are we relying on a bootrom to initialize the guest's CPU context? + */ +bool +bootrom_boot(void) +{ + return (get_config_value("bootrom") != NULL); +} diff --git a/usr.sbin/bhyve/pci_emul.c b/usr.sbin/bhyve/pci_emul.c --- a/usr.sbin/bhyve/pci_emul.c +++ b/usr.sbin/bhyve/pci_emul.c @@ -48,6 +48,7 @@ #include "acpi.h" #include "bhyverun.h" +#include "bootrom.h" #include "config.h" #include "debug.h" #ifdef __amd64__ @@ -853,6 +854,9 @@ TAILQ_INSERT_BEFORE(bar, new_bar, chain); } + if (bootrom_boot()) + return (0); + /* * pci_passthru devices synchronize their physical and virtual command * register on init. For that reason, the virtual cmd reg should be @@ -966,8 +970,19 @@ pci_set_cfgdata32(pdi, PCIR_BAR(idx + 1), bar >> 32); } - if (type != PCIBAR_ROM) { - register_bar(pdi, idx); + switch (type) { + case PCIBAR_IO: + if (porten(pdi)) + register_bar(pdi, idx); + break; + case PCIBAR_MEM32: + case PCIBAR_MEM64: + case PCIBAR_MEMHI64: + if (memen(pdi)) + register_bar(pdi, idx); + break; + default: + break; } return (0); @@ -1140,7 +1155,8 @@ pci_set_cfgdata8(pdi, PCIR_INTLINE, 255); pci_set_cfgdata8(pdi, PCIR_INTPIN, 0); - pci_set_cfgdata8(pdi, PCIR_COMMAND, PCIM_CMD_BUSMASTEREN); + if (!bootrom_boot()) + pci_set_cfgdata8(pdi, PCIR_COMMAND, PCIM_CMD_BUSMASTEREN); err = (*pde->pe_init)(pdi, fi->fi_config); if (err == 0)