提交 369e757b 编写于 作者: K Kumar Gala

[POWERPC] Rework EXC_LEVEL_EXCEPTION_PROLOG code

* Cleanup the code a bit my allocating an INT_FRAME on our exception
  stack there by make references go from GPR11-INT_FRAME_SIZE(r8) to
  just GPR11(r8)
* simplify {lvl}_transfer_to_handler code by moving the copying of the
  temp registers we use if we come from user space into the PROLOG
* If the exception came from kernel mode copy thread_info flags,
  preempt, and task pointer from the process thread_info.
Signed-off-by: NKumar Gala <galak@kernel.crashing.org>
Acked-by: NPaul Mackerras <paulus@samba.org>
上级 bcf0b088
...@@ -44,29 +44,16 @@ ...@@ -44,29 +44,16 @@
#endif #endif
#ifdef CONFIG_BOOKE #ifdef CONFIG_BOOKE
#include "head_booke.h"
#define TRANSFER_TO_HANDLER_EXC_LEVEL(exc_level) \
mtspr exc_level##_SPRG,r8; \
BOOKE_LOAD_EXC_LEVEL_STACK(exc_level); \
lwz r0,GPR10-INT_FRAME_SIZE(r8); \
stw r0,GPR10(r11); \
lwz r0,GPR11-INT_FRAME_SIZE(r8); \
stw r0,GPR11(r11); \
mfspr r8,exc_level##_SPRG
.globl mcheck_transfer_to_handler .globl mcheck_transfer_to_handler
mcheck_transfer_to_handler: mcheck_transfer_to_handler:
TRANSFER_TO_HANDLER_EXC_LEVEL(MCHECK)
b transfer_to_handler_full b transfer_to_handler_full
.globl debug_transfer_to_handler .globl debug_transfer_to_handler
debug_transfer_to_handler: debug_transfer_to_handler:
TRANSFER_TO_HANDLER_EXC_LEVEL(DEBUG)
b transfer_to_handler_full b transfer_to_handler_full
.globl crit_transfer_to_handler .globl crit_transfer_to_handler
crit_transfer_to_handler: crit_transfer_to_handler:
TRANSFER_TO_HANDLER_EXC_LEVEL(CRIT)
/* fall through */ /* fall through */
#endif #endif
......
...@@ -72,18 +72,20 @@ ...@@ -72,18 +72,20 @@
#define DEBUG_STACK_BASE dbgirq_ctx #define DEBUG_STACK_BASE dbgirq_ctx
#define DEBUG_SPRG SPRN_SPRG6W #define DEBUG_SPRG SPRN_SPRG6W
#define EXC_LVL_FRAME_OVERHEAD (THREAD_SIZE - INT_FRAME_SIZE)
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
#define BOOKE_LOAD_EXC_LEVEL_STACK(level) \ #define BOOKE_LOAD_EXC_LEVEL_STACK(level) \
mfspr r8,SPRN_PIR; \ mfspr r8,SPRN_PIR; \
slwi r8,r8,2; \ slwi r8,r8,2; \
addis r8,r8,level##_STACK_BASE@ha; \ addis r8,r8,level##_STACK_BASE@ha; \
lwz r8,level##_STACK_BASE@l(r8); \ lwz r8,level##_STACK_BASE@l(r8); \
addi r8,r8,THREAD_SIZE; addi r8,r8,EXC_LVL_FRAME_OVERHEAD;
#else #else
#define BOOKE_LOAD_EXC_LEVEL_STACK(level) \ #define BOOKE_LOAD_EXC_LEVEL_STACK(level) \
lis r8,level##_STACK_BASE@ha; \ lis r8,level##_STACK_BASE@ha; \
lwz r8,level##_STACK_BASE@l(r8); \ lwz r8,level##_STACK_BASE@l(r8); \
addi r8,r8,THREAD_SIZE; addi r8,r8,EXC_LVL_FRAME_OVERHEAD;
#endif #endif
/* /*
...@@ -97,22 +99,36 @@ ...@@ -97,22 +99,36 @@
#define EXC_LEVEL_EXCEPTION_PROLOG(exc_level, exc_level_srr0, exc_level_srr1) \ #define EXC_LEVEL_EXCEPTION_PROLOG(exc_level, exc_level_srr0, exc_level_srr1) \
mtspr exc_level##_SPRG,r8; \ mtspr exc_level##_SPRG,r8; \
BOOKE_LOAD_EXC_LEVEL_STACK(exc_level);/* r8 points to the exc_level stack*/ \ BOOKE_LOAD_EXC_LEVEL_STACK(exc_level);/* r8 points to the exc_level stack*/ \
stw r10,GPR10-INT_FRAME_SIZE(r8); \ stw r9,GPR9(r8); /* save various registers */\
stw r11,GPR11-INT_FRAME_SIZE(r8); \ mfcr r9; /* save CR in r9 for now */\
mfcr r10; /* save CR in r10 for now */\ stw r10,GPR10(r8); \
mfspr r11,exc_level_srr1; /* check whether user or kernel */\ stw r11,GPR11(r8); \
andi. r11,r11,MSR_PR; \ stw r9,_CCR(r8); /* save CR on stack */\
mr r11,r8; \ mfspr r10,exc_level_srr1; /* check whether user or kernel */\
mfspr r8,exc_level##_SPRG; \ andi. r10,r10,MSR_PR; \
beq 1f; \
/* COMING FROM USER MODE */ \
mfspr r11,SPRN_SPRG3; /* if from user, start at top of */\ mfspr r11,SPRN_SPRG3; /* if from user, start at top of */\
lwz r11,THREAD_INFO-THREAD(r11); /* this thread's kernel stack */\ lwz r11,THREAD_INFO-THREAD(r11); /* this thread's kernel stack */\
addi r11,r11,THREAD_SIZE; \ addi r11,r11,EXC_LVL_FRAME_OVERHEAD; /* allocate stack frame */\
1: subi r11,r11,INT_FRAME_SIZE; /* Allocate an exception frame */\ beq 1f; \
stw r10,_CCR(r11); /* save various registers */\ /* COMING FROM USER MODE */ \
stw r12,GPR12(r11); \ stw r9,_CCR(r11); /* save CR */\
lwz r10,GPR10(r8); /* copy regs from exception stack */\
lwz r9,GPR9(r8); \
stw r10,GPR10(r11); \
lwz r10,GPR11(r8); \
stw r9,GPR9(r11); \ stw r9,GPR9(r11); \
stw r10,GPR11(r11); \
b 2f; \
/* COMING FROM PRIV MODE */ \
1: lwz r9,TI_FLAGS-EXC_LVL_FRAME_OVERHEAD(r11); \
lwz r10,TI_PREEMPT-EXC_LVL_FRAME_OVERHEAD(r11); \
stw r9,TI_FLAGS-EXC_LVL_FRAME_OVERHEAD(r8); \
stw r10,TI_PREEMPT-EXC_LVL_FRAME_OVERHEAD(r8); \
lwz r9,TI_TASK-EXC_LVL_FRAME_OVERHEAD(r11); \
stw r9,TI_TASK-EXC_LVL_FRAME_OVERHEAD(r8); \
mr r11,r8; \
2: mfspr r8,exc_level##_SPRG; \
stw r12,GPR12(r11); /* save various registers */\
mflr r10; \ mflr r10; \
stw r10,_LINK(r11); \ stw r10,_LINK(r11); \
mfspr r12,SPRN_DEAR; /* save DEAR and ESR in the frame */\ mfspr r12,SPRN_DEAR; /* save DEAR and ESR in the frame */\
...@@ -255,8 +271,8 @@ ...@@ -255,8 +271,8 @@
lwz r12,GPR12(r11); \ lwz r12,GPR12(r11); \
mtspr DEBUG_SPRG,r8; \ mtspr DEBUG_SPRG,r8; \
BOOKE_LOAD_EXC_LEVEL_STACK(DEBUG); /* r8 points to the debug stack */ \ BOOKE_LOAD_EXC_LEVEL_STACK(DEBUG); /* r8 points to the debug stack */ \
lwz r10,GPR10-INT_FRAME_SIZE(r8); \ lwz r10,GPR10(r8); \
lwz r11,GPR11-INT_FRAME_SIZE(r8); \ lwz r11,GPR11(r8); \
mfspr r8,DEBUG_SPRG; \ mfspr r8,DEBUG_SPRG; \
\ \
RFDI; \ RFDI; \
...@@ -308,8 +324,8 @@ ...@@ -308,8 +324,8 @@
lwz r12,GPR12(r11); \ lwz r12,GPR12(r11); \
mtspr CRIT_SPRG,r8; \ mtspr CRIT_SPRG,r8; \
BOOKE_LOAD_EXC_LEVEL_STACK(CRIT); /* r8 points to the debug stack */ \ BOOKE_LOAD_EXC_LEVEL_STACK(CRIT); /* r8 points to the debug stack */ \
lwz r10,GPR10-INT_FRAME_SIZE(r8); \ lwz r10,GPR10(r8); \
lwz r11,GPR11-INT_FRAME_SIZE(r8); \ lwz r11,GPR11(r8); \
mfspr r8,CRIT_SPRG; \ mfspr r8,CRIT_SPRG; \
\ \
rfci; \ rfci; \
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册