aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc
diff options
context:
space:
mode:
authorMichael Neuling <mikey@neuling.org>2013-09-25 23:29:09 -0400
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2013-10-03 03:25:51 -0400
commite9bdc3d6143d1c4b8d8ce5231fc958268331f983 (patch)
tree1892620b40d70713d28dfdaf266ad993e41248eb /arch/powerpc
parentc69e63b0f135fa51d6e1c38b5ac8a1def15ea3fa (diff)
powerpc/tm: Switch out userspace PPR and DSCR sooner
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> Cc: <stable@vger.kernel.org> # 3.9+ Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc')
-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 8ece1908be1a..cd809eaa8b5c 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,
@@ -188,11 +193,18 @@ dont_backup_fp:
188 std r1, PACATMSCRATCH(r13) 193 std r1, PACATMSCRATCH(r13)
189 ld r1, PACAR1(r13) 194 ld r1, PACAR1(r13)
190 195
196 /* Store the PPR in r11 and reset to decent value */
197 std r11, GPR11(r1) /* Temporary stash */
198 mfspr r11, SPRN_PPR
199 HMT_MEDIUM
200
191 /* Now get some more GPRS free */ 201 /* Now get some more GPRS free */
192 std r7, GPR7(r1) /* Temporary stash */ 202 std r7, GPR7(r1) /* Temporary stash */
193 std r12, GPR12(r1) /* '' '' '' */ 203 std r12, GPR12(r1) /* '' '' '' */
194 ld r12, STACK_PARAM(0)(r1) /* Param 0, thread_struct * */ 204 ld r12, STACK_PARAM(0)(r1) /* Param 0, thread_struct * */
195 205
206 std r11, THREAD_TM_PPR(r12) /* Store PPR and free r11 */
207
196 addi r7, r12, PT_CKPT_REGS /* Thread's ckpt_regs */ 208 addi r7, r12, PT_CKPT_REGS /* Thread's ckpt_regs */
197 209
198 /* Make r7 look like an exception frame so that we 210 /* Make r7 look like an exception frame so that we
@@ -204,15 +216,19 @@ dont_backup_fp:
204 SAVE_GPR(0, r7) /* user r0 */ 216 SAVE_GPR(0, r7) /* user r0 */
205 SAVE_GPR(2, r7) /* user r2 */ 217 SAVE_GPR(2, r7) /* user r2 */
206 SAVE_4GPRS(3, r7) /* user r3-r6 */ 218 SAVE_4GPRS(3, r7) /* user r3-r6 */
207 SAVE_4GPRS(8, r7) /* user r8-r11 */ 219 SAVE_GPR(8, r7) /* user r8 */
220 SAVE_GPR(9, r7) /* user r9 */
221 SAVE_GPR(10, r7) /* user r10 */
208 ld r3, PACATMSCRATCH(r13) /* user r1 */ 222 ld r3, PACATMSCRATCH(r13) /* user r1 */
209 ld r4, GPR7(r1) /* user r7 */ 223 ld r4, GPR7(r1) /* user r7 */
210 ld r5, GPR12(r1) /* user r12 */ 224 ld r5, GPR11(r1) /* user r11 */
211 GET_SCRATCH0(6) /* user r13 */ 225 ld r6, GPR12(r1) /* user r12 */
226 GET_SCRATCH0(8) /* user r13 */
212 std r3, GPR1(r7) 227 std r3, GPR1(r7)
213 std r4, GPR7(r7) 228 std r4, GPR7(r7)
214 std r5, GPR12(r7) 229 std r5, GPR11(r7)
215 std r6, GPR13(r7) 230 std r6, GPR12(r7)
231 std r8, GPR13(r7)
216 232
217 SAVE_NVGPRS(r7) /* user r14-r31 */ 233 SAVE_NVGPRS(r7) /* user r14-r31 */
218 234
@@ -235,14 +251,12 @@ dont_backup_fp:
235 std r6, _XER(r7) 251 std r6, _XER(r7)
236 252
237 253
238 /* ******************** TAR, PPR, DSCR ********** */ 254 /* ******************** TAR, DSCR ********** */
239 mfspr r3, SPRN_TAR 255 mfspr r3, SPRN_TAR
240 mfspr r4, SPRN_PPR 256 mfspr r4, SPRN_DSCR
241 mfspr r5, SPRN_DSCR
242 257
243 std r3, THREAD_TM_TAR(r12) 258 std r3, THREAD_TM_TAR(r12)
244 std r4, THREAD_TM_PPR(r12) 259 std r4, THREAD_TM_DSCR(r12)
245 std r5, THREAD_TM_DSCR(r12)
246 260
247 /* MSR and flags: We don't change CRs, and we don't need to alter 261 /* MSR and flags: We don't change CRs, and we don't need to alter
248 * MSR. 262 * MSR.
@@ -259,7 +273,7 @@ dont_backup_fp:
259 std r3, THREAD_TM_TFHAR(r12) 273 std r3, THREAD_TM_TFHAR(r12)
260 std r4, THREAD_TM_TFIAR(r12) 274 std r4, THREAD_TM_TFIAR(r12)
261 275
262 /* AMR and PPR are checkpointed too, but are unsupported by Linux. */ 276 /* AMR is checkpointed too, but is unsupported by Linux. */
263 277
264 /* Restore original MSR/IRQ state & clear TM mode */ 278 /* Restore original MSR/IRQ state & clear TM mode */
265 ld r14, TM_FRAME_L0(r1) /* Orig MSR */ 279 ld r14, TM_FRAME_L0(r1) /* Orig MSR */
@@ -275,6 +289,12 @@ dont_backup_fp:
275 mtcr r4 289 mtcr r4
276 mtlr r0 290 mtlr r0
277 ld r2, 40(r1) 291 ld r2, 40(r1)
292
293 /* Load system default DSCR */
294 ld r4, DSCR_DEFAULT@toc(r2)
295 ld r0, 0(r4)
296 mtspr SPRN_DSCR, r0
297
278 blr 298 blr
279 299
280 300
@@ -359,25 +379,24 @@ dont_restore_fp:
359 379
360restore_gprs: 380restore_gprs:
361 381
362 /* ******************** TAR, PPR, DSCR ********** */ 382 /* ******************** CR,LR,CCR,MSR ********** */
363 ld r4, THREAD_TM_TAR(r3) 383 ld r4, _CTR(r7)
364 ld r5, THREAD_TM_PPR(r3) 384 ld r5, _LINK(r7)
365 ld r6, THREAD_TM_DSCR(r3) 385 ld r6, _CCR(r7)
386 ld r8, _XER(r7)
366 387
367 mtspr SPRN_TAR, r4 388 mtctr r4
368 mtspr SPRN_PPR, r5 389 mtlr r5
369 mtspr SPRN_DSCR, r6 390 mtcr r6
391 mtxer r8
370 392
371 /* ******************** CR,LR,CCR,MSR ********** */ 393 /* ******************** TAR ******************** */
372 ld r3, _CTR(r7) 394 ld r4, THREAD_TM_TAR(r3)
373 ld r4, _LINK(r7) 395 mtspr SPRN_TAR, r4
374 ld r5, _CCR(r7)
375 ld r6, _XER(r7)
376 396
377 mtctr r3 397 /* Load up the PPR and DSCR in GPRs only at this stage */
378 mtlr r4 398 ld r5, THREAD_TM_DSCR(r3)
379 mtcr r5 399 ld r6, THREAD_TM_PPR(r3)
380 mtxer r6
381 400
382 /* Clear the MSR RI since we are about to change R1. EE is already off 401 /* Clear the MSR RI since we are about to change R1. EE is already off
383 */ 402 */
@@ -385,19 +404,26 @@ restore_gprs:
385 mtmsrd r4, 1 404 mtmsrd r4, 1
386 405
387 REST_4GPRS(0, r7) /* GPR0-3 */ 406 REST_4GPRS(0, r7) /* GPR0-3 */
388 REST_GPR(4, r7) /* GPR4-6 */ 407 REST_GPR(4, r7) /* GPR4 */
389 REST_GPR(5, r7)
390 REST_GPR(6, r7)
391 REST_4GPRS(8, r7) /* GPR8-11 */ 408 REST_4GPRS(8, r7) /* GPR8-11 */
392 REST_2GPRS(12, r7) /* GPR12-13 */ 409 REST_2GPRS(12, r7) /* GPR12-13 */
393 410
394 REST_NVGPRS(r7) /* GPR14-31 */ 411 REST_NVGPRS(r7) /* GPR14-31 */
395 412
396 ld r7, GPR7(r7) /* GPR7 */ 413 /* Load up PPR and DSCR here so we don't run with user values for long
414 */
415 mtspr SPRN_DSCR, r5
416 mtspr SPRN_PPR, r6
417
418 REST_GPR(5, r7) /* GPR5-7 */
419 REST_GPR(6, r7)
420 ld r7, GPR7(r7)
397 421
398 /* Commit register state as checkpointed state: */ 422 /* Commit register state as checkpointed state: */
399 TRECHKPT 423 TRECHKPT
400 424
425 HMT_MEDIUM
426
401 /* Our transactional state has now changed. 427 /* Our transactional state has now changed.
402 * 428 *
403 * Now just get out of here. Transactional (current) state will be 429 * Now just get out of here. Transactional (current) state will be
@@ -420,6 +446,12 @@ restore_gprs:
420 mtcr r4 446 mtcr r4
421 mtlr r0 447 mtlr r0
422 ld r2, 40(r1) 448 ld r2, 40(r1)
449
450 /* Load system default DSCR */
451 ld r4, DSCR_DEFAULT@toc(r2)
452 ld r0, 0(r4)
453 mtspr SPRN_DSCR, r0
454
423 blr 455 blr
424 456
425 /* ****************************************************************** */ 457 /* ****************************************************************** */