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: Christophe Leroy <christophe.leroy@c-s.fr> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
This commit is contained in:
parent
40058337f2
commit
0df977eafc
@ -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 @@
|
|||||||
#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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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: \
|
|||||||
* 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: \
|
|||||||
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:
|
|||||||
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:
|
|||||||
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
|
||||||
|
Loading…
Reference in New Issue
Block a user