]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
arm64: probes: Break ret out from bl/blr
authorJeremy Linton <jeremy.linton@arm.com>
Mon, 25 Aug 2025 03:34:15 +0000 (22:34 -0500)
committerWill Deacon <will@kernel.org>
Tue, 16 Sep 2025 19:31:44 +0000 (20:31 +0100)
Prepare for GCS by breaking RET out into its own function, where
it makes more sense to encapsulate the new behavior independent
from the branch instructions.

Signed-off-by: Jeremy Linton <jeremy.linton@arm.com>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Will Deacon <will@kernel.org>
arch/arm64/kernel/probes/decode-insn.c
arch/arm64/kernel/probes/simulate-insn.c
arch/arm64/kernel/probes/simulate-insn.h

index 6438bf62e753f3db93b5c778ea677c29d57057cc..4137cc5ef031f6f94018db2219695757110f55f0 100644 (file)
@@ -108,9 +108,10 @@ arm_probe_decode_insn(u32 insn, struct arch_probe_insn *api)
            aarch64_insn_is_bl(insn)) {
                api->handler = simulate_b_bl;
        } else if (aarch64_insn_is_br(insn) ||
-           aarch64_insn_is_blr(insn) ||
-           aarch64_insn_is_ret(insn)) {
-               api->handler = simulate_br_blr_ret;
+               aarch64_insn_is_blr(insn)) {
+               api->handler = simulate_br_blr;
+       } else if (aarch64_insn_is_ret(insn)) {
+               api->handler = simulate_ret;
        } else {
                /*
                 * Instruction cannot be stepped out-of-line and we don't
index 4c6d2d712fbd3c4ed5c7cc38eb6be0348d4e1034..09a0b36122d0109dfc93834eeb011f9ce60ca444 100644 (file)
@@ -126,7 +126,7 @@ simulate_b_cond(u32 opcode, long addr, struct pt_regs *regs)
 }
 
 void __kprobes
-simulate_br_blr_ret(u32 opcode, long addr, struct pt_regs *regs)
+simulate_br_blr(u32 opcode, long addr, struct pt_regs *regs)
 {
        int xn = (opcode >> 5) & 0x1f;
 
@@ -138,6 +138,14 @@ simulate_br_blr_ret(u32 opcode, long addr, struct pt_regs *regs)
                set_x_reg(regs, 30, addr + 4);
 }
 
+void __kprobes
+simulate_ret(u32 opcode, long addr, struct pt_regs *regs)
+{
+       int xn = (opcode >> 5) & 0x1f;
+
+       instruction_pointer_set(regs, get_x_reg(regs, xn));
+}
+
 void __kprobes
 simulate_cbz_cbnz(u32 opcode, long addr, struct pt_regs *regs)
 {
index efb2803ec943d6e3443e2b311edbed10c4acecf0..9e772a292d565db2e044d0f7042a0413c02438d3 100644 (file)
@@ -11,7 +11,8 @@
 void simulate_adr_adrp(u32 opcode, long addr, struct pt_regs *regs);
 void simulate_b_bl(u32 opcode, long addr, struct pt_regs *regs);
 void simulate_b_cond(u32 opcode, long addr, struct pt_regs *regs);
-void simulate_br_blr_ret(u32 opcode, long addr, struct pt_regs *regs);
+void simulate_br_blr(u32 opcode, long addr, struct pt_regs *regs);
+void simulate_ret(u32 opcode, long addr, struct pt_regs *regs);
 void simulate_cbz_cbnz(u32 opcode, long addr, struct pt_regs *regs);
 void simulate_tbz_tbnz(u32 opcode, long addr, struct pt_regs *regs);
 void simulate_ldr_literal(u32 opcode, long addr, struct pt_regs *regs);