Skip to content

Commit b57c2f1

Browse files
l3b2w1palmer-dabbelt
authored andcommitted
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) <[email protected]> Signed-off-by: Binglei Wang <[email protected]> Signed-off-by: Conor Dooley <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Palmer Dabbelt <[email protected]>
1 parent d8bf77a commit b57c2f1

File tree

7 files changed

+40
-19
lines changed

7 files changed

+40
-19
lines changed

arch/riscv/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ config RISCV
101101
select HAVE_KPROBES if !XIP_KERNEL
102102
select HAVE_KPROBES_ON_FTRACE if !XIP_KERNEL
103103
select HAVE_KRETPROBES if !XIP_KERNEL
104+
select HAVE_RETHOOK if !XIP_KERNEL
104105
select HAVE_MOVE_PMD
105106
select HAVE_MOVE_PUD
106107
select HAVE_PCI

arch/riscv/include/asm/kprobes.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,6 @@ void arch_remove_kprobe(struct kprobe *p);
4040
int kprobe_fault_handler(struct pt_regs *regs, unsigned int trapnr);
4141
bool kprobe_breakpoint_handler(struct pt_regs *regs);
4242
bool kprobe_single_step_handler(struct pt_regs *regs);
43-
void __kretprobe_trampoline(void);
44-
void __kprobes *trampoline_probe_handler(struct pt_regs *regs);
4543

4644
#endif /* CONFIG_KPROBES */
4745
#endif /* _ASM_RISCV_KPROBES_H */

arch/riscv/kernel/probes/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# SPDX-License-Identifier: GPL-2.0
22
obj-$(CONFIG_KPROBES) += kprobes.o decode-insn.o simulate-insn.o
3-
obj-$(CONFIG_KPROBES) += kprobes_trampoline.o
3+
obj-$(CONFIG_RETHOOK) += rethook.o rethook_trampoline.o
44
obj-$(CONFIG_KPROBES_ON_FTRACE) += ftrace.o
55
obj-$(CONFIG_UPROBES) += uprobes.o decode-insn.o simulate-insn.o
66
CFLAGS_REMOVE_simulate-insn.o = $(CC_FLAGS_FTRACE)

arch/riscv/kernel/probes/kprobes.c

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -345,19 +345,6 @@ int __init arch_populate_kprobe_blacklist(void)
345345
return ret;
346346
}
347347

348-
void __kprobes __used *trampoline_probe_handler(struct pt_regs *regs)
349-
{
350-
return (void *)kretprobe_trampoline_handler(regs, NULL);
351-
}
352-
353-
void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
354-
struct pt_regs *regs)
355-
{
356-
ri->ret_addr = (kprobe_opcode_t *)regs->ra;
357-
ri->fp = NULL;
358-
regs->ra = (unsigned long) &__kretprobe_trampoline;
359-
}
360-
361348
int __kprobes arch_trampoline_kprobe(struct kprobe *p)
362349
{
363350
return 0;

arch/riscv/kernel/probes/rethook.c

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// SPDX-License-Identifier: GPL-2.0-only
2+
/*
3+
* Generic return hook for riscv.
4+
*/
5+
6+
#include <linux/kprobes.h>
7+
#include <linux/rethook.h>
8+
#include "rethook.h"
9+
10+
/* This is called from arch_rethook_trampoline() */
11+
unsigned long __used arch_rethook_trampoline_callback(struct pt_regs *regs)
12+
{
13+
return rethook_trampoline_handler(regs, regs->s0);
14+
}
15+
16+
NOKPROBE_SYMBOL(arch_rethook_trampoline_callback);
17+
18+
void arch_rethook_prepare(struct rethook_node *rhn, struct pt_regs *regs, bool mcount)
19+
{
20+
rhn->ret_addr = regs->ra;
21+
rhn->frame = regs->s0;
22+
23+
/* replace return addr with trampoline */
24+
regs->ra = (unsigned long)arch_rethook_trampoline;
25+
}
26+
27+
NOKPROBE_SYMBOL(arch_rethook_prepare);

arch/riscv/kernel/probes/rethook.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
/* SPDX-License-Identifier: GPL-2.0-only */
2+
#ifndef __RISCV_RETHOOK_H
3+
#define __RISCV_RETHOOK_H
4+
5+
unsigned long arch_rethook_trampoline_callback(struct pt_regs *regs);
6+
void arch_rethook_prepare(struct rethook_node *rhn, struct pt_regs *regs, bool mcount);
7+
8+
#endif

arch/riscv/kernel/probes/kprobes_trampoline.S renamed to arch/riscv/kernel/probes/rethook_trampoline.S

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,13 +75,13 @@
7575
REG_L x31, PT_T6(sp)
7676
.endm
7777

78-
ENTRY(__kretprobe_trampoline)
78+
ENTRY(arch_rethook_trampoline)
7979
addi sp, sp, -(PT_SIZE_ON_STACK)
8080
save_all_base_regs
8181

8282
move a0, sp /* pt_regs */
8383

84-
call trampoline_probe_handler
84+
call arch_rethook_trampoline_callback
8585

8686
/* use the result as the return-address */
8787
move ra, a0
@@ -90,4 +90,4 @@ ENTRY(__kretprobe_trampoline)
9090
addi sp, sp, PT_SIZE_ON_STACK
9191

9292
ret
93-
ENDPROC(__kretprobe_trampoline)
93+
ENDPROC(arch_rethook_trampoline)

0 commit comments

Comments
 (0)