Commit d5c24398 authored by Christophe Leroy's avatar Christophe Leroy Committed by Michael Ellerman
Browse files

powerpc/32: Fix vmap stack - Properly set r1 before activating MMU on syscall too



We need r1 to be properly set before activating MMU, otherwise any new
exception taken while saving registers into the stack in syscall
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 for now.

Fixes: da7bb43a ("powerpc/32: Fix vmap stack - Properly set r1 before activating MMU")
Cc: stable@vger.kernel.org # v5.10+
Signed-off-by: default avatarChristophe Leroy <christophe.leroy@csgroup.eu>
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/a3d819d5c348cee9783a311d5d3f3ba9b48fd219.1608531452.git.christophe.leroy@csgroup.eu
parent 2eda7f11
Loading
Loading
Loading
Loading
+16 −9
Original line number Diff line number Diff line
@@ -121,18 +121,28 @@
#ifdef CONFIG_VMAP_STACK
	mfspr	r11, SPRN_SRR0
	mtctr	r11
#endif
	andi.	r11, r9, MSR_PR
	lwz	r11,TASK_STACK-THREAD(r12)
	mr	r11, r1
	lwz	r1,TASK_STACK-THREAD(r12)
	beq-	99f
	addi	r11, r11, THREAD_SIZE - INT_FRAME_SIZE
#ifdef CONFIG_VMAP_STACK
	addi	r1, r1, THREAD_SIZE - INT_FRAME_SIZE
	li	r10, MSR_KERNEL & ~(MSR_IR | MSR_RI) /* can take DTLB miss */
	mtmsr	r10
	isync
	tovirt(r12, r12)
	stw	r11,GPR1(r1)
	stw	r11,0(r1)
	mr	r11, r1
#else
	andi.	r11, r9, MSR_PR
	lwz	r11,TASK_STACK-THREAD(r12)
	beq-	99f
	addi	r11, r11, THREAD_SIZE - INT_FRAME_SIZE
	tophys(r11, r11)
	stw	r1,GPR1(r11)
	stw	r1,0(r11)
	tovirt(r1, r11)		/* set new kernel sp */
#endif
	tovirt_vmstack r12, r12
	tophys_novmstack r11, r11
	mflr	r10
	stw	r10, _LINK(r11)
#ifdef CONFIG_VMAP_STACK
@@ -140,9 +150,6 @@
#else
	mfspr	r10,SPRN_SRR0
#endif
	stw	r1,GPR1(r11)
	stw	r1,0(r11)
	tovirt_novmstack r1, r11	/* set new kernel sp */
	stw	r10,_NIP(r11)
	mfcr	r10
	rlwinm	r10,r10,0,4,2	/* Clear SO bit in CR */