fbc8207b73
Update to qemu 3.1.0-rc5. Is almost certainly the last rc, so should be same as 3.1.0 final. Putting into devel project 'early' because of SLE and Leap needs, not to get into Factory early. Look for the final 3.1 within a week. OBS-URL: https://build.opensuse.org/request/show/655897 OBS-URL: https://build.opensuse.org/package/show/Virtualization/qemu?expand=0&rev=433
193 lines
8.7 KiB
Diff
193 lines
8.7 KiB
Diff
From 1a15064c09cfdc5d910c34cf5735e393bee67aaa Mon Sep 17 00:00:00 2001
|
|
From: Lin Ma <lma@suse.com>
|
|
Date: Wed, 14 Mar 2018 14:31:26 +0800
|
|
Subject: [PATCH] smbios: Add 1 terminator if any string fields defined in
|
|
given table.
|
|
|
|
If user specifies smbios table files through qemu command line, Then will
|
|
get error messages while decoding those table content in guest.
|
|
|
|
Reproducer:
|
|
1. dump a smbios table(say table 1) to a binary file from a pc.
|
|
2. load the binary file through command line: 'qemu -smbios file=...'.
|
|
3. perform 'dmidecode' or 'dmidecode -t 1' in guest.
|
|
|
|
It reports 'Invalid entry length...' because qemu doesn't add terminator(s)
|
|
correctly for the table.
|
|
|
|
This patch fixed the issue by:
|
|
|
|
For smbios tables which have string fields provided, qemu should add 1 terminator.
|
|
For smbios tables which dont have string fields provided, qemu should add 2.
|
|
|
|
[LM: BSC#994082]
|
|
[LM: BSC#1084316]
|
|
Signed-off-by: Lin Ma <lma@suse.com>
|
|
---
|
|
hw/smbios/smbios.c | 90 ++++++++++++++++++++++++++++++++++++++
|
|
include/hw/smbios/smbios.h | 44 +++++++++++++++++++
|
|
2 files changed, 134 insertions(+)
|
|
|
|
diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c
|
|
index 920939454e..52d1e10c3c 100644
|
|
--- a/hw/smbios/smbios.c
|
|
+++ b/hw/smbios/smbios.c
|
|
@@ -953,6 +953,9 @@ void smbios_entry_add(QemuOpts *opts, Error **errp)
|
|
Error *err = NULL;
|
|
const char *val;
|
|
|
|
+ int i, terminator_count = 2, table_str_field_count = 0;
|
|
+ int *tables_str_field_offset = NULL;
|
|
+
|
|
assert(!smbios_immutable);
|
|
|
|
val = qemu_opt_get(opts, "file");
|
|
@@ -999,7 +1002,94 @@ void smbios_entry_add(QemuOpts *opts, Error **errp)
|
|
smbios_type4_count++;
|
|
}
|
|
|
|
+ switch (header->type) {
|
|
+ case 0:
|
|
+ tables_str_field_offset = g_malloc0(sizeof(int) * \
|
|
+ TYPE_0_STR_FIELD_COUNT);
|
|
+ tables_str_field_offset = (int []){\
|
|
+ TYPE_0_STR_FIELD_OFFSET_VENDOR, \
|
|
+ TYPE_0_STR_FIELD_OFFSET_BIOS_VERSION, \
|
|
+ TYPE_0_STR_FIELD_OFFSET_BIOS_RELEASE_DATE};
|
|
+ table_str_field_count = sizeof(tables_str_field_offset) / \
|
|
+ sizeof(tables_str_field_offset[0]);
|
|
+ break;
|
|
+ case 1:
|
|
+ tables_str_field_offset = g_malloc0(sizeof(int) * \
|
|
+ TYPE_1_STR_FIELD_COUNT);
|
|
+ tables_str_field_offset = (int []){
|
|
+ TYPE_1_STR_FIELD_OFFSET_MANUFACTURER, \
|
|
+ TYPE_1_STR_FIELD_OFFSET_PRODUCT, \
|
|
+ TYPE_1_STR_FIELD_OFFSET_VERSION, \
|
|
+ TYPE_1_STR_FIELD_OFFSET_SERIAL, \
|
|
+ TYPE_1_STR_FIELD_OFFSET_SKU, \
|
|
+ TYPE_1_STR_FIELD_OFFSET_FAMILY};
|
|
+ table_str_field_count = sizeof(tables_str_field_offset) / \
|
|
+ sizeof(tables_str_field_offset[0]);
|
|
+ break;
|
|
+ case 2:
|
|
+ tables_str_field_offset = g_malloc0(sizeof(int) * \
|
|
+ TYPE_2_STR_FIELD_COUNT);
|
|
+ tables_str_field_offset = (int []){\
|
|
+ TYPE_2_STR_FIELD_OFFSET_MANUFACTURER, \
|
|
+ TYPE_2_STR_FIELD_OFFSET_PRODUCT, \
|
|
+ TYPE_2_STR_FIELD_OFFSET_VERSION, \
|
|
+ TYPE_2_STR_FIELD_OFFSET_SERIAL, \
|
|
+ TYPE_2_STR_FIELD_OFFSET_ASSET, \
|
|
+ TYPE_2_STR_FIELD_OFFSET_LOCATION};
|
|
+ table_str_field_count = sizeof(tables_str_field_offset) / \
|
|
+ sizeof(tables_str_field_offset[0]);
|
|
+ break;
|
|
+ case 3:
|
|
+ tables_str_field_offset = g_malloc0(sizeof(int) * \
|
|
+ TYPE_3_STR_FIELD_COUNT);
|
|
+ tables_str_field_offset = (int []){\
|
|
+ TYPE_3_STR_FIELD_OFFSET_MANUFACTURER, \
|
|
+ TYPE_3_STR_FIELD_OFFSET_VERSION, \
|
|
+ TYPE_3_STR_FIELD_OFFSET_SERIAL, \
|
|
+ TYPE_3_STR_FIELD_OFFSET_ASSET, \
|
|
+ TYPE_3_STR_FIELD_OFFSET_SKU};
|
|
+ table_str_field_count = sizeof(tables_str_field_offset) / \
|
|
+ sizeof(tables_str_field_offset[0]);
|
|
+ break;
|
|
+ case 4:
|
|
+ tables_str_field_offset = g_malloc0(sizeof(int) * \
|
|
+ TYPE_4_STR_FIELD_COUNT);
|
|
+ tables_str_field_offset = (int []){\
|
|
+ TYPE_4_STR_FIELD_OFFSET_SOCKET, \
|
|
+ TYPE_4_STR_FIELD_OFFSET_PROCESSOR_MANUFACTURER, \
|
|
+ TYPE_4_STR_FIELD_OFFSET_PROCESSOR_VERSION, \
|
|
+ TYPE_4_STR_FIELD_OFFSET_SERIAL, \
|
|
+ TYPE_4_STR_FIELD_OFFSET_ASSET, \
|
|
+ TYPE_4_STR_FIELD_OFFSET_PART};
|
|
+ table_str_field_count = sizeof(tables_str_field_offset) / \
|
|
+ sizeof(tables_str_field_offset[0]);
|
|
+ break;
|
|
+ case 17:
|
|
+ tables_str_field_offset = g_malloc0(sizeof(int) * \
|
|
+ TYPE_17_STR_FIELD_COUNT);
|
|
+ tables_str_field_offset = (int []){\
|
|
+ TYPE_17_STR_FIELD_OFFSET_DEVICE_LOCATOR, \
|
|
+ TYPE_17_STR_FIELD_OFFSET_BANK_LOCATOR, \
|
|
+ TYPE_17_STR_FIELD_OFFSET_MANUFACTURER, \
|
|
+ TYPE_17_STR_FIELD_OFFSET_SERIAL, \
|
|
+ TYPE_17_STR_FIELD_OFFSET_ASSET, \
|
|
+ TYPE_17_STR_FIELD_OFFSET_PART};
|
|
+ table_str_field_count = sizeof(tables_str_field_offset) / \
|
|
+ sizeof(tables_str_field_offset[0]);
|
|
+ break;
|
|
+ default:
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ for (i = 0; i < table_str_field_count; i++) {
|
|
+ if (*(uint8_t *)(smbios_tables + tables_str_field_offset[i]) > 0) {
|
|
+ terminator_count = 1;
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+
|
|
smbios_tables_len += size;
|
|
+ smbios_tables_len += terminator_count;
|
|
if (size > smbios_table_max) {
|
|
smbios_table_max = size;
|
|
}
|
|
diff --git a/include/hw/smbios/smbios.h b/include/hw/smbios/smbios.h
|
|
index eeb5a4d7b6..2662df995a 100644
|
|
--- a/include/hw/smbios/smbios.h
|
|
+++ b/include/hw/smbios/smbios.h
|
|
@@ -272,4 +272,48 @@ void smbios_get_tables(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);
|
|
+
|
|
+#define TYPE_0_STR_FIELD_OFFSET_VENDOR 0x4
|
|
+#define TYPE_0_STR_FIELD_OFFSET_BIOS_VERSION 0x5
|
|
+#define TYPE_0_STR_FIELD_OFFSET_BIOS_RELEASE_DATE 0x8
|
|
+#define TYPE_0_STR_FIELD_COUNT 3
|
|
+
|
|
+#define TYPE_1_STR_FIELD_OFFSET_MANUFACTURER 0x4
|
|
+#define TYPE_1_STR_FIELD_OFFSET_PRODUCT 0x5
|
|
+#define TYPE_1_STR_FIELD_OFFSET_VERSION 0x6
|
|
+#define TYPE_1_STR_FIELD_OFFSET_SERIAL 0x7
|
|
+#define TYPE_1_STR_FIELD_OFFSET_SKU 0x19
|
|
+#define TYPE_1_STR_FIELD_OFFSET_FAMILY 0x1a
|
|
+#define TYPE_1_STR_FIELD_COUNT 6
|
|
+
|
|
+#define TYPE_2_STR_FIELD_OFFSET_MANUFACTURER 0x4
|
|
+#define TYPE_2_STR_FIELD_OFFSET_PRODUCT 0x5
|
|
+#define TYPE_2_STR_FIELD_OFFSET_VERSION 0x6
|
|
+#define TYPE_2_STR_FIELD_OFFSET_SERIAL 0x7
|
|
+#define TYPE_2_STR_FIELD_OFFSET_ASSET 0x8
|
|
+#define TYPE_2_STR_FIELD_OFFSET_LOCATION 0xa
|
|
+#define TYPE_2_STR_FIELD_COUNT 6
|
|
+
|
|
+#define TYPE_3_STR_FIELD_OFFSET_MANUFACTURER 0x4
|
|
+#define TYPE_3_STR_FIELD_OFFSET_VERSION 0x6
|
|
+#define TYPE_3_STR_FIELD_OFFSET_SERIAL 0x7
|
|
+#define TYPE_3_STR_FIELD_OFFSET_ASSET 0x8
|
|
+#define TYPE_3_STR_FIELD_OFFSET_SKU 0x14
|
|
+#define TYPE_3_STR_FIELD_COUNT 5
|
|
+
|
|
+#define TYPE_4_STR_FIELD_OFFSET_SOCKET 0x4
|
|
+#define TYPE_4_STR_FIELD_OFFSET_PROCESSOR_MANUFACTURER 0x7
|
|
+#define TYPE_4_STR_FIELD_OFFSET_PROCESSOR_VERSION 0x10
|
|
+#define TYPE_4_STR_FIELD_OFFSET_SERIAL 0x20
|
|
+#define TYPE_4_STR_FIELD_OFFSET_ASSET 0x21
|
|
+#define TYPE_4_STR_FIELD_OFFSET_PART 0x22
|
|
+#define TYPE_4_STR_FIELD_COUNT 6
|
|
+
|
|
+#define TYPE_17_STR_FIELD_OFFSET_DEVICE_LOCATOR 0x10
|
|
+#define TYPE_17_STR_FIELD_OFFSET_BANK_LOCATOR 0x11
|
|
+#define TYPE_17_STR_FIELD_OFFSET_MANUFACTURER 0x17
|
|
+#define TYPE_17_STR_FIELD_OFFSET_SERIAL 0x18
|
|
+#define TYPE_17_STR_FIELD_OFFSET_ASSET 0x19
|
|
+#define TYPE_17_STR_FIELD_OFFSET_PART 0x1a
|
|
+#define TYPE_17_STR_FIELD_COUNT 6
|
|
#endif /* QEMU_SMBIOS_H */
|