On Wed, Jul 23, 2025 at 12:01:28PM +0300, Daniil Tatianin wrote: > This is useful to be able to indicate various supported features to the > guest, or freeze a specific version of SeaBIOS to prevent guest visible > changes between BIOS updates. This is currently not possible since the > extension bytes indicated by SeaBIOS are slightly different than those > QEMU sets by default. > > Signed-off-by: Daniil Tatianin <d-tatia...@yandex-team.ru> > --- > hw/smbios/smbios.c | 66 +++++++++++++++++++++++++++++++++--- > include/hw/firmware/smbios.h | 3 ++ > 2 files changed, 64 insertions(+), 5 deletions(-) > > diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c > index ad4cd6721e..73699e8a62 100644 > --- a/hw/smbios/smbios.c > +++ b/hw/smbios/smbios.c > @@ -178,6 +178,14 @@ static const QemuOptDesc qemu_smbios_type0_opts[] = { > .name = "uefi", > .type = QEMU_OPT_BOOL, > .help = "uefi support", > + },{ > + .name = "extension_byte_1", > + .type = QEMU_OPT_NUMBER, > + .help = "BIOS characteristics extension byte 1" > + },{ > + .name = "extension_byte_2", > + .type = QEMU_OPT_NUMBER, > + .help = "BIOS characteristics extension byte 2" > }, > { /* end of list */ } > }; > @@ -572,10 +580,23 @@ static void smbios_build_type_0_table(void) > t->bios_rom_size = 0; /* hardcoded in SeaBIOS with FIXME comment */ > > t->bios_characteristics = cpu_to_le64(0x08); /* Not supported */ > - t->bios_characteristics_extension_bytes[0] = 0; > - t->bios_characteristics_extension_bytes[1] = 0x14; /* TCD/SVVP | VM */ > - if (smbios_type0.uefi) { > - t->bios_characteristics_extension_bytes[1] |= 0x08; /* |= UEFI */ > + > + if (smbios_type0.have_extension_bytes[0]) { > + t->bios_characteristics_extension_bytes[0] = > + smbios_type0.extension_bytes[0]; > + } else { > + t->bios_characteristics_extension_bytes[0] = 0; > + } > + > + if (smbios_type0.have_extension_bytes[1]) { > + t->bios_characteristics_extension_bytes[1] = > + smbios_type0.extension_bytes[1]; > + } else { > + t->bios_characteristics_extension_bytes[1] = 0x14; /* TCD/SVVP | VM > */ > + > + if (smbios_type0.uefi) { > + t->bios_characteristics_extension_bytes[1] |= 0x08; /* |= UEFI */ > + }
should we not or these in, anyway? > } > > if (smbios_type0.have_major_minor) { > @@ -1403,7 +1424,42 @@ void smbios_entry_add(QemuOpts *opts, Error **errp) > save_opt(&smbios_type0.vendor, opts, "vendor"); > save_opt(&smbios_type0.version, opts, "version"); > save_opt(&smbios_type0.date, opts, "date"); > - smbios_type0.uefi = qemu_opt_get_bool(opts, "uefi", false); > + > + if (qemu_opt_get(opts, "extension_byte_1")) { > + uint64_t ex_val; > + > + ex_val = qemu_opt_get_number(opts, "extension_byte_1", 0); > + if (ex_val > 0xFF) { > + error_setg(errp, "Invalid extension_byte_1"); > + return; > + } > + > + smbios_type0.extension_bytes[0] = ex_val; > + smbios_type0.have_extension_bytes[0] = true; > + } > + > + if (qemu_opt_get(opts, "extension_byte_2")) { > + uint64_t ex_val; > + > + ex_val = qemu_opt_get_number(opts, "extension_byte_2", 0); > + if (ex_val > 0xFF) { > + error_setg(errp, "Invalid extension_byte_2"); > + return; > + } > + > + smbios_type0.extension_bytes[1] = ex_val; > + smbios_type0.have_extension_bytes[1] = true; > + } > + > + if (qemu_opt_get(opts, "uefi")) { > + if (smbios_type0.have_extension_bytes[1]) { > + error_setg(errp, "'uefi' and 'extension_byte_2' are " > + "mutually exclusive"); > + return; > + } > + > + smbios_type0.uefi = qemu_opt_get_bool(opts, "uefi", false); > + } > > val = qemu_opt_get(opts, "release"); > if (val) { > diff --git a/include/hw/firmware/smbios.h b/include/hw/firmware/smbios.h > index f066ab7262..67b3b28471 100644 > --- a/include/hw/firmware/smbios.h > +++ b/include/hw/firmware/smbios.h > @@ -24,6 +24,9 @@ typedef struct { > const char *vendor, *version, *date; > bool have_major_minor, uefi; > uint8_t major, minor; > + > + bool have_extension_bytes[2]; > + uint8_t extension_bytes[2]; > } smbios_type0_t; > extern smbios_type0_t smbios_type0; > > -- > 2.34.1