1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
|
From: Karel Zak <kzak@redhat.com>
Date: Thu, 21 Aug 2025 11:35:17 +0200
Subject: 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 <kzak@redhat.com>
---
sys-utils/lscpu-dmi.c | 21 +++++++++++++++++----
sys-utils/lscpu.h | 1 +
2 files changed, 18 insertions(+), 4 deletions(-)
diff --git a/sys-utils/lscpu-dmi.c b/sys-utils/lscpu-dmi.c
index 2171f76..a04cbb5 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 459fea8..64570f6 100644
--- a/sys-utils/lscpu.h
+++ b/sys-utils/lscpu.h
@@ -344,6 +344,7 @@ struct dmi_info {
char *processor_manufacturer;
char *processor_version;
uint16_t current_speed;
+ uint16_t max_speed;
char *part_num;
};
|