Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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 <chenhc@lemote.com>
Cc: Jiaxun Yang <jiaxun.yang@flygoat.com>
Signed-off-by: WANG Xuerui <git@xen0n.name>
Reviewed-by: Huacai Chen <chenhc@lemote.com>
Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>

authored by

WANG Xuerui and committed by
Thomas Bogendoerfer
70768eba b3878a6a

+35 -17
+11
arch/mips/include/asm/mach-loongson64/cpucfg-emul.h
··· 12 12 13 13 void loongson3_cpucfg_synthesize_data(struct cpuinfo_mips *c); 14 14 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 + 15 21 static inline u32 loongson3_cpucfg_read_synthesized(struct cpuinfo_mips *c, 16 22 __u64 sel) 17 23 { ··· 57 51 #else 58 52 static inline void loongson3_cpucfg_synthesize_data(struct cpuinfo_mips *c) 59 53 { 54 + } 55 + 56 + static inline bool loongson3_cpucfg_emulation_enabled(struct cpuinfo_mips *c) 57 + { 58 + return false; 60 59 } 61 60 62 61 static inline u32 loongson3_cpucfg_read_synthesized(struct cpuinfo_mips *c,
+4
arch/mips/kernel/traps.c
··· 722 722 723 723 perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, regs, 0); 724 724 725 + /* Do not emulate on unsupported core models. */ 726 + if (!loongson3_cpucfg_emulation_enabled(&current_cpu_data)) 727 + return -1; 728 + 725 729 regs->regs[rd] = loongson3_cpucfg_read_synthesized( 726 730 &current_cpu_data, sel); 727 731
+20 -17
arch/mips/loongson64/cpucfg-emul.c
··· 134 134 c->loongson3_cpucfg_data[1] = 0; 135 135 c->loongson3_cpucfg_data[2] = 0; 136 136 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: 144 140 c->loongson3_cpucfg_data[0] |= (LOONGSON_CFG1_LSLDR0 | 145 141 LOONGSON_CFG1_LSSYNCI | LOONGSON_CFG1_LSUCA | 146 142 LOONGSON_CFG1_LLSYNC | LOONGSON_CFG1_TGTSYNC); ··· 149 153 LOONGSON_CFG3_LCAMVW_REV1); 150 154 break; 151 155 152 - case PRID_REV_LOONGSON3B_R1: 153 - case PRID_REV_LOONGSON3B_R2: 156 + case PRID_IMP_LOONGSON_64C | PRID_REV_LOONGSON3B_R1: 157 + case PRID_IMP_LOONGSON_64C | PRID_REV_LOONGSON3B_R2: 154 158 c->loongson3_cpucfg_data[0] |= (LOONGSON_CFG1_LSLDR0 | 155 159 LOONGSON_CFG1_LSSYNCI | LOONGSON_CFG1_LSUCA | 156 160 LOONGSON_CFG1_LLSYNC | LOONGSON_CFG1_TGTSYNC); ··· 163 167 LOONGSON_CFG3_LCAMVW_REV1); 164 168 break; 165 169 166 - case PRID_REV_LOONGSON2K_R1_0: 167 - case PRID_REV_LOONGSON2K_R1_1: 168 - case PRID_REV_LOONGSON2K_R1_2: 169 - case PRID_REV_LOONGSON2K_R1_3: 170 + case PRID_IMP_LOONGSON_64R | PRID_REV_LOONGSON2K_R1_0: 171 + case PRID_IMP_LOONGSON_64R | PRID_REV_LOONGSON2K_R1_1: 172 + case PRID_IMP_LOONGSON_64R | PRID_REV_LOONGSON2K_R1_2: 173 + case PRID_IMP_LOONGSON_64R | PRID_REV_LOONGSON2K_R1_3: 170 174 decode_loongson_config6(c); 171 175 probe_uca(c); 172 176 ··· 179 183 c->loongson3_cpucfg_data[2] = 0; 180 184 break; 181 185 182 - case PRID_REV_LOONGSON3A_R2_0: 183 - case PRID_REV_LOONGSON3A_R2_1: 184 - case PRID_REV_LOONGSON3A_R3_0: 185 - case PRID_REV_LOONGSON3A_R3_1: 186 + case PRID_IMP_LOONGSON_64C | PRID_REV_LOONGSON3A_R2_0: 187 + case PRID_IMP_LOONGSON_64C | PRID_REV_LOONGSON3A_R2_1: 188 + case PRID_IMP_LOONGSON_64C | PRID_REV_LOONGSON3A_R3_0: 189 + case PRID_IMP_LOONGSON_64C | PRID_REV_LOONGSON3A_R3_1: 186 190 decode_loongson_config6(c); 187 191 probe_uca(c); 188 192 ··· 199 203 LOONGSON_CFG3_LCAMKW_REV1 | 200 204 LOONGSON_CFG3_LCAMVW_REV1); 201 205 break; 206 + 207 + default: 208 + /* It is possible that some future Loongson cores still do 209 + * not have CPUCFG, so do not emulate anything for these 210 + * cores. 211 + */ 212 + return; 202 213 } 203 214 204 215 /* This feature is set by firmware, but all known Loongson-64 systems