xref: /linux/arch/s390/kernel/mcount.S (revision 570f7e331f5febb30f1384817463c7e42b65ca7d)
1/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * Copyright IBM Corp. 2008, 2009
4 *
5 */
6
7#include <linux/cfi_types.h>
8#include <linux/linkage.h>
9#include <asm/asm-offsets.h>
10#include <asm/ftrace.h>
11#include <asm/nospec-insn.h>
12#include <asm/ptrace.h>
13#include <asm/march.h>
14
15#define STACK_FRAME_SIZE_PTREGS		(STACK_FRAME_OVERHEAD + __PT_SIZE)
16#define STACK_PTREGS			(STACK_FRAME_OVERHEAD)
17#define STACK_PTREGS_GPRS		(STACK_PTREGS + __PT_GPRS)
18#define STACK_PTREGS_PSW		(STACK_PTREGS + __PT_PSW)
19
20#define STACK_FRAME_SIZE_FREGS		(STACK_FRAME_OVERHEAD + __FTRACE_REGS_SIZE)
21#define STACK_FREGS			(STACK_FRAME_OVERHEAD)
22#define STACK_FREGS_PTREGS		(STACK_FRAME_OVERHEAD + __FTRACE_REGS_PT_REGS)
23#define STACK_FREGS_PTREGS_GPRS		(STACK_FREGS_PTREGS + __PT_GPRS)
24#define STACK_FREGS_PTREGS_PSW		(STACK_FREGS_PTREGS + __PT_PSW)
25#define STACK_FREGS_PTREGS_ORIG_GPR2	(STACK_FREGS_PTREGS + __PT_ORIG_GPR2)
26#define STACK_FREGS_PTREGS_FLAGS	(STACK_FREGS_PTREGS + __PT_FLAGS)
27
28/* packed stack: allocate just enough for r14, r15 and backchain */
29#define TRACED_FUNC_FRAME_SIZE	24
30
31#ifdef CONFIG_FUNCTION_TRACER
32
33	GEN_BR_THUNK %r1
34	GEN_BR_THUNK %r14
35
36	.section .kprobes.text, "ax"
37
38SYM_TYPED_FUNC_START(ftrace_stub)
39	BR_EX	%r14
40SYM_FUNC_END(ftrace_stub)
41
42#ifdef CONFIG_FUNCTION_GRAPH_TRACER
43SYM_TYPED_FUNC_START(ftrace_stub_graph)
44	BR_EX	%r14
45SYM_FUNC_END(ftrace_stub_graph)
46#endif
47
48SYM_CODE_START(ftrace_stub_direct_tramp)
49	lgr	%r1, %r0
50	BR_EX	%r1
51SYM_CODE_END(ftrace_stub_direct_tramp)
52
53	.macro	ftrace_regs_entry, allregs=0
54	stg	%r14,(__SF_GPRS+8*8)(%r15)	# save traced function caller
55
56	.if \allregs == 1
57	# save psw mask
58	# don't put any instructions clobbering CC before this point
59	epsw	%r1,%r14
60	risbg	%r14,%r1,0,31,32
61	.endif
62
63	lgr	%r1,%r15
64	# allocate stack frame for ftrace_caller to contain traced function
65	aghi	%r15,-TRACED_FUNC_FRAME_SIZE
66	stg	%r1,__SF_BACKCHAIN(%r15)
67	stg	%r0,(__SF_GPRS+8*8)(%r15)
68	stg	%r15,(__SF_GPRS+9*8)(%r15)
69	# allocate ftrace_regs and stack frame for ftrace_trace_function
70	aghi	%r15,-STACK_FRAME_SIZE_FREGS
71	stg	%r1,(STACK_FREGS_PTREGS_GPRS+15*8)(%r15)
72	xc	STACK_FREGS_PTREGS_ORIG_GPR2(8,%r15),STACK_FREGS_PTREGS_ORIG_GPR2(%r15)
73
74	.if \allregs == 1
75	stg	%r14,(STACK_FREGS_PTREGS_PSW)(%r15)
76	mvghi	STACK_FREGS_PTREGS_FLAGS(%r15),_PIF_FTRACE_FULL_REGS
77	.else
78	xc	STACK_FREGS_PTREGS_FLAGS(8,%r15),STACK_FREGS_PTREGS_FLAGS(%r15)
79	.endif
80
81	lg	%r14,(__SF_GPRS+8*8)(%r1)	# restore original return address
82	aghi	%r1,-TRACED_FUNC_FRAME_SIZE
83	stg	%r1,__SF_BACKCHAIN(%r15)
84	stg	%r0,(STACK_FREGS_PTREGS_PSW+8)(%r15)
85	stmg	%r2,%r14,(STACK_FREGS_PTREGS_GPRS+2*8)(%r15)
86	.endm
87
88SYM_CODE_START(ftrace_regs_caller)
89	ftrace_regs_entry	1
90	j	ftrace_common
91SYM_CODE_END(ftrace_regs_caller)
92
93SYM_CODE_START(ftrace_caller)
94	ftrace_regs_entry	0
95	j	ftrace_common
96SYM_CODE_END(ftrace_caller)
97
98SYM_CODE_START(ftrace_common)
99#ifdef MARCH_HAS_Z196_FEATURES
100	aghik	%r2,%r0,-MCOUNT_INSN_SIZE
101	lgrl	%r4,function_trace_op
102	lgrl	%r1,ftrace_func
103#else
104	lgr	%r2,%r0
105	aghi	%r2,-MCOUNT_INSN_SIZE
106	larl	%r4,function_trace_op
107	lg	%r4,0(%r4)
108	larl	%r1,ftrace_func
109	lg	%r1,0(%r1)
110#endif
111	lgr	%r3,%r14
112	la	%r5,STACK_FREGS(%r15)
113	BASR_EX	%r14,%r1
114	lg	%r0,(STACK_FREGS_PTREGS_PSW+8)(%r15)
115#ifdef MARCH_HAS_Z196_FEATURES
116	ltg	%r1,STACK_FREGS_PTREGS_ORIG_GPR2(%r15)
117	locgrz	%r1,%r0
118#else
119	lg	%r1,STACK_FREGS_PTREGS_ORIG_GPR2(%r15)
120	ltgr	%r1,%r1
121	jnz	0f
122	lgr	%r1,%r0
123#endif
1240:	lmg	%r2,%r15,(STACK_FREGS_PTREGS_GPRS+2*8)(%r15)
125	BR_EX	%r1
126SYM_CODE_END(ftrace_common)
127
128#ifdef CONFIG_FUNCTION_GRAPH_TRACER
129
130SYM_FUNC_START(return_to_handler)
131	stmg	%r2,%r5,32(%r15)
132	lgr	%r1,%r15
133	# allocate ftrace_regs and stack frame for ftrace_return_to_handler
134	aghi	%r15,-STACK_FRAME_SIZE_FREGS
135	stg	%r1,__SF_BACKCHAIN(%r15)
136	stg	%r2,(STACK_FREGS_PTREGS_GPRS+2*8)(%r15)
137	stg	%r1,(STACK_FREGS_PTREGS_GPRS+15*8)(%r15)
138	la	%r2,STACK_FRAME_OVERHEAD(%r15)
139	brasl	%r14,ftrace_return_to_handler
140	aghi	%r15,STACK_FRAME_SIZE_FREGS
141	lgr	%r14,%r2
142	lmg	%r2,%r5,32(%r15)
143	BR_EX	%r14
144SYM_FUNC_END(return_to_handler)
145
146#endif
147#endif /* CONFIG_FUNCTION_TRACER */
148
149SYM_CODE_START(ftrace_shared_hotpatch_trampoline_br)
150	lmg	%r0,%r1,2(%r1)
151	br	%r1
152SYM_INNER_LABEL(ftrace_shared_hotpatch_trampoline_br_end, SYM_L_GLOBAL)
153SYM_CODE_END(ftrace_shared_hotpatch_trampoline_br)
154
155#ifdef CONFIG_EXPOLINE
156SYM_CODE_START(ftrace_shared_hotpatch_trampoline_exrl)
157	lmg	%r0,%r1,2(%r1)
158	exrl	%r0,0f
159	j	.
1600:	br	%r1
161SYM_INNER_LABEL(ftrace_shared_hotpatch_trampoline_exrl_end, SYM_L_GLOBAL)
162SYM_CODE_END(ftrace_shared_hotpatch_trampoline_exrl)
163#endif /* CONFIG_EXPOLINE */
164
165#ifdef CONFIG_RETHOOK
166
167SYM_CODE_START(arch_rethook_trampoline)
168	stg	%r14,(__SF_GPRS+8*8)(%r15)
169	lay	%r15,-STACK_FRAME_SIZE_PTREGS(%r15)
170	stmg	%r0,%r14,STACK_PTREGS_GPRS(%r15)
171
172	# store original stack pointer in backchain and pt_regs
173	lay	%r7,STACK_FRAME_SIZE_PTREGS(%r15)
174	stg	%r7,__SF_BACKCHAIN(%r15)
175	stg	%r7,STACK_PTREGS_GPRS+(15*8)(%r15)
176
177	# store full psw
178	epsw	%r2,%r3
179	risbg	%r3,%r2,0,31,32
180	stg	%r3,STACK_PTREGS_PSW(%r15)
181	larl	%r1,arch_rethook_trampoline
182	stg	%r1,STACK_PTREGS_PSW+8(%r15)
183
184	lay	%r2,STACK_PTREGS(%r15)
185	brasl	%r14,arch_rethook_trampoline_callback
186
187	mvc	__SF_EMPTY(16,%r7),STACK_PTREGS_PSW(%r15)
188	lmg	%r0,%r15,STACK_PTREGS_GPRS(%r15)
189	lpswe	__SF_EMPTY(%r15)
190SYM_CODE_END(arch_rethook_trampoline)
191
192#endif /* CONFIG_RETHOOK */
193