From 59eb4404a680cdd833b3e7a573f43fced916f571 Mon Sep 17 00:00:00 2001 From: Marc Fiuczynski Date: Fri, 17 Dec 2004 20:41:32 +0000 Subject: [PATCH] Updated stack overflow handling support. --- arch/i386/kernel/entry.S | 51 ++++++++++++++++---------------------- arch/i386/kernel/process.c | 24 ++++++++++++------ 2 files changed, 38 insertions(+), 37 deletions(-) diff --git a/arch/i386/kernel/entry.S b/arch/i386/kernel/entry.S index 4ca841e0a..dfbade1b9 100644 --- a/arch/i386/kernel/entry.S +++ b/arch/i386/kernel/entry.S @@ -1043,48 +1043,41 @@ stack_overflowed: .text ENTRY(mcount) +#warning stack check enabled push %eax movl $(THREAD_SIZE - 1),%eax andl %esp,%eax - cmpl $STACK_WARN,%eax /* more than half the stack is used*/ + cmpl $STACK_WARN,%eax jle 1f 2: popl %eax ret 1: + /* prevent infinite recursion from call to mcount from the + * stack_overflow function. Need to revisit this code for + * SMP based systems. + */ lock; btsl $0,stack_overflowed jc 2b - # switch to overflow stack - movl %esp,%eax - movl $(stack_overflow_stack + THREAD_SIZE - 4),%esp + /* prepare to jmp to stack_overflow directly, as if it were + * called directly by the caller of mcount. + */ + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi - pushf - cli - pushl %eax - - # push eip then esp of error for stack_overflow_panic - pushl 4(%eax) - pushl %eax - - # update the task pointer and cpu in the overflow stack's thread_info. - GET_THREAD_INFO_WITH_ESP(%eax) - movl TI_task(%eax),%ebx - movl %ebx,stack_overflow_stack+TI_task - movl TI_cpu(%eax),%ebx - movl %ebx,stack_overflow_stack+TI_cpu - call stack_overflow + /* Note that stack_overflow() will clear the stack_overflowed + * variable. + */ - # pop off call arguments - addl $8,%esp - - popl %eax - popf - movl %eax,%esp - popl %eax - movl $0,stack_overflowed + popl %edi + popl %esi + popl %ebx + popl %ebp + + popl %eax ret - -#warning stack check enabled #endif diff --git a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c index 51c17cc52..e8a01f2b5 100644 --- a/arch/i386/kernel/process.c +++ b/arch/i386/kernel/process.c @@ -219,22 +219,30 @@ static int __init idle_setup (char *str) __setup("idle=", idle_setup); -void stack_overflow(unsigned long esp, unsigned long eip) +void stack_overflow(void) { + extern unsigned long stack_overflowed; + unsigned long esp = current_stack_pointer(); int panicing = ((esp&(THREAD_SIZE-1)) <= STACK_PANIC); + oops_in_progress = 1; printk( "esp: 0x%lx masked: 0x%lx STACK_PANIC:0x%lx %d %d\n", - esp, (esp&(THREAD_SIZE-1)), STACK_PANIC, (((esp&(THREAD_SIZE-1)) <= STACK_PANIC)), panicing ); - - if (panicing) - print_symbol("stack overflow from %s\n", eip); - else - print_symbol("excessive stack use from %s\n", eip); - printk("esp: %p\n", (void*)esp); + esp, (esp&(THREAD_SIZE-1)), STACK_PANIC, + (((esp&(THREAD_SIZE-1)) <= STACK_PANIC)), panicing); show_trace(current,(void*)esp); if (panicing) panic("stack overflow\n"); + + oops_in_progress = 0; + + /* Just let it happen once per task, as otherwise it goes nuts + * in printing stack traces. This means that I need to dump + * the stack_overflowed boolean into the task or thread_info + * structure. For now just turn it off all together. + */ + + /* stack_overflowed = 0; */ } void show_regs(struct pt_regs * regs) -- 2.47.0