Commit e9bdc3d6 authored by Michael Neuling's avatar Michael Neuling Committed by Benjamin Herrenschmidt

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: default avatarMichael Neuling <mikey@neuling.org>
Cc: <stable@vger.kernel.org> # 3.9+
Signed-off-by: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
parent c69e63b0
...@@ -79,6 +79,11 @@ _GLOBAL(tm_abort) ...@@ -79,6 +79,11 @@ _GLOBAL(tm_abort)
TABORT(R3) TABORT(R3)
blr blr
.section ".toc","aw"
DSCR_DEFAULT:
.tc dscr_default[TC],dscr_default
.section ".text"
/* void tm_reclaim(struct thread_struct *thread, /* void tm_reclaim(struct thread_struct *thread,
* unsigned long orig_msr, * unsigned long orig_msr,
...@@ -188,11 +193,18 @@ dont_backup_fp: ...@@ -188,11 +193,18 @@ dont_backup_fp:
std r1, PACATMSCRATCH(r13) std r1, PACATMSCRATCH(r13)
ld r1, PACAR1(r13) ld r1, PACAR1(r13)
/* Store the PPR in r11 and reset to decent value */
std r11, GPR11(r1) /* Temporary stash */
mfspr r11, SPRN_PPR
HMT_MEDIUM
/* Now get some more GPRS free */ /* Now get some more GPRS free */
std r7, GPR7(r1) /* Temporary stash */ std r7, GPR7(r1) /* Temporary stash */
std r12, GPR12(r1) /* '' '' '' */ std r12, GPR12(r1) /* '' '' '' */
ld r12, STACK_PARAM(0)(r1) /* Param 0, thread_struct * */ ld r12, STACK_PARAM(0)(r1) /* Param 0, thread_struct * */
std r11, THREAD_TM_PPR(r12) /* Store PPR and free r11 */
addi r7, r12, PT_CKPT_REGS /* Thread's ckpt_regs */ addi r7, r12, PT_CKPT_REGS /* Thread's ckpt_regs */
/* Make r7 look like an exception frame so that we /* Make r7 look like an exception frame so that we
...@@ -204,15 +216,19 @@ dont_backup_fp: ...@@ -204,15 +216,19 @@ dont_backup_fp:
SAVE_GPR(0, r7) /* user r0 */ SAVE_GPR(0, r7) /* user r0 */
SAVE_GPR(2, r7) /* user r2 */ SAVE_GPR(2, r7) /* user r2 */
SAVE_4GPRS(3, r7) /* user r3-r6 */ SAVE_4GPRS(3, r7) /* user r3-r6 */
SAVE_4GPRS(8, r7) /* user r8-r11 */ SAVE_GPR(8, r7) /* user r8 */
SAVE_GPR(9, r7) /* user r9 */
SAVE_GPR(10, r7) /* user r10 */
ld r3, PACATMSCRATCH(r13) /* user r1 */ ld r3, PACATMSCRATCH(r13) /* user r1 */
ld r4, GPR7(r1) /* user r7 */ ld r4, GPR7(r1) /* user r7 */
ld r5, GPR12(r1) /* user r12 */ ld r5, GPR11(r1) /* user r11 */
GET_SCRATCH0(6) /* user r13 */ ld r6, GPR12(r1) /* user r12 */
GET_SCRATCH0(8) /* user r13 */
std r3, GPR1(r7) std r3, GPR1(r7)
std r4, GPR7(r7) std r4, GPR7(r7)
std r5, GPR12(r7) std r5, GPR11(r7)
std r6, GPR13(r7) std r6, GPR12(r7)
std r8, GPR13(r7)
SAVE_NVGPRS(r7) /* user r14-r31 */ SAVE_NVGPRS(r7) /* user r14-r31 */
...@@ -235,14 +251,12 @@ dont_backup_fp: ...@@ -235,14 +251,12 @@ dont_backup_fp:
std r6, _XER(r7) std r6, _XER(r7)
/* ******************** TAR, PPR, DSCR ********** */ /* ******************** TAR, DSCR ********** */
mfspr r3, SPRN_TAR mfspr r3, SPRN_TAR
mfspr r4, SPRN_PPR mfspr r4, SPRN_DSCR
mfspr r5, SPRN_DSCR
std r3, THREAD_TM_TAR(r12) std r3, THREAD_TM_TAR(r12)
std r4, THREAD_TM_PPR(r12) std r4, THREAD_TM_DSCR(r12)
std r5, THREAD_TM_DSCR(r12)
/* MSR and flags: We don't change CRs, and we don't need to alter /* MSR and flags: We don't change CRs, and we don't need to alter
* MSR. * MSR.
...@@ -259,7 +273,7 @@ dont_backup_fp: ...@@ -259,7 +273,7 @@ dont_backup_fp:
std r3, THREAD_TM_TFHAR(r12) std r3, THREAD_TM_TFHAR(r12)
std r4, THREAD_TM_TFIAR(r12) std r4, THREAD_TM_TFIAR(r12)
/* AMR and PPR are checkpointed too, but are unsupported by Linux. */ /* AMR is checkpointed too, but is unsupported by Linux. */
/* Restore original MSR/IRQ state & clear TM mode */ /* Restore original MSR/IRQ state & clear TM mode */
ld r14, TM_FRAME_L0(r1) /* Orig MSR */ ld r14, TM_FRAME_L0(r1) /* Orig MSR */
...@@ -275,6 +289,12 @@ dont_backup_fp: ...@@ -275,6 +289,12 @@ dont_backup_fp:
mtcr r4 mtcr r4
mtlr r0 mtlr r0
ld r2, 40(r1) ld r2, 40(r1)
/* Load system default DSCR */
ld r4, DSCR_DEFAULT@toc(r2)
ld r0, 0(r4)
mtspr SPRN_DSCR, r0
blr blr
...@@ -359,25 +379,24 @@ dont_restore_fp: ...@@ -359,25 +379,24 @@ dont_restore_fp:
restore_gprs: restore_gprs:
/* ******************** TAR, PPR, DSCR ********** */ /* ******************** CR,LR,CCR,MSR ********** */
ld r4, THREAD_TM_TAR(r3) ld r4, _CTR(r7)
ld r5, THREAD_TM_PPR(r3) ld r5, _LINK(r7)
ld r6, THREAD_TM_DSCR(r3) ld r6, _CCR(r7)
ld r8, _XER(r7)
mtspr SPRN_TAR, r4 mtctr r4
mtspr SPRN_PPR, r5 mtlr r5
mtspr SPRN_DSCR, r6 mtcr r6
mtxer r8
/* ******************** CR,LR,CCR,MSR ********** */ /* ******************** TAR ******************** */
ld r3, _CTR(r7) ld r4, THREAD_TM_TAR(r3)
ld r4, _LINK(r7) mtspr SPRN_TAR, r4
ld r5, _CCR(r7)
ld r6, _XER(r7)
mtctr r3 /* Load up the PPR and DSCR in GPRs only at this stage */
mtlr r4 ld r5, THREAD_TM_DSCR(r3)
mtcr r5 ld r6, THREAD_TM_PPR(r3)
mtxer r6
/* Clear the MSR RI since we are about to change R1. EE is already off /* Clear the MSR RI since we are about to change R1. EE is already off
*/ */
...@@ -385,19 +404,26 @@ restore_gprs: ...@@ -385,19 +404,26 @@ restore_gprs:
mtmsrd r4, 1 mtmsrd r4, 1
REST_4GPRS(0, r7) /* GPR0-3 */ REST_4GPRS(0, r7) /* GPR0-3 */
REST_GPR(4, r7) /* GPR4-6 */ REST_GPR(4, r7) /* GPR4 */
REST_GPR(5, r7)
REST_GPR(6, r7)
REST_4GPRS(8, r7) /* GPR8-11 */ REST_4GPRS(8, r7) /* GPR8-11 */
REST_2GPRS(12, r7) /* GPR12-13 */ REST_2GPRS(12, r7) /* GPR12-13 */
REST_NVGPRS(r7) /* GPR14-31 */ REST_NVGPRS(r7) /* GPR14-31 */
ld r7, GPR7(r7) /* GPR7 */ /* Load up PPR and DSCR here so we don't run with user values for long
*/
mtspr SPRN_DSCR, r5
mtspr SPRN_PPR, r6
REST_GPR(5, r7) /* GPR5-7 */
REST_GPR(6, r7)
ld r7, GPR7(r7)
/* Commit register state as checkpointed state: */ /* Commit register state as checkpointed state: */
TRECHKPT TRECHKPT
HMT_MEDIUM
/* Our transactional state has now changed. /* Our transactional state has now changed.
* *
* Now just get out of here. Transactional (current) state will be * Now just get out of here. Transactional (current) state will be
...@@ -420,6 +446,12 @@ restore_gprs: ...@@ -420,6 +446,12 @@ restore_gprs:
mtcr r4 mtcr r4
mtlr r0 mtlr r0
ld r2, 40(r1) ld r2, 40(r1)
/* Load system default DSCR */
ld r4, DSCR_DEFAULT@toc(r2)
ld r0, 0(r4)
mtspr SPRN_DSCR, r0
blr blr
/* ****************************************************************** */ /* ****************************************************************** */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment