1 /* SPDX-License-Identifier: GPL-2.0 */ << 2 /* 1 /* 3 * Copyright (C) 2000 Anton Blanchard (anton@l 2 * Copyright (C) 2000 Anton Blanchard (anton@linuxcare.com) 4 * 3 * 5 * This file implements mcount(), which is use 4 * This file implements mcount(), which is used to collect profiling data. 6 * This can also be tweaked for kernel stack o 5 * This can also be tweaked for kernel stack overflow detection. 7 */ 6 */ 8 7 9 #include <linux/export.h> << 10 #include <linux/linkage.h> 8 #include <linux/linkage.h> 11 9 >> 10 #include <asm/ptrace.h> >> 11 #include <asm/thread_info.h> >> 12 12 /* 13 /* 13 * This is the main variant and is called by C 14 * This is the main variant and is called by C code. GCC's -pg option 14 * automatically instruments every C function 15 * automatically instruments every C function with a call to this. 15 */ 16 */ 16 17 >> 18 #ifdef CONFIG_STACK_DEBUG >> 19 >> 20 #define OVSTACKSIZE 4096 /* lets hope this is enough */ >> 21 >> 22 .data >> 23 .align 8 >> 24 panicstring: >> 25 .asciz "Stack overflow\n" >> 26 .align 8 >> 27 ovstack: >> 28 .skip OVSTACKSIZE >> 29 #endif 17 .text 30 .text 18 .align 32 31 .align 32 19 .globl _mcount 32 .globl _mcount 20 .type _mcount,#function 33 .type _mcount,#function 21 EXPORT_SYMBOL(_mcount) << 22 .globl mcount 34 .globl mcount 23 .type mcount,#function 35 .type mcount,#function 24 _mcount: 36 _mcount: 25 mcount: 37 mcount: >> 38 #ifdef CONFIG_STACK_DEBUG >> 39 /* >> 40 * Check whether %sp is dangerously low. >> 41 */ >> 42 ldub [%g6 + TI_FPDEPTH], %g1 >> 43 srl %g1, 1, %g3 >> 44 add %g3, 1, %g3 >> 45 sllx %g3, 8, %g3 ! each fpregs frame is 256b >> 46 add %g3, 192, %g3 >> 47 add %g6, %g3, %g3 ! where does task_struct+frame end? >> 48 sub %g3, STACK_BIAS, %g3 >> 49 cmp %sp, %g3 >> 50 bg,pt %xcc, 1f >> 51 nop >> 52 lduh [%g6 + TI_CPU], %g1 >> 53 sethi %hi(hardirq_stack), %g3 >> 54 or %g3, %lo(hardirq_stack), %g3 >> 55 sllx %g1, 3, %g1 >> 56 ldx [%g3 + %g1], %g7 >> 57 sub %g7, STACK_BIAS, %g7 >> 58 cmp %sp, %g7 >> 59 bleu,pt %xcc, 2f >> 60 sethi %hi(THREAD_SIZE), %g3 >> 61 add %g7, %g3, %g7 >> 62 cmp %sp, %g7 >> 63 blu,pn %xcc, 1f >> 64 2: sethi %hi(softirq_stack), %g3 >> 65 or %g3, %lo(softirq_stack), %g3 >> 66 ldx [%g3 + %g1], %g7 >> 67 sub %g7, STACK_BIAS, %g7 >> 68 cmp %sp, %g7 >> 69 bleu,pt %xcc, 3f >> 70 sethi %hi(THREAD_SIZE), %g3 >> 71 add %g7, %g3, %g7 >> 72 cmp %sp, %g7 >> 73 blu,pn %xcc, 1f >> 74 nop >> 75 /* If we are already on ovstack, don't hop onto it >> 76 * again, we are already trying to output the stack overflow >> 77 * message. >> 78 */ >> 79 3: sethi %hi(ovstack), %g7 ! cant move to panic stack fast enough >> 80 or %g7, %lo(ovstack), %g7 >> 81 add %g7, OVSTACKSIZE, %g3 >> 82 sub %g3, STACK_BIAS + 192, %g3 >> 83 sub %g7, STACK_BIAS, %g7 >> 84 cmp %sp, %g7 >> 85 blu,pn %xcc, 2f >> 86 cmp %sp, %g3 >> 87 bleu,pn %xcc, 1f >> 88 nop >> 89 2: mov %g3, %sp >> 90 sethi %hi(panicstring), %g3 >> 91 call prom_printf >> 92 or %g3, %lo(panicstring), %o0 >> 93 call prom_halt >> 94 nop >> 95 1: >> 96 #endif 26 #ifdef CONFIG_FUNCTION_TRACER 97 #ifdef CONFIG_FUNCTION_TRACER 27 #ifdef CONFIG_DYNAMIC_FTRACE 98 #ifdef CONFIG_DYNAMIC_FTRACE 28 /* Do nothing, the retl/nop below is a !! 99 mov %o7, %o0 >> 100 .globl mcount_call >> 101 mcount_call: >> 102 call ftrace_stub >> 103 mov %o0, %o7 29 #else 104 #else 30 sethi %hi(ftrace_trace_funct 105 sethi %hi(ftrace_trace_function), %g1 31 sethi %hi(ftrace_stub), %g2 106 sethi %hi(ftrace_stub), %g2 32 ldx [%g1 + %lo(ftrace_trac 107 ldx [%g1 + %lo(ftrace_trace_function)], %g1 33 or %g2, %lo(ftrace_stub), 108 or %g2, %lo(ftrace_stub), %g2 34 cmp %g1, %g2 109 cmp %g1, %g2 35 be,pn %icc, 1f 110 be,pn %icc, 1f 36 mov %i7, %g3 !! 111 mov %i7, %o1 37 save %sp, -176, %sp !! 112 jmpl %g1, %g0 38 mov %g3, %o1 !! 113 mov %o7, %o0 39 jmpl %g1, %o7 << 40 mov %i7, %o0 << 41 ret << 42 restore << 43 /* not reached */ 114 /* not reached */ 44 1: 115 1: 45 #ifdef CONFIG_FUNCTION_GRAPH_TRACER << 46 sethi %hi(ftrace_graph_retur << 47 ldx [%g1 + %lo(ftrace_grap << 48 cmp %g2, %g3 << 49 bne,pn %xcc, 5f << 50 sethi %hi(ftrace_graph_entry << 51 sethi %hi(ftrace_graph_entry << 52 or %g2, %lo(ftrace_graph_ << 53 ldx [%g1 + %lo(ftrace_grap << 54 cmp %g1, %g2 << 55 be,pt %xcc, 2f << 56 nop << 57 5: mov %i7, %g2 << 58 mov %fp, %g3 << 59 save %sp, -176, %sp << 60 mov %g2, %l0 << 61 ba,pt %xcc, ftrace_graph_cal << 62 mov %g3, %l1 << 63 #endif << 64 2: << 65 #endif 116 #endif 66 #endif 117 #endif 67 retl 118 retl 68 nop 119 nop 69 .size _mcount,.-_mcount 120 .size _mcount,.-_mcount 70 .size mcount,.-mcount 121 .size mcount,.-mcount 71 122 72 #ifdef CONFIG_FUNCTION_TRACER 123 #ifdef CONFIG_FUNCTION_TRACER 73 .globl ftrace_stub 124 .globl ftrace_stub 74 .type ftrace_stub,#function 125 .type ftrace_stub,#function 75 ftrace_stub: 126 ftrace_stub: 76 retl 127 retl 77 nop 128 nop 78 .size ftrace_stub,.-ftrace_s 129 .size ftrace_stub,.-ftrace_stub 79 #ifdef CONFIG_DYNAMIC_FTRACE 130 #ifdef CONFIG_DYNAMIC_FTRACE 80 .globl ftrace_caller 131 .globl ftrace_caller 81 .type ftrace_caller,#functio 132 .type ftrace_caller,#function 82 ftrace_caller: 133 ftrace_caller: 83 mov %i7, %g2 !! 134 mov %i7, %o1 84 mov %fp, %g3 !! 135 mov %o7, %o0 85 save %sp, -176, %sp << 86 mov %g2, %o1 << 87 mov %g2, %l0 << 88 mov %g3, %l1 << 89 .globl ftrace_call 136 .globl ftrace_call 90 ftrace_call: 137 ftrace_call: 91 call ftrace_stub 138 call ftrace_stub 92 mov %i7, %o0 !! 139 mov %o0, %o7 93 #ifdef CONFIG_FUNCTION_GRAPH_TRACER !! 140 retl 94 .globl ftrace_graph_call << 95 ftrace_graph_call: << 96 call ftrace_stub << 97 nop 141 nop 98 #endif << 99 ret << 100 restore << 101 #ifdef CONFIG_FUNCTION_GRAPH_TRACER << 102 .size ftrace_graph_call,.-ft << 103 #endif << 104 .size ftrace_call,.-ftrace_c << 105 .size ftrace_caller,.-ftrace 142 .size ftrace_caller,.-ftrace_caller 106 #endif 143 #endif 107 #endif << 108 << 109 #ifdef CONFIG_FUNCTION_GRAPH_TRACER << 110 ENTRY(ftrace_graph_caller) << 111 mov %l0, %o0 << 112 mov %i7, %o1 << 113 call prepare_ftrace_return << 114 mov %l1, %o2 << 115 ret << 116 restore %o0, -8, %i7 << 117 END(ftrace_graph_caller) << 118 << 119 ENTRY(return_to_handler) << 120 save %sp, -176, %sp << 121 call ftrace_return_to_handl << 122 mov %fp, %o0 << 123 jmpl %o0 + 8, %g0 << 124 restore << 125 END(return_to_handler) << 126 #endif 144 #endif
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.