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.le...@c-s.fr>
---
 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

Reply via email to