diff options
Diffstat (limited to 'arch/x86/kernel/entry_64.S')
| -rw-r--r-- | arch/x86/kernel/entry_64.S | 130 |
1 files changed, 116 insertions, 14 deletions
diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S index 1a8f3cbb6ee3..4f0322e4ecee 100644 --- a/arch/x86/kernel/entry_64.S +++ b/arch/x86/kernel/entry_64.S | |||
| @@ -69,25 +69,51 @@ | |||
| 69 | .section .entry.text, "ax" | 69 | .section .entry.text, "ax" |
| 70 | 70 | ||
| 71 | #ifdef CONFIG_FUNCTION_TRACER | 71 | #ifdef CONFIG_FUNCTION_TRACER |
| 72 | |||
| 73 | #ifdef CC_USING_FENTRY | ||
| 74 | # define function_hook __fentry__ | ||
| 75 | #else | ||
| 76 | # define function_hook mcount | ||
| 77 | #endif | ||
| 78 | |||
| 72 | #ifdef CONFIG_DYNAMIC_FTRACE | 79 | #ifdef CONFIG_DYNAMIC_FTRACE |
| 73 | ENTRY(mcount) | 80 | |
| 81 | ENTRY(function_hook) | ||
| 74 | retq | 82 | retq |
| 75 | END(mcount) | 83 | END(function_hook) |
| 84 | |||
| 85 | /* skip is set if stack has been adjusted */ | ||
| 86 | .macro ftrace_caller_setup skip=0 | ||
| 87 | MCOUNT_SAVE_FRAME \skip | ||
| 88 | |||
| 89 | /* Load the ftrace_ops into the 3rd parameter */ | ||
| 90 | leaq function_trace_op, %rdx | ||
| 91 | |||
| 92 | /* Load ip into the first parameter */ | ||
| 93 | movq RIP(%rsp), %rdi | ||
| 94 | subq $MCOUNT_INSN_SIZE, %rdi | ||
| 95 | /* Load the parent_ip into the second parameter */ | ||
| 96 | #ifdef CC_USING_FENTRY | ||
| 97 | movq SS+16(%rsp), %rsi | ||
| 98 | #else | ||
| 99 | movq 8(%rbp), %rsi | ||
| 100 | #endif | ||
| 101 | .endm | ||
| 76 | 102 | ||
| 77 | ENTRY(ftrace_caller) | 103 | ENTRY(ftrace_caller) |
| 104 | /* Check if tracing was disabled (quick check) */ | ||
| 78 | cmpl $0, function_trace_stop | 105 | cmpl $0, function_trace_stop |
| 79 | jne ftrace_stub | 106 | jne ftrace_stub |
| 80 | 107 | ||
| 81 | MCOUNT_SAVE_FRAME | 108 | ftrace_caller_setup |
| 82 | 109 | /* regs go into 4th parameter (but make it NULL) */ | |
| 83 | movq 0x38(%rsp), %rdi | 110 | movq $0, %rcx |
| 84 | movq 8(%rbp), %rsi | ||
| 85 | subq $MCOUNT_INSN_SIZE, %rdi | ||
| 86 | 111 | ||
| 87 | GLOBAL(ftrace_call) | 112 | GLOBAL(ftrace_call) |
| 88 | call ftrace_stub | 113 | call ftrace_stub |
| 89 | 114 | ||
| 90 | MCOUNT_RESTORE_FRAME | 115 | MCOUNT_RESTORE_FRAME |
| 116 | ftrace_return: | ||
| 91 | 117 | ||
| 92 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | 118 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER |
| 93 | GLOBAL(ftrace_graph_call) | 119 | GLOBAL(ftrace_graph_call) |
| @@ -98,8 +124,78 @@ GLOBAL(ftrace_stub) | |||
| 98 | retq | 124 | retq |
| 99 | END(ftrace_caller) | 125 | END(ftrace_caller) |
| 100 | 126 | ||
| 127 | ENTRY(ftrace_regs_caller) | ||
| 128 | /* Save the current flags before compare (in SS location)*/ | ||
| 129 | pushfq | ||
| 130 | |||
| 131 | /* Check if tracing was disabled (quick check) */ | ||
| 132 | cmpl $0, function_trace_stop | ||
| 133 | jne ftrace_restore_flags | ||
| 134 | |||
| 135 | /* skip=8 to skip flags saved in SS */ | ||
| 136 | ftrace_caller_setup 8 | ||
| 137 | |||
| 138 | /* Save the rest of pt_regs */ | ||
| 139 | movq %r15, R15(%rsp) | ||
| 140 | movq %r14, R14(%rsp) | ||
| 141 | movq %r13, R13(%rsp) | ||
| 142 | movq %r12, R12(%rsp) | ||
| 143 | movq %r11, R11(%rsp) | ||
| 144 | movq %r10, R10(%rsp) | ||
| 145 | movq %rbp, RBP(%rsp) | ||
| 146 | movq %rbx, RBX(%rsp) | ||
| 147 | /* Copy saved flags */ | ||
| 148 | movq SS(%rsp), %rcx | ||
| 149 | movq %rcx, EFLAGS(%rsp) | ||
| 150 | /* Kernel segments */ | ||
| 151 | movq $__KERNEL_DS, %rcx | ||
| 152 | movq %rcx, SS(%rsp) | ||
| 153 | movq $__KERNEL_CS, %rcx | ||
| 154 | movq %rcx, CS(%rsp) | ||
| 155 | /* Stack - skipping return address */ | ||
| 156 | leaq SS+16(%rsp), %rcx | ||
| 157 | movq %rcx, RSP(%rsp) | ||
| 158 | |||
| 159 | /* regs go into 4th parameter */ | ||
| 160 | leaq (%rsp), %rcx | ||
| 161 | |||
| 162 | GLOBAL(ftrace_regs_call) | ||
| 163 | call ftrace_stub | ||
| 164 | |||
| 165 | /* Copy flags back to SS, to restore them */ | ||
| 166 | movq EFLAGS(%rsp), %rax | ||
| 167 | movq %rax, SS(%rsp) | ||
| 168 | |||
| 169 | /* Handlers can change the RIP */ | ||
| 170 | movq RIP(%rsp), %rax | ||
| 171 | movq %rax, SS+8(%rsp) | ||
| 172 | |||
| 173 | /* restore the rest of pt_regs */ | ||
| 174 | movq R15(%rsp), %r15 | ||
| 175 | movq R14(%rsp), %r14 | ||
| 176 | movq R13(%rsp), %r13 | ||
| 177 | movq R12(%rsp), %r12 | ||
| 178 | movq R10(%rsp), %r10 | ||
| 179 | movq RBP(%rsp), %rbp | ||
| 180 | movq RBX(%rsp), %rbx | ||
| 181 | |||
| 182 | /* skip=8 to skip flags saved in SS */ | ||
| 183 | MCOUNT_RESTORE_FRAME 8 | ||
| 184 | |||
| 185 | /* Restore flags */ | ||
| 186 | popfq | ||
| 187 | |||
| 188 | jmp ftrace_return | ||
| 189 | ftrace_restore_flags: | ||
| 190 | popfq | ||
| 191 | jmp ftrace_stub | ||
| 192 | |||
| 193 | END(ftrace_regs_caller) | ||
| 194 | |||
| 195 | |||
| 101 | #else /* ! CONFIG_DYNAMIC_FTRACE */ | 196 | #else /* ! CONFIG_DYNAMIC_FTRACE */ |
| 102 | ENTRY(mcount) | 197 | |
| 198 | ENTRY(function_hook) | ||
| 103 | cmpl $0, function_trace_stop | 199 | cmpl $0, function_trace_stop |
| 104 | jne ftrace_stub | 200 | jne ftrace_stub |
| 105 | 201 | ||
| @@ -120,8 +216,12 @@ GLOBAL(ftrace_stub) | |||
| 120 | trace: | 216 | trace: |
| 121 | MCOUNT_SAVE_FRAME | 217 | MCOUNT_SAVE_FRAME |
| 122 | 218 | ||
| 123 | movq 0x38(%rsp), %rdi | 219 | movq RIP(%rsp), %rdi |
| 220 | #ifdef CC_USING_FENTRY | ||
| 221 | movq SS+16(%rsp), %rsi | ||
| 222 | #else | ||
| 124 | movq 8(%rbp), %rsi | 223 | movq 8(%rbp), %rsi |
| 224 | #endif | ||
| 125 | subq $MCOUNT_INSN_SIZE, %rdi | 225 | subq $MCOUNT_INSN_SIZE, %rdi |
| 126 | 226 | ||
| 127 | call *ftrace_trace_function | 227 | call *ftrace_trace_function |
| @@ -129,20 +229,22 @@ trace: | |||
| 129 | MCOUNT_RESTORE_FRAME | 229 | MCOUNT_RESTORE_FRAME |
| 130 | 230 | ||
| 131 | jmp ftrace_stub | 231 | jmp ftrace_stub |
| 132 | END(mcount) | 232 | END(function_hook) |
| 133 | #endif /* CONFIG_DYNAMIC_FTRACE */ | 233 | #endif /* CONFIG_DYNAMIC_FTRACE */ |
| 134 | #endif /* CONFIG_FUNCTION_TRACER */ | 234 | #endif /* CONFIG_FUNCTION_TRACER */ |
| 135 | 235 | ||
| 136 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | 236 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER |
| 137 | ENTRY(ftrace_graph_caller) | 237 | ENTRY(ftrace_graph_caller) |
| 138 | cmpl $0, function_trace_stop | ||
| 139 | jne ftrace_stub | ||
| 140 | |||
| 141 | MCOUNT_SAVE_FRAME | 238 | MCOUNT_SAVE_FRAME |
| 142 | 239 | ||
| 240 | #ifdef CC_USING_FENTRY | ||
| 241 | leaq SS+16(%rsp), %rdi | ||
| 242 | movq $0, %rdx /* No framepointers needed */ | ||
| 243 | #else | ||
| 143 | leaq 8(%rbp), %rdi | 244 | leaq 8(%rbp), %rdi |
| 144 | movq 0x38(%rsp), %rsi | ||
| 145 | movq (%rbp), %rdx | 245 | movq (%rbp), %rdx |
| 246 | #endif | ||
| 247 | movq RIP(%rsp), %rsi | ||
| 146 | subq $MCOUNT_INSN_SIZE, %rsi | 248 | subq $MCOUNT_INSN_SIZE, %rsi |
| 147 | 249 | ||
| 148 | call prepare_ftrace_return | 250 | call prepare_ftrace_return |
