Commit b57c2f12 authored by Binglei Wang's avatar Binglei Wang Committed by Palmer Dabbelt

riscv: add riscv rethook implementation

Implement the kretprobes on riscv arch by using rethook machenism
which abstracts general kretprobe info into a struct rethook_node
to be embedded in the struct kretprobe_instance.
Acked-by: default avatarMasami Hiramatsu (Google) <mhiramat@kernel.org>
Signed-off-by: default avatarBinglei Wang <l3b2w1@gmail.com>
Signed-off-by: default avatarConor Dooley <conor.dooley@microchip.com>
Link: https://lore.kernel.org/r/20221025151831.1097417-1-conor@kernel.orgSigned-off-by: default avatarPalmer Dabbelt <palmer@rivosinc.com>
parent d8bf77a1
...@@ -101,6 +101,7 @@ config RISCV ...@@ -101,6 +101,7 @@ config RISCV
select HAVE_KPROBES if !XIP_KERNEL select HAVE_KPROBES if !XIP_KERNEL
select HAVE_KPROBES_ON_FTRACE if !XIP_KERNEL select HAVE_KPROBES_ON_FTRACE if !XIP_KERNEL
select HAVE_KRETPROBES if !XIP_KERNEL select HAVE_KRETPROBES if !XIP_KERNEL
select HAVE_RETHOOK if !XIP_KERNEL
select HAVE_MOVE_PMD select HAVE_MOVE_PMD
select HAVE_MOVE_PUD select HAVE_MOVE_PUD
select HAVE_PCI select HAVE_PCI
......
...@@ -40,8 +40,6 @@ void arch_remove_kprobe(struct kprobe *p); ...@@ -40,8 +40,6 @@ void arch_remove_kprobe(struct kprobe *p);
int kprobe_fault_handler(struct pt_regs *regs, unsigned int trapnr); int kprobe_fault_handler(struct pt_regs *regs, unsigned int trapnr);
bool kprobe_breakpoint_handler(struct pt_regs *regs); bool kprobe_breakpoint_handler(struct pt_regs *regs);
bool kprobe_single_step_handler(struct pt_regs *regs); bool kprobe_single_step_handler(struct pt_regs *regs);
void __kretprobe_trampoline(void);
void __kprobes *trampoline_probe_handler(struct pt_regs *regs);
#endif /* CONFIG_KPROBES */ #endif /* CONFIG_KPROBES */
#endif /* _ASM_RISCV_KPROBES_H */ #endif /* _ASM_RISCV_KPROBES_H */
# SPDX-License-Identifier: GPL-2.0 # SPDX-License-Identifier: GPL-2.0
obj-$(CONFIG_KPROBES) += kprobes.o decode-insn.o simulate-insn.o obj-$(CONFIG_KPROBES) += kprobes.o decode-insn.o simulate-insn.o
obj-$(CONFIG_KPROBES) += kprobes_trampoline.o obj-$(CONFIG_RETHOOK) += rethook.o rethook_trampoline.o
obj-$(CONFIG_KPROBES_ON_FTRACE) += ftrace.o obj-$(CONFIG_KPROBES_ON_FTRACE) += ftrace.o
obj-$(CONFIG_UPROBES) += uprobes.o decode-insn.o simulate-insn.o obj-$(CONFIG_UPROBES) += uprobes.o decode-insn.o simulate-insn.o
CFLAGS_REMOVE_simulate-insn.o = $(CC_FLAGS_FTRACE) CFLAGS_REMOVE_simulate-insn.o = $(CC_FLAGS_FTRACE)
...@@ -345,19 +345,6 @@ int __init arch_populate_kprobe_blacklist(void) ...@@ -345,19 +345,6 @@ int __init arch_populate_kprobe_blacklist(void)
return ret; return ret;
} }
void __kprobes __used *trampoline_probe_handler(struct pt_regs *regs)
{
return (void *)kretprobe_trampoline_handler(regs, NULL);
}
void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
struct pt_regs *regs)
{
ri->ret_addr = (kprobe_opcode_t *)regs->ra;
ri->fp = NULL;
regs->ra = (unsigned long) &__kretprobe_trampoline;
}
int __kprobes arch_trampoline_kprobe(struct kprobe *p) int __kprobes arch_trampoline_kprobe(struct kprobe *p)
{ {
return 0; return 0;
......
// SPDX-License-Identifier: GPL-2.0-only
/*
* Generic return hook for riscv.
*/
#include <linux/kprobes.h>
#include <linux/rethook.h>
#include "rethook.h"
/* This is called from arch_rethook_trampoline() */
unsigned long __used arch_rethook_trampoline_callback(struct pt_regs *regs)
{
return rethook_trampoline_handler(regs, regs->s0);
}
NOKPROBE_SYMBOL(arch_rethook_trampoline_callback);
void arch_rethook_prepare(struct rethook_node *rhn, struct pt_regs *regs, bool mcount)
{
rhn->ret_addr = regs->ra;
rhn->frame = regs->s0;
/* replace return addr with trampoline */
regs->ra = (unsigned long)arch_rethook_trampoline;
}
NOKPROBE_SYMBOL(arch_rethook_prepare);
/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef __RISCV_RETHOOK_H
#define __RISCV_RETHOOK_H
unsigned long arch_rethook_trampoline_callback(struct pt_regs *regs);
void arch_rethook_prepare(struct rethook_node *rhn, struct pt_regs *regs, bool mcount);
#endif
...@@ -75,13 +75,13 @@ ...@@ -75,13 +75,13 @@
REG_L x31, PT_T6(sp) REG_L x31, PT_T6(sp)
.endm .endm
ENTRY(__kretprobe_trampoline) ENTRY(arch_rethook_trampoline)
addi sp, sp, -(PT_SIZE_ON_STACK) addi sp, sp, -(PT_SIZE_ON_STACK)
save_all_base_regs save_all_base_regs
move a0, sp /* pt_regs */ move a0, sp /* pt_regs */
call trampoline_probe_handler call arch_rethook_trampoline_callback
/* use the result as the return-address */ /* use the result as the return-address */
move ra, a0 move ra, a0
...@@ -90,4 +90,4 @@ ENTRY(__kretprobe_trampoline) ...@@ -90,4 +90,4 @@ ENTRY(__kretprobe_trampoline)
addi sp, sp, PT_SIZE_ON_STACK addi sp, sp, PT_SIZE_ON_STACK
ret ret
ENDPROC(__kretprobe_trampoline) ENDPROC(arch_rethook_trampoline)
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment