* [PATCH v2 00/20] Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS
@ 2024-03-05 15:57 Igor Mammedov
2024-03-05 15:57 ` [PATCH v2 01/20] tests: smbios: make it possible to write SMBIOS only test Igor Mammedov
` (19 more replies)
0 siblings, 20 replies; 37+ messages in thread
From: Igor Mammedov @ 2024-03-05 15:57 UTC (permalink / raw)
To: qemu-devel
Cc: peter.maydell, pbonzini, mst, gaosong, alistair.francis, palmer,
bin.meng, liwei1518, dbarboza, zhiwei_liu, imammedo, anisinha,
philmd, wangyanan55, eblake, armbru, qemu-arm, qemu-riscv,
f.ebner
Changelog:
* QAPI style fixes (Markus Armbruster <armbru@redhat.com>)
* squash 11/19 into 10/19 (Ani Sinha <anisinha@redhat.com>)
* split '[PATCH 09/19] smbios: build legacy mode code only for 'pc' machine'
in 3 smaller patches, to make it more readable
smbios: add smbios_add_usr_blob_size() helper
smbios: rename/expose structures/bitmaps used by both legacy and modern code
smbios: build legacy mode code only for 'pc' machine
* pick up acks
Windows (10) bootloader when running on top of SeaBIOS, fails to find
SMBIOSv3 entry point. Tracing it shows that it looks for v2 anchor markers
only and not v3. Tricking it into believing that entry point is found
lets Windows successfully locate and parse SMBIOSv3 tables. Whether it
will be fixed on Windows side is not clear so here goes a workaround.
Idea is to try build v2 tables if QEMU configuration permits,
and fallback to v3 tables otherwise. That will mask Windows issue
form majority of users.
However if VM configuration can't be described (typically large VMs)
by v2 tables, QEMU will use SMBIOSv3 and Windows will hit the issue
again. In this case complain to Microsoft and/or use UEFI instead of
SeaBIOS (requires reinstall).
Default compat setting of smbios-entry-point-type after series
for pc/q35 machines:
* 9.0-newer: 'auto'
* 8.1-8.2: '64'
* 8.0-older: '32'
Fixes: https://gitlab.com/qemu-project/qemu/-/issues/2008
CC: peter.maydell@linaro.org
CC: pbonzini@redhat.com
CC: mst@redhat.com
CC: gaosong@loongson.cn
CC: alistair.francis@wdc.com
CC: palmer@dabbelt.com
CC: bin.meng@windriver.com
CC: liwei1518@gmail.com
CC: dbarboza@ventanamicro.com
CC: zhiwei_liu@linux.alibaba.com
CC: imammedo@redhat.com
CC: anisinha@redhat.com
CC: philmd@linaro.org
CC: wangyanan55@huawei.com
CC: eblake@redhat.com
CC: armbru@redhat.com
CC: qemu-arm@nongnu.org
CC: qemu-riscv@nongnu.org
CC: f.ebner@proxmox.com
Igor Mammedov (20):
tests: smbios: make it possible to write SMBIOS only test
tests: smbios: add test for -smbios type=11 option
tests: smbios: add test for legacy mode CLI options
smbios: cleanup smbios_get_tables() from legacy handling
smbios: get rid of smbios_smp_sockets global
smbios: get rid of smbios_legacy global
smbios: avoid mangling user provided tables
smbios: don't check type4 structures in legacy mode
smbios: add smbios_add_usr_blob_size() helper
smbios: rename/expose structures/bitmaps used by both legacy and
modern code
smbios: build legacy mode code only for 'pc' machine
smbios: handle errors consistently
smbios: get rid of global smbios_ep_type
smbios: extend smbios-entry-point-type with 'auto' value
smbios: in case of entry point is 'auto' try to build v2 tables 1st
smbios: error out when building type 4 table is not possible
smbios: clear smbios_type4_count before building tables
tests: acpi/smbios: whitelist expected blobs
pc/q35: set SMBIOS entry point type to 'auto' by default
tests: acpi: update expected SSDT.dimmpxm blob
hw/i386/fw_cfg.h | 3 +-
include/hw/firmware/smbios.h | 28 +-
hw/arm/virt.c | 6 +-
hw/i386/Kconfig | 1 +
hw/i386/fw_cfg.c | 14 +-
hw/i386/pc.c | 4 +-
hw/i386/pc_piix.c | 4 +
hw/i386/pc_q35.c | 3 +
hw/loongarch/virt.c | 7 +-
hw/riscv/virt.c | 6 +-
hw/smbios/Kconfig | 2 +
hw/smbios/meson.build | 4 +
hw/smbios/smbios.c | 481 +++++++++++----------------
hw/smbios/smbios_legacy.c | 185 +++++++++++
hw/smbios/smbios_legacy_stub.c | 16 +
qapi/machine.json | 5 +-
tests/data/acpi/q35/SSDT.dimmpxm | Bin 1815 -> 1815 bytes
tests/data/smbios/type11_blob | Bin 0 -> 11 bytes
tests/data/smbios/type11_blob.legacy | Bin 0 -> 10 bytes
tests/qtest/bios-tables-test.c | 81 ++++-
20 files changed, 534 insertions(+), 316 deletions(-)
create mode 100644 hw/smbios/smbios_legacy.c
create mode 100644 hw/smbios/smbios_legacy_stub.c
create mode 100644 tests/data/smbios/type11_blob
create mode 100644 tests/data/smbios/type11_blob.legacy
--
2.39.3
^ permalink raw reply [flat|nested] 37+ messages in thread
* [PATCH v2 01/20] tests: smbios: make it possible to write SMBIOS only test
2024-03-05 15:57 [PATCH v2 00/20] Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS Igor Mammedov
@ 2024-03-05 15:57 ` Igor Mammedov
2024-03-05 15:57 ` [PATCH v2 02/20] tests: smbios: add test for -smbios type=11 option Igor Mammedov
` (18 subsequent siblings)
19 siblings, 0 replies; 37+ messages in thread
From: Igor Mammedov @ 2024-03-05 15:57 UTC (permalink / raw)
To: qemu-devel
Cc: peter.maydell, pbonzini, mst, gaosong, alistair.francis, palmer,
bin.meng, liwei1518, dbarboza, zhiwei_liu, imammedo, anisinha,
philmd, wangyanan55, eblake, armbru, qemu-arm, qemu-riscv,
f.ebner
Cureently it not possible to run SMBIOS test without ACPI one,
which gets into the way when testing ACPI-less configs.
Extract SMBIOS testing into separate routines that could also
be run without ACPI dependency and use that for testing SMBIOS.
As the 1st user add "acpi/piix4/smbios-options" test case.
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Ani Sinha <anisinha@redhat.com>
Tested-by: Fiona Ebner <f.ebner@proxmox.com>
---
tests/qtest/bios-tables-test.c | 47 +++++++++++++++++++++++++++-------
1 file changed, 38 insertions(+), 9 deletions(-)
diff --git a/tests/qtest/bios-tables-test.c b/tests/qtest/bios-tables-test.c
index 21811a1ab5..b2992bafa8 100644
--- a/tests/qtest/bios-tables-test.c
+++ b/tests/qtest/bios-tables-test.c
@@ -858,16 +858,8 @@ static void test_vm_prepare(const char *params, test_data *data)
g_free(args);
}
-static void process_acpi_tables_noexit(test_data *data)
+static void process_smbios_tables_noexit(test_data *data)
{
- test_acpi_load_tables(data);
-
- if (getenv(ACPI_REBUILD_EXPECTED_AML)) {
- dump_aml_files(data, true);
- } else {
- test_acpi_asl(data);
- }
-
/*
* TODO: make SMBIOS tests work with UEFI firmware,
* Bug on uefi-test-tools to provide entry point:
@@ -879,6 +871,27 @@ static void process_acpi_tables_noexit(test_data *data)
}
}
+static void test_smbios(const char *params, test_data *data)
+{
+ test_vm_prepare(params, data);
+ boot_sector_test(data->qts);
+ process_smbios_tables_noexit(data);
+ qtest_quit(data->qts);
+}
+
+static void process_acpi_tables_noexit(test_data *data)
+{
+ test_acpi_load_tables(data);
+
+ if (getenv(ACPI_REBUILD_EXPECTED_AML)) {
+ dump_aml_files(data, true);
+ } else {
+ test_acpi_asl(data);
+ }
+
+ process_smbios_tables_noexit(data);
+}
+
static void process_acpi_tables(test_data *data)
{
process_acpi_tables_noexit(data);
@@ -2064,6 +2077,20 @@ static void test_acpi_q35_pvpanic_isa(void)
free_test_data(&data);
}
+static void test_acpi_pc_smbios_options(void)
+{
+ uint8_t req_type11[] = { 11 };
+ test_data data = {
+ .machine = MACHINE_PC,
+ .variant = ".pc_smbios_options",
+ .required_struct_types = req_type11,
+ .required_struct_types_len = ARRAY_SIZE(req_type11),
+ };
+
+ test_smbios("-smbios type=11,value=TEST", &data);
+ free_test_data(&data);
+}
+
static void test_oem_fields(test_data *data)
{
int i;
@@ -2215,6 +2242,8 @@ int main(int argc, char *argv[])
#ifdef CONFIG_POSIX
qtest_add_func("acpi/piix4/acpierst", test_acpi_piix4_acpi_erst);
#endif
+ qtest_add_func("acpi/piix4/smbios-options",
+ test_acpi_pc_smbios_options);
}
if (qtest_has_machine(MACHINE_Q35)) {
qtest_add_func("acpi/q35", test_acpi_q35_tcg);
--
2.39.3
^ permalink raw reply related [flat|nested] 37+ messages in thread
* [PATCH v2 02/20] tests: smbios: add test for -smbios type=11 option
2024-03-05 15:57 [PATCH v2 00/20] Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS Igor Mammedov
2024-03-05 15:57 ` [PATCH v2 01/20] tests: smbios: make it possible to write SMBIOS only test Igor Mammedov
@ 2024-03-05 15:57 ` Igor Mammedov
2024-03-05 15:57 ` [PATCH v2 03/20] tests: smbios: add test for legacy mode CLI options Igor Mammedov
` (17 subsequent siblings)
19 siblings, 0 replies; 37+ messages in thread
From: Igor Mammedov @ 2024-03-05 15:57 UTC (permalink / raw)
To: qemu-devel
Cc: peter.maydell, pbonzini, mst, gaosong, alistair.francis, palmer,
bin.meng, liwei1518, dbarboza, zhiwei_liu, imammedo, anisinha,
philmd, wangyanan55, eblake, armbru, qemu-arm, qemu-riscv,
f.ebner
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Ani Sinha <anisinha@redhat.com>
Tested-by: Fiona Ebner <f.ebner@proxmox.com>
---
tests/data/smbios/type11_blob | Bin 0 -> 11 bytes
tests/qtest/bios-tables-test.c | 17 +++++++++++++++++
2 files changed, 17 insertions(+)
create mode 100644 tests/data/smbios/type11_blob
diff --git a/tests/data/smbios/type11_blob b/tests/data/smbios/type11_blob
new file mode 100644
index 0000000000000000000000000000000000000000..1d8fea4b0c6f040a13ba99c3fad762538b795614
GIT binary patch
literal 11
Scmd;PW!S(N;u;*nzyJUX)&c?m
literal 0
HcmV?d00001
diff --git a/tests/qtest/bios-tables-test.c b/tests/qtest/bios-tables-test.c
index b2992bafa8..a116f88e1d 100644
--- a/tests/qtest/bios-tables-test.c
+++ b/tests/qtest/bios-tables-test.c
@@ -2091,6 +2091,21 @@ static void test_acpi_pc_smbios_options(void)
free_test_data(&data);
}
+static void test_acpi_pc_smbios_blob(void)
+{
+ uint8_t req_type11[] = { 11 };
+ test_data data = {
+ .machine = MACHINE_PC,
+ .variant = ".pc_smbios_blob",
+ .required_struct_types = req_type11,
+ .required_struct_types_len = ARRAY_SIZE(req_type11),
+ };
+
+ test_smbios("-machine smbios-entry-point-type=32 "
+ "-smbios file=tests/data/smbios/type11_blob", &data);
+ free_test_data(&data);
+}
+
static void test_oem_fields(test_data *data)
{
int i;
@@ -2244,6 +2259,8 @@ int main(int argc, char *argv[])
#endif
qtest_add_func("acpi/piix4/smbios-options",
test_acpi_pc_smbios_options);
+ qtest_add_func("acpi/piix4/smbios-blob",
+ test_acpi_pc_smbios_blob);
}
if (qtest_has_machine(MACHINE_Q35)) {
qtest_add_func("acpi/q35", test_acpi_q35_tcg);
--
2.39.3
^ permalink raw reply related [flat|nested] 37+ messages in thread
* [PATCH v2 03/20] tests: smbios: add test for legacy mode CLI options
2024-03-05 15:57 [PATCH v2 00/20] Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS Igor Mammedov
2024-03-05 15:57 ` [PATCH v2 01/20] tests: smbios: make it possible to write SMBIOS only test Igor Mammedov
2024-03-05 15:57 ` [PATCH v2 02/20] tests: smbios: add test for -smbios type=11 option Igor Mammedov
@ 2024-03-05 15:57 ` Igor Mammedov
2024-03-05 15:57 ` [PATCH v2 04/20] smbios: cleanup smbios_get_tables() from legacy handling Igor Mammedov
` (16 subsequent siblings)
19 siblings, 0 replies; 37+ messages in thread
From: Igor Mammedov @ 2024-03-05 15:57 UTC (permalink / raw)
To: qemu-devel
Cc: peter.maydell, pbonzini, mst, gaosong, alistair.francis, palmer,
bin.meng, liwei1518, dbarboza, zhiwei_liu, imammedo, anisinha,
philmd, wangyanan55, eblake, armbru, qemu-arm, qemu-riscv,
f.ebner
Unfortunately having 2.0 machine type deprecated is not enough
to get rid of legacy SMBIOS handling since 'isapc' also uses
that and it's staying around.
Hence add test for CLI options handling to be sure that it
ain't broken during SMBIOS code refactoring.
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Ani Sinha <anisinha@redhat.com>
Tested-by: Fiona Ebner <f.ebner@proxmox.com>
---
tests/data/smbios/type11_blob.legacy | Bin 0 -> 10 bytes
tests/qtest/bios-tables-test.c | 17 +++++++++++++++++
2 files changed, 17 insertions(+)
create mode 100644 tests/data/smbios/type11_blob.legacy
diff --git a/tests/data/smbios/type11_blob.legacy b/tests/data/smbios/type11_blob.legacy
new file mode 100644
index 0000000000000000000000000000000000000000..aef463aab903405958b0a85f85c5980671c08bee
GIT binary patch
literal 10
Rcmd;PW!S(N;u;*n000Tp0s;U4
literal 0
HcmV?d00001
diff --git a/tests/qtest/bios-tables-test.c b/tests/qtest/bios-tables-test.c
index a116f88e1d..d1ff4db7a2 100644
--- a/tests/qtest/bios-tables-test.c
+++ b/tests/qtest/bios-tables-test.c
@@ -2106,6 +2106,21 @@ static void test_acpi_pc_smbios_blob(void)
free_test_data(&data);
}
+static void test_acpi_isapc_smbios_legacy(void)
+{
+ uint8_t req_type11[] = { 1, 11 };
+ test_data data = {
+ .machine = "isapc",
+ .variant = ".pc_smbios_legacy",
+ .required_struct_types = req_type11,
+ .required_struct_types_len = ARRAY_SIZE(req_type11),
+ };
+
+ test_smbios("-smbios file=tests/data/smbios/type11_blob.legacy "
+ "-smbios type=1,family=TEST", &data);
+ free_test_data(&data);
+}
+
static void test_oem_fields(test_data *data)
{
int i;
@@ -2261,6 +2276,8 @@ int main(int argc, char *argv[])
test_acpi_pc_smbios_options);
qtest_add_func("acpi/piix4/smbios-blob",
test_acpi_pc_smbios_blob);
+ qtest_add_func("acpi/piix4/smbios-legacy",
+ test_acpi_isapc_smbios_legacy);
}
if (qtest_has_machine(MACHINE_Q35)) {
qtest_add_func("acpi/q35", test_acpi_q35_tcg);
--
2.39.3
^ permalink raw reply related [flat|nested] 37+ messages in thread
* [PATCH v2 04/20] smbios: cleanup smbios_get_tables() from legacy handling
2024-03-05 15:57 [PATCH v2 00/20] Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS Igor Mammedov
` (2 preceding siblings ...)
2024-03-05 15:57 ` [PATCH v2 03/20] tests: smbios: add test for legacy mode CLI options Igor Mammedov
@ 2024-03-05 15:57 ` Igor Mammedov
2024-03-05 15:57 ` [PATCH v2 05/20] smbios: get rid of smbios_smp_sockets global Igor Mammedov
` (15 subsequent siblings)
19 siblings, 0 replies; 37+ messages in thread
From: Igor Mammedov @ 2024-03-05 15:57 UTC (permalink / raw)
To: qemu-devel
Cc: peter.maydell, pbonzini, mst, gaosong, alistair.francis, palmer,
bin.meng, liwei1518, dbarboza, zhiwei_liu, imammedo, anisinha,
philmd, wangyanan55, eblake, armbru, qemu-arm, qemu-riscv,
f.ebner
smbios_get_tables() bails out right away if leagacy mode is enabled
and won't generate any SMBIOS tables. At the same time x86 specific
fw_cfg_build_smbios() will genarate legacy tables and then proceed
to preparing temporary mem_array for useless call to
smbios_get_tables() and then discard it.
Drop legacy related check in smbios_get_tables() and return from
fw_cfg_build_smbios() early if legacy tables where built without
proceeding to non legacy part of the function.
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Ani Sinha <anisinha@redhat.com>
Tested-by: Fiona Ebner <f.ebner@proxmox.com>
---
hw/i386/fw_cfg.c | 1 +
hw/smbios/smbios.c | 6 ------
2 files changed, 1 insertion(+), 6 deletions(-)
diff --git a/hw/i386/fw_cfg.c b/hw/i386/fw_cfg.c
index 98a478c276..a635234e68 100644
--- a/hw/i386/fw_cfg.c
+++ b/hw/i386/fw_cfg.c
@@ -74,6 +74,7 @@ void fw_cfg_build_smbios(PCMachineState *pcms, FWCfgState *fw_cfg)
if (smbios_tables) {
fw_cfg_add_bytes(fw_cfg, FW_CFG_SMBIOS_ENTRIES,
smbios_tables, smbios_tables_len);
+ return;
}
/* build the array of physical mem area from e820 table */
diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c
index a3c4e52ce9..8e86c62184 100644
--- a/hw/smbios/smbios.c
+++ b/hw/smbios/smbios.c
@@ -1106,12 +1106,6 @@ void smbios_get_tables(MachineState *ms,
{
unsigned i, dimm_cnt, offset;
- if (smbios_legacy) {
- *tables = *anchor = NULL;
- *tables_len = *anchor_len = 0;
- return;
- }
-
if (!smbios_immutable) {
smbios_build_type_0_table();
smbios_build_type_1_table();
--
2.39.3
^ permalink raw reply related [flat|nested] 37+ messages in thread
* [PATCH v2 05/20] smbios: get rid of smbios_smp_sockets global
2024-03-05 15:57 [PATCH v2 00/20] Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS Igor Mammedov
` (3 preceding siblings ...)
2024-03-05 15:57 ` [PATCH v2 04/20] smbios: cleanup smbios_get_tables() from legacy handling Igor Mammedov
@ 2024-03-05 15:57 ` Igor Mammedov
2024-03-05 15:57 ` [PATCH v2 06/20] smbios: get rid of smbios_legacy global Igor Mammedov
` (14 subsequent siblings)
19 siblings, 0 replies; 37+ messages in thread
From: Igor Mammedov @ 2024-03-05 15:57 UTC (permalink / raw)
To: qemu-devel
Cc: peter.maydell, pbonzini, mst, gaosong, alistair.francis, palmer,
bin.meng, liwei1518, dbarboza, zhiwei_liu, imammedo, anisinha,
philmd, wangyanan55, eblake, armbru, qemu-arm, qemu-riscv,
f.ebner
it makes smbios_validate_table() independent from
smbios_smp_sockets global, which in turn lets
smbios_get_tables() avoid using not related legacy code.
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Ani Sinha <anisinha@redhat.com>
Tested-by: Fiona Ebner <f.ebner@proxmox.com>
---
goal here is to isolate legacy handling from generic smbios_get_tables()
---
include/hw/firmware/smbios.h | 2 +-
hw/i386/fw_cfg.c | 2 +-
hw/smbios/smbios.c | 22 +++++++++-------------
3 files changed, 11 insertions(+), 15 deletions(-)
diff --git a/include/hw/firmware/smbios.h b/include/hw/firmware/smbios.h
index 6e514982d4..a187fbbd3d 100644
--- a/include/hw/firmware/smbios.h
+++ b/include/hw/firmware/smbios.h
@@ -296,7 +296,7 @@ void smbios_set_defaults(const char *manufacturer, const char *product,
const char *version, bool legacy_mode,
bool uuid_encoded, SmbiosEntryPointType ep_type);
void smbios_set_default_processor_family(uint16_t processor_family);
-uint8_t *smbios_get_table_legacy(MachineState *ms, size_t *length);
+uint8_t *smbios_get_table_legacy(uint32_t expected_t4_count, size_t *length);
void smbios_get_tables(MachineState *ms,
const struct smbios_phys_mem_area *mem_array,
const unsigned int mem_array_size,
diff --git a/hw/i386/fw_cfg.c b/hw/i386/fw_cfg.c
index a635234e68..fcb4fb0769 100644
--- a/hw/i386/fw_cfg.c
+++ b/hw/i386/fw_cfg.c
@@ -70,7 +70,7 @@ void fw_cfg_build_smbios(PCMachineState *pcms, FWCfgState *fw_cfg)
/* tell smbios about cpuid version and features */
smbios_set_cpuid(cpu->env.cpuid_version, cpu->env.features[FEAT_1_EDX]);
- smbios_tables = smbios_get_table_legacy(ms, &smbios_tables_len);
+ smbios_tables = smbios_get_table_legacy(ms->smp.cpus, &smbios_tables_len);
if (smbios_tables) {
fw_cfg_add_bytes(fw_cfg, FW_CFG_SMBIOS_ENTRIES,
smbios_tables, smbios_tables_len);
diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c
index 8e86c62184..15339d8dbe 100644
--- a/hw/smbios/smbios.c
+++ b/hw/smbios/smbios.c
@@ -70,7 +70,7 @@ static SmbiosEntryPoint ep;
static int smbios_type4_count = 0;
static bool smbios_immutable;
static bool smbios_have_defaults;
-static uint32_t smbios_cpuid_version, smbios_cpuid_features, smbios_smp_sockets;
+static uint32_t smbios_cpuid_version, smbios_cpuid_features;
static DECLARE_BITMAP(have_binfile_bitmap, SMBIOS_MAX_TYPE+1);
static DECLARE_BITMAP(have_fields_bitmap, SMBIOS_MAX_TYPE+1);
@@ -476,14 +476,11 @@ opts_init(smbios_register_config);
*/
#define SMBIOS_21_MAX_TABLES_LEN 0xffff
-static void smbios_validate_table(MachineState *ms)
+static void smbios_validate_table(uint32_t expected_t4_count)
{
- uint32_t expect_t4_count = smbios_legacy ?
- ms->smp.cpus : smbios_smp_sockets;
-
- if (smbios_type4_count && smbios_type4_count != expect_t4_count) {
+ if (smbios_type4_count && smbios_type4_count != expected_t4_count) {
error_report("Expected %d SMBIOS Type 4 tables, got %d instead",
- expect_t4_count, smbios_type4_count);
+ expected_t4_count, smbios_type4_count);
exit(1);
}
@@ -571,7 +568,7 @@ static void smbios_build_type_1_fields(void)
}
}
-uint8_t *smbios_get_table_legacy(MachineState *ms, size_t *length)
+uint8_t *smbios_get_table_legacy(uint32_t expected_t4_count, size_t *length)
{
if (!smbios_legacy) {
*length = 0;
@@ -581,7 +578,7 @@ uint8_t *smbios_get_table_legacy(MachineState *ms, size_t *length)
if (!smbios_immutable) {
smbios_build_type_0_fields();
smbios_build_type_1_fields();
- smbios_validate_table(ms);
+ smbios_validate_table(expected_t4_count);
smbios_immutable = true;
}
*length = smbios_entries_len;
@@ -1112,10 +1109,9 @@ void smbios_get_tables(MachineState *ms,
smbios_build_type_2_table();
smbios_build_type_3_table();
- smbios_smp_sockets = ms->smp.sockets;
- assert(smbios_smp_sockets >= 1);
+ assert(ms->smp.sockets >= 1);
- for (i = 0; i < smbios_smp_sockets; i++) {
+ for (i = 0; i < ms->smp.sockets; i++) {
smbios_build_type_4_table(ms, i);
}
@@ -1160,7 +1156,7 @@ void smbios_get_tables(MachineState *ms,
smbios_build_type_41_table(errp);
smbios_build_type_127_table();
- smbios_validate_table(ms);
+ smbios_validate_table(ms->smp.sockets);
smbios_entry_point_setup();
smbios_immutable = true;
}
--
2.39.3
^ permalink raw reply related [flat|nested] 37+ messages in thread
* [PATCH v2 06/20] smbios: get rid of smbios_legacy global
2024-03-05 15:57 [PATCH v2 00/20] Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS Igor Mammedov
` (4 preceding siblings ...)
2024-03-05 15:57 ` [PATCH v2 05/20] smbios: get rid of smbios_smp_sockets global Igor Mammedov
@ 2024-03-05 15:57 ` Igor Mammedov
2024-03-05 15:57 ` [PATCH v2 07/20] smbios: avoid mangling user provided tables Igor Mammedov
` (13 subsequent siblings)
19 siblings, 0 replies; 37+ messages in thread
From: Igor Mammedov @ 2024-03-05 15:57 UTC (permalink / raw)
To: qemu-devel
Cc: peter.maydell, pbonzini, mst, gaosong, alistair.francis, palmer,
bin.meng, liwei1518, dbarboza, zhiwei_liu, imammedo, anisinha,
philmd, wangyanan55, eblake, armbru, qemu-arm, qemu-riscv,
f.ebner
clean up smbios_set_defaults() which is reused by legacy
and non legacy machines from being aware of 'legacy' notion
and need to turn it off. And push legacy handling up to
PC machine code where it's relevant.
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Ani Sinha <anisinha@redhat.com>
Acked-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Tested-by: Fiona Ebner <f.ebner@proxmox.com>
---
PS: I've moved/kept legacy smbios_entries to smbios_get_tables()
but it at least is not visible to API users. To get rid of it
as well, it would be necessary to change how '-smbios' CLI
option is processed. Which is done later in the series.
---
include/hw/firmware/smbios.h | 2 +-
hw/arm/virt.c | 2 +-
hw/i386/fw_cfg.c | 7 ++++---
hw/loongarch/virt.c | 2 +-
hw/riscv/virt.c | 2 +-
hw/smbios/smbios.c | 35 +++++++++++++++--------------------
6 files changed, 23 insertions(+), 27 deletions(-)
diff --git a/include/hw/firmware/smbios.h b/include/hw/firmware/smbios.h
index a187fbbd3d..0818184834 100644
--- a/include/hw/firmware/smbios.h
+++ b/include/hw/firmware/smbios.h
@@ -293,7 +293,7 @@ struct smbios_type_127 {
void smbios_entry_add(QemuOpts *opts, Error **errp);
void smbios_set_cpuid(uint32_t version, uint32_t features);
void smbios_set_defaults(const char *manufacturer, const char *product,
- const char *version, bool legacy_mode,
+ const char *version,
bool uuid_encoded, SmbiosEntryPointType ep_type);
void smbios_set_default_processor_family(uint16_t processor_family);
uint8_t *smbios_get_table_legacy(uint32_t expected_t4_count, size_t *length);
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 0af1943697..8588681f27 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -1633,7 +1633,7 @@ static void virt_build_smbios(VirtMachineState *vms)
}
smbios_set_defaults("QEMU", product,
- vmc->smbios_old_sys_ver ? "1.0" : mc->name, false,
+ vmc->smbios_old_sys_ver ? "1.0" : mc->name,
true, SMBIOS_ENTRY_POINT_TYPE_64);
/* build the array of physical mem area from base_memmap */
diff --git a/hw/i386/fw_cfg.c b/hw/i386/fw_cfg.c
index fcb4fb0769..c1e9c0fd9c 100644
--- a/hw/i386/fw_cfg.c
+++ b/hw/i386/fw_cfg.c
@@ -63,15 +63,16 @@ void fw_cfg_build_smbios(PCMachineState *pcms, FWCfgState *fw_cfg)
if (pcmc->smbios_defaults) {
/* These values are guest ABI, do not change */
smbios_set_defaults("QEMU", mc->desc, mc->name,
- pcmc->smbios_legacy_mode, pcmc->smbios_uuid_encoded,
+ pcmc->smbios_uuid_encoded,
pcms->smbios_entry_point_type);
}
/* tell smbios about cpuid version and features */
smbios_set_cpuid(cpu->env.cpuid_version, cpu->env.features[FEAT_1_EDX]);
- smbios_tables = smbios_get_table_legacy(ms->smp.cpus, &smbios_tables_len);
- if (smbios_tables) {
+ if (pcmc->smbios_legacy_mode) {
+ smbios_tables = smbios_get_table_legacy(ms->smp.cpus,
+ &smbios_tables_len);
fw_cfg_add_bytes(fw_cfg, FW_CFG_SMBIOS_ENTRIES,
smbios_tables, smbios_tables_len);
return;
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
index 1e98d8bda5..8c7601ef91 100644
--- a/hw/loongarch/virt.c
+++ b/hw/loongarch/virt.c
@@ -355,7 +355,7 @@ static void virt_build_smbios(LoongArchMachineState *lams)
return;
}
- smbios_set_defaults("QEMU", product, mc->name, false,
+ smbios_set_defaults("QEMU", product, mc->name,
true, SMBIOS_ENTRY_POINT_TYPE_64);
smbios_get_tables(ms, NULL, 0, &smbios_tables, &smbios_tables_len,
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index fd35c74781..e2c9529df2 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -1235,7 +1235,7 @@ static void virt_build_smbios(RISCVVirtState *s)
product = "KVM Virtual Machine";
}
- smbios_set_defaults("QEMU", product, mc->name, false,
+ smbios_set_defaults("QEMU", product, mc->name,
true, SMBIOS_ENTRY_POINT_TYPE_64);
if (riscv_is_32bit(&s->soc[0])) {
diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c
index 15339d8dbe..c46fc93357 100644
--- a/hw/smbios/smbios.c
+++ b/hw/smbios/smbios.c
@@ -54,7 +54,6 @@ struct smbios_table {
static uint8_t *smbios_entries;
static size_t smbios_entries_len;
-static bool smbios_legacy = true;
static bool smbios_uuid_encoded = true;
/* end: legacy structures & constants for <= 2.0 machines */
@@ -570,9 +569,16 @@ static void smbios_build_type_1_fields(void)
uint8_t *smbios_get_table_legacy(uint32_t expected_t4_count, size_t *length)
{
- if (!smbios_legacy) {
- *length = 0;
- return NULL;
+ /* drop unwanted version of command-line file blob(s) */
+ g_free(smbios_tables);
+ smbios_tables = NULL;
+
+ /* also complain if fields were given for types > 1 */
+ if (find_next_bit(have_fields_bitmap,
+ SMBIOS_MAX_TYPE + 1, 2) < SMBIOS_MAX_TYPE + 1) {
+ error_report("can't process fields for smbios "
+ "types > 1 on machine versions < 2.1!");
+ exit(1);
}
if (!smbios_immutable) {
@@ -1006,28 +1012,13 @@ void smbios_set_default_processor_family(uint16_t processor_family)
}
void smbios_set_defaults(const char *manufacturer, const char *product,
- const char *version, bool legacy_mode,
+ const char *version,
bool uuid_encoded, SmbiosEntryPointType ep_type)
{
smbios_have_defaults = true;
- smbios_legacy = legacy_mode;
smbios_uuid_encoded = uuid_encoded;
smbios_ep_type = ep_type;
- /* drop unwanted version of command-line file blob(s) */
- if (smbios_legacy) {
- g_free(smbios_tables);
- /* in legacy mode, also complain if fields were given for types > 1 */
- if (find_next_bit(have_fields_bitmap,
- SMBIOS_MAX_TYPE+1, 2) < SMBIOS_MAX_TYPE+1) {
- error_report("can't process fields for smbios "
- "types > 1 on machine versions < 2.1!");
- exit(1);
- }
- } else {
- g_free(smbios_entries);
- }
-
SMBIOS_SET_DEFAULT(type1.manufacturer, manufacturer);
SMBIOS_SET_DEFAULT(type1.product, product);
SMBIOS_SET_DEFAULT(type1.version, version);
@@ -1103,6 +1094,10 @@ void smbios_get_tables(MachineState *ms,
{
unsigned i, dimm_cnt, offset;
+ /* drop unwanted (legacy) version of command-line file blob(s) */
+ g_free(smbios_entries);
+ smbios_entries = NULL;
+
if (!smbios_immutable) {
smbios_build_type_0_table();
smbios_build_type_1_table();
--
2.39.3
^ permalink raw reply related [flat|nested] 37+ messages in thread
* [PATCH v2 07/20] smbios: avoid mangling user provided tables
2024-03-05 15:57 [PATCH v2 00/20] Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS Igor Mammedov
` (5 preceding siblings ...)
2024-03-05 15:57 ` [PATCH v2 06/20] smbios: get rid of smbios_legacy global Igor Mammedov
@ 2024-03-05 15:57 ` Igor Mammedov
2024-03-06 6:41 ` Ani Sinha
2024-03-05 15:57 ` [PATCH v2 08/20] smbios: don't check type4 structures in legacy mode Igor Mammedov
` (12 subsequent siblings)
19 siblings, 1 reply; 37+ messages in thread
From: Igor Mammedov @ 2024-03-05 15:57 UTC (permalink / raw)
To: qemu-devel
Cc: peter.maydell, pbonzini, mst, gaosong, alistair.francis, palmer,
bin.meng, liwei1518, dbarboza, zhiwei_liu, imammedo, anisinha,
philmd, wangyanan55, eblake, armbru, qemu-arm, qemu-riscv,
f.ebner
currently smbios_entry_add() preserves internally '-smbios type='
options but tables provided with '-smbios file=' are stored directly
into blob that eventually will be exposed to VM. And then later
QEMU adds default/'-smbios type' entries on top into the same blob.
It makes impossible to generate tables more than once, hence
'immutable' guard was used.
Make it possible to regenerate final blob by storing user provided
blobs into a dedicated area (usr_blobs) and then copy it when
composing final blob. Which also makes handling of -smbios
options consistent.
As side effect of this and previous commits there is no need to
generate legacy smbios_entries at the time options are parsed.
Instead compose smbios_entries on demand from usr_blobs like
it is done for non-legacy SMBIOS tables.
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Tested-by: Fiona Ebner <f.ebner@proxmox.com>
---
hw/smbios/smbios.c | 179 +++++++++++++++++++++++----------------------
1 file changed, 92 insertions(+), 87 deletions(-)
diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c
index c46fc93357..aa2cc5bdbd 100644
--- a/hw/smbios/smbios.c
+++ b/hw/smbios/smbios.c
@@ -57,6 +57,14 @@ static size_t smbios_entries_len;
static bool smbios_uuid_encoded = true;
/* end: legacy structures & constants for <= 2.0 machines */
+/*
+ * SMBIOS tables provided by user with '-smbios file=<foo>' option
+ */
+uint8_t *usr_blobs;
+size_t usr_blobs_len;
+static GArray *usr_blobs_sizes;
+static unsigned usr_table_max;
+static unsigned usr_table_cnt;
uint8_t *smbios_tables;
size_t smbios_tables_len;
@@ -67,7 +75,6 @@ static SmbiosEntryPointType smbios_ep_type = SMBIOS_ENTRY_POINT_TYPE_32;
static SmbiosEntryPoint ep;
static int smbios_type4_count = 0;
-static bool smbios_immutable;
static bool smbios_have_defaults;
static uint32_t smbios_cpuid_version, smbios_cpuid_features;
@@ -569,9 +576,8 @@ static void smbios_build_type_1_fields(void)
uint8_t *smbios_get_table_legacy(uint32_t expected_t4_count, size_t *length)
{
- /* drop unwanted version of command-line file blob(s) */
- g_free(smbios_tables);
- smbios_tables = NULL;
+ int i;
+ size_t usr_offset;
/* also complain if fields were given for types > 1 */
if (find_next_bit(have_fields_bitmap,
@@ -581,12 +587,33 @@ uint8_t *smbios_get_table_legacy(uint32_t expected_t4_count, size_t *length)
exit(1);
}
- if (!smbios_immutable) {
- smbios_build_type_0_fields();
- smbios_build_type_1_fields();
- smbios_validate_table(expected_t4_count);
- smbios_immutable = true;
+ g_free(smbios_entries);
+ smbios_entries_len = sizeof(uint16_t);
+ smbios_entries = g_malloc0(smbios_entries_len);
+
+ for (i = 0, usr_offset = 0; usr_blobs_sizes && i < usr_blobs_sizes->len;
+ i++)
+ {
+ struct smbios_table *table;
+ struct smbios_structure_header *header;
+ size_t size = g_array_index(usr_blobs_sizes, size_t, i);
+
+ header = (struct smbios_structure_header *)(usr_blobs + usr_offset);
+ smbios_entries = g_realloc(smbios_entries, smbios_entries_len +
+ size + sizeof(*table));
+ table = (struct smbios_table *)(smbios_entries + smbios_entries_len);
+ table->header.type = SMBIOS_TABLE_ENTRY;
+ table->header.length = cpu_to_le16(sizeof(*table) + size);
+ memcpy(table->data, header, size);
+ smbios_entries_len += sizeof(*table) + size;
+ (*(uint16_t *)smbios_entries) =
+ cpu_to_le16(le16_to_cpu(*(uint16_t *)smbios_entries) + 1);
+ usr_offset += size;
}
+
+ smbios_build_type_0_fields();
+ smbios_build_type_1_fields();
+ smbios_validate_table(expected_t4_count);
*length = smbios_entries_len;
return smbios_entries;
}
@@ -1094,67 +1121,67 @@ void smbios_get_tables(MachineState *ms,
{
unsigned i, dimm_cnt, offset;
- /* drop unwanted (legacy) version of command-line file blob(s) */
- g_free(smbios_entries);
- smbios_entries = NULL;
+ g_free(smbios_tables);
+ smbios_tables = g_memdup2(usr_blobs, usr_blobs_len);
+ smbios_tables_len = usr_blobs_len;
+ smbios_table_max = usr_table_max;
+ smbios_table_cnt = usr_table_cnt;
- if (!smbios_immutable) {
- smbios_build_type_0_table();
- smbios_build_type_1_table();
- smbios_build_type_2_table();
- smbios_build_type_3_table();
+ smbios_build_type_0_table();
+ smbios_build_type_1_table();
+ smbios_build_type_2_table();
+ smbios_build_type_3_table();
- assert(ms->smp.sockets >= 1);
+ assert(ms->smp.sockets >= 1);
- for (i = 0; i < ms->smp.sockets; i++) {
- smbios_build_type_4_table(ms, i);
- }
+ for (i = 0; i < ms->smp.sockets; i++) {
+ smbios_build_type_4_table(ms, i);
+ }
- smbios_build_type_8_table();
- smbios_build_type_11_table();
+ smbios_build_type_8_table();
+ smbios_build_type_11_table();
#define MAX_DIMM_SZ (16 * GiB)
#define GET_DIMM_SZ ((i < dimm_cnt - 1) ? MAX_DIMM_SZ \
: ((current_machine->ram_size - 1) % MAX_DIMM_SZ) + 1)
- dimm_cnt = QEMU_ALIGN_UP(current_machine->ram_size, MAX_DIMM_SZ) / MAX_DIMM_SZ;
+ dimm_cnt = QEMU_ALIGN_UP(current_machine->ram_size, MAX_DIMM_SZ) /
+ MAX_DIMM_SZ;
- /*
- * The offset determines if we need to keep additional space between
- * table 17 and table 19 header handle numbers so that they do
- * not overlap. For example, for a VM with larger than 8 TB guest
- * memory and DIMM like chunks of 16 GiB, the default space between
- * the two tables (T19_BASE - T17_BASE = 512) is not enough.
- */
- offset = (dimm_cnt > (T19_BASE - T17_BASE)) ? \
- dimm_cnt - (T19_BASE - T17_BASE) : 0;
+ /*
+ * The offset determines if we need to keep additional space between
+ * table 17 and table 19 header handle numbers so that they do
+ * not overlap. For example, for a VM with larger than 8 TB guest
+ * memory and DIMM like chunks of 16 GiB, the default space between
+ * the two tables (T19_BASE - T17_BASE = 512) is not enough.
+ */
+ offset = (dimm_cnt > (T19_BASE - T17_BASE)) ? \
+ dimm_cnt - (T19_BASE - T17_BASE) : 0;
- smbios_build_type_16_table(dimm_cnt);
+ smbios_build_type_16_table(dimm_cnt);
- for (i = 0; i < dimm_cnt; i++) {
- smbios_build_type_17_table(i, GET_DIMM_SZ);
- }
+ for (i = 0; i < dimm_cnt; i++) {
+ smbios_build_type_17_table(i, GET_DIMM_SZ);
+ }
- for (i = 0; i < mem_array_size; i++) {
- smbios_build_type_19_table(i, offset, mem_array[i].address,
- mem_array[i].length);
- }
+ for (i = 0; i < mem_array_size; i++) {
+ smbios_build_type_19_table(i, offset, mem_array[i].address,
+ mem_array[i].length);
+ }
- /*
- * make sure 16 bit handle numbers in the headers of tables 19
- * and 32 do not overlap.
- */
- assert((mem_array_size + offset) < (T32_BASE - T19_BASE));
+ /*
+ * make sure 16 bit handle numbers in the headers of tables 19
+ * and 32 do not overlap.
+ */
+ assert((mem_array_size + offset) < (T32_BASE - T19_BASE));
- smbios_build_type_32_table();
- smbios_build_type_38_table();
- smbios_build_type_41_table(errp);
- smbios_build_type_127_table();
+ smbios_build_type_32_table();
+ smbios_build_type_38_table();
+ smbios_build_type_41_table(errp);
+ smbios_build_type_127_table();
- smbios_validate_table(ms->smp.sockets);
- smbios_entry_point_setup();
- smbios_immutable = true;
- }
+ smbios_validate_table(ms->smp.sockets);
+ smbios_entry_point_setup();
/* return tables blob and entry point (anchor), and their sizes */
*tables = smbios_tables;
@@ -1254,13 +1281,10 @@ void smbios_entry_add(QemuOpts *opts, Error **errp)
{
const char *val;
- assert(!smbios_immutable);
-
val = qemu_opt_get(opts, "file");
if (val) {
struct smbios_structure_header *header;
- int size;
- struct smbios_table *table; /* legacy mode only */
+ size_t size;
if (!qemu_opts_validate(opts, qemu_smbios_file_opts, errp)) {
return;
@@ -1277,9 +1301,9 @@ void smbios_entry_add(QemuOpts *opts, Error **errp)
* (except in legacy mode, where the second '\0' is implicit and
* will be inserted by the BIOS).
*/
- smbios_tables = g_realloc(smbios_tables, smbios_tables_len + size);
- header = (struct smbios_structure_header *)(smbios_tables +
- smbios_tables_len);
+ usr_blobs = g_realloc(usr_blobs, usr_blobs_len + size);
+ header = (struct smbios_structure_header *)(usr_blobs +
+ usr_blobs_len);
if (load_image_size(val, (uint8_t *)header, size) != size) {
error_setg(errp, "Failed to load SMBIOS file %s", val);
@@ -1300,34 +1324,15 @@ void smbios_entry_add(QemuOpts *opts, Error **errp)
smbios_type4_count++;
}
- smbios_tables_len += size;
- if (size > smbios_table_max) {
- smbios_table_max = size;
+ if (!usr_blobs_sizes) {
+ usr_blobs_sizes = g_array_new(false, false, sizeof(size_t));
}
- smbios_table_cnt++;
-
- /* add a copy of the newly loaded blob to legacy smbios_entries */
- /* NOTE: This code runs before smbios_set_defaults(), so we don't
- * yet know which mode (legacy vs. aggregate-table) will be
- * required. We therefore add the binary blob to both legacy
- * (smbios_entries) and aggregate (smbios_tables) tables, and
- * delete the one we don't need from smbios_set_defaults(),
- * once we know which machine version has been requested.
- */
- if (!smbios_entries) {
- smbios_entries_len = sizeof(uint16_t);
- smbios_entries = g_malloc0(smbios_entries_len);
+ g_array_append_val(usr_blobs_sizes, size);
+ usr_blobs_len += size;
+ if (size > usr_table_max) {
+ usr_table_max = size;
}
- smbios_entries = g_realloc(smbios_entries, smbios_entries_len +
- size + sizeof(*table));
- table = (struct smbios_table *)(smbios_entries + smbios_entries_len);
- table->header.type = SMBIOS_TABLE_ENTRY;
- table->header.length = cpu_to_le16(sizeof(*table) + size);
- memcpy(table->data, header, size);
- smbios_entries_len += sizeof(*table) + size;
- (*(uint16_t *)smbios_entries) =
- cpu_to_le16(le16_to_cpu(*(uint16_t *)smbios_entries) + 1);
- /* end: add a copy of the newly loaded blob to legacy smbios_entries */
+ usr_table_cnt++;
return;
}
--
2.39.3
^ permalink raw reply related [flat|nested] 37+ messages in thread
* [PATCH v2 08/20] smbios: don't check type4 structures in legacy mode
2024-03-05 15:57 [PATCH v2 00/20] Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS Igor Mammedov
` (6 preceding siblings ...)
2024-03-05 15:57 ` [PATCH v2 07/20] smbios: avoid mangling user provided tables Igor Mammedov
@ 2024-03-05 15:57 ` Igor Mammedov
2024-03-05 15:57 ` [PATCH v2 09/20] smbios: add smbios_add_usr_blob_size() helper Igor Mammedov
` (11 subsequent siblings)
19 siblings, 0 replies; 37+ messages in thread
From: Igor Mammedov @ 2024-03-05 15:57 UTC (permalink / raw)
To: qemu-devel
Cc: peter.maydell, pbonzini, mst, gaosong, alistair.francis, palmer,
bin.meng, liwei1518, dbarboza, zhiwei_liu, imammedo, anisinha,
philmd, wangyanan55, eblake, armbru, qemu-arm, qemu-riscv,
f.ebner
legacy mode doesn't support structures of type 2 and more,
and CLI has a check for '-smbios type' option, however it's
still possible to sneak in type4 as a blob with '-smbios file'
option. However doing the later makes SMBIOS tables broken
since SeaBIOS doesn't expect that.
Rather than trying to add support for type4 to legacy code
(both QEMU and SeaBIOS), simplify smbios_get_table_legacy()
by dropping not relevant check in legacy code and error out
on type4 blob.
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Ani Sinha <anisinha@redhat.com>
Tested-by: Fiona Ebner <f.ebner@proxmox.com>
---
* The issue affects 'isapc' and pc-i440fx-2.0. the later is
in deprecated state and to be dropped in near future
* possibly the same issue applies to other SMBIOS types above type 1
but I haven't tested that, and well tables that aren't
generated by SeaBIOS can get be added just fine
(tested type11 blob). So I went with a minimal change
to fixup type4 only that I'm touching. Leaving the rest
for other time or when someone complains about it, which is
very unlikely given it's really only remaining isapc machine.
I'd very much prefer to deprecate 'isapc' and then drop
all legacy related code (it will benefit not only SMBIOS
but other code as well).
BTW: 'isapc' is in semi-dead, I cna't boot RHEL6 on it
with KVM enabled anymore (RHEL9 host), TCG still boots though.
One more reason to get deprecate it.
---
include/hw/firmware/smbios.h | 2 +-
hw/i386/fw_cfg.c | 3 +--
hw/smbios/smbios.c | 18 ++++++++++++++----
3 files changed, 16 insertions(+), 7 deletions(-)
diff --git a/include/hw/firmware/smbios.h b/include/hw/firmware/smbios.h
index 0818184834..1fbff3c55f 100644
--- a/include/hw/firmware/smbios.h
+++ b/include/hw/firmware/smbios.h
@@ -296,7 +296,7 @@ void smbios_set_defaults(const char *manufacturer, const char *product,
const char *version,
bool uuid_encoded, SmbiosEntryPointType ep_type);
void smbios_set_default_processor_family(uint16_t processor_family);
-uint8_t *smbios_get_table_legacy(uint32_t expected_t4_count, size_t *length);
+uint8_t *smbios_get_table_legacy(size_t *length);
void smbios_get_tables(MachineState *ms,
const struct smbios_phys_mem_area *mem_array,
const unsigned int mem_array_size,
diff --git a/hw/i386/fw_cfg.c b/hw/i386/fw_cfg.c
index c1e9c0fd9c..d1281066f4 100644
--- a/hw/i386/fw_cfg.c
+++ b/hw/i386/fw_cfg.c
@@ -71,8 +71,7 @@ void fw_cfg_build_smbios(PCMachineState *pcms, FWCfgState *fw_cfg)
smbios_set_cpuid(cpu->env.cpuid_version, cpu->env.features[FEAT_1_EDX]);
if (pcmc->smbios_legacy_mode) {
- smbios_tables = smbios_get_table_legacy(ms->smp.cpus,
- &smbios_tables_len);
+ smbios_tables = smbios_get_table_legacy(&smbios_tables_len);
fw_cfg_add_bytes(fw_cfg, FW_CFG_SMBIOS_ENTRIES,
smbios_tables, smbios_tables_len);
return;
diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c
index aa2cc5bdbd..97cf762228 100644
--- a/hw/smbios/smbios.c
+++ b/hw/smbios/smbios.c
@@ -482,14 +482,17 @@ opts_init(smbios_register_config);
*/
#define SMBIOS_21_MAX_TABLES_LEN 0xffff
-static void smbios_validate_table(uint32_t expected_t4_count)
+static void smbios_check_type4_count(uint32_t expected_t4_count)
{
if (smbios_type4_count && smbios_type4_count != expected_t4_count) {
error_report("Expected %d SMBIOS Type 4 tables, got %d instead",
expected_t4_count, smbios_type4_count);
exit(1);
}
+}
+static void smbios_validate_table(void)
+{
if (smbios_ep_type == SMBIOS_ENTRY_POINT_TYPE_32 &&
smbios_tables_len > SMBIOS_21_MAX_TABLES_LEN) {
error_report("SMBIOS 2.1 table length %zu exceeds %d",
@@ -574,7 +577,7 @@ static void smbios_build_type_1_fields(void)
}
}
-uint8_t *smbios_get_table_legacy(uint32_t expected_t4_count, size_t *length)
+uint8_t *smbios_get_table_legacy(size_t *length)
{
int i;
size_t usr_offset;
@@ -587,6 +590,12 @@ uint8_t *smbios_get_table_legacy(uint32_t expected_t4_count, size_t *length)
exit(1);
}
+ if (test_bit(4, have_binfile_bitmap)) {
+ error_report("can't process table for smbios "
+ "type 4 on machine versions < 2.1!");
+ exit(1);
+ }
+
g_free(smbios_entries);
smbios_entries_len = sizeof(uint16_t);
smbios_entries = g_malloc0(smbios_entries_len);
@@ -613,7 +622,7 @@ uint8_t *smbios_get_table_legacy(uint32_t expected_t4_count, size_t *length)
smbios_build_type_0_fields();
smbios_build_type_1_fields();
- smbios_validate_table(expected_t4_count);
+ smbios_validate_table();
*length = smbios_entries_len;
return smbios_entries;
}
@@ -1180,7 +1189,8 @@ void smbios_get_tables(MachineState *ms,
smbios_build_type_41_table(errp);
smbios_build_type_127_table();
- smbios_validate_table(ms->smp.sockets);
+ smbios_check_type4_count(ms->smp.sockets);
+ smbios_validate_table();
smbios_entry_point_setup();
/* return tables blob and entry point (anchor), and their sizes */
--
2.39.3
^ permalink raw reply related [flat|nested] 37+ messages in thread
* [PATCH v2 09/20] smbios: add smbios_add_usr_blob_size() helper
2024-03-05 15:57 [PATCH v2 00/20] Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS Igor Mammedov
` (7 preceding siblings ...)
2024-03-05 15:57 ` [PATCH v2 08/20] smbios: don't check type4 structures in legacy mode Igor Mammedov
@ 2024-03-05 15:57 ` Igor Mammedov
2024-03-06 6:48 ` Ani Sinha
2024-03-05 15:57 ` [PATCH v2 10/20] smbios: rename/expose structures/bitmaps used by both legacy and modern code Igor Mammedov
` (10 subsequent siblings)
19 siblings, 1 reply; 37+ messages in thread
From: Igor Mammedov @ 2024-03-05 15:57 UTC (permalink / raw)
To: qemu-devel
Cc: peter.maydell, pbonzini, mst, gaosong, alistair.francis, palmer,
bin.meng, liwei1518, dbarboza, zhiwei_liu, imammedo, anisinha,
philmd, wangyanan55, eblake, armbru, qemu-arm, qemu-riscv,
f.ebner
it will be used by follow up patch when legacy handling
is moved out into a separate file.
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
hw/smbios/smbios.c | 18 ++++++++++++++----
1 file changed, 14 insertions(+), 4 deletions(-)
diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c
index 97cf762228..01180bd82c 100644
--- a/hw/smbios/smbios.c
+++ b/hw/smbios/smbios.c
@@ -1287,6 +1287,14 @@ static bool save_opt_list(size_t *ndest, char ***dest, QemuOpts *opts,
return true;
}
+static void smbios_add_usr_blob_size(size_t size)
+{
+ if (!usr_blobs_sizes) {
+ usr_blobs_sizes = g_array_new(false, false, sizeof(size_t));
+ }
+ g_array_append_val(usr_blobs_sizes, size);
+}
+
void smbios_entry_add(QemuOpts *opts, Error **errp)
{
const char *val;
@@ -1334,10 +1342,12 @@ void smbios_entry_add(QemuOpts *opts, Error **errp)
smbios_type4_count++;
}
- if (!usr_blobs_sizes) {
- usr_blobs_sizes = g_array_new(false, false, sizeof(size_t));
- }
- g_array_append_val(usr_blobs_sizes, size);
+ /*
+ * preserve blob size for legacy mode so it could build its
+ * blobs flavor from 'usr_blobs'
+ */
+ smbios_add_usr_blob_size(size);
+
usr_blobs_len += size;
if (size > usr_table_max) {
usr_table_max = size;
--
2.39.3
^ permalink raw reply related [flat|nested] 37+ messages in thread
* [PATCH v2 10/20] smbios: rename/expose structures/bitmaps used by both legacy and modern code
2024-03-05 15:57 [PATCH v2 00/20] Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS Igor Mammedov
` (8 preceding siblings ...)
2024-03-05 15:57 ` [PATCH v2 09/20] smbios: add smbios_add_usr_blob_size() helper Igor Mammedov
@ 2024-03-05 15:57 ` Igor Mammedov
2024-03-06 7:15 ` Ani Sinha
2024-03-05 15:57 ` [PATCH v2 11/20] smbios: build legacy mode code only for 'pc' machine Igor Mammedov
` (9 subsequent siblings)
19 siblings, 1 reply; 37+ messages in thread
From: Igor Mammedov @ 2024-03-05 15:57 UTC (permalink / raw)
To: qemu-devel
Cc: peter.maydell, pbonzini, mst, gaosong, alistair.francis, palmer,
bin.meng, liwei1518, dbarboza, zhiwei_liu, imammedo, anisinha,
philmd, wangyanan55, eblake, armbru, qemu-arm, qemu-riscv,
f.ebner
As a preparation to move legacy handling into a separate file,
add prefix 'smbios_' to type0/type1/have_binfile_bitmap/have_fields_bitmap
and expose them in smbios.h so that they can be reused in
legacy and modern code.
Doing it as a separate patch to avoid rename cluttering follow-up
patch which will move legacy code into a separate file.
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
include/hw/firmware/smbios.h | 16 +++++
hw/smbios/smbios.c | 113 ++++++++++++++++-------------------
2 files changed, 69 insertions(+), 60 deletions(-)
diff --git a/include/hw/firmware/smbios.h b/include/hw/firmware/smbios.h
index 1fbff3c55f..bea5c3f1b1 100644
--- a/include/hw/firmware/smbios.h
+++ b/include/hw/firmware/smbios.h
@@ -2,6 +2,7 @@
#define QEMU_SMBIOS_H
#include "qapi/qapi-types-machine.h"
+#include "qemu/bitmap.h"
/*
* SMBIOS Support
@@ -16,8 +17,23 @@
*
*/
+typedef struct {
+ const char *vendor, *version, *date;
+ bool have_major_minor, uefi;
+ uint8_t major, minor;
+} smbios_type0_t;
+extern smbios_type0_t smbios_type0;
+
+typedef struct {
+ const char *manufacturer, *product, *version, *serial, *sku, *family;
+ /* uuid is in qemu_uuid */
+} smbios_type1_t;
+extern smbios_type1_t smbios_type1;
#define SMBIOS_MAX_TYPE 127
+extern DECLARE_BITMAP(smbios_have_binfile_bitmap, SMBIOS_MAX_TYPE + 1);
+extern DECLARE_BITMAP(smbios_have_fields_bitmap, SMBIOS_MAX_TYPE + 1);
+
#define offsetofend(TYPE, MEMBER) \
(offsetof(TYPE, MEMBER) + sizeof_field(TYPE, MEMBER))
diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c
index 01180bd82c..86cf66b5ce 100644
--- a/hw/smbios/smbios.c
+++ b/hw/smbios/smbios.c
@@ -78,19 +78,11 @@ static int smbios_type4_count = 0;
static bool smbios_have_defaults;
static uint32_t smbios_cpuid_version, smbios_cpuid_features;
-static DECLARE_BITMAP(have_binfile_bitmap, SMBIOS_MAX_TYPE+1);
-static DECLARE_BITMAP(have_fields_bitmap, SMBIOS_MAX_TYPE+1);
+DECLARE_BITMAP(smbios_have_binfile_bitmap, SMBIOS_MAX_TYPE + 1);
+DECLARE_BITMAP(smbios_have_fields_bitmap, SMBIOS_MAX_TYPE + 1);
-static struct {
- const char *vendor, *version, *date;
- bool have_major_minor, uefi;
- uint8_t major, minor;
-} type0;
-
-static struct {
- const char *manufacturer, *product, *version, *serial, *sku, *family;
- /* uuid is in qemu_uuid */
-} type1;
+smbios_type0_t smbios_type0;
+smbios_type1_t smbios_type1;
static struct {
const char *manufacturer, *product, *version, *serial, *asset, *location;
@@ -536,36 +528,36 @@ static void smbios_maybe_add_str(int type, int offset, const char *data)
static void smbios_build_type_0_fields(void)
{
smbios_maybe_add_str(0, offsetof(struct smbios_type_0, vendor_str),
- type0.vendor);
+ smbios_type0.vendor);
smbios_maybe_add_str(0, offsetof(struct smbios_type_0, bios_version_str),
- type0.version);
+ smbios_type0.version);
smbios_maybe_add_str(0, offsetof(struct smbios_type_0,
bios_release_date_str),
- type0.date);
- if (type0.have_major_minor) {
+ smbios_type0.date);
+ if (smbios_type0.have_major_minor) {
smbios_add_field(0, offsetof(struct smbios_type_0,
system_bios_major_release),
- &type0.major, 1);
+ &smbios_type0.major, 1);
smbios_add_field(0, offsetof(struct smbios_type_0,
system_bios_minor_release),
- &type0.minor, 1);
+ &smbios_type0.minor, 1);
}
}
static void smbios_build_type_1_fields(void)
{
smbios_maybe_add_str(1, offsetof(struct smbios_type_1, manufacturer_str),
- type1.manufacturer);
+ smbios_type1.manufacturer);
smbios_maybe_add_str(1, offsetof(struct smbios_type_1, product_name_str),
- type1.product);
+ smbios_type1.product);
smbios_maybe_add_str(1, offsetof(struct smbios_type_1, version_str),
- type1.version);
+ smbios_type1.version);
smbios_maybe_add_str(1, offsetof(struct smbios_type_1, serial_number_str),
- type1.serial);
+ smbios_type1.serial);
smbios_maybe_add_str(1, offsetof(struct smbios_type_1, sku_number_str),
- type1.sku);
+ smbios_type1.sku);
smbios_maybe_add_str(1, offsetof(struct smbios_type_1, family_str),
- type1.family);
+ smbios_type1.family);
if (qemu_uuid_set) {
/* We don't encode the UUID in the "wire format" here because this
* function is for legacy mode and needs to keep the guest ABI, and
@@ -583,14 +575,14 @@ uint8_t *smbios_get_table_legacy(size_t *length)
size_t usr_offset;
/* also complain if fields were given for types > 1 */
- if (find_next_bit(have_fields_bitmap,
+ if (find_next_bit(smbios_have_fields_bitmap,
SMBIOS_MAX_TYPE + 1, 2) < SMBIOS_MAX_TYPE + 1) {
error_report("can't process fields for smbios "
"types > 1 on machine versions < 2.1!");
exit(1);
}
- if (test_bit(4, have_binfile_bitmap)) {
+ if (test_bit(4, smbios_have_binfile_bitmap)) {
error_report("can't process table for smbios "
"type 4 on machine versions < 2.1!");
exit(1);
@@ -631,10 +623,10 @@ uint8_t *smbios_get_table_legacy(size_t *length)
bool smbios_skip_table(uint8_t type, bool required_table)
{
- if (test_bit(type, have_binfile_bitmap)) {
+ if (test_bit(type, smbios_have_binfile_bitmap)) {
return true; /* user provided their own binary blob(s) */
}
- if (test_bit(type, have_fields_bitmap)) {
+ if (test_bit(type, smbios_have_fields_bitmap)) {
return false; /* user provided fields via command line */
}
if (smbios_have_defaults && required_table) {
@@ -661,25 +653,25 @@ static void smbios_build_type_0_table(void)
{
SMBIOS_BUILD_TABLE_PRE(0, T0_BASE, false); /* optional, leave up to BIOS */
- SMBIOS_TABLE_SET_STR(0, vendor_str, type0.vendor);
- SMBIOS_TABLE_SET_STR(0, bios_version_str, type0.version);
+ SMBIOS_TABLE_SET_STR(0, vendor_str, smbios_type0.vendor);
+ SMBIOS_TABLE_SET_STR(0, bios_version_str, smbios_type0.version);
t->bios_starting_address_segment = cpu_to_le16(0xE800); /* from SeaBIOS */
- SMBIOS_TABLE_SET_STR(0, bios_release_date_str, type0.date);
+ SMBIOS_TABLE_SET_STR(0, bios_release_date_str, smbios_type0.date);
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 (type0.uefi) {
+ if (smbios_type0.uefi) {
t->bios_characteristics_extension_bytes[1] |= 0x08; /* |= UEFI */
}
- if (type0.have_major_minor) {
- t->system_bios_major_release = type0.major;
- t->system_bios_minor_release = type0.minor;
+ if (smbios_type0.have_major_minor) {
+ t->system_bios_major_release = smbios_type0.major;
+ t->system_bios_minor_release = smbios_type0.minor;
} else {
t->system_bios_major_release = 0;
t->system_bios_minor_release = 0;
@@ -709,18 +701,18 @@ static void smbios_build_type_1_table(void)
{
SMBIOS_BUILD_TABLE_PRE(1, T1_BASE, true); /* required */
- SMBIOS_TABLE_SET_STR(1, manufacturer_str, type1.manufacturer);
- SMBIOS_TABLE_SET_STR(1, product_name_str, type1.product);
- SMBIOS_TABLE_SET_STR(1, version_str, type1.version);
- SMBIOS_TABLE_SET_STR(1, serial_number_str, type1.serial);
+ SMBIOS_TABLE_SET_STR(1, manufacturer_str, smbios_type1.manufacturer);
+ SMBIOS_TABLE_SET_STR(1, product_name_str, smbios_type1.product);
+ SMBIOS_TABLE_SET_STR(1, version_str, smbios_type1.version);
+ SMBIOS_TABLE_SET_STR(1, serial_number_str, smbios_type1.serial);
if (qemu_uuid_set) {
smbios_encode_uuid(&t->uuid, &qemu_uuid);
} else {
memset(&t->uuid, 0, 16);
}
t->wake_up_type = 0x06; /* power switch */
- SMBIOS_TABLE_SET_STR(1, sku_number_str, type1.sku);
- SMBIOS_TABLE_SET_STR(1, family_str, type1.family);
+ SMBIOS_TABLE_SET_STR(1, sku_number_str, smbios_type1.sku);
+ SMBIOS_TABLE_SET_STR(1, family_str, smbios_type1.family);
SMBIOS_BUILD_TABLE_POST;
}
@@ -1055,9 +1047,9 @@ void smbios_set_defaults(const char *manufacturer, const char *product,
smbios_uuid_encoded = uuid_encoded;
smbios_ep_type = ep_type;
- SMBIOS_SET_DEFAULT(type1.manufacturer, manufacturer);
- SMBIOS_SET_DEFAULT(type1.product, product);
- SMBIOS_SET_DEFAULT(type1.version, version);
+ SMBIOS_SET_DEFAULT(smbios_type1.manufacturer, manufacturer);
+ SMBIOS_SET_DEFAULT(smbios_type1.product, product);
+ SMBIOS_SET_DEFAULT(smbios_type1.version, version);
SMBIOS_SET_DEFAULT(type2.manufacturer, manufacturer);
SMBIOS_SET_DEFAULT(type2.product, product);
SMBIOS_SET_DEFAULT(type2.version, version);
@@ -1329,13 +1321,13 @@ void smbios_entry_add(QemuOpts *opts, Error **errp)
}
if (header->type <= SMBIOS_MAX_TYPE) {
- if (test_bit(header->type, have_fields_bitmap)) {
+ if (test_bit(header->type, smbios_have_fields_bitmap)) {
error_setg(errp,
"can't load type %d struct, fields already specified!",
header->type);
return;
}
- set_bit(header->type, have_binfile_bitmap);
+ set_bit(header->type, smbios_have_binfile_bitmap);
}
if (header->type == 4) {
@@ -1366,41 +1358,42 @@ void smbios_entry_add(QemuOpts *opts, Error **errp)
return;
}
- if (test_bit(type, have_binfile_bitmap)) {
+ if (test_bit(type, smbios_have_binfile_bitmap)) {
error_setg(errp, "can't add fields, binary file already loaded!");
return;
}
- set_bit(type, have_fields_bitmap);
+ set_bit(type, smbios_have_fields_bitmap);
switch (type) {
case 0:
if (!qemu_opts_validate(opts, qemu_smbios_type0_opts, errp)) {
return;
}
- save_opt(&type0.vendor, opts, "vendor");
- save_opt(&type0.version, opts, "version");
- save_opt(&type0.date, opts, "date");
- type0.uefi = qemu_opt_get_bool(opts, "uefi", false);
+ 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);
val = qemu_opt_get(opts, "release");
if (val) {
- if (sscanf(val, "%hhu.%hhu", &type0.major, &type0.minor) != 2) {
+ if (sscanf(val, "%hhu.%hhu", &smbios_type0.major,
+ &smbios_type0.minor) != 2) {
error_setg(errp, "Invalid release");
return;
}
- type0.have_major_minor = true;
+ smbios_type0.have_major_minor = true;
}
return;
case 1:
if (!qemu_opts_validate(opts, qemu_smbios_type1_opts, errp)) {
return;
}
- save_opt(&type1.manufacturer, opts, "manufacturer");
- save_opt(&type1.product, opts, "product");
- save_opt(&type1.version, opts, "version");
- save_opt(&type1.serial, opts, "serial");
- save_opt(&type1.sku, opts, "sku");
- save_opt(&type1.family, opts, "family");
+ save_opt(&smbios_type1.manufacturer, opts, "manufacturer");
+ save_opt(&smbios_type1.product, opts, "product");
+ save_opt(&smbios_type1.version, opts, "version");
+ save_opt(&smbios_type1.serial, opts, "serial");
+ save_opt(&smbios_type1.sku, opts, "sku");
+ save_opt(&smbios_type1.family, opts, "family");
val = qemu_opt_get(opts, "uuid");
if (val) {
--
2.39.3
^ permalink raw reply related [flat|nested] 37+ messages in thread
* [PATCH v2 11/20] smbios: build legacy mode code only for 'pc' machine
2024-03-05 15:57 [PATCH v2 00/20] Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS Igor Mammedov
` (9 preceding siblings ...)
2024-03-05 15:57 ` [PATCH v2 10/20] smbios: rename/expose structures/bitmaps used by both legacy and modern code Igor Mammedov
@ 2024-03-05 15:57 ` Igor Mammedov
2024-03-06 7:27 ` Ani Sinha
2024-03-06 10:03 ` [PATCH v3 " Igor Mammedov
2024-03-05 15:57 ` [PATCH v2 12/20] smbios: handle errors consistently Igor Mammedov
` (8 subsequent siblings)
19 siblings, 2 replies; 37+ messages in thread
From: Igor Mammedov @ 2024-03-05 15:57 UTC (permalink / raw)
To: qemu-devel
Cc: peter.maydell, pbonzini, mst, gaosong, alistair.francis, palmer,
bin.meng, liwei1518, dbarboza, zhiwei_liu, imammedo, anisinha,
philmd, wangyanan55, eblake, armbru, qemu-arm, qemu-riscv,
f.ebner
basically moving code around without functional change.
And exposing some symbols so that they could be shared
between smbbios.c and new smbios_legacy.c
plus some meson magic to build smbios_legacy.c only
for 'pc' machine and otherwise replace it with stub
if not selected.
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
v2:
moved type0/type1/have_binfile_bitmap/have_fields_bitmap rename into
a separate patch
---
include/hw/firmware/smbios.h | 5 +
hw/i386/Kconfig | 1 +
hw/smbios/Kconfig | 2 +
hw/smbios/meson.build | 4 +
hw/smbios/smbios.c | 164 +-----------------------------
hw/smbios/smbios_legacy.c | 179 +++++++++++++++++++++++++++++++++
hw/smbios/smbios_legacy_stub.c | 16 +++
7 files changed, 208 insertions(+), 163 deletions(-)
create mode 100644 hw/smbios/smbios_legacy.c
create mode 100644 hw/smbios/smbios_legacy_stub.c
diff --git a/include/hw/firmware/smbios.h b/include/hw/firmware/smbios.h
index bea5c3f1b1..7f47475aa4 100644
--- a/include/hw/firmware/smbios.h
+++ b/include/hw/firmware/smbios.h
@@ -17,6 +17,9 @@
*
*/
+extern uint8_t *usr_blobs;
+extern GArray *usr_blobs_sizes;
+
typedef struct {
const char *vendor, *version, *date;
bool have_major_minor, uefi;
@@ -306,6 +309,8 @@ struct smbios_type_127 {
struct smbios_structure_header header;
} QEMU_PACKED;
+void smbios_validate_table(void);
+void smbios_add_usr_blob_size(size_t size);
void smbios_entry_add(QemuOpts *opts, Error **errp);
void smbios_set_cpuid(uint32_t version, uint32_t features);
void smbios_set_defaults(const char *manufacturer, const char *product,
diff --git a/hw/i386/Kconfig b/hw/i386/Kconfig
index a1846be6f7..a6ee052f9a 100644
--- a/hw/i386/Kconfig
+++ b/hw/i386/Kconfig
@@ -76,6 +76,7 @@ config I440FX
select PIIX
select DIMM
select SMBIOS
+ select SMBIOS_LEGACY
select FW_CFG_DMA
config ISAPC
diff --git a/hw/smbios/Kconfig b/hw/smbios/Kconfig
index 553adf4bfc..8d989a2f1b 100644
--- a/hw/smbios/Kconfig
+++ b/hw/smbios/Kconfig
@@ -1,2 +1,4 @@
config SMBIOS
bool
+config SMBIOS_LEGACY
+ bool
diff --git a/hw/smbios/meson.build b/hw/smbios/meson.build
index 7046967462..a59039f669 100644
--- a/hw/smbios/meson.build
+++ b/hw/smbios/meson.build
@@ -4,5 +4,9 @@ smbios_ss.add(when: 'CONFIG_IPMI',
if_true: files('smbios_type_38.c'),
if_false: files('smbios_type_38-stub.c'))
+smbios_ss.add(when: 'CONFIG_SMBIOS_LEGACY',
+ if_true: files('smbios_legacy.c'),
+ if_false: files('smbios_legacy_stub.c'))
+
system_ss.add_all(when: 'CONFIG_SMBIOS', if_true: smbios_ss)
system_ss.add(when: 'CONFIG_SMBIOS', if_false: files('smbios-stub.c'))
diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c
index 86cf66b5ce..fb1f05fcde 100644
--- a/hw/smbios/smbios.c
+++ b/hw/smbios/smbios.c
@@ -31,38 +31,12 @@
#include "hw/pci/pci_device.h"
#include "smbios_build.h"
-/* legacy structures and constants for <= 2.0 machines */
-struct smbios_header {
- uint16_t length;
- uint8_t type;
-} QEMU_PACKED;
-
-struct smbios_field {
- struct smbios_header header;
- uint8_t type;
- uint16_t offset;
- uint8_t data[];
-} QEMU_PACKED;
-
-struct smbios_table {
- struct smbios_header header;
- uint8_t data[];
-} QEMU_PACKED;
-
-#define SMBIOS_FIELD_ENTRY 0
-#define SMBIOS_TABLE_ENTRY 1
-
-static uint8_t *smbios_entries;
-static size_t smbios_entries_len;
static bool smbios_uuid_encoded = true;
-/* end: legacy structures & constants for <= 2.0 machines */
-
/*
* SMBIOS tables provided by user with '-smbios file=<foo>' option
*/
uint8_t *usr_blobs;
size_t usr_blobs_len;
-static GArray *usr_blobs_sizes;
static unsigned usr_table_max;
static unsigned usr_table_cnt;
@@ -483,7 +457,7 @@ static void smbios_check_type4_count(uint32_t expected_t4_count)
}
}
-static void smbios_validate_table(void)
+void smbios_validate_table(void)
{
if (smbios_ep_type == SMBIOS_ENTRY_POINT_TYPE_32 &&
smbios_tables_len > SMBIOS_21_MAX_TABLES_LEN) {
@@ -493,134 +467,6 @@ static void smbios_validate_table(void)
}
}
-
-/* legacy setup functions for <= 2.0 machines */
-static void smbios_add_field(int type, int offset, const void *data, size_t len)
-{
- struct smbios_field *field;
-
- if (!smbios_entries) {
- smbios_entries_len = sizeof(uint16_t);
- smbios_entries = g_malloc0(smbios_entries_len);
- }
- smbios_entries = g_realloc(smbios_entries, smbios_entries_len +
- sizeof(*field) + len);
- field = (struct smbios_field *)(smbios_entries + smbios_entries_len);
- field->header.type = SMBIOS_FIELD_ENTRY;
- field->header.length = cpu_to_le16(sizeof(*field) + len);
-
- field->type = type;
- field->offset = cpu_to_le16(offset);
- memcpy(field->data, data, len);
-
- smbios_entries_len += sizeof(*field) + len;
- (*(uint16_t *)smbios_entries) =
- cpu_to_le16(le16_to_cpu(*(uint16_t *)smbios_entries) + 1);
-}
-
-static void smbios_maybe_add_str(int type, int offset, const char *data)
-{
- if (data) {
- smbios_add_field(type, offset, data, strlen(data) + 1);
- }
-}
-
-static void smbios_build_type_0_fields(void)
-{
- smbios_maybe_add_str(0, offsetof(struct smbios_type_0, vendor_str),
- smbios_type0.vendor);
- smbios_maybe_add_str(0, offsetof(struct smbios_type_0, bios_version_str),
- smbios_type0.version);
- smbios_maybe_add_str(0, offsetof(struct smbios_type_0,
- bios_release_date_str),
- smbios_type0.date);
- if (smbios_type0.have_major_minor) {
- smbios_add_field(0, offsetof(struct smbios_type_0,
- system_bios_major_release),
- &smbios_type0.major, 1);
- smbios_add_field(0, offsetof(struct smbios_type_0,
- system_bios_minor_release),
- &smbios_type0.minor, 1);
- }
-}
-
-static void smbios_build_type_1_fields(void)
-{
- smbios_maybe_add_str(1, offsetof(struct smbios_type_1, manufacturer_str),
- smbios_type1.manufacturer);
- smbios_maybe_add_str(1, offsetof(struct smbios_type_1, product_name_str),
- smbios_type1.product);
- smbios_maybe_add_str(1, offsetof(struct smbios_type_1, version_str),
- smbios_type1.version);
- smbios_maybe_add_str(1, offsetof(struct smbios_type_1, serial_number_str),
- smbios_type1.serial);
- smbios_maybe_add_str(1, offsetof(struct smbios_type_1, sku_number_str),
- smbios_type1.sku);
- smbios_maybe_add_str(1, offsetof(struct smbios_type_1, family_str),
- smbios_type1.family);
- if (qemu_uuid_set) {
- /* We don't encode the UUID in the "wire format" here because this
- * function is for legacy mode and needs to keep the guest ABI, and
- * because we don't know what's the SMBIOS version advertised by the
- * BIOS.
- */
- smbios_add_field(1, offsetof(struct smbios_type_1, uuid),
- &qemu_uuid, 16);
- }
-}
-
-uint8_t *smbios_get_table_legacy(size_t *length)
-{
- int i;
- size_t usr_offset;
-
- /* also complain if fields were given for types > 1 */
- if (find_next_bit(smbios_have_fields_bitmap,
- SMBIOS_MAX_TYPE + 1, 2) < SMBIOS_MAX_TYPE + 1) {
- error_report("can't process fields for smbios "
- "types > 1 on machine versions < 2.1!");
- exit(1);
- }
-
- if (test_bit(4, smbios_have_binfile_bitmap)) {
- error_report("can't process table for smbios "
- "type 4 on machine versions < 2.1!");
- exit(1);
- }
-
- g_free(smbios_entries);
- smbios_entries_len = sizeof(uint16_t);
- smbios_entries = g_malloc0(smbios_entries_len);
-
- for (i = 0, usr_offset = 0; usr_blobs_sizes && i < usr_blobs_sizes->len;
- i++)
- {
- struct smbios_table *table;
- struct smbios_structure_header *header;
- size_t size = g_array_index(usr_blobs_sizes, size_t, i);
-
- header = (struct smbios_structure_header *)(usr_blobs + usr_offset);
- smbios_entries = g_realloc(smbios_entries, smbios_entries_len +
- size + sizeof(*table));
- table = (struct smbios_table *)(smbios_entries + smbios_entries_len);
- table->header.type = SMBIOS_TABLE_ENTRY;
- table->header.length = cpu_to_le16(sizeof(*table) + size);
- memcpy(table->data, header, size);
- smbios_entries_len += sizeof(*table) + size;
- (*(uint16_t *)smbios_entries) =
- cpu_to_le16(le16_to_cpu(*(uint16_t *)smbios_entries) + 1);
- usr_offset += size;
- }
-
- smbios_build_type_0_fields();
- smbios_build_type_1_fields();
- smbios_validate_table();
- *length = smbios_entries_len;
- return smbios_entries;
-}
-/* end: legacy setup functions for <= 2.0 machines */
-
-
bool smbios_skip_table(uint8_t type, bool required_table)
{
if (test_bit(type, smbios_have_binfile_bitmap)) {
@@ -1279,14 +1125,6 @@ static bool save_opt_list(size_t *ndest, char ***dest, QemuOpts *opts,
return true;
}
-static void smbios_add_usr_blob_size(size_t size)
-{
- if (!usr_blobs_sizes) {
- usr_blobs_sizes = g_array_new(false, false, sizeof(size_t));
- }
- g_array_append_val(usr_blobs_sizes, size);
-}
-
void smbios_entry_add(QemuOpts *opts, Error **errp)
{
const char *val;
diff --git a/hw/smbios/smbios_legacy.c b/hw/smbios/smbios_legacy.c
new file mode 100644
index 0000000000..21f143e738
--- /dev/null
+++ b/hw/smbios/smbios_legacy.c
@@ -0,0 +1,179 @@
+/*
+ * SMBIOS legacy support
+ *
+ * Copyright (C) 2009 Hewlett-Packard Development Company, L.P.
+ * Copyright (C) 2013 Red Hat, Inc.
+ *
+ * Authors:
+ * Alex Williamson <alex.williamson@hp.com>
+ * Markus Armbruster <armbru@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2. See
+ * the COPYING file in the top-level directory.
+ *
+ * Contributions after 2012-01-13 are licensed under the terms of the
+ * GNU GPL, version 2 or (at your option) any later version.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/bswap.h"
+#include "hw/firmware/smbios.h"
+#include "sysemu/sysemu.h"
+#include "qemu/error-report.h"
+
+struct smbios_header {
+ uint16_t length;
+ uint8_t type;
+} QEMU_PACKED;
+
+struct smbios_field {
+ struct smbios_header header;
+ uint8_t type;
+ uint16_t offset;
+ uint8_t data[];
+} QEMU_PACKED;
+
+struct smbios_table {
+ struct smbios_header header;
+ uint8_t data[];
+} QEMU_PACKED;
+
+#define SMBIOS_FIELD_ENTRY 0
+#define SMBIOS_TABLE_ENTRY 1
+
+static uint8_t *smbios_entries;
+static size_t smbios_entries_len;
+GArray *usr_blobs_sizes;
+
+void smbios_add_usr_blob_size(size_t size)
+{
+ if (!usr_blobs_sizes) {
+ usr_blobs_sizes = g_array_new(false, false, sizeof(size_t));
+ }
+ g_array_append_val(usr_blobs_sizes, size);
+}
+
+static void smbios_add_field(int type, int offset, const void *data, size_t len)
+{
+ struct smbios_field *field;
+
+ if (!smbios_entries) {
+ smbios_entries_len = sizeof(uint16_t);
+ smbios_entries = g_malloc0(smbios_entries_len);
+ }
+ smbios_entries = g_realloc(smbios_entries, smbios_entries_len +
+ sizeof(*field) + len);
+ field = (struct smbios_field *)(smbios_entries + smbios_entries_len);
+ field->header.type = SMBIOS_FIELD_ENTRY;
+ field->header.length = cpu_to_le16(sizeof(*field) + len);
+
+ field->type = type;
+ field->offset = cpu_to_le16(offset);
+ memcpy(field->data, data, len);
+
+ smbios_entries_len += sizeof(*field) + len;
+ (*(uint16_t *)smbios_entries) =
+ cpu_to_le16(le16_to_cpu(*(uint16_t *)smbios_entries) + 1);
+}
+
+static void smbios_maybe_add_str(int type, int offset, const char *data)
+{
+ if (data) {
+ smbios_add_field(type, offset, data, strlen(data) + 1);
+ }
+}
+
+static void smbios_build_type_0_fields(void)
+{
+ smbios_maybe_add_str(0, offsetof(struct smbios_type_0, vendor_str),
+ smbios_type0.vendor);
+ smbios_maybe_add_str(0, offsetof(struct smbios_type_0, bios_version_str),
+ smbios_type0.version);
+ smbios_maybe_add_str(0, offsetof(struct smbios_type_0,
+ bios_release_date_str),
+ smbios_type0.date);
+ if (smbios_type0.have_major_minor) {
+ smbios_add_field(0, offsetof(struct smbios_type_0,
+ system_bios_major_release),
+ &smbios_type0.major, 1);
+ smbios_add_field(0, offsetof(struct smbios_type_0,
+ system_bios_minor_release),
+ &smbios_type0.minor, 1);
+ }
+}
+
+static void smbios_build_type_1_fields(void)
+{
+ smbios_maybe_add_str(1, offsetof(struct smbios_type_1, manufacturer_str),
+ smbios_type1.manufacturer);
+ smbios_maybe_add_str(1, offsetof(struct smbios_type_1, product_name_str),
+ smbios_type1.product);
+ smbios_maybe_add_str(1, offsetof(struct smbios_type_1, version_str),
+ smbios_type1.version);
+ smbios_maybe_add_str(1, offsetof(struct smbios_type_1, serial_number_str),
+ smbios_type1.serial);
+ smbios_maybe_add_str(1, offsetof(struct smbios_type_1, sku_number_str),
+ smbios_type1.sku);
+ smbios_maybe_add_str(1, offsetof(struct smbios_type_1, family_str),
+ smbios_type1.family);
+ if (qemu_uuid_set) {
+ /*
+ * We don't encode the UUID in the "wire format" here because this
+ * function is for legacy mode and needs to keep the guest ABI, and
+ * because we don't know what's the SMBIOS version advertised by the
+ * BIOS.
+ */
+ smbios_add_field(1, offsetof(struct smbios_type_1, uuid),
+ &qemu_uuid, 16);
+ }
+}
+
+uint8_t *smbios_get_table_legacy(size_t *length)
+{
+ int i;
+ size_t usr_offset;
+
+ /* complain if fields were given for types > 1 */
+ if (find_next_bit(smbios_have_fields_bitmap,
+ SMBIOS_MAX_TYPE + 1, 2) < SMBIOS_MAX_TYPE + 1) {
+ error_report("can't process fields for smbios "
+ "types > 1 on machine versions < 2.1!");
+ exit(1);
+ }
+
+ if (test_bit(4, smbios_have_binfile_bitmap)) {
+ error_report("can't process table for smbios "
+ "type 4 on machine versions < 2.1!");
+ exit(1);
+ }
+
+ g_free(smbios_entries);
+ smbios_entries_len = sizeof(uint16_t);
+ smbios_entries = g_malloc0(smbios_entries_len);
+
+ for (i = 0, usr_offset = 0; usr_blobs_sizes && i < usr_blobs_sizes->len;
+ i++)
+ {
+ struct smbios_table *table;
+ struct smbios_structure_header *header;
+ size_t size = g_array_index(usr_blobs_sizes, size_t, i);
+
+ header = (struct smbios_structure_header *)(usr_blobs + usr_offset);
+ smbios_entries = g_realloc(smbios_entries, smbios_entries_len +
+ size + sizeof(*table));
+ table = (struct smbios_table *)(smbios_entries + smbios_entries_len);
+ table->header.type = SMBIOS_TABLE_ENTRY;
+ table->header.length = cpu_to_le16(sizeof(*table) + size);
+ memcpy(table->data, header, size);
+ smbios_entries_len += sizeof(*table) + size;
+ (*(uint16_t *)smbios_entries) =
+ cpu_to_le16(le16_to_cpu(*(uint16_t *)smbios_entries) + 1);
+ usr_offset += size;
+ }
+
+ smbios_build_type_0_fields();
+ smbios_build_type_1_fields();
+ smbios_validate_table();
+ *length = smbios_entries_len;
+ return smbios_entries;
+}
diff --git a/hw/smbios/smbios_legacy_stub.c b/hw/smbios/smbios_legacy_stub.c
new file mode 100644
index 0000000000..91e6c75029
--- /dev/null
+++ b/hw/smbios/smbios_legacy_stub.c
@@ -0,0 +1,16 @@
+/*
+ * IPMI SMBIOS firmware handling
+ *
+ * Copyright (c) 2024 Igor Mammedov, Red Hat, Inc.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "hw/firmware/smbios.h"
+
+void smbios_add_usr_blob_size(size_t size)
+{
+}
+
--
2.39.3
^ permalink raw reply related [flat|nested] 37+ messages in thread
* [PATCH v2 12/20] smbios: handle errors consistently
2024-03-05 15:57 [PATCH v2 00/20] Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS Igor Mammedov
` (10 preceding siblings ...)
2024-03-05 15:57 ` [PATCH v2 11/20] smbios: build legacy mode code only for 'pc' machine Igor Mammedov
@ 2024-03-05 15:57 ` Igor Mammedov
2024-03-05 15:57 ` [PATCH v2 13/20] smbios: get rid of global smbios_ep_type Igor Mammedov
` (7 subsequent siblings)
19 siblings, 0 replies; 37+ messages in thread
From: Igor Mammedov @ 2024-03-05 15:57 UTC (permalink / raw)
To: qemu-devel
Cc: peter.maydell, pbonzini, mst, gaosong, alistair.francis, palmer,
bin.meng, liwei1518, dbarboza, zhiwei_liu, imammedo, anisinha,
philmd, wangyanan55, eblake, armbru, qemu-arm, qemu-riscv,
f.ebner
Current code uses mix of error_report()+exit(1)
and error_setg() to handle errors.
Use newer error_setg() everywhere, beside consistency
it will allow to detect error condition without killing
QEMU and attempt switch-over to SMBIOS3.x tables/entrypoint
in follow up patch.
while at it, clear smbios_tables pointer after freeing.
that will avoid double free if smbios_get_tables() is called
multiple times.
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Ani Sinha <anisinha@redhat.com>
---
include/hw/firmware/smbios.h | 4 ++--
hw/i386/fw_cfg.c | 3 ++-
hw/smbios/smbios.c | 34 ++++++++++++++++++++++------------
hw/smbios/smbios_legacy.c | 22 ++++++++++++++--------
4 files changed, 40 insertions(+), 23 deletions(-)
diff --git a/include/hw/firmware/smbios.h b/include/hw/firmware/smbios.h
index 7f47475aa4..89bb10510a 100644
--- a/include/hw/firmware/smbios.h
+++ b/include/hw/firmware/smbios.h
@@ -309,7 +309,7 @@ struct smbios_type_127 {
struct smbios_structure_header header;
} QEMU_PACKED;
-void smbios_validate_table(void);
+bool smbios_validate_table(Error **errp);
void smbios_add_usr_blob_size(size_t size);
void smbios_entry_add(QemuOpts *opts, Error **errp);
void smbios_set_cpuid(uint32_t version, uint32_t features);
@@ -317,7 +317,7 @@ void smbios_set_defaults(const char *manufacturer, const char *product,
const char *version,
bool uuid_encoded, SmbiosEntryPointType ep_type);
void smbios_set_default_processor_family(uint16_t processor_family);
-uint8_t *smbios_get_table_legacy(size_t *length);
+uint8_t *smbios_get_table_legacy(size_t *length, Error **errp);
void smbios_get_tables(MachineState *ms,
const struct smbios_phys_mem_area *mem_array,
const unsigned int mem_array_size,
diff --git a/hw/i386/fw_cfg.c b/hw/i386/fw_cfg.c
index d1281066f4..e387bf50d0 100644
--- a/hw/i386/fw_cfg.c
+++ b/hw/i386/fw_cfg.c
@@ -71,7 +71,8 @@ void fw_cfg_build_smbios(PCMachineState *pcms, FWCfgState *fw_cfg)
smbios_set_cpuid(cpu->env.cpuid_version, cpu->env.features[FEAT_1_EDX]);
if (pcmc->smbios_legacy_mode) {
- smbios_tables = smbios_get_table_legacy(&smbios_tables_len);
+ smbios_tables = smbios_get_table_legacy(&smbios_tables_len,
+ &error_fatal);
fw_cfg_add_bytes(fw_cfg, FW_CFG_SMBIOS_ENTRIES,
smbios_tables, smbios_tables_len);
return;
diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c
index fb1f05fcde..d9ba2072b1 100644
--- a/hw/smbios/smbios.c
+++ b/hw/smbios/smbios.c
@@ -19,7 +19,6 @@
#include "qemu/units.h"
#include "qapi/error.h"
#include "qemu/config-file.h"
-#include "qemu/error-report.h"
#include "qemu/module.h"
#include "qemu/option.h"
#include "sysemu/sysemu.h"
@@ -448,23 +447,25 @@ opts_init(smbios_register_config);
*/
#define SMBIOS_21_MAX_TABLES_LEN 0xffff
-static void smbios_check_type4_count(uint32_t expected_t4_count)
+static bool smbios_check_type4_count(uint32_t expected_t4_count, Error **errp)
{
if (smbios_type4_count && smbios_type4_count != expected_t4_count) {
- error_report("Expected %d SMBIOS Type 4 tables, got %d instead",
- expected_t4_count, smbios_type4_count);
- exit(1);
+ error_setg(errp, "Expected %d SMBIOS Type 4 tables, got %d instead",
+ expected_t4_count, smbios_type4_count);
+ return false;
}
+ return true;
}
-void smbios_validate_table(void)
+bool smbios_validate_table(Error **errp)
{
if (smbios_ep_type == SMBIOS_ENTRY_POINT_TYPE_32 &&
smbios_tables_len > SMBIOS_21_MAX_TABLES_LEN) {
- error_report("SMBIOS 2.1 table length %zu exceeds %d",
- smbios_tables_len, SMBIOS_21_MAX_TABLES_LEN);
- exit(1);
+ error_setg(errp, "SMBIOS 2.1 table length %zu exceeds %d",
+ smbios_tables_len, SMBIOS_21_MAX_TABLES_LEN);
+ return false;
}
+ return true;
}
bool smbios_skip_table(uint8_t type, bool required_table)
@@ -1027,15 +1028,18 @@ void smbios_get_tables(MachineState *ms,
smbios_build_type_41_table(errp);
smbios_build_type_127_table();
- smbios_check_type4_count(ms->smp.sockets);
- smbios_validate_table();
+ if (!smbios_check_type4_count(ms->smp.sockets, errp)) {
+ goto err_exit;
+ }
+ if (!smbios_validate_table(errp)) {
+ goto err_exit;
+ }
smbios_entry_point_setup();
/* return tables blob and entry point (anchor), and their sizes */
*tables = smbios_tables;
*tables_len = smbios_tables_len;
*anchor = (uint8_t *)&ep;
-
/* calculate length based on anchor string */
if (!strncmp((char *)&ep, "_SM_", 4)) {
*anchor_len = sizeof(struct smbios_21_entry_point);
@@ -1044,6 +1048,12 @@ void smbios_get_tables(MachineState *ms,
} else {
abort();
}
+
+ return;
+err_exit:
+ g_free(smbios_tables);
+ smbios_tables = NULL;
+ return;
}
static void save_opt(const char **dest, QemuOpts *opts, const char *name)
diff --git a/hw/smbios/smbios_legacy.c b/hw/smbios/smbios_legacy.c
index 21f143e738..a6544bf55a 100644
--- a/hw/smbios/smbios_legacy.c
+++ b/hw/smbios/smbios_legacy.c
@@ -19,7 +19,7 @@
#include "qemu/bswap.h"
#include "hw/firmware/smbios.h"
#include "sysemu/sysemu.h"
-#include "qemu/error-report.h"
+#include "qapi/error.h"
struct smbios_header {
uint16_t length;
@@ -128,7 +128,7 @@ static void smbios_build_type_1_fields(void)
}
}
-uint8_t *smbios_get_table_legacy(size_t *length)
+uint8_t *smbios_get_table_legacy(size_t *length, Error **errp)
{
int i;
size_t usr_offset;
@@ -136,15 +136,15 @@ uint8_t *smbios_get_table_legacy(size_t *length)
/* complain if fields were given for types > 1 */
if (find_next_bit(smbios_have_fields_bitmap,
SMBIOS_MAX_TYPE + 1, 2) < SMBIOS_MAX_TYPE + 1) {
- error_report("can't process fields for smbios "
+ error_setg(errp, "can't process fields for smbios "
"types > 1 on machine versions < 2.1!");
- exit(1);
+ goto err_exit;
}
if (test_bit(4, smbios_have_binfile_bitmap)) {
- error_report("can't process table for smbios "
- "type 4 on machine versions < 2.1!");
- exit(1);
+ error_setg(errp, "can't process table for smbios "
+ "type 4 on machine versions < 2.1!");
+ goto err_exit;
}
g_free(smbios_entries);
@@ -173,7 +173,13 @@ uint8_t *smbios_get_table_legacy(size_t *length)
smbios_build_type_0_fields();
smbios_build_type_1_fields();
- smbios_validate_table();
+ if (!smbios_validate_table(errp)) {
+ goto err_exit;
+ }
+
*length = smbios_entries_len;
return smbios_entries;
+err_exit:
+ g_free(smbios_entries);
+ return NULL;
}
--
2.39.3
^ permalink raw reply related [flat|nested] 37+ messages in thread
* [PATCH v2 13/20] smbios: get rid of global smbios_ep_type
2024-03-05 15:57 [PATCH v2 00/20] Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS Igor Mammedov
` (11 preceding siblings ...)
2024-03-05 15:57 ` [PATCH v2 12/20] smbios: handle errors consistently Igor Mammedov
@ 2024-03-05 15:57 ` Igor Mammedov
2024-03-05 15:57 ` [PATCH v2 14/20] smbios: extend smbios-entry-point-type with 'auto' value Igor Mammedov
` (6 subsequent siblings)
19 siblings, 0 replies; 37+ messages in thread
From: Igor Mammedov @ 2024-03-05 15:57 UTC (permalink / raw)
To: qemu-devel
Cc: peter.maydell, pbonzini, mst, gaosong, alistair.francis, palmer,
bin.meng, liwei1518, dbarboza, zhiwei_liu, imammedo, anisinha,
philmd, wangyanan55, eblake, armbru, qemu-arm, qemu-riscv,
f.ebner
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Acked-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: Ani Sinha <anisinha@redhat.com>
Tested-by: Fiona Ebner <f.ebner@proxmox.com>
---
hw/i386/fw_cfg.h | 3 ++-
include/hw/firmware/smbios.h | 5 +++--
hw/arm/virt.c | 4 ++--
hw/i386/fw_cfg.c | 8 ++++----
hw/i386/pc.c | 2 +-
hw/loongarch/virt.c | 7 ++++---
hw/riscv/virt.c | 6 +++---
hw/smbios/smbios.c | 27 +++++++++++++++------------
hw/smbios/smbios_legacy.c | 2 +-
9 files changed, 35 insertions(+), 29 deletions(-)
diff --git a/hw/i386/fw_cfg.h b/hw/i386/fw_cfg.h
index 1e1de6b4a3..92e310f5fd 100644
--- a/hw/i386/fw_cfg.h
+++ b/hw/i386/fw_cfg.h
@@ -23,7 +23,8 @@
FWCfgState *fw_cfg_arch_create(MachineState *ms,
uint16_t boot_cpus,
uint16_t apic_id_limit);
-void fw_cfg_build_smbios(PCMachineState *ms, FWCfgState *fw_cfg);
+void fw_cfg_build_smbios(PCMachineState *pcms, FWCfgState *fw_cfg,
+ SmbiosEntryPointType ep_type);
void fw_cfg_build_feature_control(MachineState *ms, FWCfgState *fw_cfg);
void fw_cfg_add_acpi_dsdt(Aml *scope, FWCfgState *fw_cfg);
diff --git a/include/hw/firmware/smbios.h b/include/hw/firmware/smbios.h
index 89bb10510a..d128aef31d 100644
--- a/include/hw/firmware/smbios.h
+++ b/include/hw/firmware/smbios.h
@@ -309,16 +309,17 @@ struct smbios_type_127 {
struct smbios_structure_header header;
} QEMU_PACKED;
-bool smbios_validate_table(Error **errp);
+bool smbios_validate_table(SmbiosEntryPointType ep_type, Error **errp);
void smbios_add_usr_blob_size(size_t size);
void smbios_entry_add(QemuOpts *opts, Error **errp);
void smbios_set_cpuid(uint32_t version, uint32_t features);
void smbios_set_defaults(const char *manufacturer, const char *product,
const char *version,
- bool uuid_encoded, SmbiosEntryPointType ep_type);
+ bool uuid_encoded);
void smbios_set_default_processor_family(uint16_t processor_family);
uint8_t *smbios_get_table_legacy(size_t *length, Error **errp);
void smbios_get_tables(MachineState *ms,
+ SmbiosEntryPointType ep_type,
const struct smbios_phys_mem_area *mem_array,
const unsigned int mem_array_size,
uint8_t **tables, size_t *tables_len,
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 8588681f27..780224ee5b 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -1634,13 +1634,13 @@ static void virt_build_smbios(VirtMachineState *vms)
smbios_set_defaults("QEMU", product,
vmc->smbios_old_sys_ver ? "1.0" : mc->name,
- true, SMBIOS_ENTRY_POINT_TYPE_64);
+ true);
/* build the array of physical mem area from base_memmap */
mem_array.address = vms->memmap[VIRT_MEM].base;
mem_array.length = ms->ram_size;
- smbios_get_tables(ms, &mem_array, 1,
+ smbios_get_tables(ms, SMBIOS_ENTRY_POINT_TYPE_64, &mem_array, 1,
&smbios_tables, &smbios_tables_len,
&smbios_anchor, &smbios_anchor_len,
&error_fatal);
diff --git a/hw/i386/fw_cfg.c b/hw/i386/fw_cfg.c
index e387bf50d0..d802d2787f 100644
--- a/hw/i386/fw_cfg.c
+++ b/hw/i386/fw_cfg.c
@@ -48,7 +48,8 @@ const char *fw_cfg_arch_key_name(uint16_t key)
return NULL;
}
-void fw_cfg_build_smbios(PCMachineState *pcms, FWCfgState *fw_cfg)
+void fw_cfg_build_smbios(PCMachineState *pcms, FWCfgState *fw_cfg,
+ SmbiosEntryPointType ep_type)
{
#ifdef CONFIG_SMBIOS
uint8_t *smbios_tables, *smbios_anchor;
@@ -63,8 +64,7 @@ void fw_cfg_build_smbios(PCMachineState *pcms, FWCfgState *fw_cfg)
if (pcmc->smbios_defaults) {
/* These values are guest ABI, do not change */
smbios_set_defaults("QEMU", mc->desc, mc->name,
- pcmc->smbios_uuid_encoded,
- pcms->smbios_entry_point_type);
+ pcmc->smbios_uuid_encoded);
}
/* tell smbios about cpuid version and features */
@@ -89,7 +89,7 @@ void fw_cfg_build_smbios(PCMachineState *pcms, FWCfgState *fw_cfg)
array_count++;
}
}
- smbios_get_tables(ms, mem_array, array_count,
+ smbios_get_tables(ms, ep_type, mem_array, array_count,
&smbios_tables, &smbios_tables_len,
&smbios_anchor, &smbios_anchor_len,
&error_fatal);
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index f5ff970acf..a8e8aa2ac8 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -691,7 +691,7 @@ void pc_machine_done(Notifier *notifier, void *data)
acpi_setup();
if (x86ms->fw_cfg) {
- fw_cfg_build_smbios(pcms, x86ms->fw_cfg);
+ fw_cfg_build_smbios(pcms, x86ms->fw_cfg, pcms->smbios_entry_point_type);
fw_cfg_build_feature_control(MACHINE(pcms), x86ms->fw_cfg);
/* update FW_CFG_NB_CPUS to account for -device added CPUs */
fw_cfg_modify_i16(x86ms->fw_cfg, FW_CFG_NB_CPUS, x86ms->boot_cpus);
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
index 8c7601ef91..05f616682a 100644
--- a/hw/loongarch/virt.c
+++ b/hw/loongarch/virt.c
@@ -355,10 +355,11 @@ static void virt_build_smbios(LoongArchMachineState *lams)
return;
}
- smbios_set_defaults("QEMU", product, mc->name,
- true, SMBIOS_ENTRY_POINT_TYPE_64);
+ smbios_set_defaults("QEMU", product, mc->name, true);
- smbios_get_tables(ms, NULL, 0, &smbios_tables, &smbios_tables_len,
+ smbios_get_tables(ms, SMBIOS_ENTRY_POINT_TYPE_64,
+ NULL, 0,
+ &smbios_tables, &smbios_tables_len,
&smbios_anchor, &smbios_anchor_len, &error_fatal);
if (smbios_anchor) {
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index e2c9529df2..b730ff2030 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -1235,8 +1235,7 @@ static void virt_build_smbios(RISCVVirtState *s)
product = "KVM Virtual Machine";
}
- smbios_set_defaults("QEMU", product, mc->name,
- true, SMBIOS_ENTRY_POINT_TYPE_64);
+ smbios_set_defaults("QEMU", product, mc->name, true);
if (riscv_is_32bit(&s->soc[0])) {
smbios_set_default_processor_family(0x200);
@@ -1248,7 +1247,8 @@ static void virt_build_smbios(RISCVVirtState *s)
mem_array.address = s->memmap[VIRT_DRAM].base;
mem_array.length = ms->ram_size;
- smbios_get_tables(ms, &mem_array, 1,
+ smbios_get_tables(ms, SMBIOS_ENTRY_POINT_TYPE_64,
+ &mem_array, 1,
&smbios_tables, &smbios_tables_len,
&smbios_anchor, &smbios_anchor_len,
&error_fatal);
diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c
index d9ba2072b1..5a791fd9eb 100644
--- a/hw/smbios/smbios.c
+++ b/hw/smbios/smbios.c
@@ -43,7 +43,6 @@ uint8_t *smbios_tables;
size_t smbios_tables_len;
unsigned smbios_table_max;
unsigned smbios_table_cnt;
-static SmbiosEntryPointType smbios_ep_type = SMBIOS_ENTRY_POINT_TYPE_32;
static SmbiosEntryPoint ep;
@@ -457,9 +456,9 @@ static bool smbios_check_type4_count(uint32_t expected_t4_count, Error **errp)
return true;
}
-bool smbios_validate_table(Error **errp)
+bool smbios_validate_table(SmbiosEntryPointType ep_type, Error **errp)
{
- if (smbios_ep_type == SMBIOS_ENTRY_POINT_TYPE_32 &&
+ if (ep_type == SMBIOS_ENTRY_POINT_TYPE_32 &&
smbios_tables_len > SMBIOS_21_MAX_TABLES_LEN) {
error_setg(errp, "SMBIOS 2.1 table length %zu exceeds %d",
smbios_tables_len, SMBIOS_21_MAX_TABLES_LEN);
@@ -605,14 +604,15 @@ static void smbios_build_type_3_table(void)
SMBIOS_BUILD_TABLE_POST;
}
-static void smbios_build_type_4_table(MachineState *ms, unsigned instance)
+static void smbios_build_type_4_table(MachineState *ms, unsigned instance,
+ SmbiosEntryPointType ep_type)
{
char sock_str[128];
size_t tbl_len = SMBIOS_TYPE_4_LEN_V28;
unsigned threads_per_socket;
unsigned cores_per_socket;
- if (smbios_ep_type == SMBIOS_ENTRY_POINT_TYPE_64) {
+ if (ep_type == SMBIOS_ENTRY_POINT_TYPE_64) {
tbl_len = SMBIOS_TYPE_4_LEN_V30;
}
@@ -888,11 +888,10 @@ void smbios_set_default_processor_family(uint16_t processor_family)
void smbios_set_defaults(const char *manufacturer, const char *product,
const char *version,
- bool uuid_encoded, SmbiosEntryPointType ep_type)
+ bool uuid_encoded)
{
smbios_have_defaults = true;
smbios_uuid_encoded = uuid_encoded;
- smbios_ep_type = ep_type;
SMBIOS_SET_DEFAULT(smbios_type1.manufacturer, manufacturer);
SMBIOS_SET_DEFAULT(smbios_type1.product, product);
@@ -909,9 +908,9 @@ void smbios_set_defaults(const char *manufacturer, const char *product,
SMBIOS_SET_DEFAULT(type17.manufacturer, manufacturer);
}
-static void smbios_entry_point_setup(void)
+static void smbios_entry_point_setup(SmbiosEntryPointType ep_type)
{
- switch (smbios_ep_type) {
+ switch (ep_type) {
case SMBIOS_ENTRY_POINT_TYPE_32:
memcpy(ep.ep21.anchor_string, "_SM_", 4);
memcpy(ep.ep21.intermediate_anchor_string, "_DMI_", 5);
@@ -961,6 +960,7 @@ static void smbios_entry_point_setup(void)
}
void smbios_get_tables(MachineState *ms,
+ SmbiosEntryPointType ep_type,
const struct smbios_phys_mem_area *mem_array,
const unsigned int mem_array_size,
uint8_t **tables, size_t *tables_len,
@@ -969,6 +969,9 @@ void smbios_get_tables(MachineState *ms,
{
unsigned i, dimm_cnt, offset;
+ assert(ep_type == SMBIOS_ENTRY_POINT_TYPE_32 ||
+ ep_type == SMBIOS_ENTRY_POINT_TYPE_64);
+
g_free(smbios_tables);
smbios_tables = g_memdup2(usr_blobs, usr_blobs_len);
smbios_tables_len = usr_blobs_len;
@@ -983,7 +986,7 @@ void smbios_get_tables(MachineState *ms,
assert(ms->smp.sockets >= 1);
for (i = 0; i < ms->smp.sockets; i++) {
- smbios_build_type_4_table(ms, i);
+ smbios_build_type_4_table(ms, i, ep_type);
}
smbios_build_type_8_table();
@@ -1031,10 +1034,10 @@ void smbios_get_tables(MachineState *ms,
if (!smbios_check_type4_count(ms->smp.sockets, errp)) {
goto err_exit;
}
- if (!smbios_validate_table(errp)) {
+ if (!smbios_validate_table(ep_type, errp)) {
goto err_exit;
}
- smbios_entry_point_setup();
+ smbios_entry_point_setup(ep_type);
/* return tables blob and entry point (anchor), and their sizes */
*tables = smbios_tables;
diff --git a/hw/smbios/smbios_legacy.c b/hw/smbios/smbios_legacy.c
index a6544bf55a..06907cd16c 100644
--- a/hw/smbios/smbios_legacy.c
+++ b/hw/smbios/smbios_legacy.c
@@ -173,7 +173,7 @@ uint8_t *smbios_get_table_legacy(size_t *length, Error **errp)
smbios_build_type_0_fields();
smbios_build_type_1_fields();
- if (!smbios_validate_table(errp)) {
+ if (!smbios_validate_table(SMBIOS_ENTRY_POINT_TYPE_32, errp)) {
goto err_exit;
}
--
2.39.3
^ permalink raw reply related [flat|nested] 37+ messages in thread
* [PATCH v2 14/20] smbios: extend smbios-entry-point-type with 'auto' value
2024-03-05 15:57 [PATCH v2 00/20] Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS Igor Mammedov
` (12 preceding siblings ...)
2024-03-05 15:57 ` [PATCH v2 13/20] smbios: get rid of global smbios_ep_type Igor Mammedov
@ 2024-03-05 15:57 ` Igor Mammedov
2024-03-08 7:25 ` Markus Armbruster
2024-03-08 12:21 ` [PATCH v3 " Igor Mammedov
2024-03-05 15:57 ` [PATCH v2 15/20] smbios: in case of entry point is 'auto' try to build v2 tables 1st Igor Mammedov
` (5 subsequent siblings)
19 siblings, 2 replies; 37+ messages in thread
From: Igor Mammedov @ 2024-03-05 15:57 UTC (permalink / raw)
To: qemu-devel
Cc: peter.maydell, pbonzini, mst, gaosong, alistair.francis, palmer,
bin.meng, liwei1518, dbarboza, zhiwei_liu, imammedo, anisinha,
philmd, wangyanan55, eblake, armbru, qemu-arm, qemu-riscv,
f.ebner
later patches will use it to pick SMBIOS version at runtime
depending on configuration.
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Acked-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Ani Sinha <anisinha@redhat.com>
Tested-by: Fiona Ebner <f.ebner@proxmox.com>
---
qapi/machine.json | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/qapi/machine.json b/qapi/machine.json
index bb5a178909..6bdc71dc8c 100644
--- a/qapi/machine.json
+++ b/qapi/machine.json
@@ -1797,10 +1797,13 @@
#
# @64: SMBIOS version 3.0 (64-bit) Entry Point
#
+# @auto: Either 2.x or 3.x SMBIOS version, 2.x if configuration can be
+# described by it and 3.x otherwise (since: 9.0)
+#
# Since: 7.0
##
{ 'enum': 'SmbiosEntryPointType',
- 'data': [ '32', '64' ] }
+ 'data': [ '32', '64', 'auto' ] }
##
# @MemorySizeConfiguration:
--
2.39.3
^ permalink raw reply related [flat|nested] 37+ messages in thread
* [PATCH v2 15/20] smbios: in case of entry point is 'auto' try to build v2 tables 1st
2024-03-05 15:57 [PATCH v2 00/20] Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS Igor Mammedov
` (13 preceding siblings ...)
2024-03-05 15:57 ` [PATCH v2 14/20] smbios: extend smbios-entry-point-type with 'auto' value Igor Mammedov
@ 2024-03-05 15:57 ` Igor Mammedov
2024-03-05 15:57 ` [PATCH v2 16/20] smbios: error out when building type 4 table is not possible Igor Mammedov
` (4 subsequent siblings)
19 siblings, 0 replies; 37+ messages in thread
From: Igor Mammedov @ 2024-03-05 15:57 UTC (permalink / raw)
To: qemu-devel
Cc: peter.maydell, pbonzini, mst, gaosong, alistair.francis, palmer,
bin.meng, liwei1518, dbarboza, zhiwei_liu, imammedo, anisinha,
philmd, wangyanan55, eblake, armbru, qemu-arm, qemu-riscv,
f.ebner
QEMU for some time now uses SMBIOS 3.0 for PC/Q35 machines by
default, however Windows has a bug in locating SMBIOS 3.0
entrypoint and fails to find tables when booted on SeaBIOS
(on UEFI SMBIOS 3.0 tables work fine since firmware hands
over tables in another way)
Missing SMBIOS tables may lead to some issues for guest
though (worst are: possible reactiveation, inability to
get virtio drivers from 'Windows Update')
It's unclear at this point if MS will fix the issue on their
side. So instead of it (or rather in addition) this patch
will try to workaround the issue.
aka, use smbios-entry-point-type=auto to make QEMU try
generating conservative SMBIOS 2.0 tables and if that
fails (due to limits/requested configuration) fallback
to SMBIOS 3.0 tables.
With this in place majority of users will use SMBIOS 2.0
tables which work fine with (Windows + legacy BIOS).
The configurations that is not to possible to describe
with SMBIOS 2.0 will switch automatically to SMBIOS 3.0
(which will trigger Windows bug but there is nothing
QEMU can do here, so go and aks Microsoft to real fix).
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Ani Sinha <anisinha@redhat.com>
Tested-by: Fiona Ebner <f.ebner@proxmox.com>
---
hw/smbios/smbios.c | 52 +++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 49 insertions(+), 3 deletions(-)
diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c
index 5a791fd9eb..e54a9f21e6 100644
--- a/hw/smbios/smbios.c
+++ b/hw/smbios/smbios.c
@@ -959,7 +959,7 @@ static void smbios_entry_point_setup(SmbiosEntryPointType ep_type)
}
}
-void smbios_get_tables(MachineState *ms,
+static bool smbios_get_tables_ep(MachineState *ms,
SmbiosEntryPointType ep_type,
const struct smbios_phys_mem_area *mem_array,
const unsigned int mem_array_size,
@@ -968,6 +968,7 @@ void smbios_get_tables(MachineState *ms,
Error **errp)
{
unsigned i, dimm_cnt, offset;
+ ERRP_GUARD();
assert(ep_type == SMBIOS_ENTRY_POINT_TYPE_32 ||
ep_type == SMBIOS_ENTRY_POINT_TYPE_64);
@@ -1052,11 +1053,56 @@ void smbios_get_tables(MachineState *ms,
abort();
}
- return;
+ return true;
err_exit:
g_free(smbios_tables);
smbios_tables = NULL;
- return;
+ return false;
+}
+
+void smbios_get_tables(MachineState *ms,
+ SmbiosEntryPointType ep_type,
+ const struct smbios_phys_mem_area *mem_array,
+ const unsigned int mem_array_size,
+ uint8_t **tables, size_t *tables_len,
+ uint8_t **anchor, size_t *anchor_len,
+ Error **errp)
+{
+ Error *local_err = NULL;
+ bool is_valid;
+ ERRP_GUARD();
+
+ switch (ep_type) {
+ case SMBIOS_ENTRY_POINT_TYPE_AUTO:
+ case SMBIOS_ENTRY_POINT_TYPE_32:
+ is_valid = smbios_get_tables_ep(ms, SMBIOS_ENTRY_POINT_TYPE_32,
+ mem_array, mem_array_size,
+ tables, tables_len,
+ anchor, anchor_len,
+ &local_err);
+ if (is_valid || ep_type != SMBIOS_ENTRY_POINT_TYPE_AUTO) {
+ break;
+ }
+ /*
+ * fall through in case AUTO endpoint is selected and
+ * SMBIOS 2.x tables can't be generated, to try if SMBIOS 3.x
+ * tables would work
+ */
+ case SMBIOS_ENTRY_POINT_TYPE_64:
+ error_free(local_err);
+ local_err = NULL;
+ is_valid = smbios_get_tables_ep(ms, SMBIOS_ENTRY_POINT_TYPE_64,
+ mem_array, mem_array_size,
+ tables, tables_len,
+ anchor, anchor_len,
+ &local_err);
+ break;
+ default:
+ abort();
+ }
+ if (!is_valid) {
+ error_propagate(errp, local_err);
+ }
}
static void save_opt(const char **dest, QemuOpts *opts, const char *name)
--
2.39.3
^ permalink raw reply related [flat|nested] 37+ messages in thread
* [PATCH v2 16/20] smbios: error out when building type 4 table is not possible
2024-03-05 15:57 [PATCH v2 00/20] Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS Igor Mammedov
` (14 preceding siblings ...)
2024-03-05 15:57 ` [PATCH v2 15/20] smbios: in case of entry point is 'auto' try to build v2 tables 1st Igor Mammedov
@ 2024-03-05 15:57 ` Igor Mammedov
2024-03-05 15:57 ` [PATCH v2 17/20] smbios: clear smbios_type4_count before building tables Igor Mammedov
` (3 subsequent siblings)
19 siblings, 0 replies; 37+ messages in thread
From: Igor Mammedov @ 2024-03-05 15:57 UTC (permalink / raw)
To: qemu-devel
Cc: peter.maydell, pbonzini, mst, gaosong, alistair.francis, palmer,
bin.meng, liwei1518, dbarboza, zhiwei_liu, imammedo, anisinha,
philmd, wangyanan55, eblake, armbru, qemu-arm, qemu-riscv,
f.ebner
If SMBIOS v2 version is requested but number of cores/threads
are more than it's possible to describe with v2, error out
instead of silently ignoring the fact and filling core/thread
count with bogus values.
This will help caller to decide if it should fallback to
SMBIOSv3 when smbios-entry-point-type='auto'
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Ani Sinha <anisinha@redhat.com>
Tested-by: Fiona Ebner <f.ebner@proxmox.com>
---
hw/smbios/smbios.c | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c
index e54a9f21e6..bf5c7a8885 100644
--- a/hw/smbios/smbios.c
+++ b/hw/smbios/smbios.c
@@ -605,7 +605,8 @@ static void smbios_build_type_3_table(void)
}
static void smbios_build_type_4_table(MachineState *ms, unsigned instance,
- SmbiosEntryPointType ep_type)
+ SmbiosEntryPointType ep_type,
+ Error **errp)
{
char sock_str[128];
size_t tbl_len = SMBIOS_TYPE_4_LEN_V28;
@@ -659,6 +660,12 @@ static void smbios_build_type_4_table(MachineState *ms, unsigned instance,
if (tbl_len == SMBIOS_TYPE_4_LEN_V30) {
t->core_count2 = t->core_enabled2 = cpu_to_le16(cores_per_socket);
t->thread_count2 = cpu_to_le16(threads_per_socket);
+ } else if (t->core_count == 0xFF || t->thread_count == 0xFF) {
+ error_setg(errp, "SMBIOS 2.0 doesn't support number of processor "
+ "cores/threads more than 255, use "
+ "-machine smbios-entry-point-type=64 option to enable "
+ "SMBIOS 3.0 support");
+ return;
}
SMBIOS_BUILD_TABLE_POST;
@@ -987,7 +994,10 @@ static bool smbios_get_tables_ep(MachineState *ms,
assert(ms->smp.sockets >= 1);
for (i = 0; i < ms->smp.sockets; i++) {
- smbios_build_type_4_table(ms, i, ep_type);
+ smbios_build_type_4_table(ms, i, ep_type, errp);
+ if (*errp) {
+ goto err_exit;
+ }
}
smbios_build_type_8_table();
--
2.39.3
^ permalink raw reply related [flat|nested] 37+ messages in thread
* [PATCH v2 17/20] smbios: clear smbios_type4_count before building tables
2024-03-05 15:57 [PATCH v2 00/20] Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS Igor Mammedov
` (15 preceding siblings ...)
2024-03-05 15:57 ` [PATCH v2 16/20] smbios: error out when building type 4 table is not possible Igor Mammedov
@ 2024-03-05 15:57 ` Igor Mammedov
2024-03-06 7:47 ` Ani Sinha
2024-03-05 15:57 ` [PATCH v2 18/20] tests: acpi/smbios: whitelist expected blobs Igor Mammedov
` (2 subsequent siblings)
19 siblings, 1 reply; 37+ messages in thread
From: Igor Mammedov @ 2024-03-05 15:57 UTC (permalink / raw)
To: qemu-devel
Cc: peter.maydell, pbonzini, mst, gaosong, alistair.francis, palmer,
bin.meng, liwei1518, dbarboza, zhiwei_liu, imammedo, anisinha,
philmd, wangyanan55, eblake, armbru, qemu-arm, qemu-riscv,
f.ebner
it will help to keep type 4 tables accounting correct in case
SMBIOS tables are built multiple times.
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Tested-by: Fiona Ebner <f.ebner@proxmox.com>
---
hw/smbios/smbios.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c
index bf5c7a8885..b64d3bc227 100644
--- a/hw/smbios/smbios.c
+++ b/hw/smbios/smbios.c
@@ -981,6 +981,7 @@ static bool smbios_get_tables_ep(MachineState *ms,
ep_type == SMBIOS_ENTRY_POINT_TYPE_64);
g_free(smbios_tables);
+ smbios_type4_count = 0;
smbios_tables = g_memdup2(usr_blobs, usr_blobs_len);
smbios_tables_len = usr_blobs_len;
smbios_table_max = usr_table_max;
--
2.39.3
^ permalink raw reply related [flat|nested] 37+ messages in thread
* [PATCH v2 18/20] tests: acpi/smbios: whitelist expected blobs
2024-03-05 15:57 [PATCH v2 00/20] Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS Igor Mammedov
` (16 preceding siblings ...)
2024-03-05 15:57 ` [PATCH v2 17/20] smbios: clear smbios_type4_count before building tables Igor Mammedov
@ 2024-03-05 15:57 ` Igor Mammedov
2024-03-06 8:31 ` Ani Sinha
2024-03-05 15:57 ` [PATCH v2 19/20] pc/q35: set SMBIOS entry point type to 'auto' by default Igor Mammedov
2024-03-05 15:57 ` [PATCH v2 20/20] tests: acpi: update expected SSDT.dimmpxm blob Igor Mammedov
19 siblings, 1 reply; 37+ messages in thread
From: Igor Mammedov @ 2024-03-05 15:57 UTC (permalink / raw)
To: qemu-devel
Cc: peter.maydell, pbonzini, mst, gaosong, alistair.francis, palmer,
bin.meng, liwei1518, dbarboza, zhiwei_liu, imammedo, anisinha,
philmd, wangyanan55, eblake, armbru, qemu-arm, qemu-riscv,
f.ebner
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
tests/qtest/bios-tables-test-allowed-diff.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h
index dfb8523c8b..81148a604f 100644
--- a/tests/qtest/bios-tables-test-allowed-diff.h
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
@@ -1 +1,2 @@
/* List of comma-separated changed AML files to ignore */
+"tests/data/acpi/q35/SSDT.dimmpxm",
--
2.39.3
^ permalink raw reply related [flat|nested] 37+ messages in thread
* [PATCH v2 19/20] pc/q35: set SMBIOS entry point type to 'auto' by default
2024-03-05 15:57 [PATCH v2 00/20] Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS Igor Mammedov
` (17 preceding siblings ...)
2024-03-05 15:57 ` [PATCH v2 18/20] tests: acpi/smbios: whitelist expected blobs Igor Mammedov
@ 2024-03-05 15:57 ` Igor Mammedov
2024-03-05 15:57 ` [PATCH v2 20/20] tests: acpi: update expected SSDT.dimmpxm blob Igor Mammedov
19 siblings, 0 replies; 37+ messages in thread
From: Igor Mammedov @ 2024-03-05 15:57 UTC (permalink / raw)
To: qemu-devel
Cc: peter.maydell, pbonzini, mst, gaosong, alistair.francis, palmer,
bin.meng, liwei1518, dbarboza, zhiwei_liu, imammedo, anisinha,
philmd, wangyanan55, eblake, armbru, qemu-arm, qemu-riscv,
f.ebner
Use smbios-entry-point-type='auto' for newer machine types as a workaround
for Windows not detecting SMBIOS tables. Which makes QEMU pick SMBIOS tables
based on configuration (with 2.x preferred and fallback to 3.x if the former
isn't compatible with configuration)
Default compat setting of smbios-entry-point-type after series
for pc/q35 machines:
* 9.0-newer: 'auto'
* 8.1-8.2: '64'
* 8.0-older: '32'
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2008
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Ani Sinha <anisinha@redhat.com>
Tested-by: Fiona Ebner <f.ebner@proxmox.com>
---
hw/i386/pc.c | 2 +-
hw/i386/pc_piix.c | 4 ++++
hw/i386/pc_q35.c | 3 +++
3 files changed, 8 insertions(+), 1 deletion(-)
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index a8e8aa2ac8..cf16337341 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1847,7 +1847,7 @@ static void pc_machine_class_init(ObjectClass *oc, void *data)
mc->nvdimm_supported = true;
mc->smp_props.dies_supported = true;
mc->default_ram_id = "pc.ram";
- pcmc->default_smbios_ep_type = SMBIOS_ENTRY_POINT_TYPE_64;
+ pcmc->default_smbios_ep_type = SMBIOS_ENTRY_POINT_TYPE_AUTO;
object_class_property_add(oc, PC_MACHINE_MAX_RAM_BELOW_4G, "size",
pc_machine_get_max_ram_below_4g, pc_machine_set_max_ram_below_4g,
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index ce6aad758d..cebf61d12c 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -531,12 +531,16 @@ DEFINE_I440FX_MACHINE(v9_0, "pc-i440fx-9.0", NULL,
static void pc_i440fx_8_2_machine_options(MachineClass *m)
{
+ PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
+
pc_i440fx_9_0_machine_options(m);
m->alias = NULL;
m->is_default = false;
compat_props_add(m->compat_props, hw_compat_8_2, hw_compat_8_2_len);
compat_props_add(m->compat_props, pc_compat_8_2, pc_compat_8_2_len);
+ /* For pc-i44fx-8.2 and 8.1, use SMBIOS 3.X by default */
+ pcmc->default_smbios_ep_type = SMBIOS_ENTRY_POINT_TYPE_64;
}
DEFINE_I440FX_MACHINE(v8_2, "pc-i440fx-8.2", NULL,
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index 45a4102e75..6fef3b17bb 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -369,10 +369,13 @@ DEFINE_Q35_MACHINE(v9_0, "pc-q35-9.0", NULL,
static void pc_q35_8_2_machine_options(MachineClass *m)
{
+ PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
pc_q35_9_0_machine_options(m);
m->alias = NULL;
compat_props_add(m->compat_props, hw_compat_8_2, hw_compat_8_2_len);
compat_props_add(m->compat_props, pc_compat_8_2, pc_compat_8_2_len);
+ /* For pc-q35-8.2 and 8.1, use SMBIOS 3.X by default */
+ pcmc->default_smbios_ep_type = SMBIOS_ENTRY_POINT_TYPE_64;
}
DEFINE_Q35_MACHINE(v8_2, "pc-q35-8.2", NULL,
--
2.39.3
^ permalink raw reply related [flat|nested] 37+ messages in thread
* [PATCH v2 20/20] tests: acpi: update expected SSDT.dimmpxm blob
2024-03-05 15:57 [PATCH v2 00/20] Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS Igor Mammedov
` (18 preceding siblings ...)
2024-03-05 15:57 ` [PATCH v2 19/20] pc/q35: set SMBIOS entry point type to 'auto' by default Igor Mammedov
@ 2024-03-05 15:57 ` Igor Mammedov
2024-03-06 9:20 ` Ani Sinha
19 siblings, 1 reply; 37+ messages in thread
From: Igor Mammedov @ 2024-03-05 15:57 UTC (permalink / raw)
To: qemu-devel
Cc: peter.maydell, pbonzini, mst, gaosong, alistair.francis, palmer,
bin.meng, liwei1518, dbarboza, zhiwei_liu, imammedo, anisinha,
philmd, wangyanan55, eblake, armbru, qemu-arm, qemu-riscv,
f.ebner
address shift is caused by switch to 32-bit SMBIOS entry point
which has slightly different size from 64-bit one and happens
to trigger a bit different memory layout.
Expected diff:
- Name (MEMA, 0x07FFE000)
+ Name (MEMA, 0x07FFF000)
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
tests/qtest/bios-tables-test-allowed-diff.h | 1 -
tests/data/acpi/q35/SSDT.dimmpxm | Bin 1815 -> 1815 bytes
2 files changed, 1 deletion(-)
diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h
index 81148a604f..dfb8523c8b 100644
--- a/tests/qtest/bios-tables-test-allowed-diff.h
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
@@ -1,2 +1 @@
/* List of comma-separated changed AML files to ignore */
-"tests/data/acpi/q35/SSDT.dimmpxm",
diff --git a/tests/data/acpi/q35/SSDT.dimmpxm b/tests/data/acpi/q35/SSDT.dimmpxm
index 70f133412f5e0aa128ab210245a8de7304eeb843..9ea4e0d0ceaa8a5cbd706afb6d49de853fafe654 100644
GIT binary patch
delta 23
ecmbQvH=U0wIM^jboSlJzam_|9E_UV*|JeaVTLvQl
delta 23
ecmbQvH=U0wIM^jboSlJzanD9BE_UVz|JeaVy9Ofw
--
2.39.3
^ permalink raw reply related [flat|nested] 37+ messages in thread
* Re: [PATCH v2 07/20] smbios: avoid mangling user provided tables
2024-03-05 15:57 ` [PATCH v2 07/20] smbios: avoid mangling user provided tables Igor Mammedov
@ 2024-03-06 6:41 ` Ani Sinha
2024-03-07 4:03 ` Ani Sinha
0 siblings, 1 reply; 37+ messages in thread
From: Ani Sinha @ 2024-03-06 6:41 UTC (permalink / raw)
To: Igor Mammedov
Cc: qemu-devel, peter.maydell, pbonzini, mst, gaosong,
alistair.francis, palmer, bin.meng, liwei1518, dbarboza,
zhiwei_liu, philmd, wangyanan55, eblake, armbru, qemu-arm,
qemu-riscv, f.ebner
On Tue, 5 Mar 2024, Igor Mammedov wrote:
> currently smbios_entry_add() preserves internally '-smbios type='
> options but tables provided with '-smbios file=' are stored directly
> into blob that eventually will be exposed to VM. And then later
> QEMU adds default/'-smbios type' entries on top into the same blob.
>
> It makes impossible to generate tables more than once, hence
> 'immutable' guard was used.
> Make it possible to regenerate final blob by storing user provided
> blobs into a dedicated area (usr_blobs) and then copy it when
> composing final blob. Which also makes handling of -smbios
> options consistent.
>
> As side effect of this and previous commits there is no need to
> generate legacy smbios_entries at the time options are parsed.
> Instead compose smbios_entries on demand from usr_blobs like
> it is done for non-legacy SMBIOS tables.
>
> Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> Tested-by: Fiona Ebner <f.ebner@proxmox.com>
Reviewed-by: Ani Sinha <anisinha@redhat.com>
> ---
> hw/smbios/smbios.c | 179 +++++++++++++++++++++++----------------------
> 1 file changed, 92 insertions(+), 87 deletions(-)
>
> diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c
> index c46fc93357..aa2cc5bdbd 100644
> --- a/hw/smbios/smbios.c
> +++ b/hw/smbios/smbios.c
> @@ -57,6 +57,14 @@ static size_t smbios_entries_len;
> static bool smbios_uuid_encoded = true;
> /* end: legacy structures & constants for <= 2.0 machines */
>
> +/*
> + * SMBIOS tables provided by user with '-smbios file=<foo>' option
> + */
> +uint8_t *usr_blobs;
> +size_t usr_blobs_len;
> +static GArray *usr_blobs_sizes;
> +static unsigned usr_table_max;
> +static unsigned usr_table_cnt;
>
> uint8_t *smbios_tables;
> size_t smbios_tables_len;
> @@ -67,7 +75,6 @@ static SmbiosEntryPointType smbios_ep_type = SMBIOS_ENTRY_POINT_TYPE_32;
> static SmbiosEntryPoint ep;
>
> static int smbios_type4_count = 0;
> -static bool smbios_immutable;
> static bool smbios_have_defaults;
> static uint32_t smbios_cpuid_version, smbios_cpuid_features;
>
> @@ -569,9 +576,8 @@ static void smbios_build_type_1_fields(void)
>
> uint8_t *smbios_get_table_legacy(uint32_t expected_t4_count, size_t *length)
> {
> - /* drop unwanted version of command-line file blob(s) */
> - g_free(smbios_tables);
> - smbios_tables = NULL;
> + int i;
> + size_t usr_offset;
>
> /* also complain if fields were given for types > 1 */
> if (find_next_bit(have_fields_bitmap,
> @@ -581,12 +587,33 @@ uint8_t *smbios_get_table_legacy(uint32_t expected_t4_count, size_t *length)
> exit(1);
> }
>
> - if (!smbios_immutable) {
> - smbios_build_type_0_fields();
> - smbios_build_type_1_fields();
> - smbios_validate_table(expected_t4_count);
> - smbios_immutable = true;
> + g_free(smbios_entries);
> + smbios_entries_len = sizeof(uint16_t);
> + smbios_entries = g_malloc0(smbios_entries_len);
> +
> + for (i = 0, usr_offset = 0; usr_blobs_sizes && i < usr_blobs_sizes->len;
> + i++)
> + {
> + struct smbios_table *table;
> + struct smbios_structure_header *header;
> + size_t size = g_array_index(usr_blobs_sizes, size_t, i);
> +
> + header = (struct smbios_structure_header *)(usr_blobs + usr_offset);
> + smbios_entries = g_realloc(smbios_entries, smbios_entries_len +
> + size + sizeof(*table));
> + table = (struct smbios_table *)(smbios_entries + smbios_entries_len);
> + table->header.type = SMBIOS_TABLE_ENTRY;
> + table->header.length = cpu_to_le16(sizeof(*table) + size);
> + memcpy(table->data, header, size);
> + smbios_entries_len += sizeof(*table) + size;
> + (*(uint16_t *)smbios_entries) =
> + cpu_to_le16(le16_to_cpu(*(uint16_t *)smbios_entries) + 1);
I know this comes from existing code but can you please explain why we add
1 to it? This is confusing and a comment here would be nice.
> + usr_offset += size;
It would be better if we could add a comment here describing a bit what
this is all about.
user blobs are an array of smbios_structure_header entries whereas legacy
tables are an array of smbios_table structures where
smbios_table->data represents the a single user provided table blob in
smbios_structure_header.
> }
> +
> + smbios_build_type_0_fields();
> + smbios_build_type_1_fields();
> + smbios_validate_table(expected_t4_count);
> *length = smbios_entries_len;
> return smbios_entries;
> }
> @@ -1094,67 +1121,67 @@ void smbios_get_tables(MachineState *ms,
> {
> unsigned i, dimm_cnt, offset;
>
> - /* drop unwanted (legacy) version of command-line file blob(s) */
> - g_free(smbios_entries);
> - smbios_entries = NULL;
> + g_free(smbios_tables);
> + smbios_tables = g_memdup2(usr_blobs, usr_blobs_len);
Again a comment describing here would be nice as to why memdup is ok.
> + smbios_tables_len = usr_blobs_len;
> + smbios_table_max = usr_table_max;
> + smbios_table_cnt = usr_table_cnt;
>
> - if (!smbios_immutable) {
> - smbios_build_type_0_table();
> - smbios_build_type_1_table();
> - smbios_build_type_2_table();
> - smbios_build_type_3_table();
> + smbios_build_type_0_table();
> + smbios_build_type_1_table();
> + smbios_build_type_2_table();
> + smbios_build_type_3_table();
>
> - assert(ms->smp.sockets >= 1);
> + assert(ms->smp.sockets >= 1);
>
> - for (i = 0; i < ms->smp.sockets; i++) {
> - smbios_build_type_4_table(ms, i);
> - }
> + for (i = 0; i < ms->smp.sockets; i++) {
> + smbios_build_type_4_table(ms, i);
> + }
>
> - smbios_build_type_8_table();
> - smbios_build_type_11_table();
> + smbios_build_type_8_table();
> + smbios_build_type_11_table();
>
> #define MAX_DIMM_SZ (16 * GiB)
> #define GET_DIMM_SZ ((i < dimm_cnt - 1) ? MAX_DIMM_SZ \
> : ((current_machine->ram_size - 1) % MAX_DIMM_SZ) + 1)
>
> - dimm_cnt = QEMU_ALIGN_UP(current_machine->ram_size, MAX_DIMM_SZ) / MAX_DIMM_SZ;
> + dimm_cnt = QEMU_ALIGN_UP(current_machine->ram_size, MAX_DIMM_SZ) /
> + MAX_DIMM_SZ;
>
> - /*
> - * The offset determines if we need to keep additional space between
> - * table 17 and table 19 header handle numbers so that they do
> - * not overlap. For example, for a VM with larger than 8 TB guest
> - * memory and DIMM like chunks of 16 GiB, the default space between
> - * the two tables (T19_BASE - T17_BASE = 512) is not enough.
> - */
> - offset = (dimm_cnt > (T19_BASE - T17_BASE)) ? \
> - dimm_cnt - (T19_BASE - T17_BASE) : 0;
> + /*
> + * The offset determines if we need to keep additional space between
> + * table 17 and table 19 header handle numbers so that they do
> + * not overlap. For example, for a VM with larger than 8 TB guest
> + * memory and DIMM like chunks of 16 GiB, the default space between
> + * the two tables (T19_BASE - T17_BASE = 512) is not enough.
> + */
> + offset = (dimm_cnt > (T19_BASE - T17_BASE)) ? \
> + dimm_cnt - (T19_BASE - T17_BASE) : 0;
>
> - smbios_build_type_16_table(dimm_cnt);
> + smbios_build_type_16_table(dimm_cnt);
>
> - for (i = 0; i < dimm_cnt; i++) {
> - smbios_build_type_17_table(i, GET_DIMM_SZ);
> - }
> + for (i = 0; i < dimm_cnt; i++) {
> + smbios_build_type_17_table(i, GET_DIMM_SZ);
> + }
>
> - for (i = 0; i < mem_array_size; i++) {
> - smbios_build_type_19_table(i, offset, mem_array[i].address,
> - mem_array[i].length);
> - }
> + for (i = 0; i < mem_array_size; i++) {
> + smbios_build_type_19_table(i, offset, mem_array[i].address,
> + mem_array[i].length);
> + }
>
> - /*
> - * make sure 16 bit handle numbers in the headers of tables 19
> - * and 32 do not overlap.
> - */
> - assert((mem_array_size + offset) < (T32_BASE - T19_BASE));
> + /*
> + * make sure 16 bit handle numbers in the headers of tables 19
> + * and 32 do not overlap.
> + */
> + assert((mem_array_size + offset) < (T32_BASE - T19_BASE));
>
> - smbios_build_type_32_table();
> - smbios_build_type_38_table();
> - smbios_build_type_41_table(errp);
> - smbios_build_type_127_table();
> + smbios_build_type_32_table();
> + smbios_build_type_38_table();
> + smbios_build_type_41_table(errp);
> + smbios_build_type_127_table();
>
> - smbios_validate_table(ms->smp.sockets);
> - smbios_entry_point_setup();
> - smbios_immutable = true;
> - }
> + smbios_validate_table(ms->smp.sockets);
> + smbios_entry_point_setup();
>
> /* return tables blob and entry point (anchor), and their sizes */
> *tables = smbios_tables;
> @@ -1254,13 +1281,10 @@ void smbios_entry_add(QemuOpts *opts, Error **errp)
> {
> const char *val;
>
> - assert(!smbios_immutable);
> -
> val = qemu_opt_get(opts, "file");
> if (val) {
> struct smbios_structure_header *header;
> - int size;
> - struct smbios_table *table; /* legacy mode only */
> + size_t size;
>
> if (!qemu_opts_validate(opts, qemu_smbios_file_opts, errp)) {
> return;
> @@ -1277,9 +1301,9 @@ void smbios_entry_add(QemuOpts *opts, Error **errp)
> * (except in legacy mode, where the second '\0' is implicit and
> * will be inserted by the BIOS).
> */
> - smbios_tables = g_realloc(smbios_tables, smbios_tables_len + size);
> - header = (struct smbios_structure_header *)(smbios_tables +
> - smbios_tables_len);
> + usr_blobs = g_realloc(usr_blobs, usr_blobs_len + size);
> + header = (struct smbios_structure_header *)(usr_blobs +
> + usr_blobs_len);
>
> if (load_image_size(val, (uint8_t *)header, size) != size) {
> error_setg(errp, "Failed to load SMBIOS file %s", val);
> @@ -1300,34 +1324,15 @@ void smbios_entry_add(QemuOpts *opts, Error **errp)
> smbios_type4_count++;
> }
>
> - smbios_tables_len += size;
> - if (size > smbios_table_max) {
> - smbios_table_max = size;
> + if (!usr_blobs_sizes) {
> + usr_blobs_sizes = g_array_new(false, false, sizeof(size_t));
> }
> - smbios_table_cnt++;
> -
> - /* add a copy of the newly loaded blob to legacy smbios_entries */
> - /* NOTE: This code runs before smbios_set_defaults(), so we don't
> - * yet know which mode (legacy vs. aggregate-table) will be
> - * required. We therefore add the binary blob to both legacy
> - * (smbios_entries) and aggregate (smbios_tables) tables, and
> - * delete the one we don't need from smbios_set_defaults(),
> - * once we know which machine version has been requested.
> - */
> - if (!smbios_entries) {
> - smbios_entries_len = sizeof(uint16_t);
> - smbios_entries = g_malloc0(smbios_entries_len);
> + g_array_append_val(usr_blobs_sizes, size);
> + usr_blobs_len += size;
> + if (size > usr_table_max) {
> + usr_table_max = size;
> }
> - smbios_entries = g_realloc(smbios_entries, smbios_entries_len +
> - size + sizeof(*table));
> - table = (struct smbios_table *)(smbios_entries + smbios_entries_len);
> - table->header.type = SMBIOS_TABLE_ENTRY;
> - table->header.length = cpu_to_le16(sizeof(*table) + size);
> - memcpy(table->data, header, size);
> - smbios_entries_len += sizeof(*table) + size;
> - (*(uint16_t *)smbios_entries) =
> - cpu_to_le16(le16_to_cpu(*(uint16_t *)smbios_entries) + 1);
> - /* end: add a copy of the newly loaded blob to legacy smbios_entries */
> + usr_table_cnt++;
>
> return;
> }
> --
> 2.39.3
>
>
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: [PATCH v2 09/20] smbios: add smbios_add_usr_blob_size() helper
2024-03-05 15:57 ` [PATCH v2 09/20] smbios: add smbios_add_usr_blob_size() helper Igor Mammedov
@ 2024-03-06 6:48 ` Ani Sinha
0 siblings, 0 replies; 37+ messages in thread
From: Ani Sinha @ 2024-03-06 6:48 UTC (permalink / raw)
To: Igor Mammedov
Cc: QEMU Developers, Peter Maydell, Paolo Bonzini, Michael S. Tsirkin,
Song Gao, Alistair Francis, palmer, bin.meng, liwei1518, dbarboza,
zhiwei_liu, Philippe Mathieu-Daudé, Yanan Wang, Eric Blake,
Markus Armbruster, qemu-arm, qemu-riscv, f.ebner
> On 05-Mar-2024, at 21:27, Igor Mammedov <imammedo@redhat.com> wrote:
>
> it will be used by follow up patch when legacy handling
> is moved out into a separate file.
>
> Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Ani Sinha <anisinha@redhat.com>
> ---
> hw/smbios/smbios.c | 18 ++++++++++++++----
> 1 file changed, 14 insertions(+), 4 deletions(-)
>
> diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c
> index 97cf762228..01180bd82c 100644
> --- a/hw/smbios/smbios.c
> +++ b/hw/smbios/smbios.c
> @@ -1287,6 +1287,14 @@ static bool save_opt_list(size_t *ndest, char ***dest, QemuOpts *opts,
> return true;
> }
>
> +static void smbios_add_usr_blob_size(size_t size)
> +{
> + if (!usr_blobs_sizes) {
> + usr_blobs_sizes = g_array_new(false, false, sizeof(size_t));
> + }
> + g_array_append_val(usr_blobs_sizes, size);
> +}
> +
> void smbios_entry_add(QemuOpts *opts, Error **errp)
> {
> const char *val;
> @@ -1334,10 +1342,12 @@ void smbios_entry_add(QemuOpts *opts, Error **errp)
> smbios_type4_count++;
> }
>
> - if (!usr_blobs_sizes) {
> - usr_blobs_sizes = g_array_new(false, false, sizeof(size_t));
> - }
> - g_array_append_val(usr_blobs_sizes, size);
> + /*
> + * preserve blob size for legacy mode so it could build its
> + * blobs flavor from 'usr_blobs'
> + */
> + smbios_add_usr_blob_size(size);
> +
> usr_blobs_len += size;
> if (size > usr_table_max) {
> usr_table_max = size;
> --
> 2.39.3
>
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: [PATCH v2 10/20] smbios: rename/expose structures/bitmaps used by both legacy and modern code
2024-03-05 15:57 ` [PATCH v2 10/20] smbios: rename/expose structures/bitmaps used by both legacy and modern code Igor Mammedov
@ 2024-03-06 7:15 ` Ani Sinha
0 siblings, 0 replies; 37+ messages in thread
From: Ani Sinha @ 2024-03-06 7:15 UTC (permalink / raw)
To: Igor Mammedov
Cc: qemu-devel, peter.maydell, pbonzini, mst, gaosong,
alistair.francis, palmer, bin.meng, liwei1518, dbarboza,
zhiwei_liu, philmd, wangyanan55, eblake, armbru, qemu-arm,
qemu-riscv, f.ebner
On Tue, 5 Mar 2024, Igor Mammedov wrote:
> As a preparation to move legacy handling into a separate file,
> add prefix 'smbios_' to type0/type1/have_binfile_bitmap/have_fields_bitmap
> and expose them in smbios.h so that they can be reused in
> legacy and modern code.
>
> Doing it as a separate patch to avoid rename cluttering follow-up
> patch which will move legacy code into a separate file.
>
I checked that after application of this patch in the patcset, QEMU build
goes through fine. Therefore,
> Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Ani Sinha <anisinha@redhat.com>
> ---
> include/hw/firmware/smbios.h | 16 +++++
> hw/smbios/smbios.c | 113 ++++++++++++++++-------------------
> 2 files changed, 69 insertions(+), 60 deletions(-)
>
> diff --git a/include/hw/firmware/smbios.h b/include/hw/firmware/smbios.h
> index 1fbff3c55f..bea5c3f1b1 100644
> --- a/include/hw/firmware/smbios.h
> +++ b/include/hw/firmware/smbios.h
> @@ -2,6 +2,7 @@
> #define QEMU_SMBIOS_H
>
> #include "qapi/qapi-types-machine.h"
> +#include "qemu/bitmap.h"
>
> /*
> * SMBIOS Support
> @@ -16,8 +17,23 @@
> *
> */
>
> +typedef struct {
> + const char *vendor, *version, *date;
> + bool have_major_minor, uefi;
> + uint8_t major, minor;
> +} smbios_type0_t;
> +extern smbios_type0_t smbios_type0;
> +
> +typedef struct {
> + const char *manufacturer, *product, *version, *serial, *sku, *family;
> + /* uuid is in qemu_uuid */
> +} smbios_type1_t;
> +extern smbios_type1_t smbios_type1;
>
> #define SMBIOS_MAX_TYPE 127
> +extern DECLARE_BITMAP(smbios_have_binfile_bitmap, SMBIOS_MAX_TYPE + 1);
> +extern DECLARE_BITMAP(smbios_have_fields_bitmap, SMBIOS_MAX_TYPE + 1);
> +
> #define offsetofend(TYPE, MEMBER) \
> (offsetof(TYPE, MEMBER) + sizeof_field(TYPE, MEMBER))
>
> diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c
> index 01180bd82c..86cf66b5ce 100644
> --- a/hw/smbios/smbios.c
> +++ b/hw/smbios/smbios.c
> @@ -78,19 +78,11 @@ static int smbios_type4_count = 0;
> static bool smbios_have_defaults;
> static uint32_t smbios_cpuid_version, smbios_cpuid_features;
>
> -static DECLARE_BITMAP(have_binfile_bitmap, SMBIOS_MAX_TYPE+1);
> -static DECLARE_BITMAP(have_fields_bitmap, SMBIOS_MAX_TYPE+1);
> +DECLARE_BITMAP(smbios_have_binfile_bitmap, SMBIOS_MAX_TYPE + 1);
> +DECLARE_BITMAP(smbios_have_fields_bitmap, SMBIOS_MAX_TYPE + 1);
>
> -static struct {
> - const char *vendor, *version, *date;
> - bool have_major_minor, uefi;
> - uint8_t major, minor;
> -} type0;
> -
> -static struct {
> - const char *manufacturer, *product, *version, *serial, *sku, *family;
> - /* uuid is in qemu_uuid */
> -} type1;
> +smbios_type0_t smbios_type0;
> +smbios_type1_t smbios_type1;
>
> static struct {
> const char *manufacturer, *product, *version, *serial, *asset, *location;
> @@ -536,36 +528,36 @@ static void smbios_maybe_add_str(int type, int offset, const char *data)
> static void smbios_build_type_0_fields(void)
> {
> smbios_maybe_add_str(0, offsetof(struct smbios_type_0, vendor_str),
> - type0.vendor);
> + smbios_type0.vendor);
> smbios_maybe_add_str(0, offsetof(struct smbios_type_0, bios_version_str),
> - type0.version);
> + smbios_type0.version);
> smbios_maybe_add_str(0, offsetof(struct smbios_type_0,
> bios_release_date_str),
> - type0.date);
> - if (type0.have_major_minor) {
> + smbios_type0.date);
> + if (smbios_type0.have_major_minor) {
> smbios_add_field(0, offsetof(struct smbios_type_0,
> system_bios_major_release),
> - &type0.major, 1);
> + &smbios_type0.major, 1);
> smbios_add_field(0, offsetof(struct smbios_type_0,
> system_bios_minor_release),
> - &type0.minor, 1);
> + &smbios_type0.minor, 1);
> }
> }
>
> static void smbios_build_type_1_fields(void)
> {
> smbios_maybe_add_str(1, offsetof(struct smbios_type_1, manufacturer_str),
> - type1.manufacturer);
> + smbios_type1.manufacturer);
> smbios_maybe_add_str(1, offsetof(struct smbios_type_1, product_name_str),
> - type1.product);
> + smbios_type1.product);
> smbios_maybe_add_str(1, offsetof(struct smbios_type_1, version_str),
> - type1.version);
> + smbios_type1.version);
> smbios_maybe_add_str(1, offsetof(struct smbios_type_1, serial_number_str),
> - type1.serial);
> + smbios_type1.serial);
> smbios_maybe_add_str(1, offsetof(struct smbios_type_1, sku_number_str),
> - type1.sku);
> + smbios_type1.sku);
> smbios_maybe_add_str(1, offsetof(struct smbios_type_1, family_str),
> - type1.family);
> + smbios_type1.family);
> if (qemu_uuid_set) {
> /* We don't encode the UUID in the "wire format" here because this
> * function is for legacy mode and needs to keep the guest ABI, and
> @@ -583,14 +575,14 @@ uint8_t *smbios_get_table_legacy(size_t *length)
> size_t usr_offset;
>
> /* also complain if fields were given for types > 1 */
> - if (find_next_bit(have_fields_bitmap,
> + if (find_next_bit(smbios_have_fields_bitmap,
> SMBIOS_MAX_TYPE + 1, 2) < SMBIOS_MAX_TYPE + 1) {
> error_report("can't process fields for smbios "
> "types > 1 on machine versions < 2.1!");
> exit(1);
> }
>
> - if (test_bit(4, have_binfile_bitmap)) {
> + if (test_bit(4, smbios_have_binfile_bitmap)) {
> error_report("can't process table for smbios "
> "type 4 on machine versions < 2.1!");
> exit(1);
> @@ -631,10 +623,10 @@ uint8_t *smbios_get_table_legacy(size_t *length)
>
> bool smbios_skip_table(uint8_t type, bool required_table)
> {
> - if (test_bit(type, have_binfile_bitmap)) {
> + if (test_bit(type, smbios_have_binfile_bitmap)) {
> return true; /* user provided their own binary blob(s) */
> }
> - if (test_bit(type, have_fields_bitmap)) {
> + if (test_bit(type, smbios_have_fields_bitmap)) {
> return false; /* user provided fields via command line */
> }
> if (smbios_have_defaults && required_table) {
> @@ -661,25 +653,25 @@ static void smbios_build_type_0_table(void)
> {
> SMBIOS_BUILD_TABLE_PRE(0, T0_BASE, false); /* optional, leave up to BIOS */
>
> - SMBIOS_TABLE_SET_STR(0, vendor_str, type0.vendor);
> - SMBIOS_TABLE_SET_STR(0, bios_version_str, type0.version);
> + SMBIOS_TABLE_SET_STR(0, vendor_str, smbios_type0.vendor);
> + SMBIOS_TABLE_SET_STR(0, bios_version_str, smbios_type0.version);
>
> t->bios_starting_address_segment = cpu_to_le16(0xE800); /* from SeaBIOS */
>
> - SMBIOS_TABLE_SET_STR(0, bios_release_date_str, type0.date);
> + SMBIOS_TABLE_SET_STR(0, bios_release_date_str, smbios_type0.date);
>
> 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 (type0.uefi) {
> + if (smbios_type0.uefi) {
> t->bios_characteristics_extension_bytes[1] |= 0x08; /* |= UEFI */
> }
>
> - if (type0.have_major_minor) {
> - t->system_bios_major_release = type0.major;
> - t->system_bios_minor_release = type0.minor;
> + if (smbios_type0.have_major_minor) {
> + t->system_bios_major_release = smbios_type0.major;
> + t->system_bios_minor_release = smbios_type0.minor;
> } else {
> t->system_bios_major_release = 0;
> t->system_bios_minor_release = 0;
> @@ -709,18 +701,18 @@ static void smbios_build_type_1_table(void)
> {
> SMBIOS_BUILD_TABLE_PRE(1, T1_BASE, true); /* required */
>
> - SMBIOS_TABLE_SET_STR(1, manufacturer_str, type1.manufacturer);
> - SMBIOS_TABLE_SET_STR(1, product_name_str, type1.product);
> - SMBIOS_TABLE_SET_STR(1, version_str, type1.version);
> - SMBIOS_TABLE_SET_STR(1, serial_number_str, type1.serial);
> + SMBIOS_TABLE_SET_STR(1, manufacturer_str, smbios_type1.manufacturer);
> + SMBIOS_TABLE_SET_STR(1, product_name_str, smbios_type1.product);
> + SMBIOS_TABLE_SET_STR(1, version_str, smbios_type1.version);
> + SMBIOS_TABLE_SET_STR(1, serial_number_str, smbios_type1.serial);
> if (qemu_uuid_set) {
> smbios_encode_uuid(&t->uuid, &qemu_uuid);
> } else {
> memset(&t->uuid, 0, 16);
> }
> t->wake_up_type = 0x06; /* power switch */
> - SMBIOS_TABLE_SET_STR(1, sku_number_str, type1.sku);
> - SMBIOS_TABLE_SET_STR(1, family_str, type1.family);
> + SMBIOS_TABLE_SET_STR(1, sku_number_str, smbios_type1.sku);
> + SMBIOS_TABLE_SET_STR(1, family_str, smbios_type1.family);
>
> SMBIOS_BUILD_TABLE_POST;
> }
> @@ -1055,9 +1047,9 @@ void smbios_set_defaults(const char *manufacturer, const char *product,
> smbios_uuid_encoded = uuid_encoded;
> smbios_ep_type = ep_type;
>
> - SMBIOS_SET_DEFAULT(type1.manufacturer, manufacturer);
> - SMBIOS_SET_DEFAULT(type1.product, product);
> - SMBIOS_SET_DEFAULT(type1.version, version);
> + SMBIOS_SET_DEFAULT(smbios_type1.manufacturer, manufacturer);
> + SMBIOS_SET_DEFAULT(smbios_type1.product, product);
> + SMBIOS_SET_DEFAULT(smbios_type1.version, version);
> SMBIOS_SET_DEFAULT(type2.manufacturer, manufacturer);
> SMBIOS_SET_DEFAULT(type2.product, product);
> SMBIOS_SET_DEFAULT(type2.version, version);
> @@ -1329,13 +1321,13 @@ void smbios_entry_add(QemuOpts *opts, Error **errp)
> }
>
> if (header->type <= SMBIOS_MAX_TYPE) {
> - if (test_bit(header->type, have_fields_bitmap)) {
> + if (test_bit(header->type, smbios_have_fields_bitmap)) {
> error_setg(errp,
> "can't load type %d struct, fields already specified!",
> header->type);
> return;
> }
> - set_bit(header->type, have_binfile_bitmap);
> + set_bit(header->type, smbios_have_binfile_bitmap);
> }
>
> if (header->type == 4) {
> @@ -1366,41 +1358,42 @@ void smbios_entry_add(QemuOpts *opts, Error **errp)
> return;
> }
>
> - if (test_bit(type, have_binfile_bitmap)) {
> + if (test_bit(type, smbios_have_binfile_bitmap)) {
> error_setg(errp, "can't add fields, binary file already loaded!");
> return;
> }
> - set_bit(type, have_fields_bitmap);
> + set_bit(type, smbios_have_fields_bitmap);
>
> switch (type) {
> case 0:
> if (!qemu_opts_validate(opts, qemu_smbios_type0_opts, errp)) {
> return;
> }
> - save_opt(&type0.vendor, opts, "vendor");
> - save_opt(&type0.version, opts, "version");
> - save_opt(&type0.date, opts, "date");
> - type0.uefi = qemu_opt_get_bool(opts, "uefi", false);
> + 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);
>
> val = qemu_opt_get(opts, "release");
> if (val) {
> - if (sscanf(val, "%hhu.%hhu", &type0.major, &type0.minor) != 2) {
> + if (sscanf(val, "%hhu.%hhu", &smbios_type0.major,
> + &smbios_type0.minor) != 2) {
> error_setg(errp, "Invalid release");
> return;
> }
> - type0.have_major_minor = true;
> + smbios_type0.have_major_minor = true;
> }
> return;
> case 1:
> if (!qemu_opts_validate(opts, qemu_smbios_type1_opts, errp)) {
> return;
> }
> - save_opt(&type1.manufacturer, opts, "manufacturer");
> - save_opt(&type1.product, opts, "product");
> - save_opt(&type1.version, opts, "version");
> - save_opt(&type1.serial, opts, "serial");
> - save_opt(&type1.sku, opts, "sku");
> - save_opt(&type1.family, opts, "family");
> + save_opt(&smbios_type1.manufacturer, opts, "manufacturer");
> + save_opt(&smbios_type1.product, opts, "product");
> + save_opt(&smbios_type1.version, opts, "version");
> + save_opt(&smbios_type1.serial, opts, "serial");
> + save_opt(&smbios_type1.sku, opts, "sku");
> + save_opt(&smbios_type1.family, opts, "family");
>
> val = qemu_opt_get(opts, "uuid");
> if (val) {
> --
> 2.39.3
>
>
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: [PATCH v2 11/20] smbios: build legacy mode code only for 'pc' machine
2024-03-05 15:57 ` [PATCH v2 11/20] smbios: build legacy mode code only for 'pc' machine Igor Mammedov
@ 2024-03-06 7:27 ` Ani Sinha
2024-03-06 10:04 ` Igor Mammedov
2024-03-06 10:03 ` [PATCH v3 " Igor Mammedov
1 sibling, 1 reply; 37+ messages in thread
From: Ani Sinha @ 2024-03-06 7:27 UTC (permalink / raw)
To: Igor Mammedov
Cc: QEMU Developers, Peter Maydell, Paolo Bonzini, Michael S. Tsirkin,
Song Gao, Alistair Francis, palmer, bin.meng, liwei1518, dbarboza,
zhiwei_liu, Philippe Mathieu-Daudé, Yanan Wang, Eric Blake,
Markus Armbruster, qemu-arm, qemu-riscv, f.ebner
> On 05-Mar-2024, at 21:27, Igor Mammedov <imammedo@redhat.com> wrote:
>
> basically moving code around without functional change.
> And exposing some symbols so that they could be shared
> between smbbios.c and new smbios_legacy.c
>
> plus some meson magic to build smbios_legacy.c only
> for 'pc' machine and otherwise replace it with stub
> if not selected.
When I apply this, I get:
Applying: smbios: build legacy mode code only for 'pc' machine
.git/rebase-apply/patch:483: new blank line at EOF.
+
warning: 1 line adds whitespace errors.
Can you please look into this? Modulo that,
>
> Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Ani Sinha <anisinha@redhat.com>
> ---
> v2:
> moved type0/type1/have_binfile_bitmap/have_fields_bitmap rename into
> a separate patch
> ---
> include/hw/firmware/smbios.h | 5 +
> hw/i386/Kconfig | 1 +
> hw/smbios/Kconfig | 2 +
> hw/smbios/meson.build | 4 +
> hw/smbios/smbios.c | 164 +-----------------------------
> hw/smbios/smbios_legacy.c | 179 +++++++++++++++++++++++++++++++++
> hw/smbios/smbios_legacy_stub.c | 16 +++
> 7 files changed, 208 insertions(+), 163 deletions(-)
> create mode 100644 hw/smbios/smbios_legacy.c
> create mode 100644 hw/smbios/smbios_legacy_stub.c
>
> diff --git a/include/hw/firmware/smbios.h b/include/hw/firmware/smbios.h
> index bea5c3f1b1..7f47475aa4 100644
> --- a/include/hw/firmware/smbios.h
> +++ b/include/hw/firmware/smbios.h
> @@ -17,6 +17,9 @@
> *
> */
>
> +extern uint8_t *usr_blobs;
> +extern GArray *usr_blobs_sizes;
> +
> typedef struct {
> const char *vendor, *version, *date;
> bool have_major_minor, uefi;
> @@ -306,6 +309,8 @@ struct smbios_type_127 {
> struct smbios_structure_header header;
> } QEMU_PACKED;
>
> +void smbios_validate_table(void);
> +void smbios_add_usr_blob_size(size_t size);
> void smbios_entry_add(QemuOpts *opts, Error **errp);
> void smbios_set_cpuid(uint32_t version, uint32_t features);
> void smbios_set_defaults(const char *manufacturer, const char *product,
> diff --git a/hw/i386/Kconfig b/hw/i386/Kconfig
> index a1846be6f7..a6ee052f9a 100644
> --- a/hw/i386/Kconfig
> +++ b/hw/i386/Kconfig
> @@ -76,6 +76,7 @@ config I440FX
> select PIIX
> select DIMM
> select SMBIOS
> + select SMBIOS_LEGACY
> select FW_CFG_DMA
>
> config ISAPC
> diff --git a/hw/smbios/Kconfig b/hw/smbios/Kconfig
> index 553adf4bfc..8d989a2f1b 100644
> --- a/hw/smbios/Kconfig
> +++ b/hw/smbios/Kconfig
> @@ -1,2 +1,4 @@
> config SMBIOS
> bool
> +config SMBIOS_LEGACY
> + bool
> diff --git a/hw/smbios/meson.build b/hw/smbios/meson.build
> index 7046967462..a59039f669 100644
> --- a/hw/smbios/meson.build
> +++ b/hw/smbios/meson.build
> @@ -4,5 +4,9 @@ smbios_ss.add(when: 'CONFIG_IPMI',
> if_true: files('smbios_type_38.c'),
> if_false: files('smbios_type_38-stub.c'))
>
> +smbios_ss.add(when: 'CONFIG_SMBIOS_LEGACY',
> + if_true: files('smbios_legacy.c'),
> + if_false: files('smbios_legacy_stub.c'))
> +
> system_ss.add_all(when: 'CONFIG_SMBIOS', if_true: smbios_ss)
> system_ss.add(when: 'CONFIG_SMBIOS', if_false: files('smbios-stub.c'))
> diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c
> index 86cf66b5ce..fb1f05fcde 100644
> --- a/hw/smbios/smbios.c
> +++ b/hw/smbios/smbios.c
> @@ -31,38 +31,12 @@
> #include "hw/pci/pci_device.h"
> #include "smbios_build.h"
>
> -/* legacy structures and constants for <= 2.0 machines */
> -struct smbios_header {
> - uint16_t length;
> - uint8_t type;
> -} QEMU_PACKED;
> -
> -struct smbios_field {
> - struct smbios_header header;
> - uint8_t type;
> - uint16_t offset;
> - uint8_t data[];
> -} QEMU_PACKED;
> -
> -struct smbios_table {
> - struct smbios_header header;
> - uint8_t data[];
> -} QEMU_PACKED;
> -
> -#define SMBIOS_FIELD_ENTRY 0
> -#define SMBIOS_TABLE_ENTRY 1
> -
> -static uint8_t *smbios_entries;
> -static size_t smbios_entries_len;
> static bool smbios_uuid_encoded = true;
> -/* end: legacy structures & constants for <= 2.0 machines */
> -
> /*
> * SMBIOS tables provided by user with '-smbios file=<foo>' option
> */
> uint8_t *usr_blobs;
> size_t usr_blobs_len;
> -static GArray *usr_blobs_sizes;
> static unsigned usr_table_max;
> static unsigned usr_table_cnt;
>
> @@ -483,7 +457,7 @@ static void smbios_check_type4_count(uint32_t expected_t4_count)
> }
> }
>
> -static void smbios_validate_table(void)
> +void smbios_validate_table(void)
> {
> if (smbios_ep_type == SMBIOS_ENTRY_POINT_TYPE_32 &&
> smbios_tables_len > SMBIOS_21_MAX_TABLES_LEN) {
> @@ -493,134 +467,6 @@ static void smbios_validate_table(void)
> }
> }
>
> -
> -/* legacy setup functions for <= 2.0 machines */
> -static void smbios_add_field(int type, int offset, const void *data, size_t len)
> -{
> - struct smbios_field *field;
> -
> - if (!smbios_entries) {
> - smbios_entries_len = sizeof(uint16_t);
> - smbios_entries = g_malloc0(smbios_entries_len);
> - }
> - smbios_entries = g_realloc(smbios_entries, smbios_entries_len +
> - sizeof(*field) + len);
> - field = (struct smbios_field *)(smbios_entries + smbios_entries_len);
> - field->header.type = SMBIOS_FIELD_ENTRY;
> - field->header.length = cpu_to_le16(sizeof(*field) + len);
> -
> - field->type = type;
> - field->offset = cpu_to_le16(offset);
> - memcpy(field->data, data, len);
> -
> - smbios_entries_len += sizeof(*field) + len;
> - (*(uint16_t *)smbios_entries) =
> - cpu_to_le16(le16_to_cpu(*(uint16_t *)smbios_entries) + 1);
> -}
> -
> -static void smbios_maybe_add_str(int type, int offset, const char *data)
> -{
> - if (data) {
> - smbios_add_field(type, offset, data, strlen(data) + 1);
> - }
> -}
> -
> -static void smbios_build_type_0_fields(void)
> -{
> - smbios_maybe_add_str(0, offsetof(struct smbios_type_0, vendor_str),
> - smbios_type0.vendor);
> - smbios_maybe_add_str(0, offsetof(struct smbios_type_0, bios_version_str),
> - smbios_type0.version);
> - smbios_maybe_add_str(0, offsetof(struct smbios_type_0,
> - bios_release_date_str),
> - smbios_type0.date);
> - if (smbios_type0.have_major_minor) {
> - smbios_add_field(0, offsetof(struct smbios_type_0,
> - system_bios_major_release),
> - &smbios_type0.major, 1);
> - smbios_add_field(0, offsetof(struct smbios_type_0,
> - system_bios_minor_release),
> - &smbios_type0.minor, 1);
> - }
> -}
> -
> -static void smbios_build_type_1_fields(void)
> -{
> - smbios_maybe_add_str(1, offsetof(struct smbios_type_1, manufacturer_str),
> - smbios_type1.manufacturer);
> - smbios_maybe_add_str(1, offsetof(struct smbios_type_1, product_name_str),
> - smbios_type1.product);
> - smbios_maybe_add_str(1, offsetof(struct smbios_type_1, version_str),
> - smbios_type1.version);
> - smbios_maybe_add_str(1, offsetof(struct smbios_type_1, serial_number_str),
> - smbios_type1.serial);
> - smbios_maybe_add_str(1, offsetof(struct smbios_type_1, sku_number_str),
> - smbios_type1.sku);
> - smbios_maybe_add_str(1, offsetof(struct smbios_type_1, family_str),
> - smbios_type1.family);
> - if (qemu_uuid_set) {
> - /* We don't encode the UUID in the "wire format" here because this
> - * function is for legacy mode and needs to keep the guest ABI, and
> - * because we don't know what's the SMBIOS version advertised by the
> - * BIOS.
> - */
> - smbios_add_field(1, offsetof(struct smbios_type_1, uuid),
> - &qemu_uuid, 16);
> - }
> -}
> -
> -uint8_t *smbios_get_table_legacy(size_t *length)
> -{
> - int i;
> - size_t usr_offset;
> -
> - /* also complain if fields were given for types > 1 */
> - if (find_next_bit(smbios_have_fields_bitmap,
> - SMBIOS_MAX_TYPE + 1, 2) < SMBIOS_MAX_TYPE + 1) {
> - error_report("can't process fields for smbios "
> - "types > 1 on machine versions < 2.1!");
> - exit(1);
> - }
> -
> - if (test_bit(4, smbios_have_binfile_bitmap)) {
> - error_report("can't process table for smbios "
> - "type 4 on machine versions < 2.1!");
> - exit(1);
> - }
> -
> - g_free(smbios_entries);
> - smbios_entries_len = sizeof(uint16_t);
> - smbios_entries = g_malloc0(smbios_entries_len);
> -
> - for (i = 0, usr_offset = 0; usr_blobs_sizes && i < usr_blobs_sizes->len;
> - i++)
> - {
> - struct smbios_table *table;
> - struct smbios_structure_header *header;
> - size_t size = g_array_index(usr_blobs_sizes, size_t, i);
> -
> - header = (struct smbios_structure_header *)(usr_blobs + usr_offset);
> - smbios_entries = g_realloc(smbios_entries, smbios_entries_len +
> - size + sizeof(*table));
> - table = (struct smbios_table *)(smbios_entries + smbios_entries_len);
> - table->header.type = SMBIOS_TABLE_ENTRY;
> - table->header.length = cpu_to_le16(sizeof(*table) + size);
> - memcpy(table->data, header, size);
> - smbios_entries_len += sizeof(*table) + size;
> - (*(uint16_t *)smbios_entries) =
> - cpu_to_le16(le16_to_cpu(*(uint16_t *)smbios_entries) + 1);
> - usr_offset += size;
> - }
> -
> - smbios_build_type_0_fields();
> - smbios_build_type_1_fields();
> - smbios_validate_table();
> - *length = smbios_entries_len;
> - return smbios_entries;
> -}
> -/* end: legacy setup functions for <= 2.0 machines */
> -
> -
> bool smbios_skip_table(uint8_t type, bool required_table)
> {
> if (test_bit(type, smbios_have_binfile_bitmap)) {
> @@ -1279,14 +1125,6 @@ static bool save_opt_list(size_t *ndest, char ***dest, QemuOpts *opts,
> return true;
> }
>
> -static void smbios_add_usr_blob_size(size_t size)
> -{
> - if (!usr_blobs_sizes) {
> - usr_blobs_sizes = g_array_new(false, false, sizeof(size_t));
> - }
> - g_array_append_val(usr_blobs_sizes, size);
> -}
> -
> void smbios_entry_add(QemuOpts *opts, Error **errp)
> {
> const char *val;
> diff --git a/hw/smbios/smbios_legacy.c b/hw/smbios/smbios_legacy.c
> new file mode 100644
> index 0000000000..21f143e738
> --- /dev/null
> +++ b/hw/smbios/smbios_legacy.c
> @@ -0,0 +1,179 @@
> +/*
> + * SMBIOS legacy support
> + *
> + * Copyright (C) 2009 Hewlett-Packard Development Company, L.P.
> + * Copyright (C) 2013 Red Hat, Inc.
> + *
> + * Authors:
> + * Alex Williamson <alex.williamson@hp.com>
> + * Markus Armbruster <armbru@redhat.com>
> + *
> + * This work is licensed under the terms of the GNU GPL, version 2. See
> + * the COPYING file in the top-level directory.
> + *
> + * Contributions after 2012-01-13 are licensed under the terms of the
> + * GNU GPL, version 2 or (at your option) any later version.
> + */
> +
> +#include "qemu/osdep.h"
> +#include "qemu/bswap.h"
> +#include "hw/firmware/smbios.h"
> +#include "sysemu/sysemu.h"
> +#include "qemu/error-report.h"
> +
> +struct smbios_header {
> + uint16_t length;
> + uint8_t type;
> +} QEMU_PACKED;
> +
> +struct smbios_field {
> + struct smbios_header header;
> + uint8_t type;
> + uint16_t offset;
> + uint8_t data[];
> +} QEMU_PACKED;
> +
> +struct smbios_table {
> + struct smbios_header header;
> + uint8_t data[];
> +} QEMU_PACKED;
> +
> +#define SMBIOS_FIELD_ENTRY 0
> +#define SMBIOS_TABLE_ENTRY 1
> +
> +static uint8_t *smbios_entries;
> +static size_t smbios_entries_len;
> +GArray *usr_blobs_sizes;
> +
> +void smbios_add_usr_blob_size(size_t size)
> +{
> + if (!usr_blobs_sizes) {
> + usr_blobs_sizes = g_array_new(false, false, sizeof(size_t));
> + }
> + g_array_append_val(usr_blobs_sizes, size);
> +}
> +
> +static void smbios_add_field(int type, int offset, const void *data, size_t len)
> +{
> + struct smbios_field *field;
> +
> + if (!smbios_entries) {
> + smbios_entries_len = sizeof(uint16_t);
> + smbios_entries = g_malloc0(smbios_entries_len);
> + }
> + smbios_entries = g_realloc(smbios_entries, smbios_entries_len +
> + sizeof(*field) + len);
> + field = (struct smbios_field *)(smbios_entries + smbios_entries_len);
> + field->header.type = SMBIOS_FIELD_ENTRY;
> + field->header.length = cpu_to_le16(sizeof(*field) + len);
> +
> + field->type = type;
> + field->offset = cpu_to_le16(offset);
> + memcpy(field->data, data, len);
> +
> + smbios_entries_len += sizeof(*field) + len;
> + (*(uint16_t *)smbios_entries) =
> + cpu_to_le16(le16_to_cpu(*(uint16_t *)smbios_entries) + 1);
> +}
> +
> +static void smbios_maybe_add_str(int type, int offset, const char *data)
> +{
> + if (data) {
> + smbios_add_field(type, offset, data, strlen(data) + 1);
> + }
> +}
> +
> +static void smbios_build_type_0_fields(void)
> +{
> + smbios_maybe_add_str(0, offsetof(struct smbios_type_0, vendor_str),
> + smbios_type0.vendor);
> + smbios_maybe_add_str(0, offsetof(struct smbios_type_0, bios_version_str),
> + smbios_type0.version);
> + smbios_maybe_add_str(0, offsetof(struct smbios_type_0,
> + bios_release_date_str),
> + smbios_type0.date);
> + if (smbios_type0.have_major_minor) {
> + smbios_add_field(0, offsetof(struct smbios_type_0,
> + system_bios_major_release),
> + &smbios_type0.major, 1);
> + smbios_add_field(0, offsetof(struct smbios_type_0,
> + system_bios_minor_release),
> + &smbios_type0.minor, 1);
> + }
> +}
> +
> +static void smbios_build_type_1_fields(void)
> +{
> + smbios_maybe_add_str(1, offsetof(struct smbios_type_1, manufacturer_str),
> + smbios_type1.manufacturer);
> + smbios_maybe_add_str(1, offsetof(struct smbios_type_1, product_name_str),
> + smbios_type1.product);
> + smbios_maybe_add_str(1, offsetof(struct smbios_type_1, version_str),
> + smbios_type1.version);
> + smbios_maybe_add_str(1, offsetof(struct smbios_type_1, serial_number_str),
> + smbios_type1.serial);
> + smbios_maybe_add_str(1, offsetof(struct smbios_type_1, sku_number_str),
> + smbios_type1.sku);
> + smbios_maybe_add_str(1, offsetof(struct smbios_type_1, family_str),
> + smbios_type1.family);
> + if (qemu_uuid_set) {
> + /*
> + * We don't encode the UUID in the "wire format" here because this
> + * function is for legacy mode and needs to keep the guest ABI, and
> + * because we don't know what's the SMBIOS version advertised by the
> + * BIOS.
> + */
> + smbios_add_field(1, offsetof(struct smbios_type_1, uuid),
> + &qemu_uuid, 16);
> + }
> +}
> +
> +uint8_t *smbios_get_table_legacy(size_t *length)
> +{
> + int i;
> + size_t usr_offset;
> +
> + /* complain if fields were given for types > 1 */
> + if (find_next_bit(smbios_have_fields_bitmap,
> + SMBIOS_MAX_TYPE + 1, 2) < SMBIOS_MAX_TYPE + 1) {
> + error_report("can't process fields for smbios "
> + "types > 1 on machine versions < 2.1!");
> + exit(1);
> + }
> +
> + if (test_bit(4, smbios_have_binfile_bitmap)) {
> + error_report("can't process table for smbios "
> + "type 4 on machine versions < 2.1!");
> + exit(1);
> + }
> +
> + g_free(smbios_entries);
> + smbios_entries_len = sizeof(uint16_t);
> + smbios_entries = g_malloc0(smbios_entries_len);
> +
> + for (i = 0, usr_offset = 0; usr_blobs_sizes && i < usr_blobs_sizes->len;
> + i++)
> + {
> + struct smbios_table *table;
> + struct smbios_structure_header *header;
> + size_t size = g_array_index(usr_blobs_sizes, size_t, i);
> +
> + header = (struct smbios_structure_header *)(usr_blobs + usr_offset);
> + smbios_entries = g_realloc(smbios_entries, smbios_entries_len +
> + size + sizeof(*table));
> + table = (struct smbios_table *)(smbios_entries + smbios_entries_len);
> + table->header.type = SMBIOS_TABLE_ENTRY;
> + table->header.length = cpu_to_le16(sizeof(*table) + size);
> + memcpy(table->data, header, size);
> + smbios_entries_len += sizeof(*table) + size;
> + (*(uint16_t *)smbios_entries) =
> + cpu_to_le16(le16_to_cpu(*(uint16_t *)smbios_entries) + 1);
> + usr_offset += size;
> + }
> +
> + smbios_build_type_0_fields();
> + smbios_build_type_1_fields();
> + smbios_validate_table();
> + *length = smbios_entries_len;
> + return smbios_entries;
> +}
> diff --git a/hw/smbios/smbios_legacy_stub.c b/hw/smbios/smbios_legacy_stub.c
> new file mode 100644
> index 0000000000..91e6c75029
> --- /dev/null
> +++ b/hw/smbios/smbios_legacy_stub.c
> @@ -0,0 +1,16 @@
> +/*
> + * IPMI SMBIOS firmware handling
> + *
> + * Copyright (c) 2024 Igor Mammedov, Red Hat, Inc.
> + *
> + * This work is licensed under the terms of the GNU GPL, version 2 or later.
> + * See the COPYING file in the top-level directory.
> + */
> +
> +#include "qemu/osdep.h"
> +#include "hw/firmware/smbios.h"
> +
> +void smbios_add_usr_blob_size(size_t size)
> +{
> +}
> +
> --
> 2.39.3
>
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: [PATCH v2 17/20] smbios: clear smbios_type4_count before building tables
2024-03-05 15:57 ` [PATCH v2 17/20] smbios: clear smbios_type4_count before building tables Igor Mammedov
@ 2024-03-06 7:47 ` Ani Sinha
2024-03-06 9:58 ` Igor Mammedov
0 siblings, 1 reply; 37+ messages in thread
From: Ani Sinha @ 2024-03-06 7:47 UTC (permalink / raw)
To: Igor Mammedov
Cc: QEMU Developers, Peter Maydell, Paolo Bonzini, Michael S. Tsirkin,
Song Gao, Alistair Francis, palmer, bin.meng, liwei1518, dbarboza,
zhiwei_liu, philmd, wangyanan55, eblake, armbru, qemu-arm,
qemu-riscv, f.ebner
> On 05-Mar-2024, at 21:27, Igor Mammedov <imammedo@redhat.com> wrote:
>
> it will help to keep type 4 tables accounting correct in case
> SMBIOS tables are built multiple times.
I suggest you arrange this before patch 15 where you are actually calling smbios_get_tables_ep() multiple times. That way there is no window where things can break between patches.
>
> Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> Tested-by: Fiona Ebner <f.ebner@proxmox.com>
> ---
> hw/smbios/smbios.c | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c
> index bf5c7a8885..b64d3bc227 100644
> --- a/hw/smbios/smbios.c
> +++ b/hw/smbios/smbios.c
> @@ -981,6 +981,7 @@ static bool smbios_get_tables_ep(MachineState *ms,
> ep_type == SMBIOS_ENTRY_POINT_TYPE_64);
>
> g_free(smbios_tables);
> + smbios_type4_count = 0;
Nit: Can you put this before g_free() because gfree(smbios_tables) and smbios_tables = memdup2() etc are related. This is kind of coming in between.
> smbios_tables = g_memdup2(usr_blobs, usr_blobs_len);
> smbios_tables_len = usr_blobs_len;
> smbios_table_max = usr_table_max;
> --
> 2.39.3
>
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: [PATCH v2 18/20] tests: acpi/smbios: whitelist expected blobs
2024-03-05 15:57 ` [PATCH v2 18/20] tests: acpi/smbios: whitelist expected blobs Igor Mammedov
@ 2024-03-06 8:31 ` Ani Sinha
0 siblings, 0 replies; 37+ messages in thread
From: Ani Sinha @ 2024-03-06 8:31 UTC (permalink / raw)
To: Igor Mammedov
Cc: QEMU Developers, Peter Maydell, Paolo Bonzini, Michael S. Tsirkin,
Song Gao, Alistair Francis, palmer, bin.meng, liwei1518, dbarboza,
zhiwei_liu, Philippe Mathieu-Daudé, Yanan Wang, Eric Blake,
Markus Armbruster, qemu-arm, qemu-riscv, f.ebner
> On 05-Mar-2024, at 21:27, Igor Mammedov <imammedo@redhat.com> wrote:
>
> Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Acked-by: Ani Sinha <anisinha@redhat.com>
> ---
> tests/qtest/bios-tables-test-allowed-diff.h | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h
> index dfb8523c8b..81148a604f 100644
> --- a/tests/qtest/bios-tables-test-allowed-diff.h
> +++ b/tests/qtest/bios-tables-test-allowed-diff.h
> @@ -1 +1,2 @@
> /* List of comma-separated changed AML files to ignore */
> +"tests/data/acpi/q35/SSDT.dimmpxm",
> --
> 2.39.3
>
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: [PATCH v2 20/20] tests: acpi: update expected SSDT.dimmpxm blob
2024-03-05 15:57 ` [PATCH v2 20/20] tests: acpi: update expected SSDT.dimmpxm blob Igor Mammedov
@ 2024-03-06 9:20 ` Ani Sinha
2024-03-06 10:01 ` Igor Mammedov
0 siblings, 1 reply; 37+ messages in thread
From: Ani Sinha @ 2024-03-06 9:20 UTC (permalink / raw)
To: Igor Mammedov
Cc: QEMU Developers, Peter Maydell, Paolo Bonzini, Michael S. Tsirkin,
Song Gao, Alistair Francis, palmer, bin.meng, liwei1518, dbarboza,
zhiwei_liu, philmd, wangyanan55, eblake, armbru, qemu-arm,
qemu-riscv, f.ebner
> On 05-Mar-2024, at 21:27, Igor Mammedov <imammedo@redhat.com> wrote:
>
> address shift is caused by switch to 32-bit SMBIOS entry point
> which has slightly different size from 64-bit one and happens
> to trigger a bit different memory layout.
Why does it affect only q35 machines and not i440fx as well?
>
> Expected diff:
>
> - Name (MEMA, 0x07FFE000)
> + Name (MEMA, 0x07FFF000)
>
> Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Acked-by: Ani Sinha <anisinha@redhat.com>
> ---
> tests/qtest/bios-tables-test-allowed-diff.h | 1 -
> tests/data/acpi/q35/SSDT.dimmpxm | Bin 1815 -> 1815 bytes
> 2 files changed, 1 deletion(-)
>
> diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h
> index 81148a604f..dfb8523c8b 100644
> --- a/tests/qtest/bios-tables-test-allowed-diff.h
> +++ b/tests/qtest/bios-tables-test-allowed-diff.h
> @@ -1,2 +1 @@
> /* List of comma-separated changed AML files to ignore */
> -"tests/data/acpi/q35/SSDT.dimmpxm",
> diff --git a/tests/data/acpi/q35/SSDT.dimmpxm b/tests/data/acpi/q35/SSDT.dimmpxm
> index 70f133412f5e0aa128ab210245a8de7304eeb843..9ea4e0d0ceaa8a5cbd706afb6d49de853fafe654 100644
> GIT binary patch
> delta 23
> ecmbQvH=U0wIM^jboSlJzam_|9E_UV*|JeaVTLvQl
>
> delta 23
> ecmbQvH=U0wIM^jboSlJzanD9BE_UVz|JeaVy9Ofw
>
> --
> 2.39.3
>
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: [PATCH v2 17/20] smbios: clear smbios_type4_count before building tables
2024-03-06 7:47 ` Ani Sinha
@ 2024-03-06 9:58 ` Igor Mammedov
0 siblings, 0 replies; 37+ messages in thread
From: Igor Mammedov @ 2024-03-06 9:58 UTC (permalink / raw)
To: Ani Sinha
Cc: QEMU Developers, Peter Maydell, Paolo Bonzini, Michael S. Tsirkin,
Song Gao, Alistair Francis, palmer, bin.meng, liwei1518, dbarboza,
zhiwei_liu, philmd, wangyanan55, eblake, armbru, qemu-arm,
qemu-riscv, f.ebner
On Wed, 6 Mar 2024 13:17:39 +0530
Ani Sinha <anisinha@redhat.com> wrote:
> > On 05-Mar-2024, at 21:27, Igor Mammedov <imammedo@redhat.com> wrote:
> >
> > it will help to keep type 4 tables accounting correct in case
> > SMBIOS tables are built multiple times.
>
>
> I suggest you arrange this before patch 15 where you are actually calling smbios_get_tables_ep() multiple times. That way there is no window where things can break between patches.
it doesn't break in patch by patch test, because auto is not in use yet.
It could be moved but, I'd rather not respin series for the sake of reordering.
Michael can you reorder it before 15/20 when applying?
> > Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> > Tested-by: Fiona Ebner <f.ebner@proxmox.com>
> > ---
> > hw/smbios/smbios.c | 1 +
> > 1 file changed, 1 insertion(+)
> >
> > diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c
> > index bf5c7a8885..b64d3bc227 100644
> > --- a/hw/smbios/smbios.c
> > +++ b/hw/smbios/smbios.c
> > @@ -981,6 +981,7 @@ static bool smbios_get_tables_ep(MachineState *ms,
> > ep_type == SMBIOS_ENTRY_POINT_TYPE_64);
> >
> > g_free(smbios_tables);
> > + smbios_type4_count = 0;
>
> Nit: Can you put this before g_free() because gfree(smbios_tables) and smbios_tables = memdup2() etc are related. This is kind of coming in between.
cleanup is not related to memdup, the later works fine without cleanup.
I'd prefer to keep it as is.
>
> > smbios_tables = g_memdup2(usr_blobs, usr_blobs_len);
> > smbios_tables_len = usr_blobs_len;
> > smbios_table_max = usr_table_max;
> > --
> > 2.39.3
> >
>
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: [PATCH v2 20/20] tests: acpi: update expected SSDT.dimmpxm blob
2024-03-06 9:20 ` Ani Sinha
@ 2024-03-06 10:01 ` Igor Mammedov
0 siblings, 0 replies; 37+ messages in thread
From: Igor Mammedov @ 2024-03-06 10:01 UTC (permalink / raw)
To: Ani Sinha
Cc: QEMU Developers, Peter Maydell, Paolo Bonzini, Michael S. Tsirkin,
Song Gao, Alistair Francis, palmer, bin.meng, liwei1518, dbarboza,
zhiwei_liu, philmd, wangyanan55, eblake, armbru, qemu-arm,
qemu-riscv, f.ebner
On Wed, 6 Mar 2024 14:50:20 +0530
Ani Sinha <anisinha@redhat.com> wrote:
> > On 05-Mar-2024, at 21:27, Igor Mammedov <imammedo@redhat.com> wrote:
> >
> > address shift is caused by switch to 32-bit SMBIOS entry point
> > which has slightly different size from 64-bit one and happens
> > to trigger a bit different memory layout.
>
> Why does it affect only q35 machines and not i440fx as well?
that what tests show, mem layout is a bit different between those
>
> >
> > Expected diff:
> >
> > - Name (MEMA, 0x07FFE000)
> > + Name (MEMA, 0x07FFF000)
> >
> > Signed-off-by: Igor Mammedov <imammedo@redhat.com>
>
> Acked-by: Ani Sinha <anisinha@redhat.com>
>
> > ---
> > tests/qtest/bios-tables-test-allowed-diff.h | 1 -
> > tests/data/acpi/q35/SSDT.dimmpxm | Bin 1815 -> 1815 bytes
> > 2 files changed, 1 deletion(-)
> >
> > diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h
> > index 81148a604f..dfb8523c8b 100644
> > --- a/tests/qtest/bios-tables-test-allowed-diff.h
> > +++ b/tests/qtest/bios-tables-test-allowed-diff.h
> > @@ -1,2 +1 @@
> > /* List of comma-separated changed AML files to ignore */
> > -"tests/data/acpi/q35/SSDT.dimmpxm",
> > diff --git a/tests/data/acpi/q35/SSDT.dimmpxm b/tests/data/acpi/q35/SSDT.dimmpxm
> > index 70f133412f5e0aa128ab210245a8de7304eeb843..9ea4e0d0ceaa8a5cbd706afb6d49de853fafe654 100644
> > GIT binary patch
> > delta 23
> > ecmbQvH=U0wIM^jboSlJzam_|9E_UV*|JeaVTLvQl
> >
> > delta 23
> > ecmbQvH=U0wIM^jboSlJzanD9BE_UVz|JeaVy9Ofw
> >
> > --
> > 2.39.3
> >
>
^ permalink raw reply [flat|nested] 37+ messages in thread
* [PATCH v3 11/20] smbios: build legacy mode code only for 'pc' machine
2024-03-05 15:57 ` [PATCH v2 11/20] smbios: build legacy mode code only for 'pc' machine Igor Mammedov
2024-03-06 7:27 ` Ani Sinha
@ 2024-03-06 10:03 ` Igor Mammedov
1 sibling, 0 replies; 37+ messages in thread
From: Igor Mammedov @ 2024-03-06 10:03 UTC (permalink / raw)
To: qemu-devel; +Cc: mst, anisinha
basically moving code around without functional change.
And exposing some symbols so that they could be shared
between smbbios.c and new smbios_legacy.c
plus some meson magic to build smbios_legacy.c only
for 'pc' machine and otherwise replace it with stub
if not selected.
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Ani Sinha <anisinha@redhat.com>
---
v2:
moved type0/type1/have_binfile_bitmap/have_fields_bitmap rename into
a separate patch
v3:
drop blank space at the end of hw/smbios/smbios_legacy_stub.c
---
include/hw/firmware/smbios.h | 5 +
hw/i386/Kconfig | 1 +
hw/smbios/Kconfig | 2 +
hw/smbios/meson.build | 4 +
hw/smbios/smbios.c | 164 +-----------------------------
hw/smbios/smbios_legacy.c | 179 +++++++++++++++++++++++++++++++++
hw/smbios/smbios_legacy_stub.c | 15 +++
7 files changed, 207 insertions(+), 163 deletions(-)
create mode 100644 hw/smbios/smbios_legacy.c
create mode 100644 hw/smbios/smbios_legacy_stub.c
diff --git a/include/hw/firmware/smbios.h b/include/hw/firmware/smbios.h
index bea5c3f1b1..7f47475aa4 100644
--- a/include/hw/firmware/smbios.h
+++ b/include/hw/firmware/smbios.h
@@ -17,6 +17,9 @@
*
*/
+extern uint8_t *usr_blobs;
+extern GArray *usr_blobs_sizes;
+
typedef struct {
const char *vendor, *version, *date;
bool have_major_minor, uefi;
@@ -306,6 +309,8 @@ struct smbios_type_127 {
struct smbios_structure_header header;
} QEMU_PACKED;
+void smbios_validate_table(void);
+void smbios_add_usr_blob_size(size_t size);
void smbios_entry_add(QemuOpts *opts, Error **errp);
void smbios_set_cpuid(uint32_t version, uint32_t features);
void smbios_set_defaults(const char *manufacturer, const char *product,
diff --git a/hw/i386/Kconfig b/hw/i386/Kconfig
index a1846be6f7..a6ee052f9a 100644
--- a/hw/i386/Kconfig
+++ b/hw/i386/Kconfig
@@ -76,6 +76,7 @@ config I440FX
select PIIX
select DIMM
select SMBIOS
+ select SMBIOS_LEGACY
select FW_CFG_DMA
config ISAPC
diff --git a/hw/smbios/Kconfig b/hw/smbios/Kconfig
index 553adf4bfc..8d989a2f1b 100644
--- a/hw/smbios/Kconfig
+++ b/hw/smbios/Kconfig
@@ -1,2 +1,4 @@
config SMBIOS
bool
+config SMBIOS_LEGACY
+ bool
diff --git a/hw/smbios/meson.build b/hw/smbios/meson.build
index 7046967462..a59039f669 100644
--- a/hw/smbios/meson.build
+++ b/hw/smbios/meson.build
@@ -4,5 +4,9 @@ smbios_ss.add(when: 'CONFIG_IPMI',
if_true: files('smbios_type_38.c'),
if_false: files('smbios_type_38-stub.c'))
+smbios_ss.add(when: 'CONFIG_SMBIOS_LEGACY',
+ if_true: files('smbios_legacy.c'),
+ if_false: files('smbios_legacy_stub.c'))
+
system_ss.add_all(when: 'CONFIG_SMBIOS', if_true: smbios_ss)
system_ss.add(when: 'CONFIG_SMBIOS', if_false: files('smbios-stub.c'))
diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c
index 86cf66b5ce..fb1f05fcde 100644
--- a/hw/smbios/smbios.c
+++ b/hw/smbios/smbios.c
@@ -31,38 +31,12 @@
#include "hw/pci/pci_device.h"
#include "smbios_build.h"
-/* legacy structures and constants for <= 2.0 machines */
-struct smbios_header {
- uint16_t length;
- uint8_t type;
-} QEMU_PACKED;
-
-struct smbios_field {
- struct smbios_header header;
- uint8_t type;
- uint16_t offset;
- uint8_t data[];
-} QEMU_PACKED;
-
-struct smbios_table {
- struct smbios_header header;
- uint8_t data[];
-} QEMU_PACKED;
-
-#define SMBIOS_FIELD_ENTRY 0
-#define SMBIOS_TABLE_ENTRY 1
-
-static uint8_t *smbios_entries;
-static size_t smbios_entries_len;
static bool smbios_uuid_encoded = true;
-/* end: legacy structures & constants for <= 2.0 machines */
-
/*
* SMBIOS tables provided by user with '-smbios file=<foo>' option
*/
uint8_t *usr_blobs;
size_t usr_blobs_len;
-static GArray *usr_blobs_sizes;
static unsigned usr_table_max;
static unsigned usr_table_cnt;
@@ -483,7 +457,7 @@ static void smbios_check_type4_count(uint32_t expected_t4_count)
}
}
-static void smbios_validate_table(void)
+void smbios_validate_table(void)
{
if (smbios_ep_type == SMBIOS_ENTRY_POINT_TYPE_32 &&
smbios_tables_len > SMBIOS_21_MAX_TABLES_LEN) {
@@ -493,134 +467,6 @@ static void smbios_validate_table(void)
}
}
-
-/* legacy setup functions for <= 2.0 machines */
-static void smbios_add_field(int type, int offset, const void *data, size_t len)
-{
- struct smbios_field *field;
-
- if (!smbios_entries) {
- smbios_entries_len = sizeof(uint16_t);
- smbios_entries = g_malloc0(smbios_entries_len);
- }
- smbios_entries = g_realloc(smbios_entries, smbios_entries_len +
- sizeof(*field) + len);
- field = (struct smbios_field *)(smbios_entries + smbios_entries_len);
- field->header.type = SMBIOS_FIELD_ENTRY;
- field->header.length = cpu_to_le16(sizeof(*field) + len);
-
- field->type = type;
- field->offset = cpu_to_le16(offset);
- memcpy(field->data, data, len);
-
- smbios_entries_len += sizeof(*field) + len;
- (*(uint16_t *)smbios_entries) =
- cpu_to_le16(le16_to_cpu(*(uint16_t *)smbios_entries) + 1);
-}
-
-static void smbios_maybe_add_str(int type, int offset, const char *data)
-{
- if (data) {
- smbios_add_field(type, offset, data, strlen(data) + 1);
- }
-}
-
-static void smbios_build_type_0_fields(void)
-{
- smbios_maybe_add_str(0, offsetof(struct smbios_type_0, vendor_str),
- smbios_type0.vendor);
- smbios_maybe_add_str(0, offsetof(struct smbios_type_0, bios_version_str),
- smbios_type0.version);
- smbios_maybe_add_str(0, offsetof(struct smbios_type_0,
- bios_release_date_str),
- smbios_type0.date);
- if (smbios_type0.have_major_minor) {
- smbios_add_field(0, offsetof(struct smbios_type_0,
- system_bios_major_release),
- &smbios_type0.major, 1);
- smbios_add_field(0, offsetof(struct smbios_type_0,
- system_bios_minor_release),
- &smbios_type0.minor, 1);
- }
-}
-
-static void smbios_build_type_1_fields(void)
-{
- smbios_maybe_add_str(1, offsetof(struct smbios_type_1, manufacturer_str),
- smbios_type1.manufacturer);
- smbios_maybe_add_str(1, offsetof(struct smbios_type_1, product_name_str),
- smbios_type1.product);
- smbios_maybe_add_str(1, offsetof(struct smbios_type_1, version_str),
- smbios_type1.version);
- smbios_maybe_add_str(1, offsetof(struct smbios_type_1, serial_number_str),
- smbios_type1.serial);
- smbios_maybe_add_str(1, offsetof(struct smbios_type_1, sku_number_str),
- smbios_type1.sku);
- smbios_maybe_add_str(1, offsetof(struct smbios_type_1, family_str),
- smbios_type1.family);
- if (qemu_uuid_set) {
- /* We don't encode the UUID in the "wire format" here because this
- * function is for legacy mode and needs to keep the guest ABI, and
- * because we don't know what's the SMBIOS version advertised by the
- * BIOS.
- */
- smbios_add_field(1, offsetof(struct smbios_type_1, uuid),
- &qemu_uuid, 16);
- }
-}
-
-uint8_t *smbios_get_table_legacy(size_t *length)
-{
- int i;
- size_t usr_offset;
-
- /* also complain if fields were given for types > 1 */
- if (find_next_bit(smbios_have_fields_bitmap,
- SMBIOS_MAX_TYPE + 1, 2) < SMBIOS_MAX_TYPE + 1) {
- error_report("can't process fields for smbios "
- "types > 1 on machine versions < 2.1!");
- exit(1);
- }
-
- if (test_bit(4, smbios_have_binfile_bitmap)) {
- error_report("can't process table for smbios "
- "type 4 on machine versions < 2.1!");
- exit(1);
- }
-
- g_free(smbios_entries);
- smbios_entries_len = sizeof(uint16_t);
- smbios_entries = g_malloc0(smbios_entries_len);
-
- for (i = 0, usr_offset = 0; usr_blobs_sizes && i < usr_blobs_sizes->len;
- i++)
- {
- struct smbios_table *table;
- struct smbios_structure_header *header;
- size_t size = g_array_index(usr_blobs_sizes, size_t, i);
-
- header = (struct smbios_structure_header *)(usr_blobs + usr_offset);
- smbios_entries = g_realloc(smbios_entries, smbios_entries_len +
- size + sizeof(*table));
- table = (struct smbios_table *)(smbios_entries + smbios_entries_len);
- table->header.type = SMBIOS_TABLE_ENTRY;
- table->header.length = cpu_to_le16(sizeof(*table) + size);
- memcpy(table->data, header, size);
- smbios_entries_len += sizeof(*table) + size;
- (*(uint16_t *)smbios_entries) =
- cpu_to_le16(le16_to_cpu(*(uint16_t *)smbios_entries) + 1);
- usr_offset += size;
- }
-
- smbios_build_type_0_fields();
- smbios_build_type_1_fields();
- smbios_validate_table();
- *length = smbios_entries_len;
- return smbios_entries;
-}
-/* end: legacy setup functions for <= 2.0 machines */
-
-
bool smbios_skip_table(uint8_t type, bool required_table)
{
if (test_bit(type, smbios_have_binfile_bitmap)) {
@@ -1279,14 +1125,6 @@ static bool save_opt_list(size_t *ndest, char ***dest, QemuOpts *opts,
return true;
}
-static void smbios_add_usr_blob_size(size_t size)
-{
- if (!usr_blobs_sizes) {
- usr_blobs_sizes = g_array_new(false, false, sizeof(size_t));
- }
- g_array_append_val(usr_blobs_sizes, size);
-}
-
void smbios_entry_add(QemuOpts *opts, Error **errp)
{
const char *val;
diff --git a/hw/smbios/smbios_legacy.c b/hw/smbios/smbios_legacy.c
new file mode 100644
index 0000000000..21f143e738
--- /dev/null
+++ b/hw/smbios/smbios_legacy.c
@@ -0,0 +1,179 @@
+/*
+ * SMBIOS legacy support
+ *
+ * Copyright (C) 2009 Hewlett-Packard Development Company, L.P.
+ * Copyright (C) 2013 Red Hat, Inc.
+ *
+ * Authors:
+ * Alex Williamson <alex.williamson@hp.com>
+ * Markus Armbruster <armbru@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2. See
+ * the COPYING file in the top-level directory.
+ *
+ * Contributions after 2012-01-13 are licensed under the terms of the
+ * GNU GPL, version 2 or (at your option) any later version.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/bswap.h"
+#include "hw/firmware/smbios.h"
+#include "sysemu/sysemu.h"
+#include "qemu/error-report.h"
+
+struct smbios_header {
+ uint16_t length;
+ uint8_t type;
+} QEMU_PACKED;
+
+struct smbios_field {
+ struct smbios_header header;
+ uint8_t type;
+ uint16_t offset;
+ uint8_t data[];
+} QEMU_PACKED;
+
+struct smbios_table {
+ struct smbios_header header;
+ uint8_t data[];
+} QEMU_PACKED;
+
+#define SMBIOS_FIELD_ENTRY 0
+#define SMBIOS_TABLE_ENTRY 1
+
+static uint8_t *smbios_entries;
+static size_t smbios_entries_len;
+GArray *usr_blobs_sizes;
+
+void smbios_add_usr_blob_size(size_t size)
+{
+ if (!usr_blobs_sizes) {
+ usr_blobs_sizes = g_array_new(false, false, sizeof(size_t));
+ }
+ g_array_append_val(usr_blobs_sizes, size);
+}
+
+static void smbios_add_field(int type, int offset, const void *data, size_t len)
+{
+ struct smbios_field *field;
+
+ if (!smbios_entries) {
+ smbios_entries_len = sizeof(uint16_t);
+ smbios_entries = g_malloc0(smbios_entries_len);
+ }
+ smbios_entries = g_realloc(smbios_entries, smbios_entries_len +
+ sizeof(*field) + len);
+ field = (struct smbios_field *)(smbios_entries + smbios_entries_len);
+ field->header.type = SMBIOS_FIELD_ENTRY;
+ field->header.length = cpu_to_le16(sizeof(*field) + len);
+
+ field->type = type;
+ field->offset = cpu_to_le16(offset);
+ memcpy(field->data, data, len);
+
+ smbios_entries_len += sizeof(*field) + len;
+ (*(uint16_t *)smbios_entries) =
+ cpu_to_le16(le16_to_cpu(*(uint16_t *)smbios_entries) + 1);
+}
+
+static void smbios_maybe_add_str(int type, int offset, const char *data)
+{
+ if (data) {
+ smbios_add_field(type, offset, data, strlen(data) + 1);
+ }
+}
+
+static void smbios_build_type_0_fields(void)
+{
+ smbios_maybe_add_str(0, offsetof(struct smbios_type_0, vendor_str),
+ smbios_type0.vendor);
+ smbios_maybe_add_str(0, offsetof(struct smbios_type_0, bios_version_str),
+ smbios_type0.version);
+ smbios_maybe_add_str(0, offsetof(struct smbios_type_0,
+ bios_release_date_str),
+ smbios_type0.date);
+ if (smbios_type0.have_major_minor) {
+ smbios_add_field(0, offsetof(struct smbios_type_0,
+ system_bios_major_release),
+ &smbios_type0.major, 1);
+ smbios_add_field(0, offsetof(struct smbios_type_0,
+ system_bios_minor_release),
+ &smbios_type0.minor, 1);
+ }
+}
+
+static void smbios_build_type_1_fields(void)
+{
+ smbios_maybe_add_str(1, offsetof(struct smbios_type_1, manufacturer_str),
+ smbios_type1.manufacturer);
+ smbios_maybe_add_str(1, offsetof(struct smbios_type_1, product_name_str),
+ smbios_type1.product);
+ smbios_maybe_add_str(1, offsetof(struct smbios_type_1, version_str),
+ smbios_type1.version);
+ smbios_maybe_add_str(1, offsetof(struct smbios_type_1, serial_number_str),
+ smbios_type1.serial);
+ smbios_maybe_add_str(1, offsetof(struct smbios_type_1, sku_number_str),
+ smbios_type1.sku);
+ smbios_maybe_add_str(1, offsetof(struct smbios_type_1, family_str),
+ smbios_type1.family);
+ if (qemu_uuid_set) {
+ /*
+ * We don't encode the UUID in the "wire format" here because this
+ * function is for legacy mode and needs to keep the guest ABI, and
+ * because we don't know what's the SMBIOS version advertised by the
+ * BIOS.
+ */
+ smbios_add_field(1, offsetof(struct smbios_type_1, uuid),
+ &qemu_uuid, 16);
+ }
+}
+
+uint8_t *smbios_get_table_legacy(size_t *length)
+{
+ int i;
+ size_t usr_offset;
+
+ /* complain if fields were given for types > 1 */
+ if (find_next_bit(smbios_have_fields_bitmap,
+ SMBIOS_MAX_TYPE + 1, 2) < SMBIOS_MAX_TYPE + 1) {
+ error_report("can't process fields for smbios "
+ "types > 1 on machine versions < 2.1!");
+ exit(1);
+ }
+
+ if (test_bit(4, smbios_have_binfile_bitmap)) {
+ error_report("can't process table for smbios "
+ "type 4 on machine versions < 2.1!");
+ exit(1);
+ }
+
+ g_free(smbios_entries);
+ smbios_entries_len = sizeof(uint16_t);
+ smbios_entries = g_malloc0(smbios_entries_len);
+
+ for (i = 0, usr_offset = 0; usr_blobs_sizes && i < usr_blobs_sizes->len;
+ i++)
+ {
+ struct smbios_table *table;
+ struct smbios_structure_header *header;
+ size_t size = g_array_index(usr_blobs_sizes, size_t, i);
+
+ header = (struct smbios_structure_header *)(usr_blobs + usr_offset);
+ smbios_entries = g_realloc(smbios_entries, smbios_entries_len +
+ size + sizeof(*table));
+ table = (struct smbios_table *)(smbios_entries + smbios_entries_len);
+ table->header.type = SMBIOS_TABLE_ENTRY;
+ table->header.length = cpu_to_le16(sizeof(*table) + size);
+ memcpy(table->data, header, size);
+ smbios_entries_len += sizeof(*table) + size;
+ (*(uint16_t *)smbios_entries) =
+ cpu_to_le16(le16_to_cpu(*(uint16_t *)smbios_entries) + 1);
+ usr_offset += size;
+ }
+
+ smbios_build_type_0_fields();
+ smbios_build_type_1_fields();
+ smbios_validate_table();
+ *length = smbios_entries_len;
+ return smbios_entries;
+}
diff --git a/hw/smbios/smbios_legacy_stub.c b/hw/smbios/smbios_legacy_stub.c
new file mode 100644
index 0000000000..f29b15316c
--- /dev/null
+++ b/hw/smbios/smbios_legacy_stub.c
@@ -0,0 +1,15 @@
+/*
+ * IPMI SMBIOS firmware handling
+ *
+ * Copyright (c) 2024 Igor Mammedov, Red Hat, Inc.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "hw/firmware/smbios.h"
+
+void smbios_add_usr_blob_size(size_t size)
+{
+}
--
2.39.3
^ permalink raw reply related [flat|nested] 37+ messages in thread
* Re: [PATCH v2 11/20] smbios: build legacy mode code only for 'pc' machine
2024-03-06 7:27 ` Ani Sinha
@ 2024-03-06 10:04 ` Igor Mammedov
0 siblings, 0 replies; 37+ messages in thread
From: Igor Mammedov @ 2024-03-06 10:04 UTC (permalink / raw)
To: Ani Sinha
Cc: QEMU Developers, Peter Maydell, Paolo Bonzini, Michael S. Tsirkin,
Song Gao, Alistair Francis, palmer, bin.meng, liwei1518, dbarboza,
zhiwei_liu, Philippe Mathieu-Daudé, Yanan Wang, Eric Blake,
Markus Armbruster, qemu-arm, qemu-riscv, f.ebner
On Wed, 6 Mar 2024 12:57:47 +0530
Ani Sinha <anisinha@redhat.com> wrote:
> > On 05-Mar-2024, at 21:27, Igor Mammedov <imammedo@redhat.com> wrote:
> >
> > basically moving code around without functional change.
> > And exposing some symbols so that they could be shared
> > between smbbios.c and new smbios_legacy.c
> >
> > plus some meson magic to build smbios_legacy.c only
> > for 'pc' machine and otherwise replace it with stub
> > if not selected.
>
> When I apply this, I get:
>
> Applying: smbios: build legacy mode code only for 'pc' machine
> .git/rebase-apply/patch:483: new blank line at EOF.
> +
> warning: 1 line adds whitespace errors.
it looks like checkpatch missed that, v3 is on the way as a reply to this
>
> Can you please look into this? Modulo that,
>
> >
> > Signed-off-by: Igor Mammedov <imammedo@redhat.com>
>
> Reviewed-by: Ani Sinha <anisinha@redhat.com>
>
> > ---
> > v2:
> > moved type0/type1/have_binfile_bitmap/have_fields_bitmap rename into
> > a separate patch
> > ---
> > include/hw/firmware/smbios.h | 5 +
> > hw/i386/Kconfig | 1 +
> > hw/smbios/Kconfig | 2 +
> > hw/smbios/meson.build | 4 +
> > hw/smbios/smbios.c | 164 +-----------------------------
> > hw/smbios/smbios_legacy.c | 179 +++++++++++++++++++++++++++++++++
> > hw/smbios/smbios_legacy_stub.c | 16 +++
> > 7 files changed, 208 insertions(+), 163 deletions(-)
> > create mode 100644 hw/smbios/smbios_legacy.c
> > create mode 100644 hw/smbios/smbios_legacy_stub.c
> >
> > diff --git a/include/hw/firmware/smbios.h b/include/hw/firmware/smbios.h
> > index bea5c3f1b1..7f47475aa4 100644
> > --- a/include/hw/firmware/smbios.h
> > +++ b/include/hw/firmware/smbios.h
> > @@ -17,6 +17,9 @@
> > *
> > */
> >
> > +extern uint8_t *usr_blobs;
> > +extern GArray *usr_blobs_sizes;
> > +
> > typedef struct {
> > const char *vendor, *version, *date;
> > bool have_major_minor, uefi;
> > @@ -306,6 +309,8 @@ struct smbios_type_127 {
> > struct smbios_structure_header header;
> > } QEMU_PACKED;
> >
> > +void smbios_validate_table(void);
> > +void smbios_add_usr_blob_size(size_t size);
> > void smbios_entry_add(QemuOpts *opts, Error **errp);
> > void smbios_set_cpuid(uint32_t version, uint32_t features);
> > void smbios_set_defaults(const char *manufacturer, const char *product,
> > diff --git a/hw/i386/Kconfig b/hw/i386/Kconfig
> > index a1846be6f7..a6ee052f9a 100644
> > --- a/hw/i386/Kconfig
> > +++ b/hw/i386/Kconfig
> > @@ -76,6 +76,7 @@ config I440FX
> > select PIIX
> > select DIMM
> > select SMBIOS
> > + select SMBIOS_LEGACY
> > select FW_CFG_DMA
> >
> > config ISAPC
> > diff --git a/hw/smbios/Kconfig b/hw/smbios/Kconfig
> > index 553adf4bfc..8d989a2f1b 100644
> > --- a/hw/smbios/Kconfig
> > +++ b/hw/smbios/Kconfig
> > @@ -1,2 +1,4 @@
> > config SMBIOS
> > bool
> > +config SMBIOS_LEGACY
> > + bool
> > diff --git a/hw/smbios/meson.build b/hw/smbios/meson.build
> > index 7046967462..a59039f669 100644
> > --- a/hw/smbios/meson.build
> > +++ b/hw/smbios/meson.build
> > @@ -4,5 +4,9 @@ smbios_ss.add(when: 'CONFIG_IPMI',
> > if_true: files('smbios_type_38.c'),
> > if_false: files('smbios_type_38-stub.c'))
> >
> > +smbios_ss.add(when: 'CONFIG_SMBIOS_LEGACY',
> > + if_true: files('smbios_legacy.c'),
> > + if_false: files('smbios_legacy_stub.c'))
> > +
> > system_ss.add_all(when: 'CONFIG_SMBIOS', if_true: smbios_ss)
> > system_ss.add(when: 'CONFIG_SMBIOS', if_false: files('smbios-stub.c'))
> > diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c
> > index 86cf66b5ce..fb1f05fcde 100644
> > --- a/hw/smbios/smbios.c
> > +++ b/hw/smbios/smbios.c
> > @@ -31,38 +31,12 @@
> > #include "hw/pci/pci_device.h"
> > #include "smbios_build.h"
> >
> > -/* legacy structures and constants for <= 2.0 machines */
> > -struct smbios_header {
> > - uint16_t length;
> > - uint8_t type;
> > -} QEMU_PACKED;
> > -
> > -struct smbios_field {
> > - struct smbios_header header;
> > - uint8_t type;
> > - uint16_t offset;
> > - uint8_t data[];
> > -} QEMU_PACKED;
> > -
> > -struct smbios_table {
> > - struct smbios_header header;
> > - uint8_t data[];
> > -} QEMU_PACKED;
> > -
> > -#define SMBIOS_FIELD_ENTRY 0
> > -#define SMBIOS_TABLE_ENTRY 1
> > -
> > -static uint8_t *smbios_entries;
> > -static size_t smbios_entries_len;
> > static bool smbios_uuid_encoded = true;
> > -/* end: legacy structures & constants for <= 2.0 machines */
> > -
> > /*
> > * SMBIOS tables provided by user with '-smbios file=<foo>' option
> > */
> > uint8_t *usr_blobs;
> > size_t usr_blobs_len;
> > -static GArray *usr_blobs_sizes;
> > static unsigned usr_table_max;
> > static unsigned usr_table_cnt;
> >
> > @@ -483,7 +457,7 @@ static void smbios_check_type4_count(uint32_t expected_t4_count)
> > }
> > }
> >
> > -static void smbios_validate_table(void)
> > +void smbios_validate_table(void)
> > {
> > if (smbios_ep_type == SMBIOS_ENTRY_POINT_TYPE_32 &&
> > smbios_tables_len > SMBIOS_21_MAX_TABLES_LEN) {
> > @@ -493,134 +467,6 @@ static void smbios_validate_table(void)
> > }
> > }
> >
> > -
> > -/* legacy setup functions for <= 2.0 machines */
> > -static void smbios_add_field(int type, int offset, const void *data, size_t len)
> > -{
> > - struct smbios_field *field;
> > -
> > - if (!smbios_entries) {
> > - smbios_entries_len = sizeof(uint16_t);
> > - smbios_entries = g_malloc0(smbios_entries_len);
> > - }
> > - smbios_entries = g_realloc(smbios_entries, smbios_entries_len +
> > - sizeof(*field) + len);
> > - field = (struct smbios_field *)(smbios_entries + smbios_entries_len);
> > - field->header.type = SMBIOS_FIELD_ENTRY;
> > - field->header.length = cpu_to_le16(sizeof(*field) + len);
> > -
> > - field->type = type;
> > - field->offset = cpu_to_le16(offset);
> > - memcpy(field->data, data, len);
> > -
> > - smbios_entries_len += sizeof(*field) + len;
> > - (*(uint16_t *)smbios_entries) =
> > - cpu_to_le16(le16_to_cpu(*(uint16_t *)smbios_entries) + 1);
> > -}
> > -
> > -static void smbios_maybe_add_str(int type, int offset, const char *data)
> > -{
> > - if (data) {
> > - smbios_add_field(type, offset, data, strlen(data) + 1);
> > - }
> > -}
> > -
> > -static void smbios_build_type_0_fields(void)
> > -{
> > - smbios_maybe_add_str(0, offsetof(struct smbios_type_0, vendor_str),
> > - smbios_type0.vendor);
> > - smbios_maybe_add_str(0, offsetof(struct smbios_type_0, bios_version_str),
> > - smbios_type0.version);
> > - smbios_maybe_add_str(0, offsetof(struct smbios_type_0,
> > - bios_release_date_str),
> > - smbios_type0.date);
> > - if (smbios_type0.have_major_minor) {
> > - smbios_add_field(0, offsetof(struct smbios_type_0,
> > - system_bios_major_release),
> > - &smbios_type0.major, 1);
> > - smbios_add_field(0, offsetof(struct smbios_type_0,
> > - system_bios_minor_release),
> > - &smbios_type0.minor, 1);
> > - }
> > -}
> > -
> > -static void smbios_build_type_1_fields(void)
> > -{
> > - smbios_maybe_add_str(1, offsetof(struct smbios_type_1, manufacturer_str),
> > - smbios_type1.manufacturer);
> > - smbios_maybe_add_str(1, offsetof(struct smbios_type_1, product_name_str),
> > - smbios_type1.product);
> > - smbios_maybe_add_str(1, offsetof(struct smbios_type_1, version_str),
> > - smbios_type1.version);
> > - smbios_maybe_add_str(1, offsetof(struct smbios_type_1, serial_number_str),
> > - smbios_type1.serial);
> > - smbios_maybe_add_str(1, offsetof(struct smbios_type_1, sku_number_str),
> > - smbios_type1.sku);
> > - smbios_maybe_add_str(1, offsetof(struct smbios_type_1, family_str),
> > - smbios_type1.family);
> > - if (qemu_uuid_set) {
> > - /* We don't encode the UUID in the "wire format" here because this
> > - * function is for legacy mode and needs to keep the guest ABI, and
> > - * because we don't know what's the SMBIOS version advertised by the
> > - * BIOS.
> > - */
> > - smbios_add_field(1, offsetof(struct smbios_type_1, uuid),
> > - &qemu_uuid, 16);
> > - }
> > -}
> > -
> > -uint8_t *smbios_get_table_legacy(size_t *length)
> > -{
> > - int i;
> > - size_t usr_offset;
> > -
> > - /* also complain if fields were given for types > 1 */
> > - if (find_next_bit(smbios_have_fields_bitmap,
> > - SMBIOS_MAX_TYPE + 1, 2) < SMBIOS_MAX_TYPE + 1) {
> > - error_report("can't process fields for smbios "
> > - "types > 1 on machine versions < 2.1!");
> > - exit(1);
> > - }
> > -
> > - if (test_bit(4, smbios_have_binfile_bitmap)) {
> > - error_report("can't process table for smbios "
> > - "type 4 on machine versions < 2.1!");
> > - exit(1);
> > - }
> > -
> > - g_free(smbios_entries);
> > - smbios_entries_len = sizeof(uint16_t);
> > - smbios_entries = g_malloc0(smbios_entries_len);
> > -
> > - for (i = 0, usr_offset = 0; usr_blobs_sizes && i < usr_blobs_sizes->len;
> > - i++)
> > - {
> > - struct smbios_table *table;
> > - struct smbios_structure_header *header;
> > - size_t size = g_array_index(usr_blobs_sizes, size_t, i);
> > -
> > - header = (struct smbios_structure_header *)(usr_blobs + usr_offset);
> > - smbios_entries = g_realloc(smbios_entries, smbios_entries_len +
> > - size + sizeof(*table));
> > - table = (struct smbios_table *)(smbios_entries + smbios_entries_len);
> > - table->header.type = SMBIOS_TABLE_ENTRY;
> > - table->header.length = cpu_to_le16(sizeof(*table) + size);
> > - memcpy(table->data, header, size);
> > - smbios_entries_len += sizeof(*table) + size;
> > - (*(uint16_t *)smbios_entries) =
> > - cpu_to_le16(le16_to_cpu(*(uint16_t *)smbios_entries) + 1);
> > - usr_offset += size;
> > - }
> > -
> > - smbios_build_type_0_fields();
> > - smbios_build_type_1_fields();
> > - smbios_validate_table();
> > - *length = smbios_entries_len;
> > - return smbios_entries;
> > -}
> > -/* end: legacy setup functions for <= 2.0 machines */
> > -
> > -
> > bool smbios_skip_table(uint8_t type, bool required_table)
> > {
> > if (test_bit(type, smbios_have_binfile_bitmap)) {
> > @@ -1279,14 +1125,6 @@ static bool save_opt_list(size_t *ndest, char ***dest, QemuOpts *opts,
> > return true;
> > }
> >
> > -static void smbios_add_usr_blob_size(size_t size)
> > -{
> > - if (!usr_blobs_sizes) {
> > - usr_blobs_sizes = g_array_new(false, false, sizeof(size_t));
> > - }
> > - g_array_append_val(usr_blobs_sizes, size);
> > -}
> > -
> > void smbios_entry_add(QemuOpts *opts, Error **errp)
> > {
> > const char *val;
> > diff --git a/hw/smbios/smbios_legacy.c b/hw/smbios/smbios_legacy.c
> > new file mode 100644
> > index 0000000000..21f143e738
> > --- /dev/null
> > +++ b/hw/smbios/smbios_legacy.c
> > @@ -0,0 +1,179 @@
> > +/*
> > + * SMBIOS legacy support
> > + *
> > + * Copyright (C) 2009 Hewlett-Packard Development Company, L.P.
> > + * Copyright (C) 2013 Red Hat, Inc.
> > + *
> > + * Authors:
> > + * Alex Williamson <alex.williamson@hp.com>
> > + * Markus Armbruster <armbru@redhat.com>
> > + *
> > + * This work is licensed under the terms of the GNU GPL, version 2. See
> > + * the COPYING file in the top-level directory.
> > + *
> > + * Contributions after 2012-01-13 are licensed under the terms of the
> > + * GNU GPL, version 2 or (at your option) any later version.
> > + */
> > +
> > +#include "qemu/osdep.h"
> > +#include "qemu/bswap.h"
> > +#include "hw/firmware/smbios.h"
> > +#include "sysemu/sysemu.h"
> > +#include "qemu/error-report.h"
> > +
> > +struct smbios_header {
> > + uint16_t length;
> > + uint8_t type;
> > +} QEMU_PACKED;
> > +
> > +struct smbios_field {
> > + struct smbios_header header;
> > + uint8_t type;
> > + uint16_t offset;
> > + uint8_t data[];
> > +} QEMU_PACKED;
> > +
> > +struct smbios_table {
> > + struct smbios_header header;
> > + uint8_t data[];
> > +} QEMU_PACKED;
> > +
> > +#define SMBIOS_FIELD_ENTRY 0
> > +#define SMBIOS_TABLE_ENTRY 1
> > +
> > +static uint8_t *smbios_entries;
> > +static size_t smbios_entries_len;
> > +GArray *usr_blobs_sizes;
> > +
> > +void smbios_add_usr_blob_size(size_t size)
> > +{
> > + if (!usr_blobs_sizes) {
> > + usr_blobs_sizes = g_array_new(false, false, sizeof(size_t));
> > + }
> > + g_array_append_val(usr_blobs_sizes, size);
> > +}
> > +
> > +static void smbios_add_field(int type, int offset, const void *data, size_t len)
> > +{
> > + struct smbios_field *field;
> > +
> > + if (!smbios_entries) {
> > + smbios_entries_len = sizeof(uint16_t);
> > + smbios_entries = g_malloc0(smbios_entries_len);
> > + }
> > + smbios_entries = g_realloc(smbios_entries, smbios_entries_len +
> > + sizeof(*field) + len);
> > + field = (struct smbios_field *)(smbios_entries + smbios_entries_len);
> > + field->header.type = SMBIOS_FIELD_ENTRY;
> > + field->header.length = cpu_to_le16(sizeof(*field) + len);
> > +
> > + field->type = type;
> > + field->offset = cpu_to_le16(offset);
> > + memcpy(field->data, data, len);
> > +
> > + smbios_entries_len += sizeof(*field) + len;
> > + (*(uint16_t *)smbios_entries) =
> > + cpu_to_le16(le16_to_cpu(*(uint16_t *)smbios_entries) + 1);
> > +}
> > +
> > +static void smbios_maybe_add_str(int type, int offset, const char *data)
> > +{
> > + if (data) {
> > + smbios_add_field(type, offset, data, strlen(data) + 1);
> > + }
> > +}
> > +
> > +static void smbios_build_type_0_fields(void)
> > +{
> > + smbios_maybe_add_str(0, offsetof(struct smbios_type_0, vendor_str),
> > + smbios_type0.vendor);
> > + smbios_maybe_add_str(0, offsetof(struct smbios_type_0, bios_version_str),
> > + smbios_type0.version);
> > + smbios_maybe_add_str(0, offsetof(struct smbios_type_0,
> > + bios_release_date_str),
> > + smbios_type0.date);
> > + if (smbios_type0.have_major_minor) {
> > + smbios_add_field(0, offsetof(struct smbios_type_0,
> > + system_bios_major_release),
> > + &smbios_type0.major, 1);
> > + smbios_add_field(0, offsetof(struct smbios_type_0,
> > + system_bios_minor_release),
> > + &smbios_type0.minor, 1);
> > + }
> > +}
> > +
> > +static void smbios_build_type_1_fields(void)
> > +{
> > + smbios_maybe_add_str(1, offsetof(struct smbios_type_1, manufacturer_str),
> > + smbios_type1.manufacturer);
> > + smbios_maybe_add_str(1, offsetof(struct smbios_type_1, product_name_str),
> > + smbios_type1.product);
> > + smbios_maybe_add_str(1, offsetof(struct smbios_type_1, version_str),
> > + smbios_type1.version);
> > + smbios_maybe_add_str(1, offsetof(struct smbios_type_1, serial_number_str),
> > + smbios_type1.serial);
> > + smbios_maybe_add_str(1, offsetof(struct smbios_type_1, sku_number_str),
> > + smbios_type1.sku);
> > + smbios_maybe_add_str(1, offsetof(struct smbios_type_1, family_str),
> > + smbios_type1.family);
> > + if (qemu_uuid_set) {
> > + /*
> > + * We don't encode the UUID in the "wire format" here because this
> > + * function is for legacy mode and needs to keep the guest ABI, and
> > + * because we don't know what's the SMBIOS version advertised by the
> > + * BIOS.
> > + */
> > + smbios_add_field(1, offsetof(struct smbios_type_1, uuid),
> > + &qemu_uuid, 16);
> > + }
> > +}
> > +
> > +uint8_t *smbios_get_table_legacy(size_t *length)
> > +{
> > + int i;
> > + size_t usr_offset;
> > +
> > + /* complain if fields were given for types > 1 */
> > + if (find_next_bit(smbios_have_fields_bitmap,
> > + SMBIOS_MAX_TYPE + 1, 2) < SMBIOS_MAX_TYPE + 1) {
> > + error_report("can't process fields for smbios "
> > + "types > 1 on machine versions < 2.1!");
> > + exit(1);
> > + }
> > +
> > + if (test_bit(4, smbios_have_binfile_bitmap)) {
> > + error_report("can't process table for smbios "
> > + "type 4 on machine versions < 2.1!");
> > + exit(1);
> > + }
> > +
> > + g_free(smbios_entries);
> > + smbios_entries_len = sizeof(uint16_t);
> > + smbios_entries = g_malloc0(smbios_entries_len);
> > +
> > + for (i = 0, usr_offset = 0; usr_blobs_sizes && i < usr_blobs_sizes->len;
> > + i++)
> > + {
> > + struct smbios_table *table;
> > + struct smbios_structure_header *header;
> > + size_t size = g_array_index(usr_blobs_sizes, size_t, i);
> > +
> > + header = (struct smbios_structure_header *)(usr_blobs + usr_offset);
> > + smbios_entries = g_realloc(smbios_entries, smbios_entries_len +
> > + size + sizeof(*table));
> > + table = (struct smbios_table *)(smbios_entries + smbios_entries_len);
> > + table->header.type = SMBIOS_TABLE_ENTRY;
> > + table->header.length = cpu_to_le16(sizeof(*table) + size);
> > + memcpy(table->data, header, size);
> > + smbios_entries_len += sizeof(*table) + size;
> > + (*(uint16_t *)smbios_entries) =
> > + cpu_to_le16(le16_to_cpu(*(uint16_t *)smbios_entries) + 1);
> > + usr_offset += size;
> > + }
> > +
> > + smbios_build_type_0_fields();
> > + smbios_build_type_1_fields();
> > + smbios_validate_table();
> > + *length = smbios_entries_len;
> > + return smbios_entries;
> > +}
> > diff --git a/hw/smbios/smbios_legacy_stub.c b/hw/smbios/smbios_legacy_stub.c
> > new file mode 100644
> > index 0000000000..91e6c75029
> > --- /dev/null
> > +++ b/hw/smbios/smbios_legacy_stub.c
> > @@ -0,0 +1,16 @@
> > +/*
> > + * IPMI SMBIOS firmware handling
> > + *
> > + * Copyright (c) 2024 Igor Mammedov, Red Hat, Inc.
> > + *
> > + * This work is licensed under the terms of the GNU GPL, version 2 or later.
> > + * See the COPYING file in the top-level directory.
> > + */
> > +
> > +#include "qemu/osdep.h"
> > +#include "hw/firmware/smbios.h"
> > +
> > +void smbios_add_usr_blob_size(size_t size)
> > +{
> > +}
> > +
> > --
> > 2.39.3
> >
>
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: [PATCH v2 07/20] smbios: avoid mangling user provided tables
2024-03-06 6:41 ` Ani Sinha
@ 2024-03-07 4:03 ` Ani Sinha
2024-03-08 17:19 ` Igor Mammedov
0 siblings, 1 reply; 37+ messages in thread
From: Ani Sinha @ 2024-03-07 4:03 UTC (permalink / raw)
To: Igor Mammedov
Cc: QEMU Developers, Peter Maydell, Paolo Bonzini, Michael S. Tsirkin,
Song Gao, Alistair Francis, palmer, bin.meng, liwei1518, dbarboza,
zhiwei_liu, Philippe Mathieu-Daudé, Yanan Wang, Eric Blake,
Markus Armbruster, qemu-arm, qemu-riscv, f.ebner
> On 06-Mar-2024, at 12:11, Ani Sinha <anisinha@redhat.com> wrote:
>
>
>
> On Tue, 5 Mar 2024, Igor Mammedov wrote:
>
>> currently smbios_entry_add() preserves internally '-smbios type='
>> options but tables provided with '-smbios file=' are stored directly
>> into blob that eventually will be exposed to VM. And then later
>> QEMU adds default/'-smbios type' entries on top into the same blob.
>>
>> It makes impossible to generate tables more than once, hence
>> 'immutable' guard was used.
>> Make it possible to regenerate final blob by storing user provided
>> blobs into a dedicated area (usr_blobs) and then copy it when
>> composing final blob. Which also makes handling of -smbios
>> options consistent.
>>
>> As side effect of this and previous commits there is no need to
>> generate legacy smbios_entries at the time options are parsed.
>> Instead compose smbios_entries on demand from usr_blobs like
>> it is done for non-legacy SMBIOS tables.
>>
>> Signed-off-by: Igor Mammedov <imammedo@redhat.com>
>> Tested-by: Fiona Ebner <f.ebner@proxmox.com>
>
> Reviewed-by: Ani Sinha <anisinha@redhat.com>
>
>> ---
>> hw/smbios/smbios.c | 179 +++++++++++++++++++++++----------------------
>> 1 file changed, 92 insertions(+), 87 deletions(-)
>>
>> diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c
>> index c46fc93357..aa2cc5bdbd 100644
>> --- a/hw/smbios/smbios.c
>> +++ b/hw/smbios/smbios.c
>> @@ -57,6 +57,14 @@ static size_t smbios_entries_len;
>> static bool smbios_uuid_encoded = true;
>> /* end: legacy structures & constants for <= 2.0 machines */
>>
>> +/*
>> + * SMBIOS tables provided by user with '-smbios file=<foo>' option
>> + */
>> +uint8_t *usr_blobs;
>> +size_t usr_blobs_len;
>> +static GArray *usr_blobs_sizes;
>> +static unsigned usr_table_max;
>> +static unsigned usr_table_cnt;
>>
>> uint8_t *smbios_tables;
>> size_t smbios_tables_len;
>> @@ -67,7 +75,6 @@ static SmbiosEntryPointType smbios_ep_type = SMBIOS_ENTRY_POINT_TYPE_32;
>> static SmbiosEntryPoint ep;
>>
>> static int smbios_type4_count = 0;
>> -static bool smbios_immutable;
>> static bool smbios_have_defaults;
>> static uint32_t smbios_cpuid_version, smbios_cpuid_features;
>>
>> @@ -569,9 +576,8 @@ static void smbios_build_type_1_fields(void)
>>
>> uint8_t *smbios_get_table_legacy(uint32_t expected_t4_count, size_t *length)
>> {
>> - /* drop unwanted version of command-line file blob(s) */
>> - g_free(smbios_tables);
>> - smbios_tables = NULL;
>> + int i;
>> + size_t usr_offset;
>>
>> /* also complain if fields were given for types > 1 */
>> if (find_next_bit(have_fields_bitmap,
>> @@ -581,12 +587,33 @@ uint8_t *smbios_get_table_legacy(uint32_t expected_t4_count, size_t *length)
>> exit(1);
>> }
>>
>> - if (!smbios_immutable) {
>> - smbios_build_type_0_fields();
>> - smbios_build_type_1_fields();
>> - smbios_validate_table(expected_t4_count);
>> - smbios_immutable = true;
>> + g_free(smbios_entries);
>> + smbios_entries_len = sizeof(uint16_t);
>> + smbios_entries = g_malloc0(smbios_entries_len);
>> +
>> + for (i = 0, usr_offset = 0; usr_blobs_sizes && i < usr_blobs_sizes->len;
>> + i++)
>> + {
>> + struct smbios_table *table;
>> + struct smbios_structure_header *header;
>> + size_t size = g_array_index(usr_blobs_sizes, size_t, i);
>> +
>> + header = (struct smbios_structure_header *)(usr_blobs + usr_offset);
>> + smbios_entries = g_realloc(smbios_entries, smbios_entries_len +
>> + size + sizeof(*table));
>> + table = (struct smbios_table *)(smbios_entries + smbios_entries_len);
>> + table->header.type = SMBIOS_TABLE_ENTRY;
>> + table->header.length = cpu_to_le16(sizeof(*table) + size);
>> + memcpy(table->data, header, size);
>> + smbios_entries_len += sizeof(*table) + size;
>> + (*(uint16_t *)smbios_entries) =
>> + cpu_to_le16(le16_to_cpu(*(uint16_t *)smbios_entries) + 1);
>
> I know this comes from existing code but can you please explain why we add
> 1 to it? This is confusing and a comment here would be nice.
>
>> + usr_offset += size;
>
> It would be better if we could add a comment here describing a bit what
> this is all about.
>
> user blobs are an array of smbios_structure_header entries whereas legacy
> tables are an array of smbios_table structures where
> smbios_table->data represents the a single user provided table blob in
> smbios_structure_header.
Igor, are you going to send a v3 for this with the comments added?
>
>> }
>> +
>> + smbios_build_type_0_fields();
>> + smbios_build_type_1_fields();
>> + smbios_validate_table(expected_t4_count);
>> *length = smbios_entries_len;
>> return smbios_entries;
>> }
>> @@ -1094,67 +1121,67 @@ void smbios_get_tables(MachineState *ms,
>> {
>> unsigned i, dimm_cnt, offset;
>>
>> - /* drop unwanted (legacy) version of command-line file blob(s) */
>> - g_free(smbios_entries);
>> - smbios_entries = NULL;
>> + g_free(smbios_tables);
>> + smbios_tables = g_memdup2(usr_blobs, usr_blobs_len);
>
> Again a comment describing here would be nice as to why memdup is ok.
>
>> + smbios_tables_len = usr_blobs_len;
>> + smbios_table_max = usr_table_max;
>> + smbios_table_cnt = usr_table_cnt;
>>
>> - if (!smbios_immutable) {
>> - smbios_build_type_0_table();
>> - smbios_build_type_1_table();
>> - smbios_build_type_2_table();
>> - smbios_build_type_3_table();
>> + smbios_build_type_0_table();
>> + smbios_build_type_1_table();
>> + smbios_build_type_2_table();
>> + smbios_build_type_3_table();
>>
>> - assert(ms->smp.sockets >= 1);
>> + assert(ms->smp.sockets >= 1);
>>
>> - for (i = 0; i < ms->smp.sockets; i++) {
>> - smbios_build_type_4_table(ms, i);
>> - }
>> + for (i = 0; i < ms->smp.sockets; i++) {
>> + smbios_build_type_4_table(ms, i);
>> + }
>>
>> - smbios_build_type_8_table();
>> - smbios_build_type_11_table();
>> + smbios_build_type_8_table();
>> + smbios_build_type_11_table();
>>
>> #define MAX_DIMM_SZ (16 * GiB)
>> #define GET_DIMM_SZ ((i < dimm_cnt - 1) ? MAX_DIMM_SZ \
>> : ((current_machine->ram_size - 1) % MAX_DIMM_SZ) + 1)
>>
>> - dimm_cnt = QEMU_ALIGN_UP(current_machine->ram_size, MAX_DIMM_SZ) / MAX_DIMM_SZ;
>> + dimm_cnt = QEMU_ALIGN_UP(current_machine->ram_size, MAX_DIMM_SZ) /
>> + MAX_DIMM_SZ;
>>
>> - /*
>> - * The offset determines if we need to keep additional space between
>> - * table 17 and table 19 header handle numbers so that they do
>> - * not overlap. For example, for a VM with larger than 8 TB guest
>> - * memory and DIMM like chunks of 16 GiB, the default space between
>> - * the two tables (T19_BASE - T17_BASE = 512) is not enough.
>> - */
>> - offset = (dimm_cnt > (T19_BASE - T17_BASE)) ? \
>> - dimm_cnt - (T19_BASE - T17_BASE) : 0;
>> + /*
>> + * The offset determines if we need to keep additional space between
>> + * table 17 and table 19 header handle numbers so that they do
>> + * not overlap. For example, for a VM with larger than 8 TB guest
>> + * memory and DIMM like chunks of 16 GiB, the default space between
>> + * the two tables (T19_BASE - T17_BASE = 512) is not enough.
>> + */
>> + offset = (dimm_cnt > (T19_BASE - T17_BASE)) ? \
>> + dimm_cnt - (T19_BASE - T17_BASE) : 0;
>>
>> - smbios_build_type_16_table(dimm_cnt);
>> + smbios_build_type_16_table(dimm_cnt);
>>
>> - for (i = 0; i < dimm_cnt; i++) {
>> - smbios_build_type_17_table(i, GET_DIMM_SZ);
>> - }
>> + for (i = 0; i < dimm_cnt; i++) {
>> + smbios_build_type_17_table(i, GET_DIMM_SZ);
>> + }
>>
>> - for (i = 0; i < mem_array_size; i++) {
>> - smbios_build_type_19_table(i, offset, mem_array[i].address,
>> - mem_array[i].length);
>> - }
>> + for (i = 0; i < mem_array_size; i++) {
>> + smbios_build_type_19_table(i, offset, mem_array[i].address,
>> + mem_array[i].length);
>> + }
>>
>> - /*
>> - * make sure 16 bit handle numbers in the headers of tables 19
>> - * and 32 do not overlap.
>> - */
>> - assert((mem_array_size + offset) < (T32_BASE - T19_BASE));
>> + /*
>> + * make sure 16 bit handle numbers in the headers of tables 19
>> + * and 32 do not overlap.
>> + */
>> + assert((mem_array_size + offset) < (T32_BASE - T19_BASE));
>>
>> - smbios_build_type_32_table();
>> - smbios_build_type_38_table();
>> - smbios_build_type_41_table(errp);
>> - smbios_build_type_127_table();
>> + smbios_build_type_32_table();
>> + smbios_build_type_38_table();
>> + smbios_build_type_41_table(errp);
>> + smbios_build_type_127_table();
>>
>> - smbios_validate_table(ms->smp.sockets);
>> - smbios_entry_point_setup();
>> - smbios_immutable = true;
>> - }
>> + smbios_validate_table(ms->smp.sockets);
>> + smbios_entry_point_setup();
>>
>> /* return tables blob and entry point (anchor), and their sizes */
>> *tables = smbios_tables;
>> @@ -1254,13 +1281,10 @@ void smbios_entry_add(QemuOpts *opts, Error **errp)
>> {
>> const char *val;
>>
>> - assert(!smbios_immutable);
>> -
>> val = qemu_opt_get(opts, "file");
>> if (val) {
>> struct smbios_structure_header *header;
>> - int size;
>> - struct smbios_table *table; /* legacy mode only */
>> + size_t size;
>>
>> if (!qemu_opts_validate(opts, qemu_smbios_file_opts, errp)) {
>> return;
>> @@ -1277,9 +1301,9 @@ void smbios_entry_add(QemuOpts *opts, Error **errp)
>> * (except in legacy mode, where the second '\0' is implicit and
>> * will be inserted by the BIOS).
>> */
>> - smbios_tables = g_realloc(smbios_tables, smbios_tables_len + size);
>> - header = (struct smbios_structure_header *)(smbios_tables +
>> - smbios_tables_len);
>> + usr_blobs = g_realloc(usr_blobs, usr_blobs_len + size);
>> + header = (struct smbios_structure_header *)(usr_blobs +
>> + usr_blobs_len);
>>
>> if (load_image_size(val, (uint8_t *)header, size) != size) {
>> error_setg(errp, "Failed to load SMBIOS file %s", val);
>> @@ -1300,34 +1324,15 @@ void smbios_entry_add(QemuOpts *opts, Error **errp)
>> smbios_type4_count++;
>> }
>>
>> - smbios_tables_len += size;
>> - if (size > smbios_table_max) {
>> - smbios_table_max = size;
>> + if (!usr_blobs_sizes) {
>> + usr_blobs_sizes = g_array_new(false, false, sizeof(size_t));
>> }
>> - smbios_table_cnt++;
>> -
>> - /* add a copy of the newly loaded blob to legacy smbios_entries */
>> - /* NOTE: This code runs before smbios_set_defaults(), so we don't
>> - * yet know which mode (legacy vs. aggregate-table) will be
>> - * required. We therefore add the binary blob to both legacy
>> - * (smbios_entries) and aggregate (smbios_tables) tables, and
>> - * delete the one we don't need from smbios_set_defaults(),
>> - * once we know which machine version has been requested.
>> - */
>> - if (!smbios_entries) {
>> - smbios_entries_len = sizeof(uint16_t);
>> - smbios_entries = g_malloc0(smbios_entries_len);
>> + g_array_append_val(usr_blobs_sizes, size);
>> + usr_blobs_len += size;
>> + if (size > usr_table_max) {
>> + usr_table_max = size;
>> }
>> - smbios_entries = g_realloc(smbios_entries, smbios_entries_len +
>> - size + sizeof(*table));
>> - table = (struct smbios_table *)(smbios_entries + smbios_entries_len);
>> - table->header.type = SMBIOS_TABLE_ENTRY;
>> - table->header.length = cpu_to_le16(sizeof(*table) + size);
>> - memcpy(table->data, header, size);
>> - smbios_entries_len += sizeof(*table) + size;
>> - (*(uint16_t *)smbios_entries) =
>> - cpu_to_le16(le16_to_cpu(*(uint16_t *)smbios_entries) + 1);
>> - /* end: add a copy of the newly loaded blob to legacy smbios_entries */
>> + usr_table_cnt++;
>>
>> return;
>> }
>> --
>> 2.39.3
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: [PATCH v2 14/20] smbios: extend smbios-entry-point-type with 'auto' value
2024-03-05 15:57 ` [PATCH v2 14/20] smbios: extend smbios-entry-point-type with 'auto' value Igor Mammedov
@ 2024-03-08 7:25 ` Markus Armbruster
2024-03-08 12:21 ` [PATCH v3 " Igor Mammedov
1 sibling, 0 replies; 37+ messages in thread
From: Markus Armbruster @ 2024-03-08 7:25 UTC (permalink / raw)
To: Igor Mammedov
Cc: qemu-devel, peter.maydell, pbonzini, mst, gaosong,
alistair.francis, palmer, bin.meng, liwei1518, dbarboza,
zhiwei_liu, anisinha, philmd, wangyanan55, eblake, qemu-arm,
qemu-riscv, f.ebner
Igor Mammedov <imammedo@redhat.com> writes:
> later patches will use it to pick SMBIOS version at runtime
> depending on configuration.
>
> Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> Acked-by: Markus Armbruster <armbru@redhat.com>
> Reviewed-by: Ani Sinha <anisinha@redhat.com>
> Tested-by: Fiona Ebner <f.ebner@proxmox.com>
> ---
> qapi/machine.json | 5 ++++-
> 1 file changed, 4 insertions(+), 1 deletion(-)
>
> diff --git a/qapi/machine.json b/qapi/machine.json
> index bb5a178909..6bdc71dc8c 100644
> --- a/qapi/machine.json
> +++ b/qapi/machine.json
> @@ -1797,10 +1797,13 @@
> #
> # @64: SMBIOS version 3.0 (64-bit) Entry Point
> #
> +# @auto: Either 2.x or 3.x SMBIOS version, 2.x if configuration can be
> +# described by it and 3.x otherwise (since: 9.0)
Please format like
# @auto: Either 2.x or 3.x SMBIOS version, 2.x if configuration can be
# described by it and 3.x otherwise (since: 9.0)
> +#
> # Since: 7.0
> ##
> { 'enum': 'SmbiosEntryPointType',
> - 'data': [ '32', '64' ] }
> + 'data': [ '32', '64', 'auto' ] }
>
> ##
> # @MemorySizeConfiguration:
^ permalink raw reply [flat|nested] 37+ messages in thread
* [PATCH v3 14/20] smbios: extend smbios-entry-point-type with 'auto' value
2024-03-05 15:57 ` [PATCH v2 14/20] smbios: extend smbios-entry-point-type with 'auto' value Igor Mammedov
2024-03-08 7:25 ` Markus Armbruster
@ 2024-03-08 12:21 ` Igor Mammedov
1 sibling, 0 replies; 37+ messages in thread
From: Igor Mammedov @ 2024-03-08 12:21 UTC (permalink / raw)
To: qemu-devel; +Cc: mst, armbru, Ani Sinha, Fiona Ebner
later patches will use it to pick SMBIOS version at runtime
depending on configuration.
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Acked-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Ani Sinha <anisinha@redhat.com>
Tested-by: Fiona Ebner <f.ebner@proxmox.com>
---
v3:
- make sure i2nd line of comment is indented on 4 spaces only
---
qapi/machine.json | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/qapi/machine.json b/qapi/machine.json
index bb5a178909..0840c91e70 100644
--- a/qapi/machine.json
+++ b/qapi/machine.json
@@ -1797,10 +1797,13 @@
#
# @64: SMBIOS version 3.0 (64-bit) Entry Point
#
+# @auto: Either 2.x or 3.x SMBIOS version, 2.x if configuration can be
+# described by it and 3.x otherwise (since: 9.0)
+#
# Since: 7.0
##
{ 'enum': 'SmbiosEntryPointType',
- 'data': [ '32', '64' ] }
+ 'data': [ '32', '64', 'auto' ] }
##
# @MemorySizeConfiguration:
--
2.39.3
^ permalink raw reply related [flat|nested] 37+ messages in thread
* Re: [PATCH v2 07/20] smbios: avoid mangling user provided tables
2024-03-07 4:03 ` Ani Sinha
@ 2024-03-08 17:19 ` Igor Mammedov
2024-03-09 5:42 ` Ani Sinha
0 siblings, 1 reply; 37+ messages in thread
From: Igor Mammedov @ 2024-03-08 17:19 UTC (permalink / raw)
To: Ani Sinha
Cc: QEMU Developers, Peter Maydell, Paolo Bonzini, Michael S. Tsirkin,
Song Gao, Alistair Francis, palmer, bin.meng, liwei1518, dbarboza,
zhiwei_liu, Philippe Mathieu-Daudé, Yanan Wang, Eric Blake,
Markus Armbruster, qemu-arm, qemu-riscv, f.ebner
On Thu, 7 Mar 2024 09:33:17 +0530
Ani Sinha <anisinha@redhat.com> wrote:
> > On 06-Mar-2024, at 12:11, Ani Sinha <anisinha@redhat.com> wrote:
> >
> >
> >
> > On Tue, 5 Mar 2024, Igor Mammedov wrote:
> >
> >> currently smbios_entry_add() preserves internally '-smbios type='
> >> options but tables provided with '-smbios file=' are stored directly
> >> into blob that eventually will be exposed to VM. And then later
> >> QEMU adds default/'-smbios type' entries on top into the same blob.
> >>
> >> It makes impossible to generate tables more than once, hence
> >> 'immutable' guard was used.
> >> Make it possible to regenerate final blob by storing user provided
> >> blobs into a dedicated area (usr_blobs) and then copy it when
> >> composing final blob. Which also makes handling of -smbios
> >> options consistent.
> >>
> >> As side effect of this and previous commits there is no need to
> >> generate legacy smbios_entries at the time options are parsed.
> >> Instead compose smbios_entries on demand from usr_blobs like
> >> it is done for non-legacy SMBIOS tables.
> >>
> >> Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> >> Tested-by: Fiona Ebner <f.ebner@proxmox.com>
> >
> > Reviewed-by: Ani Sinha <anisinha@redhat.com>
> >
> >> ---
> >> hw/smbios/smbios.c | 179 +++++++++++++++++++++++----------------------
> >> 1 file changed, 92 insertions(+), 87 deletions(-)
> >>
> >> diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c
> >> index c46fc93357..aa2cc5bdbd 100644
> >> --- a/hw/smbios/smbios.c
> >> +++ b/hw/smbios/smbios.c
> >> @@ -57,6 +57,14 @@ static size_t smbios_entries_len;
> >> static bool smbios_uuid_encoded = true;
> >> /* end: legacy structures & constants for <= 2.0 machines */
> >>
> >> +/*
> >> + * SMBIOS tables provided by user with '-smbios file=<foo>' option
> >> + */
> >> +uint8_t *usr_blobs;
> >> +size_t usr_blobs_len;
> >> +static GArray *usr_blobs_sizes;
> >> +static unsigned usr_table_max;
> >> +static unsigned usr_table_cnt;
> >>
> >> uint8_t *smbios_tables;
> >> size_t smbios_tables_len;
> >> @@ -67,7 +75,6 @@ static SmbiosEntryPointType smbios_ep_type = SMBIOS_ENTRY_POINT_TYPE_32;
> >> static SmbiosEntryPoint ep;
> >>
> >> static int smbios_type4_count = 0;
> >> -static bool smbios_immutable;
> >> static bool smbios_have_defaults;
> >> static uint32_t smbios_cpuid_version, smbios_cpuid_features;
> >>
> >> @@ -569,9 +576,8 @@ static void smbios_build_type_1_fields(void)
> >>
> >> uint8_t *smbios_get_table_legacy(uint32_t expected_t4_count, size_t *length)
> >> {
> >> - /* drop unwanted version of command-line file blob(s) */
> >> - g_free(smbios_tables);
> >> - smbios_tables = NULL;
> >> + int i;
> >> + size_t usr_offset;
> >>
> >> /* also complain if fields were given for types > 1 */
> >> if (find_next_bit(have_fields_bitmap,
> >> @@ -581,12 +587,33 @@ uint8_t *smbios_get_table_legacy(uint32_t expected_t4_count, size_t *length)
> >> exit(1);
> >> }
> >>
> >> - if (!smbios_immutable) {
> >> - smbios_build_type_0_fields();
> >> - smbios_build_type_1_fields();
> >> - smbios_validate_table(expected_t4_count);
> >> - smbios_immutable = true;
> >> + g_free(smbios_entries);
> >> + smbios_entries_len = sizeof(uint16_t);
> >> + smbios_entries = g_malloc0(smbios_entries_len);
> >> +
> >> + for (i = 0, usr_offset = 0; usr_blobs_sizes && i < usr_blobs_sizes->len;
> >> + i++)
> >> + {
> >> + struct smbios_table *table;
> >> + struct smbios_structure_header *header;
> >> + size_t size = g_array_index(usr_blobs_sizes, size_t, i);
> >> +
> >> + header = (struct smbios_structure_header *)(usr_blobs + usr_offset);
> >> + smbios_entries = g_realloc(smbios_entries, smbios_entries_len +
> >> + size + sizeof(*table));
> >> + table = (struct smbios_table *)(smbios_entries + smbios_entries_len);
> >> + table->header.type = SMBIOS_TABLE_ENTRY;
> >> + table->header.length = cpu_to_le16(sizeof(*table) + size);
> >> + memcpy(table->data, header, size);
> >> + smbios_entries_len += sizeof(*table) + size;
> >> + (*(uint16_t *)smbios_entries) =
> >> + cpu_to_le16(le16_to_cpu(*(uint16_t *)smbios_entries) + 1);
> >
> > I know this comes from existing code but can you please explain why we add
> > 1 to it? This is confusing and a comment here would be nice.
> >
> >> + usr_offset += size;
> >
> > It would be better if we could add a comment here describing a bit what
> > this is all about.
> >
> > user blobs are an array of smbios_structure_header entries whereas legacy
> > tables are an array of smbios_table structures where
> > smbios_table->data represents the a single user provided table blob in
> > smbios_structure_header.
>
> Igor, are you going to send a v3 for this with the comments added?
I can add comments as a patch on top of series,
though I'd rather prefer to deprecate all this legacy code
(along with ISA machine) and just remove it.
>
> >
> >> }
> >> +
> >> + smbios_build_type_0_fields();
> >> + smbios_build_type_1_fields();
> >> + smbios_validate_table(expected_t4_count);
> >> *length = smbios_entries_len;
> >> return smbios_entries;
> >> }
> >> @@ -1094,67 +1121,67 @@ void smbios_get_tables(MachineState *ms,
> >> {
> >> unsigned i, dimm_cnt, offset;
> >>
> >> - /* drop unwanted (legacy) version of command-line file blob(s) */
> >> - g_free(smbios_entries);
> >> - smbios_entries = NULL;
> >> + g_free(smbios_tables);
> >> + smbios_tables = g_memdup2(usr_blobs, usr_blobs_len);
> >
> > Again a comment describing here would be nice as to why memdup is ok.
> >
> >> + smbios_tables_len = usr_blobs_len;
> >> + smbios_table_max = usr_table_max;
> >> + smbios_table_cnt = usr_table_cnt;
> >>
> >> - if (!smbios_immutable) {
> >> - smbios_build_type_0_table();
> >> - smbios_build_type_1_table();
> >> - smbios_build_type_2_table();
> >> - smbios_build_type_3_table();
> >> + smbios_build_type_0_table();
> >> + smbios_build_type_1_table();
> >> + smbios_build_type_2_table();
> >> + smbios_build_type_3_table();
> >>
> >> - assert(ms->smp.sockets >= 1);
> >> + assert(ms->smp.sockets >= 1);
> >>
> >> - for (i = 0; i < ms->smp.sockets; i++) {
> >> - smbios_build_type_4_table(ms, i);
> >> - }
> >> + for (i = 0; i < ms->smp.sockets; i++) {
> >> + smbios_build_type_4_table(ms, i);
> >> + }
> >>
> >> - smbios_build_type_8_table();
> >> - smbios_build_type_11_table();
> >> + smbios_build_type_8_table();
> >> + smbios_build_type_11_table();
> >>
> >> #define MAX_DIMM_SZ (16 * GiB)
> >> #define GET_DIMM_SZ ((i < dimm_cnt - 1) ? MAX_DIMM_SZ \
> >> : ((current_machine->ram_size - 1) % MAX_DIMM_SZ) + 1)
> >>
> >> - dimm_cnt = QEMU_ALIGN_UP(current_machine->ram_size, MAX_DIMM_SZ) / MAX_DIMM_SZ;
> >> + dimm_cnt = QEMU_ALIGN_UP(current_machine->ram_size, MAX_DIMM_SZ) /
> >> + MAX_DIMM_SZ;
> >>
> >> - /*
> >> - * The offset determines if we need to keep additional space between
> >> - * table 17 and table 19 header handle numbers so that they do
> >> - * not overlap. For example, for a VM with larger than 8 TB guest
> >> - * memory and DIMM like chunks of 16 GiB, the default space between
> >> - * the two tables (T19_BASE - T17_BASE = 512) is not enough.
> >> - */
> >> - offset = (dimm_cnt > (T19_BASE - T17_BASE)) ? \
> >> - dimm_cnt - (T19_BASE - T17_BASE) : 0;
> >> + /*
> >> + * The offset determines if we need to keep additional space between
> >> + * table 17 and table 19 header handle numbers so that they do
> >> + * not overlap. For example, for a VM with larger than 8 TB guest
> >> + * memory and DIMM like chunks of 16 GiB, the default space between
> >> + * the two tables (T19_BASE - T17_BASE = 512) is not enough.
> >> + */
> >> + offset = (dimm_cnt > (T19_BASE - T17_BASE)) ? \
> >> + dimm_cnt - (T19_BASE - T17_BASE) : 0;
> >>
> >> - smbios_build_type_16_table(dimm_cnt);
> >> + smbios_build_type_16_table(dimm_cnt);
> >>
> >> - for (i = 0; i < dimm_cnt; i++) {
> >> - smbios_build_type_17_table(i, GET_DIMM_SZ);
> >> - }
> >> + for (i = 0; i < dimm_cnt; i++) {
> >> + smbios_build_type_17_table(i, GET_DIMM_SZ);
> >> + }
> >>
> >> - for (i = 0; i < mem_array_size; i++) {
> >> - smbios_build_type_19_table(i, offset, mem_array[i].address,
> >> - mem_array[i].length);
> >> - }
> >> + for (i = 0; i < mem_array_size; i++) {
> >> + smbios_build_type_19_table(i, offset, mem_array[i].address,
> >> + mem_array[i].length);
> >> + }
> >>
> >> - /*
> >> - * make sure 16 bit handle numbers in the headers of tables 19
> >> - * and 32 do not overlap.
> >> - */
> >> - assert((mem_array_size + offset) < (T32_BASE - T19_BASE));
> >> + /*
> >> + * make sure 16 bit handle numbers in the headers of tables 19
> >> + * and 32 do not overlap.
> >> + */
> >> + assert((mem_array_size + offset) < (T32_BASE - T19_BASE));
> >>
> >> - smbios_build_type_32_table();
> >> - smbios_build_type_38_table();
> >> - smbios_build_type_41_table(errp);
> >> - smbios_build_type_127_table();
> >> + smbios_build_type_32_table();
> >> + smbios_build_type_38_table();
> >> + smbios_build_type_41_table(errp);
> >> + smbios_build_type_127_table();
> >>
> >> - smbios_validate_table(ms->smp.sockets);
> >> - smbios_entry_point_setup();
> >> - smbios_immutable = true;
> >> - }
> >> + smbios_validate_table(ms->smp.sockets);
> >> + smbios_entry_point_setup();
> >>
> >> /* return tables blob and entry point (anchor), and their sizes */
> >> *tables = smbios_tables;
> >> @@ -1254,13 +1281,10 @@ void smbios_entry_add(QemuOpts *opts, Error **errp)
> >> {
> >> const char *val;
> >>
> >> - assert(!smbios_immutable);
> >> -
> >> val = qemu_opt_get(opts, "file");
> >> if (val) {
> >> struct smbios_structure_header *header;
> >> - int size;
> >> - struct smbios_table *table; /* legacy mode only */
> >> + size_t size;
> >>
> >> if (!qemu_opts_validate(opts, qemu_smbios_file_opts, errp)) {
> >> return;
> >> @@ -1277,9 +1301,9 @@ void smbios_entry_add(QemuOpts *opts, Error **errp)
> >> * (except in legacy mode, where the second '\0' is implicit and
> >> * will be inserted by the BIOS).
> >> */
> >> - smbios_tables = g_realloc(smbios_tables, smbios_tables_len + size);
> >> - header = (struct smbios_structure_header *)(smbios_tables +
> >> - smbios_tables_len);
> >> + usr_blobs = g_realloc(usr_blobs, usr_blobs_len + size);
> >> + header = (struct smbios_structure_header *)(usr_blobs +
> >> + usr_blobs_len);
> >>
> >> if (load_image_size(val, (uint8_t *)header, size) != size) {
> >> error_setg(errp, "Failed to load SMBIOS file %s", val);
> >> @@ -1300,34 +1324,15 @@ void smbios_entry_add(QemuOpts *opts, Error **errp)
> >> smbios_type4_count++;
> >> }
> >>
> >> - smbios_tables_len += size;
> >> - if (size > smbios_table_max) {
> >> - smbios_table_max = size;
> >> + if (!usr_blobs_sizes) {
> >> + usr_blobs_sizes = g_array_new(false, false, sizeof(size_t));
> >> }
> >> - smbios_table_cnt++;
> >> -
> >> - /* add a copy of the newly loaded blob to legacy smbios_entries */
> >> - /* NOTE: This code runs before smbios_set_defaults(), so we don't
> >> - * yet know which mode (legacy vs. aggregate-table) will be
> >> - * required. We therefore add the binary blob to both legacy
> >> - * (smbios_entries) and aggregate (smbios_tables) tables, and
> >> - * delete the one we don't need from smbios_set_defaults(),
> >> - * once we know which machine version has been requested.
> >> - */
> >> - if (!smbios_entries) {
> >> - smbios_entries_len = sizeof(uint16_t);
> >> - smbios_entries = g_malloc0(smbios_entries_len);
> >> + g_array_append_val(usr_blobs_sizes, size);
> >> + usr_blobs_len += size;
> >> + if (size > usr_table_max) {
> >> + usr_table_max = size;
> >> }
> >> - smbios_entries = g_realloc(smbios_entries, smbios_entries_len +
> >> - size + sizeof(*table));
> >> - table = (struct smbios_table *)(smbios_entries + smbios_entries_len);
> >> - table->header.type = SMBIOS_TABLE_ENTRY;
> >> - table->header.length = cpu_to_le16(sizeof(*table) + size);
> >> - memcpy(table->data, header, size);
> >> - smbios_entries_len += sizeof(*table) + size;
> >> - (*(uint16_t *)smbios_entries) =
> >> - cpu_to_le16(le16_to_cpu(*(uint16_t *)smbios_entries) + 1);
> >> - /* end: add a copy of the newly loaded blob to legacy smbios_entries */
> >> + usr_table_cnt++;
> >>
> >> return;
> >> }
> >> --
> >> 2.39.3
>
>
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: [PATCH v2 07/20] smbios: avoid mangling user provided tables
2024-03-08 17:19 ` Igor Mammedov
@ 2024-03-09 5:42 ` Ani Sinha
0 siblings, 0 replies; 37+ messages in thread
From: Ani Sinha @ 2024-03-09 5:42 UTC (permalink / raw)
To: Igor Mammedov
Cc: QEMU Developers, Peter Maydell, Paolo Bonzini, Michael S. Tsirkin,
Song Gao, Alistair Francis, palmer, bin.meng, liwei1518, dbarboza,
zhiwei_liu, Philippe Mathieu-Daudé, Yanan Wang, Eric Blake,
Markus Armbruster, qemu-arm, qemu-riscv, f.ebner
> On 08-Mar-2024, at 22:49, Igor Mammedov <imammedo@redhat.com> wrote:
>
> On Thu, 7 Mar 2024 09:33:17 +0530
> Ani Sinha <anisinha@redhat.com> wrote:
>
>>> On 06-Mar-2024, at 12:11, Ani Sinha <anisinha@redhat.com> wrote:
>>>
>>>
>>>
>>> On Tue, 5 Mar 2024, Igor Mammedov wrote:
>>>
>>>> currently smbios_entry_add() preserves internally '-smbios type='
>>>> options but tables provided with '-smbios file=' are stored directly
>>>> into blob that eventually will be exposed to VM. And then later
>>>> QEMU adds default/'-smbios type' entries on top into the same blob.
>>>>
>>>> It makes impossible to generate tables more than once, hence
>>>> 'immutable' guard was used.
>>>> Make it possible to regenerate final blob by storing user provided
>>>> blobs into a dedicated area (usr_blobs) and then copy it when
>>>> composing final blob. Which also makes handling of -smbios
>>>> options consistent.
>>>>
>>>> As side effect of this and previous commits there is no need to
>>>> generate legacy smbios_entries at the time options are parsed.
>>>> Instead compose smbios_entries on demand from usr_blobs like
>>>> it is done for non-legacy SMBIOS tables.
>>>>
>>>> Signed-off-by: Igor Mammedov <imammedo@redhat.com>
>>>> Tested-by: Fiona Ebner <f.ebner@proxmox.com>
>>>
>>> Reviewed-by: Ani Sinha <anisinha@redhat.com>
>>>
>>>> ---
>>>> hw/smbios/smbios.c | 179 +++++++++++++++++++++++----------------------
>>>> 1 file changed, 92 insertions(+), 87 deletions(-)
>>>>
>>>> diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c
>>>> index c46fc93357..aa2cc5bdbd 100644
>>>> --- a/hw/smbios/smbios.c
>>>> +++ b/hw/smbios/smbios.c
>>>> @@ -57,6 +57,14 @@ static size_t smbios_entries_len;
>>>> static bool smbios_uuid_encoded = true;
>>>> /* end: legacy structures & constants for <= 2.0 machines */
>>>>
>>>> +/*
>>>> + * SMBIOS tables provided by user with '-smbios file=<foo>' option
>>>> + */
>>>> +uint8_t *usr_blobs;
>>>> +size_t usr_blobs_len;
>>>> +static GArray *usr_blobs_sizes;
>>>> +static unsigned usr_table_max;
>>>> +static unsigned usr_table_cnt;
>>>>
>>>> uint8_t *smbios_tables;
>>>> size_t smbios_tables_len;
>>>> @@ -67,7 +75,6 @@ static SmbiosEntryPointType smbios_ep_type = SMBIOS_ENTRY_POINT_TYPE_32;
>>>> static SmbiosEntryPoint ep;
>>>>
>>>> static int smbios_type4_count = 0;
>>>> -static bool smbios_immutable;
>>>> static bool smbios_have_defaults;
>>>> static uint32_t smbios_cpuid_version, smbios_cpuid_features;
>>>>
>>>> @@ -569,9 +576,8 @@ static void smbios_build_type_1_fields(void)
>>>>
>>>> uint8_t *smbios_get_table_legacy(uint32_t expected_t4_count, size_t *length)
>>>> {
>>>> - /* drop unwanted version of command-line file blob(s) */
>>>> - g_free(smbios_tables);
>>>> - smbios_tables = NULL;
>>>> + int i;
>>>> + size_t usr_offset;
>>>>
>>>> /* also complain if fields were given for types > 1 */
>>>> if (find_next_bit(have_fields_bitmap,
>>>> @@ -581,12 +587,33 @@ uint8_t *smbios_get_table_legacy(uint32_t expected_t4_count, size_t *length)
>>>> exit(1);
>>>> }
>>>>
>>>> - if (!smbios_immutable) {
>>>> - smbios_build_type_0_fields();
>>>> - smbios_build_type_1_fields();
>>>> - smbios_validate_table(expected_t4_count);
>>>> - smbios_immutable = true;
>>>> + g_free(smbios_entries);
>>>> + smbios_entries_len = sizeof(uint16_t);
>>>> + smbios_entries = g_malloc0(smbios_entries_len);
>>>> +
>>>> + for (i = 0, usr_offset = 0; usr_blobs_sizes && i < usr_blobs_sizes->len;
>>>> + i++)
>>>> + {
>>>> + struct smbios_table *table;
>>>> + struct smbios_structure_header *header;
>>>> + size_t size = g_array_index(usr_blobs_sizes, size_t, i);
>>>> +
>>>> + header = (struct smbios_structure_header *)(usr_blobs + usr_offset);
>>>> + smbios_entries = g_realloc(smbios_entries, smbios_entries_len +
>>>> + size + sizeof(*table));
>>>> + table = (struct smbios_table *)(smbios_entries + smbios_entries_len);
>>>> + table->header.type = SMBIOS_TABLE_ENTRY;
>>>> + table->header.length = cpu_to_le16(sizeof(*table) + size);
>>>> + memcpy(table->data, header, size);
>>>> + smbios_entries_len += sizeof(*table) + size;
>>>> + (*(uint16_t *)smbios_entries) =
>>>> + cpu_to_le16(le16_to_cpu(*(uint16_t *)smbios_entries) + 1);
>>>
>>> I know this comes from existing code but can you please explain why we add
>>> 1 to it? This is confusing and a comment here would be nice.
>>>
>>>> + usr_offset += size;
>>>
>>> It would be better if we could add a comment here describing a bit what
>>> this is all about.
>>>
>>> user blobs are an array of smbios_structure_header entries whereas legacy
>>> tables are an array of smbios_table structures where
>>> smbios_table->data represents the a single user provided table blob in
>>> smbios_structure_header.
>>
>> Igor, are you going to send a v3 for this with the comments added?
>
> I can add comments as a patch on top of series,
> though I'd rather prefer to deprecate all this legacy code
> (along with ISA machine) and just remove it.
The reason why I suggested this is because since you have done so much rework on this code, you are probably fresh on the knowledge of how and why the code is written the way it is. It might be better to improve the documentation at the same time while you are at it while the knowledge is still fresh in your mind so that the life is better for the next person who touches this.
>
>>
>>>
>>>> }
>>>> +
>>>> + smbios_build_type_0_fields();
>>>> + smbios_build_type_1_fields();
>>>> + smbios_validate_table(expected_t4_count);
>>>> *length = smbios_entries_len;
>>>> return smbios_entries;
>>>> }
>>>> @@ -1094,67 +1121,67 @@ void smbios_get_tables(MachineState *ms,
>>>> {
>>>> unsigned i, dimm_cnt, offset;
>>>>
>>>> - /* drop unwanted (legacy) version of command-line file blob(s) */
>>>> - g_free(smbios_entries);
>>>> - smbios_entries = NULL;
>>>> + g_free(smbios_tables);
>>>> + smbios_tables = g_memdup2(usr_blobs, usr_blobs_len);
>>>
>>> Again a comment describing here would be nice as to why memdup is ok.
>>>
>>>> + smbios_tables_len = usr_blobs_len;
>>>> + smbios_table_max = usr_table_max;
>>>> + smbios_table_cnt = usr_table_cnt;
>>>>
>>>> - if (!smbios_immutable) {
>>>> - smbios_build_type_0_table();
>>>> - smbios_build_type_1_table();
>>>> - smbios_build_type_2_table();
>>>> - smbios_build_type_3_table();
>>>> + smbios_build_type_0_table();
>>>> + smbios_build_type_1_table();
>>>> + smbios_build_type_2_table();
>>>> + smbios_build_type_3_table();
>>>>
>>>> - assert(ms->smp.sockets >= 1);
>>>> + assert(ms->smp.sockets >= 1);
>>>>
>>>> - for (i = 0; i < ms->smp.sockets; i++) {
>>>> - smbios_build_type_4_table(ms, i);
>>>> - }
>>>> + for (i = 0; i < ms->smp.sockets; i++) {
>>>> + smbios_build_type_4_table(ms, i);
>>>> + }
>>>>
>>>> - smbios_build_type_8_table();
>>>> - smbios_build_type_11_table();
>>>> + smbios_build_type_8_table();
>>>> + smbios_build_type_11_table();
>>>>
>>>> #define MAX_DIMM_SZ (16 * GiB)
>>>> #define GET_DIMM_SZ ((i < dimm_cnt - 1) ? MAX_DIMM_SZ \
>>>> : ((current_machine->ram_size - 1) % MAX_DIMM_SZ) + 1)
>>>>
>>>> - dimm_cnt = QEMU_ALIGN_UP(current_machine->ram_size, MAX_DIMM_SZ) / MAX_DIMM_SZ;
>>>> + dimm_cnt = QEMU_ALIGN_UP(current_machine->ram_size, MAX_DIMM_SZ) /
>>>> + MAX_DIMM_SZ;
>>>>
>>>> - /*
>>>> - * The offset determines if we need to keep additional space between
>>>> - * table 17 and table 19 header handle numbers so that they do
>>>> - * not overlap. For example, for a VM with larger than 8 TB guest
>>>> - * memory and DIMM like chunks of 16 GiB, the default space between
>>>> - * the two tables (T19_BASE - T17_BASE = 512) is not enough.
>>>> - */
>>>> - offset = (dimm_cnt > (T19_BASE - T17_BASE)) ? \
>>>> - dimm_cnt - (T19_BASE - T17_BASE) : 0;
>>>> + /*
>>>> + * The offset determines if we need to keep additional space between
>>>> + * table 17 and table 19 header handle numbers so that they do
>>>> + * not overlap. For example, for a VM with larger than 8 TB guest
>>>> + * memory and DIMM like chunks of 16 GiB, the default space between
>>>> + * the two tables (T19_BASE - T17_BASE = 512) is not enough.
>>>> + */
>>>> + offset = (dimm_cnt > (T19_BASE - T17_BASE)) ? \
>>>> + dimm_cnt - (T19_BASE - T17_BASE) : 0;
>>>>
>>>> - smbios_build_type_16_table(dimm_cnt);
>>>> + smbios_build_type_16_table(dimm_cnt);
>>>>
>>>> - for (i = 0; i < dimm_cnt; i++) {
>>>> - smbios_build_type_17_table(i, GET_DIMM_SZ);
>>>> - }
>>>> + for (i = 0; i < dimm_cnt; i++) {
>>>> + smbios_build_type_17_table(i, GET_DIMM_SZ);
>>>> + }
>>>>
>>>> - for (i = 0; i < mem_array_size; i++) {
>>>> - smbios_build_type_19_table(i, offset, mem_array[i].address,
>>>> - mem_array[i].length);
>>>> - }
>>>> + for (i = 0; i < mem_array_size; i++) {
>>>> + smbios_build_type_19_table(i, offset, mem_array[i].address,
>>>> + mem_array[i].length);
>>>> + }
>>>>
>>>> - /*
>>>> - * make sure 16 bit handle numbers in the headers of tables 19
>>>> - * and 32 do not overlap.
>>>> - */
>>>> - assert((mem_array_size + offset) < (T32_BASE - T19_BASE));
>>>> + /*
>>>> + * make sure 16 bit handle numbers in the headers of tables 19
>>>> + * and 32 do not overlap.
>>>> + */
>>>> + assert((mem_array_size + offset) < (T32_BASE - T19_BASE));
>>>>
>>>> - smbios_build_type_32_table();
>>>> - smbios_build_type_38_table();
>>>> - smbios_build_type_41_table(errp);
>>>> - smbios_build_type_127_table();
>>>> + smbios_build_type_32_table();
>>>> + smbios_build_type_38_table();
>>>> + smbios_build_type_41_table(errp);
>>>> + smbios_build_type_127_table();
>>>>
>>>> - smbios_validate_table(ms->smp.sockets);
>>>> - smbios_entry_point_setup();
>>>> - smbios_immutable = true;
>>>> - }
>>>> + smbios_validate_table(ms->smp.sockets);
>>>> + smbios_entry_point_setup();
>>>>
>>>> /* return tables blob and entry point (anchor), and their sizes */
>>>> *tables = smbios_tables;
>>>> @@ -1254,13 +1281,10 @@ void smbios_entry_add(QemuOpts *opts, Error **errp)
>>>> {
>>>> const char *val;
>>>>
>>>> - assert(!smbios_immutable);
>>>> -
>>>> val = qemu_opt_get(opts, "file");
>>>> if (val) {
>>>> struct smbios_structure_header *header;
>>>> - int size;
>>>> - struct smbios_table *table; /* legacy mode only */
>>>> + size_t size;
>>>>
>>>> if (!qemu_opts_validate(opts, qemu_smbios_file_opts, errp)) {
>>>> return;
>>>> @@ -1277,9 +1301,9 @@ void smbios_entry_add(QemuOpts *opts, Error **errp)
>>>> * (except in legacy mode, where the second '\0' is implicit and
>>>> * will be inserted by the BIOS).
>>>> */
>>>> - smbios_tables = g_realloc(smbios_tables, smbios_tables_len + size);
>>>> - header = (struct smbios_structure_header *)(smbios_tables +
>>>> - smbios_tables_len);
>>>> + usr_blobs = g_realloc(usr_blobs, usr_blobs_len + size);
>>>> + header = (struct smbios_structure_header *)(usr_blobs +
>>>> + usr_blobs_len);
>>>>
>>>> if (load_image_size(val, (uint8_t *)header, size) != size) {
>>>> error_setg(errp, "Failed to load SMBIOS file %s", val);
>>>> @@ -1300,34 +1324,15 @@ void smbios_entry_add(QemuOpts *opts, Error **errp)
>>>> smbios_type4_count++;
>>>> }
>>>>
>>>> - smbios_tables_len += size;
>>>> - if (size > smbios_table_max) {
>>>> - smbios_table_max = size;
>>>> + if (!usr_blobs_sizes) {
>>>> + usr_blobs_sizes = g_array_new(false, false, sizeof(size_t));
>>>> }
>>>> - smbios_table_cnt++;
>>>> -
>>>> - /* add a copy of the newly loaded blob to legacy smbios_entries */
>>>> - /* NOTE: This code runs before smbios_set_defaults(), so we don't
>>>> - * yet know which mode (legacy vs. aggregate-table) will be
>>>> - * required. We therefore add the binary blob to both legacy
>>>> - * (smbios_entries) and aggregate (smbios_tables) tables, and
>>>> - * delete the one we don't need from smbios_set_defaults(),
>>>> - * once we know which machine version has been requested.
>>>> - */
>>>> - if (!smbios_entries) {
>>>> - smbios_entries_len = sizeof(uint16_t);
>>>> - smbios_entries = g_malloc0(smbios_entries_len);
>>>> + g_array_append_val(usr_blobs_sizes, size);
>>>> + usr_blobs_len += size;
>>>> + if (size > usr_table_max) {
>>>> + usr_table_max = size;
>>>> }
>>>> - smbios_entries = g_realloc(smbios_entries, smbios_entries_len +
>>>> - size + sizeof(*table));
>>>> - table = (struct smbios_table *)(smbios_entries + smbios_entries_len);
>>>> - table->header.type = SMBIOS_TABLE_ENTRY;
>>>> - table->header.length = cpu_to_le16(sizeof(*table) + size);
>>>> - memcpy(table->data, header, size);
>>>> - smbios_entries_len += sizeof(*table) + size;
>>>> - (*(uint16_t *)smbios_entries) =
>>>> - cpu_to_le16(le16_to_cpu(*(uint16_t *)smbios_entries) + 1);
>>>> - /* end: add a copy of the newly loaded blob to legacy smbios_entries */
>>>> + usr_table_cnt++;
>>>>
>>>> return;
>>>> }
>>>> --
>>>> 2.39.3
^ permalink raw reply [flat|nested] 37+ messages in thread
end of thread, other threads:[~2024-03-09 5:43 UTC | newest]
Thread overview: 37+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-03-05 15:57 [PATCH v2 00/20] Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS Igor Mammedov
2024-03-05 15:57 ` [PATCH v2 01/20] tests: smbios: make it possible to write SMBIOS only test Igor Mammedov
2024-03-05 15:57 ` [PATCH v2 02/20] tests: smbios: add test for -smbios type=11 option Igor Mammedov
2024-03-05 15:57 ` [PATCH v2 03/20] tests: smbios: add test for legacy mode CLI options Igor Mammedov
2024-03-05 15:57 ` [PATCH v2 04/20] smbios: cleanup smbios_get_tables() from legacy handling Igor Mammedov
2024-03-05 15:57 ` [PATCH v2 05/20] smbios: get rid of smbios_smp_sockets global Igor Mammedov
2024-03-05 15:57 ` [PATCH v2 06/20] smbios: get rid of smbios_legacy global Igor Mammedov
2024-03-05 15:57 ` [PATCH v2 07/20] smbios: avoid mangling user provided tables Igor Mammedov
2024-03-06 6:41 ` Ani Sinha
2024-03-07 4:03 ` Ani Sinha
2024-03-08 17:19 ` Igor Mammedov
2024-03-09 5:42 ` Ani Sinha
2024-03-05 15:57 ` [PATCH v2 08/20] smbios: don't check type4 structures in legacy mode Igor Mammedov
2024-03-05 15:57 ` [PATCH v2 09/20] smbios: add smbios_add_usr_blob_size() helper Igor Mammedov
2024-03-06 6:48 ` Ani Sinha
2024-03-05 15:57 ` [PATCH v2 10/20] smbios: rename/expose structures/bitmaps used by both legacy and modern code Igor Mammedov
2024-03-06 7:15 ` Ani Sinha
2024-03-05 15:57 ` [PATCH v2 11/20] smbios: build legacy mode code only for 'pc' machine Igor Mammedov
2024-03-06 7:27 ` Ani Sinha
2024-03-06 10:04 ` Igor Mammedov
2024-03-06 10:03 ` [PATCH v3 " Igor Mammedov
2024-03-05 15:57 ` [PATCH v2 12/20] smbios: handle errors consistently Igor Mammedov
2024-03-05 15:57 ` [PATCH v2 13/20] smbios: get rid of global smbios_ep_type Igor Mammedov
2024-03-05 15:57 ` [PATCH v2 14/20] smbios: extend smbios-entry-point-type with 'auto' value Igor Mammedov
2024-03-08 7:25 ` Markus Armbruster
2024-03-08 12:21 ` [PATCH v3 " Igor Mammedov
2024-03-05 15:57 ` [PATCH v2 15/20] smbios: in case of entry point is 'auto' try to build v2 tables 1st Igor Mammedov
2024-03-05 15:57 ` [PATCH v2 16/20] smbios: error out when building type 4 table is not possible Igor Mammedov
2024-03-05 15:57 ` [PATCH v2 17/20] smbios: clear smbios_type4_count before building tables Igor Mammedov
2024-03-06 7:47 ` Ani Sinha
2024-03-06 9:58 ` Igor Mammedov
2024-03-05 15:57 ` [PATCH v2 18/20] tests: acpi/smbios: whitelist expected blobs Igor Mammedov
2024-03-06 8:31 ` Ani Sinha
2024-03-05 15:57 ` [PATCH v2 19/20] pc/q35: set SMBIOS entry point type to 'auto' by default Igor Mammedov
2024-03-05 15:57 ` [PATCH v2 20/20] tests: acpi: update expected SSDT.dimmpxm blob Igor Mammedov
2024-03-06 9:20 ` Ani Sinha
2024-03-06 10:01 ` Igor Mammedov
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).