Skip to content

Commit 70768eb

Browse files
xen0ntsbogend
authored andcommitted
MIPS: Loongson64: Guard against future cores without CPUCFG
Previously it was thought that all future Loongson cores would come with native CPUCFG. From new information shared by Huacai this is definitely not true (maybe some future 2K cores, for example), so collisions at PRID_REV level are inevitable. The CPU model matching needs to take PRID_IMP into consideration. The emulation logic needs to be disabled for those future cores as well, as we cannot possibly encode their non-discoverable features right now. Reported-by: Huacai Chen <[email protected]> Cc: Jiaxun Yang <[email protected]> Signed-off-by: WANG Xuerui <[email protected]> Reviewed-by: Huacai Chen <[email protected]> Signed-off-by: Thomas Bogendoerfer <[email protected]>
1 parent b3878a6 commit 70768eb

File tree

3 files changed

+35
-17
lines changed

3 files changed

+35
-17
lines changed

arch/mips/include/asm/mach-loongson64/cpucfg-emul.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,12 @@
1212

1313
void loongson3_cpucfg_synthesize_data(struct cpuinfo_mips *c);
1414

15+
static inline bool loongson3_cpucfg_emulation_enabled(struct cpuinfo_mips *c)
16+
{
17+
/* All supported cores have non-zero LOONGSON_CFG1 data. */
18+
return c->loongson3_cpucfg_data[0] != 0;
19+
}
20+
1521
static inline u32 loongson3_cpucfg_read_synthesized(struct cpuinfo_mips *c,
1622
__u64 sel)
1723
{
@@ -53,6 +59,11 @@ static inline void loongson3_cpucfg_synthesize_data(struct cpuinfo_mips *c)
5359
{
5460
}
5561

62+
static inline bool loongson3_cpucfg_emulation_enabled(struct cpuinfo_mips *c)
63+
{
64+
return false;
65+
}
66+
5667
static inline u32 loongson3_cpucfg_read_synthesized(struct cpuinfo_mips *c,
5768
__u64 sel)
5869
{

arch/mips/kernel/traps.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -722,6 +722,10 @@ static int simulate_loongson3_cpucfg(struct pt_regs *regs,
722722

723723
perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, regs, 0);
724724

725+
/* Do not emulate on unsupported core models. */
726+
if (!loongson3_cpucfg_emulation_enabled(&current_cpu_data))
727+
return -1;
728+
725729
regs->regs[rd] = loongson3_cpucfg_read_synthesized(
726730
&current_cpu_data, sel);
727731

arch/mips/loongson64/cpucfg-emul.c

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -134,13 +134,9 @@ void loongson3_cpucfg_synthesize_data(struct cpuinfo_mips *c)
134134
c->loongson3_cpucfg_data[1] = 0;
135135
c->loongson3_cpucfg_data[2] = 0;
136136

137-
/* Add CPUCFG features non-discoverable otherwise.
138-
*
139-
* All Loongson processors covered by CPUCFG emulation have distinct
140-
* PRID_REV, so take advantage of this.
141-
*/
142-
switch (c->processor_id & PRID_REV_MASK) {
143-
case PRID_REV_LOONGSON3A_R1:
137+
/* Add CPUCFG features non-discoverable otherwise. */
138+
switch (c->processor_id & (PRID_IMP_MASK | PRID_REV_MASK)) {
139+
case PRID_IMP_LOONGSON_64C | PRID_REV_LOONGSON3A_R1:
144140
c->loongson3_cpucfg_data[0] |= (LOONGSON_CFG1_LSLDR0 |
145141
LOONGSON_CFG1_LSSYNCI | LOONGSON_CFG1_LSUCA |
146142
LOONGSON_CFG1_LLSYNC | LOONGSON_CFG1_TGTSYNC);
@@ -153,8 +149,8 @@ void loongson3_cpucfg_synthesize_data(struct cpuinfo_mips *c)
153149
LOONGSON_CFG3_LCAMVW_REV1);
154150
break;
155151

156-
case PRID_REV_LOONGSON3B_R1:
157-
case PRID_REV_LOONGSON3B_R2:
152+
case PRID_IMP_LOONGSON_64C | PRID_REV_LOONGSON3B_R1:
153+
case PRID_IMP_LOONGSON_64C | PRID_REV_LOONGSON3B_R2:
158154
c->loongson3_cpucfg_data[0] |= (LOONGSON_CFG1_LSLDR0 |
159155
LOONGSON_CFG1_LSSYNCI | LOONGSON_CFG1_LSUCA |
160156
LOONGSON_CFG1_LLSYNC | LOONGSON_CFG1_TGTSYNC);
@@ -167,10 +163,10 @@ void loongson3_cpucfg_synthesize_data(struct cpuinfo_mips *c)
167163
LOONGSON_CFG3_LCAMVW_REV1);
168164
break;
169165

170-
case PRID_REV_LOONGSON2K_R1_0:
171-
case PRID_REV_LOONGSON2K_R1_1:
172-
case PRID_REV_LOONGSON2K_R1_2:
173-
case PRID_REV_LOONGSON2K_R1_3:
166+
case PRID_IMP_LOONGSON_64R | PRID_REV_LOONGSON2K_R1_0:
167+
case PRID_IMP_LOONGSON_64R | PRID_REV_LOONGSON2K_R1_1:
168+
case PRID_IMP_LOONGSON_64R | PRID_REV_LOONGSON2K_R1_2:
169+
case PRID_IMP_LOONGSON_64R | PRID_REV_LOONGSON2K_R1_3:
174170
decode_loongson_config6(c);
175171
probe_uca(c);
176172

@@ -183,10 +179,10 @@ void loongson3_cpucfg_synthesize_data(struct cpuinfo_mips *c)
183179
c->loongson3_cpucfg_data[2] = 0;
184180
break;
185181

186-
case PRID_REV_LOONGSON3A_R2_0:
187-
case PRID_REV_LOONGSON3A_R2_1:
188-
case PRID_REV_LOONGSON3A_R3_0:
189-
case PRID_REV_LOONGSON3A_R3_1:
182+
case PRID_IMP_LOONGSON_64C | PRID_REV_LOONGSON3A_R2_0:
183+
case PRID_IMP_LOONGSON_64C | PRID_REV_LOONGSON3A_R2_1:
184+
case PRID_IMP_LOONGSON_64C | PRID_REV_LOONGSON3A_R3_0:
185+
case PRID_IMP_LOONGSON_64C | PRID_REV_LOONGSON3A_R3_1:
190186
decode_loongson_config6(c);
191187
probe_uca(c);
192188

@@ -203,6 +199,13 @@ void loongson3_cpucfg_synthesize_data(struct cpuinfo_mips *c)
203199
LOONGSON_CFG3_LCAMKW_REV1 |
204200
LOONGSON_CFG3_LCAMVW_REV1);
205201
break;
202+
203+
default:
204+
/* It is possible that some future Loongson cores still do
205+
* not have CPUCFG, so do not emulate anything for these
206+
* cores.
207+
*/
208+
return;
206209
}
207210

208211
/* This feature is set by firmware, but all known Loongson-64 systems

0 commit comments

Comments
 (0)