hc
2023-11-23 7d07b3ae8ddad407913c5301877e694430a3263f
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright (C) 2017 Andes Technology Corporation */
 
#include <linux/init.h>
#include <linux/linkage.h>
#include <asm/asm.h>
#include <asm/csr.h>
#include <asm/unistd.h>
#include <asm/thread_info.h>
#include <asm/asm-offsets.h>
#include <asm-generic/export.h>
#include <asm/ftrace.h>
 
   .text
 
   .macro SAVE_ABI_STATE
   addi    sp, sp, -16
   sd    s0, 0(sp)
   sd    ra, 8(sp)
   addi    s0, sp, 16
   .endm
 
   /*
    * The call to ftrace_return_to_handler would overwrite the return
    * register if a0 was not saved.
    */
   .macro SAVE_RET_ABI_STATE
   addi    sp, sp, -32
   sd    s0, 16(sp)
   sd    ra, 24(sp)
   sd    a0, 8(sp)
   addi    s0, sp, 32
   .endm
 
   .macro RESTORE_ABI_STATE
   ld    ra, 8(sp)
   ld    s0, 0(sp)
   addi    sp, sp, 16
   .endm
 
   .macro RESTORE_RET_ABI_STATE
   ld    ra, 24(sp)
   ld    s0, 16(sp)
   ld    a0, 8(sp)
   addi    sp, sp, 32
   .endm
 
ENTRY(ftrace_stub)
#ifdef CONFIG_DYNAMIC_FTRACE
       .global MCOUNT_NAME
       .set    MCOUNT_NAME, ftrace_stub
#endif
   ret
ENDPROC(ftrace_stub)
 
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
ENTRY(return_to_handler)
/*
 * On implementing the frame point test, the ideal way is to compare the
 * s0 (frame pointer, if enabled) on entry and the sp (stack pointer) on return.
 * However, the psABI of variable-length-argument functions does not allow this.
 *
 * So alternatively we check the *old* frame pointer position, that is, the
 * value stored in -16(s0) on entry, and the s0 on return.
 */
#ifdef HAVE_FUNCTION_GRAPH_FP_TEST
   mv    t6, s0
#endif
   SAVE_RET_ABI_STATE
#ifdef HAVE_FUNCTION_GRAPH_FP_TEST
   mv    a0, t6
#endif
   call    ftrace_return_to_handler
   mv    a1, a0
   RESTORE_RET_ABI_STATE
   jalr    a1
ENDPROC(return_to_handler)
EXPORT_SYMBOL(return_to_handler)
#endif
 
#ifndef CONFIG_DYNAMIC_FTRACE
ENTRY(MCOUNT_NAME)
   la    t4, ftrace_stub
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
   la    t0, ftrace_graph_return
   ld    t1, 0(t0)
   bne    t1, t4, do_ftrace_graph_caller
 
   la    t3, ftrace_graph_entry
   ld    t2, 0(t3)
   la    t6, ftrace_graph_entry_stub
   bne    t2, t6, do_ftrace_graph_caller
#endif
   la    t3, ftrace_trace_function
   ld    t5, 0(t3)
   bne    t5, t4, do_trace
   ret
 
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
/*
 * A pseudo representation for the function graph tracer:
 * prepare_to_return(&ra_to_caller_of_caller, ra_to_caller)
 */
do_ftrace_graph_caller:
   addi    a0, s0, -8
   mv    a1, ra
#ifdef HAVE_FUNCTION_GRAPH_FP_TEST
   ld    a2, -16(s0)
#endif
   SAVE_ABI_STATE
   call    prepare_ftrace_return
   RESTORE_ABI_STATE
   ret
#endif
 
/*
 * A pseudo representation for the function tracer:
 * (*ftrace_trace_function)(ra_to_caller, ra_to_caller_of_caller)
 */
do_trace:
   ld    a1, -8(s0)
   mv    a0, ra
 
   SAVE_ABI_STATE
   jalr    t5
   RESTORE_ABI_STATE
   ret
ENDPROC(MCOUNT_NAME)
#endif
EXPORT_SYMBOL(MCOUNT_NAME)