diff --git a/hw/i386/fw_cfg.c b/hw/i386/fw_cfg.c index c1e9c0fd9c..d1281066f4 100644 --- a/hw/i386/fw_cfg.c +++ b/hw/i386/fw_cfg.c @@ -71,8 +71,7 @@ void fw_cfg_build_smbios(PCMachineState *pcms, FWCfgState *fw_cfg) smbios_set_cpuid(cpu->env.cpuid_version, cpu->env.features[FEAT_1_EDX]); if (pcmc->smbios_legacy_mode) { - smbios_tables = smbios_get_table_legacy(ms->smp.cpus, - &smbios_tables_len); + smbios_tables = smbios_get_table_legacy(&smbios_tables_len); fw_cfg_add_bytes(fw_cfg, FW_CFG_SMBIOS_ENTRIES, smbios_tables, smbios_tables_len); return; diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c index aab4ffb4cb..30196d2911 100644 --- a/hw/smbios/smbios.c +++ b/hw/smbios/smbios.c @@ -545,14 +545,17 @@ opts_init(smbios_register_config); */ #define SMBIOS_21_MAX_TABLES_LEN 0xffff -static void smbios_validate_table(uint32_t expected_t4_count) +static void smbios_check_type4_count(uint32_t expected_t4_count) { if (smbios_type4_count && smbios_type4_count != expected_t4_count) { error_report("Expected %d SMBIOS Type 4 tables, got %d instead", expected_t4_count, smbios_type4_count); exit(1); } +} +static void smbios_validate_table(void) +{ if (smbios_ep_type == SMBIOS_ENTRY_POINT_TYPE_32 && smbios_tables_len > SMBIOS_21_MAX_TABLES_LEN) { error_report("SMBIOS 2.1 table length %zu exceeds %d", @@ -637,7 +640,7 @@ static void smbios_build_type_1_fields(void) } } -uint8_t *smbios_get_table_legacy(uint32_t expected_t4_count, size_t *length) +uint8_t *smbios_get_table_legacy(size_t *length) { int i; size_t usr_offset; @@ -650,6 +653,12 @@ uint8_t *smbios_get_table_legacy(uint32_t expected_t4_count, size_t *length) exit(1); } + if (test_bit(4, have_binfile_bitmap)) { + error_report("can't process table for smbios " + "type 4 on machine versions < 2.1!"); + exit(1); + } + g_free(smbios_entries); smbios_entries_len = sizeof(uint16_t); smbios_entries = g_malloc0(smbios_entries_len); @@ -676,7 +685,7 @@ uint8_t *smbios_get_table_legacy(uint32_t expected_t4_count, size_t *length) smbios_build_type_0_fields(); smbios_build_type_1_fields(); - smbios_validate_table(expected_t4_count); + smbios_validate_table(); *length = smbios_entries_len; return smbios_entries; } @@ -1304,7 +1313,8 @@ void smbios_get_tables(MachineState *ms, smbios_build_type_41_table(errp); smbios_build_type_127_table(); - smbios_validate_table(ms->smp.sockets); + smbios_check_type4_count(ms->smp.sockets); + smbios_validate_table(); smbios_entry_point_setup(); /* return tables blob and entry point (anchor), and their sizes */ diff --git a/include/hw/firmware/smbios.h b/include/hw/firmware/smbios.h index 7b42e7b4ac..0f0dca8f83 100644 --- a/include/hw/firmware/smbios.h +++ b/include/hw/firmware/smbios.h @@ -313,7 +313,7 @@ void smbios_set_defaults(const char *manufacturer, const char *product, const char *version, bool uuid_encoded, SmbiosEntryPointType ep_type); void smbios_set_default_processor_family(uint16_t processor_family); -uint8_t *smbios_get_table_legacy(uint32_t expected_t4_count, size_t *length); +uint8_t *smbios_get_table_legacy(size_t *length); void smbios_get_tables(MachineState *ms, const struct smbios_phys_mem_area *mem_array, const unsigned int mem_array_size,