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: Masami Hiramatsu (Google) <mhiramat@kernel.org> Signed-off-by: Binglei Wang <l3b2w1@gmail.com> Signed-off-by: Conor Dooley <conor.dooley@microchip.com> Link: https://lore.kernel.org/r/20221025151831.1097417-1-conor@kernel.org Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
This commit is contained in:
parent
d8bf77a1dc
commit
b57c2f1240
|
@ -101,6 +101,7 @@ config RISCV
|
|||
select HAVE_KPROBES if !XIP_KERNEL
|
||||
select HAVE_KPROBES_ON_FTRACE if !XIP_KERNEL
|
||||
select HAVE_KRETPROBES if !XIP_KERNEL
|
||||
select HAVE_RETHOOK if !XIP_KERNEL
|
||||
select HAVE_MOVE_PMD
|
||||
select HAVE_MOVE_PUD
|
||||
select HAVE_PCI
|
||||
|
|
|
@ -40,8 +40,6 @@ void arch_remove_kprobe(struct kprobe *p);
|
|||
int kprobe_fault_handler(struct pt_regs *regs, unsigned int trapnr);
|
||||
bool kprobe_breakpoint_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 /* _ASM_RISCV_KPROBES_H */
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# SPDX-License-Identifier: GPL-2.0
|
||||
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_UPROBES) += uprobes.o decode-insn.o simulate-insn.o
|
||||
CFLAGS_REMOVE_simulate-insn.o = $(CC_FLAGS_FTRACE)
|
||||
|
|
|
@ -345,19 +345,6 @@ int __init arch_populate_kprobe_blacklist(void)
|
|||
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)
|
||||
{
|
||||
return 0;
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
// 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);
|
|
@ -0,0 +1,8 @@
|
|||
/* 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 @@
|
|||
REG_L x31, PT_T6(sp)
|
||||
.endm
|
||||
|
||||
ENTRY(__kretprobe_trampoline)
|
||||
ENTRY(arch_rethook_trampoline)
|
||||
addi sp, sp, -(PT_SIZE_ON_STACK)
|
||||
save_all_base_regs
|
||||
|
||||
move a0, sp /* pt_regs */
|
||||
|
||||
call trampoline_probe_handler
|
||||
call arch_rethook_trampoline_callback
|
||||
|
||||
/* use the result as the return-address */
|
||||
move ra, a0
|
||||
|
@ -90,4 +90,4 @@ ENTRY(__kretprobe_trampoline)
|
|||
addi sp, sp, PT_SIZE_ON_STACK
|
||||
|
||||
ret
|
||||
ENDPROC(__kretprobe_trampoline)
|
||||
ENDPROC(arch_rethook_trampoline)
|
Loading…
Reference in New Issue