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

[MIPS] Fix shadow register support.

Shadow register support would not possibly have worked on multicore
systems. The support code for it was also depending not on MIPS R2 but
VSMP or SMTC kernels even though it makes perfect sense with UP kernels.

SR sets are a scarce resource and the expected usage pattern is that
users actually hardcode the register set numbers in their code. So fix
the allocator by ditching it. Move the remaining CPU probe bits into
the generic CPU probe.

Signed-off-by: Ralf Baechle <ralf@linux-mips.org>

+11 -74
-9
arch/mips/Kconfig
··· 1409 1409 depends on SYS_SUPPORTS_MULTITHREADING 1410 1410 select CPU_MIPSR2_IRQ_VI 1411 1411 select CPU_MIPSR2_IRQ_EI 1412 - select CPU_MIPSR2_SRS 1413 1412 select MIPS_MT 1414 1413 select NR_CPUS_DEFAULT_2 1415 1414 select SMP ··· 1425 1426 select GENERIC_CLOCKEVENTS_BROADCAST 1426 1427 select CPU_MIPSR2_IRQ_VI 1427 1428 select CPU_MIPSR2_IRQ_EI 1428 - select CPU_MIPSR2_SRS 1429 1429 select MIPS_MT 1430 1430 select NR_CPUS_DEFAULT_8 1431 1431 select SMP ··· 1451 1453 depends on SYS_SUPPORTS_MULTITHREADING 1452 1454 select CPU_MIPSR2_IRQ_VI 1453 1455 select CPU_MIPSR2_IRQ_EI 1454 - select CPU_MIPSR2_SRS 1455 1456 select MIPS_MT 1456 1457 help 1457 1458 Includes a loader for loading an elf relocatable object ··· 1577 1580 # Extended interrupt mode is an R2 feature 1578 1581 # 1579 1582 config CPU_MIPSR2_IRQ_EI 1580 - bool 1581 - 1582 - # 1583 - # Shadow registers are an R2 feature 1584 - # 1585 - config CPU_MIPSR2_SRS 1586 1583 bool 1587 1584 1588 1585 config CPU_HAS_SYNC
+5
arch/mips/kernel/cpu-probe.c
··· 943 943 } 944 944 945 945 __cpu_name[cpu] = cpu_to_name(c); 946 + 947 + if (cpu_has_mips_r2) 948 + c->srsets = ((read_c0_srsctl() >> 26) & 0x0f) + 1; 949 + else 950 + c->srsets = 1; 946 951 } 947 952 948 953 __init void cpu_report(void)
+2
arch/mips/kernel/proc.c
··· 60 60 cpu_has_dsp ? " dsp" : "", 61 61 cpu_has_mipsmt ? " mt" : "" 62 62 ); 63 + seq_printf(m, "shadow register sets\t: %d\n", 64 + cpu_data[n].srsets); 63 65 64 66 sprintf(fmt, "VCE%%c exceptions\t\t: %s\n", 65 67 cpu_has_vce ? "%u" : "not available");
+3 -65
arch/mips/kernel/traps.c
··· 1100 1100 return (void *)old_handler; 1101 1101 } 1102 1102 1103 - #ifdef CONFIG_CPU_MIPSR2_SRS 1104 - /* 1105 - * MIPSR2 shadow register set allocation 1106 - * FIXME: SMP... 1107 - */ 1108 - 1109 - static struct shadow_registers { 1110 - /* 1111 - * Number of shadow register sets supported 1112 - */ 1113 - unsigned long sr_supported; 1114 - /* 1115 - * Bitmap of allocated shadow registers 1116 - */ 1117 - unsigned long sr_allocated; 1118 - } shadow_registers; 1119 - 1120 - static void mips_srs_init(void) 1121 - { 1122 - shadow_registers.sr_supported = ((read_c0_srsctl() >> 26) & 0x0f) + 1; 1123 - printk(KERN_INFO "%ld MIPSR2 register sets available\n", 1124 - shadow_registers.sr_supported); 1125 - shadow_registers.sr_allocated = 1; /* Set 0 used by kernel */ 1126 - } 1127 - 1128 - int mips_srs_max(void) 1129 - { 1130 - return shadow_registers.sr_supported; 1131 - } 1132 - 1133 - int mips_srs_alloc(void) 1134 - { 1135 - struct shadow_registers *sr = &shadow_registers; 1136 - int set; 1137 - 1138 - again: 1139 - set = find_first_zero_bit(&sr->sr_allocated, sr->sr_supported); 1140 - if (set >= sr->sr_supported) 1141 - return -1; 1142 - 1143 - if (test_and_set_bit(set, &sr->sr_allocated)) 1144 - goto again; 1145 - 1146 - return set; 1147 - } 1148 - 1149 - void mips_srs_free(int set) 1150 - { 1151 - struct shadow_registers *sr = &shadow_registers; 1152 - 1153 - clear_bit(set, &sr->sr_allocated); 1154 - } 1155 - 1156 1103 static asmlinkage void do_default_vi(void) 1157 1104 { 1158 1105 show_regs(get_irq_regs()); ··· 1110 1163 { 1111 1164 unsigned long handler; 1112 1165 unsigned long old_handler = vi_handlers[n]; 1166 + int srssets = current_cpu_data.srsets; 1113 1167 u32 *w; 1114 1168 unsigned char *b; 1115 1169 ··· 1126 1178 1127 1179 b = (unsigned char *)(ebase + 0x200 + n*VECTORSPACING); 1128 1180 1129 - if (srs >= mips_srs_max()) 1181 + if (srs >= srssets) 1130 1182 panic("Shadow register set %d not supported", srs); 1131 1183 1132 1184 if (cpu_has_veic) { ··· 1134 1186 board_bind_eic_interrupt(n, srs); 1135 1187 } else if (cpu_has_vint) { 1136 1188 /* SRSMap is only defined if shadow sets are implemented */ 1137 - if (mips_srs_max() > 1) 1189 + if (srssets > 1) 1138 1190 change_c0_srsmap(0xf << n*4, srs << n*4); 1139 1191 } 1140 1192 ··· 1200 1252 { 1201 1253 return set_vi_srs_handler(n, addr, 0); 1202 1254 } 1203 - 1204 - #else 1205 - 1206 - static inline void mips_srs_init(void) 1207 - { 1208 - } 1209 - 1210 - #endif /* CONFIG_CPU_MIPSR2_SRS */ 1211 1255 1212 1256 /* 1213 1257 * This is used by native signal handling ··· 1442 1502 ebase = (unsigned long) alloc_bootmem_low_pages(0x200 + VECTORSPACING*64); 1443 1503 else 1444 1504 ebase = CAC_BASE; 1445 - 1446 - mips_srs_init(); 1447 1505 1448 1506 per_cpu_trap_init(); 1449 1507
+1
include/asm-mips/cpu-info.h
··· 54 54 struct cache_desc dcache; /* Primary D or combined I/D cache */ 55 55 struct cache_desc scache; /* Secondary cache */ 56 56 struct cache_desc tcache; /* Tertiary/split secondary cache */ 57 + int srsets; /* Shadow register sets */ 57 58 #if defined(CONFIG_MIPS_MT_SMTC) 58 59 /* 59 60 * In the MIPS MT "SMTC" model, each TC is considered