Page MenuHomeFreeBSD

D38337.id117285.diff
No OneTemporary

D38337.id117285.diff

diff --git a/usr.sbin/bhyve/Makefile b/usr.sbin/bhyve/Makefile
--- a/usr.sbin/bhyve/Makefile
+++ b/usr.sbin/bhyve/Makefile
@@ -63,6 +63,7 @@
post.c \
ps2kbd.c \
ps2mouse.c \
+ qemu_fwcfg.c \
rfb.c \
rtc.c \
smbiostbl.c \
diff --git a/usr.sbin/bhyve/bhyve.8 b/usr.sbin/bhyve/bhyve.8
--- a/usr.sbin/bhyve/bhyve.8
+++ b/usr.sbin/bhyve/bhyve.8
@@ -200,7 +200,9 @@
.Cm com4 ,
the boot ROM device
.Cm bootrom ,
-and the debug/test device
+the
+.Cm fwcfg
+type and the debug/test device
.Cm pc-testdev .
.Pp
The possible values for the
@@ -345,7 +347,7 @@
.It Cm lpc
LPC PCI-ISA bridge with COM1, COM2, COM3, and COM4 16550 serial ports,
a boot ROM, and,
-optionally, the debug/test device.
+optionally, a fwcfg type and the debug/test device.
The LPC bridge emulation can only be configured on bus 0.
.It Cm fbuf
Raw framebuffer device attached to VNC server.
@@ -520,6 +522,20 @@
to that file.
.El
.Pp
+Fwcfg types:
+.Bl -tag -width 10n
+.It Ar fwcfg
+The fwcfg interface is used to pass informations like cpu core counts or acpi tables to the guest firmware.
+Supported values are "bhyve" and "qemu".
+Due to backward compatibility reasons, "bhyve" is the default option.
+When "bhyve" is used, bhyve's fwctl interface is used.
+It only reports the cpu core count to the guest firmware.
+The "qemu" option uses qemu's fwcfg interface.
+This interface is widely used and allows to pass user defined information.
+It's used for passing cpu core counts, acpi tables, a boot order and many other things to the guest.
+Some operating systems like Fedora CoreOS can be configured by qemu's fwcfg interface as well.
+.El
+.Pp
Pass-through device backends:
.Sm off
.Bl -bullet
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
@@ -259,6 +259,7 @@
.It Li lpc
LPC PCI-ISA bridge with COM1-COM4 16550 serial ports,
a boot ROM,
+an optional fwcfg type,
and an optional debug/test device.
This device must be configured on bus 0.
.It Li hda
@@ -529,6 +530,9 @@
Settings for the COM3 serial port device.
.It Va com4 Ta node Ta Ta
Settings for the COM4 serial port device.
+.It Va fwcfg Ta string Ta bhyve Ta
+Setting for the fwcfg type to be used.
+It supports "bhyve" for fwctl and "qemu" for fwcfg.
.It Va pc-testdev Ta bool Ta false Ta
Enable the PC debug/test device.
.El
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
@@ -101,6 +101,7 @@
#include "pci_emul.h"
#include "pci_irq.h"
#include "pci_lpc.h"
+#include "qemu_fwcfg.h"
#include "smbiostbl.h"
#ifdef BHYVE_SNAPSHOT
#include "snapshot.h"
@@ -1232,6 +1233,7 @@
set_config_bool("acpi_tables", false);
set_config_value("memory.size", "256M");
set_config_bool("x86.strictmsr", true);
+ set_config_value("lpc.fwcfg", "bhyve");
}
int
@@ -1461,6 +1463,17 @@
rtc_init(ctx);
sci_init(ctx);
+ if (qemu_fwcfg_init(ctx) != 0) {
+ fprintf(stderr, "qemu fwcfg initialization error");
+ exit(4);
+ }
+
+ if (qemu_fwcfg_add_file("opt/bhyve/hw.ncpu", sizeof(guest_ncpus),
+ &guest_ncpus) != 0) {
+ fprintf(stderr, "Could not add qemu fwcfg opt/bhyve/hw.ncpu");
+ exit(4);
+ }
+
/*
* Exit if a device emulation finds an error in its initilization
*/
@@ -1545,8 +1558,9 @@
assert(error == 0);
}
- if (lpc_bootrom())
+ if (lpc_bootrom() && strcmp(lpc_fwcfg(), "bhyve") == 0) {
fwctl_init();
+ }
/*
* Change the proc title to include the VM name.
diff --git a/usr.sbin/bhyve/pci_lpc.h b/usr.sbin/bhyve/pci_lpc.h
--- a/usr.sbin/bhyve/pci_lpc.h
+++ b/usr.sbin/bhyve/pci_lpc.h
@@ -72,5 +72,6 @@
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/pci_lpc.c b/usr.sbin/bhyve/pci_lpc.c
--- a/usr.sbin/bhyve/pci_lpc.c
+++ b/usr.sbin/bhyve/pci_lpc.c
@@ -110,10 +110,20 @@
set_config_value("lpc.bootrom", romfile);
varfile = strsep(&str, ",");
- if (varfile != NULL) {
+ if (varfile == NULL) {
+ error = 0;
+ goto done;
+ }
+ if (strchr(varfile, '=') == NULL) {
set_config_value("lpc.bootvars", varfile);
+ } else {
+ /* varfile doesn't exist, it's another config
+ * option */
+ pci_parse_legacy_config(find_config_node("lpc"),
+ varfile);
}
+ pci_parse_legacy_config(find_config_node("lpc"), str);
error = 0;
goto done;
}
@@ -160,6 +170,12 @@
return (get_config_value("lpc.bootrom"));
}
+const char *
+lpc_fwcfg(void)
+{
+ return (get_config_value("lpc.fwcfg"));
+}
+
static void
lpc_uart_intr_assert(void *arg)
{
diff --git a/usr.sbin/bhyve/qemu_fwcfg.c b/usr.sbin/bhyve/qemu_fwcfg.c
--- a/usr.sbin/bhyve/qemu_fwcfg.c
+++ b/usr.sbin/bhyve/qemu_fwcfg.c
@@ -17,6 +17,7 @@
#include "acpi_device.h"
#include "inout.h"
+#include "pci_lpc.h"
#include "qemu_fwcfg.h"
#define QEMU_FWCFG_ACPI_DEVICE_NAME "FWCF"
@@ -351,37 +352,49 @@
{
int error;
- error = acpi_device_create(&fwcfg_sc.acpi_dev, ctx,
- QEMU_FWCFG_ACPI_DEVICE_NAME, QEMU_FWCFG_ACPI_HARDWARE_ID);
- if (error) {
- warnx("%s: failed to create ACPI device for QEMU FwCfg",
- __func__);
- goto done;
- }
+ /*
+ * Bhyve supports fwctl (bhyve) and fwcfg (qemu) as firmware interfaces.
+ * Both are using the same ports. So, it's not possible to provide both
+ * interfaces at the same time to the guest. Therefore, only create acpi
+ * tables and register io ports for fwcfg, if it's used.
+ */
+ if (strcmp(lpc_fwcfg(), "qemu") == 0) {
+ error = acpi_device_create(&fwcfg_sc.acpi_dev, ctx,
+ QEMU_FWCFG_ACPI_DEVICE_NAME, QEMU_FWCFG_ACPI_HARDWARE_ID);
+ if (error) {
+ warnx("%s: failed to create ACPI device for QEMU FwCfg",
+ __func__);
+ goto done;
+ }
- error = acpi_device_add_res_fixed_ioport(fwcfg_sc.acpi_dev,
- QEMU_FWCFG_SELECTOR_PORT_NUMBER, 2);
- if (error) {
- warnx("%s: failed to add fixed IO port for QEMU FwCfg",
- __func__);
- goto done;
- }
+ error = acpi_device_add_res_fixed_ioport(fwcfg_sc.acpi_dev,
+ QEMU_FWCFG_SELECTOR_PORT_NUMBER, 2);
+ if (error) {
+ warnx("%s: failed to add fixed IO port for QEMU FwCfg",
+ __func__);
+ goto done;
+ }
- /* add handlers for fwcfg ports */
- if ((error = qemu_fwcfg_register_port("qemu_fwcfg_selector",
- QEMU_FWCFG_SELECTOR_PORT_NUMBER, QEMU_FWCFG_SELECTOR_PORT_SIZE,
- QEMU_FWCFG_SELECTOR_PORT_FLAGS,
- qemu_fwcfg_selector_port_handler)) != 0) {
- warnx("%s: Unable to register qemu fwcfg selector port 0x%x",
- __func__, QEMU_FWCFG_SELECTOR_PORT_NUMBER);
- goto done;
- }
- if ((error = qemu_fwcfg_register_port("qemu_fwcfg_data",
- QEMU_FWCFG_DATA_PORT_NUMBER, QEMU_FWCFG_DATA_PORT_SIZE,
- QEMU_FWCFG_DATA_PORT_FLAGS, qemu_fwcfg_data_port_handler)) != 0) {
- warnx("%s: Unable to register qemu fwcfg data port 0x%x",
- __func__, QEMU_FWCFG_DATA_PORT_NUMBER);
- goto done;
+ /* add handlers for fwcfg ports */
+ if ((error = qemu_fwcfg_register_port("qemu_fwcfg_selector",
+ QEMU_FWCFG_SELECTOR_PORT_NUMBER,
+ QEMU_FWCFG_SELECTOR_PORT_SIZE,
+ QEMU_FWCFG_SELECTOR_PORT_FLAGS,
+ qemu_fwcfg_selector_port_handler)) != 0) {
+ warnx(
+ "%s: Unable to register qemu fwcfg selector port 0x%x",
+ __func__, QEMU_FWCFG_SELECTOR_PORT_NUMBER);
+ goto done;
+ }
+ if ((error = qemu_fwcfg_register_port("qemu_fwcfg_data",
+ QEMU_FWCFG_DATA_PORT_NUMBER, QEMU_FWCFG_DATA_PORT_SIZE,
+ QEMU_FWCFG_DATA_PORT_FLAGS,
+ qemu_fwcfg_data_port_handler)) != 0) {
+ warnx(
+ "%s: Unable to register qemu fwcfg data port 0x%x",
+ __func__, QEMU_FWCFG_DATA_PORT_NUMBER);
+ goto done;
+ }
}
/* add common fwcfg items */

File Metadata

Mime Type
text/plain
Expires
Mon, Jan 27, 6:03 PM (6 h, 37 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
16202767
Default Alt Text
D38337.id117285.diff (7 KB)

Event Timeline