[PATCH 18/29] x86/ibt,ftrace: Annotate ftrace code patching

From: Peter Zijlstra
Date: Fri Feb 18 2022 - 12:16:42 EST


Notably the noinline is required to generate sane code; without it GCC
think's it's awesome to fold in a constant to the code reloc which
puts it in the wrong place to match with the ANNOTATE_NOENDBR.

Signed-off-by: Peter Zijlstra (Intel) <peterz@xxxxxxxxxxxxx>
---
arch/x86/kernel/ftrace.c | 2 +-
arch/x86/kernel/ftrace_64.S | 9 +++++++++
2 files changed, 10 insertions(+), 1 deletion(-)

--- a/arch/x86/kernel/ftrace.c
+++ b/arch/x86/kernel/ftrace.c
@@ -69,7 +69,7 @@ static const char *ftrace_nop_replace(vo
return x86_nops[5];
}

-static const char *ftrace_call_replace(unsigned long ip, unsigned long addr)
+static noinline const char *ftrace_call_replace(unsigned long ip, unsigned long addr)
{
return text_gen_insn(CALL_INSN_OPCODE, (void *)ip, (void *)addr);
}
--- a/arch/x86/kernel/ftrace_64.S
+++ b/arch/x86/kernel/ftrace_64.S
@@ -145,6 +145,7 @@ SYM_FUNC_START(ftrace_caller)
movq %rcx, RSP(%rsp)

SYM_INNER_LABEL(ftrace_caller_op_ptr, SYM_L_GLOBAL)
+ ANNOTATE_NOENDBR
/* Load the ftrace_ops into the 3rd parameter */
movq function_trace_op(%rip), %rdx

@@ -155,6 +156,7 @@ SYM_INNER_LABEL(ftrace_caller_op_ptr, SY
movq $0, CS(%rsp)

SYM_INNER_LABEL(ftrace_call, SYM_L_GLOBAL)
+ ANNOTATE_NOENDBR
call ftrace_stub

/* Handlers can change the RIP */
@@ -169,6 +171,7 @@ SYM_INNER_LABEL(ftrace_call, SYM_L_GLOBA
* layout here.
*/
SYM_INNER_LABEL(ftrace_caller_end, SYM_L_GLOBAL)
+ ANNOTATE_NOENDBR

jmp ftrace_epilogue
SYM_FUNC_END(ftrace_caller);
@@ -179,6 +182,7 @@ SYM_FUNC_START(ftrace_epilogue)
* It is also used to copy the RET for trampolines.
*/
SYM_INNER_LABEL_ALIGN(ftrace_stub, SYM_L_WEAK)
+ ANNOTATE_NOENDBR
UNWIND_HINT_FUNC
RET
SYM_FUNC_END(ftrace_epilogue)
@@ -192,6 +196,7 @@ SYM_FUNC_START(ftrace_regs_caller)
/* save_mcount_regs fills in first two parameters */

SYM_INNER_LABEL(ftrace_regs_caller_op_ptr, SYM_L_GLOBAL)
+ ANNOTATE_NOENDBR
/* Load the ftrace_ops into the 3rd parameter */
movq function_trace_op(%rip), %rdx

@@ -221,6 +226,7 @@ SYM_INNER_LABEL(ftrace_regs_caller_op_pt
leaq (%rsp), %rcx

SYM_INNER_LABEL(ftrace_regs_call, SYM_L_GLOBAL)
+ ANNOTATE_NOENDBR
call ftrace_stub

/* Copy flags back to SS, to restore them */
@@ -248,6 +254,7 @@ SYM_INNER_LABEL(ftrace_regs_call, SYM_L_
*/
testq %rax, %rax
SYM_INNER_LABEL(ftrace_regs_caller_jmp, SYM_L_GLOBAL)
+ ANNOTATE_NOENDBR
jnz 1f

restore_mcount_regs
@@ -261,6 +268,7 @@ SYM_INNER_LABEL(ftrace_regs_caller_jmp,
* to the return.
*/
SYM_INNER_LABEL(ftrace_regs_caller_end, SYM_L_GLOBAL)
+ ANNOTATE_NOENDBR
jmp ftrace_epilogue

/* Swap the flags with orig_rax */
@@ -284,6 +292,7 @@ SYM_FUNC_START(__fentry__)
jnz trace

SYM_INNER_LABEL(ftrace_stub, SYM_L_GLOBAL)
+ ANNOTATE_NOENDBR
RET

trace: