Currently, hvmloader uses SMBIOS 2.4, however, when using OVMF, the SMBIOS is patched to 2.8, which has clarified the UUID format (as GUID).
In Linux, if the SMBIOS version is >= 2.6, the GUID format is used, else (undefined as per SMBIOS spec), big endian is used (used by Xen). Therefore, you have a endian mismatch causing the UUIDs to mismatch in the guest. $ cat /sys/hypervisor/uuid e865e63f-3d30-4f0b-83e0-8fdfc1e30eb7 $ cat /sys/devices/virtual/dmi/id/product_uuid 3fe665e8-303d-0b4f-83e0-8fdfc1e30eb7 $ cat /sys/devices/virtual/dmi/id/product_serial e865e63f-3d30-4f0b-83e0-8fdfc1e30eb7 This patch updates the SMBIOS version from 2.4 to 2.6 and does the appropriate modifications of the table. This effectively fix this endianness mismatch with OVMF; while the UUID displayed by Linux is still the same for SeaBIOS. Fixes: c683914ef913 ("Add code to generate SMBIOS tables to hvmloader.") (SMBIOS versions before 2.6 has a ill-defined UUID definition) Signed-off-by: Teddy Astie <teddy.as...@vates.tech> --- v2: - rebase onto staging - introduce missing SMBIOS 2.5-2.6 fields - check for new SMBIOS 2.6 table lengths - update UUID conversion comment - add Fixes: note --- tools/firmware/hvmloader/smbios.c | 50 ++++++++++++++++++++----- tools/firmware/hvmloader/smbios_types.h | 9 +++++ 2 files changed, 50 insertions(+), 9 deletions(-) diff --git a/tools/firmware/hvmloader/smbios.c b/tools/firmware/hvmloader/smbios.c index 76c7090d16..e445475d78 100644 --- a/tools/firmware/hvmloader/smbios.c +++ b/tools/firmware/hvmloader/smbios.c @@ -396,7 +396,7 @@ smbios_entry_point_init(void *start, memcpy(ep->anchor_string, "_SM_", 4); ep->length = 0x1f; ep->smbios_major_version = 2; - ep->smbios_minor_version = 4; + ep->smbios_minor_version = 6; ep->max_structure_size = max_structure_size; ep->entry_point_revision = 0; memcpy(ep->intermediate_anchor_string, "_DMI_", 5); @@ -505,7 +505,22 @@ smbios_type_1_init(void *start, const char *xen_version, p->version_str = 3; p->serial_number_str = 4; - memcpy(p->uuid, uuid, 16); + /* + * Xen toolstack uses big endian UUIDs, however GUIDs (which requirement + * is clarified by SMBIOS >= 2.6) has the first 3 components appearing as + * being little endian and the rest as still being big endian. + */ + /* First component */ + for ( unsigned int i = 0; i < 4; i++ ) + p->uuid[i] = uuid[4 - i - 1]; + /* Second component */ + p->uuid[4] = uuid[5]; + p->uuid[5] = uuid[4]; + /* Third component */ + p->uuid[6] = uuid[7]; + p->uuid[7] = uuid[6]; + /* Rest */ + memcpy(p->uuid + 8, uuid + 8, 8); p->wake_up_type = 0x06; /* power switch */ p->sku_str = 0; @@ -705,8 +720,8 @@ smbios_type_4_init( struct smbios_type_4 *p = start; uint32_t eax, ebx, ecx, edx; - /* Specification says Type 4 table has length of 23h for v2.3+. */ - BUILD_BUG_ON(sizeof(*p) != 35); + /* Specification says Type 4 table has length of 2Ah for v2.6. */ + BUILD_BUG_ON(sizeof(*p) != 42); memset(p, 0, sizeof(*p)); @@ -716,7 +731,7 @@ smbios_type_4_init( p->socket_designation_str = 1; p->processor_type = 0x03; /* CPU */ - p->processor_family = 0x01; /* other */ + p->processor_family = p->processor_family_2 = 0x01; /* other */ p->manufacturer_str = 2; cpuid(1, &eax, &ebx, &ecx, &edx); @@ -736,6 +751,22 @@ smbios_type_4_init( p->l2_cache_handle = 0xffff; /* No cache information structure provided. */ p->l3_cache_handle = 0xffff; /* No cache information structure provided. */ + /* + * We have a smbios type 4 table per vCPU (which is per socket), + * which means here that we have 1 socket per vCPU. + */ + p->core_count = p->core_enabled = p->thread_count = 1; + + /* + * We set 64-bits, execute protection and enhanced virtualization. + * We don't set Multi-Core (bit 3) because this individual processor + * (as being a single vCPU) is only having one core. + * + * SMBIOS specification says that these bits don't state anything + * regarding the actual availability of such features. + */ + p->processor_characteristics = 0x64; + start += sizeof(*p); strncpy(buf, "CPU ", sizeof(buf)); @@ -780,8 +811,8 @@ smbios_type_8_init(void *start) static void * smbios_type_9_init(void *start) { - /* Specification says Type 9 table has length of 0Dh for v2.1-2.5. */ - BUILD_BUG_ON(sizeof(struct smbios_type_9) != 13); + /* Specification says Type 9 table has length of 11h for v2.6+. */ + BUILD_BUG_ON(sizeof(struct smbios_type_9) != 17); /* Only present when passed in. */ return smbios_pt_copy(start, 9, SMBIOS_HANDLE_TYPE9, @@ -870,8 +901,8 @@ smbios_type_17_init(void *start, uint32_t memory_size_mb, int instance) char buf[16]; struct smbios_type_17 *p = start; - /* Specification says Type 17 table has length of 1Bh for v2.3-2.6. */ - BUILD_BUG_ON(sizeof(*p) != 27); + /* Specification says Type 17 table has length of 1Ch for v2.6. */ + BUILD_BUG_ON(sizeof(*p) != 28); memset(p, 0, sizeof(*p)); @@ -890,6 +921,7 @@ smbios_type_17_init(void *start, uint32_t memory_size_mb, int instance) p->bank_locator_str = 0; p->memory_type = 0x07; /* RAM */ p->type_detail = 0; + p->attributes = 0; start += sizeof(*p); strcpy(start, "DIMM "); diff --git a/tools/firmware/hvmloader/smbios_types.h b/tools/firmware/hvmloader/smbios_types.h index c04b435d31..860617d86a 100644 --- a/tools/firmware/hvmloader/smbios_types.h +++ b/tools/firmware/hvmloader/smbios_types.h @@ -147,6 +147,11 @@ struct smbios_type_4 { uint8_t serial_number_str; uint8_t asset_tag_str; uint8_t part_number_str; + uint8_t core_count; + uint8_t core_enabled; + uint8_t thread_count; + uint16_t processor_characteristics; + uint16_t processor_family_2; } __attribute__ ((packed)); /* SMBIOS type 7 - Cache Information */ @@ -185,6 +190,9 @@ struct smbios_type_9 { uint16_t slot_id; uint8_t slot_characteristics_1; uint8_t slot_characteristics_2; + uint16_t sgn_base; + uint8_t bus_number_base; + uint8_t devfn_base; } __attribute__ ((packed)); /* SMBIOS type 11 - OEM Strings */ @@ -227,6 +235,7 @@ struct smbios_type_17 { uint8_t serial_number_str; uint8_t asset_tag_str; uint8_t part_number_str; + uint8_t attributes; } __attribute__ ((packed)); /* SMBIOS type 19 - Memory Array Mapped Address */ -- 2.50.1 Teddy Astie | Vates XCP-ng Developer XCP-ng & Xen Orchestra - Vates solutions web: https://vates.tech