powerpc64/idle: Fix SP offsets when saving GPRs
The idle entry/exit code saves/restores GPRs in the stack "red zone" (Protected Zone according to PowerPC64 ELF ABI v2). However, the offset used for the first GPR is incorrect and overwrites the back chain - the Protected Zone actually starts below the current SP. In practice this is probably not an issue, but it's still incorrect so fix it. Also expand the comments to explain why using the stack "red zone" instead of creating a new stackframe is appropriate here. Signed-off-by: Christopher M. Riedl <cmr@codefail.de> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> Link: https://lore.kernel.org/r/20210206072342.5067-1-cmr@codefail.de
This commit is contained in:
parent
b842d131c7
commit
73287caa92
1 changed files with 73 additions and 65 deletions
|
@ -52,28 +52,32 @@ _GLOBAL(isa300_idle_stop_mayloss)
|
||||||
std r1,PACAR1(r13)
|
std r1,PACAR1(r13)
|
||||||
mflr r4
|
mflr r4
|
||||||
mfcr r5
|
mfcr r5
|
||||||
/* use stack red zone rather than a new frame for saving regs */
|
/*
|
||||||
std r2,-8*0(r1)
|
* Use the stack red zone rather than a new frame for saving regs since
|
||||||
std r14,-8*1(r1)
|
* in the case of no GPR loss the wakeup code branches directly back to
|
||||||
std r15,-8*2(r1)
|
* the caller without deallocating the stack frame first.
|
||||||
std r16,-8*3(r1)
|
*/
|
||||||
std r17,-8*4(r1)
|
std r2,-8*1(r1)
|
||||||
std r18,-8*5(r1)
|
std r14,-8*2(r1)
|
||||||
std r19,-8*6(r1)
|
std r15,-8*3(r1)
|
||||||
std r20,-8*7(r1)
|
std r16,-8*4(r1)
|
||||||
std r21,-8*8(r1)
|
std r17,-8*5(r1)
|
||||||
std r22,-8*9(r1)
|
std r18,-8*6(r1)
|
||||||
std r23,-8*10(r1)
|
std r19,-8*7(r1)
|
||||||
std r24,-8*11(r1)
|
std r20,-8*8(r1)
|
||||||
std r25,-8*12(r1)
|
std r21,-8*9(r1)
|
||||||
std r26,-8*13(r1)
|
std r22,-8*10(r1)
|
||||||
std r27,-8*14(r1)
|
std r23,-8*11(r1)
|
||||||
std r28,-8*15(r1)
|
std r24,-8*12(r1)
|
||||||
std r29,-8*16(r1)
|
std r25,-8*13(r1)
|
||||||
std r30,-8*17(r1)
|
std r26,-8*14(r1)
|
||||||
std r31,-8*18(r1)
|
std r27,-8*15(r1)
|
||||||
std r4,-8*19(r1)
|
std r28,-8*16(r1)
|
||||||
std r5,-8*20(r1)
|
std r29,-8*17(r1)
|
||||||
|
std r30,-8*18(r1)
|
||||||
|
std r31,-8*19(r1)
|
||||||
|
std r4,-8*20(r1)
|
||||||
|
std r5,-8*21(r1)
|
||||||
/* 168 bytes */
|
/* 168 bytes */
|
||||||
PPC_STOP
|
PPC_STOP
|
||||||
b . /* catch bugs */
|
b . /* catch bugs */
|
||||||
|
@ -89,8 +93,8 @@ _GLOBAL(isa300_idle_stop_mayloss)
|
||||||
*/
|
*/
|
||||||
_GLOBAL(idle_return_gpr_loss)
|
_GLOBAL(idle_return_gpr_loss)
|
||||||
ld r1,PACAR1(r13)
|
ld r1,PACAR1(r13)
|
||||||
ld r4,-8*19(r1)
|
ld r4,-8*20(r1)
|
||||||
ld r5,-8*20(r1)
|
ld r5,-8*21(r1)
|
||||||
mtlr r4
|
mtlr r4
|
||||||
mtcr r5
|
mtcr r5
|
||||||
/*
|
/*
|
||||||
|
@ -98,25 +102,25 @@ _GLOBAL(idle_return_gpr_loss)
|
||||||
* from PACATOC. This could be avoided for that less common case
|
* from PACATOC. This could be avoided for that less common case
|
||||||
* if KVM saved its r2.
|
* if KVM saved its r2.
|
||||||
*/
|
*/
|
||||||
ld r2,-8*0(r1)
|
ld r2,-8*1(r1)
|
||||||
ld r14,-8*1(r1)
|
ld r14,-8*2(r1)
|
||||||
ld r15,-8*2(r1)
|
ld r15,-8*3(r1)
|
||||||
ld r16,-8*3(r1)
|
ld r16,-8*4(r1)
|
||||||
ld r17,-8*4(r1)
|
ld r17,-8*5(r1)
|
||||||
ld r18,-8*5(r1)
|
ld r18,-8*6(r1)
|
||||||
ld r19,-8*6(r1)
|
ld r19,-8*7(r1)
|
||||||
ld r20,-8*7(r1)
|
ld r20,-8*8(r1)
|
||||||
ld r21,-8*8(r1)
|
ld r21,-8*9(r1)
|
||||||
ld r22,-8*9(r1)
|
ld r22,-8*10(r1)
|
||||||
ld r23,-8*10(r1)
|
ld r23,-8*11(r1)
|
||||||
ld r24,-8*11(r1)
|
ld r24,-8*12(r1)
|
||||||
ld r25,-8*12(r1)
|
ld r25,-8*13(r1)
|
||||||
ld r26,-8*13(r1)
|
ld r26,-8*14(r1)
|
||||||
ld r27,-8*14(r1)
|
ld r27,-8*15(r1)
|
||||||
ld r28,-8*15(r1)
|
ld r28,-8*16(r1)
|
||||||
ld r29,-8*16(r1)
|
ld r29,-8*17(r1)
|
||||||
ld r30,-8*17(r1)
|
ld r30,-8*18(r1)
|
||||||
ld r31,-8*18(r1)
|
ld r31,-8*19(r1)
|
||||||
blr
|
blr
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -154,28 +158,32 @@ _GLOBAL(isa206_idle_insn_mayloss)
|
||||||
std r1,PACAR1(r13)
|
std r1,PACAR1(r13)
|
||||||
mflr r4
|
mflr r4
|
||||||
mfcr r5
|
mfcr r5
|
||||||
/* use stack red zone rather than a new frame for saving regs */
|
/*
|
||||||
std r2,-8*0(r1)
|
* Use the stack red zone rather than a new frame for saving regs since
|
||||||
std r14,-8*1(r1)
|
* in the case of no GPR loss the wakeup code branches directly back to
|
||||||
std r15,-8*2(r1)
|
* the caller without deallocating the stack frame first.
|
||||||
std r16,-8*3(r1)
|
*/
|
||||||
std r17,-8*4(r1)
|
std r2,-8*1(r1)
|
||||||
std r18,-8*5(r1)
|
std r14,-8*2(r1)
|
||||||
std r19,-8*6(r1)
|
std r15,-8*3(r1)
|
||||||
std r20,-8*7(r1)
|
std r16,-8*4(r1)
|
||||||
std r21,-8*8(r1)
|
std r17,-8*5(r1)
|
||||||
std r22,-8*9(r1)
|
std r18,-8*6(r1)
|
||||||
std r23,-8*10(r1)
|
std r19,-8*7(r1)
|
||||||
std r24,-8*11(r1)
|
std r20,-8*8(r1)
|
||||||
std r25,-8*12(r1)
|
std r21,-8*9(r1)
|
||||||
std r26,-8*13(r1)
|
std r22,-8*10(r1)
|
||||||
std r27,-8*14(r1)
|
std r23,-8*11(r1)
|
||||||
std r28,-8*15(r1)
|
std r24,-8*12(r1)
|
||||||
std r29,-8*16(r1)
|
std r25,-8*13(r1)
|
||||||
std r30,-8*17(r1)
|
std r26,-8*14(r1)
|
||||||
std r31,-8*18(r1)
|
std r27,-8*15(r1)
|
||||||
std r4,-8*19(r1)
|
std r28,-8*16(r1)
|
||||||
std r5,-8*20(r1)
|
std r29,-8*17(r1)
|
||||||
|
std r30,-8*18(r1)
|
||||||
|
std r31,-8*19(r1)
|
||||||
|
std r4,-8*20(r1)
|
||||||
|
std r5,-8*21(r1)
|
||||||
cmpwi r3,PNV_THREAD_NAP
|
cmpwi r3,PNV_THREAD_NAP
|
||||||
bne 1f
|
bne 1f
|
||||||
IDLE_STATE_ENTER_SEQ_NORET(PPC_NAP)
|
IDLE_STATE_ENTER_SEQ_NORET(PPC_NAP)
|
||||||
|
|
Loading…
Add table
Reference in a new issue