[PATCH v2] powerpc/tm: Save and restore AMR on treclaim and trechkpt

Aneesh Kumar K.V aneesh.kumar at linux.ibm.com
Sun Sep 20 15:56:01 AEST 2020


Gustavo Romero <gromero at linux.ibm.com> writes:

> Althought AMR is stashed in the checkpoint area, currently we don't save
> it to the per thread checkpoint struct after a treclaim and so we don't
> restore it either from that struct when we trechkpt. As a consequence when
> the transaction is later rolled back the kernel space AMR value when the
> trechkpt was done appears in userspace.
>
> That commit saves and restores AMR accordingly on treclaim and trechkpt.
> Since AMR value is also used in kernel space in other functions, it also
> takes care of stashing kernel live AMR into the stack before treclaim and
> before trechkpt, restoring it later, just before returning from tm_reclaim
> and __tm_recheckpoint.
>
> Is also fixes two nonrelated comments about CR and MSR.
>

Tested-by: Aneesh Kumar K.V <aneesh.kumar at linux.ibm.com>

> Signed-off-by: Gustavo Romero <gromero at linux.ibm.com>
> ---
>  arch/powerpc/include/asm/processor.h |  1 +
>  arch/powerpc/kernel/asm-offsets.c    |  1 +
>  arch/powerpc/kernel/tm.S             | 35 ++++++++++++++++++++++++----
>  3 files changed, 33 insertions(+), 4 deletions(-)
>
> diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h
> index ed0d633ab5aa..9f4f6cc033ac 100644
> --- a/arch/powerpc/include/asm/processor.h
> +++ b/arch/powerpc/include/asm/processor.h
> @@ -220,6 +220,7 @@ struct thread_struct {
>  	unsigned long	tm_tar;
>  	unsigned long	tm_ppr;
>  	unsigned long	tm_dscr;
> +	unsigned long   tm_amr;
>  
>  	/*
>  	 * Checkpointed FP and VSX 0-31 register set.
> diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
> index 8711c2164b45..c2722ff36e98 100644
> --- a/arch/powerpc/kernel/asm-offsets.c
> +++ b/arch/powerpc/kernel/asm-offsets.c
> @@ -176,6 +176,7 @@ int main(void)
>  	OFFSET(THREAD_TM_TAR, thread_struct, tm_tar);
>  	OFFSET(THREAD_TM_PPR, thread_struct, tm_ppr);
>  	OFFSET(THREAD_TM_DSCR, thread_struct, tm_dscr);
> +	OFFSET(THREAD_TM_AMR, thread_struct, tm_amr);
>  	OFFSET(PT_CKPT_REGS, thread_struct, ckpt_regs);
>  	OFFSET(THREAD_CKVRSTATE, thread_struct, ckvr_state.vr);
>  	OFFSET(THREAD_CKVRSAVE, thread_struct, ckvrsave);
> diff --git a/arch/powerpc/kernel/tm.S b/arch/powerpc/kernel/tm.S
> index 6ba0fdd1e7f8..2b91f233b05d 100644
> --- a/arch/powerpc/kernel/tm.S
> +++ b/arch/powerpc/kernel/tm.S
> @@ -122,6 +122,13 @@ _GLOBAL(tm_reclaim)
>  	std	r3, STK_PARAM(R3)(r1)
>  	SAVE_NVGPRS(r1)
>  
> +	/*
> +	 * Save kernel live AMR since it will be clobbered by treclaim
> +	 * but can be used elsewhere later in kernel space.
> +	 */
> +	mfspr	r3, SPRN_AMR
> +	std	r3, TM_FRAME_L1(r1)
> +
>  	/* We need to setup MSR for VSX register save instructions. */
>  	mfmsr	r14
>  	mr	r15, r14
> @@ -245,7 +252,7 @@ _GLOBAL(tm_reclaim)
>  	 * but is used in signal return to 'wind back' to the abort handler.
>  	 */
>  
> -	/* ******************** CR,LR,CCR,MSR ********** */
> +	/* ***************** CTR, LR, CR, XER ********** */
>  	mfctr	r3
>  	mflr	r4
>  	mfcr	r5
> @@ -256,7 +263,6 @@ _GLOBAL(tm_reclaim)
>  	std	r5, _CCR(r7)
>  	std	r6, _XER(r7)
>  
> -
>  	/* ******************** TAR, DSCR ********** */
>  	mfspr	r3, SPRN_TAR
>  	mfspr	r4, SPRN_DSCR
> @@ -264,6 +270,10 @@ _GLOBAL(tm_reclaim)
>  	std	r3, THREAD_TM_TAR(r12)
>  	std	r4, THREAD_TM_DSCR(r12)
>  
> +        /* ******************** AMR **************** */
> +        mfspr	r3, SPRN_AMR
> +        std	r3, THREAD_TM_AMR(r12)
> +
>  	/*
>  	 * MSR and flags: We don't change CRs, and we don't need to alter MSR.
>  	 */
> @@ -308,7 +318,9 @@ _GLOBAL(tm_reclaim)
>  	std	r3, THREAD_TM_TFHAR(r12)
>  	std	r4, THREAD_TM_TFIAR(r12)
>  
> -	/* AMR is checkpointed too, but is unsupported by Linux. */
> +	/* Restore kernel live AMR */
> +	ld	r8, TM_FRAME_L1(r1)
> +	mtspr	SPRN_AMR, r8
>  
>  	/* Restore original MSR/IRQ state & clear TM mode */
>  	ld	r14, TM_FRAME_L0(r1)		/* Orig MSR */
> @@ -355,6 +367,13 @@ _GLOBAL(__tm_recheckpoint)
>  	 */
>  	SAVE_NVGPRS(r1)
>  
> +	/*
> +	 * Save kernel live AMR since it will be clobbered for trechkpt
> +	 * but can be used elsewhere later in kernel space.
> +	 */
> +	mfspr	r8, SPRN_AMR
> +	std	r8, TM_FRAME_L0(r1)
> +
>  	/* Load complete register state from ts_ckpt* registers */
>  
>  	addi	r7, r3, PT_CKPT_REGS		/* Thread's ckpt_regs */
> @@ -404,7 +423,7 @@ _GLOBAL(__tm_recheckpoint)
>  
>  restore_gprs:
>  
> -	/* ******************** CR,LR,CCR,MSR ********** */
> +	/* ****************** CTR, LR, XER ************* */
>  	ld	r4, _CTR(r7)
>  	ld	r5, _LINK(r7)
>  	ld	r8, _XER(r7)
> @@ -417,6 +436,10 @@ restore_gprs:
>  	ld	r4, THREAD_TM_TAR(r3)
>  	mtspr	SPRN_TAR,	r4
>  
> +	/* ******************** AMR ******************** */
> +	ld	r4, THREAD_TM_AMR(r3)
> +	mtspr	SPRN_AMR, r4
> +
>  	/* Load up the PPR and DSCR in GPRs only at this stage */
>  	ld	r5, THREAD_TM_DSCR(r3)
>  	ld	r6, THREAD_TM_PPR(r3)
> @@ -509,6 +532,10 @@ restore_gprs:
>  	li	r4, MSR_RI
>  	mtmsrd	r4, 1
>  
> +	/* Restore kernel live AMR */
> +	ld	r8, TM_FRAME_L0(r1)
> +	mtspr	SPRN_AMR, r8
> +
>  	REST_NVGPRS(r1)
>  
>  	addi    r1, r1, TM_FRAME_SIZE
> -- 
> 2.25.1


More information about the Linuxppc-dev mailing list