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

Commit 0df977ea authored by Christophe Leroy's avatar Christophe Leroy Committed by Michael Ellerman
Browse files

powerpc/6xx: Don't use SPRN_SPRG2 for storing stack pointer while in RTAS



When calling RTAS, the stack pointer is stored in SPRN_SPRG2
in order to be able to restore it in case of machine check in RTAS.

As machine check is not a perfomance critical path, this patch
frees SPRN_SPRG2 by using a field in thread struct instead.

Signed-off-by: default avatarChristophe Leroy <christophe.leroy@c-s.fr>
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
parent 40058337
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -250,6 +250,9 @@ struct thread_struct {
#ifdef CONFIG_PPC32
	void		*pgdir;		/* root of page-table tree */
	unsigned long	ksp_limit;	/* if ksp <= ksp_limit stack overflow */
#ifdef CONFIG_PPC_RTAS
	unsigned long	rtas_sp;	/* stack pointer for when in RTAS */
#endif
#endif
	/* Debug Registers */
	struct debug_reg debug;
+0 −1
Original line number Diff line number Diff line
@@ -1167,7 +1167,6 @@
#ifdef CONFIG_PPC_BOOK3S_32
#define SPRN_SPRG_SCRATCH0	SPRN_SPRG0
#define SPRN_SPRG_SCRATCH1	SPRN_SPRG1
#define SPRN_SPRG_RTAS		SPRN_SPRG2
#define SPRN_SPRG_603_LRU	SPRN_SPRG4
#endif

+3 −0
Original line number Diff line number Diff line
@@ -93,6 +93,9 @@ int main(void)
	OFFSET(THREAD_INFO, task_struct, stack);
	DEFINE(THREAD_INFO_GAP, _ALIGN_UP(sizeof(struct thread_info), 16));
	OFFSET(KSP_LIMIT, thread_struct, ksp_limit);
#ifdef CONFIG_PPC_RTAS
	OFFSET(RTAS_SP, thread_struct, rtas_sp);
#endif
#endif /* CONFIG_PPC64 */

#ifdef CONFIG_LIVEPATCH
+3 −2
Original line number Diff line number Diff line
@@ -1332,7 +1332,7 @@ _GLOBAL(enter_rtas)
	MTMSRD(r0)		/* don't get trashed */
	li	r9,MSR_KERNEL & ~(MSR_IR|MSR_DR)
	mtlr	r6
	mtspr	SPRN_SPRG_RTAS,r7
	stw	r7, THREAD + RTAS_SP(r2)
	mtspr	SPRN_SRR0,r8
	mtspr	SPRN_SRR1,r9
	RFI
@@ -1341,7 +1341,8 @@ _GLOBAL(enter_rtas)
	lwz	r9,8(r9)	/* original msr value */
	addi	r1,r1,INT_FRAME_SIZE
	li	r0,0
	mtspr	SPRN_SPRG_RTAS,r0
	tophys(r7, r2)
	stw	r0, THREAD + RTAS_SP(r7)
	mtspr	SPRN_SRR0,r8
	mtspr	SPRN_SRR1,r9
	RFI			/* return to caller */
+12 −10
Original line number Diff line number Diff line
@@ -352,9 +352,8 @@ i##n: \
 * registers that might have bad values includes all the GPRs
 * and all the BATs.  We indicate that we are in RTAS by putting
 * a non-zero value, the address of the exception frame to use,
 * in SPRG2.  The machine check handler checks SPRG2 and uses its
 * value if it is non-zero.  If we ever needed to free up SPRG2,
 * we could use a field in the thread_info or thread_struct instead.
 * in thread.rtas_sp.  The machine check handler checks thread.rtas_sp
 * and uses its value if it is non-zero.
 * (Other exception handlers assume that r1 is a valid kernel stack
 * pointer when we take an exception from supervisor mode.)
 *	-- paulus.
@@ -365,16 +364,15 @@ i##n: \
	mtspr	SPRN_SPRG_SCRATCH1,r11
	mfcr	r10
#ifdef CONFIG_PPC_CHRP
	mfspr	r11,SPRN_SPRG_RTAS
	cmpwi	0,r11,0
	bne	7f
	mfspr	r11, SPRN_SPRG_THREAD
	lwz	r11, RTAS_SP(r11)
	cmpwi	cr1, r11, 0
	bne	cr1, 7f
#endif /* CONFIG_PPC_CHRP */
	EXCEPTION_PROLOG_1
7:	EXCEPTION_PROLOG_2
	addi	r3,r1,STACK_FRAME_OVERHEAD
#ifdef CONFIG_PPC_CHRP
	mfspr	r4,SPRN_SPRG_RTAS
	cmpwi	cr1,r4,0
	bne	cr1,1f
#endif
	EXC_XFER_STD(0x200, machine_check_exception)
@@ -865,8 +863,10 @@ __secondary_start:
	tophys(r4,r2)
	addi	r4,r4,THREAD	/* phys address of our thread_struct */
	mtspr	SPRN_SPRG_THREAD,r4
#ifdef CONFIG_PPC_RTAS
	li	r3,0
	mtspr	SPRN_SPRG_RTAS,r3	/* 0 => not in RTAS */
	stw	r3, RTAS_SP(r4)		/* 0 => not in RTAS */
#endif

	/* enable MMU and jump to start_secondary */
	li	r4,MSR_KERNEL
@@ -950,8 +950,10 @@ start_here:
	tophys(r4,r2)
	addi	r4,r4,THREAD	/* init task's THREAD */
	mtspr	SPRN_SPRG_THREAD,r4
#ifdef CONFIG_PPC_RTAS
	li	r3,0
	mtspr	SPRN_SPRG_RTAS,r3	/* 0 => not in RTAS */
	stw	r3, RTAS_SP(r4)		/* 0 => not in RTAS */
#endif

	/* stack */
	lis	r1,init_thread_union@ha