aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorMichael Neuling <mikey@neuling.org>2013-09-25 23:29:09 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-10-13 19:08:31 -0400
commit72daf965bb8fe1447069db3ea511047f20eca947 (patch)
tree11ab786f3eafb9a6fc9b5c79f0d086f62eb10b91 /arch
parent09bee3bc290da5f7f39b62f65f1a3deeaa3834ac (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.S94
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"
83DSCR_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
350restore_gprs: 370restore_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 /* ****************************************************************** */