ftrace_mprofile.S (5701B)
1/* SPDX-License-Identifier: GPL-2.0-or-later */ 2/* 3 * Split from ftrace_64.S 4 */ 5 6#include <linux/magic.h> 7#include <asm/ppc_asm.h> 8#include <asm/asm-offsets.h> 9#include <asm/ftrace.h> 10#include <asm/ppc-opcode.h> 11#include <asm/export.h> 12#include <asm/thread_info.h> 13#include <asm/bug.h> 14#include <asm/ptrace.h> 15 16/* 17 * 18 * ftrace_caller()/ftrace_regs_caller() is the function that replaces _mcount() 19 * when ftrace is active. 20 * 21 * We arrive here after a function A calls function B, and we are the trace 22 * function for B. When we enter r1 points to A's stack frame, B has not yet 23 * had a chance to allocate one yet. 24 * 25 * Additionally r2 may point either to the TOC for A, or B, depending on 26 * whether B did a TOC setup sequence before calling us. 27 * 28 * On entry the LR points back to the _mcount() call site, and r0 holds the 29 * saved LR as it was on entry to B, ie. the original return address at the 30 * call site in A. 31 * 32 * Our job is to save the register state into a struct pt_regs (on the stack) 33 * and then arrange for the ftrace function to be called. 34 */ 35.macro ftrace_regs_entry allregs 36 /* Create our stack frame + pt_regs */ 37 PPC_STLU r1,-SWITCH_FRAME_SIZE(r1) 38 39 /* Save all gprs to pt_regs */ 40 SAVE_GPR(0, r1) 41 SAVE_GPRS(3, 10, r1) 42 43#ifdef CONFIG_PPC64 44 /* Save the original return address in A's stack frame */ 45 std r0, LRSAVE+SWITCH_FRAME_SIZE(r1) 46 /* Ok to continue? */ 47 lbz r3, PACA_FTRACE_ENABLED(r13) 48 cmpdi r3, 0 49 beq ftrace_no_trace 50#endif 51 52 .if \allregs == 1 53 SAVE_GPR(2, r1) 54 SAVE_GPRS(11, 31, r1) 55 .else 56#ifdef CONFIG_LIVEPATCH_64 57 SAVE_GPR(14, r1) 58#endif 59 .endif 60 61 /* Save previous stack pointer (r1) */ 62 addi r8, r1, SWITCH_FRAME_SIZE 63 PPC_STL r8, GPR1(r1) 64 65 .if \allregs == 1 66 /* Load special regs for save below */ 67 mfmsr r8 68 mfctr r9 69 mfxer r10 70 mfcr r11 71 .else 72 /* Clear MSR to flag as ftrace_caller versus frace_regs_caller */ 73 li r8, 0 74 .endif 75 76 /* Get the _mcount() call site out of LR */ 77 mflr r7 78 /* Save it as pt_regs->nip */ 79 PPC_STL r7, _NIP(r1) 80 /* Save the read LR in pt_regs->link */ 81 PPC_STL r0, _LINK(r1) 82 83#ifdef CONFIG_PPC64 84 /* Save callee's TOC in the ABI compliant location */ 85 std r2, STK_GOT(r1) 86 ld r2,PACATOC(r13) /* get kernel TOC in r2 */ 87 88 addis r3,r2,function_trace_op@toc@ha 89 addi r3,r3,function_trace_op@toc@l 90 ld r5,0(r3) 91#else 92 lis r3,function_trace_op@ha 93 lwz r5,function_trace_op@l(r3) 94#endif 95 96#ifdef CONFIG_LIVEPATCH_64 97 mr r14, r7 /* remember old NIP */ 98#endif 99 100 /* Calculate ip from nip-4 into r3 for call below */ 101 subi r3, r7, MCOUNT_INSN_SIZE 102 103 /* Put the original return address in r4 as parent_ip */ 104 mr r4, r0 105 106 /* Save special regs */ 107 PPC_STL r8, _MSR(r1) 108 .if \allregs == 1 109 PPC_STL r9, _CTR(r1) 110 PPC_STL r10, _XER(r1) 111 PPC_STL r11, _CCR(r1) 112 .endif 113 114 /* Load &pt_regs in r6 for call below */ 115 addi r6, r1, STACK_FRAME_OVERHEAD 116.endm 117 118.macro ftrace_regs_exit allregs 119 /* Load ctr with the possibly modified NIP */ 120 PPC_LL r3, _NIP(r1) 121 mtctr r3 122 123#ifdef CONFIG_LIVEPATCH_64 124 cmpd r14, r3 /* has NIP been altered? */ 125#endif 126 127 /* Restore gprs */ 128 .if \allregs == 1 129 REST_GPRS(2, 31, r1) 130 .else 131 REST_GPRS(3, 10, r1) 132#ifdef CONFIG_LIVEPATCH_64 133 REST_GPR(14, r1) 134#endif 135 .endif 136 137 /* Restore possibly modified LR */ 138 PPC_LL r0, _LINK(r1) 139 mtlr r0 140 141#ifdef CONFIG_PPC64 142 /* Restore callee's TOC */ 143 ld r2, STK_GOT(r1) 144#endif 145 146 /* Pop our stack frame */ 147 addi r1, r1, SWITCH_FRAME_SIZE 148 149#ifdef CONFIG_LIVEPATCH_64 150 /* Based on the cmpd above, if the NIP was altered handle livepatch */ 151 bne- livepatch_handler 152#endif 153 bctr /* jump after _mcount site */ 154.endm 155 156_GLOBAL(ftrace_regs_caller) 157 ftrace_regs_entry 1 158 /* ftrace_call(r3, r4, r5, r6) */ 159.globl ftrace_regs_call 160ftrace_regs_call: 161 bl ftrace_stub 162 nop 163 ftrace_regs_exit 1 164 165_GLOBAL(ftrace_caller) 166 ftrace_regs_entry 0 167 /* ftrace_call(r3, r4, r5, r6) */ 168.globl ftrace_call 169ftrace_call: 170 bl ftrace_stub 171 nop 172 ftrace_regs_exit 0 173 174_GLOBAL(ftrace_stub) 175 blr 176 177#ifdef CONFIG_PPC64 178ftrace_no_trace: 179 mflr r3 180 mtctr r3 181 REST_GPR(3, r1) 182 addi r1, r1, SWITCH_FRAME_SIZE 183 mtlr r0 184 bctr 185#endif 186 187#ifdef CONFIG_LIVEPATCH_64 188 /* 189 * This function runs in the mcount context, between two functions. As 190 * such it can only clobber registers which are volatile and used in 191 * function linkage. 192 * 193 * We get here when a function A, calls another function B, but B has 194 * been live patched with a new function C. 195 * 196 * On entry: 197 * - we have no stack frame and can not allocate one 198 * - LR points back to the original caller (in A) 199 * - CTR holds the new NIP in C 200 * - r0, r11 & r12 are free 201 */ 202livepatch_handler: 203 ld r12, PACA_THREAD_INFO(r13) 204 205 /* Allocate 3 x 8 bytes */ 206 ld r11, TI_livepatch_sp(r12) 207 addi r11, r11, 24 208 std r11, TI_livepatch_sp(r12) 209 210 /* Save toc & real LR on livepatch stack */ 211 std r2, -24(r11) 212 mflr r12 213 std r12, -16(r11) 214 215 /* Store stack end marker */ 216 lis r12, STACK_END_MAGIC@h 217 ori r12, r12, STACK_END_MAGIC@l 218 std r12, -8(r11) 219 220 /* Put ctr in r12 for global entry and branch there */ 221 mfctr r12 222 bctrl 223 224 /* 225 * Now we are returning from the patched function to the original 226 * caller A. We are free to use r11, r12 and we can use r2 until we 227 * restore it. 228 */ 229 230 ld r12, PACA_THREAD_INFO(r13) 231 232 ld r11, TI_livepatch_sp(r12) 233 234 /* Check stack marker hasn't been trashed */ 235 lis r2, STACK_END_MAGIC@h 236 ori r2, r2, STACK_END_MAGIC@l 237 ld r12, -8(r11) 2381: tdne r12, r2 239 EMIT_BUG_ENTRY 1b, __FILE__, __LINE__ - 1, 0 240 241 /* Restore LR & toc from livepatch stack */ 242 ld r12, -16(r11) 243 mtlr r12 244 ld r2, -24(r11) 245 246 /* Pop livepatch stack frame */ 247 ld r12, PACA_THREAD_INFO(r13) 248 subi r11, r11, 24 249 std r11, TI_livepatch_sp(r12) 250 251 /* Return to original caller of live patched function */ 252 blr 253#endif /* CONFIG_LIVEPATCH */