Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-15-SP1:GA
qemu-linux-user.8413
0070-smbios-Add-1-terminator-if-any-stri.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 0070-smbios-Add-1-terminator-if-any-stri.patch of Package qemu-linux-user.8413
From 4529ddd777f8f56a38d853905e6b0344c6998ed6 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 5d11f01874..d9f5f1ef70 100644 --- a/hw/smbios/smbios.c +++ b/hw/smbios/smbios.c @@ -954,6 +954,9 @@ void smbios_entry_add(QemuOpts *opts, Error **errp) { 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"); @@ -995,7 +998,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 a83adb93d7..6613f68ad1 100644 --- a/include/hw/smbios/smbios.h +++ b/include/hw/smbios/smbios.h @@ -273,4 +273,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 */
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor