diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-12-31 04:23:31 +0300 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-12-31 04:23:31 +0300 |
commit | 6de71484cf9561edb45224f659a9db38b6056d5e (patch) | |
tree | 588fe6f7c98147b805085503c863d371e2fa497e /arch/sparc/lib/mcount.S | |
parent | 1dff81f20cd55ffa5a8ee984da70ce0b99d29606 (diff) | |
parent | e3c6d4ee545e427b55882d97d3b663c6411645fe (diff) | |
download | linux-6de71484cf9561edb45224f659a9db38b6056d5e.tar.xz |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-next-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-next-2.6: (98 commits)
sparc: move select of ARCH_SUPPORTS_MSI
sparc: drop SUN_IO
sparc: unify sections.h
sparc: use .data.init_task section for init_thread_union
sparc: fix array overrun check in of_device_64.c
sparc: unify module.c
sparc64: prepare module_64.c for unification
sparc64: use bit neutral Elf symbols
sparc: unify module.h
sparc: introduce CONFIG_BITS
sparc: fix hardirq.h removal fallout
sparc64: do not export pus_fs_struct
sparc: use sparc64 version of scatterlist.h
sparc: Commonize memcmp assembler.
sparc: Unify strlen assembler.
sparc: Add asm/asm.h
sparc: Kill memcmp_32.S code which has been ifdef'd out for centuries.
sparc: replace for_each_cpu_mask_nr with for_each_cpu
sparc: fix sparse warnings in irq_32.c
sparc: add include guards to kernel.h
...
Diffstat (limited to 'arch/sparc/lib/mcount.S')
-rw-r--r-- | arch/sparc/lib/mcount.S | 143 |
1 files changed, 143 insertions, 0 deletions
diff --git a/arch/sparc/lib/mcount.S b/arch/sparc/lib/mcount.S new file mode 100644 index 000000000000..7ce9c65f3592 --- /dev/null +++ b/arch/sparc/lib/mcount.S @@ -0,0 +1,143 @@ +/* + * 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 + lduh [%g6 + TI_CPU], %g1 + sethi %hi(hardirq_stack), %g3 + or %g3, %lo(hardirq_stack), %g3 + sllx %g1, 3, %g1 + ldx [%g3 + %g1], %g7 + sub %g7, STACK_BIAS, %g7 + cmp %sp, %g7 + bleu,pt %xcc, 2f + sethi %hi(THREAD_SIZE), %g3 + add %g7, %g3, %g7 + cmp %sp, %g7 + blu,pn %xcc, 1f +2: sethi %hi(softirq_stack), %g3 + or %g3, %lo(softirq_stack), %g3 + ldx [%g3 + %g1], %g7 + cmp %sp, %g7 + bleu,pt %xcc, 2f + sethi %hi(THREAD_SIZE), %g3 + add %g7, %g3, %g7 + cmp %sp, %g7 + blu,pn %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_FUNCTION_TRACER +#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_FUNCTION_TRACER + .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 |