qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 11/20] smbios: build legacy mode code only for 'pc' machine
  2024-03-05 15:57 [PATCH v2 11/20] smbios: build legacy mode code only for 'pc' machine Igor Mammedov
@ 2024-03-06 10:03 ` Igor Mammedov
  0 siblings, 0 replies; 27+ messages in thread
From: Igor Mammedov @ 2024-03-06 10:03 UTC (permalink / raw)
  To: qemu-devel; +Cc: mst, anisinha

basically moving code around without functional change.
And exposing some symbols so that they could be shared
between smbbios.c and new smbios_legacy.c

plus some meson magic to build smbios_legacy.c only
for 'pc' machine and otherwise replace it with stub
if not selected.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Ani Sinha <anisinha@redhat.com>
---
v2:
  moved type0/type1/have_binfile_bitmap/have_fields_bitmap rename into
  a separate patch
v3:
  drop blank space at the end of hw/smbios/smbios_legacy_stub.c
---
 include/hw/firmware/smbios.h   |   5 +
 hw/i386/Kconfig                |   1 +
 hw/smbios/Kconfig              |   2 +
 hw/smbios/meson.build          |   4 +
 hw/smbios/smbios.c             | 164 +-----------------------------
 hw/smbios/smbios_legacy.c      | 179 +++++++++++++++++++++++++++++++++
 hw/smbios/smbios_legacy_stub.c |  15 +++
 7 files changed, 207 insertions(+), 163 deletions(-)
 create mode 100644 hw/smbios/smbios_legacy.c
 create mode 100644 hw/smbios/smbios_legacy_stub.c

diff --git a/include/hw/firmware/smbios.h b/include/hw/firmware/smbios.h
index bea5c3f1b1..7f47475aa4 100644
--- a/include/hw/firmware/smbios.h
+++ b/include/hw/firmware/smbios.h
@@ -17,6 +17,9 @@
  *
  */
 
+extern uint8_t *usr_blobs;
+extern GArray *usr_blobs_sizes;
+
 typedef struct {
     const char *vendor, *version, *date;
     bool have_major_minor, uefi;
@@ -306,6 +309,8 @@ struct smbios_type_127 {
     struct smbios_structure_header header;
 } QEMU_PACKED;
 
+void smbios_validate_table(void);
+void smbios_add_usr_blob_size(size_t size);
 void smbios_entry_add(QemuOpts *opts, Error **errp);
 void smbios_set_cpuid(uint32_t version, uint32_t features);
 void smbios_set_defaults(const char *manufacturer, const char *product,
diff --git a/hw/i386/Kconfig b/hw/i386/Kconfig
index a1846be6f7..a6ee052f9a 100644
--- a/hw/i386/Kconfig
+++ b/hw/i386/Kconfig
@@ -76,6 +76,7 @@ config I440FX
     select PIIX
     select DIMM
     select SMBIOS
+    select SMBIOS_LEGACY
     select FW_CFG_DMA
 
 config ISAPC
diff --git a/hw/smbios/Kconfig b/hw/smbios/Kconfig
index 553adf4bfc..8d989a2f1b 100644
--- a/hw/smbios/Kconfig
+++ b/hw/smbios/Kconfig
@@ -1,2 +1,4 @@
 config SMBIOS
     bool
+config SMBIOS_LEGACY
+    bool
diff --git a/hw/smbios/meson.build b/hw/smbios/meson.build
index 7046967462..a59039f669 100644
--- a/hw/smbios/meson.build
+++ b/hw/smbios/meson.build
@@ -4,5 +4,9 @@ smbios_ss.add(when: 'CONFIG_IPMI',
               if_true: files('smbios_type_38.c'),
               if_false: files('smbios_type_38-stub.c'))
 
+smbios_ss.add(when: 'CONFIG_SMBIOS_LEGACY',
+              if_true: files('smbios_legacy.c'),
+              if_false: files('smbios_legacy_stub.c'))
+
 system_ss.add_all(when: 'CONFIG_SMBIOS', if_true: smbios_ss)
 system_ss.add(when: 'CONFIG_SMBIOS', if_false: files('smbios-stub.c'))
diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c
index 86cf66b5ce..fb1f05fcde 100644
--- a/hw/smbios/smbios.c
+++ b/hw/smbios/smbios.c
@@ -31,38 +31,12 @@
 #include "hw/pci/pci_device.h"
 #include "smbios_build.h"
 
-/* legacy structures and constants for <= 2.0 machines */
-struct smbios_header {
-    uint16_t length;
-    uint8_t type;
-} QEMU_PACKED;
-
-struct smbios_field {
-    struct smbios_header header;
-    uint8_t type;
-    uint16_t offset;
-    uint8_t data[];
-} QEMU_PACKED;
-
-struct smbios_table {
-    struct smbios_header header;
-    uint8_t data[];
-} QEMU_PACKED;
-
-#define SMBIOS_FIELD_ENTRY 0
-#define SMBIOS_TABLE_ENTRY 1
-
-static uint8_t *smbios_entries;
-static size_t smbios_entries_len;
 static bool smbios_uuid_encoded = true;
-/* end: legacy structures & constants for <= 2.0 machines */
-
 /*
  * SMBIOS tables provided by user with '-smbios file=<foo>' option
  */
 uint8_t *usr_blobs;
 size_t usr_blobs_len;
-static GArray *usr_blobs_sizes;
 static unsigned usr_table_max;
 static unsigned usr_table_cnt;
 
@@ -483,7 +457,7 @@ static void smbios_check_type4_count(uint32_t expected_t4_count)
     }
 }
 
-static void smbios_validate_table(void)
+void smbios_validate_table(void)
 {
     if (smbios_ep_type == SMBIOS_ENTRY_POINT_TYPE_32 &&
         smbios_tables_len > SMBIOS_21_MAX_TABLES_LEN) {
@@ -493,134 +467,6 @@ static void smbios_validate_table(void)
     }
 }
 
-
-/* legacy setup functions for <= 2.0 machines */
-static void smbios_add_field(int type, int offset, const void *data, size_t len)
-{
-    struct smbios_field *field;
-
-    if (!smbios_entries) {
-        smbios_entries_len = sizeof(uint16_t);
-        smbios_entries = g_malloc0(smbios_entries_len);
-    }
-    smbios_entries = g_realloc(smbios_entries, smbios_entries_len +
-                                                  sizeof(*field) + len);
-    field = (struct smbios_field *)(smbios_entries + smbios_entries_len);
-    field->header.type = SMBIOS_FIELD_ENTRY;
-    field->header.length = cpu_to_le16(sizeof(*field) + len);
-
-    field->type = type;
-    field->offset = cpu_to_le16(offset);
-    memcpy(field->data, data, len);
-
-    smbios_entries_len += sizeof(*field) + len;
-    (*(uint16_t *)smbios_entries) =
-            cpu_to_le16(le16_to_cpu(*(uint16_t *)smbios_entries) + 1);
-}
-
-static void smbios_maybe_add_str(int type, int offset, const char *data)
-{
-    if (data) {
-        smbios_add_field(type, offset, data, strlen(data) + 1);
-    }
-}
-
-static void smbios_build_type_0_fields(void)
-{
-    smbios_maybe_add_str(0, offsetof(struct smbios_type_0, vendor_str),
-                         smbios_type0.vendor);
-    smbios_maybe_add_str(0, offsetof(struct smbios_type_0, bios_version_str),
-                         smbios_type0.version);
-    smbios_maybe_add_str(0, offsetof(struct smbios_type_0,
-                                     bios_release_date_str),
-                         smbios_type0.date);
-    if (smbios_type0.have_major_minor) {
-        smbios_add_field(0, offsetof(struct smbios_type_0,
-                                     system_bios_major_release),
-                         &smbios_type0.major, 1);
-        smbios_add_field(0, offsetof(struct smbios_type_0,
-                                     system_bios_minor_release),
-                         &smbios_type0.minor, 1);
-    }
-}
-
-static void smbios_build_type_1_fields(void)
-{
-    smbios_maybe_add_str(1, offsetof(struct smbios_type_1, manufacturer_str),
-                         smbios_type1.manufacturer);
-    smbios_maybe_add_str(1, offsetof(struct smbios_type_1, product_name_str),
-                         smbios_type1.product);
-    smbios_maybe_add_str(1, offsetof(struct smbios_type_1, version_str),
-                         smbios_type1.version);
-    smbios_maybe_add_str(1, offsetof(struct smbios_type_1, serial_number_str),
-                         smbios_type1.serial);
-    smbios_maybe_add_str(1, offsetof(struct smbios_type_1, sku_number_str),
-                         smbios_type1.sku);
-    smbios_maybe_add_str(1, offsetof(struct smbios_type_1, family_str),
-                         smbios_type1.family);
-    if (qemu_uuid_set) {
-        /* We don't encode the UUID in the "wire format" here because this
-         * function is for legacy mode and needs to keep the guest ABI, and
-         * because we don't know what's the SMBIOS version advertised by the
-         * BIOS.
-         */
-        smbios_add_field(1, offsetof(struct smbios_type_1, uuid),
-                         &qemu_uuid, 16);
-    }
-}
-
-uint8_t *smbios_get_table_legacy(size_t *length)
-{
-    int i;
-    size_t usr_offset;
-
-    /* also complain if fields were given for types > 1 */
-    if (find_next_bit(smbios_have_fields_bitmap,
-                      SMBIOS_MAX_TYPE + 1, 2) < SMBIOS_MAX_TYPE + 1) {
-        error_report("can't process fields for smbios "
-                     "types > 1 on machine versions < 2.1!");
-        exit(1);
-    }
-
-    if (test_bit(4, smbios_have_binfile_bitmap)) {
-        error_report("can't process table for smbios "
-                     "type 4 on machine versions < 2.1!");
-        exit(1);
-    }
-
-    g_free(smbios_entries);
-    smbios_entries_len = sizeof(uint16_t);
-    smbios_entries = g_malloc0(smbios_entries_len);
-
-    for (i = 0, usr_offset = 0; usr_blobs_sizes && i < usr_blobs_sizes->len;
-         i++)
-    {
-        struct smbios_table *table;
-        struct smbios_structure_header *header;
-        size_t size = g_array_index(usr_blobs_sizes, size_t, i);
-
-        header = (struct smbios_structure_header *)(usr_blobs + usr_offset);
-        smbios_entries = g_realloc(smbios_entries, smbios_entries_len +
-                                                   size + sizeof(*table));
-        table = (struct smbios_table *)(smbios_entries + smbios_entries_len);
-        table->header.type = SMBIOS_TABLE_ENTRY;
-        table->header.length = cpu_to_le16(sizeof(*table) + size);
-        memcpy(table->data, header, size);
-        smbios_entries_len += sizeof(*table) + size;
-        (*(uint16_t *)smbios_entries) =
-            cpu_to_le16(le16_to_cpu(*(uint16_t *)smbios_entries) + 1);
-        usr_offset += size;
-    }
-
-    smbios_build_type_0_fields();
-    smbios_build_type_1_fields();
-    smbios_validate_table();
-    *length = smbios_entries_len;
-    return smbios_entries;
-}
-/* end: legacy setup functions for <= 2.0 machines */
-
-
 bool smbios_skip_table(uint8_t type, bool required_table)
 {
     if (test_bit(type, smbios_have_binfile_bitmap)) {
@@ -1279,14 +1125,6 @@ static bool save_opt_list(size_t *ndest, char ***dest, QemuOpts *opts,
     return true;
 }
 
-static void smbios_add_usr_blob_size(size_t size)
-{
-    if (!usr_blobs_sizes) {
-        usr_blobs_sizes = g_array_new(false, false, sizeof(size_t));
-    }
-    g_array_append_val(usr_blobs_sizes, size);
-}
-
 void smbios_entry_add(QemuOpts *opts, Error **errp)
 {
     const char *val;
diff --git a/hw/smbios/smbios_legacy.c b/hw/smbios/smbios_legacy.c
new file mode 100644
index 0000000000..21f143e738
--- /dev/null
+++ b/hw/smbios/smbios_legacy.c
@@ -0,0 +1,179 @@
+/*
+ * SMBIOS legacy support
+ *
+ * Copyright (C) 2009 Hewlett-Packard Development Company, L.P.
+ * Copyright (C) 2013 Red Hat, Inc.
+ *
+ * Authors:
+ *  Alex Williamson <alex.williamson@hp.com>
+ *  Markus Armbruster <armbru@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.  See
+ * the COPYING file in the top-level directory.
+ *
+ * Contributions after 2012-01-13 are licensed under the terms of the
+ * GNU GPL, version 2 or (at your option) any later version.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/bswap.h"
+#include "hw/firmware/smbios.h"
+#include "sysemu/sysemu.h"
+#include "qemu/error-report.h"
+
+struct smbios_header {
+    uint16_t length;
+    uint8_t type;
+} QEMU_PACKED;
+
+struct smbios_field {
+    struct smbios_header header;
+    uint8_t type;
+    uint16_t offset;
+    uint8_t data[];
+} QEMU_PACKED;
+
+struct smbios_table {
+    struct smbios_header header;
+    uint8_t data[];
+} QEMU_PACKED;
+
+#define SMBIOS_FIELD_ENTRY 0
+#define SMBIOS_TABLE_ENTRY 1
+
+static uint8_t *smbios_entries;
+static size_t smbios_entries_len;
+GArray *usr_blobs_sizes;
+
+void smbios_add_usr_blob_size(size_t size)
+{
+    if (!usr_blobs_sizes) {
+        usr_blobs_sizes = g_array_new(false, false, sizeof(size_t));
+    }
+    g_array_append_val(usr_blobs_sizes, size);
+}
+
+static void smbios_add_field(int type, int offset, const void *data, size_t len)
+{
+    struct smbios_field *field;
+
+    if (!smbios_entries) {
+        smbios_entries_len = sizeof(uint16_t);
+        smbios_entries = g_malloc0(smbios_entries_len);
+    }
+    smbios_entries = g_realloc(smbios_entries, smbios_entries_len +
+                                                  sizeof(*field) + len);
+    field = (struct smbios_field *)(smbios_entries + smbios_entries_len);
+    field->header.type = SMBIOS_FIELD_ENTRY;
+    field->header.length = cpu_to_le16(sizeof(*field) + len);
+
+    field->type = type;
+    field->offset = cpu_to_le16(offset);
+    memcpy(field->data, data, len);
+
+    smbios_entries_len += sizeof(*field) + len;
+    (*(uint16_t *)smbios_entries) =
+            cpu_to_le16(le16_to_cpu(*(uint16_t *)smbios_entries) + 1);
+}
+
+static void smbios_maybe_add_str(int type, int offset, const char *data)
+{
+    if (data) {
+        smbios_add_field(type, offset, data, strlen(data) + 1);
+    }
+}
+
+static void smbios_build_type_0_fields(void)
+{
+    smbios_maybe_add_str(0, offsetof(struct smbios_type_0, vendor_str),
+                         smbios_type0.vendor);
+    smbios_maybe_add_str(0, offsetof(struct smbios_type_0, bios_version_str),
+                         smbios_type0.version);
+    smbios_maybe_add_str(0, offsetof(struct smbios_type_0,
+                                     bios_release_date_str),
+                         smbios_type0.date);
+    if (smbios_type0.have_major_minor) {
+        smbios_add_field(0, offsetof(struct smbios_type_0,
+                                     system_bios_major_release),
+                         &smbios_type0.major, 1);
+        smbios_add_field(0, offsetof(struct smbios_type_0,
+                                     system_bios_minor_release),
+                         &smbios_type0.minor, 1);
+    }
+}
+
+static void smbios_build_type_1_fields(void)
+{
+    smbios_maybe_add_str(1, offsetof(struct smbios_type_1, manufacturer_str),
+                         smbios_type1.manufacturer);
+    smbios_maybe_add_str(1, offsetof(struct smbios_type_1, product_name_str),
+                         smbios_type1.product);
+    smbios_maybe_add_str(1, offsetof(struct smbios_type_1, version_str),
+                         smbios_type1.version);
+    smbios_maybe_add_str(1, offsetof(struct smbios_type_1, serial_number_str),
+                         smbios_type1.serial);
+    smbios_maybe_add_str(1, offsetof(struct smbios_type_1, sku_number_str),
+                         smbios_type1.sku);
+    smbios_maybe_add_str(1, offsetof(struct smbios_type_1, family_str),
+                         smbios_type1.family);
+    if (qemu_uuid_set) {
+        /*
+         * We don't encode the UUID in the "wire format" here because this
+         * function is for legacy mode and needs to keep the guest ABI, and
+         * because we don't know what's the SMBIOS version advertised by the
+         * BIOS.
+         */
+        smbios_add_field(1, offsetof(struct smbios_type_1, uuid),
+                         &qemu_uuid, 16);
+    }
+}
+
+uint8_t *smbios_get_table_legacy(size_t *length)
+{
+    int i;
+    size_t usr_offset;
+
+    /* complain if fields were given for types > 1 */
+    if (find_next_bit(smbios_have_fields_bitmap,
+                      SMBIOS_MAX_TYPE + 1, 2) < SMBIOS_MAX_TYPE + 1) {
+        error_report("can't process fields for smbios "
+                     "types > 1 on machine versions < 2.1!");
+        exit(1);
+    }
+
+    if (test_bit(4, smbios_have_binfile_bitmap)) {
+        error_report("can't process table for smbios "
+                     "type 4 on machine versions < 2.1!");
+        exit(1);
+    }
+
+    g_free(smbios_entries);
+    smbios_entries_len = sizeof(uint16_t);
+    smbios_entries = g_malloc0(smbios_entries_len);
+
+    for (i = 0, usr_offset = 0; usr_blobs_sizes && i < usr_blobs_sizes->len;
+         i++)
+    {
+        struct smbios_table *table;
+        struct smbios_structure_header *header;
+        size_t size = g_array_index(usr_blobs_sizes, size_t, i);
+
+        header = (struct smbios_structure_header *)(usr_blobs + usr_offset);
+        smbios_entries = g_realloc(smbios_entries, smbios_entries_len +
+                                                   size + sizeof(*table));
+        table = (struct smbios_table *)(smbios_entries + smbios_entries_len);
+        table->header.type = SMBIOS_TABLE_ENTRY;
+        table->header.length = cpu_to_le16(sizeof(*table) + size);
+        memcpy(table->data, header, size);
+        smbios_entries_len += sizeof(*table) + size;
+        (*(uint16_t *)smbios_entries) =
+            cpu_to_le16(le16_to_cpu(*(uint16_t *)smbios_entries) + 1);
+        usr_offset += size;
+    }
+
+    smbios_build_type_0_fields();
+    smbios_build_type_1_fields();
+    smbios_validate_table();
+    *length = smbios_entries_len;
+    return smbios_entries;
+}
diff --git a/hw/smbios/smbios_legacy_stub.c b/hw/smbios/smbios_legacy_stub.c
new file mode 100644
index 0000000000..f29b15316c
--- /dev/null
+++ b/hw/smbios/smbios_legacy_stub.c
@@ -0,0 +1,15 @@
+/*
+ * IPMI SMBIOS firmware handling
+ *
+ * Copyright (c) 2024 Igor Mammedov, Red Hat, Inc.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "hw/firmware/smbios.h"
+
+void smbios_add_usr_blob_size(size_t size)
+{
+}
-- 
2.39.3



^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v3 00/20] Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS
@ 2024-03-12 16:10 Igor Mammedov
  2024-03-12 16:10 ` [PATCH v3 01/20] tests: smbios: make it possible to write SMBIOS only test Igor Mammedov
                   ` (21 more replies)
  0 siblings, 22 replies; 27+ messages in thread
From: Igor Mammedov @ 2024-03-12 16:10 UTC (permalink / raw)
  To: qemu-devel; +Cc: imammedo, mst

Changelog:
 v3:
   * whitespace missed by checkpatch
   * fix idndent in QAPI
   * reorder 17/20 before 1st 'auto' can be used
   * pick up acks
 v2:
   * QAPI style fixes (Markus Armbruster <armbru@redhat.com>)
   * squash 11/19 into 10/19 (Ani Sinha <anisinha@redhat.com>)
   * split '[PATCH 09/19] smbios: build legacy mode code only for 'pc' machine'
     in 3 smaller patches, to make it more readable
       smbios: add smbios_add_usr_blob_size() helper                                  
       smbios: rename/expose structures/bitmaps used by both legacy and modern code                                                                  
       smbios: build legacy mode code only for 'pc' machine
   * pick up acks

Windows (10) bootloader when running on top of SeaBIOS, fails to find            
SMBIOSv3 entry point. Tracing it shows that it looks for v2 anchor markers       
only and not v3. Tricking it into believing that entry point is found            
lets Windows successfully locate and parse SMBIOSv3 tables. Whether it           
will be fixed on Windows side is not clear so here goes a workaround.            
                                                                                 
Idea is to try build v2 tables if QEMU configuration permits,                    
and fallback to v3 tables otherwise. That will mask Windows issue                
form majority of users.                                                          
However if VM configuration can't be described (typically large VMs)             
by v2 tables, QEMU will use SMBIOSv3 and Windows will hit the issue              
again. In this case complain to Microsoft and/or use UEFI instead of             
SeaBIOS (requires reinstall).                                                    
                                                                                 
Default compat setting of smbios-entry-point-type after series                   
for pc/q35 machines:                                                             
  * 9.0-newer: 'auto'                                                            
  * 8.1-8.2: '64'                                                                
  * 8.0-older: '32'                                                              
                                                                                 
Fixes: https://gitlab.com/qemu-project/qemu/-/issues/2008                        
CC: imammedo@redhat.com                                                          
CC: mst@redhat.com

Igor Mammedov (20):
  tests: smbios: make it possible to write SMBIOS only test
  tests: smbios: add test for -smbios type=11 option
  tests: smbios: add test for legacy mode CLI options
  smbios: cleanup smbios_get_tables() from legacy handling
  smbios: get rid of smbios_smp_sockets global
  smbios: get rid of smbios_legacy global
  smbios: avoid mangling user provided tables
  smbios: don't check type4 structures in legacy mode
  smbios: add smbios_add_usr_blob_size() helper
  smbios: rename/expose structures/bitmaps used by both legacy and
    modern code
  smbios: build legacy mode code only for 'pc' machine
  smbios: handle errors consistently
  smbios: get rid of global smbios_ep_type
  smbios: clear smbios_type4_count before building tables
  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
  tests: acpi/smbios: whitelist expected blobs
  pc/q35: set SMBIOS entry point type to 'auto' by default
  tests: acpi: update expected SSDT.dimmpxm blob

 hw/i386/fw_cfg.h                     |   3 +-
 include/hw/firmware/smbios.h         |  28 +-
 hw/arm/virt.c                        |   6 +-
 hw/i386/Kconfig                      |   1 +
 hw/i386/fw_cfg.c                     |  14 +-
 hw/i386/pc.c                         |   4 +-
 hw/i386/pc_piix.c                    |   4 +
 hw/i386/pc_q35.c                     |   3 +
 hw/loongarch/virt.c                  |   7 +-
 hw/riscv/virt.c                      |   6 +-
 hw/smbios/Kconfig                    |   2 +
 hw/smbios/meson.build                |   4 +
 hw/smbios/smbios.c                   | 481 +++++++++++----------------
 hw/smbios/smbios_legacy.c            | 185 +++++++++++
 hw/smbios/smbios_legacy_stub.c       |  15 +
 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, 533 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] 27+ messages in thread

* [PATCH v3 01/20] tests: smbios: make it possible to write SMBIOS only test
  2024-03-12 16:10 [PATCH v3 00/20] Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS Igor Mammedov
@ 2024-03-12 16:10 ` Igor Mammedov
  2024-03-12 16:10 ` [PATCH v3 02/20] tests: smbios: add test for -smbios type=11 option Igor Mammedov
                   ` (20 subsequent siblings)
  21 siblings, 0 replies; 27+ messages in thread
From: Igor Mammedov @ 2024-03-12 16:10 UTC (permalink / raw)
  To: qemu-devel; +Cc: imammedo, mst, Ani Sinha, Fiona Ebner

Cureently it not possible to run SMBIOS test without ACPI one,
which gets into the way when testing ACPI-less configs.

Extract SMBIOS testing into separate routines that could also
be run without ACPI dependency and use that for testing SMBIOS.

As the 1st user add "acpi/piix4/smbios-options" test case.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Ani Sinha <anisinha@redhat.com>
Tested-by: Fiona Ebner <f.ebner@proxmox.com>
---
 tests/qtest/bios-tables-test.c | 47 +++++++++++++++++++++++++++-------
 1 file changed, 38 insertions(+), 9 deletions(-)

diff --git a/tests/qtest/bios-tables-test.c b/tests/qtest/bios-tables-test.c
index 21811a1ab5..b2992bafa8 100644
--- a/tests/qtest/bios-tables-test.c
+++ b/tests/qtest/bios-tables-test.c
@@ -858,16 +858,8 @@ static void test_vm_prepare(const char *params, test_data *data)
     g_free(args);
 }
 
-static void process_acpi_tables_noexit(test_data *data)
+static void process_smbios_tables_noexit(test_data *data)
 {
-    test_acpi_load_tables(data);
-
-    if (getenv(ACPI_REBUILD_EXPECTED_AML)) {
-        dump_aml_files(data, true);
-    } else {
-        test_acpi_asl(data);
-    }
-
     /*
      * TODO: make SMBIOS tests work with UEFI firmware,
      * Bug on uefi-test-tools to provide entry point:
@@ -879,6 +871,27 @@ static void process_acpi_tables_noexit(test_data *data)
     }
 }
 
+static void test_smbios(const char *params, test_data *data)
+{
+    test_vm_prepare(params, data);
+    boot_sector_test(data->qts);
+    process_smbios_tables_noexit(data);
+    qtest_quit(data->qts);
+}
+
+static void process_acpi_tables_noexit(test_data *data)
+{
+    test_acpi_load_tables(data);
+
+    if (getenv(ACPI_REBUILD_EXPECTED_AML)) {
+        dump_aml_files(data, true);
+    } else {
+        test_acpi_asl(data);
+    }
+
+    process_smbios_tables_noexit(data);
+}
+
 static void process_acpi_tables(test_data *data)
 {
     process_acpi_tables_noexit(data);
@@ -2064,6 +2077,20 @@ static void test_acpi_q35_pvpanic_isa(void)
     free_test_data(&data);
 }
 
+static void test_acpi_pc_smbios_options(void)
+{
+    uint8_t req_type11[] = { 11 };
+    test_data data = {
+        .machine = MACHINE_PC,
+        .variant = ".pc_smbios_options",
+        .required_struct_types = req_type11,
+        .required_struct_types_len = ARRAY_SIZE(req_type11),
+    };
+
+    test_smbios("-smbios type=11,value=TEST", &data);
+    free_test_data(&data);
+}
+
 static void test_oem_fields(test_data *data)
 {
     int i;
@@ -2215,6 +2242,8 @@ int main(int argc, char *argv[])
 #ifdef CONFIG_POSIX
             qtest_add_func("acpi/piix4/acpierst", test_acpi_piix4_acpi_erst);
 #endif
+            qtest_add_func("acpi/piix4/smbios-options",
+                           test_acpi_pc_smbios_options);
         }
         if (qtest_has_machine(MACHINE_Q35)) {
             qtest_add_func("acpi/q35", test_acpi_q35_tcg);
-- 
2.39.3



^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v3 02/20] tests: smbios: add test for -smbios type=11 option
  2024-03-12 16:10 [PATCH v3 00/20] Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS Igor Mammedov
  2024-03-12 16:10 ` [PATCH v3 01/20] tests: smbios: make it possible to write SMBIOS only test Igor Mammedov
@ 2024-03-12 16:10 ` Igor Mammedov
  2024-03-12 16:10 ` [PATCH v3 03/20] tests: smbios: add test for legacy mode CLI options Igor Mammedov
                   ` (19 subsequent siblings)
  21 siblings, 0 replies; 27+ messages in thread
From: Igor Mammedov @ 2024-03-12 16:10 UTC (permalink / raw)
  To: qemu-devel; +Cc: imammedo, mst, Ani Sinha, Fiona Ebner

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Ani Sinha <anisinha@redhat.com>
Tested-by: Fiona Ebner <f.ebner@proxmox.com>
---
 tests/data/smbios/type11_blob  | Bin 0 -> 11 bytes
 tests/qtest/bios-tables-test.c |  17 +++++++++++++++++
 2 files changed, 17 insertions(+)
 create mode 100644 tests/data/smbios/type11_blob

diff --git a/tests/data/smbios/type11_blob b/tests/data/smbios/type11_blob
new file mode 100644
index 0000000000000000000000000000000000000000..1d8fea4b0c6f040a13ba99c3fad762538b795614
GIT binary patch
literal 11
Scmd;PW!S(N;u;*nzyJUX)&c?m

literal 0
HcmV?d00001

diff --git a/tests/qtest/bios-tables-test.c b/tests/qtest/bios-tables-test.c
index b2992bafa8..a116f88e1d 100644
--- a/tests/qtest/bios-tables-test.c
+++ b/tests/qtest/bios-tables-test.c
@@ -2091,6 +2091,21 @@ static void test_acpi_pc_smbios_options(void)
     free_test_data(&data);
 }
 
+static void test_acpi_pc_smbios_blob(void)
+{
+    uint8_t req_type11[] = { 11 };
+    test_data data = {
+        .machine = MACHINE_PC,
+        .variant = ".pc_smbios_blob",
+        .required_struct_types = req_type11,
+        .required_struct_types_len = ARRAY_SIZE(req_type11),
+    };
+
+    test_smbios("-machine smbios-entry-point-type=32 "
+                "-smbios file=tests/data/smbios/type11_blob", &data);
+    free_test_data(&data);
+}
+
 static void test_oem_fields(test_data *data)
 {
     int i;
@@ -2244,6 +2259,8 @@ int main(int argc, char *argv[])
 #endif
             qtest_add_func("acpi/piix4/smbios-options",
                            test_acpi_pc_smbios_options);
+            qtest_add_func("acpi/piix4/smbios-blob",
+                           test_acpi_pc_smbios_blob);
         }
         if (qtest_has_machine(MACHINE_Q35)) {
             qtest_add_func("acpi/q35", test_acpi_q35_tcg);
-- 
2.39.3



^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v3 03/20] tests: smbios: add test for legacy mode CLI options
  2024-03-12 16:10 [PATCH v3 00/20] Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS Igor Mammedov
  2024-03-12 16:10 ` [PATCH v3 01/20] tests: smbios: make it possible to write SMBIOS only test Igor Mammedov
  2024-03-12 16:10 ` [PATCH v3 02/20] tests: smbios: add test for -smbios type=11 option Igor Mammedov
@ 2024-03-12 16:10 ` Igor Mammedov
  2024-03-12 16:10 ` [PATCH v3 04/20] smbios: cleanup smbios_get_tables() from legacy handling Igor Mammedov
                   ` (18 subsequent siblings)
  21 siblings, 0 replies; 27+ messages in thread
From: Igor Mammedov @ 2024-03-12 16:10 UTC (permalink / raw)
  To: qemu-devel; +Cc: imammedo, mst, Ani Sinha, Fiona Ebner

Unfortunately having 2.0 machine type deprecated is not enough
to get rid of legacy SMBIOS handling since 'isapc' also uses
that and it's staying around.

Hence add test for CLI options handling to be sure that it
ain't broken during SMBIOS code refactoring.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Ani Sinha <anisinha@redhat.com>
Tested-by: Fiona Ebner <f.ebner@proxmox.com>
---
 tests/data/smbios/type11_blob.legacy | Bin 0 -> 10 bytes
 tests/qtest/bios-tables-test.c       |  17 +++++++++++++++++
 2 files changed, 17 insertions(+)
 create mode 100644 tests/data/smbios/type11_blob.legacy

diff --git a/tests/data/smbios/type11_blob.legacy b/tests/data/smbios/type11_blob.legacy
new file mode 100644
index 0000000000000000000000000000000000000000..aef463aab903405958b0a85f85c5980671c08bee
GIT binary patch
literal 10
Rcmd;PW!S(N;u;*n000Tp0s;U4

literal 0
HcmV?d00001

diff --git a/tests/qtest/bios-tables-test.c b/tests/qtest/bios-tables-test.c
index a116f88e1d..d1ff4db7a2 100644
--- a/tests/qtest/bios-tables-test.c
+++ b/tests/qtest/bios-tables-test.c
@@ -2106,6 +2106,21 @@ static void test_acpi_pc_smbios_blob(void)
     free_test_data(&data);
 }
 
+static void test_acpi_isapc_smbios_legacy(void)
+{
+    uint8_t req_type11[] = { 1, 11 };
+    test_data data = {
+        .machine = "isapc",
+        .variant = ".pc_smbios_legacy",
+        .required_struct_types = req_type11,
+        .required_struct_types_len = ARRAY_SIZE(req_type11),
+    };
+
+    test_smbios("-smbios file=tests/data/smbios/type11_blob.legacy "
+                "-smbios type=1,family=TEST", &data);
+    free_test_data(&data);
+}
+
 static void test_oem_fields(test_data *data)
 {
     int i;
@@ -2261,6 +2276,8 @@ int main(int argc, char *argv[])
                            test_acpi_pc_smbios_options);
             qtest_add_func("acpi/piix4/smbios-blob",
                            test_acpi_pc_smbios_blob);
+            qtest_add_func("acpi/piix4/smbios-legacy",
+                           test_acpi_isapc_smbios_legacy);
         }
         if (qtest_has_machine(MACHINE_Q35)) {
             qtest_add_func("acpi/q35", test_acpi_q35_tcg);
-- 
2.39.3



^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v3 04/20] smbios: cleanup smbios_get_tables() from legacy handling
  2024-03-12 16:10 [PATCH v3 00/20] Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS Igor Mammedov
                   ` (2 preceding siblings ...)
  2024-03-12 16:10 ` [PATCH v3 03/20] tests: smbios: add test for legacy mode CLI options Igor Mammedov
@ 2024-03-12 16:10 ` Igor Mammedov
  2024-03-12 16:10 ` [PATCH v3 05/20] smbios: get rid of smbios_smp_sockets global Igor Mammedov
                   ` (17 subsequent siblings)
  21 siblings, 0 replies; 27+ messages in thread
From: Igor Mammedov @ 2024-03-12 16:10 UTC (permalink / raw)
  To: qemu-devel; +Cc: imammedo, mst, Ani Sinha, Fiona Ebner

smbios_get_tables() bails out right away if leagacy mode is enabled
and won't generate any SMBIOS tables. At the same time x86 specific
fw_cfg_build_smbios() will genarate legacy tables and then proceed
to preparing temporary mem_array for useless call to
smbios_get_tables() and then discard it.

Drop legacy related check in smbios_get_tables() and return from
fw_cfg_build_smbios() early if legacy tables where built without
proceeding to non legacy part of the function.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Ani Sinha <anisinha@redhat.com>
Tested-by: Fiona Ebner <f.ebner@proxmox.com>
---
 hw/i386/fw_cfg.c   | 1 +
 hw/smbios/smbios.c | 6 ------
 2 files changed, 1 insertion(+), 6 deletions(-)

diff --git a/hw/i386/fw_cfg.c b/hw/i386/fw_cfg.c
index 98a478c276..a635234e68 100644
--- a/hw/i386/fw_cfg.c
+++ b/hw/i386/fw_cfg.c
@@ -74,6 +74,7 @@ void fw_cfg_build_smbios(PCMachineState *pcms, FWCfgState *fw_cfg)
     if (smbios_tables) {
         fw_cfg_add_bytes(fw_cfg, FW_CFG_SMBIOS_ENTRIES,
                          smbios_tables, smbios_tables_len);
+        return;
     }
 
     /* build the array of physical mem area from e820 table */
diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c
index a3c4e52ce9..8e86c62184 100644
--- a/hw/smbios/smbios.c
+++ b/hw/smbios/smbios.c
@@ -1106,12 +1106,6 @@ void smbios_get_tables(MachineState *ms,
 {
     unsigned i, dimm_cnt, offset;
 
-    if (smbios_legacy) {
-        *tables = *anchor = NULL;
-        *tables_len = *anchor_len = 0;
-        return;
-    }
-
     if (!smbios_immutable) {
         smbios_build_type_0_table();
         smbios_build_type_1_table();
-- 
2.39.3



^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v3 05/20] smbios: get rid of smbios_smp_sockets global
  2024-03-12 16:10 [PATCH v3 00/20] Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS Igor Mammedov
                   ` (3 preceding siblings ...)
  2024-03-12 16:10 ` [PATCH v3 04/20] smbios: cleanup smbios_get_tables() from legacy handling Igor Mammedov
@ 2024-03-12 16:10 ` Igor Mammedov
  2024-03-12 16:10 ` [PATCH v3 06/20] smbios: get rid of smbios_legacy global Igor Mammedov
                   ` (16 subsequent siblings)
  21 siblings, 0 replies; 27+ messages in thread
From: Igor Mammedov @ 2024-03-12 16:10 UTC (permalink / raw)
  To: qemu-devel; +Cc: imammedo, mst, Ani Sinha, Fiona Ebner

it makes smbios_validate_table() independent from
smbios_smp_sockets global, which in turn lets
smbios_get_tables() avoid using not related legacy code.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Ani Sinha <anisinha@redhat.com>
Tested-by: Fiona Ebner <f.ebner@proxmox.com>
---
goal here is to isolate legacy handling from generic smbios_get_tables()
---
 include/hw/firmware/smbios.h |  2 +-
 hw/i386/fw_cfg.c             |  2 +-
 hw/smbios/smbios.c           | 22 +++++++++-------------
 3 files changed, 11 insertions(+), 15 deletions(-)

diff --git a/include/hw/firmware/smbios.h b/include/hw/firmware/smbios.h
index 6e514982d4..a187fbbd3d 100644
--- a/include/hw/firmware/smbios.h
+++ b/include/hw/firmware/smbios.h
@@ -296,7 +296,7 @@ void smbios_set_defaults(const char *manufacturer, const char *product,
                          const char *version, bool legacy_mode,
                          bool uuid_encoded, SmbiosEntryPointType ep_type);
 void smbios_set_default_processor_family(uint16_t processor_family);
-uint8_t *smbios_get_table_legacy(MachineState *ms, size_t *length);
+uint8_t *smbios_get_table_legacy(uint32_t expected_t4_count, size_t *length);
 void smbios_get_tables(MachineState *ms,
                        const struct smbios_phys_mem_area *mem_array,
                        const unsigned int mem_array_size,
diff --git a/hw/i386/fw_cfg.c b/hw/i386/fw_cfg.c
index a635234e68..fcb4fb0769 100644
--- a/hw/i386/fw_cfg.c
+++ b/hw/i386/fw_cfg.c
@@ -70,7 +70,7 @@ void fw_cfg_build_smbios(PCMachineState *pcms, FWCfgState *fw_cfg)
     /* tell smbios about cpuid version and features */
     smbios_set_cpuid(cpu->env.cpuid_version, cpu->env.features[FEAT_1_EDX]);
 
-    smbios_tables = smbios_get_table_legacy(ms, &smbios_tables_len);
+    smbios_tables = smbios_get_table_legacy(ms->smp.cpus, &smbios_tables_len);
     if (smbios_tables) {
         fw_cfg_add_bytes(fw_cfg, FW_CFG_SMBIOS_ENTRIES,
                          smbios_tables, smbios_tables_len);
diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c
index 8e86c62184..15339d8dbe 100644
--- a/hw/smbios/smbios.c
+++ b/hw/smbios/smbios.c
@@ -70,7 +70,7 @@ static SmbiosEntryPoint ep;
 static int smbios_type4_count = 0;
 static bool smbios_immutable;
 static bool smbios_have_defaults;
-static uint32_t smbios_cpuid_version, smbios_cpuid_features, smbios_smp_sockets;
+static uint32_t smbios_cpuid_version, smbios_cpuid_features;
 
 static DECLARE_BITMAP(have_binfile_bitmap, SMBIOS_MAX_TYPE+1);
 static DECLARE_BITMAP(have_fields_bitmap, SMBIOS_MAX_TYPE+1);
@@ -476,14 +476,11 @@ opts_init(smbios_register_config);
  */
 #define SMBIOS_21_MAX_TABLES_LEN 0xffff
 
-static void smbios_validate_table(MachineState *ms)
+static void smbios_validate_table(uint32_t expected_t4_count)
 {
-    uint32_t expect_t4_count = smbios_legacy ?
-                                        ms->smp.cpus : smbios_smp_sockets;
-
-    if (smbios_type4_count && smbios_type4_count != expect_t4_count) {
+    if (smbios_type4_count && smbios_type4_count != expected_t4_count) {
         error_report("Expected %d SMBIOS Type 4 tables, got %d instead",
-                     expect_t4_count, smbios_type4_count);
+                     expected_t4_count, smbios_type4_count);
         exit(1);
     }
 
@@ -571,7 +568,7 @@ static void smbios_build_type_1_fields(void)
     }
 }
 
-uint8_t *smbios_get_table_legacy(MachineState *ms, size_t *length)
+uint8_t *smbios_get_table_legacy(uint32_t expected_t4_count, size_t *length)
 {
     if (!smbios_legacy) {
         *length = 0;
@@ -581,7 +578,7 @@ uint8_t *smbios_get_table_legacy(MachineState *ms, size_t *length)
     if (!smbios_immutable) {
         smbios_build_type_0_fields();
         smbios_build_type_1_fields();
-        smbios_validate_table(ms);
+        smbios_validate_table(expected_t4_count);
         smbios_immutable = true;
     }
     *length = smbios_entries_len;
@@ -1112,10 +1109,9 @@ void smbios_get_tables(MachineState *ms,
         smbios_build_type_2_table();
         smbios_build_type_3_table();
 
-        smbios_smp_sockets = ms->smp.sockets;
-        assert(smbios_smp_sockets >= 1);
+        assert(ms->smp.sockets >= 1);
 
-        for (i = 0; i < smbios_smp_sockets; i++) {
+        for (i = 0; i < ms->smp.sockets; i++) {
             smbios_build_type_4_table(ms, i);
         }
 
@@ -1160,7 +1156,7 @@ void smbios_get_tables(MachineState *ms,
         smbios_build_type_41_table(errp);
         smbios_build_type_127_table();
 
-        smbios_validate_table(ms);
+        smbios_validate_table(ms->smp.sockets);
         smbios_entry_point_setup();
         smbios_immutable = true;
     }
-- 
2.39.3



^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v3 06/20] smbios: get rid of smbios_legacy global
  2024-03-12 16:10 [PATCH v3 00/20] Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS Igor Mammedov
                   ` (4 preceding siblings ...)
  2024-03-12 16:10 ` [PATCH v3 05/20] smbios: get rid of smbios_smp_sockets global Igor Mammedov
@ 2024-03-12 16:10 ` Igor Mammedov
  2024-03-12 16:10 ` [PATCH v3 07/20] smbios: avoid mangling user provided tables Igor Mammedov
                   ` (15 subsequent siblings)
  21 siblings, 0 replies; 27+ messages in thread
From: Igor Mammedov @ 2024-03-12 16:10 UTC (permalink / raw)
  To: qemu-devel; +Cc: imammedo, mst, Ani Sinha, Daniel Henrique Barboza, Fiona Ebner

clean up smbios_set_defaults() which is reused by legacy
and non legacy machines from being aware of 'legacy' notion
and need to turn it off. And push legacy handling up to
PC machine code where it's relevant.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Ani Sinha <anisinha@redhat.com>
Acked-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Tested-by: Fiona Ebner <f.ebner@proxmox.com>
---
PS: I've moved/kept legacy smbios_entries to smbios_get_tables()
but it at least is not visible to API users. To get rid of it
as well, it would be necessary to change how '-smbios' CLI
option is processed. Which is done later in the series.
---
 include/hw/firmware/smbios.h |  2 +-
 hw/arm/virt.c                |  2 +-
 hw/i386/fw_cfg.c             |  7 ++++---
 hw/loongarch/virt.c          |  2 +-
 hw/riscv/virt.c              |  2 +-
 hw/smbios/smbios.c           | 35 +++++++++++++++--------------------
 6 files changed, 23 insertions(+), 27 deletions(-)

diff --git a/include/hw/firmware/smbios.h b/include/hw/firmware/smbios.h
index a187fbbd3d..0818184834 100644
--- a/include/hw/firmware/smbios.h
+++ b/include/hw/firmware/smbios.h
@@ -293,7 +293,7 @@ struct smbios_type_127 {
 void smbios_entry_add(QemuOpts *opts, Error **errp);
 void smbios_set_cpuid(uint32_t version, uint32_t features);
 void smbios_set_defaults(const char *manufacturer, const char *product,
-                         const char *version, bool legacy_mode,
+                         const char *version,
                          bool uuid_encoded, SmbiosEntryPointType ep_type);
 void smbios_set_default_processor_family(uint16_t processor_family);
 uint8_t *smbios_get_table_legacy(uint32_t expected_t4_count, size_t *length);
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 0af1943697..8588681f27 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -1633,7 +1633,7 @@ static void virt_build_smbios(VirtMachineState *vms)
     }
 
     smbios_set_defaults("QEMU", product,
-                        vmc->smbios_old_sys_ver ? "1.0" : mc->name, false,
+                        vmc->smbios_old_sys_ver ? "1.0" : mc->name,
                         true, SMBIOS_ENTRY_POINT_TYPE_64);
 
     /* build the array of physical mem area from base_memmap */
diff --git a/hw/i386/fw_cfg.c b/hw/i386/fw_cfg.c
index fcb4fb0769..c1e9c0fd9c 100644
--- a/hw/i386/fw_cfg.c
+++ b/hw/i386/fw_cfg.c
@@ -63,15 +63,16 @@ void fw_cfg_build_smbios(PCMachineState *pcms, FWCfgState *fw_cfg)
     if (pcmc->smbios_defaults) {
         /* These values are guest ABI, do not change */
         smbios_set_defaults("QEMU", mc->desc, mc->name,
-                            pcmc->smbios_legacy_mode, pcmc->smbios_uuid_encoded,
+                            pcmc->smbios_uuid_encoded,
                             pcms->smbios_entry_point_type);
     }
 
     /* tell smbios about cpuid version and features */
     smbios_set_cpuid(cpu->env.cpuid_version, cpu->env.features[FEAT_1_EDX]);
 
-    smbios_tables = smbios_get_table_legacy(ms->smp.cpus, &smbios_tables_len);
-    if (smbios_tables) {
+    if (pcmc->smbios_legacy_mode) {
+        smbios_tables = smbios_get_table_legacy(ms->smp.cpus,
+                                                &smbios_tables_len);
         fw_cfg_add_bytes(fw_cfg, FW_CFG_SMBIOS_ENTRIES,
                          smbios_tables, smbios_tables_len);
         return;
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
index 1e98d8bda5..8c7601ef91 100644
--- a/hw/loongarch/virt.c
+++ b/hw/loongarch/virt.c
@@ -355,7 +355,7 @@ static void virt_build_smbios(LoongArchMachineState *lams)
         return;
     }
 
-    smbios_set_defaults("QEMU", product, mc->name, false,
+    smbios_set_defaults("QEMU", product, mc->name,
                         true, SMBIOS_ENTRY_POINT_TYPE_64);
 
     smbios_get_tables(ms, NULL, 0, &smbios_tables, &smbios_tables_len,
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index a094af97c3..535fd047ba 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -1275,7 +1275,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] 27+ messages in thread

* [PATCH v3 07/20] smbios: avoid mangling user provided tables
  2024-03-12 16:10 [PATCH v3 00/20] Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS Igor Mammedov
                   ` (5 preceding siblings ...)
  2024-03-12 16:10 ` [PATCH v3 06/20] smbios: get rid of smbios_legacy global Igor Mammedov
@ 2024-03-12 16:10 ` Igor Mammedov
  2024-03-12 16:10 ` [PATCH v3 08/20] smbios: don't check type4 structures in legacy mode Igor Mammedov
                   ` (14 subsequent siblings)
  21 siblings, 0 replies; 27+ messages in thread
From: Igor Mammedov @ 2024-03-12 16:10 UTC (permalink / raw)
  To: qemu-devel; +Cc: imammedo, mst, Fiona Ebner, Ani Sinha

currently smbios_entry_add() preserves internally '-smbios type='
options but tables provided with '-smbios file=' are stored directly
into blob that eventually will be exposed to VM. And then later
QEMU adds default/'-smbios type' entries on top into the same blob.

It makes impossible to generate tables more than once, hence
'immutable' guard was used.
Make it possible to regenerate final blob by storing user provided
blobs into a dedicated area (usr_blobs) and then copy it when
composing final blob. Which also makes handling of -smbios
options consistent.

As side effect of this and previous commits there is no need to
generate legacy smbios_entries at the time options are parsed.
Instead compose smbios_entries on demand from  usr_blobs like
it is done for non-legacy SMBIOS tables.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Tested-by: Fiona Ebner <f.ebner@proxmox.com>
Reviewed-by: Ani Sinha <anisinha@redhat.com>
---
 hw/smbios/smbios.c | 179 +++++++++++++++++++++++----------------------
 1 file changed, 92 insertions(+), 87 deletions(-)

diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c
index c46fc93357..aa2cc5bdbd 100644
--- a/hw/smbios/smbios.c
+++ b/hw/smbios/smbios.c
@@ -57,6 +57,14 @@ static size_t smbios_entries_len;
 static bool smbios_uuid_encoded = true;
 /* end: legacy structures & constants for <= 2.0 machines */
 
+/*
+ * SMBIOS tables provided by user with '-smbios file=<foo>' option
+ */
+uint8_t *usr_blobs;
+size_t usr_blobs_len;
+static GArray *usr_blobs_sizes;
+static unsigned usr_table_max;
+static unsigned usr_table_cnt;
 
 uint8_t *smbios_tables;
 size_t smbios_tables_len;
@@ -67,7 +75,6 @@ static SmbiosEntryPointType smbios_ep_type = SMBIOS_ENTRY_POINT_TYPE_32;
 static SmbiosEntryPoint ep;
 
 static int smbios_type4_count = 0;
-static bool smbios_immutable;
 static bool smbios_have_defaults;
 static uint32_t smbios_cpuid_version, smbios_cpuid_features;
 
@@ -569,9 +576,8 @@ static void smbios_build_type_1_fields(void)
 
 uint8_t *smbios_get_table_legacy(uint32_t expected_t4_count, size_t *length)
 {
-    /* drop unwanted version of command-line file blob(s) */
-    g_free(smbios_tables);
-    smbios_tables = NULL;
+    int i;
+    size_t usr_offset;
 
     /* also complain if fields were given for types > 1 */
     if (find_next_bit(have_fields_bitmap,
@@ -581,12 +587,33 @@ uint8_t *smbios_get_table_legacy(uint32_t expected_t4_count, size_t *length)
         exit(1);
     }
 
-    if (!smbios_immutable) {
-        smbios_build_type_0_fields();
-        smbios_build_type_1_fields();
-        smbios_validate_table(expected_t4_count);
-        smbios_immutable = true;
+    g_free(smbios_entries);
+    smbios_entries_len = sizeof(uint16_t);
+    smbios_entries = g_malloc0(smbios_entries_len);
+
+    for (i = 0, usr_offset = 0; usr_blobs_sizes && i < usr_blobs_sizes->len;
+         i++)
+    {
+        struct smbios_table *table;
+        struct smbios_structure_header *header;
+        size_t size = g_array_index(usr_blobs_sizes, size_t, i);
+
+        header = (struct smbios_structure_header *)(usr_blobs + usr_offset);
+        smbios_entries = g_realloc(smbios_entries, smbios_entries_len +
+                                                   size + sizeof(*table));
+        table = (struct smbios_table *)(smbios_entries + smbios_entries_len);
+        table->header.type = SMBIOS_TABLE_ENTRY;
+        table->header.length = cpu_to_le16(sizeof(*table) + size);
+        memcpy(table->data, header, size);
+        smbios_entries_len += sizeof(*table) + size;
+        (*(uint16_t *)smbios_entries) =
+            cpu_to_le16(le16_to_cpu(*(uint16_t *)smbios_entries) + 1);
+        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] 27+ messages in thread

* [PATCH v3 08/20] smbios: don't check type4 structures in legacy mode
  2024-03-12 16:10 [PATCH v3 00/20] Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS Igor Mammedov
                   ` (6 preceding siblings ...)
  2024-03-12 16:10 ` [PATCH v3 07/20] smbios: avoid mangling user provided tables Igor Mammedov
@ 2024-03-12 16:10 ` Igor Mammedov
  2024-03-12 16:10 ` [PATCH v3 09/20] smbios: add smbios_add_usr_blob_size() helper Igor Mammedov
                   ` (13 subsequent siblings)
  21 siblings, 0 replies; 27+ messages in thread
From: Igor Mammedov @ 2024-03-12 16:10 UTC (permalink / raw)
  To: qemu-devel; +Cc: imammedo, mst, Ani Sinha, Fiona Ebner

legacy mode doesn't support structures of type 2 and more,
and CLI has a check for '-smbios type' option, however it's
still possible to sneak in type4 as a blob with '-smbios file'
option. However doing the later makes SMBIOS tables broken
since SeaBIOS doesn't expect that.

Rather than trying to add support for type4 to legacy code
(both QEMU and SeaBIOS), simplify smbios_get_table_legacy()
by dropping not relevant check in legacy code and error out
on type4 blob.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Ani Sinha <anisinha@redhat.com>
Tested-by: Fiona Ebner <f.ebner@proxmox.com>
---
 * The issue affects 'isapc' and pc-i440fx-2.0. the later is
   in deprecated state and to be dropped in near future
 * possibly the same issue applies to other SMBIOS types above type 1
   but I haven't tested that, and well tables that aren't
   generated by SeaBIOS can get be added just fine
   (tested type11 blob). So I went with a minimal change
   to fixup type4 only that I'm touching. Leaving the rest
   for other time or when someone complains about it, which is
   very unlikely given it's really only remaining isapc machine.

   I'd very much prefer to deprecate 'isapc' and then drop
   all legacy related code (it will benefit not only SMBIOS
   but other code as well).
   BTW: 'isapc' is in semi-dead, I cna't boot RHEL6 on it
   with KVM enabled anymore (RHEL9 host), TCG still boots though.
   One more reason to get deprecate it.
---
 include/hw/firmware/smbios.h |  2 +-
 hw/i386/fw_cfg.c             |  3 +--
 hw/smbios/smbios.c           | 18 ++++++++++++++----
 3 files changed, 16 insertions(+), 7 deletions(-)

diff --git a/include/hw/firmware/smbios.h b/include/hw/firmware/smbios.h
index 0818184834..1fbff3c55f 100644
--- a/include/hw/firmware/smbios.h
+++ b/include/hw/firmware/smbios.h
@@ -296,7 +296,7 @@ void smbios_set_defaults(const char *manufacturer, const char *product,
                          const char *version,
                          bool uuid_encoded, SmbiosEntryPointType ep_type);
 void smbios_set_default_processor_family(uint16_t processor_family);
-uint8_t *smbios_get_table_legacy(uint32_t expected_t4_count, size_t *length);
+uint8_t *smbios_get_table_legacy(size_t *length);
 void smbios_get_tables(MachineState *ms,
                        const struct smbios_phys_mem_area *mem_array,
                        const unsigned int mem_array_size,
diff --git a/hw/i386/fw_cfg.c b/hw/i386/fw_cfg.c
index c1e9c0fd9c..d1281066f4 100644
--- a/hw/i386/fw_cfg.c
+++ b/hw/i386/fw_cfg.c
@@ -71,8 +71,7 @@ void fw_cfg_build_smbios(PCMachineState *pcms, FWCfgState *fw_cfg)
     smbios_set_cpuid(cpu->env.cpuid_version, cpu->env.features[FEAT_1_EDX]);
 
     if (pcmc->smbios_legacy_mode) {
-        smbios_tables = smbios_get_table_legacy(ms->smp.cpus,
-                                                &smbios_tables_len);
+        smbios_tables = smbios_get_table_legacy(&smbios_tables_len);
         fw_cfg_add_bytes(fw_cfg, FW_CFG_SMBIOS_ENTRIES,
                          smbios_tables, smbios_tables_len);
         return;
diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c
index aa2cc5bdbd..97cf762228 100644
--- a/hw/smbios/smbios.c
+++ b/hw/smbios/smbios.c
@@ -482,14 +482,17 @@ opts_init(smbios_register_config);
  */
 #define SMBIOS_21_MAX_TABLES_LEN 0xffff
 
-static void smbios_validate_table(uint32_t expected_t4_count)
+static void smbios_check_type4_count(uint32_t expected_t4_count)
 {
     if (smbios_type4_count && smbios_type4_count != expected_t4_count) {
         error_report("Expected %d SMBIOS Type 4 tables, got %d instead",
                      expected_t4_count, smbios_type4_count);
         exit(1);
     }
+}
 
+static void smbios_validate_table(void)
+{
     if (smbios_ep_type == SMBIOS_ENTRY_POINT_TYPE_32 &&
         smbios_tables_len > SMBIOS_21_MAX_TABLES_LEN) {
         error_report("SMBIOS 2.1 table length %zu exceeds %d",
@@ -574,7 +577,7 @@ static void smbios_build_type_1_fields(void)
     }
 }
 
-uint8_t *smbios_get_table_legacy(uint32_t expected_t4_count, size_t *length)
+uint8_t *smbios_get_table_legacy(size_t *length)
 {
     int i;
     size_t usr_offset;
@@ -587,6 +590,12 @@ uint8_t *smbios_get_table_legacy(uint32_t expected_t4_count, size_t *length)
         exit(1);
     }
 
+    if (test_bit(4, have_binfile_bitmap)) {
+        error_report("can't process table for smbios "
+                     "type 4 on machine versions < 2.1!");
+        exit(1);
+    }
+
     g_free(smbios_entries);
     smbios_entries_len = sizeof(uint16_t);
     smbios_entries = g_malloc0(smbios_entries_len);
@@ -613,7 +622,7 @@ uint8_t *smbios_get_table_legacy(uint32_t expected_t4_count, size_t *length)
 
     smbios_build_type_0_fields();
     smbios_build_type_1_fields();
-    smbios_validate_table(expected_t4_count);
+    smbios_validate_table();
     *length = smbios_entries_len;
     return smbios_entries;
 }
@@ -1180,7 +1189,8 @@ void smbios_get_tables(MachineState *ms,
     smbios_build_type_41_table(errp);
     smbios_build_type_127_table();
 
-    smbios_validate_table(ms->smp.sockets);
+    smbios_check_type4_count(ms->smp.sockets);
+    smbios_validate_table();
     smbios_entry_point_setup();
 
     /* return tables blob and entry point (anchor), and their sizes */
-- 
2.39.3



^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v3 09/20] smbios: add smbios_add_usr_blob_size() helper
  2024-03-12 16:10 [PATCH v3 00/20] Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS Igor Mammedov
                   ` (7 preceding siblings ...)
  2024-03-12 16:10 ` [PATCH v3 08/20] smbios: don't check type4 structures in legacy mode Igor Mammedov
@ 2024-03-12 16:10 ` Igor Mammedov
  2024-03-12 16:10 ` [PATCH v3 10/20] smbios: rename/expose structures/bitmaps used by both legacy and modern code Igor Mammedov
                   ` (12 subsequent siblings)
  21 siblings, 0 replies; 27+ messages in thread
From: Igor Mammedov @ 2024-03-12 16:10 UTC (permalink / raw)
  To: qemu-devel; +Cc: imammedo, mst, Ani Sinha

it will be used by follow up patch when legacy handling
is moved out into a separate file.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Ani Sinha <anisinha@redhat.com>
---
 hw/smbios/smbios.c | 18 ++++++++++++++----
 1 file changed, 14 insertions(+), 4 deletions(-)

diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c
index 97cf762228..01180bd82c 100644
--- a/hw/smbios/smbios.c
+++ b/hw/smbios/smbios.c
@@ -1287,6 +1287,14 @@ static bool save_opt_list(size_t *ndest, char ***dest, QemuOpts *opts,
     return true;
 }
 
+static void smbios_add_usr_blob_size(size_t size)
+{
+    if (!usr_blobs_sizes) {
+        usr_blobs_sizes = g_array_new(false, false, sizeof(size_t));
+    }
+    g_array_append_val(usr_blobs_sizes, size);
+}
+
 void smbios_entry_add(QemuOpts *opts, Error **errp)
 {
     const char *val;
@@ -1334,10 +1342,12 @@ void smbios_entry_add(QemuOpts *opts, Error **errp)
             smbios_type4_count++;
         }
 
-        if (!usr_blobs_sizes) {
-            usr_blobs_sizes = g_array_new(false, false, sizeof(size_t));
-        }
-        g_array_append_val(usr_blobs_sizes, size);
+        /*
+         * preserve blob size for legacy mode so it could build its
+         * blobs flavor from 'usr_blobs'
+         */
+        smbios_add_usr_blob_size(size);
+
         usr_blobs_len += size;
         if (size > usr_table_max) {
             usr_table_max = size;
-- 
2.39.3



^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v3 10/20] smbios: rename/expose structures/bitmaps used by both legacy and modern code
  2024-03-12 16:10 [PATCH v3 00/20] Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS Igor Mammedov
                   ` (8 preceding siblings ...)
  2024-03-12 16:10 ` [PATCH v3 09/20] smbios: add smbios_add_usr_blob_size() helper Igor Mammedov
@ 2024-03-12 16:10 ` Igor Mammedov
  2024-03-12 16:10 ` [PATCH v3 11/20] smbios: build legacy mode code only for 'pc' machine Igor Mammedov
                   ` (11 subsequent siblings)
  21 siblings, 0 replies; 27+ messages in thread
From: Igor Mammedov @ 2024-03-12 16:10 UTC (permalink / raw)
  To: qemu-devel; +Cc: imammedo, mst, Ani Sinha

As a preparation to move legacy handling into a separate file,
add prefix 'smbios_' to type0/type1/have_binfile_bitmap/have_fields_bitmap
and expose them in smbios.h so that they can be reused in
legacy and modern code.

Doing it as a separate patch to avoid rename cluttering follow-up
patch which will move legacy code into a separate file.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Ani Sinha <anisinha@redhat.com>
---
 include/hw/firmware/smbios.h |  16 +++++
 hw/smbios/smbios.c           | 113 ++++++++++++++++-------------------
 2 files changed, 69 insertions(+), 60 deletions(-)

diff --git a/include/hw/firmware/smbios.h b/include/hw/firmware/smbios.h
index 1fbff3c55f..bea5c3f1b1 100644
--- a/include/hw/firmware/smbios.h
+++ b/include/hw/firmware/smbios.h
@@ -2,6 +2,7 @@
 #define QEMU_SMBIOS_H
 
 #include "qapi/qapi-types-machine.h"
+#include "qemu/bitmap.h"
 
 /*
  * SMBIOS Support
@@ -16,8 +17,23 @@
  *
  */
 
+typedef struct {
+    const char *vendor, *version, *date;
+    bool have_major_minor, uefi;
+    uint8_t major, minor;
+} smbios_type0_t;
+extern smbios_type0_t smbios_type0;
+
+typedef struct {
+    const char *manufacturer, *product, *version, *serial, *sku, *family;
+    /* uuid is in qemu_uuid */
+} smbios_type1_t;
+extern smbios_type1_t smbios_type1;
 
 #define SMBIOS_MAX_TYPE 127
+extern DECLARE_BITMAP(smbios_have_binfile_bitmap, SMBIOS_MAX_TYPE + 1);
+extern DECLARE_BITMAP(smbios_have_fields_bitmap, SMBIOS_MAX_TYPE + 1);
+
 #define offsetofend(TYPE, MEMBER) \
        (offsetof(TYPE, MEMBER) + sizeof_field(TYPE, MEMBER))
 
diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c
index 01180bd82c..86cf66b5ce 100644
--- a/hw/smbios/smbios.c
+++ b/hw/smbios/smbios.c
@@ -78,19 +78,11 @@ static int smbios_type4_count = 0;
 static bool smbios_have_defaults;
 static uint32_t smbios_cpuid_version, smbios_cpuid_features;
 
-static DECLARE_BITMAP(have_binfile_bitmap, SMBIOS_MAX_TYPE+1);
-static DECLARE_BITMAP(have_fields_bitmap, SMBIOS_MAX_TYPE+1);
+DECLARE_BITMAP(smbios_have_binfile_bitmap, SMBIOS_MAX_TYPE + 1);
+DECLARE_BITMAP(smbios_have_fields_bitmap, SMBIOS_MAX_TYPE + 1);
 
-static struct {
-    const char *vendor, *version, *date;
-    bool have_major_minor, uefi;
-    uint8_t major, minor;
-} type0;
-
-static struct {
-    const char *manufacturer, *product, *version, *serial, *sku, *family;
-    /* uuid is in qemu_uuid */
-} type1;
+smbios_type0_t smbios_type0;
+smbios_type1_t smbios_type1;
 
 static struct {
     const char *manufacturer, *product, *version, *serial, *asset, *location;
@@ -536,36 +528,36 @@ static void smbios_maybe_add_str(int type, int offset, const char *data)
 static void smbios_build_type_0_fields(void)
 {
     smbios_maybe_add_str(0, offsetof(struct smbios_type_0, vendor_str),
-                         type0.vendor);
+                         smbios_type0.vendor);
     smbios_maybe_add_str(0, offsetof(struct smbios_type_0, bios_version_str),
-                         type0.version);
+                         smbios_type0.version);
     smbios_maybe_add_str(0, offsetof(struct smbios_type_0,
                                      bios_release_date_str),
-                         type0.date);
-    if (type0.have_major_minor) {
+                         smbios_type0.date);
+    if (smbios_type0.have_major_minor) {
         smbios_add_field(0, offsetof(struct smbios_type_0,
                                      system_bios_major_release),
-                         &type0.major, 1);
+                         &smbios_type0.major, 1);
         smbios_add_field(0, offsetof(struct smbios_type_0,
                                      system_bios_minor_release),
-                         &type0.minor, 1);
+                         &smbios_type0.minor, 1);
     }
 }
 
 static void smbios_build_type_1_fields(void)
 {
     smbios_maybe_add_str(1, offsetof(struct smbios_type_1, manufacturer_str),
-                         type1.manufacturer);
+                         smbios_type1.manufacturer);
     smbios_maybe_add_str(1, offsetof(struct smbios_type_1, product_name_str),
-                         type1.product);
+                         smbios_type1.product);
     smbios_maybe_add_str(1, offsetof(struct smbios_type_1, version_str),
-                         type1.version);
+                         smbios_type1.version);
     smbios_maybe_add_str(1, offsetof(struct smbios_type_1, serial_number_str),
-                         type1.serial);
+                         smbios_type1.serial);
     smbios_maybe_add_str(1, offsetof(struct smbios_type_1, sku_number_str),
-                         type1.sku);
+                         smbios_type1.sku);
     smbios_maybe_add_str(1, offsetof(struct smbios_type_1, family_str),
-                         type1.family);
+                         smbios_type1.family);
     if (qemu_uuid_set) {
         /* We don't encode the UUID in the "wire format" here because this
          * function is for legacy mode and needs to keep the guest ABI, and
@@ -583,14 +575,14 @@ uint8_t *smbios_get_table_legacy(size_t *length)
     size_t usr_offset;
 
     /* also complain if fields were given for types > 1 */
-    if (find_next_bit(have_fields_bitmap,
+    if (find_next_bit(smbios_have_fields_bitmap,
                       SMBIOS_MAX_TYPE + 1, 2) < SMBIOS_MAX_TYPE + 1) {
         error_report("can't process fields for smbios "
                      "types > 1 on machine versions < 2.1!");
         exit(1);
     }
 
-    if (test_bit(4, have_binfile_bitmap)) {
+    if (test_bit(4, smbios_have_binfile_bitmap)) {
         error_report("can't process table for smbios "
                      "type 4 on machine versions < 2.1!");
         exit(1);
@@ -631,10 +623,10 @@ uint8_t *smbios_get_table_legacy(size_t *length)
 
 bool smbios_skip_table(uint8_t type, bool required_table)
 {
-    if (test_bit(type, have_binfile_bitmap)) {
+    if (test_bit(type, smbios_have_binfile_bitmap)) {
         return true; /* user provided their own binary blob(s) */
     }
-    if (test_bit(type, have_fields_bitmap)) {
+    if (test_bit(type, smbios_have_fields_bitmap)) {
         return false; /* user provided fields via command line */
     }
     if (smbios_have_defaults && required_table) {
@@ -661,25 +653,25 @@ static void smbios_build_type_0_table(void)
 {
     SMBIOS_BUILD_TABLE_PRE(0, T0_BASE, false); /* optional, leave up to BIOS */
 
-    SMBIOS_TABLE_SET_STR(0, vendor_str, type0.vendor);
-    SMBIOS_TABLE_SET_STR(0, bios_version_str, type0.version);
+    SMBIOS_TABLE_SET_STR(0, vendor_str, smbios_type0.vendor);
+    SMBIOS_TABLE_SET_STR(0, bios_version_str, smbios_type0.version);
 
     t->bios_starting_address_segment = cpu_to_le16(0xE800); /* from SeaBIOS */
 
-    SMBIOS_TABLE_SET_STR(0, bios_release_date_str, type0.date);
+    SMBIOS_TABLE_SET_STR(0, bios_release_date_str, smbios_type0.date);
 
     t->bios_rom_size = 0; /* hardcoded in SeaBIOS with FIXME comment */
 
     t->bios_characteristics = cpu_to_le64(0x08); /* Not supported */
     t->bios_characteristics_extension_bytes[0] = 0;
     t->bios_characteristics_extension_bytes[1] = 0x14; /* TCD/SVVP | VM */
-    if (type0.uefi) {
+    if (smbios_type0.uefi) {
         t->bios_characteristics_extension_bytes[1] |= 0x08; /* |= UEFI */
     }
 
-    if (type0.have_major_minor) {
-        t->system_bios_major_release = type0.major;
-        t->system_bios_minor_release = type0.minor;
+    if (smbios_type0.have_major_minor) {
+        t->system_bios_major_release = smbios_type0.major;
+        t->system_bios_minor_release = smbios_type0.minor;
     } else {
         t->system_bios_major_release = 0;
         t->system_bios_minor_release = 0;
@@ -709,18 +701,18 @@ static void smbios_build_type_1_table(void)
 {
     SMBIOS_BUILD_TABLE_PRE(1, T1_BASE, true); /* required */
 
-    SMBIOS_TABLE_SET_STR(1, manufacturer_str, type1.manufacturer);
-    SMBIOS_TABLE_SET_STR(1, product_name_str, type1.product);
-    SMBIOS_TABLE_SET_STR(1, version_str, type1.version);
-    SMBIOS_TABLE_SET_STR(1, serial_number_str, type1.serial);
+    SMBIOS_TABLE_SET_STR(1, manufacturer_str, smbios_type1.manufacturer);
+    SMBIOS_TABLE_SET_STR(1, product_name_str, smbios_type1.product);
+    SMBIOS_TABLE_SET_STR(1, version_str, smbios_type1.version);
+    SMBIOS_TABLE_SET_STR(1, serial_number_str, smbios_type1.serial);
     if (qemu_uuid_set) {
         smbios_encode_uuid(&t->uuid, &qemu_uuid);
     } else {
         memset(&t->uuid, 0, 16);
     }
     t->wake_up_type = 0x06; /* power switch */
-    SMBIOS_TABLE_SET_STR(1, sku_number_str, type1.sku);
-    SMBIOS_TABLE_SET_STR(1, family_str, type1.family);
+    SMBIOS_TABLE_SET_STR(1, sku_number_str, smbios_type1.sku);
+    SMBIOS_TABLE_SET_STR(1, family_str, smbios_type1.family);
 
     SMBIOS_BUILD_TABLE_POST;
 }
@@ -1055,9 +1047,9 @@ void smbios_set_defaults(const char *manufacturer, const char *product,
     smbios_uuid_encoded = uuid_encoded;
     smbios_ep_type = ep_type;
 
-    SMBIOS_SET_DEFAULT(type1.manufacturer, manufacturer);
-    SMBIOS_SET_DEFAULT(type1.product, product);
-    SMBIOS_SET_DEFAULT(type1.version, version);
+    SMBIOS_SET_DEFAULT(smbios_type1.manufacturer, manufacturer);
+    SMBIOS_SET_DEFAULT(smbios_type1.product, product);
+    SMBIOS_SET_DEFAULT(smbios_type1.version, version);
     SMBIOS_SET_DEFAULT(type2.manufacturer, manufacturer);
     SMBIOS_SET_DEFAULT(type2.product, product);
     SMBIOS_SET_DEFAULT(type2.version, version);
@@ -1329,13 +1321,13 @@ void smbios_entry_add(QemuOpts *opts, Error **errp)
         }
 
         if (header->type <= SMBIOS_MAX_TYPE) {
-            if (test_bit(header->type, have_fields_bitmap)) {
+            if (test_bit(header->type, smbios_have_fields_bitmap)) {
                 error_setg(errp,
                            "can't load type %d struct, fields already specified!",
                            header->type);
                 return;
             }
-            set_bit(header->type, have_binfile_bitmap);
+            set_bit(header->type, smbios_have_binfile_bitmap);
         }
 
         if (header->type == 4) {
@@ -1366,41 +1358,42 @@ void smbios_entry_add(QemuOpts *opts, Error **errp)
             return;
         }
 
-        if (test_bit(type, have_binfile_bitmap)) {
+        if (test_bit(type, smbios_have_binfile_bitmap)) {
             error_setg(errp, "can't add fields, binary file already loaded!");
             return;
         }
-        set_bit(type, have_fields_bitmap);
+        set_bit(type, smbios_have_fields_bitmap);
 
         switch (type) {
         case 0:
             if (!qemu_opts_validate(opts, qemu_smbios_type0_opts, errp)) {
                 return;
             }
-            save_opt(&type0.vendor, opts, "vendor");
-            save_opt(&type0.version, opts, "version");
-            save_opt(&type0.date, opts, "date");
-            type0.uefi = qemu_opt_get_bool(opts, "uefi", false);
+            save_opt(&smbios_type0.vendor, opts, "vendor");
+            save_opt(&smbios_type0.version, opts, "version");
+            save_opt(&smbios_type0.date, opts, "date");
+            smbios_type0.uefi = qemu_opt_get_bool(opts, "uefi", false);
 
             val = qemu_opt_get(opts, "release");
             if (val) {
-                if (sscanf(val, "%hhu.%hhu", &type0.major, &type0.minor) != 2) {
+                if (sscanf(val, "%hhu.%hhu", &smbios_type0.major,
+                           &smbios_type0.minor) != 2) {
                     error_setg(errp, "Invalid release");
                     return;
                 }
-                type0.have_major_minor = true;
+                smbios_type0.have_major_minor = true;
             }
             return;
         case 1:
             if (!qemu_opts_validate(opts, qemu_smbios_type1_opts, errp)) {
                 return;
             }
-            save_opt(&type1.manufacturer, opts, "manufacturer");
-            save_opt(&type1.product, opts, "product");
-            save_opt(&type1.version, opts, "version");
-            save_opt(&type1.serial, opts, "serial");
-            save_opt(&type1.sku, opts, "sku");
-            save_opt(&type1.family, opts, "family");
+            save_opt(&smbios_type1.manufacturer, opts, "manufacturer");
+            save_opt(&smbios_type1.product, opts, "product");
+            save_opt(&smbios_type1.version, opts, "version");
+            save_opt(&smbios_type1.serial, opts, "serial");
+            save_opt(&smbios_type1.sku, opts, "sku");
+            save_opt(&smbios_type1.family, opts, "family");
 
             val = qemu_opt_get(opts, "uuid");
             if (val) {
-- 
2.39.3



^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v3 11/20] smbios: build legacy mode code only for 'pc' machine
  2024-03-12 16:10 [PATCH v3 00/20] Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS Igor Mammedov
                   ` (9 preceding siblings ...)
  2024-03-12 16:10 ` [PATCH v3 10/20] smbios: rename/expose structures/bitmaps used by both legacy and modern code Igor Mammedov
@ 2024-03-12 16:10 ` Igor Mammedov
  2024-03-12 16:10 ` [PATCH v3 12/20] smbios: handle errors consistently Igor Mammedov
                   ` (10 subsequent siblings)
  21 siblings, 0 replies; 27+ messages in thread
From: Igor Mammedov @ 2024-03-12 16:10 UTC (permalink / raw)
  To: qemu-devel; +Cc: imammedo, mst, Ani Sinha

basically moving code around without functional change.
And exposing some symbols so that they could be shared
between smbbios.c and new smbios_legacy.c

plus some meson magic to build smbios_legacy.c only
for 'pc' machine and otherwise replace it with stub
if not selected.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Ani Sinha <anisinha@redhat.com>
---
v2:
  moved type0/type1/have_binfile_bitmap/have_fields_bitmap rename into
  a separate patch
v3:
  drop blank space at the end of hw/smbios/smbios_legacy_stub.c
---
 include/hw/firmware/smbios.h   |   5 +
 hw/i386/Kconfig                |   1 +
 hw/smbios/Kconfig              |   2 +
 hw/smbios/meson.build          |   4 +
 hw/smbios/smbios.c             | 164 +-----------------------------
 hw/smbios/smbios_legacy.c      | 179 +++++++++++++++++++++++++++++++++
 hw/smbios/smbios_legacy_stub.c |  15 +++
 7 files changed, 207 insertions(+), 163 deletions(-)
 create mode 100644 hw/smbios/smbios_legacy.c
 create mode 100644 hw/smbios/smbios_legacy_stub.c

diff --git a/include/hw/firmware/smbios.h b/include/hw/firmware/smbios.h
index bea5c3f1b1..7f47475aa4 100644
--- a/include/hw/firmware/smbios.h
+++ b/include/hw/firmware/smbios.h
@@ -17,6 +17,9 @@
  *
  */
 
+extern uint8_t *usr_blobs;
+extern GArray *usr_blobs_sizes;
+
 typedef struct {
     const char *vendor, *version, *date;
     bool have_major_minor, uefi;
@@ -306,6 +309,8 @@ struct smbios_type_127 {
     struct smbios_structure_header header;
 } QEMU_PACKED;
 
+void smbios_validate_table(void);
+void smbios_add_usr_blob_size(size_t size);
 void smbios_entry_add(QemuOpts *opts, Error **errp);
 void smbios_set_cpuid(uint32_t version, uint32_t features);
 void smbios_set_defaults(const char *manufacturer, const char *product,
diff --git a/hw/i386/Kconfig b/hw/i386/Kconfig
index a1846be6f7..a6ee052f9a 100644
--- a/hw/i386/Kconfig
+++ b/hw/i386/Kconfig
@@ -76,6 +76,7 @@ config I440FX
     select PIIX
     select DIMM
     select SMBIOS
+    select SMBIOS_LEGACY
     select FW_CFG_DMA
 
 config ISAPC
diff --git a/hw/smbios/Kconfig b/hw/smbios/Kconfig
index 553adf4bfc..8d989a2f1b 100644
--- a/hw/smbios/Kconfig
+++ b/hw/smbios/Kconfig
@@ -1,2 +1,4 @@
 config SMBIOS
     bool
+config SMBIOS_LEGACY
+    bool
diff --git a/hw/smbios/meson.build b/hw/smbios/meson.build
index 7046967462..a59039f669 100644
--- a/hw/smbios/meson.build
+++ b/hw/smbios/meson.build
@@ -4,5 +4,9 @@ smbios_ss.add(when: 'CONFIG_IPMI',
               if_true: files('smbios_type_38.c'),
               if_false: files('smbios_type_38-stub.c'))
 
+smbios_ss.add(when: 'CONFIG_SMBIOS_LEGACY',
+              if_true: files('smbios_legacy.c'),
+              if_false: files('smbios_legacy_stub.c'))
+
 system_ss.add_all(when: 'CONFIG_SMBIOS', if_true: smbios_ss)
 system_ss.add(when: 'CONFIG_SMBIOS', if_false: files('smbios-stub.c'))
diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c
index 86cf66b5ce..fb1f05fcde 100644
--- a/hw/smbios/smbios.c
+++ b/hw/smbios/smbios.c
@@ -31,38 +31,12 @@
 #include "hw/pci/pci_device.h"
 #include "smbios_build.h"
 
-/* legacy structures and constants for <= 2.0 machines */
-struct smbios_header {
-    uint16_t length;
-    uint8_t type;
-} QEMU_PACKED;
-
-struct smbios_field {
-    struct smbios_header header;
-    uint8_t type;
-    uint16_t offset;
-    uint8_t data[];
-} QEMU_PACKED;
-
-struct smbios_table {
-    struct smbios_header header;
-    uint8_t data[];
-} QEMU_PACKED;
-
-#define SMBIOS_FIELD_ENTRY 0
-#define SMBIOS_TABLE_ENTRY 1
-
-static uint8_t *smbios_entries;
-static size_t smbios_entries_len;
 static bool smbios_uuid_encoded = true;
-/* end: legacy structures & constants for <= 2.0 machines */
-
 /*
  * SMBIOS tables provided by user with '-smbios file=<foo>' option
  */
 uint8_t *usr_blobs;
 size_t usr_blobs_len;
-static GArray *usr_blobs_sizes;
 static unsigned usr_table_max;
 static unsigned usr_table_cnt;
 
@@ -483,7 +457,7 @@ static void smbios_check_type4_count(uint32_t expected_t4_count)
     }
 }
 
-static void smbios_validate_table(void)
+void smbios_validate_table(void)
 {
     if (smbios_ep_type == SMBIOS_ENTRY_POINT_TYPE_32 &&
         smbios_tables_len > SMBIOS_21_MAX_TABLES_LEN) {
@@ -493,134 +467,6 @@ static void smbios_validate_table(void)
     }
 }
 
-
-/* legacy setup functions for <= 2.0 machines */
-static void smbios_add_field(int type, int offset, const void *data, size_t len)
-{
-    struct smbios_field *field;
-
-    if (!smbios_entries) {
-        smbios_entries_len = sizeof(uint16_t);
-        smbios_entries = g_malloc0(smbios_entries_len);
-    }
-    smbios_entries = g_realloc(smbios_entries, smbios_entries_len +
-                                                  sizeof(*field) + len);
-    field = (struct smbios_field *)(smbios_entries + smbios_entries_len);
-    field->header.type = SMBIOS_FIELD_ENTRY;
-    field->header.length = cpu_to_le16(sizeof(*field) + len);
-
-    field->type = type;
-    field->offset = cpu_to_le16(offset);
-    memcpy(field->data, data, len);
-
-    smbios_entries_len += sizeof(*field) + len;
-    (*(uint16_t *)smbios_entries) =
-            cpu_to_le16(le16_to_cpu(*(uint16_t *)smbios_entries) + 1);
-}
-
-static void smbios_maybe_add_str(int type, int offset, const char *data)
-{
-    if (data) {
-        smbios_add_field(type, offset, data, strlen(data) + 1);
-    }
-}
-
-static void smbios_build_type_0_fields(void)
-{
-    smbios_maybe_add_str(0, offsetof(struct smbios_type_0, vendor_str),
-                         smbios_type0.vendor);
-    smbios_maybe_add_str(0, offsetof(struct smbios_type_0, bios_version_str),
-                         smbios_type0.version);
-    smbios_maybe_add_str(0, offsetof(struct smbios_type_0,
-                                     bios_release_date_str),
-                         smbios_type0.date);
-    if (smbios_type0.have_major_minor) {
-        smbios_add_field(0, offsetof(struct smbios_type_0,
-                                     system_bios_major_release),
-                         &smbios_type0.major, 1);
-        smbios_add_field(0, offsetof(struct smbios_type_0,
-                                     system_bios_minor_release),
-                         &smbios_type0.minor, 1);
-    }
-}
-
-static void smbios_build_type_1_fields(void)
-{
-    smbios_maybe_add_str(1, offsetof(struct smbios_type_1, manufacturer_str),
-                         smbios_type1.manufacturer);
-    smbios_maybe_add_str(1, offsetof(struct smbios_type_1, product_name_str),
-                         smbios_type1.product);
-    smbios_maybe_add_str(1, offsetof(struct smbios_type_1, version_str),
-                         smbios_type1.version);
-    smbios_maybe_add_str(1, offsetof(struct smbios_type_1, serial_number_str),
-                         smbios_type1.serial);
-    smbios_maybe_add_str(1, offsetof(struct smbios_type_1, sku_number_str),
-                         smbios_type1.sku);
-    smbios_maybe_add_str(1, offsetof(struct smbios_type_1, family_str),
-                         smbios_type1.family);
-    if (qemu_uuid_set) {
-        /* We don't encode the UUID in the "wire format" here because this
-         * function is for legacy mode and needs to keep the guest ABI, and
-         * because we don't know what's the SMBIOS version advertised by the
-         * BIOS.
-         */
-        smbios_add_field(1, offsetof(struct smbios_type_1, uuid),
-                         &qemu_uuid, 16);
-    }
-}
-
-uint8_t *smbios_get_table_legacy(size_t *length)
-{
-    int i;
-    size_t usr_offset;
-
-    /* also complain if fields were given for types > 1 */
-    if (find_next_bit(smbios_have_fields_bitmap,
-                      SMBIOS_MAX_TYPE + 1, 2) < SMBIOS_MAX_TYPE + 1) {
-        error_report("can't process fields for smbios "
-                     "types > 1 on machine versions < 2.1!");
-        exit(1);
-    }
-
-    if (test_bit(4, smbios_have_binfile_bitmap)) {
-        error_report("can't process table for smbios "
-                     "type 4 on machine versions < 2.1!");
-        exit(1);
-    }
-
-    g_free(smbios_entries);
-    smbios_entries_len = sizeof(uint16_t);
-    smbios_entries = g_malloc0(smbios_entries_len);
-
-    for (i = 0, usr_offset = 0; usr_blobs_sizes && i < usr_blobs_sizes->len;
-         i++)
-    {
-        struct smbios_table *table;
-        struct smbios_structure_header *header;
-        size_t size = g_array_index(usr_blobs_sizes, size_t, i);
-
-        header = (struct smbios_structure_header *)(usr_blobs + usr_offset);
-        smbios_entries = g_realloc(smbios_entries, smbios_entries_len +
-                                                   size + sizeof(*table));
-        table = (struct smbios_table *)(smbios_entries + smbios_entries_len);
-        table->header.type = SMBIOS_TABLE_ENTRY;
-        table->header.length = cpu_to_le16(sizeof(*table) + size);
-        memcpy(table->data, header, size);
-        smbios_entries_len += sizeof(*table) + size;
-        (*(uint16_t *)smbios_entries) =
-            cpu_to_le16(le16_to_cpu(*(uint16_t *)smbios_entries) + 1);
-        usr_offset += size;
-    }
-
-    smbios_build_type_0_fields();
-    smbios_build_type_1_fields();
-    smbios_validate_table();
-    *length = smbios_entries_len;
-    return smbios_entries;
-}
-/* end: legacy setup functions for <= 2.0 machines */
-
-
 bool smbios_skip_table(uint8_t type, bool required_table)
 {
     if (test_bit(type, smbios_have_binfile_bitmap)) {
@@ -1279,14 +1125,6 @@ static bool save_opt_list(size_t *ndest, char ***dest, QemuOpts *opts,
     return true;
 }
 
-static void smbios_add_usr_blob_size(size_t size)
-{
-    if (!usr_blobs_sizes) {
-        usr_blobs_sizes = g_array_new(false, false, sizeof(size_t));
-    }
-    g_array_append_val(usr_blobs_sizes, size);
-}
-
 void smbios_entry_add(QemuOpts *opts, Error **errp)
 {
     const char *val;
diff --git a/hw/smbios/smbios_legacy.c b/hw/smbios/smbios_legacy.c
new file mode 100644
index 0000000000..21f143e738
--- /dev/null
+++ b/hw/smbios/smbios_legacy.c
@@ -0,0 +1,179 @@
+/*
+ * SMBIOS legacy support
+ *
+ * Copyright (C) 2009 Hewlett-Packard Development Company, L.P.
+ * Copyright (C) 2013 Red Hat, Inc.
+ *
+ * Authors:
+ *  Alex Williamson <alex.williamson@hp.com>
+ *  Markus Armbruster <armbru@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.  See
+ * the COPYING file in the top-level directory.
+ *
+ * Contributions after 2012-01-13 are licensed under the terms of the
+ * GNU GPL, version 2 or (at your option) any later version.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/bswap.h"
+#include "hw/firmware/smbios.h"
+#include "sysemu/sysemu.h"
+#include "qemu/error-report.h"
+
+struct smbios_header {
+    uint16_t length;
+    uint8_t type;
+} QEMU_PACKED;
+
+struct smbios_field {
+    struct smbios_header header;
+    uint8_t type;
+    uint16_t offset;
+    uint8_t data[];
+} QEMU_PACKED;
+
+struct smbios_table {
+    struct smbios_header header;
+    uint8_t data[];
+} QEMU_PACKED;
+
+#define SMBIOS_FIELD_ENTRY 0
+#define SMBIOS_TABLE_ENTRY 1
+
+static uint8_t *smbios_entries;
+static size_t smbios_entries_len;
+GArray *usr_blobs_sizes;
+
+void smbios_add_usr_blob_size(size_t size)
+{
+    if (!usr_blobs_sizes) {
+        usr_blobs_sizes = g_array_new(false, false, sizeof(size_t));
+    }
+    g_array_append_val(usr_blobs_sizes, size);
+}
+
+static void smbios_add_field(int type, int offset, const void *data, size_t len)
+{
+    struct smbios_field *field;
+
+    if (!smbios_entries) {
+        smbios_entries_len = sizeof(uint16_t);
+        smbios_entries = g_malloc0(smbios_entries_len);
+    }
+    smbios_entries = g_realloc(smbios_entries, smbios_entries_len +
+                                                  sizeof(*field) + len);
+    field = (struct smbios_field *)(smbios_entries + smbios_entries_len);
+    field->header.type = SMBIOS_FIELD_ENTRY;
+    field->header.length = cpu_to_le16(sizeof(*field) + len);
+
+    field->type = type;
+    field->offset = cpu_to_le16(offset);
+    memcpy(field->data, data, len);
+
+    smbios_entries_len += sizeof(*field) + len;
+    (*(uint16_t *)smbios_entries) =
+            cpu_to_le16(le16_to_cpu(*(uint16_t *)smbios_entries) + 1);
+}
+
+static void smbios_maybe_add_str(int type, int offset, const char *data)
+{
+    if (data) {
+        smbios_add_field(type, offset, data, strlen(data) + 1);
+    }
+}
+
+static void smbios_build_type_0_fields(void)
+{
+    smbios_maybe_add_str(0, offsetof(struct smbios_type_0, vendor_str),
+                         smbios_type0.vendor);
+    smbios_maybe_add_str(0, offsetof(struct smbios_type_0, bios_version_str),
+                         smbios_type0.version);
+    smbios_maybe_add_str(0, offsetof(struct smbios_type_0,
+                                     bios_release_date_str),
+                         smbios_type0.date);
+    if (smbios_type0.have_major_minor) {
+        smbios_add_field(0, offsetof(struct smbios_type_0,
+                                     system_bios_major_release),
+                         &smbios_type0.major, 1);
+        smbios_add_field(0, offsetof(struct smbios_type_0,
+                                     system_bios_minor_release),
+                         &smbios_type0.minor, 1);
+    }
+}
+
+static void smbios_build_type_1_fields(void)
+{
+    smbios_maybe_add_str(1, offsetof(struct smbios_type_1, manufacturer_str),
+                         smbios_type1.manufacturer);
+    smbios_maybe_add_str(1, offsetof(struct smbios_type_1, product_name_str),
+                         smbios_type1.product);
+    smbios_maybe_add_str(1, offsetof(struct smbios_type_1, version_str),
+                         smbios_type1.version);
+    smbios_maybe_add_str(1, offsetof(struct smbios_type_1, serial_number_str),
+                         smbios_type1.serial);
+    smbios_maybe_add_str(1, offsetof(struct smbios_type_1, sku_number_str),
+                         smbios_type1.sku);
+    smbios_maybe_add_str(1, offsetof(struct smbios_type_1, family_str),
+                         smbios_type1.family);
+    if (qemu_uuid_set) {
+        /*
+         * We don't encode the UUID in the "wire format" here because this
+         * function is for legacy mode and needs to keep the guest ABI, and
+         * because we don't know what's the SMBIOS version advertised by the
+         * BIOS.
+         */
+        smbios_add_field(1, offsetof(struct smbios_type_1, uuid),
+                         &qemu_uuid, 16);
+    }
+}
+
+uint8_t *smbios_get_table_legacy(size_t *length)
+{
+    int i;
+    size_t usr_offset;
+
+    /* complain if fields were given for types > 1 */
+    if (find_next_bit(smbios_have_fields_bitmap,
+                      SMBIOS_MAX_TYPE + 1, 2) < SMBIOS_MAX_TYPE + 1) {
+        error_report("can't process fields for smbios "
+                     "types > 1 on machine versions < 2.1!");
+        exit(1);
+    }
+
+    if (test_bit(4, smbios_have_binfile_bitmap)) {
+        error_report("can't process table for smbios "
+                     "type 4 on machine versions < 2.1!");
+        exit(1);
+    }
+
+    g_free(smbios_entries);
+    smbios_entries_len = sizeof(uint16_t);
+    smbios_entries = g_malloc0(smbios_entries_len);
+
+    for (i = 0, usr_offset = 0; usr_blobs_sizes && i < usr_blobs_sizes->len;
+         i++)
+    {
+        struct smbios_table *table;
+        struct smbios_structure_header *header;
+        size_t size = g_array_index(usr_blobs_sizes, size_t, i);
+
+        header = (struct smbios_structure_header *)(usr_blobs + usr_offset);
+        smbios_entries = g_realloc(smbios_entries, smbios_entries_len +
+                                                   size + sizeof(*table));
+        table = (struct smbios_table *)(smbios_entries + smbios_entries_len);
+        table->header.type = SMBIOS_TABLE_ENTRY;
+        table->header.length = cpu_to_le16(sizeof(*table) + size);
+        memcpy(table->data, header, size);
+        smbios_entries_len += sizeof(*table) + size;
+        (*(uint16_t *)smbios_entries) =
+            cpu_to_le16(le16_to_cpu(*(uint16_t *)smbios_entries) + 1);
+        usr_offset += size;
+    }
+
+    smbios_build_type_0_fields();
+    smbios_build_type_1_fields();
+    smbios_validate_table();
+    *length = smbios_entries_len;
+    return smbios_entries;
+}
diff --git a/hw/smbios/smbios_legacy_stub.c b/hw/smbios/smbios_legacy_stub.c
new file mode 100644
index 0000000000..f29b15316c
--- /dev/null
+++ b/hw/smbios/smbios_legacy_stub.c
@@ -0,0 +1,15 @@
+/*
+ * IPMI SMBIOS firmware handling
+ *
+ * Copyright (c) 2024 Igor Mammedov, Red Hat, Inc.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "hw/firmware/smbios.h"
+
+void smbios_add_usr_blob_size(size_t size)
+{
+}
-- 
2.39.3



^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v3 12/20] smbios: handle errors consistently
  2024-03-12 16:10 [PATCH v3 00/20] Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS Igor Mammedov
                   ` (10 preceding siblings ...)
  2024-03-12 16:10 ` [PATCH v3 11/20] smbios: build legacy mode code only for 'pc' machine Igor Mammedov
@ 2024-03-12 16:10 ` Igor Mammedov
  2024-03-12 16:10 ` [PATCH v3 13/20] smbios: get rid of global smbios_ep_type Igor Mammedov
                   ` (9 subsequent siblings)
  21 siblings, 0 replies; 27+ messages in thread
From: Igor Mammedov @ 2024-03-12 16:10 UTC (permalink / raw)
  To: qemu-devel; +Cc: imammedo, mst, Ani Sinha

Current code uses mix of error_report()+exit(1)
and error_setg() to handle errors.
Use newer error_setg() everywhere, beside consistency
it will allow to detect error condition without killing
QEMU and attempt switch-over to SMBIOS3.x tables/entrypoint
in follow up patch.

while at it, clear smbios_tables pointer after freeing.
that will avoid double free if smbios_get_tables() is called
multiple times.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Ani Sinha <anisinha@redhat.com>
---
 include/hw/firmware/smbios.h |  4 ++--
 hw/i386/fw_cfg.c             |  3 ++-
 hw/smbios/smbios.c           | 34 ++++++++++++++++++++++------------
 hw/smbios/smbios_legacy.c    | 22 ++++++++++++++--------
 4 files changed, 40 insertions(+), 23 deletions(-)

diff --git a/include/hw/firmware/smbios.h b/include/hw/firmware/smbios.h
index 7f47475aa4..89bb10510a 100644
--- a/include/hw/firmware/smbios.h
+++ b/include/hw/firmware/smbios.h
@@ -309,7 +309,7 @@ struct smbios_type_127 {
     struct smbios_structure_header header;
 } QEMU_PACKED;
 
-void smbios_validate_table(void);
+bool smbios_validate_table(Error **errp);
 void smbios_add_usr_blob_size(size_t size);
 void smbios_entry_add(QemuOpts *opts, Error **errp);
 void smbios_set_cpuid(uint32_t version, uint32_t features);
@@ -317,7 +317,7 @@ void smbios_set_defaults(const char *manufacturer, const char *product,
                          const char *version,
                          bool uuid_encoded, SmbiosEntryPointType ep_type);
 void smbios_set_default_processor_family(uint16_t processor_family);
-uint8_t *smbios_get_table_legacy(size_t *length);
+uint8_t *smbios_get_table_legacy(size_t *length, Error **errp);
 void smbios_get_tables(MachineState *ms,
                        const struct smbios_phys_mem_area *mem_array,
                        const unsigned int mem_array_size,
diff --git a/hw/i386/fw_cfg.c b/hw/i386/fw_cfg.c
index d1281066f4..e387bf50d0 100644
--- a/hw/i386/fw_cfg.c
+++ b/hw/i386/fw_cfg.c
@@ -71,7 +71,8 @@ void fw_cfg_build_smbios(PCMachineState *pcms, FWCfgState *fw_cfg)
     smbios_set_cpuid(cpu->env.cpuid_version, cpu->env.features[FEAT_1_EDX]);
 
     if (pcmc->smbios_legacy_mode) {
-        smbios_tables = smbios_get_table_legacy(&smbios_tables_len);
+        smbios_tables = smbios_get_table_legacy(&smbios_tables_len,
+                                                &error_fatal);
         fw_cfg_add_bytes(fw_cfg, FW_CFG_SMBIOS_ENTRIES,
                          smbios_tables, smbios_tables_len);
         return;
diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c
index fb1f05fcde..d9ba2072b1 100644
--- a/hw/smbios/smbios.c
+++ b/hw/smbios/smbios.c
@@ -19,7 +19,6 @@
 #include "qemu/units.h"
 #include "qapi/error.h"
 #include "qemu/config-file.h"
-#include "qemu/error-report.h"
 #include "qemu/module.h"
 #include "qemu/option.h"
 #include "sysemu/sysemu.h"
@@ -448,23 +447,25 @@ opts_init(smbios_register_config);
  */
 #define SMBIOS_21_MAX_TABLES_LEN 0xffff
 
-static void smbios_check_type4_count(uint32_t expected_t4_count)
+static bool smbios_check_type4_count(uint32_t expected_t4_count, Error **errp)
 {
     if (smbios_type4_count && smbios_type4_count != expected_t4_count) {
-        error_report("Expected %d SMBIOS Type 4 tables, got %d instead",
-                     expected_t4_count, smbios_type4_count);
-        exit(1);
+        error_setg(errp, "Expected %d SMBIOS Type 4 tables, got %d instead",
+                   expected_t4_count, smbios_type4_count);
+        return false;
     }
+    return true;
 }
 
-void smbios_validate_table(void)
+bool smbios_validate_table(Error **errp)
 {
     if (smbios_ep_type == SMBIOS_ENTRY_POINT_TYPE_32 &&
         smbios_tables_len > SMBIOS_21_MAX_TABLES_LEN) {
-        error_report("SMBIOS 2.1 table length %zu exceeds %d",
-                     smbios_tables_len, SMBIOS_21_MAX_TABLES_LEN);
-        exit(1);
+        error_setg(errp, "SMBIOS 2.1 table length %zu exceeds %d",
+                   smbios_tables_len, SMBIOS_21_MAX_TABLES_LEN);
+        return false;
     }
+    return true;
 }
 
 bool smbios_skip_table(uint8_t type, bool required_table)
@@ -1027,15 +1028,18 @@ void smbios_get_tables(MachineState *ms,
     smbios_build_type_41_table(errp);
     smbios_build_type_127_table();
 
-    smbios_check_type4_count(ms->smp.sockets);
-    smbios_validate_table();
+    if (!smbios_check_type4_count(ms->smp.sockets, errp)) {
+        goto err_exit;
+    }
+    if (!smbios_validate_table(errp)) {
+        goto err_exit;
+    }
     smbios_entry_point_setup();
 
     /* return tables blob and entry point (anchor), and their sizes */
     *tables = smbios_tables;
     *tables_len = smbios_tables_len;
     *anchor = (uint8_t *)&ep;
-
     /* calculate length based on anchor string */
     if (!strncmp((char *)&ep, "_SM_", 4)) {
         *anchor_len = sizeof(struct smbios_21_entry_point);
@@ -1044,6 +1048,12 @@ void smbios_get_tables(MachineState *ms,
     } else {
         abort();
     }
+
+    return;
+err_exit:
+    g_free(smbios_tables);
+    smbios_tables = NULL;
+    return;
 }
 
 static void save_opt(const char **dest, QemuOpts *opts, const char *name)
diff --git a/hw/smbios/smbios_legacy.c b/hw/smbios/smbios_legacy.c
index 21f143e738..a6544bf55a 100644
--- a/hw/smbios/smbios_legacy.c
+++ b/hw/smbios/smbios_legacy.c
@@ -19,7 +19,7 @@
 #include "qemu/bswap.h"
 #include "hw/firmware/smbios.h"
 #include "sysemu/sysemu.h"
-#include "qemu/error-report.h"
+#include "qapi/error.h"
 
 struct smbios_header {
     uint16_t length;
@@ -128,7 +128,7 @@ static void smbios_build_type_1_fields(void)
     }
 }
 
-uint8_t *smbios_get_table_legacy(size_t *length)
+uint8_t *smbios_get_table_legacy(size_t *length, Error **errp)
 {
     int i;
     size_t usr_offset;
@@ -136,15 +136,15 @@ uint8_t *smbios_get_table_legacy(size_t *length)
     /* complain if fields were given for types > 1 */
     if (find_next_bit(smbios_have_fields_bitmap,
                       SMBIOS_MAX_TYPE + 1, 2) < SMBIOS_MAX_TYPE + 1) {
-        error_report("can't process fields for smbios "
+        error_setg(errp, "can't process fields for smbios "
                      "types > 1 on machine versions < 2.1!");
-        exit(1);
+        goto err_exit;
     }
 
     if (test_bit(4, smbios_have_binfile_bitmap)) {
-        error_report("can't process table for smbios "
-                     "type 4 on machine versions < 2.1!");
-        exit(1);
+        error_setg(errp, "can't process table for smbios "
+                   "type 4 on machine versions < 2.1!");
+        goto err_exit;
     }
 
     g_free(smbios_entries);
@@ -173,7 +173,13 @@ uint8_t *smbios_get_table_legacy(size_t *length)
 
     smbios_build_type_0_fields();
     smbios_build_type_1_fields();
-    smbios_validate_table();
+    if (!smbios_validate_table(errp)) {
+        goto err_exit;
+    }
+
     *length = smbios_entries_len;
     return smbios_entries;
+err_exit:
+    g_free(smbios_entries);
+    return NULL;
 }
-- 
2.39.3



^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v3 13/20] smbios: get rid of global smbios_ep_type
  2024-03-12 16:10 [PATCH v3 00/20] Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS Igor Mammedov
                   ` (11 preceding siblings ...)
  2024-03-12 16:10 ` [PATCH v3 12/20] smbios: handle errors consistently Igor Mammedov
@ 2024-03-12 16:10 ` Igor Mammedov
  2024-03-12 16:10 ` [PATCH v3 14/20] smbios: clear smbios_type4_count before building tables Igor Mammedov
                   ` (8 subsequent siblings)
  21 siblings, 0 replies; 27+ messages in thread
From: Igor Mammedov @ 2024-03-12 16:10 UTC (permalink / raw)
  To: qemu-devel; +Cc: imammedo, mst, Daniel Henrique Barboza, Ani Sinha, Fiona Ebner

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Acked-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: Ani Sinha <anisinha@redhat.com>
Tested-by: Fiona Ebner <f.ebner@proxmox.com>
---
 hw/i386/fw_cfg.h             |  3 ++-
 include/hw/firmware/smbios.h |  5 +++--
 hw/arm/virt.c                |  4 ++--
 hw/i386/fw_cfg.c             |  8 ++++----
 hw/i386/pc.c                 |  2 +-
 hw/loongarch/virt.c          |  7 ++++---
 hw/riscv/virt.c              |  6 +++---
 hw/smbios/smbios.c           | 27 +++++++++++++++------------
 hw/smbios/smbios_legacy.c    |  2 +-
 9 files changed, 35 insertions(+), 29 deletions(-)

diff --git a/hw/i386/fw_cfg.h b/hw/i386/fw_cfg.h
index 1e1de6b4a3..92e310f5fd 100644
--- a/hw/i386/fw_cfg.h
+++ b/hw/i386/fw_cfg.h
@@ -23,7 +23,8 @@
 FWCfgState *fw_cfg_arch_create(MachineState *ms,
                                uint16_t boot_cpus,
                                uint16_t apic_id_limit);
-void fw_cfg_build_smbios(PCMachineState *ms, FWCfgState *fw_cfg);
+void fw_cfg_build_smbios(PCMachineState *pcms, FWCfgState *fw_cfg,
+                         SmbiosEntryPointType ep_type);
 void fw_cfg_build_feature_control(MachineState *ms, FWCfgState *fw_cfg);
 void fw_cfg_add_acpi_dsdt(Aml *scope, FWCfgState *fw_cfg);
 
diff --git a/include/hw/firmware/smbios.h b/include/hw/firmware/smbios.h
index 89bb10510a..d128aef31d 100644
--- a/include/hw/firmware/smbios.h
+++ b/include/hw/firmware/smbios.h
@@ -309,16 +309,17 @@ struct smbios_type_127 {
     struct smbios_structure_header header;
 } QEMU_PACKED;
 
-bool smbios_validate_table(Error **errp);
+bool smbios_validate_table(SmbiosEntryPointType ep_type, Error **errp);
 void smbios_add_usr_blob_size(size_t size);
 void smbios_entry_add(QemuOpts *opts, Error **errp);
 void smbios_set_cpuid(uint32_t version, uint32_t features);
 void smbios_set_defaults(const char *manufacturer, const char *product,
                          const char *version,
-                         bool uuid_encoded, SmbiosEntryPointType ep_type);
+                         bool uuid_encoded);
 void smbios_set_default_processor_family(uint16_t processor_family);
 uint8_t *smbios_get_table_legacy(size_t *length, Error **errp);
 void smbios_get_tables(MachineState *ms,
+                       SmbiosEntryPointType ep_type,
                        const struct smbios_phys_mem_area *mem_array,
                        const unsigned int mem_array_size,
                        uint8_t **tables, size_t *tables_len,
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 8588681f27..780224ee5b 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -1634,13 +1634,13 @@ static void virt_build_smbios(VirtMachineState *vms)
 
     smbios_set_defaults("QEMU", product,
                         vmc->smbios_old_sys_ver ? "1.0" : mc->name,
-                        true, SMBIOS_ENTRY_POINT_TYPE_64);
+                        true);
 
     /* build the array of physical mem area from base_memmap */
     mem_array.address = vms->memmap[VIRT_MEM].base;
     mem_array.length = ms->ram_size;
 
-    smbios_get_tables(ms, &mem_array, 1,
+    smbios_get_tables(ms, SMBIOS_ENTRY_POINT_TYPE_64, &mem_array, 1,
                       &smbios_tables, &smbios_tables_len,
                       &smbios_anchor, &smbios_anchor_len,
                       &error_fatal);
diff --git a/hw/i386/fw_cfg.c b/hw/i386/fw_cfg.c
index e387bf50d0..d802d2787f 100644
--- a/hw/i386/fw_cfg.c
+++ b/hw/i386/fw_cfg.c
@@ -48,7 +48,8 @@ const char *fw_cfg_arch_key_name(uint16_t key)
     return NULL;
 }
 
-void fw_cfg_build_smbios(PCMachineState *pcms, FWCfgState *fw_cfg)
+void fw_cfg_build_smbios(PCMachineState *pcms, FWCfgState *fw_cfg,
+                         SmbiosEntryPointType ep_type)
 {
 #ifdef CONFIG_SMBIOS
     uint8_t *smbios_tables, *smbios_anchor;
@@ -63,8 +64,7 @@ void fw_cfg_build_smbios(PCMachineState *pcms, FWCfgState *fw_cfg)
     if (pcmc->smbios_defaults) {
         /* These values are guest ABI, do not change */
         smbios_set_defaults("QEMU", mc->desc, mc->name,
-                            pcmc->smbios_uuid_encoded,
-                            pcms->smbios_entry_point_type);
+                            pcmc->smbios_uuid_encoded);
     }
 
     /* tell smbios about cpuid version and features */
@@ -89,7 +89,7 @@ void fw_cfg_build_smbios(PCMachineState *pcms, FWCfgState *fw_cfg)
             array_count++;
         }
     }
-    smbios_get_tables(ms, mem_array, array_count,
+    smbios_get_tables(ms, ep_type, mem_array, array_count,
                       &smbios_tables, &smbios_tables_len,
                       &smbios_anchor, &smbios_anchor_len,
                       &error_fatal);
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index f5ff970acf..a8e8aa2ac8 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -691,7 +691,7 @@ void pc_machine_done(Notifier *notifier, void *data)
 
     acpi_setup();
     if (x86ms->fw_cfg) {
-        fw_cfg_build_smbios(pcms, x86ms->fw_cfg);
+        fw_cfg_build_smbios(pcms, x86ms->fw_cfg, pcms->smbios_entry_point_type);
         fw_cfg_build_feature_control(MACHINE(pcms), x86ms->fw_cfg);
         /* update FW_CFG_NB_CPUS to account for -device added CPUs */
         fw_cfg_modify_i16(x86ms->fw_cfg, FW_CFG_NB_CPUS, x86ms->boot_cpus);
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
index 8c7601ef91..05f616682a 100644
--- a/hw/loongarch/virt.c
+++ b/hw/loongarch/virt.c
@@ -355,10 +355,11 @@ static void virt_build_smbios(LoongArchMachineState *lams)
         return;
     }
 
-    smbios_set_defaults("QEMU", product, mc->name,
-                        true, SMBIOS_ENTRY_POINT_TYPE_64);
+    smbios_set_defaults("QEMU", product, mc->name, true);
 
-    smbios_get_tables(ms, NULL, 0, &smbios_tables, &smbios_tables_len,
+    smbios_get_tables(ms, SMBIOS_ENTRY_POINT_TYPE_64,
+                      NULL, 0,
+                      &smbios_tables, &smbios_tables_len,
                       &smbios_anchor, &smbios_anchor_len, &error_fatal);
 
     if (smbios_anchor) {
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index 535fd047ba..72a55b8af1 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -1275,8 +1275,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);
@@ -1288,7 +1287,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] 27+ messages in thread

* [PATCH v3 14/20] smbios: clear smbios_type4_count before building tables
  2024-03-12 16:10 [PATCH v3 00/20] Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS Igor Mammedov
                   ` (12 preceding siblings ...)
  2024-03-12 16:10 ` [PATCH v3 13/20] smbios: get rid of global smbios_ep_type Igor Mammedov
@ 2024-03-12 16:10 ` Igor Mammedov
  2024-03-12 16:10 ` [PATCH v3 15/20] smbios: extend smbios-entry-point-type with 'auto' value Igor Mammedov
                   ` (7 subsequent siblings)
  21 siblings, 0 replies; 27+ messages in thread
From: Igor Mammedov @ 2024-03-12 16:10 UTC (permalink / raw)
  To: qemu-devel; +Cc: imammedo, mst, Fiona Ebner

it will help to keep type 4 tables accounting correct in case
SMBIOS tables are built multiple times.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Tested-by: Fiona Ebner <f.ebner@proxmox.com>
---
 hw/smbios/smbios.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c
index 5a791fd9eb..d3d89b4dd0 100644
--- a/hw/smbios/smbios.c
+++ b/hw/smbios/smbios.c
@@ -973,6 +973,7 @@ void smbios_get_tables(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] 27+ messages in thread

* [PATCH v3 15/20] smbios: extend smbios-entry-point-type with 'auto' value
  2024-03-12 16:10 [PATCH v3 00/20] Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS Igor Mammedov
                   ` (13 preceding siblings ...)
  2024-03-12 16:10 ` [PATCH v3 14/20] smbios: clear smbios_type4_count before building tables Igor Mammedov
@ 2024-03-12 16:10 ` Igor Mammedov
  2024-03-12 16:10 ` [PATCH v3 16/20] smbios: in case of entry point is 'auto' try to build v2 tables 1st Igor Mammedov
                   ` (6 subsequent siblings)
  21 siblings, 0 replies; 27+ messages in thread
From: Igor Mammedov @ 2024-03-12 16:10 UTC (permalink / raw)
  To: qemu-devel; +Cc: imammedo, mst, Markus Armbruster, Ani Sinha, Fiona Ebner

later patches will use it to pick SMBIOS version at runtime
depending on configuration.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Acked-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Ani Sinha <anisinha@redhat.com>
Tested-by: Fiona Ebner <f.ebner@proxmox.com>
---
v3:
    - make sure i2nd line of comment is indented on 4 spaces only
---
 qapi/machine.json | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/qapi/machine.json b/qapi/machine.json
index bb5a178909..0840c91e70 100644
--- a/qapi/machine.json
+++ b/qapi/machine.json
@@ -1797,10 +1797,13 @@
 #
 # @64: SMBIOS version 3.0 (64-bit) Entry Point
 #
+# @auto: Either 2.x or 3.x SMBIOS version, 2.x if configuration can be
+#     described by it and 3.x otherwise (since: 9.0)
+#
 # Since: 7.0
 ##
 { 'enum': 'SmbiosEntryPointType',
-  'data': [ '32', '64' ] }
+  'data': [ '32', '64', 'auto' ] }
 
 ##
 # @MemorySizeConfiguration:
-- 
2.39.3



^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v3 16/20] smbios: in case of entry point is 'auto' try to build v2 tables 1st
  2024-03-12 16:10 [PATCH v3 00/20] Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS Igor Mammedov
                   ` (14 preceding siblings ...)
  2024-03-12 16:10 ` [PATCH v3 15/20] smbios: extend smbios-entry-point-type with 'auto' value Igor Mammedov
@ 2024-03-12 16:10 ` Igor Mammedov
  2024-03-12 16:10 ` [PATCH v3 17/20] smbios: error out when building type 4 table is not possible Igor Mammedov
                   ` (5 subsequent siblings)
  21 siblings, 0 replies; 27+ messages in thread
From: Igor Mammedov @ 2024-03-12 16:10 UTC (permalink / raw)
  To: qemu-devel; +Cc: imammedo, mst, Ani Sinha, Fiona Ebner

QEMU for some time now uses SMBIOS 3.0 for PC/Q35 machines by
default, however Windows has a bug in locating SMBIOS 3.0
entrypoint and fails to find tables when booted on SeaBIOS
(on UEFI SMBIOS 3.0 tables work fine since firmware hands
over tables in another way)

Missing SMBIOS tables may lead to some issues for guest
though (worst are: possible reactiveation, inability to
get virtio drivers from 'Windows Update')

It's unclear  at this point if MS will fix the issue on their
side. So instead of it (or rather in addition) this patch
will try to workaround the issue.

aka, use smbios-entry-point-type=auto to make QEMU try
generating conservative SMBIOS 2.0 tables and if that
fails (due to limits/requested configuration) fallback
to SMBIOS 3.0 tables.

With this in place majority of users will use SMBIOS 2.0
tables which work fine with (Windows + legacy BIOS).
The configurations that is not to possible to describe
with SMBIOS 2.0 will switch automatically to SMBIOS 3.0
(which will trigger Windows bug but there is nothing
QEMU can do here, so go and aks Microsoft to real fix).

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Ani Sinha <anisinha@redhat.com>
Tested-by: Fiona Ebner <f.ebner@proxmox.com>
---
 hw/smbios/smbios.c | 52 +++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 49 insertions(+), 3 deletions(-)

diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c
index d3d89b4dd0..c4a953bbc9 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);
@@ -1053,11 +1054,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] 27+ messages in thread

* [PATCH v3 17/20] smbios: error out when building type 4 table is not possible
  2024-03-12 16:10 [PATCH v3 00/20] Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS Igor Mammedov
                   ` (15 preceding siblings ...)
  2024-03-12 16:10 ` [PATCH v3 16/20] smbios: in case of entry point is 'auto' try to build v2 tables 1st Igor Mammedov
@ 2024-03-12 16:10 ` Igor Mammedov
  2024-03-12 16:10 ` [PATCH v3 18/20] tests: acpi/smbios: whitelist expected blobs Igor Mammedov
                   ` (4 subsequent siblings)
  21 siblings, 0 replies; 27+ messages in thread
From: Igor Mammedov @ 2024-03-12 16:10 UTC (permalink / raw)
  To: qemu-devel; +Cc: imammedo, mst, Ani Sinha, Fiona Ebner

If SMBIOS v2 version is requested but number of cores/threads
are more than it's possible to describe with v2, error out
instead of silently ignoring the fact and filling core/thread
count with bogus values.

This will help caller to decide if it should fallback to
SMBIOSv3 when smbios-entry-point-type='auto'

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Ani Sinha <anisinha@redhat.com>
Tested-by: Fiona Ebner <f.ebner@proxmox.com>
---
 hw/smbios/smbios.c | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c
index c4a953bbc9..b64d3bc227 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;
@@ -988,7 +995,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] 27+ messages in thread

* [PATCH v3 18/20] tests: acpi/smbios: whitelist expected blobs
  2024-03-12 16:10 [PATCH v3 00/20] Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS Igor Mammedov
                   ` (16 preceding siblings ...)
  2024-03-12 16:10 ` [PATCH v3 17/20] smbios: error out when building type 4 table is not possible Igor Mammedov
@ 2024-03-12 16:10 ` Igor Mammedov
  2024-03-12 16:10 ` [PATCH v3 19/20] pc/q35: set SMBIOS entry point type to 'auto' by default Igor Mammedov
                   ` (3 subsequent siblings)
  21 siblings, 0 replies; 27+ messages in thread
From: Igor Mammedov @ 2024-03-12 16:10 UTC (permalink / raw)
  To: qemu-devel; +Cc: imammedo, mst, Ani Sinha

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Acked-by: Ani Sinha <anisinha@redhat.com>
---
 tests/qtest/bios-tables-test-allowed-diff.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h
index dfb8523c8b..81148a604f 100644
--- a/tests/qtest/bios-tables-test-allowed-diff.h
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
@@ -1 +1,2 @@
 /* List of comma-separated changed AML files to ignore */
+"tests/data/acpi/q35/SSDT.dimmpxm",
-- 
2.39.3



^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v3 19/20] pc/q35: set SMBIOS entry point type to 'auto' by default
  2024-03-12 16:10 [PATCH v3 00/20] Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS Igor Mammedov
                   ` (17 preceding siblings ...)
  2024-03-12 16:10 ` [PATCH v3 18/20] tests: acpi/smbios: whitelist expected blobs Igor Mammedov
@ 2024-03-12 16:10 ` Igor Mammedov
  2024-03-12 16:10 ` [PATCH v3 20/20] tests: acpi: update expected SSDT.dimmpxm blob Igor Mammedov
                   ` (2 subsequent siblings)
  21 siblings, 0 replies; 27+ messages in thread
From: Igor Mammedov @ 2024-03-12 16:10 UTC (permalink / raw)
  To: qemu-devel; +Cc: imammedo, mst, Ani Sinha, Fiona Ebner

Use smbios-entry-point-type='auto' for newer machine types as a workaround
for Windows not detecting SMBIOS tables. Which makes QEMU pick SMBIOS tables
based on configuration (with 2.x preferred and fallback to 3.x if the former
isn't compatible with configuration)

Default compat setting of smbios-entry-point-type after series
for pc/q35 machines:
  * 9.0-newer: 'auto'
  * 8.1-8.2: '64'
  * 8.0-older: '32'

Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2008
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Ani Sinha <anisinha@redhat.com>
Tested-by: Fiona Ebner <f.ebner@proxmox.com>
---
 hw/i386/pc.c      | 2 +-
 hw/i386/pc_piix.c | 4 ++++
 hw/i386/pc_q35.c  | 3 +++
 3 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index a8e8aa2ac8..cf16337341 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1847,7 +1847,7 @@ static void pc_machine_class_init(ObjectClass *oc, void *data)
     mc->nvdimm_supported = true;
     mc->smp_props.dies_supported = true;
     mc->default_ram_id = "pc.ram";
-    pcmc->default_smbios_ep_type = SMBIOS_ENTRY_POINT_TYPE_64;
+    pcmc->default_smbios_ep_type = SMBIOS_ENTRY_POINT_TYPE_AUTO;
 
     object_class_property_add(oc, PC_MACHINE_MAX_RAM_BELOW_4G, "size",
         pc_machine_get_max_ram_below_4g, pc_machine_set_max_ram_below_4g,
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 319bc4b180..bb80c10b96 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -526,12 +526,16 @@ DEFINE_I440FX_MACHINE(v9_0, "pc-i440fx-9.0", NULL,
 
 static void pc_i440fx_8_2_machine_options(MachineClass *m)
 {
+    PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
+
     pc_i440fx_9_0_machine_options(m);
     m->alias = NULL;
     m->is_default = false;
 
     compat_props_add(m->compat_props, hw_compat_8_2, hw_compat_8_2_len);
     compat_props_add(m->compat_props, pc_compat_8_2, pc_compat_8_2_len);
+    /* For pc-i44fx-8.2 and 8.1, use SMBIOS 3.X by default */
+    pcmc->default_smbios_ep_type = SMBIOS_ENTRY_POINT_TYPE_64;
 }
 
 DEFINE_I440FX_MACHINE(v8_2, "pc-i440fx-8.2", NULL,
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index 45a4102e75..6fef3b17bb 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -369,10 +369,13 @@ DEFINE_Q35_MACHINE(v9_0, "pc-q35-9.0", NULL,
 
 static void pc_q35_8_2_machine_options(MachineClass *m)
 {
+    PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
     pc_q35_9_0_machine_options(m);
     m->alias = NULL;
     compat_props_add(m->compat_props, hw_compat_8_2, hw_compat_8_2_len);
     compat_props_add(m->compat_props, pc_compat_8_2, pc_compat_8_2_len);
+    /* For pc-q35-8.2 and 8.1, use SMBIOS 3.X by default */
+    pcmc->default_smbios_ep_type = SMBIOS_ENTRY_POINT_TYPE_64;
 }
 
 DEFINE_Q35_MACHINE(v8_2, "pc-q35-8.2", NULL,
-- 
2.39.3



^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v3 20/20] tests: acpi: update expected SSDT.dimmpxm blob
  2024-03-12 16:10 [PATCH v3 00/20] Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS Igor Mammedov
                   ` (18 preceding siblings ...)
  2024-03-12 16:10 ` [PATCH v3 19/20] pc/q35: set SMBIOS entry point type to 'auto' by default Igor Mammedov
@ 2024-03-12 16:10 ` Igor Mammedov
  2024-03-12 17:31 ` [PATCH v3 00/20] Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS Michael S. Tsirkin
  2024-03-12 17:37 ` Michael S. Tsirkin
  21 siblings, 0 replies; 27+ messages in thread
From: Igor Mammedov @ 2024-03-12 16:10 UTC (permalink / raw)
  To: qemu-devel; +Cc: imammedo, mst, Ani Sinha

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>
Acked-by: Ani Sinha <anisinha@redhat.com>
---
 tests/qtest/bios-tables-test-allowed-diff.h |   1 -
 tests/data/acpi/q35/SSDT.dimmpxm            | Bin 1815 -> 1815 bytes
 2 files changed, 1 deletion(-)

diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h
index 81148a604f..dfb8523c8b 100644
--- a/tests/qtest/bios-tables-test-allowed-diff.h
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
@@ -1,2 +1 @@
 /* List of comma-separated changed AML files to ignore */
-"tests/data/acpi/q35/SSDT.dimmpxm",
diff --git a/tests/data/acpi/q35/SSDT.dimmpxm b/tests/data/acpi/q35/SSDT.dimmpxm
index 70f133412f5e0aa128ab210245a8de7304eeb843..9ea4e0d0ceaa8a5cbd706afb6d49de853fafe654 100644
GIT binary patch
delta 23
ecmbQvH=U0wIM^jboSlJzam_|9E_UV*|JeaVTLvQl

delta 23
ecmbQvH=U0wIM^jboSlJzanD9BE_UVz|JeaVy9Ofw

-- 
2.39.3



^ permalink raw reply related	[flat|nested] 27+ messages in thread

* Re: [PATCH v3 00/20] Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS
  2024-03-12 16:10 [PATCH v3 00/20] Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS Igor Mammedov
                   ` (19 preceding siblings ...)
  2024-03-12 16:10 ` [PATCH v3 20/20] tests: acpi: update expected SSDT.dimmpxm blob Igor Mammedov
@ 2024-03-12 17:31 ` Michael S. Tsirkin
  2024-03-13  8:49   ` Igor Mammedov
  2024-03-12 17:37 ` Michael S. Tsirkin
  21 siblings, 1 reply; 27+ messages in thread
From: Michael S. Tsirkin @ 2024-03-12 17:31 UTC (permalink / raw)
  To: Igor Mammedov; +Cc: qemu-devel

On Tue, Mar 12, 2024 at 05:10:30PM +0100, Igor Mammedov wrote:
> Changelog:
>  v3:
>    * whitespace missed by checkpatch
>    * fix idndent in QAPI
>    * reorder 17/20 before 1st 'auto' can be used
>    * pick up acks
>  v2:
>    * QAPI style fixes (Markus Armbruster <armbru@redhat.com>)
>    * squash 11/19 into 10/19 (Ani Sinha <anisinha@redhat.com>)
>    * split '[PATCH 09/19] smbios: build legacy mode code only for 'pc' machine'
>      in 3 smaller patches, to make it more readable
>        smbios: add smbios_add_usr_blob_size() helper                                  
>        smbios: rename/expose structures/bitmaps used by both legacy and modern code                                                                  
>        smbios: build legacy mode code only for 'pc' machine
>    * pick up acks

thanks!
of course this conflicts with
SMBIOS type 9
and I am trying to figure out how to resolve this again.
Do you ack SMBIOS type 9 btw?

> Windows (10) bootloader when running on top of SeaBIOS, fails to find            
> SMBIOSv3 entry point. Tracing it shows that it looks for v2 anchor markers       
> only and not v3. Tricking it into believing that entry point is found            
> lets Windows successfully locate and parse SMBIOSv3 tables. Whether it           
> will be fixed on Windows side is not clear so here goes a workaround.            
>                                                                                  
> Idea is to try build v2 tables if QEMU configuration permits,                    
> and fallback to v3 tables otherwise. That will mask Windows issue                
> form majority of users.                                                          
> However if VM configuration can't be described (typically large VMs)             
> by v2 tables, QEMU will use SMBIOSv3 and Windows will hit the issue              
> again. In this case complain to Microsoft and/or use UEFI instead of             
> SeaBIOS (requires reinstall).                                                    
>                                                                                  
> Default compat setting of smbios-entry-point-type after series                   
> for pc/q35 machines:                                                             
>   * 9.0-newer: 'auto'                                                            
>   * 8.1-8.2: '64'                                                                
>   * 8.0-older: '32'                                                              
>                                                                                  
> Fixes: https://gitlab.com/qemu-project/qemu/-/issues/2008                        
> CC: imammedo@redhat.com                                                          
> CC: mst@redhat.com
> 
> Igor Mammedov (20):
>   tests: smbios: make it possible to write SMBIOS only test
>   tests: smbios: add test for -smbios type=11 option
>   tests: smbios: add test for legacy mode CLI options
>   smbios: cleanup smbios_get_tables() from legacy handling
>   smbios: get rid of smbios_smp_sockets global
>   smbios: get rid of smbios_legacy global
>   smbios: avoid mangling user provided tables
>   smbios: don't check type4 structures in legacy mode
>   smbios: add smbios_add_usr_blob_size() helper
>   smbios: rename/expose structures/bitmaps used by both legacy and
>     modern code
>   smbios: build legacy mode code only for 'pc' machine
>   smbios: handle errors consistently
>   smbios: get rid of global smbios_ep_type
>   smbios: clear smbios_type4_count before building tables
>   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
>   tests: acpi/smbios: whitelist expected blobs
>   pc/q35: set SMBIOS entry point type to 'auto' by default
>   tests: acpi: update expected SSDT.dimmpxm blob
> 
>  hw/i386/fw_cfg.h                     |   3 +-
>  include/hw/firmware/smbios.h         |  28 +-
>  hw/arm/virt.c                        |   6 +-
>  hw/i386/Kconfig                      |   1 +
>  hw/i386/fw_cfg.c                     |  14 +-
>  hw/i386/pc.c                         |   4 +-
>  hw/i386/pc_piix.c                    |   4 +
>  hw/i386/pc_q35.c                     |   3 +
>  hw/loongarch/virt.c                  |   7 +-
>  hw/riscv/virt.c                      |   6 +-
>  hw/smbios/Kconfig                    |   2 +
>  hw/smbios/meson.build                |   4 +
>  hw/smbios/smbios.c                   | 481 +++++++++++----------------
>  hw/smbios/smbios_legacy.c            | 185 +++++++++++
>  hw/smbios/smbios_legacy_stub.c       |  15 +
>  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, 533 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] 27+ messages in thread

* Re: [PATCH v3 00/20] Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS
  2024-03-12 16:10 [PATCH v3 00/20] Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS Igor Mammedov
                   ` (20 preceding siblings ...)
  2024-03-12 17:31 ` [PATCH v3 00/20] Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS Michael S. Tsirkin
@ 2024-03-12 17:37 ` Michael S. Tsirkin
  21 siblings, 0 replies; 27+ messages in thread
From: Michael S. Tsirkin @ 2024-03-12 17:37 UTC (permalink / raw)
  To: Igor Mammedov; +Cc: qemu-devel

On Tue, Mar 12, 2024 at 05:10:30PM +0100, Igor Mammedov wrote:
> Changelog:
>  v3:
>    * whitespace missed by checkpatch
>    * fix idndent in QAPI
>    * reorder 17/20 before 1st 'auto' can be used
>    * pick up acks
>  v2:
>    * QAPI style fixes (Markus Armbruster <armbru@redhat.com>)
>    * squash 11/19 into 10/19 (Ani Sinha <anisinha@redhat.com>)
>    * split '[PATCH 09/19] smbios: build legacy mode code only for 'pc' machine'
>      in 3 smaller patches, to make it more readable
>        smbios: add smbios_add_usr_blob_size() helper                                  
>        smbios: rename/expose structures/bitmaps used by both legacy and modern code                                                                  
>        smbios: build legacy mode code only for 'pc' machine
>    * pick up acks

I think I'll do this after the freeze, it's a bugfix so ok to do then.
Will probably need a rebase, too.


> Windows (10) bootloader when running on top of SeaBIOS, fails to find            
> SMBIOSv3 entry point. Tracing it shows that it looks for v2 anchor markers       
> only and not v3. Tricking it into believing that entry point is found            
> lets Windows successfully locate and parse SMBIOSv3 tables. Whether it           
> will be fixed on Windows side is not clear so here goes a workaround.            
>                                                                                  
> Idea is to try build v2 tables if QEMU configuration permits,                    
> and fallback to v3 tables otherwise. That will mask Windows issue                
> form majority of users.                                                          
> However if VM configuration can't be described (typically large VMs)             
> by v2 tables, QEMU will use SMBIOSv3 and Windows will hit the issue              
> again. In this case complain to Microsoft and/or use UEFI instead of             
> SeaBIOS (requires reinstall).                                                    
>                                                                                  
> Default compat setting of smbios-entry-point-type after series                   
> for pc/q35 machines:                                                             
>   * 9.0-newer: 'auto'                                                            
>   * 8.1-8.2: '64'                                                                
>   * 8.0-older: '32'                                                              
>                                                                                  
> Fixes: https://gitlab.com/qemu-project/qemu/-/issues/2008                        
> CC: imammedo@redhat.com                                                          
> CC: mst@redhat.com
> 
> Igor Mammedov (20):
>   tests: smbios: make it possible to write SMBIOS only test
>   tests: smbios: add test for -smbios type=11 option
>   tests: smbios: add test for legacy mode CLI options
>   smbios: cleanup smbios_get_tables() from legacy handling
>   smbios: get rid of smbios_smp_sockets global
>   smbios: get rid of smbios_legacy global
>   smbios: avoid mangling user provided tables
>   smbios: don't check type4 structures in legacy mode
>   smbios: add smbios_add_usr_blob_size() helper
>   smbios: rename/expose structures/bitmaps used by both legacy and
>     modern code
>   smbios: build legacy mode code only for 'pc' machine
>   smbios: handle errors consistently
>   smbios: get rid of global smbios_ep_type
>   smbios: clear smbios_type4_count before building tables
>   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
>   tests: acpi/smbios: whitelist expected blobs
>   pc/q35: set SMBIOS entry point type to 'auto' by default
>   tests: acpi: update expected SSDT.dimmpxm blob
> 
>  hw/i386/fw_cfg.h                     |   3 +-
>  include/hw/firmware/smbios.h         |  28 +-
>  hw/arm/virt.c                        |   6 +-
>  hw/i386/Kconfig                      |   1 +
>  hw/i386/fw_cfg.c                     |  14 +-
>  hw/i386/pc.c                         |   4 +-
>  hw/i386/pc_piix.c                    |   4 +
>  hw/i386/pc_q35.c                     |   3 +
>  hw/loongarch/virt.c                  |   7 +-
>  hw/riscv/virt.c                      |   6 +-
>  hw/smbios/Kconfig                    |   2 +
>  hw/smbios/meson.build                |   4 +
>  hw/smbios/smbios.c                   | 481 +++++++++++----------------
>  hw/smbios/smbios_legacy.c            | 185 +++++++++++
>  hw/smbios/smbios_legacy_stub.c       |  15 +
>  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, 533 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] 27+ messages in thread

* Re: [PATCH v3 00/20] Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS
  2024-03-12 17:31 ` [PATCH v3 00/20] Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS Michael S. Tsirkin
@ 2024-03-13  8:49   ` Igor Mammedov
  2024-03-13  9:10     ` Michael S. Tsirkin
  2024-03-13 22:51     ` Michael S. Tsirkin
  0 siblings, 2 replies; 27+ messages in thread
From: Igor Mammedov @ 2024-03-13  8:49 UTC (permalink / raw)
  To: Michael S. Tsirkin; +Cc: qemu-devel

On Tue, 12 Mar 2024 13:31:39 -0400
"Michael S. Tsirkin" <mst@redhat.com> wrote:

> On Tue, Mar 12, 2024 at 05:10:30PM +0100, Igor Mammedov wrote:
> > Changelog:
> >  v3:
> >    * whitespace missed by checkpatch
> >    * fix idndent in QAPI
> >    * reorder 17/20 before 1st 'auto' can be used
> >    * pick up acks
> >  v2:
> >    * QAPI style fixes (Markus Armbruster <armbru@redhat.com>)
> >    * squash 11/19 into 10/19 (Ani Sinha <anisinha@redhat.com>)
> >    * split '[PATCH 09/19] smbios: build legacy mode code only for 'pc' machine'
> >      in 3 smaller patches, to make it more readable
> >        smbios: add smbios_add_usr_blob_size() helper                                  
> >        smbios: rename/expose structures/bitmaps used by both legacy and modern code                                                                  
> >        smbios: build legacy mode code only for 'pc' machine
> >    * pick up acks  
> 
> thanks!
> of course this conflicts with
> SMBIOS type 9
> and I am trying to figure out how to resolve this again.

I'll rebase once your pull req is merged. 

> Do you ack SMBIOS type 9 btw?
nope, and it seems it's too late do so now.

> 
> > Windows (10) bootloader when running on top of SeaBIOS, fails to find            
> > SMBIOSv3 entry point. Tracing it shows that it looks for v2 anchor markers       
> > only and not v3. Tricking it into believing that entry point is found            
> > lets Windows successfully locate and parse SMBIOSv3 tables. Whether it           
> > will be fixed on Windows side is not clear so here goes a workaround.            
> >                                                                                  
> > Idea is to try build v2 tables if QEMU configuration permits,                    
> > and fallback to v3 tables otherwise. That will mask Windows issue                
> > form majority of users.                                                          
> > However if VM configuration can't be described (typically large VMs)             
> > by v2 tables, QEMU will use SMBIOSv3 and Windows will hit the issue              
> > again. In this case complain to Microsoft and/or use UEFI instead of             
> > SeaBIOS (requires reinstall).                                                    
> >                                                                                  
> > Default compat setting of smbios-entry-point-type after series                   
> > for pc/q35 machines:                                                             
> >   * 9.0-newer: 'auto'                                                            
> >   * 8.1-8.2: '64'                                                                
> >   * 8.0-older: '32'                                                              
> >                                                                                  
> > Fixes: https://gitlab.com/qemu-project/qemu/-/issues/2008                        
> > CC: imammedo@redhat.com                                                          
> > CC: mst@redhat.com
> > 
> > Igor Mammedov (20):
> >   tests: smbios: make it possible to write SMBIOS only test
> >   tests: smbios: add test for -smbios type=11 option
> >   tests: smbios: add test for legacy mode CLI options
> >   smbios: cleanup smbios_get_tables() from legacy handling
> >   smbios: get rid of smbios_smp_sockets global
> >   smbios: get rid of smbios_legacy global
> >   smbios: avoid mangling user provided tables
> >   smbios: don't check type4 structures in legacy mode
> >   smbios: add smbios_add_usr_blob_size() helper
> >   smbios: rename/expose structures/bitmaps used by both legacy and
> >     modern code
> >   smbios: build legacy mode code only for 'pc' machine
> >   smbios: handle errors consistently
> >   smbios: get rid of global smbios_ep_type
> >   smbios: clear smbios_type4_count before building tables
> >   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
> >   tests: acpi/smbios: whitelist expected blobs
> >   pc/q35: set SMBIOS entry point type to 'auto' by default
> >   tests: acpi: update expected SSDT.dimmpxm blob
> > 
> >  hw/i386/fw_cfg.h                     |   3 +-
> >  include/hw/firmware/smbios.h         |  28 +-
> >  hw/arm/virt.c                        |   6 +-
> >  hw/i386/Kconfig                      |   1 +
> >  hw/i386/fw_cfg.c                     |  14 +-
> >  hw/i386/pc.c                         |   4 +-
> >  hw/i386/pc_piix.c                    |   4 +
> >  hw/i386/pc_q35.c                     |   3 +
> >  hw/loongarch/virt.c                  |   7 +-
> >  hw/riscv/virt.c                      |   6 +-
> >  hw/smbios/Kconfig                    |   2 +
> >  hw/smbios/meson.build                |   4 +
> >  hw/smbios/smbios.c                   | 481 +++++++++++----------------
> >  hw/smbios/smbios_legacy.c            | 185 +++++++++++
> >  hw/smbios/smbios_legacy_stub.c       |  15 +
> >  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, 533 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] 27+ messages in thread

* Re: [PATCH v3 00/20] Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS
  2024-03-13  8:49   ` Igor Mammedov
@ 2024-03-13  9:10     ` Michael S. Tsirkin
  2024-03-13 22:51     ` Michael S. Tsirkin
  1 sibling, 0 replies; 27+ messages in thread
From: Michael S. Tsirkin @ 2024-03-13  9:10 UTC (permalink / raw)
  To: Igor Mammedov; +Cc: qemu-devel

On Wed, Mar 13, 2024 at 09:49:39AM +0100, Igor Mammedov wrote:
> On Tue, 12 Mar 2024 13:31:39 -0400
> "Michael S. Tsirkin" <mst@redhat.com> wrote:
> 
> > On Tue, Mar 12, 2024 at 05:10:30PM +0100, Igor Mammedov wrote:
> > > Changelog:
> > >  v3:
> > >    * whitespace missed by checkpatch
> > >    * fix idndent in QAPI
> > >    * reorder 17/20 before 1st 'auto' can be used
> > >    * pick up acks
> > >  v2:
> > >    * QAPI style fixes (Markus Armbruster <armbru@redhat.com>)
> > >    * squash 11/19 into 10/19 (Ani Sinha <anisinha@redhat.com>)
> > >    * split '[PATCH 09/19] smbios: build legacy mode code only for 'pc' machine'
> > >      in 3 smaller patches, to make it more readable
> > >        smbios: add smbios_add_usr_blob_size() helper                                  
> > >        smbios: rename/expose structures/bitmaps used by both legacy and modern code                                                                  
> > >        smbios: build legacy mode code only for 'pc' machine
> > >    * pick up acks  
> > 
> > thanks!
> > of course this conflicts with
> > SMBIOS type 9
> > and I am trying to figure out how to resolve this again.
> 
> I'll rebase once your pull req is merged. 
> 
> > Do you ack SMBIOS type 9 btw?
> nope, and it seems it's too late do so now.

I mean if there's a big problem I can always revert after
freeze or we can apply a fixup.


> > 
> > > Windows (10) bootloader when running on top of SeaBIOS, fails to find            
> > > SMBIOSv3 entry point. Tracing it shows that it looks for v2 anchor markers       
> > > only and not v3. Tricking it into believing that entry point is found            
> > > lets Windows successfully locate and parse SMBIOSv3 tables. Whether it           
> > > will be fixed on Windows side is not clear so here goes a workaround.            
> > >                                                                                  
> > > Idea is to try build v2 tables if QEMU configuration permits,                    
> > > and fallback to v3 tables otherwise. That will mask Windows issue                
> > > form majority of users.                                                          
> > > However if VM configuration can't be described (typically large VMs)             
> > > by v2 tables, QEMU will use SMBIOSv3 and Windows will hit the issue              
> > > again. In this case complain to Microsoft and/or use UEFI instead of             
> > > SeaBIOS (requires reinstall).                                                    
> > >                                                                                  
> > > Default compat setting of smbios-entry-point-type after series                   
> > > for pc/q35 machines:                                                             
> > >   * 9.0-newer: 'auto'                                                            
> > >   * 8.1-8.2: '64'                                                                
> > >   * 8.0-older: '32'                                                              
> > >                                                                                  
> > > Fixes: https://gitlab.com/qemu-project/qemu/-/issues/2008                        
> > > CC: imammedo@redhat.com                                                          
> > > CC: mst@redhat.com
> > > 
> > > Igor Mammedov (20):
> > >   tests: smbios: make it possible to write SMBIOS only test
> > >   tests: smbios: add test for -smbios type=11 option
> > >   tests: smbios: add test for legacy mode CLI options
> > >   smbios: cleanup smbios_get_tables() from legacy handling
> > >   smbios: get rid of smbios_smp_sockets global
> > >   smbios: get rid of smbios_legacy global
> > >   smbios: avoid mangling user provided tables
> > >   smbios: don't check type4 structures in legacy mode
> > >   smbios: add smbios_add_usr_blob_size() helper
> > >   smbios: rename/expose structures/bitmaps used by both legacy and
> > >     modern code
> > >   smbios: build legacy mode code only for 'pc' machine
> > >   smbios: handle errors consistently
> > >   smbios: get rid of global smbios_ep_type
> > >   smbios: clear smbios_type4_count before building tables
> > >   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
> > >   tests: acpi/smbios: whitelist expected blobs
> > >   pc/q35: set SMBIOS entry point type to 'auto' by default
> > >   tests: acpi: update expected SSDT.dimmpxm blob
> > > 
> > >  hw/i386/fw_cfg.h                     |   3 +-
> > >  include/hw/firmware/smbios.h         |  28 +-
> > >  hw/arm/virt.c                        |   6 +-
> > >  hw/i386/Kconfig                      |   1 +
> > >  hw/i386/fw_cfg.c                     |  14 +-
> > >  hw/i386/pc.c                         |   4 +-
> > >  hw/i386/pc_piix.c                    |   4 +
> > >  hw/i386/pc_q35.c                     |   3 +
> > >  hw/loongarch/virt.c                  |   7 +-
> > >  hw/riscv/virt.c                      |   6 +-
> > >  hw/smbios/Kconfig                    |   2 +
> > >  hw/smbios/meson.build                |   4 +
> > >  hw/smbios/smbios.c                   | 481 +++++++++++----------------
> > >  hw/smbios/smbios_legacy.c            | 185 +++++++++++
> > >  hw/smbios/smbios_legacy_stub.c       |  15 +
> > >  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, 533 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] 27+ messages in thread

* Re: [PATCH v3 00/20] Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS
  2024-03-13  8:49   ` Igor Mammedov
  2024-03-13  9:10     ` Michael S. Tsirkin
@ 2024-03-13 22:51     ` Michael S. Tsirkin
  1 sibling, 0 replies; 27+ messages in thread
From: Michael S. Tsirkin @ 2024-03-13 22:51 UTC (permalink / raw)
  To: Igor Mammedov; +Cc: qemu-devel

On Wed, Mar 13, 2024 at 09:49:39AM +0100, Igor Mammedov wrote:
> On Tue, 12 Mar 2024 13:31:39 -0400
> "Michael S. Tsirkin" <mst@redhat.com> wrote:
> 
> > On Tue, Mar 12, 2024 at 05:10:30PM +0100, Igor Mammedov wrote:
> > > Changelog:
> > >  v3:
> > >    * whitespace missed by checkpatch
> > >    * fix idndent in QAPI
> > >    * reorder 17/20 before 1st 'auto' can be used
> > >    * pick up acks
> > >  v2:
> > >    * QAPI style fixes (Markus Armbruster <armbru@redhat.com>)
> > >    * squash 11/19 into 10/19 (Ani Sinha <anisinha@redhat.com>)
> > >    * split '[PATCH 09/19] smbios: build legacy mode code only for 'pc' machine'
> > >      in 3 smaller patches, to make it more readable
> > >        smbios: add smbios_add_usr_blob_size() helper                                  
> > >        smbios: rename/expose structures/bitmaps used by both legacy and modern code                                                                  
> > >        smbios: build legacy mode code only for 'pc' machine
> > >    * pick up acks  
> > 
> > thanks!
> > of course this conflicts with
> > SMBIOS type 9
> > and I am trying to figure out how to resolve this again.
> 
> I'll rebase once your pull req is merged. 

Note it's merged already.

> > Do you ack SMBIOS type 9 btw?
> nope, and it seems it's too late do so now.
> 
> > 
> > > Windows (10) bootloader when running on top of SeaBIOS, fails to find            
> > > SMBIOSv3 entry point. Tracing it shows that it looks for v2 anchor markers       
> > > only and not v3. Tricking it into believing that entry point is found            
> > > lets Windows successfully locate and parse SMBIOSv3 tables. Whether it           
> > > will be fixed on Windows side is not clear so here goes a workaround.            
> > >                                                                                  
> > > Idea is to try build v2 tables if QEMU configuration permits,                    
> > > and fallback to v3 tables otherwise. That will mask Windows issue                
> > > form majority of users.                                                          
> > > However if VM configuration can't be described (typically large VMs)             
> > > by v2 tables, QEMU will use SMBIOSv3 and Windows will hit the issue              
> > > again. In this case complain to Microsoft and/or use UEFI instead of             
> > > SeaBIOS (requires reinstall).                                                    
> > >                                                                                  
> > > Default compat setting of smbios-entry-point-type after series                   
> > > for pc/q35 machines:                                                             
> > >   * 9.0-newer: 'auto'                                                            
> > >   * 8.1-8.2: '64'                                                                
> > >   * 8.0-older: '32'                                                              
> > >                                                                                  
> > > Fixes: https://gitlab.com/qemu-project/qemu/-/issues/2008                        
> > > CC: imammedo@redhat.com                                                          
> > > CC: mst@redhat.com
> > > 
> > > Igor Mammedov (20):
> > >   tests: smbios: make it possible to write SMBIOS only test
> > >   tests: smbios: add test for -smbios type=11 option
> > >   tests: smbios: add test for legacy mode CLI options
> > >   smbios: cleanup smbios_get_tables() from legacy handling
> > >   smbios: get rid of smbios_smp_sockets global
> > >   smbios: get rid of smbios_legacy global
> > >   smbios: avoid mangling user provided tables
> > >   smbios: don't check type4 structures in legacy mode
> > >   smbios: add smbios_add_usr_blob_size() helper
> > >   smbios: rename/expose structures/bitmaps used by both legacy and
> > >     modern code
> > >   smbios: build legacy mode code only for 'pc' machine
> > >   smbios: handle errors consistently
> > >   smbios: get rid of global smbios_ep_type
> > >   smbios: clear smbios_type4_count before building tables
> > >   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
> > >   tests: acpi/smbios: whitelist expected blobs
> > >   pc/q35: set SMBIOS entry point type to 'auto' by default
> > >   tests: acpi: update expected SSDT.dimmpxm blob
> > > 
> > >  hw/i386/fw_cfg.h                     |   3 +-
> > >  include/hw/firmware/smbios.h         |  28 +-
> > >  hw/arm/virt.c                        |   6 +-
> > >  hw/i386/Kconfig                      |   1 +
> > >  hw/i386/fw_cfg.c                     |  14 +-
> > >  hw/i386/pc.c                         |   4 +-
> > >  hw/i386/pc_piix.c                    |   4 +
> > >  hw/i386/pc_q35.c                     |   3 +
> > >  hw/loongarch/virt.c                  |   7 +-
> > >  hw/riscv/virt.c                      |   6 +-
> > >  hw/smbios/Kconfig                    |   2 +
> > >  hw/smbios/meson.build                |   4 +
> > >  hw/smbios/smbios.c                   | 481 +++++++++++----------------
> > >  hw/smbios/smbios_legacy.c            | 185 +++++++++++
> > >  hw/smbios/smbios_legacy_stub.c       |  15 +
> > >  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, 533 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] 27+ messages in thread

end of thread, other threads:[~2024-03-13 22:52 UTC | newest]

Thread overview: 27+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-03-12 16:10 [PATCH v3 00/20] Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS Igor Mammedov
2024-03-12 16:10 ` [PATCH v3 01/20] tests: smbios: make it possible to write SMBIOS only test Igor Mammedov
2024-03-12 16:10 ` [PATCH v3 02/20] tests: smbios: add test for -smbios type=11 option Igor Mammedov
2024-03-12 16:10 ` [PATCH v3 03/20] tests: smbios: add test for legacy mode CLI options Igor Mammedov
2024-03-12 16:10 ` [PATCH v3 04/20] smbios: cleanup smbios_get_tables() from legacy handling Igor Mammedov
2024-03-12 16:10 ` [PATCH v3 05/20] smbios: get rid of smbios_smp_sockets global Igor Mammedov
2024-03-12 16:10 ` [PATCH v3 06/20] smbios: get rid of smbios_legacy global Igor Mammedov
2024-03-12 16:10 ` [PATCH v3 07/20] smbios: avoid mangling user provided tables Igor Mammedov
2024-03-12 16:10 ` [PATCH v3 08/20] smbios: don't check type4 structures in legacy mode Igor Mammedov
2024-03-12 16:10 ` [PATCH v3 09/20] smbios: add smbios_add_usr_blob_size() helper Igor Mammedov
2024-03-12 16:10 ` [PATCH v3 10/20] smbios: rename/expose structures/bitmaps used by both legacy and modern code Igor Mammedov
2024-03-12 16:10 ` [PATCH v3 11/20] smbios: build legacy mode code only for 'pc' machine Igor Mammedov
2024-03-12 16:10 ` [PATCH v3 12/20] smbios: handle errors consistently Igor Mammedov
2024-03-12 16:10 ` [PATCH v3 13/20] smbios: get rid of global smbios_ep_type Igor Mammedov
2024-03-12 16:10 ` [PATCH v3 14/20] smbios: clear smbios_type4_count before building tables Igor Mammedov
2024-03-12 16:10 ` [PATCH v3 15/20] smbios: extend smbios-entry-point-type with 'auto' value Igor Mammedov
2024-03-12 16:10 ` [PATCH v3 16/20] smbios: in case of entry point is 'auto' try to build v2 tables 1st Igor Mammedov
2024-03-12 16:10 ` [PATCH v3 17/20] smbios: error out when building type 4 table is not possible Igor Mammedov
2024-03-12 16:10 ` [PATCH v3 18/20] tests: acpi/smbios: whitelist expected blobs Igor Mammedov
2024-03-12 16:10 ` [PATCH v3 19/20] pc/q35: set SMBIOS entry point type to 'auto' by default Igor Mammedov
2024-03-12 16:10 ` [PATCH v3 20/20] tests: acpi: update expected SSDT.dimmpxm blob Igor Mammedov
2024-03-12 17:31 ` [PATCH v3 00/20] Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS Michael S. Tsirkin
2024-03-13  8:49   ` Igor Mammedov
2024-03-13  9:10     ` Michael S. Tsirkin
2024-03-13 22:51     ` Michael S. Tsirkin
2024-03-12 17:37 ` Michael S. Tsirkin
  -- strict thread matches above, loose matches on Subject: below --
2024-03-05 15:57 [PATCH v2 11/20] smbios: build legacy mode code only for 'pc' machine Igor Mammedov
2024-03-06 10:03 ` [PATCH v3 " Igor Mammedov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).