Fix ftrace-based kprobes
cover Fix ftrace-based kprobes
Hi,
This series of patches fixes some bugs and corrects behaviors of ftrace and ftrace-based kprobe.
As Fengguang reported at https://lkml.org/lkml/2012/8/24/45
ftrace-based kprobes and -mfentry option caused failures on kprobe smoke test. This basically comes from the initial design of ftrace-based kprobe which prohibits jprobe on ftraced kprobe.
Without -mfentry support, this works well because NO mcount call is at the first instruction of any function. However, -mfentry calls it at the first one and it conflicts with jprobe.
On this series, kprobe allows jprobe even if it is based on ftrace. For this fix, I need following fixes.
- Make ftrace-handler interface same on x86/x86-64 On x86, ftrace_regs_caller puts a same address on ip and regs.ip, however those are different on x86-64. I've modified x86 to fit to x86-64 ABI.
- Fix kprobe ftrace handler for above ABI change Current kprobe_ftrace_handler expects ip == regs.ip, but it's not correct on x86-64 (and now on x86 too). This should be fixed.
- Use regs.ip for return address on ftrace
From Steven, this change is suggested. Thanks!
Thank you,
---
Masami Hiramatsu (3):
[BUGFIX] kprobes/x86: Fix to support jprobes on ftrace-based kprobe [BUGFIX] kprobes/x86: Fix kprobes to collectly handle IP on ftrace [BUGFIX] ftrace/x86: Adjust x86 regs.ip as like as x86-64
Steven Rostedt (1):
ftrace/x86-64: Allow to change RIP in handlers
arch/x86/kernel/entry_32.S | 3 +-- arch/x86/kernel/entry_64.S | 4 ++++ arch/x86/kernel/kprobes.c | 43 +++++++++++++++++++++++++++++++------------ kernel/kprobes.c | 3 --- 4 files changed, 36 insertions(+), 17 deletions(-)
Signature · 4 lines
Masami HIRAMATSU Software Platform Research Dept. Linux Technology Center Hitachi, Ltd., Yokohama Research Laboratory E-mail: [email protected]
PATCH 1/4 ftrace/x86: Adjust x86 regs.ip as like as x86-64
Adjust x86 regs.ip to ip + MCOUNT_INSN_SIZE as like as on x86-64. This helps us to consolidate codes which use regs->ip on both of x86/x86-64.
---
arch/x86/kernel/entry_32.S | 3 +-- 1 files changed, 1 insertions(+), 2 deletions(-)
arch/x86/kernel/entry_32.S +1 -2
@@ -1148,7 +1148,6 @@ ENTRY(ftrace_regs_caller) * ip location, and move flags into the return ip location. */ pushl 4(%esp) /* save return ip into ip slot */ - subl $MCOUNT_INSN_SIZE, (%esp) /* Adjust ip */ pushl $0 /* Load 0 into orig_ax */ pushl %gs
@@ -1169,6 +1168,7 @@ ENTRY(ftrace_regs_caller) movl $__KERNEL_CS,13*4(%esp) movl 12*4(%esp), %eax /* Load ip (1st parameter) */ + subl $MCOUNT_INSN_SIZE, %eax /* Adjust ip */ movl 0x4(%ebp), %edx /* Load parent ip (2nd parameter) */ leal function_trace_op, %ecx /* Save ftrace_pos in 3rd parameter */ pushl %esp /* Save pt_regs as 4th parameter */
@@ -1180,7 +1180,6 @@ GLOBAL(ftrace_regs_call) movl 14*4(%esp), %eax /* Move flags back into cs */ movl %eax, 13*4(%esp) /* Needed to keep addl from modifying flags */ movl 12*4(%esp), %eax /* Get return ip from regs->ip */ - addl $MCOUNT_INSN_SIZE, %eax movl %eax, 14*4(%esp) /* Put return ip back for ret */ popl %ebx
[tip:perf/core] ftrace/x86: Adjust x86 regs.ip as like as x86-64
Commit-ID: a5e37863ab31d78faddff15675c89979792bc0bd Gitweb: http://git.kernel.org/tip/a5e37863ab31d78faddff15675c89979792bc0bd Author: Masami Hiramatsu <[email protected]> AuthorDate: Wed, 5 Sep 2012 23:31:00 +0900 Committer: Steven Rostedt <[email protected]> CommitDate: Thu, 13 Sep 2012 22:52:09 -0400
ftrace/x86: Adjust x86 regs.ip as like as x86-64
Adjust x86 regs.ip to ip + MCOUNT_INSN_SIZE as like as on x86-64. This helps us to consolidate codes which use regs->ip on both of x86/x86-64.
--- arch/x86/kernel/entry_32.S | 3 +-- 1 files changed, 1 insertions(+), 2 deletions(-)
arch/x86/kernel/entry_32.S +1 -2
@@ -1148,7 +1148,6 @@ ENTRY(ftrace_regs_caller) * ip location, and move flags into the return ip location. */ pushl 4(%esp) /* save return ip into ip slot */ - subl $MCOUNT_INSN_SIZE, (%esp) /* Adjust ip */ pushl $0 /* Load 0 into orig_ax */ pushl %gs
@@ -1169,6 +1168,7 @@ ENTRY(ftrace_regs_caller) movl $__KERNEL_CS,13*4(%esp) movl 12*4(%esp), %eax /* Load ip (1st parameter) */ + subl $MCOUNT_INSN_SIZE, %eax /* Adjust ip */ movl 0x4(%ebp), %edx /* Load parent ip (2nd parameter) */ leal function_trace_op, %ecx /* Save ftrace_pos in 3rd parameter */ pushl %esp /* Save pt_regs as 4th parameter */
@@ -1180,7 +1180,6 @@ GLOBAL(ftrace_regs_call) movl 14*4(%esp), %eax /* Move flags back into cs */ movl %eax, 13*4(%esp) /* Needed to keep addl from modifying flags */ movl 12*4(%esp), %eax /* Get return ip from regs->ip */ - addl $MCOUNT_INSN_SIZE, %eax movl %eax, 14*4(%esp) /* Put return ip back for ret */ popl %ebx
PATCH 2/4 kprobes/x86: Fix kprobes to collectly handle IP on ftrace
In reply to Masami HiramatsuCurrent kprobe_ftrace_handler expects regs->ip == ip, but it is incorrect (originally on x86-64). Actually, ftrace handler sets regs->ip = ip + MCOUNT_INSN_SIZE. kprobe_ftrace_handler must take care for that.
---
arch/x86/kernel/kprobes.c | 9 ++++++--- 1 files changed, 6 insertions(+), 3 deletions(-)
arch/x86/kernel/kprobes.c +6 -3
@@ -1072,7 +1072,8 @@ void __kprobes kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip,if (kprobe_running ()) {kprobes_inc_nmissed_count (p); }else { - regs->ip +=sizeof (kprobe_opcode_t); +/* Kprobe handler expects regs->ip = ip + 1 as breakpoint hit */ + regs->ip = ip +sizeof (kprobe_opcode_t);__this_cpu_write (current_kprobe, p); kcb->kprobe_status =KPROBE_HIT_ACTIVE ;
@@ -1080,13 +1081,15 @@ void __kprobes kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip, p->pre_handler (p, regs);if (unlikely (p->post_handler)) { -/* Emulate singlestep as if there is a 5byte nop */ +/* +* Emulate singlestep (and also recover regs->ip) +* as if there is a 5byte nop +*/ regs->ip = ip +MCOUNT_INSN_SIZE ; kcb->kprobe_status =KPROBE_HIT_SSDONE ; p->post_handler (p, regs,0 ); }__this_cpu_write (current_kprobe,NULL ); - regs->ip = ip;/* Recover for next callback */ } end:local_irq_restore (flags);
[tip:perf/core] kprobes/x86: Fix kprobes to collectly handle IP on ftrace
Commit-ID: 4b036d54bf849a75d0103b33d92a53f89ecb9315 Gitweb: http://git.kernel.org/tip/4b036d54bf849a75d0103b33d92a53f89ecb9315 Author: Masami Hiramatsu <[email protected]> AuthorDate: Wed, 5 Sep 2012 23:31:12 +0900 Committer: Steven Rostedt <[email protected]> CommitDate: Thu, 13 Sep 2012 22:52:09 -0400
kprobes/x86: Fix kprobes to collectly handle IP on ftrace
Current kprobe_ftrace_handler expects regs->ip == ip, but it is incorrect (originally on x86-64). Actually, ftrace handler sets regs->ip = ip + MCOUNT_INSN_SIZE. kprobe_ftrace_handler must take care for that.
--- arch/x86/kernel/kprobes.c | 9 ++++++--- 1 files changed, 6 insertions(+), 3 deletions(-)
arch/x86/kernel/kprobes.c +6 -3
@@ -1072,7 +1072,8 @@ void __kprobes kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip,if (kprobe_running ()) {kprobes_inc_nmissed_count (p); }else { - regs->ip +=sizeof (kprobe_opcode_t); +/* Kprobe handler expects regs->ip = ip + 1 as breakpoint hit */ + regs->ip = ip +sizeof (kprobe_opcode_t);__this_cpu_write (current_kprobe, p); kcb->kprobe_status =KPROBE_HIT_ACTIVE ;
@@ -1080,13 +1081,15 @@ void __kprobes kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip, p->pre_handler (p, regs);if (unlikely (p->post_handler)) { -/* Emulate singlestep as if there is a 5byte nop */ +/* +* Emulate singlestep (and also recover regs->ip) +* as if there is a 5byte nop +*/ regs->ip = ip +MCOUNT_INSN_SIZE ; kcb->kprobe_status =KPROBE_HIT_SSDONE ; p->post_handler (p, regs,0 ); }__this_cpu_write (current_kprobe,NULL ); - regs->ip = ip;/* Recover for next callback */ } end:local_irq_restore (flags);
PATCH 3/4 ftrace/x86-64: Allow to change RIP in handlers
In reply to Masami HiramatsuFrom: Steven Rostedt <[email protected]>
Allow ftrace handlers to change RIP register (regs->ip) in handlers. This will allow handlers to call another function instead of original function.
---
arch/x86/kernel/entry_64.S | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-)
arch/x86/kernel/entry_64.S +4 -0
@@ -165,6 +165,10 @@ GLOBAL(ftrace_regs_call) movq EFLAGS(%rsp), %rax movq %rax, SS(%rsp) + /* Handlers can change the RIP */ + movq RIP(%rsp), %rax + movq %rax, SS+8(%rsp) + /* restore the rest of pt_regs */ movq R15(%rsp), %r15 movq R14(%rsp), %r14
[tip:perf/core] ftrace/x86-64: Allow to change RIP in handlers
Commit-ID: 47d5a5f88b9d25d6464c9b60c28f391e84e3ed65 Gitweb: http://git.kernel.org/tip/47d5a5f88b9d25d6464c9b60c28f391e84e3ed65 Author: Steven Rostedt <[email protected]> AuthorDate: Wed, 5 Sep 2012 23:31:18 +0900 Committer: Steven Rostedt <[email protected]> CommitDate: Thu, 13 Sep 2012 22:52:10 -0400
ftrace/x86-64: Allow to change RIP in handlers
Allow ftrace handlers to change RIP register (regs->ip) in handlers. This will allow handlers to call another function instead of original function.
--- arch/x86/kernel/entry_64.S | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-)
arch/x86/kernel/entry_64.S +4 -0
@@ -165,6 +165,10 @@ GLOBAL(ftrace_regs_call) movq EFLAGS(%rsp), %rax movq %rax, SS(%rsp) + /* Handlers can change the RIP */ + movq RIP(%rsp), %rax + movq %rax, SS+8(%rsp) + /* restore the rest of pt_regs */ movq R15(%rsp), %r15 movq R14(%rsp), %r14
PATCH 4/4 kprobes/x86: Fix to support jprobes on ftrace-based kprobe
In reply to Masami HiramatsuFix kprobes/x86 to support jprobes on ftrace-based kprobes. Because of -mfentry support of ftrace, ftrace is now put on the beginning of function where jprobes are put.
Originally ftrace-based kprobes doesn't support jprobe because it will change regs->ip and ftrace doesn't support changing IP and ftrace itself doesn't conflict jprobe. However, ftrace -mfentry support moves mcount call on the top of functions where jprobes are put. This means that jprobe always conflicts with ftrace-based kprobe and fails.
This patch allows ftrace-based kprobes to support jprobes by allowing to modify regs->ip and kprobes breakpoint handler also allows to skip singlestepping because there is a ftrace call (not an original instruction).
---
arch/x86/kernel/kprobes.c | 42 +++++++++++++++++++++++++++++------------- kernel/kprobes.c | 3 --- 2 files changed, 29 insertions(+), 16 deletions(-)
arch/x86/kernel/kprobes.c +29 -13
@@ -541,6 +541,8 @@ reenter_kprobe(struct kprobe *p, struct pt_regs *regs, struct kprobe_ctlblk *kcbreturn 1 ; } +static void __kprobes skip_singlestep (struct kprobe *p,struct pt_regs *regs, +struct kprobe_ctlblk *kcb);/* * Interrupts are disabled on entry as trap3 is an interrupt gate and they * remain disabled throughout this function.
@@ -599,6 +601,12 @@ static int __kprobes kprobe_handler(struct pt_regs *regs) }else if (kprobe_running ()) { p =__this_cpu_read (current_kprobe);if (p->break_handler && p->break_handler (p, regs)) { +#ifdef KPROBES_CAN_USE_FTRACE +if (kprobe_ftrace (p)) { +skip_singlestep (p, regs, kcb); +return 1 ; + } +#endif setup_singlestep (p, regs, kcb,0 );return 1 ; }
@@ -1053,6 +1061,21 @@ int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) }#ifdef KPROBES_CAN_USE_FTRACE +static void __kprobes skip_singlestep (struct kprobe *p,struct pt_regs *regs, +struct kprobe_ctlblk *kcb) +{ +/* +* Emulate singlestep (and also recover regs->ip) +* as if there is a 5byte nop +*/ + regs->ip = (unsigned long )p->addr +MCOUNT_INSN_SIZE ; +if (unlikely (p->post_handler)) { + kcb->kprobe_status =KPROBE_HIT_SSDONE ; + p->post_handler (p, regs,0 ); + } +__this_cpu_write (current_kprobe,NULL ); +} +/* Ftrace callback handler for kprobes */ void __kprobes kprobe_ftrace_handler (unsigned long ip,unsigned long parent_ip,struct ftrace_ops *ops,struct pt_regs *regs)
@@ -1077,19 +1100,12 @@ void __kprobes kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip,__this_cpu_write (current_kprobe, p); kcb->kprobe_status =KPROBE_HIT_ACTIVE ; -if (p->pre_handler) - p->pre_handler (p, regs); - -if (unlikely (p->post_handler)) { -/* -* Emulate singlestep (and also recover regs->ip) -* as if there is a 5byte nop -*/ - regs->ip = ip +MCOUNT_INSN_SIZE ; - kcb->kprobe_status =KPROBE_HIT_SSDONE ; - p->post_handler (p, regs,0 ); - } -__this_cpu_write (current_kprobe,NULL ); +if (!p->pre_handler || !p->pre_handler (p, regs)) +skip_singlestep (p, regs, kcb); +/* +* If pre_handler returns !0, it sets regs->ip and +* resets current kprobe. +*/ } end:local_irq_restore (flags);
kernel/kprobes.c +0 -3
@@ -1418,9 +1418,6 @@ static __kprobes int check_kprobe_address_safe(struct kprobe *p,/* Given address is not on the instruction boundary */ if ((unsigned long )p->addr != ftrace_addr)return -EILSEQ ; -/* break_handler (jprobe) can not work with ftrace */ -if (p->break_handler) -return -EINVAL ; p->flags |=KPROBE_FLAG_FTRACE ;#else /* !KPROBES_CAN_USE_FTRACE */ return -EINVAL ;
Re: [PATCH -tip 4/4] [BUGFIX] kprobes/x86: Fix to support jprobes on ftrace-based kprobe
Quoted 16 lines · Masami Hiramatsu
Fix kprobes/x86 to support jprobes on ftrace-based kprobes. Because of -mfentry support of ftrace, ftrace is now put on the beginning of function where jprobes are put.
Originally ftrace-based kprobes doesn't support jprobe because it will change
regs->ipand ftrace doesn't support changing IP and ftrace itself doesn't conflict jprobe. However, ftrace -mfentry support moves mcount call on the top of functions where jprobes are put. This means that jprobe always conflicts with ftrace-based kprobe and fails.This patch allows ftrace-based kprobes to support jprobes by allowing to modify
regs->ipand kprobes breakpoint handler also allows to skip singlestepping because there is a ftrace call (not an original instruction).
Quoted 5 lines
Signed-off-by Masami Hiramatsu <[email protected]>Cc Thomas Gleixner <[email protected]>Cc Ingo Molnar <[email protected]>Cc "H. Peter Anvin" <[email protected]>Cc Steven Rostedt <[email protected]>
This should have a below line...
Thanks!
Quoted 95 lines
---
arch/x86/kernel/kprobes.c | 42 +++++++++++++++++++++++++++++------------- kernel/kprobes.c | 3 --- 2 files changed, 29 insertions(+), 16 deletions(-)arch/x86/kernel/kprobes.c +29
-13@@ -541,6 +541,8 @@ reenter_kprobe(struct kprobe *p, struct pt_regs *regs, struct kprobe_ctlblk *kcbreturn 1 ; } +static void __kprobes skip_singlestep (struct kprobe *p,struct pt_regs *regs, +struct kprobe_ctlblk *kcb);/* * Interrupts are disabled on entry as trap3 is an interrupt gate and they * remain disabled throughout this function. @@ -599,6 +601,12 @@ static int __kprobes kprobe_handler(struct pt_regs *regs) }else if (kprobe_running ()) { p =__this_cpu_read (current_kprobe);if (p->break_handler && p->break_handler (p, regs)) { +#ifdef KPROBES_CAN_USE_FTRACE +if (kprobe_ftrace (p)) { +skip_singlestep (p, regs, kcb); +return 1 ; + } +#endif setup_singlestep (p, regs, kcb,0 );return 1 ; }@@ -1053,6 +1061,21 @@ int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) }#ifdef KPROBES_CAN_USE_FTRACE +static void __kprobes skip_singlestep (struct kprobe *p,struct pt_regs *regs, +struct kprobe_ctlblk *kcb) +{ +/* +* Emulate singlestep (and also recover regs->ip) +* as if there is a 5byte nop +*/ + regs->ip = (unsigned long )p->addr +MCOUNT_INSN_SIZE ; +if (unlikely (p->post_handler)) { + kcb->kprobe_status =KPROBE_HIT_SSDONE ; + p->post_handler (p, regs,0 ); + } +__this_cpu_write (current_kprobe,NULL ); +} +/* Ftrace callback handler for kprobes */ void __kprobes kprobe_ftrace_handler (unsigned long ip,unsigned long parent_ip,struct ftrace_ops *ops,struct pt_regs *regs)@@ -1077,19 +1100,12 @@ void __kprobes kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip,__this_cpu_write (current_kprobe, p); kcb->kprobe_status =KPROBE_HIT_ACTIVE ; -if (p->pre_handler) - p->pre_handler (p, regs); - -if (unlikely (p->post_handler)) { -/* -* Emulate singlestep (and also recover regs->ip) -* as if there is a 5byte nop -*/ - regs->ip = ip +MCOUNT_INSN_SIZE ; - kcb->kprobe_status =KPROBE_HIT_SSDONE ; - p->post_handler (p, regs,0 ); - } -__this_cpu_write (current_kprobe,NULL ); +if (!p->pre_handler || !p->pre_handler (p, regs)) +skip_singlestep (p, regs, kcb); +/* +* If pre_handler returns !0, it sets regs->ip and +* resets current kprobe. +*/ } end:local_irq_restore (flags);kernel/kprobes.c +0
-3@@ -1418,9 +1418,6 @@ static __kprobes int check_kprobe_address_safe(struct kprobe *p,/* Given address is not on the instruction boundary */ if ((unsigned long )p->addr != ftrace_addr)return -EILSEQ ; -/* break_handler (jprobe) can not work with ftrace */ -if (p->break_handler) -return -EINVAL ; p->flags |=KPROBE_FLAG_FTRACE ;#else /* !KPROBES_CAN_USE_FTRACE */ return -EINVAL ;
Signature · 4 lines
Masami HIRAMATSU Software Platform Research Dept. Linux Technology Center Hitachi, Ltd., Yokohama Research Laboratory E-mail: [email protected]
[tip:perf/core] kprobes/x86: Fix to support jprobes on ftrace-based kprobe
In reply to Masami HiramatsuCommit-ID: c6aaf4d0bb86e2154ea31a33804cec300611255f Gitweb: http://git.kernel.org/tip/c6aaf4d0bb86e2154ea31a33804cec300611255f Author: Masami Hiramatsu <[email protected]> AuthorDate: Wed, 5 Sep 2012 23:31:25 +0900 Committer: Steven Rostedt <[email protected]> CommitDate: Thu, 13 Sep 2012 22:52:11 -0400
kprobes/x86: Fix to support jprobes on ftrace-based kprobe
Fix kprobes/x86 to support jprobes on ftrace-based kprobes. Because of -mfentry support of ftrace, ftrace is now put on the beginning of function where jprobes are put.
Originally ftrace-based kprobes doesn't support jprobe because it will change regs->ip and ftrace doesn't support changing IP and ftrace itself doesn't conflict jprobe. However, ftrace -mfentry support moves mcount call on the top of functions where jprobes are put. This means that jprobe always conflicts with ftrace-based kprobe and fails.
This patch allows ftrace-based kprobes to support jprobes by allowing to modify regs->ip and kprobes breakpoint handler also allows to skip singlestepping because there is a ftrace call (not an original instruction).
--- arch/x86/kernel/kprobes.c | 42 +++++++++++++++++++++++++++++------------- kernel/kprobes.c | 3 --- 2 files changed, 29 insertions(+), 16 deletions(-)
arch/x86/kernel/kprobes.c +29 -13
@@ -541,6 +541,8 @@ reenter_kprobe(struct kprobe *p, struct pt_regs *regs, struct kprobe_ctlblk *kcbreturn 1 ; } +static void __kprobes skip_singlestep (struct kprobe *p,struct pt_regs *regs, +struct kprobe_ctlblk *kcb);/* * Interrupts are disabled on entry as trap3 is an interrupt gate and they * remain disabled throughout this function.
@@ -599,6 +601,12 @@ static int __kprobes kprobe_handler(struct pt_regs *regs) }else if (kprobe_running ()) { p =__this_cpu_read (current_kprobe);if (p->break_handler && p->break_handler (p, regs)) { +#ifdef KPROBES_CAN_USE_FTRACE +if (kprobe_ftrace (p)) { +skip_singlestep (p, regs, kcb); +return 1 ; + } +#endif setup_singlestep (p, regs, kcb,0 );return 1 ; }
@@ -1053,6 +1061,21 @@ int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) }#ifdef KPROBES_CAN_USE_FTRACE +static void __kprobes skip_singlestep (struct kprobe *p,struct pt_regs *regs, +struct kprobe_ctlblk *kcb) +{ +/* +* Emulate singlestep (and also recover regs->ip) +* as if there is a 5byte nop +*/ + regs->ip = (unsigned long )p->addr +MCOUNT_INSN_SIZE ; +if (unlikely (p->post_handler)) { + kcb->kprobe_status =KPROBE_HIT_SSDONE ; + p->post_handler (p, regs,0 ); + } +__this_cpu_write (current_kprobe,NULL ); +} +/* Ftrace callback handler for kprobes */ void __kprobes kprobe_ftrace_handler (unsigned long ip,unsigned long parent_ip,struct ftrace_ops *ops,struct pt_regs *regs)
@@ -1077,19 +1100,12 @@ void __kprobes kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip,__this_cpu_write (current_kprobe, p); kcb->kprobe_status =KPROBE_HIT_ACTIVE ; -if (p->pre_handler) - p->pre_handler (p, regs); - -if (unlikely (p->post_handler)) { -/* -* Emulate singlestep (and also recover regs->ip) -* as if there is a 5byte nop -*/ - regs->ip = ip +MCOUNT_INSN_SIZE ; - kcb->kprobe_status =KPROBE_HIT_SSDONE ; - p->post_handler (p, regs,0 ); - } -__this_cpu_write (current_kprobe,NULL ); +if (!p->pre_handler || !p->pre_handler (p, regs)) +skip_singlestep (p, regs, kcb); +/* +* If pre_handler returns !0, it sets regs->ip and +* resets current kprobe. +*/ } end:local_irq_restore (flags);
kernel/kprobes.c +0 -3
@@ -1418,9 +1418,6 @@ static __kprobes int check_kprobe_address_safe(struct kprobe *p,/* Given address is not on the instruction boundary */ if ((unsigned long )p->addr != ftrace_addr)return -EILSEQ ; -/* break_handler (jprobe) can not work with ftrace */ -if (p->break_handler) -return -EINVAL ; p->flags |=KPROBE_FLAG_FTRACE ;#else /* !KPROBES_CAN_USE_FTRACE */ return -EINVAL ;