1 /* SPDX-License-Identifier: GPL-2.0 */ << 2 /* 1 /* 3 * LoongArch specific _mcount support !! 2 * MIPS specific _mcount support 4 * 3 * 5 * Copyright (C) 2022 Loongson Technology Corp !! 4 * This file is subject to the terms and conditions of the GNU General Public >> 5 * License. See the file "COPYING" in the main directory of this archive for >> 6 * more details. >> 7 * >> 8 * Copyright (C) 2009 Lemote Inc. & DSLab, Lanzhou University, China >> 9 * Copyright (C) 2010 DSLab, Lanzhou University, China >> 10 * Author: Wu Zhangjin <wuzhangjin@gmail.com> 6 */ 11 */ 7 12 8 #include <linux/export.h> !! 13 #include <asm/export.h> 9 #include <asm/ftrace.h> << 10 #include <asm/regdef.h> 14 #include <asm/regdef.h> 11 #include <asm/stackframe.h> 15 #include <asm/stackframe.h> >> 16 #include <asm/ftrace.h> 12 17 13 .text 18 .text 14 !! 19 .set noreorder 15 #define MCOUNT_S0_OFFSET (0) !! 20 .set noat 16 #define MCOUNT_RA_OFFSET (SZREG) << 17 #define MCOUNT_STACK_SIZE (2 * SZREG) << 18 21 19 .macro MCOUNT_SAVE_REGS 22 .macro MCOUNT_SAVE_REGS 20 PTR_ADDI sp, sp, -MCOUNT_STACK_ !! 23 PTR_SUBU sp, PT_SIZE 21 PTR_S s0, sp, MCOUNT_S0_OFFS !! 24 PTR_S ra, PT_R31(sp) 22 PTR_S ra, sp, MCOUNT_RA_OFFS !! 25 PTR_S AT, PT_R1(sp) 23 move s0, a0 !! 26 PTR_S a0, PT_R4(sp) >> 27 PTR_S a1, PT_R5(sp) >> 28 PTR_S a2, PT_R6(sp) >> 29 PTR_S a3, PT_R7(sp) >> 30 #ifdef CONFIG_64BIT >> 31 PTR_S a4, PT_R8(sp) >> 32 PTR_S a5, PT_R9(sp) >> 33 PTR_S a6, PT_R10(sp) >> 34 PTR_S a7, PT_R11(sp) >> 35 #endif 24 .endm 36 .endm 25 37 26 .macro MCOUNT_RESTORE_REGS 38 .macro MCOUNT_RESTORE_REGS 27 move a0, s0 !! 39 PTR_L ra, PT_R31(sp) 28 PTR_L ra, sp, MCOUNT_RA_OFFS !! 40 PTR_L AT, PT_R1(sp) 29 PTR_L s0, sp, MCOUNT_S0_OFFS !! 41 PTR_L a0, PT_R4(sp) 30 PTR_ADDI sp, sp, MCOUNT_STACK_S !! 42 PTR_L a1, PT_R5(sp) >> 43 PTR_L a2, PT_R6(sp) >> 44 PTR_L a3, PT_R7(sp) >> 45 #ifdef CONFIG_64BIT >> 46 PTR_L a4, PT_R8(sp) >> 47 PTR_L a5, PT_R9(sp) >> 48 PTR_L a6, PT_R10(sp) >> 49 PTR_L a7, PT_R11(sp) >> 50 #endif >> 51 PTR_ADDIU sp, PT_SIZE 31 .endm 52 .endm 32 53 33 SYM_FUNC_START(_mcount) !! 54 .macro RETURN_BACK 34 la.pcrel t1, ftrace_stub !! 55 jr ra 35 la.pcrel t2, ftrace_trace_funct !! 56 move ra, AT 36 PTR_L t2, t2, 0 !! 57 .endm 37 beq t1, t2, fgraph_trace << 38 58 39 MCOUNT_SAVE_REGS !! 59 /* >> 60 * The -mmcount-ra-address option of gcc 4.5 uses register $12 to pass >> 61 * the location of the parent's return address. >> 62 */ >> 63 #define MCOUNT_RA_ADDRESS_REG $12 40 64 41 move a0, ra !! 65 #ifdef CONFIG_DYNAMIC_FTRACE 42 move a1, s0 << 43 jirl ra, t2, 0 << 44 66 45 MCOUNT_RESTORE_REGS !! 67 NESTED(ftrace_caller, PT_SIZE, ra) >> 68 .globl _mcount >> 69 _mcount: >> 70 EXPORT_SYMBOL(_mcount) >> 71 b ftrace_stub >> 72 #ifdef CONFIG_32BIT >> 73 addiu sp,sp,8 >> 74 #else >> 75 nop >> 76 #endif 46 77 47 fgraph_trace: !! 78 /* When tracing is activated, it calls ftrace_caller+8 (aka here) */ 48 #ifdef CONFIG_FUNCTION_GRAPH_TRACER !! 79 MCOUNT_SAVE_REGS 49 la.pcrel t1, ftrace_stub !! 80 #ifdef KBUILD_MCOUNT_RA_ADDRESS 50 la.pcrel t3, ftrace_graph_retur !! 81 PTR_S MCOUNT_RA_ADDRESS_REG, PT_R12(sp) 51 PTR_L t3, t3, 0 !! 82 #endif 52 bne t1, t3, ftrace_graph_c !! 83 53 la.pcrel t1, ftrace_graph_entry !! 84 PTR_SUBU a0, ra, 8 /* arg1: self address */ 54 la.pcrel t3, ftrace_graph_entry !! 85 PTR_LA t1, _stext 55 PTR_L t3, t3, 0 !! 86 sltu t2, a0, t1 /* t2 = (a0 < _stext) */ 56 bne t1, t3, ftrace_graph_c !! 87 PTR_LA t1, _etext >> 88 sltu t3, t1, a0 /* t3 = (a0 > _etext) */ >> 89 or t1, t2, t3 >> 90 beqz t1, ftrace_call >> 91 nop >> 92 #if defined(KBUILD_MCOUNT_RA_ADDRESS) && defined(CONFIG_32BIT) >> 93 PTR_SUBU a0, a0, 16 /* arg1: adjust to module's recorded callsite */ >> 94 #else >> 95 PTR_SUBU a0, a0, 12 57 #endif 96 #endif 58 97 59 SYM_INNER_LABEL(ftrace_stub, SYM_L_GLOBAL) !! 98 .globl ftrace_call 60 jr ra !! 99 ftrace_call: >> 100 nop /* a placeholder for the call to a real tracing function */ >> 101 move a1, AT /* arg2: parent's return address */ >> 102 61 #ifdef CONFIG_FUNCTION_GRAPH_TRACER 103 #ifdef CONFIG_FUNCTION_GRAPH_TRACER 62 SYM_INNER_LABEL(ftrace_graph_func, SYM_L_GLOBA !! 104 .globl ftrace_graph_call 63 bl ftrace_stub !! 105 ftrace_graph_call: >> 106 nop >> 107 nop 64 #endif 108 #endif 65 SYM_FUNC_END(_mcount) !! 109 >> 110 MCOUNT_RESTORE_REGS >> 111 .globl ftrace_stub >> 112 ftrace_stub: >> 113 RETURN_BACK >> 114 END(ftrace_caller) >> 115 >> 116 #else /* ! CONFIG_DYNAMIC_FTRACE */ >> 117 >> 118 NESTED(_mcount, PT_SIZE, ra) 66 EXPORT_SYMBOL(_mcount) 119 EXPORT_SYMBOL(_mcount) >> 120 PTR_LA t1, ftrace_stub >> 121 PTR_L t2, ftrace_trace_function /* Prepare t2 for (1) */ >> 122 bne t1, t2, static_trace >> 123 nop >> 124 >> 125 #ifdef CONFIG_FUNCTION_GRAPH_TRACER >> 126 PTR_L t3, ftrace_graph_return >> 127 bne t1, t3, ftrace_graph_caller >> 128 nop >> 129 PTR_LA t1, ftrace_graph_entry_stub >> 130 PTR_L t3, ftrace_graph_entry >> 131 bne t1, t3, ftrace_graph_caller >> 132 nop >> 133 #endif >> 134 b ftrace_stub >> 135 #ifdef CONFIG_32BIT >> 136 addiu sp, sp, 8 >> 137 #else >> 138 nop >> 139 #endif >> 140 >> 141 static_trace: >> 142 MCOUNT_SAVE_REGS >> 143 >> 144 move a0, ra /* arg1: self return address */ >> 145 jalr t2 /* (1) call *ftrace_trace_function */ >> 146 move a1, AT /* arg2: parent's return address */ >> 147 >> 148 MCOUNT_RESTORE_REGS >> 149 #ifdef CONFIG_32BIT >> 150 addiu sp, sp, 8 >> 151 #endif >> 152 .globl ftrace_stub >> 153 ftrace_stub: >> 154 RETURN_BACK >> 155 END(_mcount) >> 156 >> 157 #endif /* ! CONFIG_DYNAMIC_FTRACE */ 67 158 68 #ifdef CONFIG_FUNCTION_GRAPH_TRACER 159 #ifdef CONFIG_FUNCTION_GRAPH_TRACER 69 SYM_FUNC_START(ftrace_graph_caller) !! 160 >> 161 NESTED(ftrace_graph_caller, PT_SIZE, ra) >> 162 #ifndef CONFIG_DYNAMIC_FTRACE 70 MCOUNT_SAVE_REGS 163 MCOUNT_SAVE_REGS >> 164 #endif >> 165 >> 166 /* arg1: Get the location of the parent's return address */ >> 167 #ifdef KBUILD_MCOUNT_RA_ADDRESS >> 168 #ifdef CONFIG_DYNAMIC_FTRACE >> 169 PTR_L a0, PT_R12(sp) >> 170 #else >> 171 move a0, MCOUNT_RA_ADDRESS_REG >> 172 #endif >> 173 bnez a0, 1f /* non-leaf func: stored in MCOUNT_RA_ADDRESS_REG */ >> 174 nop >> 175 #endif >> 176 PTR_LA a0, PT_R1(sp) /* leaf func: the location in current stack */ >> 177 1: >> 178 >> 179 /* arg2: Get self return address */ >> 180 #ifdef CONFIG_DYNAMIC_FTRACE >> 181 PTR_L a1, PT_R31(sp) >> 182 #else >> 183 move a1, ra >> 184 #endif 71 185 72 PTR_ADDI a0, ra, -4 !! 186 /* arg3: Get frame pointer of current stack */ 73 PTR_ADDI a1, sp, MCOUNT_STACK_S !! 187 #ifdef CONFIG_64BIT 74 move a2, s0 !! 188 PTR_LA a2, PT_SIZE(sp) 75 bl prepare_ftrace_return !! 189 #else >> 190 PTR_LA a2, (PT_SIZE+8)(sp) >> 191 #endif 76 192 >> 193 jal prepare_ftrace_return >> 194 nop 77 MCOUNT_RESTORE_REGS 195 MCOUNT_RESTORE_REGS 78 jr ra !! 196 #ifndef CONFIG_DYNAMIC_FTRACE 79 SYM_FUNC_END(ftrace_graph_caller) !! 197 #ifdef CONFIG_32BIT >> 198 addiu sp, sp, 8 >> 199 #endif >> 200 #endif >> 201 RETURN_BACK >> 202 END(ftrace_graph_caller) 80 203 81 SYM_FUNC_START(return_to_handler) !! 204 .align 2 82 PTR_ADDI sp, sp, -FGRET_REGS_SI !! 205 .globl return_to_handler 83 PTR_S a0, sp, FGRET_REGS_A0 !! 206 return_to_handler: 84 PTR_S a1, sp, FGRET_REGS_A1 !! 207 PTR_SUBU sp, PT_SIZE 85 PTR_S zero, sp, FGRET_REGS_F !! 208 PTR_S v0, PT_R2(sp) 86 !! 209 87 move a0, sp !! 210 jal ftrace_return_to_handler 88 bl ftrace_return_to_handl !! 211 PTR_S v1, PT_R3(sp) 89 !! 212 90 /* Restore the real parent address: a0 !! 213 /* restore the real parent address: v0 -> ra */ 91 move ra, a0 !! 214 move ra, v0 92 !! 215 93 PTR_L a0, sp, FGRET_REGS_A0 !! 216 PTR_L v0, PT_R2(sp) 94 PTR_L a1, sp, FGRET_REGS_A1 !! 217 PTR_L v1, PT_R3(sp) 95 PTR_ADDI sp, sp, FGRET_REGS_SIZ !! 218 jr ra 96 jr ra !! 219 PTR_ADDIU sp, PT_SIZE 97 SYM_FUNC_END(return_to_handler) << 98 #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ 220 #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ >> 221 >> 222 .set at >> 223 .set reorder
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.