Skip to content

Commit 6300129

Browse files
image-dragonKernel Patches Daemon
authored andcommitted
x86/ftrace: implement DYNAMIC_FTRACE_WITH_JMP
Implement the DYNAMIC_FTRACE_WITH_JMP for x86_64. In ftrace_call_replace, we will use JMP32_INSN_OPCODE instead of CALL_INSN_OPCODE if the address should use "jmp". Meanwhile, adjust the direct call in the ftrace_regs_caller. The RSB is balanced in the "jmp" mode. Take the function "foo" for example: original_caller: call foo -> foo: call fentry -> fentry: [do ftrace callbacks ] move tramp_addr to stack RET -> tramp_addr tramp_addr: [..] call foo_body -> foo_body: [..] RET -> back to tramp_addr [..] RET -> back to original_caller Signed-off-by: Menglong Dong <[email protected]>
1 parent 8b0ca38 commit 6300129

File tree

3 files changed

+18
-2
lines changed

3 files changed

+18
-2
lines changed

arch/x86/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,7 @@ config X86
230230
select HAVE_DYNAMIC_FTRACE_WITH_ARGS if X86_64
231231
select HAVE_FTRACE_REGS_HAVING_PT_REGS if X86_64
232232
select HAVE_DYNAMIC_FTRACE_WITH_DIRECT_CALLS
233+
select HAVE_DYNAMIC_FTRACE_WITH_JMP if X86_64
233234
select HAVE_SAMPLE_FTRACE_DIRECT if X86_64
234235
select HAVE_SAMPLE_FTRACE_DIRECT_MULTI if X86_64
235236
select HAVE_EBPF_JIT

arch/x86/kernel/ftrace.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,12 @@ static const char *ftrace_call_replace(unsigned long ip, unsigned long addr)
7474
* No need to translate into a callthunk. The trampoline does
7575
* the depth accounting itself.
7676
*/
77-
return text_gen_insn(CALL_INSN_OPCODE, (void *)ip, (void *)addr);
77+
if (ftrace_is_jmp(addr)) {
78+
addr = ftrace_jmp_get(addr);
79+
return text_gen_insn(JMP32_INSN_OPCODE, (void *)ip, (void *)addr);
80+
} else {
81+
return text_gen_insn(CALL_INSN_OPCODE, (void *)ip, (void *)addr);
82+
}
7883
}
7984

8085
static int ftrace_verify_code(unsigned long ip, const char *old_code)

arch/x86/kernel/ftrace_64.S

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -285,8 +285,18 @@ SYM_INNER_LABEL(ftrace_regs_caller_end, SYM_L_GLOBAL)
285285
ANNOTATE_NOENDBR
286286
RET
287287

288+
1:
289+
testb $1, %al
290+
jz 2f
291+
andq $0xfffffffffffffffe, %rax
292+
movq %rax, MCOUNT_REG_SIZE+8(%rsp)
293+
restore_mcount_regs
294+
/* Restore flags */
295+
popfq
296+
RET
297+
288298
/* Swap the flags with orig_rax */
289-
1: movq MCOUNT_REG_SIZE(%rsp), %rdi
299+
2: movq MCOUNT_REG_SIZE(%rsp), %rdi
290300
movq %rdi, MCOUNT_REG_SIZE-8(%rsp)
291301
movq %rax, MCOUNT_REG_SIZE(%rsp)
292302

0 commit comments

Comments
 (0)