bhyve supports populating SMBIOS fields. Each
field is set using the -o option, such as:

 -o system.product_name=Virt-Manager

There are 4 groups of options:

 - bios.*
 - system.*
 - board.*
 - chassis.*

As a side note, the '-o' option can be used
for setting options not related to the SMBIOS fields.

Extend virBhyveProcessBuildBhyveCmd() to build the appropriate
arguments for what's specified in the domain's
`<sysinfo type='smbios'>` section.

Signed-off-by: Roman Bogorodskiy <[email protected]>
---
 src/bhyve/bhyve_command.c                     | 147 ++++++++++++++++++
 .../x86_64/bhyvexml2argv-sysinfo-smbios.args  |  29 ++++
 .../bhyvexml2argv-sysinfo-smbios.ldargs       |   4 +
 .../x86_64/bhyvexml2argv-sysinfo-smbios.xml   |  52 +++++++
 tests/bhyvexml2argvtest.c                     |   1 +
 5 files changed, 233 insertions(+)
 create mode 100644 
tests/bhyvexml2argvdata/x86_64/bhyvexml2argv-sysinfo-smbios.args
 create mode 100644 
tests/bhyvexml2argvdata/x86_64/bhyvexml2argv-sysinfo-smbios.ldargs
 create mode 100644 
tests/bhyvexml2argvdata/x86_64/bhyvexml2argv-sysinfo-smbios.xml

diff --git a/src/bhyve/bhyve_command.c b/src/bhyve/bhyve_command.c
index 1da344f503..941b48eb66 100644
--- a/src/bhyve/bhyve_command.c
+++ b/src/bhyve/bhyve_command.c
@@ -928,6 +928,148 @@ bhyveBuildFSArgStr(const virDomainDef *def G_GNUC_UNUSED,
     return 0;
 }
 
+static void
+bhyveBuildSysinfoBiosArgStr(virSysinfoBIOSDef *def,
+                            virCommand *cmd)
+{
+    if (def->vendor) {
+        virCommandAddArg(cmd, "-o");
+        virCommandAddArgPair(cmd, "bios.vendor", def->vendor);
+    }
+
+    if (def->version) {
+        virCommandAddArg(cmd, "-o");
+        virCommandAddArgPair(cmd, "bios.version", def->version);
+    }
+
+    if (def->date) {
+        virCommandAddArg(cmd, "-o");
+        virCommandAddArgPair(cmd, "bios.release_date", def->date);
+    }
+}
+
+static void
+bhyveBuildSysinfoSystemArgStr(virSysinfoSystemDef *def,
+                              virCommand *cmd)
+{
+    if (def->manufacturer) {
+        virCommandAddArg(cmd, "-o");
+        virCommandAddArgPair(cmd, "system.manufacturer", def->manufacturer);
+    }
+
+    if (def->product) {
+        virCommandAddArg(cmd, "-o");
+        virCommandAddArgPair(cmd, "system.product_name", def->product);
+    }
+
+    if (def->serial) {
+        virCommandAddArg(cmd, "-o");
+        virCommandAddArgPair(cmd, "system.serial_number", def->serial);
+    }
+
+    if (def->sku) {
+        virCommandAddArg(cmd, "-o");
+        virCommandAddArgPair(cmd, "system.sku", def->sku);
+    }
+
+    if (def->version) {
+        virCommandAddArg(cmd, "-o");
+        virCommandAddArgPair(cmd, "system.version", def->version);
+    }
+}
+
+static void
+bhyveBuildSysinfoBaseBoardArgStr(virSysinfoBaseBoardDef *def,
+                                 virCommand *cmd)
+{
+    if (def->manufacturer) {
+        virCommandAddArg(cmd, "-o");
+        virCommandAddArgPair(cmd, "board.manufacturer", def->manufacturer);
+    }
+
+    if (def->product) {
+        virCommandAddArg(cmd, "-o");
+        virCommandAddArgPair(cmd, "board.product_name", def->product);
+    }
+
+    if (def->version) {
+        virCommandAddArg(cmd, "-o");
+        virCommandAddArgPair(cmd, "board.version", def->version);
+    }
+
+    if (def->serial) {
+        virCommandAddArg(cmd, "-o");
+        virCommandAddArgPair(cmd, "board.serial_number", def->serial);
+    }
+
+    if (def->asset) {
+        virCommandAddArg(cmd, "-o");
+        virCommandAddArgPair(cmd, "board.asset_tag", def->asset);
+    }
+
+    if (def->location) {
+        virCommandAddArg(cmd, "-o");
+        virCommandAddArgPair(cmd, "board.location", def->location);
+    }
+}
+
+static void
+bhyveBuildSysinfoChassisArgStr(virSysinfoChassisDef *def,
+                               virCommand *cmd)
+{
+    if (def->manufacturer) {
+        virCommandAddArg(cmd, "-o");
+        virCommandAddArgPair(cmd, "chassis.manufacturer", def->manufacturer);
+    }
+
+    if (def->version) {
+        virCommandAddArg(cmd, "-o");
+        virCommandAddArgPair(cmd, "chassis.version", def->version);
+    }
+
+    if (def->serial) {
+        virCommandAddArg(cmd, "-o");
+        virCommandAddArgPair(cmd, "chassis.serial_number", def->serial);
+    }
+
+    if (def->asset) {
+        virCommandAddArg(cmd, "-o");
+        virCommandAddArgPair(cmd, "chassis.asset_tag", def->asset);
+    }
+
+    if (def->sku) {
+        virCommandAddArg(cmd, "-o");
+        virCommandAddArgPair(cmd, "chassis.sku", def->sku);
+    }
+}
+
+static int
+bhyveBuildSysinfoArgStr(virSysinfoDef *sysinfo,
+                        virCommand *cmd)
+{
+    size_t i;
+
+    if (sysinfo->bios)
+        bhyveBuildSysinfoBiosArgStr(sysinfo->bios, cmd);
+
+    if (sysinfo->system)
+        bhyveBuildSysinfoSystemArgStr(sysinfo->system, cmd);
+
+    if (sysinfo->nbaseBoard > 1) {
+        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                       _("bhyve does not support more than one entry to Type 2 
in SMBIOS table"));
+        return -1;
+    }
+
+    for (i = 0; i < sysinfo->nbaseBoard; i++)
+        bhyveBuildSysinfoBaseBoardArgStr(&sysinfo->baseBoard[i], cmd);
+
+    if (sysinfo->chassis)
+        bhyveBuildSysinfoChassisArgStr(sysinfo->chassis, cmd);
+
+    return 0;
+}
+
 virCommand *
 virBhyveProcessBuildBhyveCmd(struct _bhyveConn *driver, virDomainDef *def,
                              bool dryRun)
@@ -1164,6 +1306,11 @@ virBhyveProcessBuildBhyveCmd(struct _bhyveConn *driver, 
virDomainDef *def,
     if (bhyveBuildHostdevArgStr(def, cmd) < 0)
         return NULL;
 
+    for (i = 0; i < def->nsysinfo; i++)
+        if (def->sysinfo[i]->type == VIR_SYSINFO_SMBIOS)
+            if (bhyveBuildSysinfoArgStr(def->sysinfo[i], cmd) < 0)
+                return NULL;
+
     virCommandAddArg(cmd, def->name);
 
     return g_steal_pointer(&cmd);
diff --git a/tests/bhyvexml2argvdata/x86_64/bhyvexml2argv-sysinfo-smbios.args 
b/tests/bhyvexml2argvdata/x86_64/bhyvexml2argv-sysinfo-smbios.args
new file mode 100644
index 0000000000..f4894a60b0
--- /dev/null
+++ b/tests/bhyvexml2argvdata/x86_64/bhyvexml2argv-sysinfo-smbios.args
@@ -0,0 +1,29 @@
+bhyve \
+-c 1 \
+-m 214 \
+-u \
+-H \
+-P \
+-s 0:0,hostbridge \
+-s 2:0,ahci,hd:/tmp/freebsd.img \
+-s 3:0,virtio-net,faketapdev,mac=52:54:00:b9:94:02 \
+-o bios.vendor=LENOVO \
+-o bios.version=14.1 \
+-o bios.release_date=11/24/2025 \
+-o system.manufacturer=Fedora \
+-o system.product_name=Virt-Manager \
+-o system.serial_number=xxx-yyy-zzz \
+-o system.sku=0000 \
+-o system.version=0.9.4 \
+-o board.manufacturer=LENOVO \
+-o board.product_name=20BE0061MC \
+-o 'board.version=0B98401 Pro' \
+-o board.serial_number=W1KS427111E \
+-o 'board.asset_tag=Asset Tag' \
+-o board.location=Nowhere \
+-o 'chassis.manufacturer=Dell Inc.' \
+-o chassis.version=2.12 \
+-o chassis.serial_number=65X0XF2 \
+-o chassis.asset_tag=40000101 \
+-o chassis.sku=Type3Sku1 \
+bhyve
diff --git a/tests/bhyvexml2argvdata/x86_64/bhyvexml2argv-sysinfo-smbios.ldargs 
b/tests/bhyvexml2argvdata/x86_64/bhyvexml2argv-sysinfo-smbios.ldargs
new file mode 100644
index 0000000000..5905f4b3e6
--- /dev/null
+++ b/tests/bhyvexml2argvdata/x86_64/bhyvexml2argv-sysinfo-smbios.ldargs
@@ -0,0 +1,4 @@
+bhyveload \
+-m 214 \
+-d /tmp/freebsd.img \
+bhyve
diff --git a/tests/bhyvexml2argvdata/x86_64/bhyvexml2argv-sysinfo-smbios.xml 
b/tests/bhyvexml2argvdata/x86_64/bhyvexml2argv-sysinfo-smbios.xml
new file mode 100644
index 0000000000..111421211c
--- /dev/null
+++ b/tests/bhyvexml2argvdata/x86_64/bhyvexml2argv-sysinfo-smbios.xml
@@ -0,0 +1,52 @@
+<domain type='bhyve'>
+  <name>bhyve</name>
+  <uuid>df3be7e7-a104-11e3-aeb0-50e5492bd3dc</uuid>
+  <memory>219136</memory>
+  <vcpu>1</vcpu>
+  <os>
+    <type>hvm</type>
+  </os>
+  <sysinfo type='smbios'>
+    <bios>
+      <entry name='vendor'>LENOVO</entry>
+      <entry name='version'>14.1</entry>
+      <entry name='date'>11/24/2025</entry>
+    </bios>
+    <system>
+      <entry name='manufacturer'>Fedora</entry>
+      <entry name='product'>Virt-Manager</entry>
+      <entry name='version'>0.9.4</entry>
+      <entry name='serial'>xxx-yyy-zzz</entry>
+      <entry name='sku'>0000</entry>
+    </system>
+    <baseBoard>
+      <entry name='manufacturer'>LENOVO</entry>
+      <entry name='product'>20BE0061MC</entry>
+      <entry name='version'>0B98401 Pro</entry>
+      <entry name='serial'>W1KS427111E</entry>
+      <entry name='asset'>Asset Tag</entry>
+      <entry name='location'>Nowhere</entry>
+    </baseBoard>
+    <chassis>
+      <entry name='manufacturer'>Dell Inc.</entry>
+      <entry name='version'>2.12</entry>
+      <entry name='serial'>65X0XF2</entry>
+      <entry name='asset'>40000101</entry>
+      <entry name='sku'>Type3Sku1</entry>
+    </chassis>
+  </sysinfo>
+  <devices>
+    <disk type='file'>
+      <driver name='file' type='raw'/>
+      <source file='/tmp/freebsd.img'/>
+      <target dev='hda' bus='sata'/>
+      <address type='drive' controller='0' bus='0' target='2' unit='0'/>
+    </disk>
+    <interface type='bridge'>
+      <mac address='52:54:00:b9:94:02'/>
+      <model type='virtio'/>
+      <source bridge="virbr0"/>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' 
function='0x0'/>
+    </interface>
+  </devices>
+</domain>
diff --git a/tests/bhyvexml2argvtest.c b/tests/bhyvexml2argvtest.c
index 818b51e178..71322d1330 100644
--- a/tests/bhyvexml2argvtest.c
+++ b/tests/bhyvexml2argvtest.c
@@ -303,6 +303,7 @@ mymain(void)
     DO_TEST_FAILURE("virtio-console-invalid-path");
     DO_TEST("memtune");
     DO_TEST_FAILURE("memtune-unsupported-params");
+    DO_TEST("sysinfo-smbios");
 
     /* Address allocation tests */
     DO_TEST("addr-single-sata-disk");
-- 
2.52.0

Reply via email to