powerpc/tm: Fix userspace r13 corruption
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>
This commit is contained in:
		
							parent
							
								
									8604895a34
								
							
						
					
					
						commit
						cf13435b73
					
				| @ -176,13 +176,20 @@ _GLOBAL(tm_reclaim) | ||||
| 	std	r1, PACATMSCRATCH(r13) | ||||
| 	ld	r1, PACAR1(r13) | ||||
| 
 | ||||
| 	/* Store the PPR in r11 and reset to decent value */ | ||||
| 	std	r11, GPR11(r1)			/* Temporary stash */ | ||||
| 
 | ||||
| 	/* | ||||
| 	 * Store r13 away so we can free up the scratch SPR for the SLB fault | ||||
| 	 * handler (needed once we start accessing the thread_struct). | ||||
| 	 */ | ||||
| 	GET_SCRATCH0(r11) | ||||
| 	std	r11, GPR13(r1) | ||||
| 
 | ||||
| 	/* Reset MSR RI so we can take SLB faults again */ | ||||
| 	li	r11, MSR_RI | ||||
| 	mtmsrd	r11, 1 | ||||
| 
 | ||||
| 	/* Store the PPR in r11 and reset to decent value */ | ||||
| 	mfspr	r11, SPRN_PPR | ||||
| 	HMT_MEDIUM | ||||
| 
 | ||||
| @ -211,7 +218,7 @@ _GLOBAL(tm_reclaim) | ||||
| 	ld	r4, GPR7(r1)			/* user r7 */ | ||||
| 	ld	r5, GPR11(r1)			/* user r11 */ | ||||
| 	ld	r6, GPR12(r1)			/* user r12 */ | ||||
| 	GET_SCRATCH0(8)				/* user r13 */ | ||||
| 	ld	r8, GPR13(r1)			/* user r13 */ | ||||
| 	std	r3, GPR1(r7) | ||||
| 	std	r4, GPR7(r7) | ||||
| 	std	r5, GPR11(r7) | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user