diff --git a/usr.sbin/bhyve/aarch64/bhyverun_machdep.c b/usr.sbin/bhyve/aarch64/bhyverun_machdep.c --- a/usr.sbin/bhyve/aarch64/bhyverun_machdep.c +++ b/usr.sbin/bhyve/aarch64/bhyverun_machdep.c @@ -82,6 +82,14 @@ set_config_bool("acpi_tables", false); set_config_bool("acpi_tables_in_memory", false); set_config_value("memory.size", "256M"); + + /* + * At least U-Boot (re-)maps BARs during device initialization. Our PCI + * emulation doesn't really handle the case where the guest creates a + * BAR mapping that overlaps with an existing one. The simplest thing + * to do is to let the boot firmware handle BAR mapping on its own. + */ + set_config_bool("pci.enable_bars", false); } void 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/pci_emul.c b/usr.sbin/bhyve/pci_emul.c --- a/usr.sbin/bhyve/pci_emul.c +++ b/usr.sbin/bhyve/pci_emul.c @@ -859,17 +859,18 @@ * updated as early as possible. */ uint16_t enbit = 0; - switch (type) { - case PCIBAR_IO: - enbit = PCIM_CMD_PORTEN; - break; - case PCIBAR_MEM64: - case PCIBAR_MEM32: - enbit = PCIM_CMD_MEMEN; - break; - default: - enbit = 0; - break; + if (get_config_bool_default("pci.enable_bars", true)) { + switch (type) { + case PCIBAR_IO: + enbit = PCIM_CMD_PORTEN; + break; + case PCIBAR_MEM64: + case PCIBAR_MEM32: + enbit = PCIM_CMD_MEMEN; + break; + default: + break; + } } const uint16_t cmd = pci_get_cfgdata16(pdi, PCIR_COMMAND); @@ -966,8 +967,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);