Skip to content

Commit d0ffdee

Browse files
Gustavo Romerompe
authored andcommitted
powerpc/tm: Save and restore AMR on treclaim and trechkpt
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. Signed-off-by: Gustavo Romero <[email protected]> Tested-by: Aneesh Kumar K.V <[email protected]> Signed-off-by: Michael Ellerman <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 35d6473 commit d0ffdee

File tree

3 files changed

+33
-4
lines changed

3 files changed

+33
-4
lines changed

arch/powerpc/include/asm/processor.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,7 @@ struct thread_struct {
220220
unsigned long tm_tar;
221221
unsigned long tm_ppr;
222222
unsigned long tm_dscr;
223+
unsigned long tm_amr;
223224

224225
/*
225226
* Checkpointed FP and VSX 0-31 register set.

arch/powerpc/kernel/asm-offsets.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,7 @@ int main(void)
176176
OFFSET(THREAD_TM_TAR, thread_struct, tm_tar);
177177
OFFSET(THREAD_TM_PPR, thread_struct, tm_ppr);
178178
OFFSET(THREAD_TM_DSCR, thread_struct, tm_dscr);
179+
OFFSET(THREAD_TM_AMR, thread_struct, tm_amr);
179180
OFFSET(PT_CKPT_REGS, thread_struct, ckpt_regs);
180181
OFFSET(THREAD_CKVRSTATE, thread_struct, ckvr_state.vr);
181182
OFFSET(THREAD_CKVRSAVE, thread_struct, ckvrsave);

arch/powerpc/kernel/tm.S

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,13 @@ _GLOBAL(tm_reclaim)
122122
std r3, STK_PARAM(R3)(r1)
123123
SAVE_NVGPRS(r1)
124124

125+
/*
126+
* Save kernel live AMR since it will be clobbered by treclaim
127+
* but can be used elsewhere later in kernel space.
128+
*/
129+
mfspr r3, SPRN_AMR
130+
std r3, TM_FRAME_L1(r1)
131+
125132
/* We need to setup MSR for VSX register save instructions. */
126133
mfmsr r14
127134
mr r15, r14
@@ -245,7 +252,7 @@ _GLOBAL(tm_reclaim)
245252
* but is used in signal return to 'wind back' to the abort handler.
246253
*/
247254

248-
/* ******************** CR,LR,CCR,MSR ********** */
255+
/* ***************** CTR, LR, CR, XER ********** */
249256
mfctr r3
250257
mflr r4
251258
mfcr r5
@@ -256,14 +263,17 @@ _GLOBAL(tm_reclaim)
256263
std r5, _CCR(r7)
257264
std r6, _XER(r7)
258265

259-
260266
/* ******************** TAR, DSCR ********** */
261267
mfspr r3, SPRN_TAR
262268
mfspr r4, SPRN_DSCR
263269

264270
std r3, THREAD_TM_TAR(r12)
265271
std r4, THREAD_TM_DSCR(r12)
266272

273+
/* ******************** AMR **************** */
274+
mfspr r3, SPRN_AMR
275+
std r3, THREAD_TM_AMR(r12)
276+
267277
/*
268278
* MSR and flags: We don't change CRs, and we don't need to alter MSR.
269279
*/
@@ -308,7 +318,9 @@ _GLOBAL(tm_reclaim)
308318
std r3, THREAD_TM_TFHAR(r12)
309319
std r4, THREAD_TM_TFIAR(r12)
310320

311-
/* AMR is checkpointed too, but is unsupported by Linux. */
321+
/* Restore kernel live AMR */
322+
ld r8, TM_FRAME_L1(r1)
323+
mtspr SPRN_AMR, r8
312324

313325
/* Restore original MSR/IRQ state & clear TM mode */
314326
ld r14, TM_FRAME_L0(r1) /* Orig MSR */
@@ -355,6 +367,13 @@ _GLOBAL(__tm_recheckpoint)
355367
*/
356368
SAVE_NVGPRS(r1)
357369

370+
/*
371+
* Save kernel live AMR since it will be clobbered for trechkpt
372+
* but can be used elsewhere later in kernel space.
373+
*/
374+
mfspr r8, SPRN_AMR
375+
std r8, TM_FRAME_L0(r1)
376+
358377
/* Load complete register state from ts_ckpt* registers */
359378

360379
addi r7, r3, PT_CKPT_REGS /* Thread's ckpt_regs */
@@ -404,7 +423,7 @@ _GLOBAL(__tm_recheckpoint)
404423

405424
restore_gprs:
406425

407-
/* ******************** CR,LR,CCR,MSR ********** */
426+
/* ****************** CTR, LR, XER ************* */
408427
ld r4, _CTR(r7)
409428
ld r5, _LINK(r7)
410429
ld r8, _XER(r7)
@@ -417,6 +436,10 @@ restore_gprs:
417436
ld r4, THREAD_TM_TAR(r3)
418437
mtspr SPRN_TAR, r4
419438

439+
/* ******************** AMR ******************** */
440+
ld r4, THREAD_TM_AMR(r3)
441+
mtspr SPRN_AMR, r4
442+
420443
/* Load up the PPR and DSCR in GPRs only at this stage */
421444
ld r5, THREAD_TM_DSCR(r3)
422445
ld r6, THREAD_TM_PPR(r3)
@@ -509,6 +532,10 @@ restore_gprs:
509532
li r4, MSR_RI
510533
mtmsrd r4, 1
511534

535+
/* Restore kernel live AMR */
536+
ld r8, TM_FRAME_L0(r1)
537+
mtspr SPRN_AMR, r8
538+
512539
REST_NVGPRS(r1)
513540

514541
addi r1, r1, TM_FRAME_SIZE

0 commit comments

Comments
 (0)