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 | 19 ++++++++++++++----- include/hw/i386/smbios.h | 8 ++++++-- 2 files changed, 20 insertions(+), 7 deletions(-)
diff --git a/hw/i386/smbios.c b/hw/i386/smbios.c index f5507cb..382b75d 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" @@ -43,7 +44,7 @@ static size_t smbios_entries_len; 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); @@ -295,8 +296,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); } } @@ -490,7 +492,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; @@ -507,6 +508,10 @@ static void smbios_build_type_4_table(unsigned instance) 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++; @@ -658,7 +663,11 @@ uint8_t *smbios_get_table(size_t *length) 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 ce2f0f2..9067139 100644 --- a/include/hw/i386/smbios.h +++ b/include/hw/i386/smbios.h @@ -99,7 +99,7 @@ struct smbios_type_3 { /* contained elements follow */ } QEMU_PACKED;
-/* SMBIOS type 4 - Processor Information (v2.3) */ +/* SMBIOS type 4 - Processor Information (v2.6) */ struct smbios_type_4 { struct smbios_structure_header header; uint8_t socket_designation_str; @@ -120,7 +120,11 @@ struct smbios_type_4 { 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 */