Skip to content

Commit c8810e2

Browse files
jwrdegoedeKAGA-KOKO
authored andcommitted
x86/tsc_msr: Fix MSR_FSB_FREQ mask for Cherry Trail devices
According to the "Intel 64 and IA-32 Architectures Software Developer's Manual Volume 4: Model-Specific Registers" on Cherry Trail (Airmont) devices the 4 lowest bits of the MSR_FSB_FREQ mask indicate the bus freq unlike on e.g. Bay Trail where only the lowest 3 bits are used. This is also the reason why MAX_NUM_FREQS is defined as 9, since Cherry Trail SoCs have 9 possible frequencies, so the lo value from the MSR needs to be masked with 0x0f, not with 0x07 otherwise the 9th frequency will get interpreted as the 1st. Bump MAX_NUM_FREQS to 16 to avoid any possibility of addressing the array out of bounds and makes the mask part of the cpufreq struct so it can be set it per model. While at it also log an error when the index points to an uninitialized part of the freqs lookup-table. Signed-off-by: Hans de Goede <[email protected]> Signed-off-by: Thomas Gleixner <[email protected]> Cc: [email protected] Link: https://lkml.kernel.org/r/[email protected]
1 parent 812c2d7 commit c8810e2

File tree

1 file changed

+15
-2
lines changed

1 file changed

+15
-2
lines changed

arch/x86/kernel/tsc_msr.c

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
#include <asm/param.h>
1616
#include <asm/tsc.h>
1717

18-
#define MAX_NUM_FREQS 9
18+
#define MAX_NUM_FREQS 16 /* 4 bits to select the frequency */
1919

2020
/*
2121
* If MSR_PERF_STAT[31] is set, the maximum resolved bus ratio can be
@@ -27,6 +27,7 @@
2727
struct freq_desc {
2828
bool use_msr_plat;
2929
u32 freqs[MAX_NUM_FREQS];
30+
u32 mask;
3031
};
3132

3233
/*
@@ -37,37 +38,44 @@ struct freq_desc {
3738
static const struct freq_desc freq_desc_pnw = {
3839
.use_msr_plat = false,
3940
.freqs = { 0, 0, 0, 0, 0, 99840, 0, 83200 },
41+
.mask = 0x07,
4042
};
4143

4244
static const struct freq_desc freq_desc_clv = {
4345
.use_msr_plat = false,
4446
.freqs = { 0, 133200, 0, 0, 0, 99840, 0, 83200 },
47+
.mask = 0x07,
4548
};
4649

4750
static const struct freq_desc freq_desc_byt = {
4851
.use_msr_plat = true,
4952
.freqs = { 83300, 100000, 133300, 116700, 80000, 0, 0, 0 },
53+
.mask = 0x07,
5054
};
5155

5256
static const struct freq_desc freq_desc_cht = {
5357
.use_msr_plat = true,
5458
.freqs = { 83300, 100000, 133300, 116700, 80000, 93300, 90000,
5559
88900, 87500 },
60+
.mask = 0x0f,
5661
};
5762

5863
static const struct freq_desc freq_desc_tng = {
5964
.use_msr_plat = true,
6065
.freqs = { 0, 100000, 133300, 0, 0, 0, 0, 0 },
66+
.mask = 0x07,
6167
};
6268

6369
static const struct freq_desc freq_desc_ann = {
6470
.use_msr_plat = true,
6571
.freqs = { 83300, 100000, 133300, 100000, 0, 0, 0, 0 },
72+
.mask = 0x0f,
6673
};
6774

6875
static const struct freq_desc freq_desc_lgm = {
6976
.use_msr_plat = true,
7077
.freqs = { 78000, 78000, 78000, 78000, 78000, 78000, 78000, 78000 },
78+
.mask = 0x0f,
7179
};
7280

7381
static const struct x86_cpu_id tsc_msr_cpu_ids[] = {
@@ -93,6 +101,7 @@ unsigned long cpu_khz_from_msr(void)
93101
const struct freq_desc *freq_desc;
94102
const struct x86_cpu_id *id;
95103
unsigned long res;
104+
int index;
96105

97106
id = x86_match_cpu(tsc_msr_cpu_ids);
98107
if (!id)
@@ -109,13 +118,17 @@ unsigned long cpu_khz_from_msr(void)
109118

110119
/* Get FSB FREQ ID */
111120
rdmsr(MSR_FSB_FREQ, lo, hi);
121+
index = lo & freq_desc->mask;
112122

113123
/* Map CPU reference clock freq ID(0-7) to CPU reference clock freq(KHz) */
114-
freq = freq_desc->freqs[lo & 0x7];
124+
freq = freq_desc->freqs[index];
115125

116126
/* TSC frequency = maximum resolved freq * maximum resolved bus ratio */
117127
res = freq * ratio;
118128

129+
if (freq == 0)
130+
pr_err("Error MSR_FSB_FREQ index %d is unknown\n", index);
131+
119132
#ifdef CONFIG_X86_LOCAL_APIC
120133
lapic_timer_period = (freq * 1000) / HZ;
121134
#endif

0 commit comments

Comments
 (0)