Skip to content

Commit

Permalink
powerpc/tm: Fix context switching TAR, PPR and DSCR SPRs
Browse files Browse the repository at this point in the history
If a transaction is rolled back, the Target Address Register (TAR), Processor
Priority Register (PPR) and Data Stream Control Register (DSCR) should be
restored to the checkpointed values before the transaction began.  Any changes
to these SPRs inside the transaction should not be visible in the abort
handler.

Currently Linux doesn't save or restore the checkpointed TAR, PPR or DSCR.  If
we preempt a processes inside a transaction which has modified any of these, on
process restore, that same transaction may be aborted we but we won't see the
checkpointed versions of these SPRs.

This adds checkpointed versions of these SPRs to the thread_struct and adds the
save/restore of these three SPRs to the treclaim/trechkpt code.

Without this if any of these SPRs are modified during a transaction, users may
incorrectly see a speculated SPR value even if the transaction is aborted.

Signed-off-by: Michael Neuling <mikey@neuling.org>
Cc: <stable@vger.kernel.org> [v3.10]
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
  • Loading branch information
Michael Neuling authored and Benjamin Herrenschmidt committed Aug 9, 2013
1 parent c2d5264 commit 28e61cc
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 0 deletions.
4 changes: 4 additions & 0 deletions arch/powerpc/include/asm/processor.h
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,10 @@ struct thread_struct {
unsigned long tm_orig_msr; /* Thread's MSR on ctx switch */
struct pt_regs ckpt_regs; /* Checkpointed registers */

unsigned long tm_tar;
unsigned long tm_ppr;
unsigned long tm_dscr;

/*
* Transactional FP and VSX 0-31 register set.
* NOTE: the sense of these is the opposite of the integer ckpt_regs!
Expand Down
3 changes: 3 additions & 0 deletions arch/powerpc/kernel/asm-offsets.c
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,9 @@ int main(void)
DEFINE(THREAD_TM_TFHAR, offsetof(struct thread_struct, tm_tfhar));
DEFINE(THREAD_TM_TEXASR, offsetof(struct thread_struct, tm_texasr));
DEFINE(THREAD_TM_TFIAR, offsetof(struct thread_struct, tm_tfiar));
DEFINE(THREAD_TM_TAR, offsetof(struct thread_struct, tm_tar));
DEFINE(THREAD_TM_PPR, offsetof(struct thread_struct, tm_ppr));
DEFINE(THREAD_TM_DSCR, offsetof(struct thread_struct, tm_dscr));
DEFINE(PT_CKPT_REGS, offsetof(struct thread_struct, ckpt_regs));
DEFINE(THREAD_TRANSACT_VR0, offsetof(struct thread_struct,
transact_vr[0]));
Expand Down
20 changes: 20 additions & 0 deletions arch/powerpc/kernel/tm.S
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,16 @@ dont_backup_fp:
std r5, _CCR(r7)
std r6, _XER(r7)


/* ******************** TAR, PPR, DSCR ********** */
mfspr r3, SPRN_TAR
mfspr r4, SPRN_PPR
mfspr r5, SPRN_DSCR

std r3, THREAD_TM_TAR(r12)
std r4, THREAD_TM_PPR(r12)
std r5, THREAD_TM_DSCR(r12)

/* MSR and flags: We don't change CRs, and we don't need to alter
* MSR.
*/
Expand Down Expand Up @@ -347,6 +357,16 @@ dont_restore_fp:
mtmsr r6 /* FP/Vec off again! */

restore_gprs:

/* ******************** TAR, PPR, DSCR ********** */
ld r4, THREAD_TM_TAR(r3)
ld r5, THREAD_TM_PPR(r3)
ld r6, THREAD_TM_DSCR(r3)

mtspr SPRN_TAR, r4
mtspr SPRN_PPR, r5
mtspr SPRN_DSCR, r6

/* ******************** CR,LR,CCR,MSR ********** */
ld r3, _CTR(r7)
ld r4, _LINK(r7)
Expand Down

0 comments on commit 28e61cc

Please sign in to comment.