aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorNicholas Piggin <npiggin@gmail.com>2018-04-08 16:49:38 +1000
committerStewart Smith <stewart@linux.ibm.com>2018-04-18 20:23:07 -0500
commit3fdd2629516dd8be2b52a3a13e7ef5713411c7bf (patch)
tree5001a42b2b3d17fa03500ca97849c658715a1c6e /include
parent8514e4dc9a82f3ff85d40138f2c8e8a1dc64efa4 (diff)
downloadskiboot-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 'include')
-rw-r--r--include/cpu.h1
-rw-r--r--include/mem-map.h10
-rw-r--r--include/stack.h9
3 files changed, 15 insertions, 5 deletions
diff --git a/include/cpu.h b/include/cpu.h
index 4a6bc4a..2ca59b9 100644
--- a/include/cpu.h
+++ b/include/cpu.h
@@ -310,6 +310,7 @@ static inline void cpu_give_self_os(void)
extern unsigned long __attrconst cpu_stack_bottom(unsigned int pir);
extern unsigned long __attrconst cpu_stack_top(unsigned int pir);
+extern unsigned long __attrconst cpu_emergency_stack_top(unsigned int pir);
extern void cpu_idle_job(void);
extern void cpu_idle_delay(unsigned long delay);
diff --git a/include/mem-map.h b/include/mem-map.h
index d2bc23f..3e30d9b 100644
--- a/include/mem-map.h
+++ b/include/mem-map.h
@@ -23,10 +23,10 @@
*/
#define SKIBOOT_BASE 0x30000000
-/* Stack size set to 16K, some of it will be used for
- * machine check (see stack.h)
+/* Stack size set to 32K, 16K for general stack and 16K for an emergency
+ * stack.
*/
-#define STACK_SHIFT 14
+#define STACK_SHIFT 15
#define STACK_SIZE (1 << STACK_SHIFT)
/* End of the exception region we copy from 0x0. 0x0-0x100 will have
@@ -109,7 +109,9 @@
* each stack is STACK_SIZE in size (naturally aligned power of
* two) and the bottom of the stack contains the cpu thread
* structure for the processor, so it can be obtained by a simple
- * bit mask from the stack pointer.
+ * bit mask from the stack pointer. Within the CPU stack is divided
+ * into a normal and emergency stack to cope with a single level of
+ * re-entrancy.
*
* The size of this array is dynamically determined at boot time
*/
diff --git a/include/stack.h b/include/stack.h
index 4d3e504..a41a4a9 100644
--- a/include/stack.h
+++ b/include/stack.h
@@ -28,12 +28,19 @@
#define STACK_TOP_GAP 0x100
/* Remaining stack space (gap included) */
-#define NORMAL_STACK_SIZE STACK_SIZE
+#define NORMAL_STACK_SIZE (STACK_SIZE/2)
+
+/* Emergency (re-entry) stack size */
+#define EMERGENCY_STACK_SIZE (STACK_SIZE/2)
/* Offset to get to normal CPU stacks */
#define CPU_STACKS_OFFSET (CPU_STACKS_BASE + \
NORMAL_STACK_SIZE - STACK_TOP_GAP)
+/* Offset to get to emergency CPU stacks */
+#define EMERGENCY_CPU_STACKS_OFFSET (CPU_STACKS_BASE + NORMAL_STACK_SIZE + \
+ EMERGENCY_STACK_SIZE - STACK_TOP_GAP)
+
/* Gap below the stack. If our stack checker sees the stack below that
* gap, it will flag a stack overflow
*/