diff options
author | Nicholas Piggin <npiggin@gmail.com> | 2018-04-08 16:49:38 +1000 |
---|---|---|
committer | Stewart Smith <stewart@linux.ibm.com> | 2018-04-18 20:23:07 -0500 |
commit | 3fdd2629516dd8be2b52a3a13e7ef5713411c7bf (patch) | |
tree | 5001a42b2b3d17fa03500ca97849c658715a1c6e /asm | |
parent | 8514e4dc9a82f3ff85d40138f2c8e8a1dc64efa4 (diff) | |
download | skiboot-3fdd2629516dd8be2b52a3a13e7ef5713411c7bf.zip skiboot-3fdd2629516dd8be2b52a3a13e7ef5713411c7bf.tar.gz skiboot-3fdd2629516dd8be2b52a3a13e7ef5713411c7bf.tar.bz2 |
core/opal: Emergency stack for re-entry
This detects OPAL being re-entered by the OS, and switches to an
emergency stack if it was. This protects the firmware's main stack
from re-entrancy and allows the OS to use NMI facilities for crash
/ debug functionality.
Further nested re-entry will destroy the previous emergency stack
and prevent returning, but those should be rare cases.
This stack is sized at 16kB, which doubles the size of CPU stacks,
so as not to introduce a regression in primary stack size. The 16kB
stack originally had a 4kB machine check stack at the top, which was
removed by 80eee1946 ("opal: Remove machine check interrupt patching
in OPAL."). So it is possible the size could be tightened again, but
that would require further analysis.
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
Signed-off-by: Stewart Smith <stewart@linux.ibm.com>
Diffstat (limited to 'asm')
-rw-r--r-- | asm/head.S | 22 |
1 files changed, 18 insertions, 4 deletions
@@ -30,12 +30,17 @@ #define PPC_INST_STOP .long 0x4c0002e4 -#define GET_STACK(stack_reg,pir_reg) \ - sldi stack_reg,pir_reg,STACK_SHIFT; \ - addis stack_reg,stack_reg,CPU_STACKS_OFFSET@ha; \ +#define GET_STACK(stack_reg,pir_reg) \ + sldi stack_reg,pir_reg,STACK_SHIFT; \ + addis stack_reg,stack_reg,CPU_STACKS_OFFSET@ha; \ addi stack_reg,stack_reg,CPU_STACKS_OFFSET@l; -#define GET_CPU() \ +#define GET_EMERGENCY_STACK(stack_reg,pir_reg) \ + sldi stack_reg,pir_reg,STACK_SHIFT; \ + addis stack_reg,stack_reg,EMERGENCY_CPU_STACKS_OFFSET@ha; \ + addi stack_reg,stack_reg,EMERGENCY_CPU_STACKS_OFFSET@l; + +#define GET_CPU() \ clrrdi %r13,%r1,STACK_SHIFT #define SAVE_GPR(reg,sp) std %r##reg,STACK_GPR##reg(sp) @@ -1013,8 +1018,17 @@ opal_entry: b 1b 4: /* Quiesce protocol done, get our per CPU stack */ + /* Emergency stack if we have re-entered OPAL */ + lwz %r11,CPUTHREAD_IN_OPAL_CALL(%r12) + cmpwi %r11,1 + mfspr %r12,SPR_PIR + beq 5f GET_STACK(%r12,%r12) + b 6f +5: + GET_EMERGENCY_STACK(%r12,%r12) +6: stdu %r12,-STACK_FRAMESIZE(%r12) /* Save caller r1, establish new r1 */ |