[RFC PATCH v2 10/10] powerpc/32: Add stack overflow detection with VMAP stack.

From: Christophe Leroy
Date: Sat Aug 31 2019 - 06:18:46 EST


To avoid recursive faults, stack overflow detection has to be
performed before writing in the stack in exception prologs.

Do it by checking the alignment. If the stack pointer alignment is
wrong, it means it is pointing to the following or preceding page.

Signed-off-by: Christophe Leroy <christophe.leroy@xxxxxx>
---
arch/powerpc/kernel/entry_32.S | 12 ++++++++++++
arch/powerpc/kernel/head_32.h | 5 ++++-
arch/powerpc/kernel/head_8xx.S | 3 +++
3 files changed, 19 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S
index ef296572a513..68e03feb4bd1 100644
--- a/arch/powerpc/kernel/entry_32.S
+++ b/arch/powerpc/kernel/entry_32.S
@@ -184,9 +184,11 @@ transfer_to_handler:
*/
kuap_save_and_lock r11, r12, r9, r2, r0
addi r2, r12, -THREAD
+#ifndef CONFIG_VMAP_STACK
lwz r9,KSP_LIMIT(r12)
cmplw r1,r9 /* if r1 <= ksp_limit */
ble- stack_ovf /* then the kernel stack overflowed */
+#endif
5:
#if defined(CONFIG_PPC_BOOK3S_32) || defined(CONFIG_E500)
lwz r12,TI_LOCAL_FLAGS(r2)
@@ -298,6 +300,15 @@ reenable_mmu:
* On kernel stack overflow, load up an initial stack pointer
* and call StackOverflow(regs), which should not return.
*/
+#ifdef CONFIG_VMAP_STACK
+_GLOBAL(stack_ovf)
+ lis r11, init_thread_union + THREAD_SIZE - INT_FRAME_SIZE@ha
+ addi r11, r11, init_thread_union + THREAD_SIZE - INT_FRAME_SIZE@l
+ EXCEPTION_PROLOG_2
+ SAVE_NVGPRS(r11)
+ addi r3, r1, STACK_FRAME_OVERHEAD
+ EXC_XFER_STD(0, StackOverflow)
+#else
stack_ovf:
/* sometimes we use a statically-allocated stack, which is OK. */
lis r12,_end@h
@@ -319,6 +330,7 @@ stack_ovf:
mtspr SPRN_SRR1,r10
SYNC
RFI
+#endif

#ifdef CONFIG_TRACE_IRQFLAGS
trace_syscall_entry_irq_off:
diff --git a/arch/powerpc/kernel/head_32.h b/arch/powerpc/kernel/head_32.h
index 4980babde59e..d442625d9649 100644
--- a/arch/powerpc/kernel/head_32.h
+++ b/arch/powerpc/kernel/head_32.h
@@ -51,7 +51,10 @@
#endif
lwz r11,TASK_STACK-THREAD(r11)
addi r11, r11, THREAD_SIZE - INT_FRAME_SIZE
-#ifndef CONFIG_VMAP_STACK
+#ifdef CONFIG_VMAP_STACK
+ mtcrf 0xfe, r11
+ bt 32 - THREAD_ALIGN_SHIFT, stack_ovf_trampoline
+#else
tophys(r11,r11)
#endif
1:
diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S
index dfd68b72688e..b9c9cfd72b19 100644
--- a/arch/powerpc/kernel/head_8xx.S
+++ b/arch/powerpc/kernel/head_8xx.S
@@ -572,6 +572,9 @@ InstructionBreakpoint:
EXCEPTION(0x1e00, Trap_1e, unknown_exception, EXC_XFER_STD)
EXCEPTION(0x1f00, Trap_1f, unknown_exception, EXC_XFER_STD)

+stack_ovf_trampoline:
+ b stack_ovf
+
. = 0x2000

/* This is the procedure to calculate the data EA for buggy dcbx,dcbi instructions
--
2.13.3