Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 /*
0003  * Copyright IBM Corp. 2008, 2009
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 /* packed stack: allocate just enough for r14, r15 and backchain */
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 /* CONFIG_FUNCTION_TRACER */
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 /* CONFIG_KPROBES */