Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/arch/loongarch/kernel/mcount_dyn.S
26451 views
1
/* SPDX-License-Identifier: GPL-2.0 */
2
/*
3
* Copyright (C) 2022 Loongson Technology Corporation Limited
4
*/
5
6
#include <asm/ftrace.h>
7
#include <asm/regdef.h>
8
#include <asm/stackframe.h>
9
10
.text
11
/*
12
* Due to -fpatchable-function-entry=2: the compiler inserted 2 NOPs before the
13
* regular C function prologue. When PC arrived here, the last 2 instructions
14
* are as follows:
15
* move t0, ra
16
* bl callsite (for modules, callsite is a tramplione)
17
*
18
* modules trampoline is as follows:
19
* lu12i.w t1, callsite[31:12]
20
* lu32i.d t1, callsite[51:32]
21
* lu52i.d t1, t1, callsite[63:52]
22
* jirl zero, t1, callsite[11:0] >> 2
23
*
24
* See arch/loongarch/kernel/ftrace_dyn.c for details. Here, pay attention to
25
* that the T series regs are available and safe because each C functions
26
* follows the LoongArch's psABI as well.
27
*/
28
29
.macro ftrace_regs_entry allregs=0
30
PTR_ADDI sp, sp, -PT_SIZE
31
PTR_S t0, sp, PT_R1 /* Save parent ra at PT_R1(RA) */
32
PTR_S a0, sp, PT_R4
33
PTR_S a1, sp, PT_R5
34
PTR_S a2, sp, PT_R6
35
PTR_S a3, sp, PT_R7
36
PTR_S a4, sp, PT_R8
37
PTR_S a5, sp, PT_R9
38
PTR_S a6, sp, PT_R10
39
PTR_S a7, sp, PT_R11
40
PTR_S fp, sp, PT_R22
41
.if \allregs
42
PTR_S tp, sp, PT_R2
43
PTR_S t0, sp, PT_R12
44
PTR_S t2, sp, PT_R14
45
PTR_S t3, sp, PT_R15
46
PTR_S t4, sp, PT_R16
47
PTR_S t5, sp, PT_R17
48
PTR_S t6, sp, PT_R18
49
PTR_S t7, sp, PT_R19
50
PTR_S t8, sp, PT_R20
51
PTR_S u0, sp, PT_R21
52
PTR_S s0, sp, PT_R23
53
PTR_S s1, sp, PT_R24
54
PTR_S s2, sp, PT_R25
55
PTR_S s3, sp, PT_R26
56
PTR_S s4, sp, PT_R27
57
PTR_S s5, sp, PT_R28
58
PTR_S s6, sp, PT_R29
59
PTR_S s7, sp, PT_R30
60
PTR_S s8, sp, PT_R31
61
/* Clear it for later use as a flag sometimes. */
62
PTR_S zero, sp, PT_R0
63
.endif
64
PTR_S ra, sp, PT_ERA /* Save trace function ra at PT_ERA */
65
move t1, zero
66
PTR_S t1, sp, PT_R13
67
PTR_ADDI t8, sp, PT_SIZE
68
PTR_S t8, sp, PT_R3
69
.endm
70
71
SYM_FUNC_START(ftrace_stub)
72
jr ra
73
SYM_FUNC_END(ftrace_stub)
74
75
SYM_CODE_START(ftrace_common)
76
UNWIND_HINT_UNDEFINED
77
PTR_ADDI a0, ra, -8 /* arg0: ip */
78
move a1, t0 /* arg1: parent_ip */
79
la.pcrel t1, function_trace_op
80
PTR_L a2, t1, 0 /* arg2: op */
81
move a3, sp /* arg3: regs */
82
83
SYM_INNER_LABEL(ftrace_call, SYM_L_GLOBAL)
84
bl ftrace_stub
85
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
86
SYM_INNER_LABEL(ftrace_graph_call, SYM_L_GLOBAL)
87
nop /* b ftrace_graph_caller */
88
#endif
89
90
/*
91
* As we didn't use S series regs in this assmembly code and all calls
92
* are C function which will save S series regs by themselves, there is
93
* no need to restore S series regs. The T series is available and safe
94
* at the callsite, so there is no need to restore the T series regs.
95
*/
96
ftrace_common_return:
97
PTR_L ra, sp, PT_R1
98
PTR_L a0, sp, PT_R4
99
PTR_L a1, sp, PT_R5
100
PTR_L a2, sp, PT_R6
101
PTR_L a3, sp, PT_R7
102
PTR_L a4, sp, PT_R8
103
PTR_L a5, sp, PT_R9
104
PTR_L a6, sp, PT_R10
105
PTR_L a7, sp, PT_R11
106
PTR_L fp, sp, PT_R22
107
PTR_L t0, sp, PT_ERA
108
PTR_L t1, sp, PT_R13
109
PTR_ADDI sp, sp, PT_SIZE
110
bnez t1, .Ldirect
111
jr t0
112
.Ldirect:
113
jr t1
114
SYM_CODE_END(ftrace_common)
115
116
SYM_CODE_START(ftrace_caller)
117
UNWIND_HINT_UNDEFINED
118
ftrace_regs_entry allregs=0
119
b ftrace_common
120
SYM_CODE_END(ftrace_caller)
121
122
#ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS
123
SYM_CODE_START(ftrace_regs_caller)
124
UNWIND_HINT_UNDEFINED
125
ftrace_regs_entry allregs=1
126
b ftrace_common
127
SYM_CODE_END(ftrace_regs_caller)
128
#endif
129
130
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
131
SYM_CODE_START(ftrace_graph_caller)
132
UNWIND_HINT_UNDEFINED
133
PTR_L a0, sp, PT_ERA
134
PTR_ADDI a0, a0, -8 /* arg0: self_addr */
135
PTR_ADDI a1, sp, PT_R1 /* arg1: parent */
136
bl prepare_ftrace_return
137
b ftrace_common_return
138
SYM_CODE_END(ftrace_graph_caller)
139
140
SYM_CODE_START(return_to_handler)
141
UNWIND_HINT_UNDEFINED
142
/* Save return value regs */
143
PTR_ADDI sp, sp, -PT_SIZE
144
PTR_S a0, sp, PT_R4
145
PTR_S a1, sp, PT_R5
146
PTR_S zero, sp, PT_R22
147
148
move a0, sp
149
bl ftrace_return_to_handler
150
move ra, a0
151
152
/* Restore return value regs */
153
PTR_L a0, sp, PT_R4
154
PTR_L a1, sp, PT_R5
155
PTR_ADDI sp, sp, PT_SIZE
156
157
jr ra
158
SYM_CODE_END(return_to_handler)
159
#endif
160
161
#ifdef CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS
162
SYM_CODE_START(ftrace_stub_direct_tramp)
163
UNWIND_HINT_UNDEFINED
164
jr t0
165
SYM_CODE_END(ftrace_stub_direct_tramp)
166
#endif /* CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS */
167
168