linux/arch/sparc64/lib/mcount.S
David S. Miller c7498081a6 sparc64: Fix recursion in stack overflow detection handling.
The calls down into prom_printf() when we detect an overflowed stack
can recurse again since the overflow stack will be "below" the current
kernel stack limit.

Prevent this by just returning straight if we are on the stack
overflow safe stack already.

Signed-off-by: David S. Miller <davem@davemloft.net>
2008-08-12 02:03:49 -07:00

122 lines
2.4 KiB
ArmAsm

/*
* Copyright (C) 2000 Anton Blanchard (anton@linuxcare.com)
*
* This file implements mcount(), which is used to collect profiling data.
* This can also be tweaked for kernel stack overflow detection.
*/
#include <linux/linkage.h>
#include <asm/ptrace.h>
#include <asm/thread_info.h>
/*
* This is the main variant and is called by C code. GCC's -pg option
* automatically instruments every C function with a call to this.
*/
#ifdef CONFIG_STACK_DEBUG
#define OVSTACKSIZE 4096 /* lets hope this is enough */
.data
.align 8
panicstring:
.asciz "Stack overflow\n"
.align 8
ovstack:
.skip OVSTACKSIZE
#endif
.text
.align 32
.globl _mcount
.type _mcount,#function
.globl mcount
.type mcount,#function
_mcount:
mcount:
#ifdef CONFIG_STACK_DEBUG
/*
* Check whether %sp is dangerously low.
*/
ldub [%g6 + TI_FPDEPTH], %g1
srl %g1, 1, %g3
add %g3, 1, %g3
sllx %g3, 8, %g3 ! each fpregs frame is 256b
add %g3, 192, %g3
add %g6, %g3, %g3 ! where does task_struct+frame end?
sub %g3, STACK_BIAS, %g3
cmp %sp, %g3
bg,pt %xcc, 1f
nop
/* If we are already on ovstack, don't hop onto it
* again, we are already trying to output the stack overflow
* message.
*/
sethi %hi(ovstack), %g7 ! cant move to panic stack fast enough
or %g7, %lo(ovstack), %g7
add %g7, OVSTACKSIZE, %g3
sub %g3, STACK_BIAS + 192, %g3
sub %g7, STACK_BIAS, %g7
cmp %sp, %g7
blu,pn %xcc, 2f
cmp %sp, %g3
bleu,pn %xcc, 1f
nop
2: mov %g3, %sp
sethi %hi(panicstring), %g3
call prom_printf
or %g3, %lo(panicstring), %o0
call prom_halt
nop
1:
#endif
#ifdef CONFIG_FTRACE
#ifdef CONFIG_DYNAMIC_FTRACE
mov %o7, %o0
.globl mcount_call
mcount_call:
call ftrace_stub
mov %o0, %o7
#else
sethi %hi(ftrace_trace_function), %g1
sethi %hi(ftrace_stub), %g2
ldx [%g1 + %lo(ftrace_trace_function)], %g1
or %g2, %lo(ftrace_stub), %g2
cmp %g1, %g2
be,pn %icc, 1f
mov %i7, %o1
jmpl %g1, %g0
mov %o7, %o0
/* not reached */
1:
#endif
#endif
retl
nop
.size _mcount,.-_mcount
.size mcount,.-mcount
#ifdef CONFIG_FTRACE
.globl ftrace_stub
.type ftrace_stub,#function
ftrace_stub:
retl
nop
.size ftrace_stub,.-ftrace_stub
#ifdef CONFIG_DYNAMIC_FTRACE
.globl ftrace_caller
.type ftrace_caller,#function
ftrace_caller:
mov %i7, %o1
mov %o7, %o0
.globl ftrace_call
ftrace_call:
call ftrace_stub
mov %o0, %o7
retl
nop
.size ftrace_caller,.-ftrace_caller
#endif
#endif