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

openrisc: use shadow registers to save regs on exception

Previously, the area between 0x0-0x100 have been used as a "scratch"
memory area to temporarily store regs during exception entry. In a
multi-core environment, this will not work.

This change is to use shadow registers for nested context.

Currently only the "critical" temp load/stores are covered, the
EMERGENCY_PRINT ones are left as is (when they are used, it's game over
anyway), they need to be handled as well in the future.

Signed-off-by: Stefan Kristiansson <stefan.kristiansson@saunalahti.fi>
Signed-off-by: Stafford Horne <shorne@gmail.com>

authored by

Stefan Kristiansson and committed by
Stafford Horne
91993c8c ddc92bec

+80 -26
+11
arch/openrisc/Kconfig
··· 124 124 Say N here if you know that your OpenRISC processor has 125 125 SPR_SR_DSX bit implemented. Say Y if you are unsure. 126 126 127 + config OPENRISC_HAVE_SHADOW_GPRS 128 + bool "Support for shadow gpr files" if !SMP 129 + default y if SMP 130 + help 131 + Say Y here if your OpenRISC processor features shadowed 132 + register files. They will in such case be used as a 133 + scratch reg storage on exception entry. 134 + 135 + On SMP systems, this feature is mandatory. 136 + On a unicore system it's safe to say N here if you are unsure. 137 + 127 138 config CMDLINE 128 139 string "Default kernel command string" 129 140 default ""
+69 -26
arch/openrisc/kernel/head.S
··· 49 49 50 50 /* ============================================[ tmp store locations ]=== */ 51 51 52 + #define SPR_SHADOW_GPR(x) ((x) + SPR_GPR_BASE + 32) 53 + 52 54 /* 53 55 * emergency_print temporary stores 54 56 */ 57 + #ifdef CONFIG_OPENRISC_HAVE_SHADOW_GPRS 58 + #define EMERGENCY_PRINT_STORE_GPR4 l.mtspr r0,r4,SPR_SHADOW_GPR(14) 59 + #define EMERGENCY_PRINT_LOAD_GPR4 l.mfspr r4,r0,SPR_SHADOW_GPR(14) 60 + 61 + #define EMERGENCY_PRINT_STORE_GPR5 l.mtspr r0,r5,SPR_SHADOW_GPR(15) 62 + #define EMERGENCY_PRINT_LOAD_GPR5 l.mfspr r5,r0,SPR_SHADOW_GPR(15) 63 + 64 + #define EMERGENCY_PRINT_STORE_GPR6 l.mtspr r0,r6,SPR_SHADOW_GPR(16) 65 + #define EMERGENCY_PRINT_LOAD_GPR6 l.mfspr r6,r0,SPR_SHADOW_GPR(16) 66 + 67 + #define EMERGENCY_PRINT_STORE_GPR7 l.mtspr r0,r7,SPR_SHADOW_GPR(7) 68 + #define EMERGENCY_PRINT_LOAD_GPR7 l.mfspr r7,r0,SPR_SHADOW_GPR(7) 69 + 70 + #define EMERGENCY_PRINT_STORE_GPR8 l.mtspr r0,r8,SPR_SHADOW_GPR(8) 71 + #define EMERGENCY_PRINT_LOAD_GPR8 l.mfspr r8,r0,SPR_SHADOW_GPR(8) 72 + 73 + #define EMERGENCY_PRINT_STORE_GPR9 l.mtspr r0,r9,SPR_SHADOW_GPR(9) 74 + #define EMERGENCY_PRINT_LOAD_GPR9 l.mfspr r9,r0,SPR_SHADOW_GPR(9) 75 + 76 + #else /* !CONFIG_OPENRISC_HAVE_SHADOW_GPRS */ 55 77 #define EMERGENCY_PRINT_STORE_GPR4 l.sw 0x20(r0),r4 56 78 #define EMERGENCY_PRINT_LOAD_GPR4 l.lwz r4,0x20(r0) 57 79 ··· 92 70 #define EMERGENCY_PRINT_STORE_GPR9 l.sw 0x34(r0),r9 93 71 #define EMERGENCY_PRINT_LOAD_GPR9 l.lwz r9,0x34(r0) 94 72 73 + #endif 95 74 96 75 /* 97 76 * TLB miss handlers temorary stores 98 77 */ 99 - #define EXCEPTION_STORE_GPR9 l.sw 0x10(r0),r9 100 - #define EXCEPTION_LOAD_GPR9 l.lwz r9,0x10(r0) 78 + #ifdef CONFIG_OPENRISC_HAVE_SHADOW_GPRS 79 + #define EXCEPTION_STORE_GPR2 l.mtspr r0,r2,SPR_SHADOW_GPR(2) 80 + #define EXCEPTION_LOAD_GPR2 l.mfspr r2,r0,SPR_SHADOW_GPR(2) 101 81 82 + #define EXCEPTION_STORE_GPR3 l.mtspr r0,r3,SPR_SHADOW_GPR(3) 83 + #define EXCEPTION_LOAD_GPR3 l.mfspr r3,r0,SPR_SHADOW_GPR(3) 84 + 85 + #define EXCEPTION_STORE_GPR4 l.mtspr r0,r4,SPR_SHADOW_GPR(4) 86 + #define EXCEPTION_LOAD_GPR4 l.mfspr r4,r0,SPR_SHADOW_GPR(4) 87 + 88 + #define EXCEPTION_STORE_GPR5 l.mtspr r0,r5,SPR_SHADOW_GPR(5) 89 + #define EXCEPTION_LOAD_GPR5 l.mfspr r5,r0,SPR_SHADOW_GPR(5) 90 + 91 + #define EXCEPTION_STORE_GPR6 l.mtspr r0,r6,SPR_SHADOW_GPR(6) 92 + #define EXCEPTION_LOAD_GPR6 l.mfspr r6,r0,SPR_SHADOW_GPR(6) 93 + 94 + #else /* !CONFIG_OPENRISC_HAVE_SHADOW_GPRS */ 102 95 #define EXCEPTION_STORE_GPR2 l.sw 0x64(r0),r2 103 96 #define EXCEPTION_LOAD_GPR2 l.lwz r2,0x64(r0) 104 97 ··· 129 92 #define EXCEPTION_STORE_GPR6 l.sw 0x74(r0),r6 130 93 #define EXCEPTION_LOAD_GPR6 l.lwz r6,0x74(r0) 131 94 95 + #endif 132 96 133 97 /* 134 98 * EXCEPTION_HANDLE temporary stores 135 99 */ 136 100 101 + #ifdef CONFIG_OPENRISC_HAVE_SHADOW_GPRS 102 + #define EXCEPTION_T_STORE_GPR30 l.mtspr r0,r30,SPR_SHADOW_GPR(30) 103 + #define EXCEPTION_T_LOAD_GPR30(reg) l.mfspr reg,r0,SPR_SHADOW_GPR(30) 104 + 105 + #define EXCEPTION_T_STORE_GPR10 l.mtspr r0,r10,SPR_SHADOW_GPR(10) 106 + #define EXCEPTION_T_LOAD_GPR10(reg) l.mfspr reg,r0,SPR_SHADOW_GPR(10) 107 + 108 + #define EXCEPTION_T_STORE_SP l.mtspr r0,r1,SPR_SHADOW_GPR(1) 109 + #define EXCEPTION_T_LOAD_SP(reg) l.mfspr reg,r0,SPR_SHADOW_GPR(1) 110 + 111 + #else /* !CONFIG_OPENRISC_HAVE_SHADOW_GPRS */ 137 112 #define EXCEPTION_T_STORE_GPR30 l.sw 0x78(r0),r30 138 113 #define EXCEPTION_T_LOAD_GPR30(reg) l.lwz reg,0x78(r0) 139 114 140 115 #define EXCEPTION_T_STORE_GPR10 l.sw 0x7c(r0),r10 141 116 #define EXCEPTION_T_LOAD_GPR10(reg) l.lwz reg,0x7c(r0) 142 117 143 - #define EXCEPTION_T_STORE_SP l.sw 0x80(r0),r1 118 + #define EXCEPTION_T_STORE_SP l.sw 0x80(r0),r1 144 119 #define EXCEPTION_T_LOAD_SP(reg) l.lwz reg,0x80(r0) 145 - 146 - /* 147 - * For UNHANLDED_EXCEPTION 148 - */ 149 - 150 - #define EXCEPTION_T_STORE_GPR31 l.sw 0x84(r0),r31 151 - #define EXCEPTION_T_LOAD_GPR31(reg) l.lwz reg,0x84(r0) 120 + #endif 152 121 153 122 /* =========================================================[ macros ]=== */ 154 123 ··· 269 226 * 270 227 */ 271 228 #define UNHANDLED_EXCEPTION(handler) \ 272 - EXCEPTION_T_STORE_GPR31 ;\ 229 + EXCEPTION_T_STORE_GPR30 ;\ 273 230 EXCEPTION_T_STORE_GPR10 ;\ 274 231 EXCEPTION_T_STORE_SP ;\ 275 232 /* temporary store r3, r9 into r1, r10 */ ;\ ··· 298 255 /* r1: KSP, r10: current, r31: __pa(KSP) */ ;\ 299 256 /* r12: temp, syscall indicator, r13 temp */ ;\ 300 257 l.addi r1,r1,-(INT_FRAME_SIZE) ;\ 301 - /* r1 is KSP, r31 is __pa(KSP) */ ;\ 302 - tophys (r31,r1) ;\ 303 - l.sw PT_GPR12(r31),r12 ;\ 258 + /* r1 is KSP, r30 is __pa(KSP) */ ;\ 259 + tophys (r30,r1) ;\ 260 + l.sw PT_GPR12(r30),r12 ;\ 304 261 l.mfspr r12,r0,SPR_EPCR_BASE ;\ 305 - l.sw PT_PC(r31),r12 ;\ 262 + l.sw PT_PC(r30),r12 ;\ 306 263 l.mfspr r12,r0,SPR_ESR_BASE ;\ 307 - l.sw PT_SR(r31),r12 ;\ 264 + l.sw PT_SR(r30),r12 ;\ 308 265 /* save r31 */ ;\ 309 - EXCEPTION_T_LOAD_GPR31(r12) ;\ 310 - l.sw PT_GPR31(r31),r12 ;\ 266 + EXCEPTION_T_LOAD_GPR30(r12) ;\ 267 + l.sw PT_GPR30(r30),r12 ;\ 311 268 /* save r10 as was prior to exception */ ;\ 312 269 EXCEPTION_T_LOAD_GPR10(r12) ;\ 313 - l.sw PT_GPR10(r31),r12 ;\ 270 + l.sw PT_GPR10(r30),r12 ;\ 314 271 /* save PT_SP as was prior to exception */ ;\ 315 272 EXCEPTION_T_LOAD_SP(r12) ;\ 316 - l.sw PT_SP(r31),r12 ;\ 317 - l.sw PT_GPR13(r31),r13 ;\ 273 + l.sw PT_SP(r30),r12 ;\ 274 + l.sw PT_GPR13(r30),r13 ;\ 318 275 /* --> */ ;\ 319 276 /* save exception r4, set r4 = EA */ ;\ 320 - l.sw PT_GPR4(r31),r4 ;\ 277 + l.sw PT_GPR4(r30),r4 ;\ 321 278 l.mfspr r4,r0,SPR_EEAR_BASE ;\ 322 279 /* r12 == 1 if we come from syscall */ ;\ 323 280 CLEAR_GPR(r12) ;\ 324 281 /* ----- play a MMU trick ----- */ ;\ 325 - l.ori r31,r0,(EXCEPTION_SR) ;\ 326 - l.mtspr r0,r31,SPR_ESR_BASE ;\ 282 + l.ori r30,r0,(EXCEPTION_SR) ;\ 283 + l.mtspr r0,r30,SPR_ESR_BASE ;\ 327 284 /* r31: EA address of handler */ ;\ 328 - LOAD_SYMBOL_2_GPR(r31,handler) ;\ 329 - l.mtspr r0,r31,SPR_EPCR_BASE ;\ 285 + LOAD_SYMBOL_2_GPR(r30,handler) ;\ 286 + l.mtspr r0,r30,SPR_EPCR_BASE ;\ 330 287 l.rfe 331 288 332 289 /* =====================================================[ exceptions] === */