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