5757 .endm
5858
5959#ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS
60- .macro SAVE_ALL
60+
61+ /**
62+ * SAVE_ABI_REGS - save regs against the pt_regs struct
63+ *
64+ * @all: tell if saving all the regs
65+ *
66+ * If all is set, all the regs will be saved, otherwise only ABI
67+ * related regs (a0-a7,epc,ra and optional s0) will be saved.
68+ *
69+ * After the stack is established,
70+ *
71+ * 0(sp) stores the PC of the traced function which can be accessed
72+ * by &(fregs)->regs->epc in tracing function. Note that the real
73+ * function entry address should be computed with -FENTRY_RA_OFFSET.
74+ *
75+ * 8(sp) stores the function return address (i.e. parent IP) that
76+ * can be accessed by &(fregs)->regs->ra in tracing function.
77+ *
78+ * The other regs are saved at the respective localtion and accessed
79+ * by the respective pt_regs member.
80+ *
81+ * Here is the layout of stack for your reference.
82+ *
83+ * PT_SIZE_ON_STACK -> +++++++++
84+ * + ..... +
85+ * + t3-t6 +
86+ * + s2-s11+
87+ * + a0-a7 + --++++-> ftrace_caller saved
88+ * + s1 + +
89+ * + s0 + --+
90+ * + t0-t2 + +
91+ * + tp + +
92+ * + gp + +
93+ * + sp + +
94+ * + ra + --+ // parent IP
95+ * sp -> + epc + --+ // PC
96+ * +++++++++
97+ **/
98+ .macro SAVE_ABI_REGS, all=0
6199 addi sp , sp , -PT_SIZE_ON_STACK
62100
63- REG_S t0, PT_EPC(sp )
64- REG_S x1, PT_RA(sp )
65- REG_S x2, PT_SP(sp )
66- REG_S x3, PT_GP(sp )
67- REG_S x4, PT_TP(sp )
68- REG_S x5, PT_T0(sp )
69- save_from_x6_to_x31
101+ REG_S t0, PT_EPC(sp )
102+ REG_S x1, PT_RA(sp )
103+
104+ // save the ABI regs
105+
106+ REG_S x10, PT_A0(sp )
107+ REG_S x11, PT_A1(sp )
108+ REG_S x12, PT_A2(sp )
109+ REG_S x13, PT_A3(sp )
110+ REG_S x14, PT_A4(sp )
111+ REG_S x15, PT_A5(sp )
112+ REG_S x16, PT_A6(sp )
113+ REG_S x17, PT_A7(sp )
114+
115+ // save the leftover regs
116+
117+ .if \all == 1
118+ REG_S x2, PT_SP(sp )
119+ REG_S x3, PT_GP(sp )
120+ REG_S x4, PT_TP(sp )
121+ REG_S x5, PT_T0(sp )
122+ REG_S x6, PT_T1(sp )
123+ REG_S x7, PT_T2(sp )
124+ REG_S x8, PT_S0(sp )
125+ REG_S x9, PT_S1(sp )
126+ REG_S x18, PT_S2(sp )
127+ REG_S x19, PT_S3(sp )
128+ REG_S x20, PT_S4(sp )
129+ REG_S x21, PT_S5(sp )
130+ REG_S x22, PT_S6(sp )
131+ REG_S x23, PT_S7(sp )
132+ REG_S x24, PT_S8(sp )
133+ REG_S x25, PT_S9(sp )
134+ REG_S x26, PT_S10(sp )
135+ REG_S x27, PT_S11(sp )
136+ REG_S x28, PT_T3(sp )
137+ REG_S x29, PT_T4(sp )
138+ REG_S x30, PT_T5(sp )
139+ REG_S x31, PT_T6(sp )
140+
141+ // save s0 if FP_TEST defined
142+
143+ .else
144+ #ifdef HAVE_FUNCTION_GRAPH_FP_TEST
145+ REG_S x8, PT_S0(sp )
146+ #endif
147+ .endif
70148 .endm
71149
72- .macro RESTORE_ALL
73- REG_L x1, PT_RA(sp )
74- REG_L x2, PT_SP(sp )
75- REG_L x3, PT_GP(sp )
76- REG_L x4, PT_TP(sp )
77- /* Restore t0 with PT_EPC */
78- REG_L x5, PT_EPC(sp )
79- restore_from_x6_to_x31
150+ .macro RESTORE_ABI_REGS, all=0
151+ REG_L t0, PT_EPC(sp )
152+ REG_L x1, PT_RA(sp )
153+ REG_L x10, PT_A0(sp )
154+ REG_L x11, PT_A1(sp )
155+ REG_L x12, PT_A2(sp )
156+ REG_L x13, PT_A3(sp )
157+ REG_L x14, PT_A4(sp )
158+ REG_L x15, PT_A5(sp )
159+ REG_L x16, PT_A6(sp )
160+ REG_L x17, PT_A7(sp )
80161
162+ .if \all == 1
163+ REG_L x2, PT_SP(sp )
164+ REG_L x3, PT_GP(sp )
165+ REG_L x4, PT_TP(sp )
166+ REG_L x6, PT_T1(sp )
167+ REG_L x7, PT_T2(sp )
168+ REG_L x8, PT_S0(sp )
169+ REG_L x9, PT_S1(sp )
170+ REG_L x18, PT_S2(sp )
171+ REG_L x19, PT_S3(sp )
172+ REG_L x20, PT_S4(sp )
173+ REG_L x21, PT_S5(sp )
174+ REG_L x22, PT_S6(sp )
175+ REG_L x23, PT_S7(sp )
176+ REG_L x24, PT_S8(sp )
177+ REG_L x25, PT_S9(sp )
178+ REG_L x26, PT_S10(sp )
179+ REG_L x27, PT_S11(sp )
180+ REG_L x28, PT_T3(sp )
181+ REG_L x29, PT_T4(sp )
182+ REG_L x30, PT_T5(sp )
183+ REG_L x31, PT_T6(sp )
184+
185+ .else
186+ #ifdef HAVE_FUNCTION_GRAPH_FP_TEST
187+ REG_L x8, PT_S0(sp )
188+ #endif
189+ .endif
81190 addi sp , sp , PT_SIZE_ON_STACK
82191 .endm
192+
193+ .macro PREPARE_ARGS
194+ addi a0 , t0, -FENTRY_RA_OFFSET
195+ la a1 , function_trace_op
196+ REG_L a2 , 0 (a1 )
197+ mv a1 , ra
198+ mv a3 , sp
199+ .endm
200+
83201#endif /* CONFIG_DYNAMIC_FTRACE_WITH_REGS */
84202
203+ #ifndef CONFIG_DYNAMIC_FTRACE_WITH_REGS
85204SYM_FUNC_START (ftrace_caller)
86205 SAVE_ABI
87206
@@ -105,34 +224,39 @@ SYM_INNER_LABEL(ftrace_graph_call, SYM_L_GLOBAL)
105224 call ftrace_stub
106225#endif
107226 RESTORE_ABI
108- jr t0
227+ jr t0
109228SYM_FUNC_END (ftrace_caller)
110229
111- #ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS
230+ #else / * CONFIG_DYNAMIC_FTRACE_WITH_REGS */
112231SYM_FUNC_START (ftrace_regs_caller)
113- SAVE_ALL
114-
115- addi a0 , t0, -FENTRY_RA_OFFSET
116- la a1 , function_trace_op
117- REG_L a2 , 0 (a1 )
118- mv a1 , ra
119- mv a3 , sp
232+ mv t1, zero
233+ SAVE_ABI_REGS 1
234+ PREPARE_ARGS
120235
121236SYM_INNER_LABEL (ftrace_regs_call, SYM_L_GLOBAL)
122237 call ftrace_stub
123238
124- #ifdef CONFIG_FUNCTION_GRAPH_TRACER
125- addi a0 , sp , PT_RA
126- REG_L a1 , PT_EPC(sp )
127- addi a1 , a1 , -FENTRY_RA_OFFSET
128- #ifdef HAVE_FUNCTION_GRAPH_FP_TEST
129- mv a2 , s0
130- #endif
131- SYM_INNER_LABEL (ftrace_graph_regs_call, SYM_L_GLOBAL)
239+ RESTORE_ABI_REGS 1
240+ bnez t1, .Ldirect
241+ jr t0
242+ .Ldirect:
243+ jr t1
244+ SYM_FUNC_END (ftrace_regs_caller)
245+
246+ SYM_FUNC_START (ftrace_caller)
247+ SAVE_ABI_REGS 0
248+ PREPARE_ARGS
249+
250+ SYM_INNER_LABEL (ftrace_call, SYM_L_GLOBAL)
132251 call ftrace_stub
133- #endif
134252
135- RESTORE_ALL
136- jr t0
137- SYM_FUNC_END (ftrace_regs_caller )
253+ RESTORE_ABI_REGS 0
254+ jr t0
255+ SYM_FUNC_END (ftrace_caller )
138256#endif /* CONFIG_DYNAMIC_FTRACE_WITH_REGS */
257+
258+ #ifdef CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS
259+ SYM_CODE_START (ftrace_stub_direct_tramp)
260+ jr t0
261+ SYM_CODE_END (ftrace_stub_direct_tramp)
262+ #endif /* CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS */
0 commit comments