]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/commitdiff
powerpc/32: Fix vmap stack - Properly set r1 before activating MMU
authorChristophe Leroy <christophe.leroy@csgroup.eu>
Mon, 7 Sep 2020 13:42:10 +0000 (13:42 +0000)
committerMichael Ellerman <mpe@ellerman.id.au>
Tue, 15 Sep 2020 12:13:33 +0000 (22:13 +1000)
We need r1 to be properly set before activating MMU, otherwise any new
exception taken while saving registers into the stack in exception
prologs will use the user stack, which is wrong and will even lockup
or crash when KUAP is selected.

Do that by switching the meaning of r11 and r1 until we have saved r1
to the stack: copy r1 into r11 and setup the new stack pointer in r1.
To avoid complicating and impacting all generic and specific prolog
code (and more), copy back r1 into r11 once r11 is save onto
the stack.

We could get rid of copying r1 back and forth at the cost of
rewriting everything to use r1 instead of r11 all the way when
CONFIG_VMAP_STACK is set, but the effort is probably not worth it.

Fixes: 028474876f47 ("powerpc/32: prepare for CONFIG_VMAP_STACK")
Cc: stable@vger.kernel.org
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/8f85e8752ac5af602db7237ef53d634f4f3d3892.1599486108.git.christophe.leroy@csgroup.eu
arch/powerpc/kernel/head_32.h

index 21effebb927796b5dfc8a9ca4afe2b63c48081b6..cc36998c554160540701f9aa6071cefbc433de2e 100644 (file)
 .endm
 
 .macro EXCEPTION_PROLOG_1 for_rtas=0
+#ifdef CONFIG_VMAP_STACK
+       mr      r11, r1
+       subi    r1, r1, INT_FRAME_SIZE          /* use r1 if kernel */
+       beq     1f
+       mfspr   r1,SPRN_SPRG_THREAD
+       lwz     r1,TASK_STACK-THREAD(r1)
+       addi    r1, r1, THREAD_SIZE - INT_FRAME_SIZE
+#else
        subi    r11, r1, INT_FRAME_SIZE         /* use r1 if kernel */
        beq     1f
        mfspr   r11,SPRN_SPRG_THREAD
        lwz     r11,TASK_STACK-THREAD(r11)
        addi    r11, r11, THREAD_SIZE - INT_FRAME_SIZE
+#endif
 1:
        tophys_novmstack r11, r11
 #ifdef CONFIG_VMAP_STACK
-       mtcrf   0x7f, r11
+       mtcrf   0x7f, r1
        bt      32 - THREAD_ALIGN_SHIFT, stack_overflow
 #endif
 .endm
        stw     r10,_CCR(r11)           /* save registers */
 #endif
        mfspr   r10, SPRN_SPRG_SCRATCH0
+#ifdef CONFIG_VMAP_STACK
+       stw     r11,GPR1(r1)
+       stw     r11,0(r1)
+       mr      r11, r1
+#else
+       stw     r1,GPR1(r11)
+       stw     r1,0(r11)
+       tovirt(r1, r11)         /* set new kernel sp */
+#endif
        stw     r12,GPR12(r11)
        stw     r9,GPR9(r11)
        stw     r10,GPR10(r11)
        mfspr   r12,SPRN_SRR0
        mfspr   r9,SPRN_SRR1
 #endif
-       stw     r1,GPR1(r11)
-       stw     r1,0(r11)
-       tovirt_novmstack r1, r11        /* set new kernel sp */
 #ifdef CONFIG_40x
        rlwinm  r9,r9,0,14,12           /* clear MSR_WE (necessary?) */
 #else
@@ -309,19 +324,19 @@ label:
 .macro vmap_stack_overflow_exception
 #ifdef CONFIG_VMAP_STACK
 #ifdef CONFIG_SMP
-       mfspr   r11, SPRN_SPRG_THREAD
-       lwz     r11, TASK_CPU - THREAD(r11)
-       slwi    r11, r11, 3
-       addis   r11, r11, emergency_ctx@ha
+       mfspr   r1, SPRN_SPRG_THREAD
+       lwz     r1, TASK_CPU - THREAD(r1)
+       slwi    r1, r1, 3
+       addis   r1, r1, emergency_ctx@ha
 #else
-       lis     r11, emergency_ctx@ha
+       lis     r1, emergency_ctx@ha
 #endif
-       lwz     r11, emergency_ctx@l(r11)
-       cmpwi   cr1, r11, 0
+       lwz     r1, emergency_ctx@l(r1)
+       cmpwi   cr1, r1, 0
        bne     cr1, 1f
-       lis     r11, init_thread_union@ha
-       addi    r11, r11, init_thread_union@l
-1:     addi    r11, r11, THREAD_SIZE - INT_FRAME_SIZE
+       lis     r1, init_thread_union@ha
+       addi    r1, r1, init_thread_union@l
+1:     addi    r1, r1, THREAD_SIZE - INT_FRAME_SIZE
        EXCEPTION_PROLOG_2
        SAVE_NVGPRS(r11)
        addi    r3, r1, STACK_FRAME_OVERHEAD