1 /* SPDX-License-Identifier: GPL-2.0 */ 2 /* 3 * Copyright IBM Corp. 2008, 2009 4 * 5 */ 6 7 #include <linux/linkage.h> 8 #include <asm/asm-offsets.h> 9 #include <asm/ftrace.h> 10 #include <asm/nospec-insn.h> 11 #include <asm/ptrace.h> 12 #include <asm/march.h> 13 14 #define STACK_FRAME_SIZE_PTREGS (STACK 15 #define STACK_PTREGS (STACK 16 #define STACK_PTREGS_GPRS (STACK 17 #define STACK_PTREGS_PSW (STACK 18 19 #define STACK_FRAME_SIZE_FREGS (STACK 20 #define STACK_FREGS (STACK 21 #define STACK_FREGS_PTREGS (STACK 22 #define STACK_FREGS_PTREGS_GPRS (STACK 23 #define STACK_FREGS_PTREGS_PSW (STACK 24 #define STACK_FREGS_PTREGS_ORIG_GPR2 (STACK 25 #define STACK_FREGS_PTREGS_FLAGS (STACK 26 27 /* packed stack: allocate just enough for r14, 28 #define TRACED_FUNC_FRAME_SIZE 24 29 30 #ifdef CONFIG_FUNCTION_TRACER 31 32 GEN_BR_THUNK %r1 33 GEN_BR_THUNK %r14 34 35 .section .kprobes.text, "ax" 36 37 SYM_FUNC_START(ftrace_stub) 38 BR_EX %r14 39 SYM_FUNC_END(ftrace_stub) 40 41 SYM_CODE_START(ftrace_stub_direct_tramp) 42 lgr %r1, %r0 43 BR_EX %r1 44 SYM_CODE_END(ftrace_stub_direct_tramp) 45 46 .macro ftrace_regs_entry, allregs=0 47 stg %r14,(__SF_GPRS+8*8)(%r15) 48 49 .if \allregs == 1 50 # save psw mask 51 # don't put any instructions clobberin 52 epsw %r1,%r14 53 risbg %r14,%r1,0,31,32 54 .endif 55 56 lgr %r1,%r15 57 # allocate stack frame for ftrace_call 58 aghi %r15,-TRACED_FUNC_FRAME_SIZE 59 stg %r1,__SF_BACKCHAIN(%r15) 60 stg %r0,(__SF_GPRS+8*8)(%r15) 61 stg %r15,(__SF_GPRS+9*8)(%r15) 62 # allocate ftrace_regs and stack frame 63 aghi %r15,-STACK_FRAME_SIZE_FREGS 64 stg %r1,(STACK_FREGS_PTREGS_GPRS+1 65 xc STACK_FREGS_PTREGS_ORIG_GPR2(8 66 67 .if \allregs == 1 68 stg %r14,(STACK_FREGS_PTREGS_PSW)( 69 mvghi STACK_FREGS_PTREGS_FLAGS(%r15) 70 .else 71 xc STACK_FREGS_PTREGS_FLAGS(8,%r1 72 .endif 73 74 lg %r14,(__SF_GPRS+8*8)(%r1) 75 aghi %r1,-TRACED_FUNC_FRAME_SIZE 76 stg %r1,__SF_BACKCHAIN(%r15) 77 stg %r0,(STACK_FREGS_PTREGS_PSW+8) 78 stmg %r2,%r14,(STACK_FREGS_PTREGS_G 79 .endm 80 81 SYM_CODE_START(ftrace_regs_caller) 82 ftrace_regs_entry 1 83 j ftrace_common 84 SYM_CODE_END(ftrace_regs_caller) 85 86 SYM_CODE_START(ftrace_caller) 87 ftrace_regs_entry 0 88 j ftrace_common 89 SYM_CODE_END(ftrace_caller) 90 91 SYM_CODE_START(ftrace_common) 92 #ifdef MARCH_HAS_Z196_FEATURES 93 aghik %r2,%r0,-MCOUNT_INSN_SIZE 94 lgrl %r4,function_trace_op 95 lgrl %r1,ftrace_func 96 #else 97 lgr %r2,%r0 98 aghi %r2,-MCOUNT_INSN_SIZE 99 larl %r4,function_trace_op 100 lg %r4,0(%r4) 101 larl %r1,ftrace_func 102 lg %r1,0(%r1) 103 #endif 104 lgr %r3,%r14 105 la %r5,STACK_FREGS(%r15) 106 BASR_EX %r14,%r1 107 #ifdef CONFIG_FUNCTION_GRAPH_TRACER 108 # The j instruction gets runtime patched to a 109 # See ftrace_enable_ftrace_graph_caller. 110 SYM_INNER_LABEL(ftrace_graph_caller, SYM_L_GLO 111 j .Lftrace_graph_caller_end 112 lmg %r2,%r3,(STACK_FREGS_PTREGS_GP 113 lg %r4,(STACK_FREGS_PTREGS_PSW+8) 114 brasl %r14,prepare_ftrace_return 115 stg %r2,(STACK_FREGS_PTREGS_GPRS+1 116 .Lftrace_graph_caller_end: 117 #endif 118 lg %r0,(STACK_FREGS_PTREGS_PSW+8) 119 #ifdef MARCH_HAS_Z196_FEATURES 120 ltg %r1,STACK_FREGS_PTREGS_ORIG_GP 121 locgrz %r1,%r0 122 #else 123 lg %r1,STACK_FREGS_PTREGS_ORIG_GP 124 ltgr %r1,%r1 125 jnz 0f 126 lgr %r1,%r0 127 #endif 128 0: lmg %r2,%r15,(STACK_FREGS_PTREGS_G 129 BR_EX %r1 130 SYM_CODE_END(ftrace_common) 131 132 #ifdef CONFIG_FUNCTION_GRAPH_TRACER 133 134 SYM_FUNC_START(return_to_handler) 135 stmg %r2,%r5,32(%r15) 136 lgr %r1,%r15 137 aghi %r15,-(STACK_FRAME_OVERHEAD+__ 138 stg %r1,__SF_BACKCHAIN(%r15) 139 la %r3,STACK_FRAME_OVERHEAD(%r15) 140 stg %r1,__FGRAPH_RET_FP(%r3) 141 stg %r2,__FGRAPH_RET_GPR2(%r3) 142 lgr %r2,%r3 143 brasl %r14,ftrace_return_to_handler 144 aghi %r15,STACK_FRAME_OVERHEAD+__FG 145 lgr %r14,%r2 146 lmg %r2,%r5,32(%r15) 147 BR_EX %r14 148 SYM_FUNC_END(return_to_handler) 149 150 #endif 151 #endif /* CONFIG_FUNCTION_TRACER */ 152 153 SYM_CODE_START(ftrace_shared_hotpatch_trampoli 154 lmg %r0,%r1,2(%r1) 155 br %r1 156 SYM_INNER_LABEL(ftrace_shared_hotpatch_trampol 157 SYM_CODE_END(ftrace_shared_hotpatch_trampoline 158 159 #ifdef CONFIG_EXPOLINE 160 SYM_CODE_START(ftrace_shared_hotpatch_trampoli 161 lmg %r0,%r1,2(%r1) 162 exrl %r0,0f 163 j . 164 0: br %r1 165 SYM_INNER_LABEL(ftrace_shared_hotpatch_trampol 166 SYM_CODE_END(ftrace_shared_hotpatch_trampoline 167 #endif /* CONFIG_EXPOLINE */ 168 169 #ifdef CONFIG_RETHOOK 170 171 SYM_CODE_START(arch_rethook_trampoline) 172 stg %r14,(__SF_GPRS+8*8)(%r15) 173 lay %r15,-STACK_FRAME_SIZE_PTREGS( 174 stmg %r0,%r14,STACK_PTREGS_GPRS(%r1 175 176 # store original stack pointer in back 177 lay %r7,STACK_FRAME_SIZE_PTREGS(%r 178 stg %r7,__SF_BACKCHAIN(%r15) 179 stg %r7,STACK_PTREGS_GPRS+(15*8)(% 180 181 # store full psw 182 epsw %r2,%r3 183 risbg %r3,%r2,0,31,32 184 stg %r3,STACK_PTREGS_PSW(%r15) 185 larl %r1,arch_rethook_trampoline 186 stg %r1,STACK_PTREGS_PSW+8(%r15) 187 188 lay %r2,STACK_PTREGS(%r15) 189 brasl %r14,arch_rethook_trampoline_c 190 191 mvc __SF_EMPTY(16,%r7),STACK_PTREG 192 lmg %r0,%r15,STACK_PTREGS_GPRS(%r1 193 lpswe __SF_EMPTY(%r15) 194 SYM_CODE_END(arch_rethook_trampoline) 195 196 #endif /* CONFIG_RETHOOK */
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.