^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /* SPDX-License-Identifier: GPL-2.0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (C) 2000 Anton Blanchard (anton@linuxcare.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * This file implements mcount(), which is used to collect profiling data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * This can also be tweaked for kernel stack overflow detection.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/linkage.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <asm/export.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * This is the main variant and is called by C code. GCC's -pg option
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * automatically instruments every C function with a call to this.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) .text
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) .align 32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) .globl _mcount
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) .type _mcount,#function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) EXPORT_SYMBOL(_mcount)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) .globl mcount
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) .type mcount,#function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) _mcount:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) mcount:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #ifdef CONFIG_FUNCTION_TRACER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #ifdef CONFIG_DYNAMIC_FTRACE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) /* Do nothing, the retl/nop below is all we need. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) sethi %hi(ftrace_trace_function), %g1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) sethi %hi(ftrace_stub), %g2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) ldx [%g1 + %lo(ftrace_trace_function)], %g1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) or %g2, %lo(ftrace_stub), %g2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) cmp %g1, %g2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) be,pn %icc, 1f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) mov %i7, %g3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) save %sp, -176, %sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) mov %g3, %o1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) jmpl %g1, %o7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) mov %i7, %o0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) ret
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) restore
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) /* not reached */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #ifdef CONFIG_FUNCTION_GRAPH_TRACER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) sethi %hi(ftrace_graph_return), %g1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) ldx [%g1 + %lo(ftrace_graph_return)], %g3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) cmp %g2, %g3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) bne,pn %xcc, 5f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) sethi %hi(ftrace_graph_entry_stub), %g2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) sethi %hi(ftrace_graph_entry), %g1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) or %g2, %lo(ftrace_graph_entry_stub), %g2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) ldx [%g1 + %lo(ftrace_graph_entry)], %g1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) cmp %g1, %g2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) be,pt %xcc, 2f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) 5: mov %i7, %g2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) mov %fp, %g3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) save %sp, -176, %sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) mov %g2, %l0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) ba,pt %xcc, ftrace_graph_caller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) mov %g3, %l1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) retl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) .size _mcount,.-_mcount
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) .size mcount,.-mcount
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #ifdef CONFIG_FUNCTION_TRACER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) .globl ftrace_stub
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) .type ftrace_stub,#function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) ftrace_stub:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) retl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) .size ftrace_stub,.-ftrace_stub
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #ifdef CONFIG_DYNAMIC_FTRACE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) .globl ftrace_caller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) .type ftrace_caller,#function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) ftrace_caller:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) mov %i7, %g2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) mov %fp, %g3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) save %sp, -176, %sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) mov %g2, %o1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) mov %g2, %l0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) mov %g3, %l1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) .globl ftrace_call
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) ftrace_call:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) call ftrace_stub
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) mov %i7, %o0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) #ifdef CONFIG_FUNCTION_GRAPH_TRACER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) .globl ftrace_graph_call
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) ftrace_graph_call:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) call ftrace_stub
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) ret
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) restore
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) #ifdef CONFIG_FUNCTION_GRAPH_TRACER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) .size ftrace_graph_call,.-ftrace_graph_call
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) .size ftrace_call,.-ftrace_call
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) .size ftrace_caller,.-ftrace_caller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) #ifdef CONFIG_FUNCTION_GRAPH_TRACER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) ENTRY(ftrace_graph_caller)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) mov %l0, %o0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) mov %i7, %o1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) call prepare_ftrace_return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) mov %l1, %o2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) ret
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) restore %o0, -8, %i7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) END(ftrace_graph_caller)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) ENTRY(return_to_handler)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) save %sp, -176, %sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) call ftrace_return_to_handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) mov %fp, %o0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) jmpl %o0 + 8, %g0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) restore
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) END(return_to_handler)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) #endif