Skip to content

Commit

Permalink
riscv: add riscv rethook implementation
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Binglei Wang authored and Palmer Dabbelt committed Dec 2, 2022
1 parent d8bf77a commit b57c2f1
Show file tree
Hide file tree
Showing 7 changed files with 40 additions and 19 deletions.
1 change: 1 addition & 0 deletions arch/riscv/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 0 additions & 2 deletions arch/riscv/include/asm/kprobes.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
2 changes: 1 addition & 1 deletion arch/riscv/kernel/probes/Makefile
Original file line number Diff line number Diff line change
@@ -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)
13 changes: 0 additions & 13 deletions arch/riscv/kernel/probes/kprobes.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
27 changes: 27 additions & 0 deletions arch/riscv/kernel/probes/rethook.c
Original file line number Diff line number Diff line change
@@ -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);
8 changes: 8 additions & 0 deletions arch/riscv/kernel/probes/rethook.h
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -90,4 +90,4 @@ ENTRY(__kretprobe_trampoline)
addi sp, sp, PT_SIZE_ON_STACK

ret
ENDPROC(__kretprobe_trampoline)
ENDPROC(arch_rethook_trampoline)

0 comments on commit b57c2f1

Please sign in to comment.