From: Karel Zak Date: Thu, 21 Aug 2025 09:35:17 +0000 (+0200) Subject: lscpu: use maximum CPU speed from DMI, avoid duplicate version string X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=c332544d215ccb466a64a441eb5a421b9fe8cdfd;p=thirdparty%2Futil-linux.git lscpu: use maximum CPU speed from DMI, avoid duplicate version string * Read maximum CPU speed from DMI * Don't use max speed if nonsensical * Avoid appending "CPU @ speed" to the version string if it's already included. (This is a code robustness improvement as DMI is currently read for ARMs only, and the issue was detected on Intel.) Fixes: https://github.com/util-linux/util-linux/commit/a772d7c493afcec32f0123fc947013f74db6e45d Signed-off-by: Karel Zak --- diff --git a/sys-utils/lscpu-dmi.c b/sys-utils/lscpu-dmi.c index 2171f7623..a04cbb567 100644 --- a/sys-utils/lscpu-dmi.c +++ b/sys-utils/lscpu-dmi.c @@ -76,6 +76,7 @@ int parse_dmi_table(uint16_t len, uint16_t num, di->processor_manufacturer = dmi_string(&h, data[0x7]); di->processor_version = dmi_string(&h, data[0x10]); di->current_speed = *((uint16_t *)(&data[0x16])); + di->max_speed = *((uint16_t *)(&data[0x14])); di->part_num = dmi_string(&h, data[0x22]); if (data[0x6] == 0xfe) @@ -122,10 +123,22 @@ int dmi_decode_cputype(struct lscpu_cputype *ct) if (di.processor_manufacturer) ct->bios_vendor = xstrdup(di.processor_manufacturer); - snprintf(buf, sizeof(buf), "%s %s CPU @ %d.%dGHz", - (di.processor_version ?: ""), (di.part_num ?: ""), - di.current_speed/1000, (di.current_speed % 1000) / 100); - ct->bios_modelname = xstrdup(buf); + /* The CPU version string may include the maximum speed (e.g., on Intel); in + * this case, use the version string as the complete model name. */ + if (di.processor_version && strstr(di.processor_version, " CPU @ ")) + ct->bios_modelname = xstrdup(di.processor_version); + else { + /* DMI may provide incorrect data (max_speed < current_speed) */ + uint16_t speed = max(di.current_speed, di.max_speed); + + snprintf(buf, sizeof(buf), "%s %s CPU @ %d.%dGHz", + (di.processor_version ?: ""), + (di.part_num ?: ""), + speed/1000, + (speed % 1000) / 100); + + ct->bios_modelname = xstrdup(buf); + } /* Get CPU family */ memset(buf, 0, sizeof(buf)); diff --git a/sys-utils/lscpu.h b/sys-utils/lscpu.h index bd7b64cc5..e132d63c6 100644 --- a/sys-utils/lscpu.h +++ b/sys-utils/lscpu.h @@ -346,6 +346,7 @@ struct dmi_info { char *processor_manufacturer; char *processor_version; uint16_t current_speed; + uint16_t max_speed; char *part_num; };