Skip to content

Commit 4638d7e

Browse files
committed
x86/kprobes: Cleanup kprobes on ftrace code
Cleanup kprobes on ftrace code for x86. - Set instruction pointer (ip + MCOUNT_INSN_SIZE) after pre_handler only when p->post_handler exists. - Use INT3_INSN_SIZE instead of 1. - Use instruction_pointer/instruction_pointer_set() functions instead of accessing regs->ip directly. Link: https://lore.kernel.org/all/172951436219.167263.18330240454389154327.stgit@devnote2/ Signed-off-by: Masami Hiramatsu (Google) <[email protected]>
1 parent 3fbff98 commit 4638d7e

File tree

1 file changed

+11
-8
lines changed

1 file changed

+11
-8
lines changed

arch/x86/kernel/kprobes/ftrace.c

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include <linux/hardirq.h>
1010
#include <linux/preempt.h>
1111
#include <linux/ftrace.h>
12+
#include <asm/text-patching.h>
1213

1314
#include "common.h"
1415

@@ -36,23 +37,25 @@ void kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip,
3637
if (kprobe_running()) {
3738
kprobes_inc_nmissed_count(p);
3839
} else {
39-
unsigned long orig_ip = regs->ip;
40+
unsigned long orig_ip = instruction_pointer(regs);
41+
4042
/* Kprobe handler expects regs->ip = ip + 1 as breakpoint hit */
41-
regs->ip = ip + sizeof(kprobe_opcode_t);
43+
instruction_pointer_set(regs, ip + INT3_INSN_SIZE);
4244

4345
__this_cpu_write(current_kprobe, p);
4446
kcb->kprobe_status = KPROBE_HIT_ACTIVE;
4547
if (!p->pre_handler || !p->pre_handler(p, regs)) {
46-
/*
47-
* Emulate singlestep (and also recover regs->ip)
48-
* as if there is a 5byte nop
49-
*/
50-
regs->ip = (unsigned long)p->addr + MCOUNT_INSN_SIZE;
5148
if (unlikely(p->post_handler)) {
49+
/*
50+
* Emulate singlestep (and also recover regs->ip)
51+
* as if there is a 5byte nop
52+
*/
53+
instruction_pointer_set(regs, ip + MCOUNT_INSN_SIZE);
5254
kcb->kprobe_status = KPROBE_HIT_SSDONE;
5355
p->post_handler(p, regs, 0);
5456
}
55-
regs->ip = orig_ip;
57+
/* Recover IP address */
58+
instruction_pointer_set(regs, orig_ip);
5659
}
5760
/*
5861
* If pre_handler returns !0, it changes regs->ip. We have to

0 commit comments

Comments
 (0)