72 lines
2.1 KiB
Diff
72 lines
2.1 KiB
Diff
|
From c149b054fe5b1851860fd01d54596ea75f5008d3 Mon Sep 17 00:00:00 2001
|
||
|
From: Sandipan Das <sandipan.das@amd.com>
|
||
|
Date: Wed, 13 Apr 2022 11:45:08 +0530
|
||
|
Subject: [PATCH 09/15] x86: Fix clock frequency parsing
|
||
|
|
||
|
AMD processors do not advertise a base clock frequency as
|
||
|
a part of the "model name" in /proc/cpuinfo. The parsing
|
||
|
must fail in order to let os_calibrate() determine clock
|
||
|
speed from cpufreq information or from TSC instead.
|
||
|
|
||
|
Since the parser fails to find "@", strcspn() returns the
|
||
|
length of the line instead and sscanf() ends up scanning
|
||
|
garbage values beyond the null terminator that match the
|
||
|
format specifier. To avoid this, add an additional check
|
||
|
that makes the condition fail if "@" is not found.
|
||
|
|
||
|
Fixes: eaeed92 ("Powerpc: Fix CPU% utilization for PowerVMs")
|
||
|
Signed-off-by: Sandipan Das <sandipan.das@amd.com>
|
||
|
---
|
||
|
x86/util.c | 19 ++++++++++++++-----
|
||
|
1 file changed, 14 insertions(+), 5 deletions(-)
|
||
|
|
||
|
diff --git a/x86/util.c b/x86/util.c
|
||
|
index fdff877..655a677 100644
|
||
|
--- a/x86/util.c
|
||
|
+++ b/x86/util.c
|
||
|
@@ -67,27 +67,36 @@ rdtsc(void)
|
||
|
|
||
|
/*
|
||
|
* Check the cpu name in proc info. Intel CPUs always have @ x.y
|
||
|
- * Ghz and that is the TSC frequency.
|
||
|
+ * GHz and that is the TSC frequency. AMD CPUs do not advertise
|
||
|
+ * clock frequency as a part of the model name.
|
||
|
*/
|
||
|
int
|
||
|
arch__cpuinfo_freq(double *freq, char *unit)
|
||
|
{
|
||
|
FILE *f;
|
||
|
char *line = NULL;
|
||
|
- size_t len = 0;
|
||
|
+ size_t idx, len = 0;
|
||
|
int ret = -1;
|
||
|
|
||
|
if ((f = fopen(CPUINFO_PATH, "r")) == NULL) {
|
||
|
return (-1);
|
||
|
}
|
||
|
|
||
|
- while (getline(&line, &len, f) > 0) {
|
||
|
+ while ((len = getline(&line, &len, f)) > 0) {
|
||
|
if (strncmp(line, "model name", sizeof ("model name") - 1) != 0) {
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
- if (sscanf(line + strcspn(line, "@") + 1, "%lf%10s",
|
||
|
- freq, unit) == 2) {
|
||
|
+ idx = strcspn(line, "@") + 1;
|
||
|
+
|
||
|
+ /*
|
||
|
+ * The model name will not change for other processors. So
|
||
|
+ * bail out if "@" is not found.
|
||
|
+ */
|
||
|
+ if (idx >= len)
|
||
|
+ break;
|
||
|
+
|
||
|
+ if (sscanf(line + idx, "%lf%10s", freq, unit) == 2) {
|
||
|
if (strcasecmp(unit, "GHz") == 0) {
|
||
|
*freq *= GHZ;
|
||
|
} else if (strcasecmp(unit, "Mhz") == 0) {
|
||
|
--
|
||
|
2.31.1
|
||
|
|