select HAVE_PERF_REGS
select HAVE_PERF_USER_STACK_DUMP
select HAVE_REGS_AND_STACK_ACCESS_API
+ select HAVE_RETHOOK
select HAVE_RSEQ
select HAVE_SAMPLE_FTRACE_DIRECT
select HAVE_SAMPLE_FTRACE_DIRECT_MULTI
bool kprobe_breakpoint_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 */
static inline bool kprobe_breakpoint_handler(struct pt_regs *regs) { return false; }
CFLAGS_REMOVE_inst.o = $(CC_FLAGS_FTRACE)
CFLAGS_REMOVE_time.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
obj-$(CONFIG_MODULES) += module.o module-sections.o
obj-$(CONFIG_PERF_EVENTS) += perf_event.o perf_regs.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
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)
{
return 0;
+++ /dev/null
-/* SPDX-License-Identifier: GPL-2.0+ */
-#include <linux/linkage.h>
-#include <asm/stackframe.h>
-
- .text
-
- .macro save_all_base_regs
- cfi_st ra, PT_R1
- cfi_st tp, PT_R2
- cfi_st a0, PT_R4
- cfi_st a1, PT_R5
- cfi_st a2, PT_R6
- cfi_st a3, PT_R7
- cfi_st a4, PT_R8
- cfi_st a5, PT_R9
- cfi_st a6, PT_R10
- cfi_st a7, PT_R11
- cfi_st t0, PT_R12
- cfi_st t1, PT_R13
- cfi_st t2, PT_R14
- cfi_st t3, PT_R15
- cfi_st t4, PT_R16
- cfi_st t5, PT_R17
- cfi_st t6, PT_R18
- cfi_st t7, PT_R19
- cfi_st t8, PT_R20
- cfi_st u0, PT_R21
- cfi_st fp, PT_R22
- cfi_st s0, PT_R23
- cfi_st s1, PT_R24
- cfi_st s2, PT_R25
- cfi_st s3, PT_R26
- cfi_st s4, PT_R27
- cfi_st s5, PT_R28
- cfi_st s6, PT_R29
- cfi_st s7, PT_R30
- cfi_st s8, PT_R31
- csrrd t0, LOONGARCH_CSR_CRMD
- andi t0, t0, 0x7 /* extract bit[1:0] PLV, bit[2] IE */
- LONG_S t0, sp, PT_CRMD
- .endm
-
- .macro restore_all_base_regs
- cfi_ld tp, PT_R2
- cfi_ld a0, PT_R4
- cfi_ld a1, PT_R5
- cfi_ld a2, PT_R6
- cfi_ld a3, PT_R7
- cfi_ld a4, PT_R8
- cfi_ld a5, PT_R9
- cfi_ld a6, PT_R10
- cfi_ld a7, PT_R11
- cfi_ld t0, PT_R12
- cfi_ld t1, PT_R13
- cfi_ld t2, PT_R14
- cfi_ld t3, PT_R15
- cfi_ld t4, PT_R16
- cfi_ld t5, PT_R17
- cfi_ld t6, PT_R18
- cfi_ld t7, PT_R19
- cfi_ld t8, PT_R20
- cfi_ld u0, PT_R21
- cfi_ld fp, PT_R22
- cfi_ld s0, PT_R23
- cfi_ld s1, PT_R24
- cfi_ld s2, PT_R25
- cfi_ld s3, PT_R26
- cfi_ld s4, PT_R27
- cfi_ld s5, PT_R28
- cfi_ld s6, PT_R29
- cfi_ld s7, PT_R30
- cfi_ld s8, PT_R31
- LONG_L t0, sp, PT_CRMD
- li.d t1, 0x7 /* mask bit[1:0] PLV, bit[2] IE */
- csrxchg t0, t1, LOONGARCH_CSR_CRMD
- .endm
-
-SYM_CODE_START(__kretprobe_trampoline)
- addi.d sp, sp, -PT_SIZE
- save_all_base_regs
-
- addi.d t0, sp, PT_SIZE
- LONG_S t0, sp, PT_R3
-
- move a0, sp /* pt_regs */
-
- bl trampoline_probe_handler
-
- /* use the result as the return-address */
- move ra, a0
-
- restore_all_base_regs
- addi.d sp, sp, PT_SIZE
-
- jr ra
-SYM_CODE_END(__kretprobe_trampoline)
--- /dev/null
+// 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);
--- /dev/null
+/* 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
--- /dev/null
+/* SPDX-License-Identifier: GPL-2.0+ */
+#include <linux/linkage.h>
+#include <asm/stackframe.h>
+
+ .text
+
+ .macro save_all_base_regs
+ cfi_st ra, PT_R1
+ cfi_st tp, PT_R2
+ cfi_st a0, PT_R4
+ cfi_st a1, PT_R5
+ cfi_st a2, PT_R6
+ cfi_st a3, PT_R7
+ cfi_st a4, PT_R8
+ cfi_st a5, PT_R9
+ cfi_st a6, PT_R10
+ cfi_st a7, PT_R11
+ cfi_st t0, PT_R12
+ cfi_st t1, PT_R13
+ cfi_st t2, PT_R14
+ cfi_st t3, PT_R15
+ cfi_st t4, PT_R16
+ cfi_st t5, PT_R17
+ cfi_st t6, PT_R18
+ cfi_st t7, PT_R19
+ cfi_st t8, PT_R20
+ cfi_st u0, PT_R21
+ cfi_st fp, PT_R22
+ cfi_st s0, PT_R23
+ cfi_st s1, PT_R24
+ cfi_st s2, PT_R25
+ cfi_st s3, PT_R26
+ cfi_st s4, PT_R27
+ cfi_st s5, PT_R28
+ cfi_st s6, PT_R29
+ cfi_st s7, PT_R30
+ cfi_st s8, PT_R31
+ csrrd t0, LOONGARCH_CSR_CRMD
+ andi t0, t0, 0x7 /* extract bit[1:0] PLV, bit[2] IE */
+ LONG_S t0, sp, PT_CRMD
+ .endm
+
+ .macro restore_all_base_regs
+ cfi_ld tp, PT_R2
+ cfi_ld a0, PT_R4
+ cfi_ld a1, PT_R5
+ cfi_ld a2, PT_R6
+ cfi_ld a3, PT_R7
+ cfi_ld a4, PT_R8
+ cfi_ld a5, PT_R9
+ cfi_ld a6, PT_R10
+ cfi_ld a7, PT_R11
+ cfi_ld t0, PT_R12
+ cfi_ld t1, PT_R13
+ cfi_ld t2, PT_R14
+ cfi_ld t3, PT_R15
+ cfi_ld t4, PT_R16
+ cfi_ld t5, PT_R17
+ cfi_ld t6, PT_R18
+ cfi_ld t7, PT_R19
+ cfi_ld t8, PT_R20
+ cfi_ld u0, PT_R21
+ cfi_ld fp, PT_R22
+ cfi_ld s0, PT_R23
+ cfi_ld s1, PT_R24
+ cfi_ld s2, PT_R25
+ cfi_ld s3, PT_R26
+ cfi_ld s4, PT_R27
+ cfi_ld s5, PT_R28
+ cfi_ld s6, PT_R29
+ cfi_ld s7, PT_R30
+ cfi_ld s8, PT_R31
+ LONG_L t0, sp, PT_CRMD
+ li.d t1, 0x7 /* mask bit[1:0] PLV, bit[2] IE */
+ csrxchg t0, t1, LOONGARCH_CSR_CRMD
+ .endm
+
+SYM_CODE_START(arch_rethook_trampoline)
+ addi.d sp, sp, -PT_SIZE
+ save_all_base_regs
+
+ addi.d t0, sp, PT_SIZE
+ LONG_S t0, sp, PT_R3
+
+ move a0, sp /* pt_regs */
+
+ bl arch_rethook_trampoline_callback
+
+ /* use the result as the return-address */
+ move ra, a0
+
+ restore_all_base_regs
+ addi.d sp, sp, PT_SIZE
+
+ jr ra
+SYM_CODE_END(arch_rethook_trampoline)