^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) 2017 Steven Rostedt, VMware Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <linux/linkage.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <asm/page_types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <asm/segment.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <asm/export.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <asm/ftrace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <asm/nospec-branch.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <asm/frame.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <asm/asm-offsets.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #ifdef CONFIG_FRAME_POINTER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) # define MCOUNT_FRAME 1 /* using frame = true */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) # define MCOUNT_FRAME 0 /* using frame = false */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) SYM_FUNC_START(__fentry__)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) ret
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) SYM_FUNC_END(__fentry__)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) EXPORT_SYMBOL(__fentry__)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) SYM_CODE_START(ftrace_caller)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #ifdef CONFIG_FRAME_POINTER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * Frame pointers are of ip followed by bp.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * Since fentry is an immediate jump, we are left with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) * parent-ip, function-ip. We need to add a frame with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) * parent-ip followed by ebp.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) pushl 4(%esp) /* parent ip */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) pushl %ebp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) movl %esp, %ebp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) pushl 2*4(%esp) /* function ip */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) /* For mcount, the function ip is directly above */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) pushl %ebp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) movl %esp, %ebp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) pushl %eax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) pushl %ecx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) pushl %edx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) pushl $0 /* Pass NULL as regs pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #ifdef CONFIG_FRAME_POINTER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) /* Load parent ebp into edx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) movl 4*4(%esp), %edx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) /* There's no frame pointer, load the appropriate stack addr instead */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) lea 4*4(%esp), %edx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) movl (MCOUNT_FRAME+4)*4(%esp), %eax /* load the rip */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) /* Get the parent ip */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) movl 4(%edx), %edx /* edx has ebp */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) movl function_trace_op, %ecx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) subl $MCOUNT_INSN_SIZE, %eax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) .globl ftrace_call
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) ftrace_call:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) call ftrace_stub
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) addl $4, %esp /* skip NULL pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) popl %edx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) popl %ecx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) popl %eax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #ifdef CONFIG_FRAME_POINTER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) popl %ebp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) addl $4,%esp /* skip function ip */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) popl %ebp /* this is the orig bp */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) addl $4, %esp /* skip parent ip */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) .Lftrace_ret:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #ifdef CONFIG_FUNCTION_GRAPH_TRACER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) .globl ftrace_graph_call
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) ftrace_graph_call:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) jmp ftrace_stub
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) /* This is weak to keep gas from relaxing the jumps */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) SYM_INNER_LABEL_ALIGN(ftrace_stub, SYM_L_WEAK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) ret
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) SYM_CODE_END(ftrace_caller)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) SYM_CODE_START(ftrace_regs_caller)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) * We're here from an mcount/fentry CALL, and the stack frame looks like:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) * <previous context>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) * RET-IP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) * The purpose of this function is to call out in an emulated INT3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) * environment with a stack frame like:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) * <previous context>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) * gap / RET-IP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) * gap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) * gap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) * gap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) * pt_regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) * We do _NOT_ restore: ss, flags, cs, gs, fs, es, ds
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) subl $3*4, %esp # RET-IP + 3 gaps
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) pushl %ss # ss
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) pushl %esp # points at ss
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) addl $5*4, (%esp) # make it point at <previous context>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) pushfl # flags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) pushl $__KERNEL_CS # cs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) pushl 7*4(%esp) # ip <- RET-IP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) pushl $0 # orig_eax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) pushl %gs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) pushl %fs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) pushl %es
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) pushl %ds
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) pushl %eax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) pushl %ebp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) pushl %edi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) pushl %esi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) pushl %edx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) pushl %ecx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) pushl %ebx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) ENCODE_FRAME_POINTER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) movl PT_EIP(%esp), %eax # 1st argument: IP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) subl $MCOUNT_INSN_SIZE, %eax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) movl 21*4(%esp), %edx # 2nd argument: parent ip
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) movl function_trace_op, %ecx # 3rd argument: ftrace_pos
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) pushl %esp # 4th argument: pt_regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) SYM_INNER_LABEL(ftrace_regs_call, SYM_L_GLOBAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) call ftrace_stub
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) addl $4, %esp # skip 4th argument
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) /* place IP below the new SP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) movl PT_OLDESP(%esp), %eax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) movl PT_EIP(%esp), %ecx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) movl %ecx, -4(%eax)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) /* place EAX below that */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) movl PT_EAX(%esp), %ecx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) movl %ecx, -8(%eax)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) popl %ebx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) popl %ecx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) popl %edx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) popl %esi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) popl %edi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) popl %ebp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) lea -8(%eax), %esp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) popl %eax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) jmp .Lftrace_ret
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) SYM_CODE_END(ftrace_regs_caller)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) #ifdef CONFIG_FUNCTION_GRAPH_TRACER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) SYM_CODE_START(ftrace_graph_caller)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) pushl %eax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) pushl %ecx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) pushl %edx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) movl 3*4(%esp), %eax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) /* Even with frame pointers, fentry doesn't have one here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) lea 4*4(%esp), %edx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) movl $0, %ecx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) subl $MCOUNT_INSN_SIZE, %eax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) call prepare_ftrace_return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) popl %edx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) popl %ecx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) popl %eax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) ret
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) SYM_CODE_END(ftrace_graph_caller)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) .globl return_to_handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) return_to_handler:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) pushl %eax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) pushl %edx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) movl $0, %eax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) call ftrace_return_to_handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) movl %eax, %ecx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) popl %edx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) popl %eax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) JMP_NOSPEC ecx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) #endif