Skip to content

Commit 256707d

Browse files
mikeygregkh
authored andcommitted
powerpc/tm: Fix userspace r13 corruption
[ Upstream commit cf13435 ] When we treclaim we store the userspace checkpointed r13 to a scratch SPR and then later save the scratch SPR to the user thread struct. Unfortunately, this doesn't work as accessing the user thread struct can take an SLB fault and the SLB fault handler will write the same scratch SPRG that now contains the userspace r13. To fix this, we store r13 to the kernel stack (which can't fault) before we access the user thread struct. Found by running P8 guest + powervm + disable_1tb_segments + TM. Seen as a random userspace segfault with r13 looking like a kernel address. Signed-off-by: Michael Neuling <mikey@neuling.org> Reviewed-by: Breno Leitao <leitao@debian.org> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> Signed-off-by: Sasha Levin <alexander.levin@microsoft.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 4f5dbf2 commit 256707d

1 file changed

Lines changed: 9 additions & 2 deletions

File tree

  • arch/powerpc/kernel

arch/powerpc/kernel/tm.S

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -167,13 +167,20 @@ _GLOBAL(tm_reclaim)
167167
std r1, PACATMSCRATCH(r13)
168168
ld r1, PACAR1(r13)
169169

170-
/* Store the PPR in r11 and reset to decent value */
171170
std r11, GPR11(r1) /* Temporary stash */
172171

172+
/*
173+
* Store r13 away so we can free up the scratch SPR for the SLB fault
174+
* handler (needed once we start accessing the thread_struct).
175+
*/
176+
GET_SCRATCH0(r11)
177+
std r11, GPR13(r1)
178+
173179
/* Reset MSR RI so we can take SLB faults again */
174180
li r11, MSR_RI
175181
mtmsrd r11, 1
176182

183+
/* Store the PPR in r11 and reset to decent value */
177184
mfspr r11, SPRN_PPR
178185
HMT_MEDIUM
179186

@@ -202,7 +209,7 @@ _GLOBAL(tm_reclaim)
202209
ld r4, GPR7(r1) /* user r7 */
203210
ld r5, GPR11(r1) /* user r11 */
204211
ld r6, GPR12(r1) /* user r12 */
205-
GET_SCRATCH0(8) /* user r13 */
212+
ld r8, GPR13(r1) /* user r13 */
206213
std r3, GPR1(r7)
207214
std r4, GPR7(r7)
208215
std r5, GPR11(r7)

0 commit comments

Comments
 (0)