LoongArch: Replace kretprobe with rethook
This is an adaptation of commitf3a112c0c4
("x86,rethook,kprobes: Replace kretprobe with rethook on x86") and commitb57c2f1240
("riscv: add riscv rethook implementation") to LoongArch. Mainly refer to commitb57c2f1240
("riscv: add riscv rethook implementation"). Replaces the kretprobe code with rethook on LoongArch. With this patch, kretprobe on LoongArch uses the rethook instead of kretprobe specific trampoline code. Signed-off-by: Haoran Jiang <jianghaoran@kylinos.cn> Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
This commit is contained in:
parent
f02644e32c
commit
7b0a096436
7 changed files with 44 additions and 28 deletions
|
@ -127,6 +127,7 @@ config LOONGARCH
|
||||||
select HAVE_PERF_REGS
|
select HAVE_PERF_REGS
|
||||||
select HAVE_PERF_USER_STACK_DUMP
|
select HAVE_PERF_USER_STACK_DUMP
|
||||||
select HAVE_REGS_AND_STACK_ACCESS_API
|
select HAVE_REGS_AND_STACK_ACCESS_API
|
||||||
|
select HAVE_RETHOOK
|
||||||
select HAVE_RSEQ
|
select HAVE_RSEQ
|
||||||
select HAVE_SAMPLE_FTRACE_DIRECT
|
select HAVE_SAMPLE_FTRACE_DIRECT
|
||||||
select HAVE_SAMPLE_FTRACE_DIRECT_MULTI
|
select HAVE_SAMPLE_FTRACE_DIRECT_MULTI
|
||||||
|
|
|
@ -49,9 +49,6 @@ bool kprobe_fault_handler(struct pt_regs *regs, int trapnr);
|
||||||
bool kprobe_breakpoint_handler(struct pt_regs *regs);
|
bool kprobe_breakpoint_handler(struct pt_regs *regs);
|
||||||
bool kprobe_singlestep_handler(struct pt_regs *regs);
|
bool kprobe_singlestep_handler(struct pt_regs *regs);
|
||||||
|
|
||||||
void __kretprobe_trampoline(void);
|
|
||||||
void *trampoline_probe_handler(struct pt_regs *regs);
|
|
||||||
|
|
||||||
#else /* !CONFIG_KPROBES */
|
#else /* !CONFIG_KPROBES */
|
||||||
|
|
||||||
static inline bool kprobe_breakpoint_handler(struct pt_regs *regs) { return false; }
|
static inline bool kprobe_breakpoint_handler(struct pt_regs *regs) { return false; }
|
||||||
|
|
|
@ -28,6 +28,8 @@ ifdef CONFIG_FUNCTION_TRACER
|
||||||
CFLAGS_REMOVE_inst.o = $(CC_FLAGS_FTRACE)
|
CFLAGS_REMOVE_inst.o = $(CC_FLAGS_FTRACE)
|
||||||
CFLAGS_REMOVE_time.o = $(CC_FLAGS_FTRACE)
|
CFLAGS_REMOVE_time.o = $(CC_FLAGS_FTRACE)
|
||||||
CFLAGS_REMOVE_perf_event.o = $(CC_FLAGS_FTRACE)
|
CFLAGS_REMOVE_perf_event.o = $(CC_FLAGS_FTRACE)
|
||||||
|
CFLAGS_REMOVE_rethook.o = $(CC_FLAGS_FTRACE)
|
||||||
|
CFLAGS_REMOVE_rethook_trampoline.o = $(CC_FLAGS_FTRACE)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
obj-$(CONFIG_MODULES) += module.o module-sections.o
|
obj-$(CONFIG_MODULES) += module.o module-sections.o
|
||||||
|
@ -52,7 +54,8 @@ obj-$(CONFIG_UNWINDER_PROLOGUE) += unwind_prologue.o
|
||||||
obj-$(CONFIG_PERF_EVENTS) += perf_event.o perf_regs.o
|
obj-$(CONFIG_PERF_EVENTS) += perf_event.o perf_regs.o
|
||||||
obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o
|
obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o
|
||||||
|
|
||||||
obj-$(CONFIG_KPROBES) += kprobes.o kprobes_trampoline.o
|
obj-$(CONFIG_KPROBES) += kprobes.o
|
||||||
|
obj-$(CONFIG_RETHOOK) += rethook.o rethook_trampoline.o
|
||||||
|
|
||||||
obj-$(CONFIG_JUMP_LABEL) += jump_label.o
|
obj-$(CONFIG_JUMP_LABEL) += jump_label.o
|
||||||
|
|
||||||
|
|
|
@ -378,27 +378,6 @@ int __init arch_init_kprobes(void)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ASM function that handles the kretprobes must not be probed */
|
|
||||||
NOKPROBE_SYMBOL(__kretprobe_trampoline);
|
|
||||||
|
|
||||||
/* Called from __kretprobe_trampoline */
|
|
||||||
void __used *trampoline_probe_handler(struct pt_regs *regs)
|
|
||||||
{
|
|
||||||
return (void *)kretprobe_trampoline_handler(regs, NULL);
|
|
||||||
}
|
|
||||||
NOKPROBE_SYMBOL(trampoline_probe_handler);
|
|
||||||
|
|
||||||
void arch_prepare_kretprobe(struct kretprobe_instance *ri,
|
|
||||||
struct pt_regs *regs)
|
|
||||||
{
|
|
||||||
ri->ret_addr = (kprobe_opcode_t *)regs->regs[1];
|
|
||||||
ri->fp = NULL;
|
|
||||||
|
|
||||||
/* Replace the return addr with trampoline addr */
|
|
||||||
regs->regs[1] = (unsigned long)&__kretprobe_trampoline;
|
|
||||||
}
|
|
||||||
NOKPROBE_SYMBOL(arch_prepare_kretprobe);
|
|
||||||
|
|
||||||
int arch_trampoline_kprobe(struct kprobe *p)
|
int arch_trampoline_kprobe(struct kprobe *p)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
|
|
28
arch/loongarch/kernel/rethook.c
Normal file
28
arch/loongarch/kernel/rethook.c
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0
|
||||||
|
/*
|
||||||
|
* Generic return hook for LoongArch.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#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, 0);
|
||||||
|
}
|
||||||
|
NOKPROBE_SYMBOL(arch_rethook_trampoline_callback);
|
||||||
|
|
||||||
|
void arch_rethook_prepare(struct rethook_node *rhn, struct pt_regs *regs, bool mcount)
|
||||||
|
{
|
||||||
|
rhn->frame = 0;
|
||||||
|
rhn->ret_addr = regs->regs[1];
|
||||||
|
|
||||||
|
/* replace return addr with trampoline */
|
||||||
|
regs->regs[1] = (unsigned long)arch_rethook_trampoline;
|
||||||
|
}
|
||||||
|
NOKPROBE_SYMBOL(arch_rethook_prepare);
|
||||||
|
|
||||||
|
/* ASM function that handles the rethook must not be probed itself */
|
||||||
|
NOKPROBE_SYMBOL(arch_rethook_trampoline);
|
8
arch/loongarch/kernel/rethook.h
Normal file
8
arch/loongarch/kernel/rethook.h
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
/* SPDX-License-Identifier: GPL-2.0 */
|
||||||
|
#ifndef __LOONGARCH_RETHOOK_H
|
||||||
|
#define __LOONGARCH_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,7 +75,7 @@
|
||||||
csrxchg t0, t1, LOONGARCH_CSR_CRMD
|
csrxchg t0, t1, LOONGARCH_CSR_CRMD
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
SYM_CODE_START(__kretprobe_trampoline)
|
SYM_CODE_START(arch_rethook_trampoline)
|
||||||
addi.d sp, sp, -PT_SIZE
|
addi.d sp, sp, -PT_SIZE
|
||||||
save_all_base_regs
|
save_all_base_regs
|
||||||
|
|
||||||
|
@ -84,7 +84,7 @@ SYM_CODE_START(__kretprobe_trampoline)
|
||||||
|
|
||||||
move a0, sp /* pt_regs */
|
move a0, sp /* pt_regs */
|
||||||
|
|
||||||
bl trampoline_probe_handler
|
bl arch_rethook_trampoline_callback
|
||||||
|
|
||||||
/* use the result as the return-address */
|
/* use the result as the return-address */
|
||||||
move ra, a0
|
move ra, a0
|
||||||
|
@ -93,4 +93,4 @@ SYM_CODE_START(__kretprobe_trampoline)
|
||||||
addi.d sp, sp, PT_SIZE
|
addi.d sp, sp, PT_SIZE
|
||||||
|
|
||||||
jr ra
|
jr ra
|
||||||
SYM_CODE_END(__kretprobe_trampoline)
|
SYM_CODE_END(arch_rethook_trampoline)
|
Loading…
Add table
Reference in a new issue