Commit 28e61cc466d8daace4b0f04ba2b83e0bd68f5832

Authored by Michael Neuling
Committed by Benjamin Herrenschmidt
1 parent c2d52644e2

powerpc/tm: Fix context switching TAR, PPR and DSCR SPRs

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>

Showing 3 changed files with 27 additions and 0 deletions Side-by-side Diff

arch/powerpc/include/asm/processor.h
... ... @@ -247,6 +247,10 @@
247 247 unsigned long tm_orig_msr; /* Thread's MSR on ctx switch */
248 248 struct pt_regs ckpt_regs; /* Checkpointed registers */
249 249  
  250 + unsigned long tm_tar;
  251 + unsigned long tm_ppr;
  252 + unsigned long tm_dscr;
  253 +
250 254 /*
251 255 * Transactional FP and VSX 0-31 register set.
252 256 * NOTE: the sense of these is the opposite of the integer ckpt_regs!
arch/powerpc/kernel/asm-offsets.c
... ... @@ -138,6 +138,9 @@
138 138 DEFINE(THREAD_TM_TFHAR, offsetof(struct thread_struct, tm_tfhar));
139 139 DEFINE(THREAD_TM_TEXASR, offsetof(struct thread_struct, tm_texasr));
140 140 DEFINE(THREAD_TM_TFIAR, offsetof(struct thread_struct, tm_tfiar));
  141 + DEFINE(THREAD_TM_TAR, offsetof(struct thread_struct, tm_tar));
  142 + DEFINE(THREAD_TM_PPR, offsetof(struct thread_struct, tm_ppr));
  143 + DEFINE(THREAD_TM_DSCR, offsetof(struct thread_struct, tm_dscr));
141 144 DEFINE(PT_CKPT_REGS, offsetof(struct thread_struct, ckpt_regs));
142 145 DEFINE(THREAD_TRANSACT_VR0, offsetof(struct thread_struct,
143 146 transact_vr[0]));
arch/powerpc/kernel/tm.S
... ... @@ -233,6 +233,16 @@
233 233 std r5, _CCR(r7)
234 234 std r6, _XER(r7)
235 235  
  236 +
  237 + /* ******************** TAR, PPR, DSCR ********** */
  238 + mfspr r3, SPRN_TAR
  239 + mfspr r4, SPRN_PPR
  240 + mfspr r5, SPRN_DSCR
  241 +
  242 + std r3, THREAD_TM_TAR(r12)
  243 + std r4, THREAD_TM_PPR(r12)
  244 + std r5, THREAD_TM_DSCR(r12)
  245 +
236 246 /* MSR and flags: We don't change CRs, and we don't need to alter
237 247 * MSR.
238 248 */
... ... @@ -347,6 +357,16 @@
347 357 mtmsr r6 /* FP/Vec off again! */
348 358  
349 359 restore_gprs:
  360 +
  361 + /* ******************** TAR, PPR, DSCR ********** */
  362 + ld r4, THREAD_TM_TAR(r3)
  363 + ld r5, THREAD_TM_PPR(r3)
  364 + ld r6, THREAD_TM_DSCR(r3)
  365 +
  366 + mtspr SPRN_TAR, r4
  367 + mtspr SPRN_PPR, r5
  368 + mtspr SPRN_DSCR, r6
  369 +
350 370 /* ******************** CR,LR,CCR,MSR ********** */
351 371 ld r3, _CTR(r7)
352 372 ld r4, _LINK(r7)