From 15644804c3c2bd5a8b69f1739e99aea6dbc16206 Mon Sep 17 00:00:00 2001 From: Gao Chen Date: Fri, 14 Feb 2025 15:53:01 +0800 Subject: [PATCH] anolis: sw64: ftrace: implement ftrace_modify_call ANBZ: #4688 In some cases, ftrace needs to call ftrace_modify_call() to change the target address of "call r28" from ftrace_caller to ftrace_regs_caller, the latter of which prepares an additional $19 to pass pt_regs. However, since we implememted ftrace_modify_call() as empty, a subsequent function might use a random value of $19, which could cause panic. This patch implements the ftrace_modify_call(). Signed-off-by: Gao Chen Reviewed-by: He Sheng Signed-off-by: Gu Zitao --- arch/sw_64/kernel/ftrace.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/arch/sw_64/kernel/ftrace.c b/arch/sw_64/kernel/ftrace.c index 335c5b3db1bb..72b4ddb5395f 100644 --- a/arch/sw_64/kernel/ftrace.c +++ b/arch/sw_64/kernel/ftrace.c @@ -124,6 +124,19 @@ int __init ftrace_dyn_arch_init(void) int ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr, unsigned long addr) { + unsigned int insn[1]; + unsigned long pc = rec->ip + MCOUNT_LDGP_SIZE + 4; + unsigned long offset; + + if (addr == FTRACE_ADDR) + offset = TI_FTRACE_ADDR; + else + offset = TI_FTRACE_REGS_ADDR; + + /* ldl r28,(ftrace_addr_offset)(r8) */ + insn[0] = (0x23U << 26) | (28U << 21) | (8U << 16) | offset; + copy_to_kernel_nofault((void *)pc, insn, SW64_INSN_SIZE); + return 0; } #endif -- Gitee