@@ -456,3 +456,34 @@ int setup_detour_execution(struct kprobe *p, struct pt_regs *regs, int reenter)
return 0;
}
NOKPROBE_SYMBOL(setup_detour_execution);
+
+#ifdef CONFIG_EARLY_KPROBES
+void arch_fix_ftrace_early_kprobe(struct optimized_kprobe *op)
+{
+ const unsigned char *correct_nop5 = ideal_nops[NOP_ATOMIC5];
+ struct kprobe *list_p;
+
+ u32 mask = KPROBE_FLAG_EARLY |
+ KPROBE_FLAG_OPTIMIZED |
+ KPROBE_FLAG_FTRACE;
+
+ if ((op->kp.flags & mask) != mask)
+ return;
+
+ /*
+ * For early kprobe on ftrace, use right nop instruction.
+ * See x86 ftrace_make_nop and ftrace_nop_replace. Note that
+ * ideal_nops used by ftrace_nop_replace is setupt after early
+ * kprobe registration.
+ */
+
+ memcpy(&op->kp.opcode, correct_nop5, sizeof(kprobe_opcode_t));
+ memcpy(op->optinsn.copied_insn, correct_nop5 + INT3_SIZE,
+ RELATIVE_ADDR_SIZE);
+
+ /* Fix all kprobes connected to it */
+ list_for_each_entry_rcu(list_p, &op->kp.list, list)
+ memcpy(&list_p->opcode, correct_nop5, sizeof(kprobe_opcode_t));
+
+}
+#endif
@@ -459,6 +459,11 @@ struct early_kprobe_slot {
extern void kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip,
struct ftrace_ops *ops, struct pt_regs *regs);
extern int arch_prepare_kprobe_ftrace(struct kprobe *p);
+
+#ifdef CONFIG_EARLY_KPROBES
+extern void arch_fix_ftrace_early_kprobe(struct optimized_kprobe *p);
+#endif
+
#endif
int arch_check_ftrace_location(struct kprobe *p);
@@ -2536,6 +2536,12 @@ EXPORT_SYMBOL_GPL(jprobe_return);
#ifdef CONFIG_EARLY_KPROBES
+#ifdef CONFIG_KPROBES_ON_FTRACE
+void __weak arch_fix_ftrace_early_kprobe(struct optimized_kprobe *p)
+{
+}
+#endif
+
static int register_early_kprobe(struct kprobe *p)
{
struct early_kprobe_slot *slot;
This patch is for futher use. arch_fix_ftrace_early_kprobe() will be called when ftrace trying to convert ftrace entries to nop and fail. For x86 it should adjust the saved nop instruction here because it doesn't know what nop ftrace will choose when early probing. Signed-off-by: Wang Nan <wangnan0@huawei.com> --- arch/x86/kernel/kprobes/opt.c | 31 +++++++++++++++++++++++++++++++ include/linux/kprobes.h | 5 +++++ kernel/kprobes.c | 6 ++++++ 3 files changed, 42 insertions(+)