Commit 57bc13ac authored by Christophe Leroy's avatar Christophe Leroy Committed by Michael Ellerman

powerpc/40x: Don't use SPRN_SPRG_SCRATCH2 in EXCEPTION_PROLOG

Unlike said in the comment, r1 is not reused by the critical
exception handler, as it uses a dedicated critirq_ctx stack.
Decrementing r1 early is then unneeded.

Should the above be valid, the code is crap buggy anyway as
r1 gets some intermediate values that would jeopardise the
whole process (for instance after mfspr   r1,SPRN_SPRG_THREAD)

Using SPRN_SPRG_SCRATCH2 to save r1 is then not needed, r11 can be
used instead. This avoids one mtspr and one mfspr and makes the
prolog closer to what's done on 6xx and 8xx.
Signed-off-by: default avatarChristophe Leroy <christophe.leroy@c-s.fr>
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
parent 1d3034ae
...@@ -102,23 +102,20 @@ _ENTRY(saved_ksp_limit) ...@@ -102,23 +102,20 @@ _ENTRY(saved_ksp_limit)
* Exception vector entry code. This code runs with address translation * Exception vector entry code. This code runs with address translation
* turned off (i.e. using physical addresses). We assume SPRG_THREAD has * turned off (i.e. using physical addresses). We assume SPRG_THREAD has
* the physical address of the current task thread_struct. * the physical address of the current task thread_struct.
* Note that we have to have decremented r1 before we write to any fields
* of the exception frame, since a critical interrupt could occur at any
* time, and it will write to the area immediately below the current r1.
*/ */
#define NORMAL_EXCEPTION_PROLOG \ #define NORMAL_EXCEPTION_PROLOG \
mtspr SPRN_SPRG_SCRATCH0,r10; /* save two registers to work with */\ mtspr SPRN_SPRG_SCRATCH0,r10; /* save two registers to work with */\
mtspr SPRN_SPRG_SCRATCH1,r11; \ mtspr SPRN_SPRG_SCRATCH1,r11; \
mtspr SPRN_SPRG_SCRATCH2,r1; \
mfcr r10; /* save CR in r10 for now */\ mfcr r10; /* save CR in r10 for now */\
mfspr r11,SPRN_SRR1; /* check whether user or kernel */\ mfspr r11,SPRN_SRR1; /* check whether user or kernel */\
andi. r11,r11,MSR_PR; \ andi. r11,r11,MSR_PR; \
beq 1f; \
mfspr r1,SPRN_SPRG_THREAD; /* if from user, start at top of */\
lwz r1,TASK_STACK-THREAD(r1); /* this thread's kernel stack */\
addi r1,r1,THREAD_SIZE; \
1: subi r1,r1,INT_FRAME_SIZE; /* Allocate an exception frame */\
tophys(r11,r1); \ tophys(r11,r1); \
beq 1f; \
mfspr r11,SPRN_SPRG_THREAD; /* if from user, start at top of */\
lwz r11,TASK_STACK-THREAD(r11); /* this thread's kernel stack */\
addi r11,r11,THREAD_SIZE; \
tophys(r11,r11); \
1: subi r11,r11,INT_FRAME_SIZE; /* Allocate an exception frame */\
stw r10,_CCR(r11); /* save various registers */\ stw r10,_CCR(r11); /* save various registers */\
stw r12,GPR12(r11); \ stw r12,GPR12(r11); \
stw r9,GPR9(r11); \ stw r9,GPR9(r11); \
...@@ -128,11 +125,11 @@ _ENTRY(saved_ksp_limit) ...@@ -128,11 +125,11 @@ _ENTRY(saved_ksp_limit)
stw r12,GPR11(r11); \ stw r12,GPR11(r11); \
mflr r10; \ mflr r10; \
stw r10,_LINK(r11); \ stw r10,_LINK(r11); \
mfspr r10,SPRN_SPRG_SCRATCH2; \
mfspr r12,SPRN_SRR0; \ mfspr r12,SPRN_SRR0; \
stw r10,GPR1(r11); \ stw r1,GPR1(r11); \
mfspr r9,SPRN_SRR1; \ mfspr r9,SPRN_SRR1; \
stw r10,0(r11); \ stw r1,0(r11); \
tovirt(r1,r11); /* set new kernel sp */ \
rlwinm r9,r9,0,14,12; /* clear MSR_WE (necessary?) */\ rlwinm r9,r9,0,14,12; /* clear MSR_WE (necessary?) */\
stw r0,GPR0(r11); \ stw r0,GPR0(r11); \
SAVE_4GPRS(3, r11); \ SAVE_4GPRS(3, r11); \
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment