提交 0df977ea 编写于 作者: C Christophe Leroy 提交者: Michael Ellerman

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: NChristophe Leroy <christophe.leroy@c-s.fr>
Signed-off-by: NMichael Ellerman <mpe@ellerman.id.au>
上级 40058337
...@@ -250,6 +250,9 @@ struct thread_struct { ...@@ -250,6 +250,9 @@ struct thread_struct {
#ifdef CONFIG_PPC32 #ifdef CONFIG_PPC32
void *pgdir; /* root of page-table tree */ void *pgdir; /* root of page-table tree */
unsigned long ksp_limit; /* if ksp <= ksp_limit stack overflow */ 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 #endif
/* Debug Registers */ /* Debug Registers */
struct debug_reg debug; struct debug_reg debug;
......
...@@ -1167,7 +1167,6 @@ ...@@ -1167,7 +1167,6 @@
#ifdef CONFIG_PPC_BOOK3S_32 #ifdef CONFIG_PPC_BOOK3S_32
#define SPRN_SPRG_SCRATCH0 SPRN_SPRG0 #define SPRN_SPRG_SCRATCH0 SPRN_SPRG0
#define SPRN_SPRG_SCRATCH1 SPRN_SPRG1 #define SPRN_SPRG_SCRATCH1 SPRN_SPRG1
#define SPRN_SPRG_RTAS SPRN_SPRG2
#define SPRN_SPRG_603_LRU SPRN_SPRG4 #define SPRN_SPRG_603_LRU SPRN_SPRG4
#endif #endif
......
...@@ -93,6 +93,9 @@ int main(void) ...@@ -93,6 +93,9 @@ int main(void)
OFFSET(THREAD_INFO, task_struct, stack); OFFSET(THREAD_INFO, task_struct, stack);
DEFINE(THREAD_INFO_GAP, _ALIGN_UP(sizeof(struct thread_info), 16)); DEFINE(THREAD_INFO_GAP, _ALIGN_UP(sizeof(struct thread_info), 16));
OFFSET(KSP_LIMIT, thread_struct, ksp_limit); OFFSET(KSP_LIMIT, thread_struct, ksp_limit);
#ifdef CONFIG_PPC_RTAS
OFFSET(RTAS_SP, thread_struct, rtas_sp);
#endif
#endif /* CONFIG_PPC64 */ #endif /* CONFIG_PPC64 */
#ifdef CONFIG_LIVEPATCH #ifdef CONFIG_LIVEPATCH
......
...@@ -1332,7 +1332,7 @@ _GLOBAL(enter_rtas) ...@@ -1332,7 +1332,7 @@ _GLOBAL(enter_rtas)
MTMSRD(r0) /* don't get trashed */ MTMSRD(r0) /* don't get trashed */
li r9,MSR_KERNEL & ~(MSR_IR|MSR_DR) li r9,MSR_KERNEL & ~(MSR_IR|MSR_DR)
mtlr r6 mtlr r6
mtspr SPRN_SPRG_RTAS,r7 stw r7, THREAD + RTAS_SP(r2)
mtspr SPRN_SRR0,r8 mtspr SPRN_SRR0,r8
mtspr SPRN_SRR1,r9 mtspr SPRN_SRR1,r9
RFI RFI
...@@ -1341,7 +1341,8 @@ _GLOBAL(enter_rtas) ...@@ -1341,7 +1341,8 @@ _GLOBAL(enter_rtas)
lwz r9,8(r9) /* original msr value */ lwz r9,8(r9) /* original msr value */
addi r1,r1,INT_FRAME_SIZE addi r1,r1,INT_FRAME_SIZE
li r0,0 li r0,0
mtspr SPRN_SPRG_RTAS,r0 tophys(r7, r2)
stw r0, THREAD + RTAS_SP(r7)
mtspr SPRN_SRR0,r8 mtspr SPRN_SRR0,r8
mtspr SPRN_SRR1,r9 mtspr SPRN_SRR1,r9
RFI /* return to caller */ RFI /* return to caller */
......
...@@ -352,9 +352,8 @@ i##n: \ ...@@ -352,9 +352,8 @@ i##n: \
* registers that might have bad values includes all the GPRs * registers that might have bad values includes all the GPRs
* and all the BATs. We indicate that we are in RTAS by putting * 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, * a non-zero value, the address of the exception frame to use,
* in SPRG2. The machine check handler checks SPRG2 and uses its * in thread.rtas_sp. The machine check handler checks thread.rtas_sp
* value if it is non-zero. If we ever needed to free up SPRG2, * and uses its value if it is non-zero.
* we could use a field in the thread_info or thread_struct instead.
* (Other exception handlers assume that r1 is a valid kernel stack * (Other exception handlers assume that r1 is a valid kernel stack
* pointer when we take an exception from supervisor mode.) * pointer when we take an exception from supervisor mode.)
* -- paulus. * -- paulus.
...@@ -365,16 +364,15 @@ i##n: \ ...@@ -365,16 +364,15 @@ i##n: \
mtspr SPRN_SPRG_SCRATCH1,r11 mtspr SPRN_SPRG_SCRATCH1,r11
mfcr r10 mfcr r10
#ifdef CONFIG_PPC_CHRP #ifdef CONFIG_PPC_CHRP
mfspr r11,SPRN_SPRG_RTAS mfspr r11, SPRN_SPRG_THREAD
cmpwi 0,r11,0 lwz r11, RTAS_SP(r11)
bne 7f cmpwi cr1, r11, 0
bne cr1, 7f
#endif /* CONFIG_PPC_CHRP */ #endif /* CONFIG_PPC_CHRP */
EXCEPTION_PROLOG_1 EXCEPTION_PROLOG_1
7: EXCEPTION_PROLOG_2 7: EXCEPTION_PROLOG_2
addi r3,r1,STACK_FRAME_OVERHEAD addi r3,r1,STACK_FRAME_OVERHEAD
#ifdef CONFIG_PPC_CHRP #ifdef CONFIG_PPC_CHRP
mfspr r4,SPRN_SPRG_RTAS
cmpwi cr1,r4,0
bne cr1,1f bne cr1,1f
#endif #endif
EXC_XFER_STD(0x200, machine_check_exception) EXC_XFER_STD(0x200, machine_check_exception)
...@@ -865,8 +863,10 @@ __secondary_start: ...@@ -865,8 +863,10 @@ __secondary_start:
tophys(r4,r2) tophys(r4,r2)
addi r4,r4,THREAD /* phys address of our thread_struct */ addi r4,r4,THREAD /* phys address of our thread_struct */
mtspr SPRN_SPRG_THREAD,r4 mtspr SPRN_SPRG_THREAD,r4
#ifdef CONFIG_PPC_RTAS
li r3,0 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 */ /* enable MMU and jump to start_secondary */
li r4,MSR_KERNEL li r4,MSR_KERNEL
...@@ -950,8 +950,10 @@ start_here: ...@@ -950,8 +950,10 @@ start_here:
tophys(r4,r2) tophys(r4,r2)
addi r4,r4,THREAD /* init task's THREAD */ addi r4,r4,THREAD /* init task's THREAD */
mtspr SPRN_SPRG_THREAD,r4 mtspr SPRN_SPRG_THREAD,r4
#ifdef CONFIG_PPC_RTAS
li r3,0 li r3,0
mtspr SPRN_SPRG_RTAS,r3 /* 0 => not in RTAS */ stw r3, RTAS_SP(r4) /* 0 => not in RTAS */
#endif
/* stack */ /* stack */
lis r1,init_thread_union@ha lis r1,init_thread_union@ha
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册