Commit 1977b502 authored by Paul Mackerras's avatar Paul Mackerras Committed by Benjamin Herrenschmidt

powerpc: Save register r9-r13 values accurately on interrupt with bad stack

When we take an interrupt or exception from kernel mode and the stack
pointer is obviously not a kernel address (i.e. the top bit is 0), we
switch to an emergency stack, save register values and panic.  However,
on 64-bit server machines, we don't actually save the values of r9 - r13
at the time of the interrupt, but rather values corrupted by the
exception entry code for r12-r13, and nothing at all for r9-r11.

This fixes it by passing a pointer to the register save area in the paca
through to the bad_stack code in r3.  The register values are saved in
one of the paca register save areas (depending on which exception this
is).  Using the pointer in r3, the bad_stack code now retrieves the
saved values of r9 - r13 and stores them in the exception frame on the
emergency stack.  This also stores the normal exception frame marker
("regshere") in the exception frame.
Signed-off-by: default avatarPaul Mackerras <paulus@samba.org>
Signed-off-by: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
parent 851d2e2f
...@@ -104,10 +104,11 @@ ...@@ -104,10 +104,11 @@
beq- 1f; \ beq- 1f; \
ld r1,PACAKSAVE(r13); /* kernel stack to use */ \ ld r1,PACAKSAVE(r13); /* kernel stack to use */ \
1: cmpdi cr1,r1,0; /* check if r1 is in userspace */ \ 1: cmpdi cr1,r1,0; /* check if r1 is in userspace */ \
bge- cr1,2f; /* abort if it is */ \ blt+ cr1,3f; /* abort if it is */ \
b 3f; \ li r1,(n); /* will be reloaded later */ \
2: li r1,(n); /* will be reloaded later */ \
sth r1,PACA_TRAP_SAVE(r13); \ sth r1,PACA_TRAP_SAVE(r13); \
std r3,area+EX_R3(r13); \
addi r3,r13,area; /* r3 -> where regs are saved*/ \
b bad_stack; \ b bad_stack; \
3: std r9,_CCR(r1); /* save CR in stackframe */ \ 3: std r9,_CCR(r1); /* save CR in stackframe */ \
std r11,_NIP(r1); /* save SRR0 in stackframe */ \ std r11,_NIP(r1); /* save SRR0 in stackframe */ \
......
...@@ -461,9 +461,20 @@ bad_stack: ...@@ -461,9 +461,20 @@ bad_stack:
std r12,_XER(r1) std r12,_XER(r1)
SAVE_GPR(0,r1) SAVE_GPR(0,r1)
SAVE_GPR(2,r1) SAVE_GPR(2,r1)
SAVE_4GPRS(3,r1) ld r10,EX_R3(r3)
SAVE_2GPRS(7,r1) std r10,GPR3(r1)
SAVE_10GPRS(12,r1) SAVE_GPR(4,r1)
SAVE_4GPRS(5,r1)
ld r9,EX_R9(r3)
ld r10,EX_R10(r3)
SAVE_2GPRS(9,r1)
ld r9,EX_R11(r3)
ld r10,EX_R12(r3)
ld r11,EX_R13(r3)
std r9,GPR11(r1)
std r10,GPR12(r1)
std r11,GPR13(r1)
SAVE_8GPRS(14,r1)
SAVE_10GPRS(22,r1) SAVE_10GPRS(22,r1)
lhz r12,PACA_TRAP_SAVE(r13) lhz r12,PACA_TRAP_SAVE(r13)
std r12,_TRAP(r1) std r12,_TRAP(r1)
...@@ -472,6 +483,9 @@ bad_stack: ...@@ -472,6 +483,9 @@ bad_stack:
li r12,0 li r12,0
std r12,0(r11) std r12,0(r11)
ld r2,PACATOC(r13) ld r2,PACATOC(r13)
ld r11,exception_marker@toc(r2)
std r12,RESULT(r1)
std r11,STACK_FRAME_OVERHEAD-16(r1)
1: addi r3,r1,STACK_FRAME_OVERHEAD 1: addi r3,r1,STACK_FRAME_OVERHEAD
bl .kernel_bad_stack bl .kernel_bad_stack
b 1b b 1b
......
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