Re: [PATCH v4 5/9] riscv: Add kprobes supported
On Fri, Nov 6, 2020 at 9:02 AM Palmer Dabbelt wrote: > > On Sat, 17 Oct 2020 00:06:13 PDT (-0700), guo...@kernel.org wrote: > > From: Guo Ren > > > > This patch enables "kprobe & kretprobe" to work with ftrace > > interface. It utilized software breakpoint as single-step > > mechanism. > > > > Some instructions which can't be single-step executed must be > > simulated in kernel execution slot, such as: branch, jal, auipc, > > la ... > > > > Some instructions should be rejected for probing and we use a > > blacklist to filter, such as: ecall, ebreak, ... > > > > We use ebreak & c.ebreak to replace origin instruction and the > > kprobe handler prepares an executable memory slot for out-of-line > > execution with a copy of the original instruction being probed. > > In execution slot we add ebreak behind original instruction to > > simulate a single-setp mechanism. > > > > The patch is based on packi's work [1] and csky's work [2]. > > - The kprobes_trampoline.S is all from packi's patch > > - The single-step mechanism is new designed for riscv without hw > >single-step trap > > - The simulation codes are from csky > > - Frankly, all codes refer to other archs' implementation > > > > [1] https://lore.kernel.org/linux-riscv/20181113195804.22825-1...@packi.ch/ > > [2] > > https://lore.kernel.org/linux-csky/20200403044150.20562-9-guo...@kernel.org/ > > > > Signed-off-by: Guo Ren > > Co-Developed-by: Patrick Stählin > > Checkpatch says > > WARNING: 'Co-developed-by:' is the preferred signature form > #108: > Co-Developed-by: Patrick Stählin > > WARNING: Co-developed-by: must be immediately followed by Signed-off-by: > #108: > Co-Developed-by: Patrick Stählin > Acked-by: Masami Hiramatsu > > There's some other checkpatch warnings throughout the patch set, but this is > one I'm not supposed to fix up. Can one of you re-post the patches with the > correct DCO? Ok, I'll fix it up in V5 and rebase 5.10-rc2 -- Best Regards Guo Ren ML: https://lore.kernel.org/linux-csky/
Re: [PATCH v4 5/9] riscv: Add kprobes supported
On Sat, 17 Oct 2020 00:06:13 PDT (-0700), guo...@kernel.org wrote: From: Guo Ren This patch enables "kprobe & kretprobe" to work with ftrace interface. It utilized software breakpoint as single-step mechanism. Some instructions which can't be single-step executed must be simulated in kernel execution slot, such as: branch, jal, auipc, la ... Some instructions should be rejected for probing and we use a blacklist to filter, such as: ecall, ebreak, ... We use ebreak & c.ebreak to replace origin instruction and the kprobe handler prepares an executable memory slot for out-of-line execution with a copy of the original instruction being probed. In execution slot we add ebreak behind original instruction to simulate a single-setp mechanism. The patch is based on packi's work [1] and csky's work [2]. - The kprobes_trampoline.S is all from packi's patch - The single-step mechanism is new designed for riscv without hw single-step trap - The simulation codes are from csky - Frankly, all codes refer to other archs' implementation [1] https://lore.kernel.org/linux-riscv/20181113195804.22825-1...@packi.ch/ [2] https://lore.kernel.org/linux-csky/20200403044150.20562-9-guo...@kernel.org/ Signed-off-by: Guo Ren Co-Developed-by: Patrick Stählin Checkpatch says WARNING: 'Co-developed-by:' is the preferred signature form #108: Co-Developed-by: Patrick Stählin WARNING: Co-developed-by: must be immediately followed by Signed-off-by: #108: Co-Developed-by: Patrick Stählin Acked-by: Masami Hiramatsu There's some other checkpatch warnings throughout the patch set, but this is one I'm not supposed to fix up. Can one of you re-post the patches with the correct DCO? Acked-by: Masami Hiramatsu Tested-by: Zong Li Reviewed-by: Pekka Enberg Cc: Patrick Stählin Cc: Palmer Dabbelt Cc: Björn Töpel --- arch/riscv/Kconfig| 2 + arch/riscv/include/asm/kprobes.h | 40 +++ arch/riscv/include/asm/probes.h | 24 ++ arch/riscv/kernel/Makefile| 1 + arch/riscv/kernel/probes/Makefile | 4 + arch/riscv/kernel/probes/decode-insn.c| 48 arch/riscv/kernel/probes/decode-insn.h| 18 ++ arch/riscv/kernel/probes/kprobes.c| 398 ++ arch/riscv/kernel/probes/kprobes_trampoline.S | 93 ++ arch/riscv/kernel/probes/simulate-insn.c | 85 ++ arch/riscv/kernel/probes/simulate-insn.h | 47 +++ arch/riscv/kernel/traps.c | 9 + arch/riscv/mm/fault.c | 4 + 13 files changed, 773 insertions(+) create mode 100644 arch/riscv/include/asm/probes.h create mode 100644 arch/riscv/kernel/probes/Makefile create mode 100644 arch/riscv/kernel/probes/decode-insn.c create mode 100644 arch/riscv/kernel/probes/decode-insn.h create mode 100644 arch/riscv/kernel/probes/kprobes.c create mode 100644 arch/riscv/kernel/probes/kprobes_trampoline.S create mode 100644 arch/riscv/kernel/probes/simulate-insn.c create mode 100644 arch/riscv/kernel/probes/simulate-insn.h diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index e6424d8b..c07214a 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -67,6 +67,8 @@ config RISCV select HAVE_FUTEX_CMPXCHG if FUTEX select HAVE_GCC_PLUGINS select HAVE_GENERIC_VDSO if MMU && 64BIT + select HAVE_KPROBES + select HAVE_KRETPROBES select HAVE_PCI select HAVE_PERF_EVENTS select HAVE_PERF_REGS diff --git a/arch/riscv/include/asm/kprobes.h b/arch/riscv/include/asm/kprobes.h index 56a98ea3..4647d38 100644 --- a/arch/riscv/include/asm/kprobes.h +++ b/arch/riscv/include/asm/kprobes.h @@ -11,4 +11,44 @@ #include +#ifdef CONFIG_KPROBES +#include +#include +#include + +#define __ARCH_WANT_KPROBES_INSN_SLOT +#define MAX_INSN_SIZE 2 + +#define flush_insn_slot(p) do { } while (0) +#define kretprobe_blacklist_size 0 + +#include + +struct prev_kprobe { + struct kprobe *kp; + unsigned int status; +}; + +/* Single step context for kprobe */ +struct kprobe_step_ctx { + unsigned long ss_pending; + unsigned long match_addr; +}; + +/* per-cpu kprobe control block */ +struct kprobe_ctlblk { + unsigned int kprobe_status; + unsigned long saved_status; + struct prev_kprobe prev_kprobe; + struct kprobe_step_ctx ss_ctx; +}; + +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 */ diff --git a/arch/riscv/include/asm/probes.h b/arch/riscv/include/asm/probes.h new file mode 100644 index ..a787e6d ---
[PATCH v4 5/9] riscv: Add kprobes supported
From: Guo Ren This patch enables "kprobe & kretprobe" to work with ftrace interface. It utilized software breakpoint as single-step mechanism. Some instructions which can't be single-step executed must be simulated in kernel execution slot, such as: branch, jal, auipc, la ... Some instructions should be rejected for probing and we use a blacklist to filter, such as: ecall, ebreak, ... We use ebreak & c.ebreak to replace origin instruction and the kprobe handler prepares an executable memory slot for out-of-line execution with a copy of the original instruction being probed. In execution slot we add ebreak behind original instruction to simulate a single-setp mechanism. The patch is based on packi's work [1] and csky's work [2]. - The kprobes_trampoline.S is all from packi's patch - The single-step mechanism is new designed for riscv without hw single-step trap - The simulation codes are from csky - Frankly, all codes refer to other archs' implementation [1] https://lore.kernel.org/linux-riscv/20181113195804.22825-1...@packi.ch/ [2] https://lore.kernel.org/linux-csky/20200403044150.20562-9-guo...@kernel.org/ Signed-off-by: Guo Ren Co-Developed-by: Patrick Stählin Acked-by: Masami Hiramatsu Tested-by: Zong Li Reviewed-by: Pekka Enberg Cc: Patrick Stählin Cc: Palmer Dabbelt Cc: Björn Töpel --- arch/riscv/Kconfig| 2 + arch/riscv/include/asm/kprobes.h | 40 +++ arch/riscv/include/asm/probes.h | 24 ++ arch/riscv/kernel/Makefile| 1 + arch/riscv/kernel/probes/Makefile | 4 + arch/riscv/kernel/probes/decode-insn.c| 48 arch/riscv/kernel/probes/decode-insn.h| 18 ++ arch/riscv/kernel/probes/kprobes.c| 398 ++ arch/riscv/kernel/probes/kprobes_trampoline.S | 93 ++ arch/riscv/kernel/probes/simulate-insn.c | 85 ++ arch/riscv/kernel/probes/simulate-insn.h | 47 +++ arch/riscv/kernel/traps.c | 9 + arch/riscv/mm/fault.c | 4 + 13 files changed, 773 insertions(+) create mode 100644 arch/riscv/include/asm/probes.h create mode 100644 arch/riscv/kernel/probes/Makefile create mode 100644 arch/riscv/kernel/probes/decode-insn.c create mode 100644 arch/riscv/kernel/probes/decode-insn.h create mode 100644 arch/riscv/kernel/probes/kprobes.c create mode 100644 arch/riscv/kernel/probes/kprobes_trampoline.S create mode 100644 arch/riscv/kernel/probes/simulate-insn.c create mode 100644 arch/riscv/kernel/probes/simulate-insn.h diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index e6424d8b..c07214a 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -67,6 +67,8 @@ config RISCV select HAVE_FUTEX_CMPXCHG if FUTEX select HAVE_GCC_PLUGINS select HAVE_GENERIC_VDSO if MMU && 64BIT + select HAVE_KPROBES + select HAVE_KRETPROBES select HAVE_PCI select HAVE_PERF_EVENTS select HAVE_PERF_REGS diff --git a/arch/riscv/include/asm/kprobes.h b/arch/riscv/include/asm/kprobes.h index 56a98ea3..4647d38 100644 --- a/arch/riscv/include/asm/kprobes.h +++ b/arch/riscv/include/asm/kprobes.h @@ -11,4 +11,44 @@ #include +#ifdef CONFIG_KPROBES +#include +#include +#include + +#define __ARCH_WANT_KPROBES_INSN_SLOT +#define MAX_INSN_SIZE 2 + +#define flush_insn_slot(p) do { } while (0) +#define kretprobe_blacklist_size 0 + +#include + +struct prev_kprobe { + struct kprobe *kp; + unsigned int status; +}; + +/* Single step context for kprobe */ +struct kprobe_step_ctx { + unsigned long ss_pending; + unsigned long match_addr; +}; + +/* per-cpu kprobe control block */ +struct kprobe_ctlblk { + unsigned int kprobe_status; + unsigned long saved_status; + struct prev_kprobe prev_kprobe; + struct kprobe_step_ctx ss_ctx; +}; + +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 */ diff --git a/arch/riscv/include/asm/probes.h b/arch/riscv/include/asm/probes.h new file mode 100644 index ..a787e6d --- /dev/null +++ b/arch/riscv/include/asm/probes.h @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef _ASM_RISCV_PROBES_H +#define _ASM_RISCV_PROBES_H + +typedef u32 probe_opcode_t; +typedef bool (probes_handler_t) (u32 opcode, unsigned long addr, struct pt_regs *); + +/* architecture specific copy of original instruction */ +struct arch_probe_insn { + probe_opcode_t *insn; + probes_handler_t *handler; + /* restore address after simulation */ + unsigned long restore; +}; + +#ifdef