Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e56a6e20 authored by Paul Mackerras's avatar Paul Mackerras
Browse files

[POWERPC] Clear RI bit in MSR before restoring r13 when returning to userspace



Some instruction tracing tools use the RI (recoverable interrupt) bit
in the MSR to indicate when it's safe to single-step.  Currently we
clear RI after restoring r13 when returning to userspace.  However,
if we single-step past the point where r13 is restored, we'll corrupt
r13 in the exception entry code and not restore it.  This moves the
clearing of RI to just before r13 is restored so this doesn't happen.

Signed-off-by: default avatarPaul Mackerras <paulus@samba.org>
parent 449d846d
Loading
Loading
Loading
Loading
+33 −26
Original line number Diff line number Diff line
@@ -172,13 +172,18 @@ syscall_error_cont:
	stdcx.	r0,0,r1			/* to clear the reservation */
	andi.	r6,r8,MSR_PR
	ld	r4,_LINK(r1)
	/*
	 * Clear RI before restoring r13.  If we are returning to
	 * userspace and we take an exception after restoring r13,
	 * we end up corrupting the userspace r13 value.
	 */
	li	r12,MSR_RI
	andc	r11,r10,r12
	mtmsrd	r11,1			/* clear MSR.RI */
	beq-	1f
	ACCOUNT_CPU_USER_EXIT(r11, r12)
	ld	r13,GPR13(r1)	/* only restore r13 if returning to usermode */
1:	ld	r2,GPR2(r1)
	li	r12,MSR_RI
	andc	r11,r10,r12
	mtmsrd	r11,1			/* clear MSR.RI */
	ld	r1,GPR1(r1)
	mtlr	r4
	mtcr	r5
@@ -488,42 +493,44 @@ END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
#endif
	stb	r5,PACASOFTIRQEN(r13)

	/* extract EE bit and use it to restore paca->hard_enabled */
	ld	r3,_MSR(r1)
	rldicl	r4,r3,49,63		/* r0 = (r3 >> 15) & 1 */
	stb	r4,PACAHARDIRQEN(r13)

	ld	r4,_CTR(r1)
	ld	r0,_LINK(r1)
	mtctr	r4
	mtlr	r0
	ld	r4,_XER(r1)
	mtspr	SPRN_XER,r4

	REST_8GPRS(5, r1)

	andi.	r0,r3,MSR_RI
	beq-	unrecov_restore

	/* extract EE bit and use it to restore paca->hard_enabled */
	rldicl	r4,r3,49,63		/* r0 = (r3 >> 15) & 1 */
	stb	r4,PACAHARDIRQEN(r13)
	stdcx.	r0,0,r1		/* to clear the reservation */

	andi.	r0,r3,MSR_PR
	/*
	 * Clear RI before restoring r13.  If we are returning to
	 * userspace and we take an exception after restoring r13,
	 * we end up corrupting the userspace r13 value.
	 */
	mfmsr	r4
	andc	r4,r4,r0	/* r0 contains MSR_RI here */
	mtmsrd	r4,1

	/*
	 * r13 is our per cpu area, only restore it if we are returning to
	 * userspace
	 */
	andi.	r0,r3,MSR_PR
	beq	1f
	ACCOUNT_CPU_USER_EXIT(r3, r4)
	ACCOUNT_CPU_USER_EXIT(r2, r4)
	REST_GPR(13, r1)
1:
	ld	r3,_CTR(r1)
	ld	r0,_LINK(r1)
	mtctr	r3
	mtlr	r0
	ld	r3,_XER(r1)
	mtspr	SPRN_XER,r3

	REST_8GPRS(5, r1)

	stdcx.	r0,0,r1		/* to clear the reservation */

	mfmsr	r0
	li	r2, MSR_RI
	andc	r0,r0,r2
	mtmsrd	r0,1

	ld	r0,_MSR(r1)
	mtspr	SPRN_SRR1,r0
	mtspr	SPRN_SRR1,r3

	ld	r2,_CCR(r1)
	mtcrf	0xFF,r2