From 9d056b81e6e8d4b82a4ff8143bdfe29d7a1d0fa1 Mon Sep 17 00:00:00 2001 From: Gao Chen Date: Thu, 20 Feb 2025 17:05:34 +0800 Subject: [PATCH 1/2] anolis: sw64: fix ftrace_make_call & ftrace_make_nop ANBZ: #4688 This patch fix the bug by reorganizing the instruction sequence. Signed-off-by: Gao Chen Reviewed-by: He Sheng Signed-off-by: Gu Zitao --- arch/sw_64/kernel/ftrace.c | 18 +++++++++--------- drivers/irqchip/irq-sunway-cpu.c | 3 --- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/arch/sw_64/kernel/ftrace.c b/arch/sw_64/kernel/ftrace.c index 72b4ddb5395f..ac10d18f72a3 100644 --- a/arch/sw_64/kernel/ftrace.c +++ b/arch/sw_64/kernel/ftrace.c @@ -72,15 +72,15 @@ int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) else offset = TI_FTRACE_REGS_ADDR; - insn[0] = SW64_NOP; /* ldl r28,(ftrace_addr_offset)(r8) */ - insn[1] = (0x23U << 26) | (28U << 21) | (8U << 16) | offset; - insn[2] = SW64_CALL(R28, R28, 0); + insn[0] = (0x23U << 26) | (28U << 21) | (8U << 16) | offset; + insn[1] = SW64_CALL(R28, R28, 0); + insn[2] = SW64_NOP; - copy_to_kernel_nofault((void *)pc, insn, SW64_INSN_SIZE); - copy_to_kernel_nofault((void *)(pc + 4), insn + 1, SW64_INSN_SIZE); + *((u32 *)pc) = insn[0]; mb(); - copy_to_kernel_nofault((void *)(pc + 8), insn + 2, SW64_INSN_SIZE); + *((u32 *)(pc + 4)) = insn[1]; + *((u32 *)(pc + 8)) = insn[2]; return 0; } @@ -94,10 +94,10 @@ int ftrace_make_nop(struct module *mod, struct dyn_ftrace *rec, unsigned long pc = rec->ip + MCOUNT_LDGP_SIZE; unsigned int insn[3] = {SW64_NOP, SW64_NOP, SW64_NOP}; - copy_to_kernel_nofault((void *)(pc + 8), insn, SW64_INSN_SIZE); + *((u32 *)(pc + 8)) = insn[2]; + *((u32 *)(pc + 4)) = insn[1]; mb(); - copy_to_kernel_nofault((void *)(pc + 4), insn + 1, SW64_INSN_SIZE); - copy_to_kernel_nofault((void *)pc, insn + 2, SW64_INSN_SIZE); + *((u32 *)pc) = insn[0]; return 0; } diff --git a/drivers/irqchip/irq-sunway-cpu.c b/drivers/irqchip/irq-sunway-cpu.c index b54d4388f41e..325408be9a56 100644 --- a/drivers/irqchip/irq-sunway-cpu.c +++ b/drivers/irqchip/irq-sunway-cpu.c @@ -82,9 +82,6 @@ asmlinkage void noinstr do_entInt(unsigned long type, unsigned long vector, struct pt_regs *old_regs; extern char __idle_start[], __idle_end[]; - if (*((u32 *)(regs->pc)) >> 16 == 0x79c) - regs->pc -= 4; - /* restart idle routine if it is interrupted */ if (regs->pc > (u64)__idle_start && regs->pc < (u64)__idle_end) regs->pc = (u64)__idle_start; -- Gitee From c02414ec09243cd24b0c2a9454e7b319067a21c4 Mon Sep 17 00:00:00 2001 From: Gao Chen Date: Thu, 20 Feb 2025 17:22:00 +0800 Subject: [PATCH 2/2] anolis: sw64: fix ftrace_modify_call ANBZ: #4688 This patch fix ftrace_modify_call to accommodate the reorganization. Signed-off-by: Gao Chen Reviewed-by: He Sheng Signed-off-by: Gu Zitao --- arch/sw_64/kernel/ftrace.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/sw_64/kernel/ftrace.c b/arch/sw_64/kernel/ftrace.c index ac10d18f72a3..511760ac18c2 100644 --- a/arch/sw_64/kernel/ftrace.c +++ b/arch/sw_64/kernel/ftrace.c @@ -125,7 +125,7 @@ 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 pc = rec->ip + MCOUNT_LDGP_SIZE; unsigned long offset; if (addr == FTRACE_ADDR) -- Gitee