* [PATCH 01/19] tests: smbios: make it possible to write SMBIOS only test
2024-02-27 15:47 [PATCH 00/19] Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS Igor Mammedov
@ 2024-02-27 15:47 ` Igor Mammedov
2024-02-28 9:35 ` Ani Sinha
2024-02-27 15:47 ` [PATCH 02/19] tests: smbios: add test for -smbios type=11 option Igor Mammedov
` (20 subsequent siblings)
21 siblings, 1 reply; 54+ messages in thread
From: Igor Mammedov @ 2024-02-27 15:47 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>
---
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] 54+ messages in thread
* Re: [PATCH 01/19] tests: smbios: make it possible to write SMBIOS only test
2024-02-27 15:47 ` [PATCH 01/19] tests: smbios: make it possible to write SMBIOS only test Igor Mammedov
@ 2024-02-28 9:35 ` Ani Sinha
0 siblings, 0 replies; 54+ messages in thread
From: Ani Sinha @ 2024-02-28 9:35 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 27-Feb-2024, at 21:17, Igor Mammedov <imammedo@redhat.com> wrote:
>
> 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>
> ---
> 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 [flat|nested] 54+ messages in thread
* [PATCH 02/19] tests: smbios: add test for -smbios type=11 option
2024-02-27 15:47 [PATCH 00/19] Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS Igor Mammedov
2024-02-27 15:47 ` [PATCH 01/19] tests: smbios: make it possible to write SMBIOS only test Igor Mammedov
@ 2024-02-27 15:47 ` Igor Mammedov
2024-02-28 9:55 ` Ani Sinha
2024-02-27 15:47 ` [PATCH 03/19] tests: smbios: add test for legacy mode CLI options Igor Mammedov
` (19 subsequent siblings)
21 siblings, 1 reply; 54+ messages in thread
From: Igor Mammedov @ 2024-02-27 15:47 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/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] 54+ messages in thread
* Re: [PATCH 02/19] tests: smbios: add test for -smbios type=11 option
2024-02-27 15:47 ` [PATCH 02/19] tests: smbios: add test for -smbios type=11 option Igor Mammedov
@ 2024-02-28 9:55 ` Ani Sinha
0 siblings, 0 replies; 54+ messages in thread
From: Ani Sinha @ 2024-02-28 9:55 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 27-Feb-2024, at 21:17, Igor Mammedov <imammedo@redhat.com> wrote:
>
> Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Empty description is not nice. Other than that,
Reviewed-by: Ani Sinha <anisinha@redhat.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 [flat|nested] 54+ messages in thread
* [PATCH 03/19] tests: smbios: add test for legacy mode CLI options
2024-02-27 15:47 [PATCH 00/19] Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS Igor Mammedov
2024-02-27 15:47 ` [PATCH 01/19] tests: smbios: make it possible to write SMBIOS only test Igor Mammedov
2024-02-27 15:47 ` [PATCH 02/19] tests: smbios: add test for -smbios type=11 option Igor Mammedov
@ 2024-02-27 15:47 ` Igor Mammedov
2024-02-28 11:11 ` Ani Sinha
2024-02-28 14:18 ` Ani Sinha
2024-02-27 15:47 ` [PATCH 04/19] smbios: cleanup smbios_get_tables() from legacy handling Igor Mammedov
` (18 subsequent siblings)
21 siblings, 2 replies; 54+ messages in thread
From: Igor Mammedov @ 2024-02-27 15:47 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>
---
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] 54+ messages in thread
* Re: [PATCH 03/19] tests: smbios: add test for legacy mode CLI options
2024-02-27 15:47 ` [PATCH 03/19] tests: smbios: add test for legacy mode CLI options Igor Mammedov
@ 2024-02-28 11:11 ` Ani Sinha
2024-02-28 13:59 ` Igor Mammedov
2024-02-28 14:18 ` Ani Sinha
1 sibling, 1 reply; 54+ messages in thread
From: Ani Sinha @ 2024-02-28 11:11 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 27-Feb-2024, at 21:17, Igor Mammedov <imammedo@redhat.com> wrote:
>
> 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>
> ---
> 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 };
Ok so looking at the code, it won’t let you specify smbios type other than 1 …
See the following in smbios_set_defaults()
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 {
BUT you lets you load a blob of type 11? Is that a bug in QEMU? Should we also add a similar check for have_binfile_bitmap?
> + 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 [flat|nested] 54+ messages in thread
* Re: [PATCH 03/19] tests: smbios: add test for legacy mode CLI options
2024-02-28 11:11 ` Ani Sinha
@ 2024-02-28 13:59 ` Igor Mammedov
0 siblings, 0 replies; 54+ messages in thread
From: Igor Mammedov @ 2024-02-28 13:59 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, 28 Feb 2024 16:41:22 +0530
Ani Sinha <anisinha@redhat.com> wrote:
> > On 27-Feb-2024, at 21:17, Igor Mammedov <imammedo@redhat.com> wrote:
> >
> > 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>
> > ---
> > 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 };
>
> Ok so looking at the code, it won’t let you specify smbios type other than 1 …
>
> See the following in smbios_set_defaults()
>
> 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 {
>
> BUT you lets you load a blob of type 11? Is that a bug in QEMU? Should we also add a similar check for have_binfile_bitmap?
I'd say bug (oversight) in QEMU, actually some of patches later in series
mention this issue in commit messages.
And I'm adding check only for type4 which I have to touch
as for other types it might work (type11) or not.
But I have not tested every possible type (only type 11 and 4)
the former lets test bloated SMBIOS blob and the later
needs refactoring to make this series work..
Everything else was ignored for this series and
can be done later on top.
As mentioned later in series I'd rather deprecate and
drop all legacy code instead of fixing it.
These tests are mostly for me to be sure that existing
CLI handling and blob building aren't broken during
refactoring.
> > + 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 [flat|nested] 54+ messages in thread
* Re: [PATCH 03/19] tests: smbios: add test for legacy mode CLI options
2024-02-27 15:47 ` [PATCH 03/19] tests: smbios: add test for legacy mode CLI options Igor Mammedov
2024-02-28 11:11 ` Ani Sinha
@ 2024-02-28 14:18 ` Ani Sinha
1 sibling, 0 replies; 54+ messages in thread
From: Ani Sinha @ 2024-02-28 14:18 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 27-Feb-2024, at 21:17, Igor Mammedov <imammedo@redhat.com> wrote:
>
> 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>
> ---
> 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 [flat|nested] 54+ messages in thread
* [PATCH 04/19] smbios: cleanup smbios_get_tables() from legacy handling
2024-02-27 15:47 [PATCH 00/19] Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS Igor Mammedov
` (2 preceding siblings ...)
2024-02-27 15:47 ` [PATCH 03/19] tests: smbios: add test for legacy mode CLI options Igor Mammedov
@ 2024-02-27 15:47 ` Igor Mammedov
2024-02-28 11:27 ` Ani Sinha
2024-02-27 15:47 ` [PATCH 05/19] smbios: get rid of smbios_smp_sockets global Igor Mammedov
` (17 subsequent siblings)
21 siblings, 1 reply; 54+ messages in thread
From: Igor Mammedov @ 2024-02-27 15:47 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>
---
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] 54+ messages in thread
* Re: [PATCH 04/19] smbios: cleanup smbios_get_tables() from legacy handling
2024-02-27 15:47 ` [PATCH 04/19] smbios: cleanup smbios_get_tables() from legacy handling Igor Mammedov
@ 2024-02-28 11:27 ` Ani Sinha
0 siblings, 0 replies; 54+ messages in thread
From: Ani Sinha @ 2024-02-28 11: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 27-Feb-2024, at 21:17, Igor Mammedov <imammedo@redhat.com> wrote:
>
> 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>
> ---
> 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 [flat|nested] 54+ messages in thread
* [PATCH 05/19] smbios: get rid of smbios_smp_sockets global
2024-02-27 15:47 [PATCH 00/19] Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS Igor Mammedov
` (3 preceding siblings ...)
2024-02-27 15:47 ` [PATCH 04/19] smbios: cleanup smbios_get_tables() from legacy handling Igor Mammedov
@ 2024-02-27 15:47 ` Igor Mammedov
2024-02-29 7:51 ` Ani Sinha
2024-02-27 15:47 ` [PATCH 06/19] smbios: get rid of smbios_legacy global Igor Mammedov
` (16 subsequent siblings)
21 siblings, 1 reply; 54+ messages in thread
From: Igor Mammedov @ 2024-02-27 15:47 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>
---
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] 54+ messages in thread
* Re: [PATCH 05/19] smbios: get rid of smbios_smp_sockets global
2024-02-27 15:47 ` [PATCH 05/19] smbios: get rid of smbios_smp_sockets global Igor Mammedov
@ 2024-02-29 7:51 ` Ani Sinha
0 siblings, 0 replies; 54+ messages in thread
From: Ani Sinha @ 2024-02-29 7:51 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 27-Feb-2024, at 21:17, Igor Mammedov <imammedo@redhat.com> wrote:
>
> it makes smbios_validate_table() independent from
> smbios_smp_sockets global, which in turn lets
> smbios_get_tables() avoid using not related legacy code.
>
Good cleanup!
> Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Ani Sinha <anisinha@redhat.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 [flat|nested] 54+ messages in thread
* [PATCH 06/19] smbios: get rid of smbios_legacy global
2024-02-27 15:47 [PATCH 00/19] Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS Igor Mammedov
` (4 preceding siblings ...)
2024-02-27 15:47 ` [PATCH 05/19] smbios: get rid of smbios_smp_sockets global Igor Mammedov
@ 2024-02-27 15:47 ` Igor Mammedov
2024-02-29 10:53 ` Ani Sinha
2024-03-04 17:38 ` Daniel Henrique Barboza
2024-02-27 15:47 ` [PATCH 07/19] smbios: avoid mangling user provided tables Igor Mammedov
` (15 subsequent siblings)
21 siblings, 2 replies; 54+ messages in thread
From: Igor Mammedov @ 2024-02-27 15:47 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>
---
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 0ad7d8c887..73fb3522ba 100644
--- a/hw/loongarch/virt.c
+++ b/hw/loongarch/virt.c
@@ -320,7 +320,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] 54+ messages in thread
* Re: [PATCH 06/19] smbios: get rid of smbios_legacy global
2024-02-27 15:47 ` [PATCH 06/19] smbios: get rid of smbios_legacy global Igor Mammedov
@ 2024-02-29 10:53 ` Ani Sinha
2024-02-29 14:29 ` Igor Mammedov
2024-03-04 17:38 ` Daniel Henrique Barboza
1 sibling, 1 reply; 54+ messages in thread
From: Ani Sinha @ 2024-02-29 10:53 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 27-Feb-2024, at 21:17, Igor Mammedov <imammedo@redhat.com> wrote:
>
> 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>
> ---
> 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 0ad7d8c887..73fb3522ba 100644
> --- a/hw/loongarch/virt.c
> +++ b/hw/loongarch/virt.c
> @@ -320,7 +320,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;
> +
Can you please explain why you do this unconditionally without checking for legacy mode? Seems wrong?
> if (!smbios_immutable) {
> smbios_build_type_0_table();
> smbios_build_type_1_table();
> --
> 2.39.3
>
^ permalink raw reply [flat|nested] 54+ messages in thread
* Re: [PATCH 06/19] smbios: get rid of smbios_legacy global
2024-02-29 10:53 ` Ani Sinha
@ 2024-02-29 14:29 ` Igor Mammedov
2024-03-01 8:33 ` Ani Sinha
0 siblings, 1 reply; 54+ messages in thread
From: Igor Mammedov @ 2024-02-29 14:29 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, 29 Feb 2024 16:23:21 +0530
Ani Sinha <anisinha@redhat.com> wrote:
> > On 27-Feb-2024, at 21:17, Igor Mammedov <imammedo@redhat.com> wrote:
> >
> > 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>
> > ---
> > 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 0ad7d8c887..73fb3522ba 100644
> > --- a/hw/loongarch/virt.c
> > +++ b/hw/loongarch/virt.c
> > @@ -320,7 +320,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;
> > +
>
> Can you please explain why you do this unconditionally without checking for legacy mode? Seems wrong?
with this patch legacy tables build is moved to fw_cfg_build_smbios(),
however at this point QEMU still has option processing that fills
both new and legacy smbios_entries blobs.
this hunk cleanups not needed blob smbios_entries when building
modern tables, and smbios_get_table_legacy() has a corresponding
smbios_tables cleanup since modern is not needed there.
[7/19] removes this in favor of a single blob.
>
> > if (!smbios_immutable) {
> > smbios_build_type_0_table();
> > smbios_build_type_1_table();
> > --
> > 2.39.3
> >
>
^ permalink raw reply [flat|nested] 54+ messages in thread
* Re: [PATCH 06/19] smbios: get rid of smbios_legacy global
2024-02-29 14:29 ` Igor Mammedov
@ 2024-03-01 8:33 ` Ani Sinha
0 siblings, 0 replies; 54+ messages in thread
From: Ani Sinha @ 2024-03-01 8:33 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 29-Feb-2024, at 19:59, Igor Mammedov <imammedo@redhat.com> wrote:
>
> On Thu, 29 Feb 2024 16:23:21 +0530
> Ani Sinha <anisinha@redhat.com> wrote:
>
>>> On 27-Feb-2024, at 21:17, Igor Mammedov <imammedo@redhat.com> wrote:
>>>
>>> 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>
>>> ---
>>> 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 0ad7d8c887..73fb3522ba 100644
>>> --- a/hw/loongarch/virt.c
>>> +++ b/hw/loongarch/virt.c
>>> @@ -320,7 +320,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;
>>> +
>>
>> Can you please explain why you do this unconditionally without checking for legacy mode? Seems wrong?
>
> with this patch legacy tables build is moved to fw_cfg_build_smbios(),
> however at this point QEMU still has option processing that fills
> both new and legacy smbios_entries blobs.
>
> this hunk cleanups not needed blob smbios_entries when building
> modern tables, and smbios_get_table_legacy() has a corresponding
> smbios_tables cleanup since modern is not needed there.
Yes the naming is confusing! There is smbios_entries and then there is smbios_tables. The former is only for legacy as the comment above smbios_add_field() says.
>
> [7/19] removes this in favor of a single blob.
>
>>
>>> if (!smbios_immutable) {
>>> smbios_build_type_0_table();
>>> smbios_build_type_1_table();
>>> --
>>> 2.39.3
^ permalink raw reply [flat|nested] 54+ messages in thread
* Re: [PATCH 06/19] smbios: get rid of smbios_legacy global
2024-02-27 15:47 ` [PATCH 06/19] smbios: get rid of smbios_legacy global Igor Mammedov
2024-02-29 10:53 ` Ani Sinha
@ 2024-03-04 17:38 ` Daniel Henrique Barboza
1 sibling, 0 replies; 54+ messages in thread
From: Daniel Henrique Barboza @ 2024-03-04 17:38 UTC (permalink / raw)
To: Igor Mammedov, qemu-devel
Cc: peter.maydell, pbonzini, mst, gaosong, alistair.francis, palmer,
bin.meng, liwei1518, zhiwei_liu, anisinha, philmd, wangyanan55,
eblake, armbru, qemu-arm, qemu-riscv, f.ebner
On 2/27/24 12:47, Igor Mammedov wrote:
> 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>
> ---
For hw/riscv/virt.c changes:
Acked-by: Daniel Henrique Barboza <dbarboza@ventanamicro.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 0ad7d8c887..73fb3522ba 100644
> --- a/hw/loongarch/virt.c
> +++ b/hw/loongarch/virt.c
> @@ -320,7 +320,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();
^ permalink raw reply [flat|nested] 54+ messages in thread
* [PATCH 07/19] smbios: avoid mangling user provided tables
2024-02-27 15:47 [PATCH 00/19] Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS Igor Mammedov
` (5 preceding siblings ...)
2024-02-27 15:47 ` [PATCH 06/19] smbios: get rid of smbios_legacy global Igor Mammedov
@ 2024-02-27 15:47 ` Igor Mammedov
2024-03-04 9:55 ` Ani Sinha
2024-02-27 15:47 ` [PATCH 08/19] smbios: don't check type4 structures in legacy mode Igor Mammedov
` (14 subsequent siblings)
21 siblings, 1 reply; 54+ messages in thread
From: Igor Mammedov @ 2024-02-27 15:47 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>
---
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] 54+ messages in thread
* Re: [PATCH 07/19] smbios: avoid mangling user provided tables
2024-02-27 15:47 ` [PATCH 07/19] smbios: avoid mangling user provided tables Igor Mammedov
@ 2024-03-04 9:55 ` Ani Sinha
2024-03-04 14:17 ` Igor Mammedov
0 siblings, 1 reply; 54+ messages in thread
From: Ani Sinha @ 2024-03-04 9:55 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, 27 Feb 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.
>
This patch is very dense and even after taking several iterations through
it, I am not confident that I have not missed anything.
> Signed-off-by: Igor Mammedov <imammedo@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);
> + 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);
Why can't we do a memdup even for the legacy case instead of memcpy?
Secondly, here and other places we should check for NULL returns.
https://docs.gtk.org/glib/func.memdup2.html
return from memdup2 can be null.
> + 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] 54+ messages in thread
* Re: [PATCH 07/19] smbios: avoid mangling user provided tables
2024-03-04 9:55 ` Ani Sinha
@ 2024-03-04 14:17 ` Igor Mammedov
0 siblings, 0 replies; 54+ messages in thread
From: Igor Mammedov @ 2024-03-04 14:17 UTC (permalink / raw)
To: Ani Sinha
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 Mon, 4 Mar 2024 15:25:11 +0530 (IST)
Ani Sinha <anisinha@redhat.com> wrote:
> On Tue, 27 Feb 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.
> >
>
> This patch is very dense and even after taking several iterations through
> it, I am not confident that I have not missed anything.
it's shortest variant, I've came up with and still keeping it
as an atomic change.
Potentially I can split off removal of smbios_immutable to reduce
context changes (shift to left due to removal of 'if') but then
it wont's be a single step anymore and won't really help much.
> > Signed-off-by: Igor Mammedov <imammedo@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);
> > + usr_offset += size;
[...]
>
> Why can't we do a memdup even for the legacy case instead of memcpy?
because legacy entries have different structure,
see above or corresponding code that removes original handling at comment
" add a copy of the newly loaded blob to legacy smbios_entries"
> Secondly, here and other places we should check for NULL returns.
> https://docs.gtk.org/glib/func.memdup2.html
> return from memdup2 can be null.
all SMBIOS code is pestered with unchecked allocations,
so I followed the same style for consistency.
A patch on top can address that in consistent manner
cleaning up all places. Doing cleanup is out of scope
of this series (it's already too big as it is).
In this case I can add assert() on respin if you insist.
>
>
> > + 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] 54+ messages in thread
* [PATCH 08/19] smbios: don't check type4 structures in legacy mode
2024-02-27 15:47 [PATCH 00/19] Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS Igor Mammedov
` (6 preceding siblings ...)
2024-02-27 15:47 ` [PATCH 07/19] smbios: avoid mangling user provided tables Igor Mammedov
@ 2024-02-27 15:47 ` Igor Mammedov
2024-03-04 7:16 ` Ani Sinha
2024-02-27 15:47 ` [PATCH 09/19] smbios: build legacy mode code only for 'pc' machine Igor Mammedov
` (13 subsequent siblings)
21 siblings, 1 reply; 54+ messages in thread
From: Igor Mammedov @ 2024-02-27 15:47 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>
---
* 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] 54+ messages in thread
* Re: [PATCH 08/19] smbios: don't check type4 structures in legacy mode
2024-02-27 15:47 ` [PATCH 08/19] smbios: don't check type4 structures in legacy mode Igor Mammedov
@ 2024-03-04 7:16 ` Ani Sinha
0 siblings, 0 replies; 54+ messages in thread
From: Ani Sinha @ 2024-03-04 7:16 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, 27 Feb 2024, Igor Mammedov wrote:
> 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>
> ---
> * 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 [flat|nested] 54+ messages in thread
* [PATCH 09/19] smbios: build legacy mode code only for 'pc' machine
2024-02-27 15:47 [PATCH 00/19] Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS Igor Mammedov
` (7 preceding siblings ...)
2024-02-27 15:47 ` [PATCH 08/19] smbios: don't check type4 structures in legacy mode Igor Mammedov
@ 2024-02-27 15:47 ` Igor Mammedov
2024-03-04 10:55 ` Ani Sinha
2024-02-27 15:47 ` [PATCH 10/19] smbios: handle errors consistently Igor Mammedov
` (12 subsequent siblings)
21 siblings, 1 reply; 54+ messages in thread
From: Igor Mammedov @ 2024-02-27 15:47 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>
---
include/hw/firmware/smbios.h | 22 +++
hw/i386/Kconfig | 1 +
hw/smbios/Kconfig | 2 +
hw/smbios/meson.build | 4 +
hw/smbios/smbios.c | 251 ++++++---------------------------
hw/smbios/smbios_legacy.c | 179 +++++++++++++++++++++++
hw/smbios/smbios_legacy_stub.c | 16 +++
7 files changed, 270 insertions(+), 205 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 1fbff3c55f..a6d8fd6591 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,27 @@
*
*/
+extern uint8_t *usr_blobs;
+extern GArray *usr_blobs_sizes;
+
+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))
@@ -290,6 +310,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 97cf762228..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;
@@ -78,19 +52,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);
-
-static struct {
- const char *vendor, *version, *date;
- bool have_major_minor, uefi;
- uint8_t major, minor;
-} type0;
+DECLARE_BITMAP(smbios_have_binfile_bitmap, SMBIOS_MAX_TYPE + 1);
+DECLARE_BITMAP(smbios_have_fields_bitmap, SMBIOS_MAX_TYPE + 1);
-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;
@@ -491,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) {
@@ -501,140 +467,12 @@ 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),
- type0.vendor);
- smbios_maybe_add_str(0, offsetof(struct smbios_type_0, bios_version_str),
- type0.version);
- smbios_maybe_add_str(0, offsetof(struct smbios_type_0,
- bios_release_date_str),
- type0.date);
- if (type0.have_major_minor) {
- smbios_add_field(0, offsetof(struct smbios_type_0,
- system_bios_major_release),
- &type0.major, 1);
- smbios_add_field(0, offsetof(struct smbios_type_0,
- system_bios_minor_release),
- &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_maybe_add_str(1, offsetof(struct smbios_type_1, product_name_str),
- type1.product);
- smbios_maybe_add_str(1, offsetof(struct smbios_type_1, version_str),
- type1.version);
- smbios_maybe_add_str(1, offsetof(struct smbios_type_1, serial_number_str),
- type1.serial);
- smbios_maybe_add_str(1, offsetof(struct smbios_type_1, sku_number_str),
- type1.sku);
- smbios_maybe_add_str(1, offsetof(struct smbios_type_1, family_str),
- 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(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)) {
- 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, 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 +499,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 +547,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 +893,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);
@@ -1321,23 +1159,25 @@ 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) {
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;
@@ -1356,41 +1196,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) {
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] 54+ messages in thread
* Re: [PATCH 09/19] smbios: build legacy mode code only for 'pc' machine
2024-02-27 15:47 ` [PATCH 09/19] smbios: build legacy mode code only for 'pc' machine Igor Mammedov
@ 2024-03-04 10:55 ` Ani Sinha
2024-03-04 14:23 ` Igor Mammedov
0 siblings, 1 reply; 54+ messages in thread
From: Ani Sinha @ 2024-03-04 10:55 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 27-Feb-2024, at 21:17, 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.
>
> Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> ---
> include/hw/firmware/smbios.h | 22 +++
> hw/i386/Kconfig | 1 +
> hw/smbios/Kconfig | 2 +
> hw/smbios/meson.build | 4 +
> hw/smbios/smbios.c | 251 ++++++---------------------------
> hw/smbios/smbios_legacy.c | 179 +++++++++++++++++++++++
> hw/smbios/smbios_legacy_stub.c | 16 +++
> 7 files changed, 270 insertions(+), 205 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 1fbff3c55f..a6d8fd6591 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,27 @@
> *
> */
>
> +extern uint8_t *usr_blobs;
> +extern GArray *usr_blobs_sizes;
> +
> +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))
>
> @@ -290,6 +310,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 97cf762228..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;
>
> @@ -78,19 +52,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);
> -
> -static struct {
> - const char *vendor, *version, *date;
> - bool have_major_minor, uefi;
> - uint8_t major, minor;
> -} type0;
> +DECLARE_BITMAP(smbios_have_binfile_bitmap, SMBIOS_MAX_TYPE + 1);
> +DECLARE_BITMAP(smbios_have_fields_bitmap, SMBIOS_MAX_TYPE + 1);
>
> -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;
> @@ -491,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) {
> @@ -501,140 +467,12 @@ 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),
> - type0.vendor);
> - smbios_maybe_add_str(0, offsetof(struct smbios_type_0, bios_version_str),
> - type0.version);
> - smbios_maybe_add_str(0, offsetof(struct smbios_type_0,
> - bios_release_date_str),
> - type0.date);
> - if (type0.have_major_minor) {
> - smbios_add_field(0, offsetof(struct smbios_type_0,
> - system_bios_major_release),
> - &type0.major, 1);
> - smbios_add_field(0, offsetof(struct smbios_type_0,
> - system_bios_minor_release),
> - &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_maybe_add_str(1, offsetof(struct smbios_type_1, product_name_str),
> - type1.product);
> - smbios_maybe_add_str(1, offsetof(struct smbios_type_1, version_str),
> - type1.version);
> - smbios_maybe_add_str(1, offsetof(struct smbios_type_1, serial_number_str),
> - type1.serial);
> - smbios_maybe_add_str(1, offsetof(struct smbios_type_1, sku_number_str),
> - type1.sku);
> - smbios_maybe_add_str(1, offsetof(struct smbios_type_1, family_str),
> - 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(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)) {
> - 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, 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 +499,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 +547,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 +893,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);
> @@ -1321,23 +1159,25 @@ 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) {
> 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);
> +
Could this have been made as a part of a separate patch? It is extremely hard to understand why you are doing this when it’s a part of a larger code refactoring/modularisation.
> usr_blobs_len += size;
> if (size > usr_table_max) {
> usr_table_max = size;
> @@ -1356,41 +1196,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) {
> 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] 54+ messages in thread
* Re: [PATCH 09/19] smbios: build legacy mode code only for 'pc' machine
2024-03-04 10:55 ` Ani Sinha
@ 2024-03-04 14:23 ` Igor Mammedov
2024-03-04 16:43 ` Igor Mammedov
0 siblings, 1 reply; 54+ messages in thread
From: Igor Mammedov @ 2024-03-04 14:23 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 Mon, 4 Mar 2024 16:25:03 +0530
Ani Sinha <anisinha@redhat.com> wrote:
> > On 27-Feb-2024, at 21:17, 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.
> >
> > Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> > ---
> > include/hw/firmware/smbios.h | 22 +++
> > hw/i386/Kconfig | 1 +
> > hw/smbios/Kconfig | 2 +
> > hw/smbios/meson.build | 4 +
> > hw/smbios/smbios.c | 251 ++++++---------------------------
> > hw/smbios/smbios_legacy.c | 179 +++++++++++++++++++++++
> > hw/smbios/smbios_legacy_stub.c | 16 +++
> > 7 files changed, 270 insertions(+), 205 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 1fbff3c55f..a6d8fd6591 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,27 @@
> > *
> > */
> >
> > +extern uint8_t *usr_blobs;
> > +extern GArray *usr_blobs_sizes;
> > +
> > +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))
> >
> > @@ -290,6 +310,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 97cf762228..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;
> >
> > @@ -78,19 +52,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);
> > -
> > -static struct {
> > - const char *vendor, *version, *date;
> > - bool have_major_minor, uefi;
> > - uint8_t major, minor;
> > -} type0;
> > +DECLARE_BITMAP(smbios_have_binfile_bitmap, SMBIOS_MAX_TYPE + 1);
> > +DECLARE_BITMAP(smbios_have_fields_bitmap, SMBIOS_MAX_TYPE + 1);
> >
> > -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;
> > @@ -491,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) {
> > @@ -501,140 +467,12 @@ 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),
> > - type0.vendor);
> > - smbios_maybe_add_str(0, offsetof(struct smbios_type_0, bios_version_str),
> > - type0.version);
> > - smbios_maybe_add_str(0, offsetof(struct smbios_type_0,
> > - bios_release_date_str),
> > - type0.date);
> > - if (type0.have_major_minor) {
> > - smbios_add_field(0, offsetof(struct smbios_type_0,
> > - system_bios_major_release),
> > - &type0.major, 1);
> > - smbios_add_field(0, offsetof(struct smbios_type_0,
> > - system_bios_minor_release),
> > - &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_maybe_add_str(1, offsetof(struct smbios_type_1, product_name_str),
> > - type1.product);
> > - smbios_maybe_add_str(1, offsetof(struct smbios_type_1, version_str),
> > - type1.version);
> > - smbios_maybe_add_str(1, offsetof(struct smbios_type_1, serial_number_str),
> > - type1.serial);
> > - smbios_maybe_add_str(1, offsetof(struct smbios_type_1, sku_number_str),
> > - type1.sku);
> > - smbios_maybe_add_str(1, offsetof(struct smbios_type_1, family_str),
> > - 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(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)) {
> > - 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, 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 +499,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 +547,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 +893,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);
> > @@ -1321,23 +1159,25 @@ 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) {
> > 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);
> > +
>
> Could this have been made as a part of a separate patch? It is extremely hard to understand why you are doing this when it’s a part of a larger code refactoring/modularisation.
sure, will do on respin
>
>
> > usr_blobs_len += size;
> > if (size > usr_table_max) {
> > usr_table_max = size;
> > @@ -1356,41 +1196,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) {
> > 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] 54+ messages in thread
* Re: [PATCH 09/19] smbios: build legacy mode code only for 'pc' machine
2024-03-04 14:23 ` Igor Mammedov
@ 2024-03-04 16:43 ` Igor Mammedov
0 siblings, 0 replies; 54+ messages in thread
From: Igor Mammedov @ 2024-03-04 16:43 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 Mon, 4 Mar 2024 15:23:00 +0100
Igor Mammedov <imammedo@redhat.com> wrote:
> On Mon, 4 Mar 2024 16:25:03 +0530
> Ani Sinha <anisinha@redhat.com> wrote:
>
> > > On 27-Feb-2024, at 21:17, 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.
> > >
> > > Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> > > ---
[...]
> > > + /*
> > > + * preserve blob size for legacy mode so it could build its
> > > + * blobs flavor from 'usr_blobs'
> > > + */
> > > + smbios_add_usr_blob_size(size);
> > > +
> >
> > Could this have been made as a part of a separate patch? It is extremely hard to understand why you are doing this when it’s a part of a larger code refactoring/modularisation.
>
> sure, will do on respin
I also has split out variables renaming into a separate patch.
Hope it will make it easier to review.
>
[...]
^ permalink raw reply [flat|nested] 54+ messages in thread
* [PATCH 10/19] smbios: handle errors consistently
2024-02-27 15:47 [PATCH 00/19] Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS Igor Mammedov
` (8 preceding siblings ...)
2024-02-27 15:47 ` [PATCH 09/19] smbios: build legacy mode code only for 'pc' machine Igor Mammedov
@ 2024-02-27 15:47 ` Igor Mammedov
2024-03-04 11:14 ` Ani Sinha
2024-02-27 15:47 ` [PATCH 11/19] smbios: clear smbios_tables pointer after freeing Igor Mammedov
` (11 subsequent siblings)
21 siblings, 1 reply; 54+ messages in thread
From: Igor Mammedov @ 2024-02-27 15:47 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.
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
include/hw/firmware/smbios.h | 4 ++--
hw/i386/fw_cfg.c | 3 ++-
hw/smbios/smbios.c | 32 ++++++++++++++++++++------------
hw/smbios/smbios_legacy.c | 22 ++++++++++++++--------
4 files changed, 38 insertions(+), 23 deletions(-)
diff --git a/include/hw/firmware/smbios.h b/include/hw/firmware/smbios.h
index a6d8fd6591..d1194c9cc2 100644
--- a/include/hw/firmware/smbios.h
+++ b/include/hw/firmware/smbios.h
@@ -310,7 +310,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);
@@ -318,7 +318,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..7c28b5f748 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,10 @@ void smbios_get_tables(MachineState *ms,
} else {
abort();
}
+
+ return;
+err_exit:
+ g_free(smbios_tables);
}
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] 54+ messages in thread
* Re: [PATCH 10/19] smbios: handle errors consistently
2024-02-27 15:47 ` [PATCH 10/19] smbios: handle errors consistently Igor Mammedov
@ 2024-03-04 11:14 ` Ani Sinha
2024-03-04 13:39 ` Igor Mammedov
0 siblings, 1 reply; 54+ messages in thread
From: Ani Sinha @ 2024-03-04 11:14 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, 27 Feb 2024, Igor Mammedov wrote:
> 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.
>
> Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Other than the nit below,
Reviewed-by: Ani Sinha <anisinha@redhat.com>
> ---
> include/hw/firmware/smbios.h | 4 ++--
> hw/i386/fw_cfg.c | 3 ++-
> hw/smbios/smbios.c | 32 ++++++++++++++++++++------------
> hw/smbios/smbios_legacy.c | 22 ++++++++++++++--------
> 4 files changed, 38 insertions(+), 23 deletions(-)
>
> diff --git a/include/hw/firmware/smbios.h b/include/hw/firmware/smbios.h
> index a6d8fd6591..d1194c9cc2 100644
> --- a/include/hw/firmware/smbios.h
> +++ b/include/hw/firmware/smbios.h
> @@ -310,7 +310,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);
> @@ -318,7 +318,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..7c28b5f748 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)) {
nit: I would do a gfree(smbios_tables) here ..
> + goto err_exit;
> + }
> + if (!smbios_validate_table(errp)) {
> + goto err_exit;
and here. Then in 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,10 @@ void smbios_get_tables(MachineState *ms,
> } else {
> abort();
> }
> +
> + return;
> +err_exit:
I would add a return here.
That way all paths explicitly return void.
> + g_free(smbios_tables);
No return here?
> }
>
> 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 [flat|nested] 54+ messages in thread
* Re: [PATCH 10/19] smbios: handle errors consistently
2024-03-04 11:14 ` Ani Sinha
@ 2024-03-04 13:39 ` Igor Mammedov
2024-03-04 13:53 ` Ani Sinha
0 siblings, 1 reply; 54+ messages in thread
From: Igor Mammedov @ 2024-03-04 13:39 UTC (permalink / raw)
To: Ani Sinha
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 Mon, 4 Mar 2024 16:44:34 +0530 (IST)
Ani Sinha <anisinha@redhat.com> wrote:
> On Tue, 27 Feb 2024, Igor Mammedov wrote:
>
> > 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.
> >
> > Signed-off-by: Igor Mammedov <imammedo@redhat.com>
>
> Other than the nit below,
>
> Reviewed-by: Ani Sinha <anisinha@redhat.com>
>
> > ---
> > include/hw/firmware/smbios.h | 4 ++--
> > hw/i386/fw_cfg.c | 3 ++-
> > hw/smbios/smbios.c | 32 ++++++++++++++++++++------------
> > hw/smbios/smbios_legacy.c | 22 ++++++++++++++--------
> > 4 files changed, 38 insertions(+), 23 deletions(-)
> >
> > diff --git a/include/hw/firmware/smbios.h b/include/hw/firmware/smbios.h
> > index a6d8fd6591..d1194c9cc2 100644
> > --- a/include/hw/firmware/smbios.h
> > +++ b/include/hw/firmware/smbios.h
> > @@ -310,7 +310,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);
> > @@ -318,7 +318,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..7c28b5f748 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)) {
>
> nit: I would do a gfree(smbios_tables) here ..
>
> > + goto err_exit;
> > + }
> > + if (!smbios_validate_table(errp)) {
> > + goto err_exit;
>
> and here. Then in err_exit ...
>
the whole point of err_exit is to do error patch clean up
in one place to avoid duplicate the work.
> > + }
> > 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,10 @@ void smbios_get_tables(MachineState *ms,
> > } else {
> > abort();
> > }
> > +
> > + return;
> > +err_exit:
>
> I would add a return here.
>
> That way all paths explicitly return void.
>
> > + g_free(smbios_tables);
>
> No return here?
technically there is no need for at the end,
but I can fix it up for clarity.
>
>
> > }
> >
> > 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 [flat|nested] 54+ messages in thread
* Re: [PATCH 10/19] smbios: handle errors consistently
2024-03-04 13:39 ` Igor Mammedov
@ 2024-03-04 13:53 ` Ani Sinha
0 siblings, 0 replies; 54+ messages in thread
From: Ani Sinha @ 2024-03-04 13:53 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 04-Mar-2024, at 19:09, Igor Mammedov <imammedo@redhat.com> wrote:
>
> On Mon, 4 Mar 2024 16:44:34 +0530 (IST)
> Ani Sinha <anisinha@redhat.com> wrote:
>
>> On Tue, 27 Feb 2024, Igor Mammedov wrote:
>>
>>> 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.
>>>
>>> Signed-off-by: Igor Mammedov <imammedo@redhat.com>
>>
>> Other than the nit below,
>>
>> Reviewed-by: Ani Sinha <anisinha@redhat.com>
>>
>>> ---
>>> include/hw/firmware/smbios.h | 4 ++--
>>> hw/i386/fw_cfg.c | 3 ++-
>>> hw/smbios/smbios.c | 32 ++++++++++++++++++++------------
>>> hw/smbios/smbios_legacy.c | 22 ++++++++++++++--------
>>> 4 files changed, 38 insertions(+), 23 deletions(-)
>>>
>>> diff --git a/include/hw/firmware/smbios.h b/include/hw/firmware/smbios.h
>>> index a6d8fd6591..d1194c9cc2 100644
>>> --- a/include/hw/firmware/smbios.h
>>> +++ b/include/hw/firmware/smbios.h
>>> @@ -310,7 +310,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);
>>> @@ -318,7 +318,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..7c28b5f748 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)) {
>>
>> nit: I would do a gfree(smbios_tables) here ..
>>
>>> + goto err_exit;
>>> + }
>>> + if (!smbios_validate_table(errp)) {
>>> + goto err_exit;
>>
>> and here. Then in err_exit ...
>>
>
> the whole point of err_exit is to do error patch clean up
> in one place to avoid duplicate the work.
>
>>> + }
>>> 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,10 @@ void smbios_get_tables(MachineState *ms,
>>> } else {
>>> abort();
>>> }
>>> +
>>> + return;
>>> +err_exit:
>>
>> I would add a return here.
>>
>> That way all paths explicitly return void.
>>
>>> + g_free(smbios_tables);
>>
>> No return here?
>
> technically there is no need for at the end,
> but I can fix it up for clarity.
I think you do that in patch 11. I suggest you can squash this one with patch 11 and I am happy then.
>
>>
>>
>>> }
>>>
>>> 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 [flat|nested] 54+ messages in thread
* [PATCH 11/19] smbios: clear smbios_tables pointer after freeing
2024-02-27 15:47 [PATCH 00/19] Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS Igor Mammedov
` (9 preceding siblings ...)
2024-02-27 15:47 ` [PATCH 10/19] smbios: handle errors consistently Igor Mammedov
@ 2024-02-27 15:47 ` Igor Mammedov
2024-03-04 13:54 ` Ani Sinha
2024-02-27 15:47 ` [PATCH 12/19] get rid of global smbios_ep_type Igor Mammedov
` (10 subsequent siblings)
21 siblings, 1 reply; 54+ messages in thread
From: Igor Mammedov @ 2024-02-27 15:47 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
that will avoid double free if smbios_get_tables() is called
multiple times.
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
hw/smbios/smbios.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c
index 7c28b5f748..d9ba2072b1 100644
--- a/hw/smbios/smbios.c
+++ b/hw/smbios/smbios.c
@@ -1052,6 +1052,8 @@ void smbios_get_tables(MachineState *ms,
return;
err_exit:
g_free(smbios_tables);
+ smbios_tables = NULL;
+ return;
}
static void save_opt(const char **dest, QemuOpts *opts, const char *name)
--
2.39.3
^ permalink raw reply related [flat|nested] 54+ messages in thread
* Re: [PATCH 11/19] smbios: clear smbios_tables pointer after freeing
2024-02-27 15:47 ` [PATCH 11/19] smbios: clear smbios_tables pointer after freeing Igor Mammedov
@ 2024-03-04 13:54 ` Ani Sinha
2024-03-04 14:25 ` Igor Mammedov
0 siblings, 1 reply; 54+ messages in thread
From: Ani Sinha @ 2024-03-04 13:54 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 27-Feb-2024, at 21:17, Igor Mammedov <imammedo@redhat.com> wrote:
>
> that will avoid double free if smbios_get_tables() is called
> multiple times.
>
> Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Maybe we can squash this with patch 10.
Other than that,
Reviewed-by: Ani Sinha <anisinha@redhat.com>
> ---
> hw/smbios/smbios.c | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c
> index 7c28b5f748..d9ba2072b1 100644
> --- a/hw/smbios/smbios.c
> +++ b/hw/smbios/smbios.c
> @@ -1052,6 +1052,8 @@ void smbios_get_tables(MachineState *ms,
> return;
> err_exit:
> g_free(smbios_tables);
> + smbios_tables = NULL;
> + return;
> }
>
> static void save_opt(const char **dest, QemuOpts *opts, const char *name)
> --
> 2.39.3
>
^ permalink raw reply [flat|nested] 54+ messages in thread
* Re: [PATCH 11/19] smbios: clear smbios_tables pointer after freeing
2024-03-04 13:54 ` Ani Sinha
@ 2024-03-04 14:25 ` Igor Mammedov
0 siblings, 0 replies; 54+ messages in thread
From: Igor Mammedov @ 2024-03-04 14:25 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 Mon, 4 Mar 2024 19:24:06 +0530
Ani Sinha <anisinha@redhat.com> wrote:
> > On 27-Feb-2024, at 21:17, Igor Mammedov <imammedo@redhat.com> wrote:
> >
> > that will avoid double free if smbios_get_tables() is called
> > multiple times.
> >
> > Signed-off-by: Igor Mammedov <imammedo@redhat.com>
>
> Maybe we can squash this with patch 10.
Ok, I'll squash it into 10/19
> Other than that,
>
> Reviewed-by: Ani Sinha <anisinha@redhat.com>
>
> > ---
> > hw/smbios/smbios.c | 2 ++
> > 1 file changed, 2 insertions(+)
> >
> > diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c
> > index 7c28b5f748..d9ba2072b1 100644
> > --- a/hw/smbios/smbios.c
> > +++ b/hw/smbios/smbios.c
> > @@ -1052,6 +1052,8 @@ void smbios_get_tables(MachineState *ms,
> > return;
> > err_exit:
> > g_free(smbios_tables);
> > + smbios_tables = NULL;
> > + return;
> > }
> >
> > static void save_opt(const char **dest, QemuOpts *opts, const char *name)
> > --
> > 2.39.3
> >
>
^ permalink raw reply [flat|nested] 54+ messages in thread
* [PATCH 12/19] get rid of global smbios_ep_type
2024-02-27 15:47 [PATCH 00/19] Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS Igor Mammedov
` (10 preceding siblings ...)
2024-02-27 15:47 ` [PATCH 11/19] smbios: clear smbios_tables pointer after freeing Igor Mammedov
@ 2024-02-27 15:47 ` Igor Mammedov
2024-03-04 17:38 ` Daniel Henrique Barboza
2024-03-05 8:39 ` Ani Sinha
2024-02-27 15:47 ` [PATCH 13/19] smbios: extend smbios-entry-point-type with 'auto' value Igor Mammedov
` (9 subsequent siblings)
21 siblings, 2 replies; 54+ messages in thread
From: Igor Mammedov @ 2024-02-27 15:47 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>
---
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 d1194c9cc2..d59c2f5a13 100644
--- a/include/hw/firmware/smbios.h
+++ b/include/hw/firmware/smbios.h
@@ -310,16 +310,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 f8eb684a49..56562e7d9e 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -689,7 +689,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 73fb3522ba..d2ed15da75 100644
--- a/hw/loongarch/virt.c
+++ b/hw/loongarch/virt.c
@@ -320,10 +320,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] 54+ messages in thread
* Re: [PATCH 12/19] get rid of global smbios_ep_type
2024-02-27 15:47 ` [PATCH 12/19] get rid of global smbios_ep_type Igor Mammedov
@ 2024-03-04 17:38 ` Daniel Henrique Barboza
2024-03-05 8:39 ` Ani Sinha
1 sibling, 0 replies; 54+ messages in thread
From: Daniel Henrique Barboza @ 2024-03-04 17:38 UTC (permalink / raw)
To: Igor Mammedov, qemu-devel
Cc: peter.maydell, pbonzini, mst, gaosong, alistair.francis, palmer,
bin.meng, liwei1518, zhiwei_liu, anisinha, philmd, wangyanan55,
eblake, armbru, qemu-arm, qemu-riscv, f.ebner
On 2/27/24 12:47, Igor Mammedov wrote:
> Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> ---
For hw/riscv/virt.c changes:
Acked-by: Daniel Henrique Barboza <dbarboza@ventanamicro.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 d1194c9cc2..d59c2f5a13 100644
> --- a/include/hw/firmware/smbios.h
> +++ b/include/hw/firmware/smbios.h
> @@ -310,16 +310,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 f8eb684a49..56562e7d9e 100644
> --- a/hw/i386/pc.c
> +++ b/hw/i386/pc.c
> @@ -689,7 +689,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 73fb3522ba..d2ed15da75 100644
> --- a/hw/loongarch/virt.c
> +++ b/hw/loongarch/virt.c
> @@ -320,10 +320,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;
> }
>
^ permalink raw reply [flat|nested] 54+ messages in thread
* Re: [PATCH 12/19] get rid of global smbios_ep_type
2024-02-27 15:47 ` [PATCH 12/19] get rid of global smbios_ep_type Igor Mammedov
2024-03-04 17:38 ` Daniel Henrique Barboza
@ 2024-03-05 8:39 ` Ani Sinha
1 sibling, 0 replies; 54+ messages in thread
From: Ani Sinha @ 2024-03-05 8:39 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
please add "smbios:" prefix just like your other patches in the commit
header.
On Tue, 27 Feb 2024, Igor Mammedov wrote:
> Signed-off-by: Igor Mammedov <imammedo@redhat.com>
I have not checked all the code paths for the changed function signatures
and left that instead for the compiler. Assuming the build is fine,
Reviewed-by: Ani Sinha <anisinha@redhat.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 d1194c9cc2..d59c2f5a13 100644
> --- a/include/hw/firmware/smbios.h
> +++ b/include/hw/firmware/smbios.h
> @@ -310,16 +310,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 f8eb684a49..56562e7d9e 100644
> --- a/hw/i386/pc.c
> +++ b/hw/i386/pc.c
> @@ -689,7 +689,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 73fb3522ba..d2ed15da75 100644
> --- a/hw/loongarch/virt.c
> +++ b/hw/loongarch/virt.c
> @@ -320,10 +320,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 [flat|nested] 54+ messages in thread
* [PATCH 13/19] smbios: extend smbios-entry-point-type with 'auto' value
2024-02-27 15:47 [PATCH 00/19] Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS Igor Mammedov
` (11 preceding siblings ...)
2024-02-27 15:47 ` [PATCH 12/19] get rid of global smbios_ep_type Igor Mammedov
@ 2024-02-27 15:47 ` Igor Mammedov
2024-02-27 17:00 ` Markus Armbruster
2024-03-05 9:15 ` Ani Sinha
2024-02-27 15:47 ` [PATCH 14/19] smbios: in case of entry point is 'auto' try to build v2 tables 1st Igor Mammedov
` (8 subsequent siblings)
21 siblings, 2 replies; 54+ messages in thread
From: Igor Mammedov @ 2024-02-27 15:47 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>
---
qapi/machine.json | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/qapi/machine.json b/qapi/machine.json
index 93b4677286..4c68528507 100644
--- a/qapi/machine.json
+++ b/qapi/machine.json
@@ -1802,10 +1802,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] 54+ messages in thread
* Re: [PATCH 13/19] smbios: extend smbios-entry-point-type with 'auto' value
2024-02-27 15:47 ` [PATCH 13/19] smbios: extend smbios-entry-point-type with 'auto' value Igor Mammedov
@ 2024-02-27 17:00 ` Markus Armbruster
2024-03-05 9:15 ` Ani Sinha
1 sibling, 0 replies; 54+ messages in thread
From: Markus Armbruster @ 2024-02-27 17:00 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>
> ---
> qapi/machine.json | 5 ++++-
> 1 file changed, 4 insertions(+), 1 deletion(-)
>
> diff --git a/qapi/machine.json b/qapi/machine.json
> index 93b4677286..4c68528507 100644
> --- a/qapi/machine.json
> +++ b/qapi/machine.json
> @@ -1802,10 +1802,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:
With that
Acked-by: Markus Armbruster <armbru@redhat.com>
^ permalink raw reply [flat|nested] 54+ messages in thread
* Re: [PATCH 13/19] smbios: extend smbios-entry-point-type with 'auto' value
2024-02-27 15:47 ` [PATCH 13/19] smbios: extend smbios-entry-point-type with 'auto' value Igor Mammedov
2024-02-27 17:00 ` Markus Armbruster
@ 2024-03-05 9:15 ` Ani Sinha
1 sibling, 0 replies; 54+ messages in thread
From: Ani Sinha @ 2024-03-05 9: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, 27 Feb 2024, Igor Mammedov wrote:
> later patches will use it to pick SMBIOS version at runtime
> depending on configuration.
>
> Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Ani Sinha <anisinha@redhat.com>
> ---
> qapi/machine.json | 5 ++++-
> 1 file changed, 4 insertions(+), 1 deletion(-)
>
> diff --git a/qapi/machine.json b/qapi/machine.json
> index 93b4677286..4c68528507 100644
> --- a/qapi/machine.json
> +++ b/qapi/machine.json
> @@ -1802,10 +1802,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 [flat|nested] 54+ messages in thread
* [PATCH 14/19] smbios: in case of entry point is 'auto' try to build v2 tables 1st
2024-02-27 15:47 [PATCH 00/19] Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS Igor Mammedov
` (12 preceding siblings ...)
2024-02-27 15:47 ` [PATCH 13/19] smbios: extend smbios-entry-point-type with 'auto' value Igor Mammedov
@ 2024-02-27 15:47 ` Igor Mammedov
2024-03-05 6:00 ` Ani Sinha
2024-02-27 15:47 ` [PATCH 15/19] smbios: error out when building type 4 table is not possible Igor Mammedov
` (7 subsequent siblings)
21 siblings, 1 reply; 54+ messages in thread
From: Igor Mammedov @ 2024-02-27 15:47 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>
---
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] 54+ messages in thread
* Re: [PATCH 14/19] smbios: in case of entry point is 'auto' try to build v2 tables 1st
2024-02-27 15:47 ` [PATCH 14/19] smbios: in case of entry point is 'auto' try to build v2 tables 1st Igor Mammedov
@ 2024-03-05 6:00 ` Ani Sinha
0 siblings, 0 replies; 54+ messages in thread
From: Ani Sinha @ 2024-03-05 6:00 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 27-Feb-2024, at 21:17, Igor Mammedov <imammedo@redhat.com> wrote:
>
> 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>
> ---
> 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 [flat|nested] 54+ messages in thread
* [PATCH 15/19] smbios: error out when building type 4 table is not possible
2024-02-27 15:47 [PATCH 00/19] Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS Igor Mammedov
` (13 preceding siblings ...)
2024-02-27 15:47 ` [PATCH 14/19] smbios: in case of entry point is 'auto' try to build v2 tables 1st Igor Mammedov
@ 2024-02-27 15:47 ` Igor Mammedov
2024-03-05 11:36 ` Ani Sinha
2024-02-27 15:47 ` [PATCH 16/19] smbios: clear smbios_type4_count before building tables Igor Mammedov
` (6 subsequent siblings)
21 siblings, 1 reply; 54+ messages in thread
From: Igor Mammedov @ 2024-02-27 15:47 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>
---
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] 54+ messages in thread
* Re: [PATCH 15/19] smbios: error out when building type 4 table is not possible
2024-02-27 15:47 ` [PATCH 15/19] smbios: error out when building type 4 table is not possible Igor Mammedov
@ 2024-03-05 11:36 ` Ani Sinha
0 siblings, 0 replies; 54+ messages in thread
From: Ani Sinha @ 2024-03-05 11:36 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 27-Feb-2024, at 21:17, Igor Mammedov <imammedo@redhat.com> wrote:
>
> 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>
> ---
> 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 [flat|nested] 54+ messages in thread
* [PATCH 16/19] smbios: clear smbios_type4_count before building tables
2024-02-27 15:47 [PATCH 00/19] Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS Igor Mammedov
` (14 preceding siblings ...)
2024-02-27 15:47 ` [PATCH 15/19] smbios: error out when building type 4 table is not possible Igor Mammedov
@ 2024-02-27 15:47 ` Igor Mammedov
2024-02-27 15:47 ` [PATCH 17/19] tests: acpi/smbios: whitelist expected blobs Igor Mammedov
` (5 subsequent siblings)
21 siblings, 0 replies; 54+ messages in thread
From: Igor Mammedov @ 2024-02-27 15:47 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>
---
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] 54+ messages in thread
* [PATCH 17/19] tests: acpi/smbios: whitelist expected blobs
2024-02-27 15:47 [PATCH 00/19] Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS Igor Mammedov
` (15 preceding siblings ...)
2024-02-27 15:47 ` [PATCH 16/19] smbios: clear smbios_type4_count before building tables Igor Mammedov
@ 2024-02-27 15:47 ` Igor Mammedov
2024-02-27 15:47 ` [PATCH 18/19] pc/q35: set SMBIOS entry point type to 'auto' by default Igor Mammedov
` (4 subsequent siblings)
21 siblings, 0 replies; 54+ messages in thread
From: Igor Mammedov @ 2024-02-27 15:47 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] 54+ messages in thread
* [PATCH 18/19] pc/q35: set SMBIOS entry point type to 'auto' by default
2024-02-27 15:47 [PATCH 00/19] Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS Igor Mammedov
` (16 preceding siblings ...)
2024-02-27 15:47 ` [PATCH 17/19] tests: acpi/smbios: whitelist expected blobs Igor Mammedov
@ 2024-02-27 15:47 ` Igor Mammedov
2024-03-05 12:21 ` Ani Sinha
2024-02-27 15:47 ` [PATCH 19/19] tests: acpi: update expected SSDT.dimmpxm blob Igor Mammedov
` (3 subsequent siblings)
21 siblings, 1 reply; 54+ messages in thread
From: Igor Mammedov @ 2024-02-27 15:47 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>
---
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 56562e7d9e..2f69dfd0a8 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1831,7 +1831,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 ec7c07b362..f9da942c55 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -535,12 +535,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 53fb3db26d..da3f92bea7 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -371,10 +371,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] 54+ messages in thread
* Re: [PATCH 18/19] pc/q35: set SMBIOS entry point type to 'auto' by default
2024-02-27 15:47 ` [PATCH 18/19] pc/q35: set SMBIOS entry point type to 'auto' by default Igor Mammedov
@ 2024-03-05 12:21 ` Ani Sinha
0 siblings, 0 replies; 54+ messages in thread
From: Ani Sinha @ 2024-03-05 12:21 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 27-Feb-2024, at 21:17, Igor Mammedov <imammedo@redhat.com> wrote:
>
> 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>
> ---
> 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 56562e7d9e..2f69dfd0a8 100644
> --- a/hw/i386/pc.c
> +++ b/hw/i386/pc.c
> @@ -1831,7 +1831,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 ec7c07b362..f9da942c55 100644
> --- a/hw/i386/pc_piix.c
> +++ b/hw/i386/pc_piix.c
> @@ -535,12 +535,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 53fb3db26d..da3f92bea7 100644
> --- a/hw/i386/pc_q35.c
> +++ b/hw/i386/pc_q35.c
> @@ -371,10 +371,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 [flat|nested] 54+ messages in thread
* [PATCH 19/19] tests: acpi: update expected SSDT.dimmpxm blob
2024-02-27 15:47 [PATCH 00/19] Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS Igor Mammedov
` (17 preceding siblings ...)
2024-02-27 15:47 ` [PATCH 18/19] pc/q35: set SMBIOS entry point type to 'auto' by default Igor Mammedov
@ 2024-02-27 15:47 ` Igor Mammedov
2024-02-27 15:49 ` [PATCH 00/19] Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS Michael S. Tsirkin
` (2 subsequent siblings)
21 siblings, 0 replies; 54+ messages in thread
From: Igor Mammedov @ 2024-02-27 15:47 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] 54+ messages in thread
* Re: [PATCH 00/19] Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS
2024-02-27 15:47 [PATCH 00/19] Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS Igor Mammedov
` (18 preceding siblings ...)
2024-02-27 15:47 ` [PATCH 19/19] tests: acpi: update expected SSDT.dimmpxm blob Igor Mammedov
@ 2024-02-27 15:49 ` Michael S. Tsirkin
2024-02-29 13:18 ` Fiona Ebner
2024-03-05 10:08 ` Michael S. Tsirkin
21 siblings, 0 replies; 54+ messages in thread
From: Michael S. Tsirkin @ 2024-02-27 15:49 UTC (permalink / raw)
To: Igor Mammedov
Cc: qemu-devel, peter.maydell, pbonzini, gaosong, alistair.francis,
palmer, bin.meng, liwei1518, dbarboza, zhiwei_liu, anisinha,
philmd, wangyanan55, eblake, armbru, qemu-arm, qemu-riscv,
f.ebner
On Tue, Feb 27, 2024 at 04:47:30PM +0100, Igor Mammedov wrote:
> 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).
Sounds like the best we can do.
> 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 (19):
> 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: build legacy mode code only for 'pc' machine
> smbios: handle errors consistently
> smbios: clear smbios_tables pointer after freeing
> 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 | 29 +-
> 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, 535 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] 54+ messages in thread
* Re: [PATCH 00/19] Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS
2024-02-27 15:47 [PATCH 00/19] Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS Igor Mammedov
` (19 preceding siblings ...)
2024-02-27 15:49 ` [PATCH 00/19] Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS Michael S. Tsirkin
@ 2024-02-29 13:18 ` Fiona Ebner
2024-03-01 13:55 ` Fiona Ebner
2024-03-05 10:08 ` Michael S. Tsirkin
21 siblings, 1 reply; 54+ messages in thread
From: Fiona Ebner @ 2024-02-29 13:18 UTC (permalink / raw)
To: Igor Mammedov, qemu-devel
Cc: peter.maydell, pbonzini, mst, gaosong, alistair.francis, palmer,
bin.meng, liwei1518, dbarboza, zhiwei_liu, anisinha, philmd,
wangyanan55, eblake, armbru, qemu-arm, qemu-riscv
Am 27.02.24 um 16:47 schrieb Igor Mammedov:
> 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
Thank you! I'm happy to confirm that this series works around the issue :)
Best Regards,
Fiona
^ permalink raw reply [flat|nested] 54+ messages in thread
* Re: [PATCH 00/19] Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS
2024-02-29 13:18 ` Fiona Ebner
@ 2024-03-01 13:55 ` Fiona Ebner
0 siblings, 0 replies; 54+ messages in thread
From: Fiona Ebner @ 2024-03-01 13:55 UTC (permalink / raw)
To: Igor Mammedov, qemu-devel
Cc: peter.maydell, pbonzini, mst, gaosong, alistair.francis, palmer,
bin.meng, liwei1518, dbarboza, zhiwei_liu, anisinha, philmd,
wangyanan55, eblake, armbru, qemu-arm, qemu-riscv
Am 29.02.24 um 14:18 schrieb Fiona Ebner:
> Am 27.02.24 um 16:47 schrieb Igor Mammedov:
>> 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
>
> Thank you! I'm happy to confirm that this series works around the issue :)
>
While I still didn't do any in-depth testing (don't have enough
knowledge for that anyways), I played around a bit more now, check that
nothing obvious breaks also with a Linux VM and also ran a successful
'make check'.
If that is enough, feel free to add:
Tested-by: Fiona Ebner <f.ebner@proxmox.com>
Best Regards,
Fiona
^ permalink raw reply [flat|nested] 54+ messages in thread
* Re: [PATCH 00/19] Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS
2024-02-27 15:47 [PATCH 00/19] Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS Igor Mammedov
` (20 preceding siblings ...)
2024-02-29 13:18 ` Fiona Ebner
@ 2024-03-05 10:08 ` Michael S. Tsirkin
2024-03-05 10:32 ` Igor Mammedov
21 siblings, 1 reply; 54+ messages in thread
From: Michael S. Tsirkin @ 2024-03-05 10:08 UTC (permalink / raw)
To: Igor Mammedov
Cc: qemu-devel, peter.maydell, pbonzini, gaosong, alistair.francis,
palmer, bin.meng, liwei1518, dbarboza, zhiwei_liu, anisinha,
philmd, wangyanan55, eblake, armbru, qemu-arm, qemu-riscv,
f.ebner
On Tue, Feb 27, 2024 at 04:47:30PM +0100, Igor Mammedov wrote:
> 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).
Igor so you want to repost a version with a couple of patches squashed?
> 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 (19):
> 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: build legacy mode code only for 'pc' machine
> smbios: handle errors consistently
> smbios: clear smbios_tables pointer after freeing
> 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 | 29 +-
> 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, 535 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] 54+ messages in thread
* Re: [PATCH 00/19] Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS
2024-03-05 10:08 ` Michael S. Tsirkin
@ 2024-03-05 10:32 ` Igor Mammedov
0 siblings, 0 replies; 54+ messages in thread
From: Igor Mammedov @ 2024-03-05 10:32 UTC (permalink / raw)
To: Michael S. Tsirkin
Cc: qemu-devel, peter.maydell, pbonzini, gaosong, alistair.francis,
palmer, bin.meng, liwei1518, dbarboza, zhiwei_liu, anisinha,
philmd, wangyanan55, eblake, armbru, qemu-arm, qemu-riscv,
f.ebner
On Tue, 5 Mar 2024 05:08:05 -0500
"Michael S. Tsirkin" <mst@redhat.com> wrote:
> On Tue, Feb 27, 2024 at 04:47:30PM +0100, Igor Mammedov wrote:
> > 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).
>
> Igor so you want to repost a version with a couple of patches squashed?
requested changes where in several patches
(style and making series easier to review),
I'll repost series with those changes today.
> > 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 (19):
> > 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: build legacy mode code only for 'pc' machine
> > smbios: handle errors consistently
> > smbios: clear smbios_tables pointer after freeing
> > 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 | 29 +-
> > 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, 535 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] 54+ messages in thread