diff options
author | Michael Neuling <mikey@neuling.org> | 2013-09-25 23:29:09 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-10-13 19:08:31 -0400 |
commit | 72daf965bb8fe1447069db3ea511047f20eca947 (patch) | |
tree | 11ab786f3eafb9a6fc9b5c79f0d086f62eb10b91 /arch | |
parent | 09bee3bc290da5f7f39b62f65f1a3deeaa3834ac (diff) |
powerpc/tm: Switch out userspace PPR and DSCR sooner
commit e9bdc3d6143d1c4b8d8ce5231fc958268331f983 upstream.
When we do a treclaim or trecheckpoint we end up running with userspace
PPR and DSCR values. Currently we don't do anything special to avoid
running with user values which could cause a severe performance
degradation.
This patch moves the PPR and DSCR save and restore around treclaim and
trecheckpoint so that we run with user values for a much shorter period.
More care is taken with the PPR as it's impact is greater than the DSCR.
This is similar to user exceptions, where we run HTM_MEDIUM early to
ensure that we don't run with a userspace PPR values in the kernel.
Signed-off-by: Michael Neuling <mikey@neuling.org>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/powerpc/kernel/tm.S | 94 |
1 files changed, 63 insertions, 31 deletions
diff --git a/arch/powerpc/kernel/tm.S b/arch/powerpc/kernel/tm.S index 1edd6c2a168d..f2abb219a17b 100644 --- a/arch/powerpc/kernel/tm.S +++ b/arch/powerpc/kernel/tm.S | |||
@@ -79,6 +79,11 @@ _GLOBAL(tm_abort) | |||
79 | TABORT(R3) | 79 | TABORT(R3) |
80 | blr | 80 | blr |
81 | 81 | ||
82 | .section ".toc","aw" | ||
83 | DSCR_DEFAULT: | ||
84 | .tc dscr_default[TC],dscr_default | ||
85 | |||
86 | .section ".text" | ||
82 | 87 | ||
83 | /* void tm_reclaim(struct thread_struct *thread, | 88 | /* void tm_reclaim(struct thread_struct *thread, |
84 | * unsigned long orig_msr, | 89 | * unsigned long orig_msr, |
@@ -178,11 +183,18 @@ dont_backup_fp: | |||
178 | std r1, PACATMSCRATCH(r13) | 183 | std r1, PACATMSCRATCH(r13) |
179 | ld r1, PACAR1(r13) | 184 | ld r1, PACAR1(r13) |
180 | 185 | ||
186 | /* Store the PPR in r11 and reset to decent value */ | ||
187 | std r11, GPR11(r1) /* Temporary stash */ | ||
188 | mfspr r11, SPRN_PPR | ||
189 | HMT_MEDIUM | ||
190 | |||
181 | /* Now get some more GPRS free */ | 191 | /* Now get some more GPRS free */ |
182 | std r7, GPR7(r1) /* Temporary stash */ | 192 | std r7, GPR7(r1) /* Temporary stash */ |
183 | std r12, GPR12(r1) /* '' '' '' */ | 193 | std r12, GPR12(r1) /* '' '' '' */ |
184 | ld r12, STACK_PARAM(0)(r1) /* Param 0, thread_struct * */ | 194 | ld r12, STACK_PARAM(0)(r1) /* Param 0, thread_struct * */ |
185 | 195 | ||
196 | std r11, THREAD_TM_PPR(r12) /* Store PPR and free r11 */ | ||
197 | |||
186 | addi r7, r12, PT_CKPT_REGS /* Thread's ckpt_regs */ | 198 | addi r7, r12, PT_CKPT_REGS /* Thread's ckpt_regs */ |
187 | 199 | ||
188 | /* Make r7 look like an exception frame so that we | 200 | /* Make r7 look like an exception frame so that we |
@@ -194,15 +206,19 @@ dont_backup_fp: | |||
194 | SAVE_GPR(0, r7) /* user r0 */ | 206 | SAVE_GPR(0, r7) /* user r0 */ |
195 | SAVE_GPR(2, r7) /* user r2 */ | 207 | SAVE_GPR(2, r7) /* user r2 */ |
196 | SAVE_4GPRS(3, r7) /* user r3-r6 */ | 208 | SAVE_4GPRS(3, r7) /* user r3-r6 */ |
197 | SAVE_4GPRS(8, r7) /* user r8-r11 */ | 209 | SAVE_GPR(8, r7) /* user r8 */ |
210 | SAVE_GPR(9, r7) /* user r9 */ | ||
211 | SAVE_GPR(10, r7) /* user r10 */ | ||
198 | ld r3, PACATMSCRATCH(r13) /* user r1 */ | 212 | ld r3, PACATMSCRATCH(r13) /* user r1 */ |
199 | ld r4, GPR7(r1) /* user r7 */ | 213 | ld r4, GPR7(r1) /* user r7 */ |
200 | ld r5, GPR12(r1) /* user r12 */ | 214 | ld r5, GPR11(r1) /* user r11 */ |
201 | GET_SCRATCH0(6) /* user r13 */ | 215 | ld r6, GPR12(r1) /* user r12 */ |
216 | GET_SCRATCH0(8) /* user r13 */ | ||
202 | std r3, GPR1(r7) | 217 | std r3, GPR1(r7) |
203 | std r4, GPR7(r7) | 218 | std r4, GPR7(r7) |
204 | std r5, GPR12(r7) | 219 | std r5, GPR11(r7) |
205 | std r6, GPR13(r7) | 220 | std r6, GPR12(r7) |
221 | std r8, GPR13(r7) | ||
206 | 222 | ||
207 | SAVE_NVGPRS(r7) /* user r14-r31 */ | 223 | SAVE_NVGPRS(r7) /* user r14-r31 */ |
208 | 224 | ||
@@ -225,14 +241,12 @@ dont_backup_fp: | |||
225 | std r6, _XER(r7) | 241 | std r6, _XER(r7) |
226 | 242 | ||
227 | 243 | ||
228 | /* ******************** TAR, PPR, DSCR ********** */ | 244 | /* ******************** TAR, DSCR ********** */ |
229 | mfspr r3, SPRN_TAR | 245 | mfspr r3, SPRN_TAR |
230 | mfspr r4, SPRN_PPR | 246 | mfspr r4, SPRN_DSCR |
231 | mfspr r5, SPRN_DSCR | ||
232 | 247 | ||
233 | std r3, THREAD_TM_TAR(r12) | 248 | std r3, THREAD_TM_TAR(r12) |
234 | std r4, THREAD_TM_PPR(r12) | 249 | std r4, THREAD_TM_DSCR(r12) |
235 | std r5, THREAD_TM_DSCR(r12) | ||
236 | 250 | ||
237 | /* MSR and flags: We don't change CRs, and we don't need to alter | 251 | /* MSR and flags: We don't change CRs, and we don't need to alter |
238 | * MSR. | 252 | * MSR. |
@@ -249,7 +263,7 @@ dont_backup_fp: | |||
249 | std r3, THREAD_TM_TFHAR(r12) | 263 | std r3, THREAD_TM_TFHAR(r12) |
250 | std r4, THREAD_TM_TFIAR(r12) | 264 | std r4, THREAD_TM_TFIAR(r12) |
251 | 265 | ||
252 | /* AMR and PPR are checkpointed too, but are unsupported by Linux. */ | 266 | /* AMR is checkpointed too, but is unsupported by Linux. */ |
253 | 267 | ||
254 | /* Restore original MSR/IRQ state & clear TM mode */ | 268 | /* Restore original MSR/IRQ state & clear TM mode */ |
255 | ld r14, TM_FRAME_L0(r1) /* Orig MSR */ | 269 | ld r14, TM_FRAME_L0(r1) /* Orig MSR */ |
@@ -265,6 +279,12 @@ dont_backup_fp: | |||
265 | mtcr r4 | 279 | mtcr r4 |
266 | mtlr r0 | 280 | mtlr r0 |
267 | ld r2, 40(r1) | 281 | ld r2, 40(r1) |
282 | |||
283 | /* Load system default DSCR */ | ||
284 | ld r4, DSCR_DEFAULT@toc(r2) | ||
285 | ld r0, 0(r4) | ||
286 | mtspr SPRN_DSCR, r0 | ||
287 | |||
268 | blr | 288 | blr |
269 | 289 | ||
270 | 290 | ||
@@ -349,44 +369,50 @@ dont_restore_fp: | |||
349 | 369 | ||
350 | restore_gprs: | 370 | restore_gprs: |
351 | 371 | ||
352 | /* ******************** TAR, PPR, DSCR ********** */ | 372 | /* ******************** CR,LR,CCR,MSR ********** */ |
353 | ld r4, THREAD_TM_TAR(r3) | 373 | ld r4, _CTR(r7) |
354 | ld r5, THREAD_TM_PPR(r3) | 374 | ld r5, _LINK(r7) |
355 | ld r6, THREAD_TM_DSCR(r3) | 375 | ld r6, _CCR(r7) |
376 | ld r8, _XER(r7) | ||
356 | 377 | ||
357 | mtspr SPRN_TAR, r4 | 378 | mtctr r4 |
358 | mtspr SPRN_PPR, r5 | 379 | mtlr r5 |
359 | mtspr SPRN_DSCR, r6 | 380 | mtcr r6 |
381 | mtxer r8 | ||
360 | 382 | ||
361 | /* ******************** CR,LR,CCR,MSR ********** */ | 383 | /* ******************** TAR ******************** */ |
362 | ld r3, _CTR(r7) | 384 | ld r4, THREAD_TM_TAR(r3) |
363 | ld r4, _LINK(r7) | 385 | mtspr SPRN_TAR, r4 |
364 | ld r5, _CCR(r7) | ||
365 | ld r6, _XER(r7) | ||
366 | 386 | ||
367 | mtctr r3 | 387 | /* Load up the PPR and DSCR in GPRs only at this stage */ |
368 | mtlr r4 | 388 | ld r5, THREAD_TM_DSCR(r3) |
369 | mtcr r5 | 389 | ld r6, THREAD_TM_PPR(r3) |
370 | mtxer r6 | ||
371 | 390 | ||
372 | /* MSR and flags: We don't change CRs, and we don't need to alter | 391 | /* MSR and flags: We don't change CRs, and we don't need to alter |
373 | * MSR. | 392 | * MSR. |
374 | */ | 393 | */ |
375 | 394 | ||
376 | REST_4GPRS(0, r7) /* GPR0-3 */ | 395 | REST_4GPRS(0, r7) /* GPR0-3 */ |
377 | REST_GPR(4, r7) /* GPR4-6 */ | 396 | REST_GPR(4, r7) /* GPR4 */ |
378 | REST_GPR(5, r7) | ||
379 | REST_GPR(6, r7) | ||
380 | REST_4GPRS(8, r7) /* GPR8-11 */ | 397 | REST_4GPRS(8, r7) /* GPR8-11 */ |
381 | REST_2GPRS(12, r7) /* GPR12-13 */ | 398 | REST_2GPRS(12, r7) /* GPR12-13 */ |
382 | 399 | ||
383 | REST_NVGPRS(r7) /* GPR14-31 */ | 400 | REST_NVGPRS(r7) /* GPR14-31 */ |
384 | 401 | ||
385 | ld r7, GPR7(r7) /* GPR7 */ | 402 | /* Load up PPR and DSCR here so we don't run with user values for long |
403 | */ | ||
404 | mtspr SPRN_DSCR, r5 | ||
405 | mtspr SPRN_PPR, r6 | ||
406 | |||
407 | REST_GPR(5, r7) /* GPR5-7 */ | ||
408 | REST_GPR(6, r7) | ||
409 | ld r7, GPR7(r7) | ||
386 | 410 | ||
387 | /* Commit register state as checkpointed state: */ | 411 | /* Commit register state as checkpointed state: */ |
388 | TRECHKPT | 412 | TRECHKPT |
389 | 413 | ||
414 | HMT_MEDIUM | ||
415 | |||
390 | /* Our transactional state has now changed. | 416 | /* Our transactional state has now changed. |
391 | * | 417 | * |
392 | * Now just get out of here. Transactional (current) state will be | 418 | * Now just get out of here. Transactional (current) state will be |
@@ -405,6 +431,12 @@ restore_gprs: | |||
405 | mtcr r4 | 431 | mtcr r4 |
406 | mtlr r0 | 432 | mtlr r0 |
407 | ld r2, 40(r1) | 433 | ld r2, 40(r1) |
434 | |||
435 | /* Load system default DSCR */ | ||
436 | ld r4, DSCR_DEFAULT@toc(r2) | ||
437 | ld r0, 0(r4) | ||
438 | mtspr SPRN_DSCR, r0 | ||
439 | |||
408 | blr | 440 | blr |
409 | 441 | ||
410 | /* ****************************************************************** */ | 442 | /* ****************************************************************** */ |