Re: [PATCH] uprobes: Restore original return address in uretprobe context
daichengrong <[email protected]>
| Newsgroups | org.infradead.lists.linux-riscv,org.kernel.vger.linux-kernel,org.kernel.vger.linux-trace-kernel |
|---|---|
| Message-ID | <[email protected]> |
On 7/23/26 08:31, Masami Hiramatsu (Google) wrote: > On Fri, 17 Jul 2026 16:23:31 +0800 > daichengrong <[email protected]> wrote: > >> uretprobe replaces the original return address of a probed function with >> a trampoline address to capture function return events. >> >> After the trampoline is entered and the uretprobe handler completes, the >> original return address needs to be restored in the user register context >> to keep the register state consistent with the state before probing. >> >> Add an architecture-specific hook for restoring the original return >> address during uretprobe handling. >> >> The initial implementation adds support for RISC-V. Other architectures >> keep the default empty implementation until their corresponding restore >> logic is implemented. >> >> Signed-off-by: daichengrong <[email protected]> >> --- >> arch/riscv/kernel/probes/uprobes.c | 7 +++++++ >> include/linux/uprobes.h | 1 + >> kernel/events/uprobes.c | 5 +++++ >> 3 files changed, 13 insertions(+) >> >> diff --git a/arch/riscv/kernel/probes/uprobes.c b/arch/riscv/kernel/probes/uprobes.c >> index eb177d0ce8ab..0b1b94d9683e 100644 >> --- a/arch/riscv/kernel/probes/uprobes.c >> +++ b/arch/riscv/kernel/probes/uprobes.c >> @@ -139,6 +139,13 @@ arch_uretprobe_hijack_return_addr(unsigned long trampoline_vaddr, >> return ra; >> } >> >> +void >> +arch_uretprobe_hijack_set_addr(unsigned long orig_ret_vaddr, >> + struct pt_regs *regs) > > OK, but hijack may not be a good naming, what about > "arch_uretprobe_restore_return_address()"? Thanks for the suggestion. I’ve renamed the function in v2 as suggested: https://lore.kernel.org/all/[email protected]/ Thanks, > > And I need RISC-V maintainer's review. > > Thank you, > >> +{ >> + regs->ra = orig_ret_vaddr; >> +} >> + >> int arch_uprobe_exception_notify(struct notifier_block *self, >> unsigned long val, void *data) >> { >> diff --git a/include/linux/uprobes.h b/include/linux/uprobes.h >> index f548fea2adec..2d0dc919845d 100644 >> --- a/include/linux/uprobes.h >> +++ b/include/linux/uprobes.h >> @@ -230,6 +230,7 @@ extern bool arch_uprobe_xol_was_trapped(struct task_struct *tsk); >> extern int arch_uprobe_exception_notify(struct notifier_block *self, unsigned long val, void *data); >> extern void arch_uprobe_abort_xol(struct arch_uprobe *aup, struct pt_regs *regs); >> extern unsigned long arch_uretprobe_hijack_return_addr(unsigned long trampoline_vaddr, struct pt_regs *regs); >> +extern void arch_uretprobe_hijack_set_addr(unsigned long orig_ret_vaddr, struct pt_regs *regs); >> extern bool arch_uretprobe_is_alive(struct return_instance *ret, enum rp_check ctx, struct pt_regs *regs); >> extern bool arch_uprobe_ignore(struct arch_uprobe *aup, struct pt_regs *regs); >> extern void arch_uprobe_copy_ixol(struct page *page, unsigned long vaddr, >> diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c >> index 4084e926e284..deecaae01ab7 100644 >> --- a/kernel/events/uprobes.c >> +++ b/kernel/events/uprobes.c >> @@ -1748,6 +1748,10 @@ void * __weak arch_uretprobe_trampoline(unsigned long *psize) >> return &insn; >> } >> >> +void __weak arch_uretprobe_hijack_set_addr(unsigned long orig_ret_vaddr, struct pt_regs *regs) >> +{ >> +} >> + >> static struct xol_area *__create_xol_area(unsigned long vaddr) >> { >> struct mm_struct *mm = current->mm; >> @@ -2659,6 +2663,7 @@ void uprobe_handle_trampoline(struct pt_regs *regs) >> valid = !next_chain || arch_uretprobe_is_alive(next_chain, RP_CHECK_RET, regs); >> >> instruction_pointer_set(regs, ri->orig_ret_vaddr); >> + arch_uretprobe_hijack_set_addr(ri->orig_ret_vaddr, regs); >> do { >> /* pop current instance from the stack of pending return instances, >> * as it's not pending anymore: we just fixed up original >> -- >> 2.25.1 >> >> > > -- Chengrong _______________________________________________ linux-riscv mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-riscv