]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
LoongArch: Refactor register restoration in ftrace_common_return
authorChenghao Duan <duanchenghao@kylinos.cn>
Wed, 31 Dec 2025 07:19:20 +0000 (15:19 +0800)
committerHuacai Chen <chenhuacai@loongson.cn>
Wed, 31 Dec 2025 07:19:20 +0000 (15:19 +0800)
Refactor the register restoration sequence in the ftrace_common_return
function to clearly distinguish between the logic of normal returns and
direct call returns in function tracing scenarios. The logic is as
follows:

1. In the case of a normal return, the execution flow returns to the
traced function, and ftrace must ensure that the register data is
consistent with the state when the function was entered.

ra = parent return address; t0 = traced function return address.

2. In the case of a direct call return, the execution flow jumps to the
custom trampoline function, and ftrace must ensure that the register
data is consistent with the state when ftrace was entered.

ra = traced function return address; t0 = parent return address.

Cc: stable@vger.kernel.org
Fixes: 9cdc3b6a299c ("LoongArch: ftrace: Add direct call support")
Signed-off-by: Chenghao Duan <duanchenghao@kylinos.cn>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
arch/loongarch/kernel/mcount_dyn.S

index d6b474ad1d5e5518ec11efb94a88f99dfa103cc4..5729c20e5b8b0ee719918f28f9afc2c374b7c34d 100644 (file)
@@ -94,7 +94,6 @@ SYM_INNER_LABEL(ftrace_graph_call, SYM_L_GLOBAL)
  * at the callsite, so there is no need to restore the T series regs.
  */
 ftrace_common_return:
-       PTR_L           ra, sp, PT_R1
        PTR_L           a0, sp, PT_R4
        PTR_L           a1, sp, PT_R5
        PTR_L           a2, sp, PT_R6
@@ -104,12 +103,17 @@ ftrace_common_return:
        PTR_L           a6, sp, PT_R10
        PTR_L           a7, sp, PT_R11
        PTR_L           fp, sp, PT_R22
-       PTR_L           t0, sp, PT_ERA
        PTR_L           t1, sp, PT_R13
-       PTR_ADDI        sp, sp, PT_SIZE
        bnez            t1, .Ldirect
+
+       PTR_L           ra, sp, PT_R1
+       PTR_L           t0, sp, PT_ERA
+       PTR_ADDI        sp, sp, PT_SIZE
        jr              t0
 .Ldirect:
+       PTR_L           t0, sp, PT_R1
+       PTR_L           ra, sp, PT_ERA
+       PTR_ADDI        sp, sp, PT_SIZE
        jr              t1
 SYM_CODE_END(ftrace_common)
 
@@ -161,6 +165,8 @@ SYM_CODE_END(return_to_handler)
 #ifdef CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS
 SYM_CODE_START(ftrace_stub_direct_tramp)
        UNWIND_HINT_UNDEFINED
-       jr              t0
+       move            t1, ra
+       move            ra, t0
+       jr              t1
 SYM_CODE_END(ftrace_stub_direct_tramp)
 #endif /* CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS */