0001
0002
0003
0004
0005
0006
0007 #include <linux/linkage.h>
0008 #include <asm/asm-offsets.h>
0009 #include <asm/ftrace.h>
0010 #include <asm/nospec-insn.h>
0011 #include <asm/ptrace.h>
0012 #include <asm/export.h>
0013
0014
0015 #define STACK_FRAME_SIZE (STACK_FRAME_OVERHEAD + __PT_SIZE)
0016 #define STACK_PTREGS (STACK_FRAME_OVERHEAD)
0017 #define STACK_PTREGS_GPRS (STACK_PTREGS + __PT_GPRS)
0018 #define STACK_PTREGS_PSW (STACK_PTREGS + __PT_PSW)
0019 #define STACK_PTREGS_ORIG_GPR2 (STACK_PTREGS + __PT_ORIG_GPR2)
0020 #define STACK_PTREGS_FLAGS (STACK_PTREGS + __PT_FLAGS)
0021
0022 #define TRACED_FUNC_FRAME_SIZE 24
0023
0024 #ifdef CONFIG_FUNCTION_TRACER
0025
0026 GEN_BR_THUNK %r1
0027 GEN_BR_THUNK %r14
0028
0029 .section .kprobes.text, "ax"
0030
0031 ENTRY(ftrace_stub)
0032 BR_EX %r14
0033 ENDPROC(ftrace_stub)
0034
0035 .macro ftrace_regs_entry, allregs=0
0036 stg %r14,(__SF_GPRS+8*8)(%r15) # save traced function caller
0037
0038 .if \allregs == 1
0039 # save psw mask
0040 # don't put any instructions clobbering CC before this point
0041 epsw %r1,%r14
0042 risbg %r14,%r1,0,31,32
0043 .endif
0044
0045 lgr %r1,%r15
0046 # allocate stack frame for ftrace_caller to contain traced function
0047 aghi %r15,-TRACED_FUNC_FRAME_SIZE
0048 stg %r1,__SF_BACKCHAIN(%r15)
0049 stg %r0,(__SF_GPRS+8*8)(%r15)
0050 stg %r15,(__SF_GPRS+9*8)(%r15)
0051 # allocate pt_regs and stack frame for ftrace_trace_function
0052 aghi %r15,-STACK_FRAME_SIZE
0053 stg %r1,(STACK_PTREGS_GPRS+15*8)(%r15)
0054 xc STACK_PTREGS_ORIG_GPR2(8,%r15),STACK_PTREGS_ORIG_GPR2(%r15)
0055
0056 .if \allregs == 1
0057 stg %r14,(STACK_PTREGS_PSW)(%r15)
0058 mvghi STACK_PTREGS_FLAGS(%r15),_PIF_FTRACE_FULL_REGS
0059 .else
0060 xc STACK_PTREGS_FLAGS(8,%r15),STACK_PTREGS_FLAGS(%r15)
0061 .endif
0062
0063 lg %r14,(__SF_GPRS+8*8)(%r1) # restore original return address
0064 aghi %r1,-TRACED_FUNC_FRAME_SIZE
0065 stg %r1,__SF_BACKCHAIN(%r15)
0066 stg %r0,(STACK_PTREGS_PSW+8)(%r15)
0067 stmg %r2,%r14,(STACK_PTREGS_GPRS+2*8)(%r15)
0068 .endm
0069
0070 SYM_CODE_START(ftrace_regs_caller)
0071 ftrace_regs_entry 1
0072 j ftrace_common
0073 SYM_CODE_END(ftrace_regs_caller)
0074
0075 SYM_CODE_START(ftrace_caller)
0076 ftrace_regs_entry 0
0077 j ftrace_common
0078 SYM_CODE_END(ftrace_caller)
0079
0080 SYM_CODE_START(ftrace_common)
0081 #ifdef CONFIG_HAVE_MARCH_Z196_FEATURES
0082 aghik %r2,%r0,-MCOUNT_INSN_SIZE
0083 lgrl %r4,function_trace_op
0084 lgrl %r1,ftrace_func
0085 #else
0086 lgr %r2,%r0
0087 aghi %r2,-MCOUNT_INSN_SIZE
0088 larl %r4,function_trace_op
0089 lg %r4,0(%r4)
0090 larl %r1,ftrace_func
0091 lg %r1,0(%r1)
0092 #endif
0093 lgr %r3,%r14
0094 la %r5,STACK_PTREGS(%r15)
0095 BASR_EX %r14,%r1
0096 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
0097 # The j instruction gets runtime patched to a nop instruction.
0098 # See ftrace_enable_ftrace_graph_caller.
0099 SYM_INNER_LABEL(ftrace_graph_caller, SYM_L_GLOBAL)
0100 j .Lftrace_graph_caller_end
0101 lmg %r2,%r3,(STACK_PTREGS_GPRS+14*8)(%r15)
0102 lg %r4,(STACK_PTREGS_PSW+8)(%r15)
0103 brasl %r14,prepare_ftrace_return
0104 stg %r2,(STACK_PTREGS_GPRS+14*8)(%r15)
0105 .Lftrace_graph_caller_end:
0106 #endif
0107 lg %r0,(STACK_PTREGS_PSW+8)(%r15)
0108 #ifdef CONFIG_HAVE_MARCH_Z196_FEATURES
0109 ltg %r1,STACK_PTREGS_ORIG_GPR2(%r15)
0110 locgrz %r1,%r0
0111 #else
0112 lg %r1,STACK_PTREGS_ORIG_GPR2(%r15)
0113 ltgr %r1,%r1
0114 jnz 0f
0115 lgr %r1,%r0
0116 #endif
0117 0: lmg %r2,%r15,(STACK_PTREGS_GPRS+2*8)(%r15)
0118 BR_EX %r1
0119 SYM_CODE_END(ftrace_common)
0120
0121 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
0122
0123 SYM_FUNC_START(return_to_handler)
0124 stmg %r2,%r5,32(%r15)
0125 lgr %r1,%r15
0126 aghi %r15,-STACK_FRAME_OVERHEAD
0127 stg %r1,__SF_BACKCHAIN(%r15)
0128 brasl %r14,ftrace_return_to_handler
0129 aghi %r15,STACK_FRAME_OVERHEAD
0130 lgr %r14,%r2
0131 lmg %r2,%r5,32(%r15)
0132 BR_EX %r14
0133 SYM_FUNC_END(return_to_handler)
0134
0135 #endif
0136 #endif
0137
0138 #ifdef CONFIG_KPROBES
0139
0140 SYM_FUNC_START(__kretprobe_trampoline)
0141
0142 stg %r14,(__SF_GPRS+8*8)(%r15)
0143 lay %r15,-STACK_FRAME_SIZE(%r15)
0144 stmg %r0,%r14,STACK_PTREGS_GPRS(%r15)
0145
0146 # store original stack pointer in backchain and pt_regs
0147 lay %r7,STACK_FRAME_SIZE(%r15)
0148 stg %r7,__SF_BACKCHAIN(%r15)
0149 stg %r7,STACK_PTREGS_GPRS+(15*8)(%r15)
0150
0151 # store full psw
0152 epsw %r2,%r3
0153 risbg %r3,%r2,0,31,32
0154 stg %r3,STACK_PTREGS_PSW(%r15)
0155 larl %r1,__kretprobe_trampoline
0156 stg %r1,STACK_PTREGS_PSW+8(%r15)
0157
0158 lay %r2,STACK_PTREGS(%r15)
0159 brasl %r14,trampoline_probe_handler
0160
0161 mvc __SF_EMPTY(16,%r7),STACK_PTREGS_PSW(%r15)
0162 lmg %r0,%r15,STACK_PTREGS_GPRS(%r15)
0163 lpswe __SF_EMPTY(%r15)
0164
0165 SYM_FUNC_END(__kretprobe_trampoline)
0166
0167 #endif