]> git.baikalelectronics.ru Git - kernel.git/commitdiff
powerpc64/idle: Fix SP offsets when saving GPRs
authorChristopher M. Riedl <cmr@codefail.de>
Sat, 6 Feb 2021 07:23:42 +0000 (01:23 -0600)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 27 Oct 2021 07:54:28 +0000 (09:54 +0200)
commit 73287caa9210ded6066833195f4335f7f688a46b upstream.

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
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
arch/powerpc/kernel/idle_book3s.S

index d32751994a62c7ea8de19b3a5935637a6c9dbb2a..f2320c78372bf1d39b888466976211f9f18bbc1d 100644 (file)
@@ -50,28 +50,32 @@ _GLOBAL(isa300_idle_stop_mayloss)
        std     r1,PACAR1(r13)
        mflr    r4
        mfcr    r5
-       /* use stack red zone rather than a new frame for saving regs */
-       std     r2,-8*0(r1)
-       std     r14,-8*1(r1)
-       std     r15,-8*2(r1)
-       std     r16,-8*3(r1)
-       std     r17,-8*4(r1)
-       std     r18,-8*5(r1)
-       std     r19,-8*6(r1)
-       std     r20,-8*7(r1)
-       std     r21,-8*8(r1)
-       std     r22,-8*9(r1)
-       std     r23,-8*10(r1)
-       std     r24,-8*11(r1)
-       std     r25,-8*12(r1)
-       std     r26,-8*13(r1)
-       std     r27,-8*14(r1)
-       std     r28,-8*15(r1)
-       std     r29,-8*16(r1)
-       std     r30,-8*17(r1)
-       std     r31,-8*18(r1)
-       std     r4,-8*19(r1)
-       std     r5,-8*20(r1)
+       /*
+        * Use the stack red zone rather than a new frame for saving regs since
+        * in the case of no GPR loss the wakeup code branches directly back to
+        * the caller without deallocating the stack frame first.
+        */
+       std     r2,-8*1(r1)
+       std     r14,-8*2(r1)
+       std     r15,-8*3(r1)
+       std     r16,-8*4(r1)
+       std     r17,-8*5(r1)
+       std     r18,-8*6(r1)
+       std     r19,-8*7(r1)
+       std     r20,-8*8(r1)
+       std     r21,-8*9(r1)
+       std     r22,-8*10(r1)
+       std     r23,-8*11(r1)
+       std     r24,-8*12(r1)
+       std     r25,-8*13(r1)
+       std     r26,-8*14(r1)
+       std     r27,-8*15(r1)
+       std     r28,-8*16(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 */
        PPC_STOP
        b       .       /* catch bugs */
@@ -87,8 +91,8 @@ _GLOBAL(isa300_idle_stop_mayloss)
  */
 _GLOBAL(idle_return_gpr_loss)
        ld      r1,PACAR1(r13)
-       ld      r4,-8*19(r1)
-       ld      r5,-8*20(r1)
+       ld      r4,-8*20(r1)
+       ld      r5,-8*21(r1)
        mtlr    r4
        mtcr    r5
        /*
@@ -96,25 +100,25 @@ _GLOBAL(idle_return_gpr_loss)
         * from PACATOC. This could be avoided for that less common case
         * if KVM saved its r2.
         */
-       ld      r2,-8*0(r1)
-       ld      r14,-8*1(r1)
-       ld      r15,-8*2(r1)
-       ld      r16,-8*3(r1)
-       ld      r17,-8*4(r1)
-       ld      r18,-8*5(r1)
-       ld      r19,-8*6(r1)
-       ld      r20,-8*7(r1)
-       ld      r21,-8*8(r1)
-       ld      r22,-8*9(r1)
-       ld      r23,-8*10(r1)
-       ld      r24,-8*11(r1)
-       ld      r25,-8*12(r1)
-       ld      r26,-8*13(r1)
-       ld      r27,-8*14(r1)
-       ld      r28,-8*15(r1)
-       ld      r29,-8*16(r1)
-       ld      r30,-8*17(r1)
-       ld      r31,-8*18(r1)
+       ld      r2,-8*1(r1)
+       ld      r14,-8*2(r1)
+       ld      r15,-8*3(r1)
+       ld      r16,-8*4(r1)
+       ld      r17,-8*5(r1)
+       ld      r18,-8*6(r1)
+       ld      r19,-8*7(r1)
+       ld      r20,-8*8(r1)
+       ld      r21,-8*9(r1)
+       ld      r22,-8*10(r1)
+       ld      r23,-8*11(r1)
+       ld      r24,-8*12(r1)
+       ld      r25,-8*13(r1)
+       ld      r26,-8*14(r1)
+       ld      r27,-8*15(r1)
+       ld      r28,-8*16(r1)
+       ld      r29,-8*17(r1)
+       ld      r30,-8*18(r1)
+       ld      r31,-8*19(r1)
        blr
 
 /*
@@ -152,28 +156,32 @@ _GLOBAL(isa206_idle_insn_mayloss)
        std     r1,PACAR1(r13)
        mflr    r4
        mfcr    r5
-       /* use stack red zone rather than a new frame for saving regs */
-       std     r2,-8*0(r1)
-       std     r14,-8*1(r1)
-       std     r15,-8*2(r1)
-       std     r16,-8*3(r1)
-       std     r17,-8*4(r1)
-       std     r18,-8*5(r1)
-       std     r19,-8*6(r1)
-       std     r20,-8*7(r1)
-       std     r21,-8*8(r1)
-       std     r22,-8*9(r1)
-       std     r23,-8*10(r1)
-       std     r24,-8*11(r1)
-       std     r25,-8*12(r1)
-       std     r26,-8*13(r1)
-       std     r27,-8*14(r1)
-       std     r28,-8*15(r1)
-       std     r29,-8*16(r1)
-       std     r30,-8*17(r1)
-       std     r31,-8*18(r1)
-       std     r4,-8*19(r1)
-       std     r5,-8*20(r1)
+       /*
+        * Use the stack red zone rather than a new frame for saving regs since
+        * in the case of no GPR loss the wakeup code branches directly back to
+        * the caller without deallocating the stack frame first.
+        */
+       std     r2,-8*1(r1)
+       std     r14,-8*2(r1)
+       std     r15,-8*3(r1)
+       std     r16,-8*4(r1)
+       std     r17,-8*5(r1)
+       std     r18,-8*6(r1)
+       std     r19,-8*7(r1)
+       std     r20,-8*8(r1)
+       std     r21,-8*9(r1)
+       std     r22,-8*10(r1)
+       std     r23,-8*11(r1)
+       std     r24,-8*12(r1)
+       std     r25,-8*13(r1)
+       std     r26,-8*14(r1)
+       std     r27,-8*15(r1)
+       std     r28,-8*16(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
        bne     1f
        IDLE_STATE_ENTER_SEQ_NORET(PPC_NAP)