.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
__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)