Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 | /* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (C) 2017 Andes Technology Corporation */ #include <linux/init.h> #include <linux/linkage.h> #include <asm/asm.h> #include <asm/csr.h> #include <asm/unistd.h> #include <asm/thread_info.h> #include <asm/asm-offsets.h> #include <asm-generic/export.h> #include <asm/ftrace.h> .text .macro SAVE_ABI_STATE #ifdef CONFIG_FUNCTION_GRAPH_TRACER addi sp, sp, -48 sd s0, 32(sp) sd ra, 40(sp) addi s0, sp, 48 sd t0, 24(sp) sd t1, 16(sp) #ifdef HAVE_FUNCTION_GRAPH_FP_TEST sd t2, 8(sp) #endif #else addi sp, sp, -16 sd s0, 0(sp) sd ra, 8(sp) addi s0, sp, 16 #endif .endm .macro RESTORE_ABI_STATE #ifdef CONFIG_FUNCTION_GRAPH_TRACER ld s0, 32(sp) ld ra, 40(sp) addi sp, sp, 48 #else ld ra, 8(sp) ld s0, 0(sp) addi sp, sp, 16 #endif .endm .macro RESTORE_GRAPH_ARGS ld a0, 24(sp) ld a1, 16(sp) #ifdef HAVE_FUNCTION_GRAPH_FP_TEST ld a2, 8(sp) #endif .endm ENTRY(ftrace_graph_caller) addi sp, sp, -16 sd s0, 0(sp) sd ra, 8(sp) addi s0, sp, 16 ftrace_graph_call: .global ftrace_graph_call /* * Calling ftrace_enable/disable_ftrace_graph_caller would overwrite the * call below. Check ftrace_modify_all_code for details. */ call ftrace_stub ld ra, 8(sp) ld s0, 0(sp) addi sp, sp, 16 ret ENDPROC(ftrace_graph_caller) ENTRY(ftrace_caller) /* * a0: the address in the caller when calling ftrace_caller * a1: the caller's return address * a2: the address of global variable function_trace_op */ ld a1, -8(s0) addi a0, ra, -MCOUNT_INSN_SIZE la t5, function_trace_op ld a2, 0(t5) #ifdef CONFIG_FUNCTION_GRAPH_TRACER /* * the graph tracer (specifically, prepare_ftrace_return) needs these * arguments but for now the function tracer occupies the regs, so we * save them in temporary regs to recover later. */ addi t0, s0, -8 mv t1, a0 #ifdef HAVE_FUNCTION_GRAPH_FP_TEST ld t2, -16(s0) #endif #endif SAVE_ABI_STATE ftrace_call: .global ftrace_call /* * For the dynamic ftrace to work, here we should reserve at least * 8 bytes for a functional auipc-jalr pair. The following call * serves this purpose. * * Calling ftrace_update_ftrace_func would overwrite the nops below. * Check ftrace_modify_all_code for details. */ call ftrace_stub #ifdef CONFIG_FUNCTION_GRAPH_TRACER RESTORE_GRAPH_ARGS call ftrace_graph_caller #endif RESTORE_ABI_STATE ret ENDPROC(ftrace_caller) #ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS .macro SAVE_ALL addi sp, sp, -(PT_SIZE_ON_STACK+16) sd s0, (PT_SIZE_ON_STACK)(sp) sd ra, (PT_SIZE_ON_STACK+8)(sp) addi s0, sp, (PT_SIZE_ON_STACK+16) sd x1, PT_RA(sp) sd x2, PT_SP(sp) sd x3, PT_GP(sp) sd x4, PT_TP(sp) sd x5, PT_T0(sp) sd x6, PT_T1(sp) sd x7, PT_T2(sp) sd x8, PT_S0(sp) sd x9, PT_S1(sp) sd x10, PT_A0(sp) sd x11, PT_A1(sp) sd x12, PT_A2(sp) sd x13, PT_A3(sp) sd x14, PT_A4(sp) sd x15, PT_A5(sp) sd x16, PT_A6(sp) sd x17, PT_A7(sp) sd x18, PT_S2(sp) sd x19, PT_S3(sp) sd x20, PT_S4(sp) sd x21, PT_S5(sp) sd x22, PT_S6(sp) sd x23, PT_S7(sp) sd x24, PT_S8(sp) sd x25, PT_S9(sp) sd x26, PT_S10(sp) sd x27, PT_S11(sp) sd x28, PT_T3(sp) sd x29, PT_T4(sp) sd x30, PT_T5(sp) sd x31, PT_T6(sp) .endm .macro RESTORE_ALL ld x1, PT_RA(sp) ld x2, PT_SP(sp) ld x3, PT_GP(sp) ld x4, PT_TP(sp) ld x5, PT_T0(sp) ld x6, PT_T1(sp) ld x7, PT_T2(sp) ld x8, PT_S0(sp) ld x9, PT_S1(sp) ld x10, PT_A0(sp) ld x11, PT_A1(sp) ld x12, PT_A2(sp) ld x13, PT_A3(sp) ld x14, PT_A4(sp) ld x15, PT_A5(sp) ld x16, PT_A6(sp) ld x17, PT_A7(sp) ld x18, PT_S2(sp) ld x19, PT_S3(sp) ld x20, PT_S4(sp) ld x21, PT_S5(sp) ld x22, PT_S6(sp) ld x23, PT_S7(sp) ld x24, PT_S8(sp) ld x25, PT_S9(sp) ld x26, PT_S10(sp) ld x27, PT_S11(sp) ld x28, PT_T3(sp) ld x29, PT_T4(sp) ld x30, PT_T5(sp) ld x31, PT_T6(sp) ld s0, (PT_SIZE_ON_STACK)(sp) ld ra, (PT_SIZE_ON_STACK+8)(sp) addi sp, sp, (PT_SIZE_ON_STACK+16) .endm .macro RESTORE_GRAPH_REG_ARGS ld a0, PT_T0(sp) ld a1, PT_T1(sp) #ifdef HAVE_FUNCTION_GRAPH_FP_TEST ld a2, PT_T2(sp) #endif .endm /* * Most of the contents are the same as ftrace_caller. */ ENTRY(ftrace_regs_caller) /* * a3: the address of all registers in the stack */ ld a1, -8(s0) addi a0, ra, -MCOUNT_INSN_SIZE la t5, function_trace_op ld a2, 0(t5) addi a3, sp, -(PT_SIZE_ON_STACK+16) #ifdef CONFIG_FUNCTION_GRAPH_TRACER addi t0, s0, -8 mv t1, a0 #ifdef HAVE_FUNCTION_GRAPH_FP_TEST ld t2, -16(s0) #endif #endif SAVE_ALL ftrace_regs_call: .global ftrace_regs_call call ftrace_stub #ifdef CONFIG_FUNCTION_GRAPH_TRACER RESTORE_GRAPH_REG_ARGS call ftrace_graph_caller #endif RESTORE_ALL ret ENDPROC(ftrace_regs_caller) #endif /* CONFIG_DYNAMIC_FTRACE_WITH_REGS */ |