With this update, we generate one type 4 (processor information) table per socket, calculated as "smp_cpus / (smp_cores * smp_threads)", which is in line with what happens on modern hardware.
Signed-off-by: Gabriel Somlo somlo@cmu.edu --- hw/i386/smbios.c | 22 +++++++++++++++++----- include/hw/i386/smbios.h | 10 +++++++++- 2 files changed, 26 insertions(+), 6 deletions(-)
diff --git a/hw/i386/smbios.c b/hw/i386/smbios.c index 25d2aa3..8b524a9 100644 --- a/hw/i386/smbios.c +++ b/hw/i386/smbios.c @@ -18,6 +18,7 @@ #include "qemu/config-file.h" #include "qemu/error-report.h" #include "sysemu/sysemu.h" +#include "sysemu/cpus.h" #include "hw/i386/pc.h" #include "hw/i386/smbios.h" #include "hw/loader.h" @@ -31,7 +32,7 @@ static struct smbios_entry_point 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; /* for type 4 */ +static uint32_t smbios_cpuid_version, smbios_cpuid_features, smbios_smp_sockets;
static DECLARE_BITMAP(have_binfile_bitmap, SMBIOS_MAX_TYPE+1); static DECLARE_BITMAP(have_fields_bitmap, SMBIOS_MAX_TYPE+1); @@ -283,8 +284,9 @@ machine_init(smbios_register_config);
static void smbios_validate_table(void) { - if (smbios_type4_count && smbios_type4_count != smp_cpus) { - error_report("Number of SMBIOS Type 4 tables must match cpu count"); + if (smbios_type4_count && smbios_type4_count != smbios_smp_sockets) { + error_report("Number of SMBIOS Type 4 tables " + "must match socket count (%d)", smbios_smp_sockets); exit(1); } } @@ -467,7 +469,6 @@ static void smbios_build_type_4_table(unsigned instance) snprintf(sock_str, sizeof(sock_str), "%s%2x", type4.sock_pfx, instance); SMBIOS_TABLE_SET_STR(4, socket_designation_str, sock_str); t->processor_type = 0x03; /* CPU */ - t->processor_family = 0x01; /* Other */ SMBIOS_TABLE_SET_STR(4, processor_manufacturer_str, type4.manufacturer); t->processor_id[0] = smbios_cpuid_version; t->processor_id[1] = smbios_cpuid_features; @@ -481,6 +482,13 @@ static void smbios_build_type_4_table(unsigned instance) t->l1_cache_handle = 0xFFFF; /* N/A */ t->l2_cache_handle = 0xFFFF; /* N/A */ t->l3_cache_handle = 0xFFFF; /* N/A */ + SMBIOS_TABLE_SET_STR(4, serial_number_str, type4.serial); + SMBIOS_TABLE_SET_STR(4, asset_tag_number_str, type4.asset); + SMBIOS_TABLE_SET_STR(4, part_number_str, type4.part); + t->core_count = t->core_enabled = smp_cores; + t->thread_count = smp_threads; + t->processor_characteristics = 0x02; /* Unknown */ + t->processor_family = t->processor_family2 = 0x01; /* Other */
SMBIOS_BUILD_TABLE_POST; smbios_type4_count++; @@ -651,7 +659,11 @@ void smbios_get_tables(uint8_t **tables, size_t *tables_len, smbios_build_type_1_table(); smbios_build_type_2_table(); smbios_build_type_3_table(); - for (i = 0; i < smp_cpus; i++) { + + smbios_smp_sockets = smp_cpus / (smp_cores * smp_threads); + assert(smbios_smp_sockets >= 1); + + for (i = 0; i < smbios_smp_sockets; i++) { smbios_build_type_4_table(i); }
diff --git a/include/hw/i386/smbios.h b/include/hw/i386/smbios.h index 7d5eac8..649c80c 100644 --- a/include/hw/i386/smbios.h +++ b/include/hw/i386/smbios.h @@ -120,7 +120,7 @@ struct smbios_type_3 { /* contained elements follow */ } QEMU_PACKED;
-/* SMBIOS type 4 - Processor Information (v2.0) */ +/* SMBIOS type 4 - Processor Information (v2.6) */ struct smbios_type_4 { struct smbios_structure_header header; uint8_t socket_designation_str; @@ -138,6 +138,14 @@ struct smbios_type_4 { uint16_t l1_cache_handle; uint16_t l2_cache_handle; uint16_t l3_cache_handle; + uint8_t serial_number_str; + uint8_t asset_tag_number_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_family2; } QEMU_PACKED;
/* SMBIOS type 16 - Physical Memory Array */