132 lines
4.6 KiB
Diff
132 lines
4.6 KiB
Diff
From 38220bc61bdb1614f34a53481f7604720c9e9e5a Mon Sep 17 00:00:00 2001
|
|
From: Igor Mammedov <imammedo@redhat.com>
|
|
Date: Tue, 20 Feb 2024 10:41:06 +0100
|
|
Subject: [PATCH 18/20] smbios: in case of entry point is 'auto' try to build
|
|
v2 tables 1st
|
|
|
|
RH-Author: Igor Mammedov <imammedo@redhat.com>
|
|
RH-MergeRequest: 230: Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS
|
|
RH-Jira: RHEL-21705
|
|
RH-Acked-by: MST <mst@redhat.com>
|
|
RH-Acked-by: Ani Sinha <None>
|
|
RH-Commit: [16/18] becbcb3d8dad4842e5939bb75e21f4e737a4a325
|
|
|
|
JIRA: https://issues.redhat.com/browse/RHEL-21705
|
|
|
|
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 4521ea386c..3d9dcb0d31 100644
|
|
--- a/hw/smbios/smbios.c
|
|
+++ b/hw/smbios/smbios.c
|
|
@@ -1097,7 +1097,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,
|
|
@@ -1106,6 +1106,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);
|
|
@@ -1192,11 +1193,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
|
|
|