powerpc/32: Fix vmap stack - Properly set r1 before activating MMU
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: 028474876f
("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
This commit is contained in:
parent
c118c7303a
commit
da7bb43ab9
@ -39,15 +39,24 @@
|
|||||||
.endm
|
.endm
|
||||||
|
|
||||||
.macro EXCEPTION_PROLOG_1 for_rtas=0
|
.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 */
|
subi r11, r1, INT_FRAME_SIZE /* use r1 if kernel */
|
||||||
beq 1f
|
beq 1f
|
||||||
mfspr r11,SPRN_SPRG_THREAD
|
mfspr r11,SPRN_SPRG_THREAD
|
||||||
lwz r11,TASK_STACK-THREAD(r11)
|
lwz r11,TASK_STACK-THREAD(r11)
|
||||||
addi r11, r11, THREAD_SIZE - INT_FRAME_SIZE
|
addi r11, r11, THREAD_SIZE - INT_FRAME_SIZE
|
||||||
|
#endif
|
||||||
1:
|
1:
|
||||||
tophys_novmstack r11, r11
|
tophys_novmstack r11, r11
|
||||||
#ifdef CONFIG_VMAP_STACK
|
#ifdef CONFIG_VMAP_STACK
|
||||||
mtcrf 0x7f, r11
|
mtcrf 0x7f, r1
|
||||||
bt 32 - THREAD_ALIGN_SHIFT, stack_overflow
|
bt 32 - THREAD_ALIGN_SHIFT, stack_overflow
|
||||||
#endif
|
#endif
|
||||||
.endm
|
.endm
|
||||||
@ -62,6 +71,15 @@
|
|||||||
stw r10,_CCR(r11) /* save registers */
|
stw r10,_CCR(r11) /* save registers */
|
||||||
#endif
|
#endif
|
||||||
mfspr r10, SPRN_SPRG_SCRATCH0
|
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 r12,GPR12(r11)
|
||||||
stw r9,GPR9(r11)
|
stw r9,GPR9(r11)
|
||||||
stw r10,GPR10(r11)
|
stw r10,GPR10(r11)
|
||||||
@ -89,9 +107,6 @@
|
|||||||
mfspr r12,SPRN_SRR0
|
mfspr r12,SPRN_SRR0
|
||||||
mfspr r9,SPRN_SRR1
|
mfspr r9,SPRN_SRR1
|
||||||
#endif
|
#endif
|
||||||
stw r1,GPR1(r11)
|
|
||||||
stw r1,0(r11)
|
|
||||||
tovirt_novmstack r1, r11 /* set new kernel sp */
|
|
||||||
#ifdef CONFIG_40x
|
#ifdef CONFIG_40x
|
||||||
rlwinm r9,r9,0,14,12 /* clear MSR_WE (necessary?) */
|
rlwinm r9,r9,0,14,12 /* clear MSR_WE (necessary?) */
|
||||||
#else
|
#else
|
||||||
@ -309,19 +324,19 @@ label:
|
|||||||
.macro vmap_stack_overflow_exception
|
.macro vmap_stack_overflow_exception
|
||||||
#ifdef CONFIG_VMAP_STACK
|
#ifdef CONFIG_VMAP_STACK
|
||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
mfspr r11, SPRN_SPRG_THREAD
|
mfspr r1, SPRN_SPRG_THREAD
|
||||||
lwz r11, TASK_CPU - THREAD(r11)
|
lwz r1, TASK_CPU - THREAD(r1)
|
||||||
slwi r11, r11, 3
|
slwi r1, r1, 3
|
||||||
addis r11, r11, emergency_ctx@ha
|
addis r1, r1, emergency_ctx@ha
|
||||||
#else
|
#else
|
||||||
lis r11, emergency_ctx@ha
|
lis r1, emergency_ctx@ha
|
||||||
#endif
|
#endif
|
||||||
lwz r11, emergency_ctx@l(r11)
|
lwz r1, emergency_ctx@l(r1)
|
||||||
cmpwi cr1, r11, 0
|
cmpwi cr1, r1, 0
|
||||||
bne cr1, 1f
|
bne cr1, 1f
|
||||||
lis r11, init_thread_union@ha
|
lis r1, init_thread_union@ha
|
||||||
addi r11, r11, init_thread_union@l
|
addi r1, r1, init_thread_union@l
|
||||||
1: addi r11, r11, THREAD_SIZE - INT_FRAME_SIZE
|
1: addi r1, r1, THREAD_SIZE - INT_FRAME_SIZE
|
||||||
EXCEPTION_PROLOG_2
|
EXCEPTION_PROLOG_2
|
||||||
SAVE_NVGPRS(r11)
|
SAVE_NVGPRS(r11)
|
||||||
addi r3, r1, STACK_FRAME_OVERHEAD
|
addi r3, r1, STACK_FRAME_OVERHEAD
|
||||||
|
Loading…
Reference in New Issue
Block a user