GNU Linux-libre 5.4.274-gnu1
[releases.git] / arch / powerpc / kernel / trace / ftrace_32.S
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 /*
3  * Split from entry_32.S
4  */
5
6 #include <linux/magic.h>
7 #include <asm/reg.h>
8 #include <asm/ppc_asm.h>
9 #include <asm/asm-offsets.h>
10 #include <asm/ftrace.h>
11 #include <asm/export.h>
12
13 _GLOBAL(mcount)
14 _GLOBAL(_mcount)
15         /*
16          * It is required that _mcount on PPC32 must preserve the
17          * link register. But we have r0 to play with. We use r0
18          * to push the return address back to the caller of mcount
19          * into the ctr register, restore the link register and
20          * then jump back using the ctr register.
21          */
22         mflr    r0
23         mtctr   r0
24         lwz     r0, 4(r1)
25         mtlr    r0
26         bctr
27
28 _GLOBAL(ftrace_caller)
29         MCOUNT_SAVE_FRAME
30         /* r3 ends up with link register */
31         subi    r3, r3, MCOUNT_INSN_SIZE
32 .globl ftrace_call
33 ftrace_call:
34         bl      ftrace_stub
35         nop
36 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
37 .globl ftrace_graph_call
38 ftrace_graph_call:
39         b       ftrace_graph_stub
40 _GLOBAL(ftrace_graph_stub)
41 #endif
42         MCOUNT_RESTORE_FRAME
43         /* old link register ends up in ctr reg */
44         bctr
45
46 EXPORT_SYMBOL(_mcount)
47
48 _GLOBAL(ftrace_stub)
49         blr
50
51 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
52 _GLOBAL(ftrace_graph_caller)
53         addi    r5, r1, 48
54         /* load r4 with local address */
55         lwz     r4, 44(r1)
56         subi    r4, r4, MCOUNT_INSN_SIZE
57
58         /* Grab the LR out of the caller stack frame */
59         lwz     r3,52(r1)
60
61         bl      prepare_ftrace_return
62         nop
63
64         /*
65          * prepare_ftrace_return gives us the address we divert to.
66          * Change the LR in the callers stack frame to this.
67          */
68         stw     r3,52(r1)
69
70         MCOUNT_RESTORE_FRAME
71         /* old link register ends up in ctr reg */
72         bctr
73
74 _GLOBAL(return_to_handler)
75         /* need to save return values */
76         stwu    r1, -32(r1)
77         stw     r3, 20(r1)
78         stw     r4, 16(r1)
79         stw     r31, 12(r1)
80         mr      r31, r1
81
82         bl      ftrace_return_to_handler
83         nop
84
85         /* return value has real return address */
86         mtlr    r3
87
88         lwz     r3, 20(r1)
89         lwz     r4, 16(r1)
90         lwz     r31,12(r1)
91         lwz     r1, 0(r1)
92
93         /* Jump back to real return address */
94         blr
95 #endif /* CONFIG_FUNCTION_GRAPH_TRACER */