Message ID | 164800289923.1716332.9772144337267953560.stgit@devnote2 (mailing list archive) |
---|---|
State | Changes Requested |
Delegated to: | BPF |
Headers | show |
Series | fprobe: Introduce fprobe function entry/exit probe | expand |
On Wed, Mar 23, 2022 at 11:34:59AM +0900, Masami Hiramatsu wrote: > Add rethook for x86 implementation. Most of the code has been copied from > kretprobes on x86. Right; as said, I'm really unhappy with growing a carbon copy of this stuff instead of sharing. Can we *please* keep it a single instance? Them being basically indentical, it should be trivial to have CONFIG_KPROBE_ON_RETHOOK (or somesuch) and just share this. Also, what's rethook for anyway? > diff --git a/arch/x86/kernel/kprobes/common.h b/arch/x86/kernel/kprobes/common.h > index 7d3a2e2daf01..c993521d4933 100644 > --- a/arch/x86/kernel/kprobes/common.h > +++ b/arch/x86/kernel/kprobes/common.h > @@ -6,6 +6,7 @@ > > #include <asm/asm.h> > #include <asm/frame.h> > +#include <asm/insn.h> > > #ifdef CONFIG_X86_64 > > diff --git a/arch/x86/kernel/rethook.c b/arch/x86/kernel/rethook.c > new file mode 100644 > index 000000000000..3e916361c33b > --- /dev/null > +++ b/arch/x86/kernel/rethook.c > @@ -0,0 +1,121 @@ > +// SPDX-License-Identifier: GPL-2.0-or-later > +/* > + * x86 implementation of rethook. Mostly copied from arch/x86/kernel/kprobes/core.c. > + */ > +#include <linux/bug.h> > +#include <linux/rethook.h> > +#include <linux/kprobes.h> > +#include <linux/objtool.h> > + > +#include "kprobes/common.h" > + > +__visible void arch_rethook_trampoline_callback(struct pt_regs *regs); > + > +/* > + * When a target function returns, this code saves registers and calls > + * arch_rethook_trampoline_callback(), which calls the rethook handler. > + */ > +asm( > + ".text\n" > + ".global arch_rethook_trampoline\n" > + ".type arch_rethook_trampoline, @function\n" > + "arch_rethook_trampoline:\n" > +#ifdef CONFIG_X86_64 > + ANNOTATE_NOENDBR /* This is only jumped from ret instruction */ > + /* Push a fake return address to tell the unwinder it's a kretprobe. */ > + " pushq $arch_rethook_trampoline\n" > + UNWIND_HINT_FUNC " pushq $" __stringify(__KERNEL_DS) "\n" /* %ss */ /* Save the 'sp - 16', this will be fixed later. */ > + " pushq %rsp\n" > + " pushfq\n" > + SAVE_REGS_STRING > + " movq %rsp, %rdi\n" > + " call arch_rethook_trampoline_callback\n" > + RESTORE_REGS_STRING /* In the callback function, 'regs->flags' is copied to 'regs->ss'. */ this comment could do with a 'why' though... Because neither this nor the one in the handler really explains why it is important to have popf last " addq $16, %rsp\n" > + " popfq\n" > +#else same for i386: > + /* Push a fake return address to tell the unwinder it's a kretprobe. */ > + " pushl $arch_rethook_trampoline\n" > + UNWIND_HINT_FUNC /* Save the 'sp - 8', this will be fixed later. */ " pushl %ss\n" > + " pushl %esp\n" > + " pushfl\n" > + SAVE_REGS_STRING > + " movl %esp, %eax\n" > + " call arch_rethook_trampoline_callback\n" > + RESTORE_REGS_STRING /* In the callback function, 'regs->flags' is copied to 'regs->ss'. */ " addl $8, %esp\n" > + " popfl\n" > +#endif > + ASM_RET > + ".size arch_rethook_trampoline, .-arch_rethook_trampoline\n" > +); > +NOKPROBE_SYMBOL(arch_rethook_trampoline); > + > +/* > + * Called from arch_rethook_trampoline > + */ > +__used __visible void arch_rethook_trampoline_callback(struct pt_regs *regs) > +{ > + unsigned long *frame_pointer; > + > + /* fixup registers */ > + regs->cs = __KERNEL_CS; > +#ifdef CONFIG_X86_32 > + regs->gs = 0; > +#endif > + regs->ip = (unsigned long)&arch_rethook_trampoline; > + regs->orig_ax = ~0UL; regs->sp += 2*sizeof(long); > + frame_pointer = ®s->sp + 1; > + > + /* > + * The return address at 'frame_pointer' is recovered by the > + * arch_rethook_fixup_return() which called from this > + * rethook_trampoline_handler(). > + */ > + rethook_trampoline_handler(regs, (unsigned long)frame_pointer); > + > + /* > + * Copy FLAGS to 'pt_regs::sp' so that arch_rethook_trapmoline() > + * can do RET right after POPF. > + */ regs->ss = regs->flags; > +} > +NOKPROBE_SYMBOL(arch_rethook_trampoline_callback);
On Wed, 23 Mar 2022 09:05:26 +0100 Peter Zijlstra <peterz@infradead.org> wrote: > On Wed, Mar 23, 2022 at 11:34:59AM +0900, Masami Hiramatsu wrote: > > Add rethook for x86 implementation. Most of the code has been copied from > > kretprobes on x86. > > Right; as said, I'm really unhappy with growing a carbon copy of this > stuff instead of sharing. Can we *please* keep it a single instance? OK, then let me update the kprobe side too. > Them being basically indentical, it should be trivial to have > CONFIG_KPROBE_ON_RETHOOK (or somesuch) and just share this. Yes, ideally it should use CONFIG_HAVE_RETHOOK since the rethook arch port must be a copy of the kretprobe implementation. But for safety, I think having CONFIG_KPROBE_ON_RETHOOK is a good idea until replacing all kretprobe implementations. > > Also, what's rethook for anyway? Rethook is a feature which hooks the function return. Most of the logic came from the kretprobe. Simply to say, 'kretprobe - kprobe' is the rethook :) Thank you, > > > diff --git a/arch/x86/kernel/kprobes/common.h b/arch/x86/kernel/kprobes/common.h > > index 7d3a2e2daf01..c993521d4933 100644 > > --- a/arch/x86/kernel/kprobes/common.h > > +++ b/arch/x86/kernel/kprobes/common.h > > @@ -6,6 +6,7 @@ > > > > #include <asm/asm.h> > > #include <asm/frame.h> > > +#include <asm/insn.h> > > > > #ifdef CONFIG_X86_64 > > > > diff --git a/arch/x86/kernel/rethook.c b/arch/x86/kernel/rethook.c > > new file mode 100644 > > index 000000000000..3e916361c33b > > --- /dev/null > > +++ b/arch/x86/kernel/rethook.c > > @@ -0,0 +1,121 @@ > > +// SPDX-License-Identifier: GPL-2.0-or-later > > +/* > > + * x86 implementation of rethook. Mostly copied from arch/x86/kernel/kprobes/core.c. > > + */ > > +#include <linux/bug.h> > > +#include <linux/rethook.h> > > +#include <linux/kprobes.h> > > +#include <linux/objtool.h> > > + > > +#include "kprobes/common.h" > > + > > +__visible void arch_rethook_trampoline_callback(struct pt_regs *regs); > > + > > +/* > > + * When a target function returns, this code saves registers and calls > > + * arch_rethook_trampoline_callback(), which calls the rethook handler. > > + */ > > +asm( > > + ".text\n" > > + ".global arch_rethook_trampoline\n" > > + ".type arch_rethook_trampoline, @function\n" > > + "arch_rethook_trampoline:\n" > > +#ifdef CONFIG_X86_64 > > + ANNOTATE_NOENDBR /* This is only jumped from ret instruction */ > > + /* Push a fake return address to tell the unwinder it's a kretprobe. */ > > + " pushq $arch_rethook_trampoline\n" > > + UNWIND_HINT_FUNC > " pushq $" __stringify(__KERNEL_DS) "\n" /* %ss */ > /* Save the 'sp - 16', this will be fixed later. */ > > + " pushq %rsp\n" > > + " pushfq\n" > > + SAVE_REGS_STRING > > + " movq %rsp, %rdi\n" > > + " call arch_rethook_trampoline_callback\n" > > + RESTORE_REGS_STRING > /* In the callback function, 'regs->flags' is copied to 'regs->ss'. */ > > this comment could do with a 'why' though... Because neither > this nor the one in the handler really explains why it is > important to have popf last > > " addq $16, %rsp\n" > > + " popfq\n" > > +#else > > same for i386: > > > + /* Push a fake return address to tell the unwinder it's a kretprobe. */ > > + " pushl $arch_rethook_trampoline\n" > > + UNWIND_HINT_FUNC > /* Save the 'sp - 8', this will be fixed later. */ > " pushl %ss\n" > > + " pushl %esp\n" > > + " pushfl\n" > > + SAVE_REGS_STRING > > + " movl %esp, %eax\n" > > + " call arch_rethook_trampoline_callback\n" > > + RESTORE_REGS_STRING > /* In the callback function, 'regs->flags' is copied to 'regs->ss'. */ > " addl $8, %esp\n" > > + " popfl\n" > > +#endif > > + ASM_RET > > + ".size arch_rethook_trampoline, .-arch_rethook_trampoline\n" > > +); > > +NOKPROBE_SYMBOL(arch_rethook_trampoline); > > + > > +/* > > + * Called from arch_rethook_trampoline > > + */ > > +__used __visible void arch_rethook_trampoline_callback(struct pt_regs *regs) > > +{ > > + unsigned long *frame_pointer; > > + > > + /* fixup registers */ > > + regs->cs = __KERNEL_CS; > > +#ifdef CONFIG_X86_32 > > + regs->gs = 0; > > +#endif > > + regs->ip = (unsigned long)&arch_rethook_trampoline; > > + regs->orig_ax = ~0UL; > regs->sp += 2*sizeof(long); > > + frame_pointer = ®s->sp + 1; > > + > > + /* > > + * The return address at 'frame_pointer' is recovered by the > > + * arch_rethook_fixup_return() which called from this > > + * rethook_trampoline_handler(). > > + */ > > + rethook_trampoline_handler(regs, (unsigned long)frame_pointer); > > + > > + /* > > + * Copy FLAGS to 'pt_regs::sp' so that arch_rethook_trapmoline() > > + * can do RET right after POPF. > > + */ > regs->ss = regs->flags; > > +} > > +NOKPROBE_SYMBOL(arch_rethook_trampoline_callback);
On Wed, Mar 23, 2022 at 08:41:19PM +0900, Masami Hiramatsu wrote: > > Also, what's rethook for anyway? > > Rethook is a feature which hooks the function return. Most of the > logic came from the kretprobe. Simply to say, 'kretprobe - kprobe' is > the rethook :) I got that far, but why did you take the bother to do these patches? Why wasn't 'use kretprobe' a good enough option?
On Wed, 23 Mar 2022 13:34:54 +0100 Peter Zijlstra <peterz@infradead.org> wrote: > On Wed, Mar 23, 2022 at 08:41:19PM +0900, Masami Hiramatsu wrote: > > > > Also, what's rethook for anyway? > > > > Rethook is a feature which hooks the function return. Most of the > > logic came from the kretprobe. Simply to say, 'kretprobe - kprobe' is > > the rethook :) > > I got that far, but why did you take the bother to do these patches? Why > wasn't 'use kretprobe' a good enough option? Ah, sorry about lacking the background story. Actually this came from Jiri's request of multiple kprobe for bpf[1]. He tried to solve an issue that starting bpf with multiple kprobe will take a long time because bpf-kprobe will wait for RCU grace period for sync rcu events. Jiri wanted to attach a single bpf handler to multiple kprobes and he tried to introduce multiple-probe interface to kprobe. So I asked him to use ftrace and kretprobe-like hook if it is only for the function entry and exit, instead of adding ad-hoc interface to kprobes. So I introduced fprobe (kprobe like interface for ftrace) and rethook (this is a generic return hook feature for fprobe exit handler)[2]. [1] https://lore.kernel.org/all/20220104080943.113249-1-jolsa@kernel.org/T/#u [2] https://lore.kernel.org/all/164191321766.806991.7930388561276940676.stgit@devnote2/T/#u This is the reason why I need to split the kretprobe's trampoline as rethook. Kretprobe is only for probing a single function entry/exit, thus it does not suit for this purpose. Thank you,
On Wed, Mar 23, 2022 at 4:41 AM Masami Hiramatsu <mhiramat@kernel.org> wrote: > > On Wed, 23 Mar 2022 09:05:26 +0100 > Peter Zijlstra <peterz@infradead.org> wrote: > > > On Wed, Mar 23, 2022 at 11:34:59AM +0900, Masami Hiramatsu wrote: > > > Add rethook for x86 implementation. Most of the code has been copied from > > > kretprobes on x86. > > > > Right; as said, I'm really unhappy with growing a carbon copy of this > > stuff instead of sharing. Can we *please* keep it a single instance? > > OK, then let me update the kprobe side too. > > > Them being basically indentical, it should be trivial to have > > CONFIG_KPROBE_ON_RETHOOK (or somesuch) and just share this. > > Yes, ideally it should use CONFIG_HAVE_RETHOOK since the rethook arch port > must be a copy of the kretprobe implementation. But for safety, I think > having CONFIG_KPROBE_ON_RETHOOK is a good idea until replacing all kretprobe > implementations. Masami, you're respinning this patch to combine arch_rethook_trampoline and __kretprobe_trampoline right?
On Thu, 24 Mar 2022 19:03:43 -0700 Alexei Starovoitov <alexei.starovoitov@gmail.com> wrote: > On Wed, Mar 23, 2022 at 4:41 AM Masami Hiramatsu <mhiramat@kernel.org> wrote: > > > > On Wed, 23 Mar 2022 09:05:26 +0100 > > Peter Zijlstra <peterz@infradead.org> wrote: > > > > > On Wed, Mar 23, 2022 at 11:34:59AM +0900, Masami Hiramatsu wrote: > > > > Add rethook for x86 implementation. Most of the code has been copied from > > > > kretprobes on x86. > > > > > > Right; as said, I'm really unhappy with growing a carbon copy of this > > > stuff instead of sharing. Can we *please* keep it a single instance? > > > > OK, then let me update the kprobe side too. > > > > > Them being basically indentical, it should be trivial to have > > > CONFIG_KPROBE_ON_RETHOOK (or somesuch) and just share this. > > > > Yes, ideally it should use CONFIG_HAVE_RETHOOK since the rethook arch port > > must be a copy of the kretprobe implementation. But for safety, I think > > having CONFIG_KPROBE_ON_RETHOOK is a good idea until replacing all kretprobe > > implementations. > > Masami, > > you're respinning this patch to combine > arch_rethook_trampoline and __kretprobe_trampoline > right? Yes, let me send the first patch set (for x86 at first). BTW, can you review these 2 patches? These are only for the fprobes, so it can be picked to bpf-next. https://lore.kernel.org/all/164802091567.1732982.1242854551611267542.stgit@devnote2/T/#u Thank you,
On Thu, Mar 24, 2022 at 7:21 PM Masami Hiramatsu <mhiramat@kernel.org> wrote: > > On Thu, 24 Mar 2022 19:03:43 -0700 > Alexei Starovoitov <alexei.starovoitov@gmail.com> wrote: > > > On Wed, Mar 23, 2022 at 4:41 AM Masami Hiramatsu <mhiramat@kernel.org> wrote: > > > > > > On Wed, 23 Mar 2022 09:05:26 +0100 > > > Peter Zijlstra <peterz@infradead.org> wrote: > > > > > > > On Wed, Mar 23, 2022 at 11:34:59AM +0900, Masami Hiramatsu wrote: > > > > > Add rethook for x86 implementation. Most of the code has been copied from > > > > > kretprobes on x86. > > > > > > > > Right; as said, I'm really unhappy with growing a carbon copy of this > > > > stuff instead of sharing. Can we *please* keep it a single instance? > > > > > > OK, then let me update the kprobe side too. > > > > > > > Them being basically indentical, it should be trivial to have > > > > CONFIG_KPROBE_ON_RETHOOK (or somesuch) and just share this. > > > > > > Yes, ideally it should use CONFIG_HAVE_RETHOOK since the rethook arch port > > > must be a copy of the kretprobe implementation. But for safety, I think > > > having CONFIG_KPROBE_ON_RETHOOK is a good idea until replacing all kretprobe > > > implementations. > > > > Masami, > > > > you're respinning this patch to combine > > arch_rethook_trampoline and __kretprobe_trampoline > > right? > > Yes, let me send the first patch set (for x86 at first). great > BTW, can you review these 2 patches? These are only for the fprobes, > so it can be picked to bpf-next. > > https://lore.kernel.org/all/164802091567.1732982.1242854551611267542.stgit@devnote2/T/#u Yes. They look good. Will push them soon.
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 9b356da6f46b..1270b65a5546 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -221,6 +221,7 @@ config X86 select HAVE_KPROBES_ON_FTRACE select HAVE_FUNCTION_ERROR_INJECTION select HAVE_KRETPROBES + select HAVE_RETHOOK select HAVE_KVM select HAVE_LIVEPATCH if X86_64 select HAVE_MIXED_BREAKPOINTS_REGS diff --git a/arch/x86/include/asm/unwind.h b/arch/x86/include/asm/unwind.h index 2a1f8734416d..192df5b2094d 100644 --- a/arch/x86/include/asm/unwind.h +++ b/arch/x86/include/asm/unwind.h @@ -5,6 +5,7 @@ #include <linux/sched.h> #include <linux/ftrace.h> #include <linux/kprobes.h> +#include <linux/rethook.h> #include <asm/ptrace.h> #include <asm/stacktrace.h> @@ -16,7 +17,7 @@ struct unwind_state { unsigned long stack_mask; struct task_struct *task; int graph_idx; -#ifdef CONFIG_KRETPROBES +#if defined(CONFIG_KRETPROBES) || defined(CONFIG_RETHOOK) struct llist_node *kr_cur; #endif bool error; @@ -107,6 +108,11 @@ static inline unsigned long unwind_recover_kretprobe(struct unwind_state *state, unsigned long addr, unsigned long *addr_p) { +#ifdef CONFIG_RETHOOK + if (is_rethook_trampoline(addr)) + return rethook_find_ret_addr(state->task, (unsigned long)addr_p, + &state->kr_cur); +#endif #ifdef CONFIG_KRETPROBES return is_kretprobe_trampoline(addr) ? kretprobe_find_ret_addr(state->task, addr_p, &state->kr_cur) : diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile index 6aef9ee28a39..792a893a5cc5 100644 --- a/arch/x86/kernel/Makefile +++ b/arch/x86/kernel/Makefile @@ -106,6 +106,7 @@ obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o obj-$(CONFIG_FTRACE_SYSCALLS) += ftrace.o obj-$(CONFIG_X86_TSC) += trace_clock.o obj-$(CONFIG_TRACING) += trace.o +obj-$(CONFIG_RETHOOK) += rethook.o obj-$(CONFIG_CRASH_CORE) += crash_core_$(BITS).o obj-$(CONFIG_KEXEC_CORE) += machine_kexec_$(BITS).o obj-$(CONFIG_KEXEC_CORE) += relocate_kernel_$(BITS).o crash.o diff --git a/arch/x86/kernel/kprobes/common.h b/arch/x86/kernel/kprobes/common.h index 7d3a2e2daf01..c993521d4933 100644 --- a/arch/x86/kernel/kprobes/common.h +++ b/arch/x86/kernel/kprobes/common.h @@ -6,6 +6,7 @@ #include <asm/asm.h> #include <asm/frame.h> +#include <asm/insn.h> #ifdef CONFIG_X86_64 diff --git a/arch/x86/kernel/rethook.c b/arch/x86/kernel/rethook.c new file mode 100644 index 000000000000..3e916361c33b --- /dev/null +++ b/arch/x86/kernel/rethook.c @@ -0,0 +1,121 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * x86 implementation of rethook. Mostly copied from arch/x86/kernel/kprobes/core.c. + */ +#include <linux/bug.h> +#include <linux/rethook.h> +#include <linux/kprobes.h> +#include <linux/objtool.h> + +#include "kprobes/common.h" + +__visible void arch_rethook_trampoline_callback(struct pt_regs *regs); + +/* + * When a target function returns, this code saves registers and calls + * arch_rethook_trampoline_callback(), which calls the rethook handler. + */ +asm( + ".text\n" + ".global arch_rethook_trampoline\n" + ".type arch_rethook_trampoline, @function\n" + "arch_rethook_trampoline:\n" +#ifdef CONFIG_X86_64 + ANNOTATE_NOENDBR /* This is only jumped from ret instruction */ + /* Push a fake return address to tell the unwinder it's a kretprobe. */ + " pushq $arch_rethook_trampoline\n" + UNWIND_HINT_FUNC + /* Save the 'sp - 8', this will be fixed later. */ + " pushq %rsp\n" + " pushfq\n" + SAVE_REGS_STRING + " movq %rsp, %rdi\n" + " call arch_rethook_trampoline_callback\n" + RESTORE_REGS_STRING + /* In the callback function, 'regs->flags' is copied to 'regs->sp'. */ + " addq $8, %rsp\n" + " popfq\n" +#else + /* Push a fake return address to tell the unwinder it's a kretprobe. */ + " pushl $arch_rethook_trampoline\n" + UNWIND_HINT_FUNC + /* Save the 'sp - 4', this will be fixed later. */ + " pushl %esp\n" + " pushfl\n" + SAVE_REGS_STRING + " movl %esp, %eax\n" + " call arch_rethook_trampoline_callback\n" + RESTORE_REGS_STRING + /* In the callback function, 'regs->flags' is copied to 'regs->sp'. */ + " addl $4, %esp\n" + " popfl\n" +#endif + ASM_RET + ".size arch_rethook_trampoline, .-arch_rethook_trampoline\n" +); +NOKPROBE_SYMBOL(arch_rethook_trampoline); + +/* + * Called from arch_rethook_trampoline + */ +__used __visible void arch_rethook_trampoline_callback(struct pt_regs *regs) +{ + unsigned long *frame_pointer; + + /* fixup registers */ + regs->cs = __KERNEL_CS; +#ifdef CONFIG_X86_32 + regs->gs = 0; +#endif + regs->ip = (unsigned long)&arch_rethook_trampoline; + regs->orig_ax = ~0UL; + regs->sp += sizeof(long); + frame_pointer = ®s->sp + 1; + + /* + * The return address at 'frame_pointer' is recovered by the + * arch_rethook_fixup_return() which called from this + * rethook_trampoline_handler(). + */ + rethook_trampoline_handler(regs, (unsigned long)frame_pointer); + + /* + * Copy FLAGS to 'pt_regs::sp' so that arch_rethook_trapmoline() + * can do RET right after POPF. + */ + regs->sp = regs->flags; +} +NOKPROBE_SYMBOL(arch_rethook_trampoline_callback); + +/* + * arch_rethook_trampoline() skips updating frame pointer. The frame pointer + * saved in arch_rethook_trampoline_callback() points to the real caller + * function's frame pointer. Thus the arch_rethook_trampoline() doesn't have + * a standard stack frame with CONFIG_FRAME_POINTER=y. + * Let's mark it non-standard function. Anyway, FP unwinder can correctly + * unwind without the hint. + */ +STACK_FRAME_NON_STANDARD_FP(arch_rethook_trampoline); + +/* This is called from rethook_trampoline_handler(). */ +void arch_rethook_fixup_return(struct pt_regs *regs, + unsigned long correct_ret_addr) +{ + unsigned long *frame_pointer = ®s->sp + 1; + + /* Replace fake return address with real one. */ + *frame_pointer = correct_ret_addr; +} +NOKPROBE_SYMBOL(arch_rethook_fixup_return); + +void arch_rethook_prepare(struct rethook_node *rh, struct pt_regs *regs, bool mcount) +{ + unsigned long *stack = (unsigned long *)regs->sp; + + rh->ret_addr = stack[0]; + rh->frame = regs->sp; + + /* Replace the return addr with trampoline addr */ + stack[0] = (unsigned long) arch_rethook_trampoline; +} +NOKPROBE_SYMBOL(arch_rethook_prepare);
Add rethook for x86 implementation. Most of the code has been copied from kretprobes on x86. Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org> --- Changes in v13: - Add no ENDBR annotation for return trampoline code. - Replace ret with ASM_RET for Straight-Line-Speculation mitigation. Changes in v11: - Mark arch_rethook_fixup_return() as NOKPROBE_SYMBOL. - Add a function prototype of arch_rethook_trampoline_callback to suppress warning. Changes in v10: - Add a dummy @mcount to arch_rethook_prepare(). Changes in v5: - Fix a build error if !CONFIG_KRETPROBES and !CONFIG_RETHOOK. Changes in v4: - fix stack backtrace as same as kretprobe does. --- arch/x86/Kconfig | 1 arch/x86/include/asm/unwind.h | 8 ++- arch/x86/kernel/Makefile | 1 arch/x86/kernel/kprobes/common.h | 1 arch/x86/kernel/rethook.c | 121 ++++++++++++++++++++++++++++++++++++++ 5 files changed, 131 insertions(+), 1 deletion(-) create mode 100644 arch/x86/kernel/rethook.c