As we are going to switch to IRQ stack immediately in the exception handler, it won't be possible anymore to check stack overflow by reading stack pointer.
Do the verification on regs->gpr[1] which contains the stack pointer at the time the IRQ happended, and move it to __do_irq() so that the verification is also done when calling __do_irq() directly once the exception entry does the stack switch. Signed-off-by: Christophe Leroy <christophe.le...@c-s.fr> --- arch/powerpc/kernel/irq.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c index 28414c6665cc..4df49f6e9987 100644 --- a/arch/powerpc/kernel/irq.c +++ b/arch/powerpc/kernel/irq.c @@ -596,15 +596,16 @@ u64 arch_irq_stat_cpu(unsigned int cpu) return sum; } -static inline void check_stack_overflow(void) +static inline void check_stack_overflow(struct pt_regs *regs) { #ifdef CONFIG_DEBUG_STACKOVERFLOW + bool is_user = user_mode(regs); long sp; - sp = current_stack_pointer() & (THREAD_SIZE-1); + sp = regs->gpr[1] & (THREAD_SIZE - 1); /* check for stack overflow: is there less than 2KB free? */ - if (unlikely(sp < 2048)) { + if (unlikely(!is_user && sp < 2048)) { pr_err("do_IRQ: stack overflow: %ld\n", sp); dump_stack(); } @@ -654,6 +655,8 @@ void __do_irq(struct pt_regs *regs) trace_irq_entry(regs); + check_stack_overflow(regs); + /* * Query the platform PIC for the interrupt & ack it. * @@ -685,8 +688,6 @@ void do_IRQ(struct pt_regs *regs) irqsp = hardirq_ctx[raw_smp_processor_id()]; sirqsp = softirq_ctx[raw_smp_processor_id()]; - check_stack_overflow(); - /* Already there ? Otherwise switch stack and call */ if (unlikely(cursp == irqsp || cursp == sirqsp)) __do_irq(regs); -- 2.13.3