* [PATCH -tip 0/4][BUGFIX] Fix ftrace-based kprobes
@ 2012-09-05 14:30 Masami Hiramatsu
2012-09-05 14:31 ` [PATCH -tip 1/4] [BUGFIX] ftrace/x86: Adjust x86 regs.ip as like as x86-64 Masami Hiramatsu
` (3 more replies)
0 siblings, 4 replies; 10+ messages in thread
From: Masami Hiramatsu @ 2012-09-05 14:30 UTC (permalink / raw)
To: Steven Rostedt, linux-kernel
Cc: H. Peter Anvin, Peter Zijlstra, Frederic Weisbecker,
Thomas Gleixner, Ingo Molnar, Andrew Morton, yrl.pp-manager.tt
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(-)
--
Masami HIRAMATSU
Software Platform Research Dept. Linux Technology Center
Hitachi, Ltd., Yokohama Research Laboratory
E-mail: masami.hiramatsu.pt@hitachi.com
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH -tip 1/4] [BUGFIX] ftrace/x86: Adjust x86 regs.ip as like as x86-64
2012-09-05 14:30 [PATCH -tip 0/4][BUGFIX] Fix ftrace-based kprobes Masami Hiramatsu
@ 2012-09-05 14:31 ` Masami Hiramatsu
2012-09-14 11:42 ` [tip:perf/core] " tip-bot for Masami Hiramatsu
2012-09-05 14:31 ` [PATCH -tip 2/4] [BUGFIX] kprobes/x86: Fix kprobes to collectly handle IP on ftrace Masami Hiramatsu
` (2 subsequent siblings)
3 siblings, 1 reply; 10+ messages in thread
From: Masami Hiramatsu @ 2012-09-05 14:31 UTC (permalink / raw)
To: Steven Rostedt, linux-kernel
Cc: H. Peter Anvin, Peter Zijlstra, Frederic Weisbecker,
Thomas Gleixner, Ingo Molnar, Andrew Morton, yrl.pp-manager.tt,
Masami Hiramatsu, Thomas Gleixner, Ingo Molnar, H. Peter Anvin,
Steven Rostedt
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.
Signed-off-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
---
arch/x86/kernel/entry_32.S | 3 +--
1 files changed, 1 insertions(+), 2 deletions(-)
diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S
index 061ac17..f438a44 100644
--- a/arch/x86/kernel/entry_32.S
+++ b/arch/x86/kernel/entry_32.S
@@ -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
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH -tip 2/4] [BUGFIX] kprobes/x86: Fix kprobes to collectly handle IP on ftrace
2012-09-05 14:30 [PATCH -tip 0/4][BUGFIX] Fix ftrace-based kprobes Masami Hiramatsu
2012-09-05 14:31 ` [PATCH -tip 1/4] [BUGFIX] ftrace/x86: Adjust x86 regs.ip as like as x86-64 Masami Hiramatsu
@ 2012-09-05 14:31 ` Masami Hiramatsu
2012-09-14 11:43 ` [tip:perf/core] " tip-bot for Masami Hiramatsu
2012-09-05 14:31 ` [PATCH -tip 3/4] ftrace/x86-64: Allow to change RIP in handlers Masami Hiramatsu
2012-09-05 14:31 ` [PATCH -tip 4/4] [BUGFIX] kprobes/x86: Fix to support jprobes on ftrace-based kprobe Masami Hiramatsu
3 siblings, 1 reply; 10+ messages in thread
From: Masami Hiramatsu @ 2012-09-05 14:31 UTC (permalink / raw)
To: Steven Rostedt, linux-kernel
Cc: H. Peter Anvin, Peter Zijlstra, Frederic Weisbecker,
Thomas Gleixner, Ingo Molnar, Andrew Morton, yrl.pp-manager.tt,
Masami Hiramatsu, Thomas Gleixner, Ingo Molnar, H. Peter Anvin,
Steven Rostedt
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.
Signed-off-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
---
arch/x86/kernel/kprobes.c | 9 ++++++---
1 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/arch/x86/kernel/kprobes.c b/arch/x86/kernel/kprobes.c
index 47ae102..f49f60c 100644
--- a/arch/x86/kernel/kprobes.c
+++ b/arch/x86/kernel/kprobes.c
@@ -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);
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH -tip 3/4] ftrace/x86-64: Allow to change RIP in handlers
2012-09-05 14:30 [PATCH -tip 0/4][BUGFIX] Fix ftrace-based kprobes Masami Hiramatsu
2012-09-05 14:31 ` [PATCH -tip 1/4] [BUGFIX] ftrace/x86: Adjust x86 regs.ip as like as x86-64 Masami Hiramatsu
2012-09-05 14:31 ` [PATCH -tip 2/4] [BUGFIX] kprobes/x86: Fix kprobes to collectly handle IP on ftrace Masami Hiramatsu
@ 2012-09-05 14:31 ` Masami Hiramatsu
2012-09-14 11:44 ` [tip:perf/core] " tip-bot for Steven Rostedt
2012-09-05 14:31 ` [PATCH -tip 4/4] [BUGFIX] kprobes/x86: Fix to support jprobes on ftrace-based kprobe Masami Hiramatsu
3 siblings, 1 reply; 10+ messages in thread
From: Masami Hiramatsu @ 2012-09-05 14:31 UTC (permalink / raw)
To: Steven Rostedt, linux-kernel
Cc: H. Peter Anvin, Peter Zijlstra, Frederic Weisbecker,
Thomas Gleixner, Ingo Molnar, Andrew Morton, yrl.pp-manager.tt,
Steven Rostedt, Masami Hiramatsu, Thomas Gleixner, Ingo Molnar,
H. Peter Anvin
From: Steven Rostedt <rostedt@goodmis.org>
Allow ftrace handlers to change RIP register (regs->ip)
in handlers. This will allow handlers to call another
function instead of original function.
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Signed-off-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: "H. Peter Anvin" <hpa@zytor.com>
---
arch/x86/kernel/entry_64.S | 4 ++++
1 files changed, 4 insertions(+), 0 deletions(-)
diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S
index ed767b7..e9cc2b3 100644
--- a/arch/x86/kernel/entry_64.S
+++ b/arch/x86/kernel/entry_64.S
@@ -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
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH -tip 4/4] [BUGFIX] kprobes/x86: Fix to support jprobes on ftrace-based kprobe
2012-09-05 14:30 [PATCH -tip 0/4][BUGFIX] Fix ftrace-based kprobes Masami Hiramatsu
` (2 preceding siblings ...)
2012-09-05 14:31 ` [PATCH -tip 3/4] ftrace/x86-64: Allow to change RIP in handlers Masami Hiramatsu
@ 2012-09-05 14:31 ` Masami Hiramatsu
2012-09-07 8:44 ` Masami Hiramatsu
2012-09-14 11:45 ` [tip:perf/core] " tip-bot for Masami Hiramatsu
3 siblings, 2 replies; 10+ messages in thread
From: Masami Hiramatsu @ 2012-09-05 14:31 UTC (permalink / raw)
To: Steven Rostedt, linux-kernel
Cc: H. Peter Anvin, Peter Zijlstra, Frederic Weisbecker,
Thomas Gleixner, Ingo Molnar, Andrew Morton, yrl.pp-manager.tt,
Masami Hiramatsu, Thomas Gleixner, Ingo Molnar, H. Peter Anvin,
Steven Rostedt
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).
Signed-off-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
---
arch/x86/kernel/kprobes.c | 42 +++++++++++++++++++++++++++++-------------
kernel/kprobes.c | 3 ---
2 files changed, 29 insertions(+), 16 deletions(-)
diff --git a/arch/x86/kernel/kprobes.c b/arch/x86/kernel/kprobes.c
index f49f60c..b7c2a85 100644
--- a/arch/x86/kernel/kprobes.c
+++ b/arch/x86/kernel/kprobes.c
@@ -541,6 +541,8 @@ reenter_kprobe(struct kprobe *p, struct pt_regs *regs, struct kprobe_ctlblk *kcb
return 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);
diff --git a/kernel/kprobes.c b/kernel/kprobes.c
index 35b4315..098f396 100644
--- a/kernel/kprobes.c
+++ b/kernel/kprobes.c
@@ -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;
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH -tip 4/4] [BUGFIX] kprobes/x86: Fix to support jprobes on ftrace-based kprobe
2012-09-05 14:31 ` [PATCH -tip 4/4] [BUGFIX] kprobes/x86: Fix to support jprobes on ftrace-based kprobe Masami Hiramatsu
@ 2012-09-07 8:44 ` Masami Hiramatsu
2012-09-14 11:45 ` [tip:perf/core] " tip-bot for Masami Hiramatsu
1 sibling, 0 replies; 10+ messages in thread
From: Masami Hiramatsu @ 2012-09-07 8:44 UTC (permalink / raw)
To: Masami Hiramatsu, Fengguang Wu
Cc: Steven Rostedt, linux-kernel, H. Peter Anvin, Peter Zijlstra,
Frederic Weisbecker, Thomas Gleixner, Ingo Molnar, Andrew Morton,
yrl.pp-manager.tt, Ingo Molnar, H. Peter Anvin
(2012/09/05 23:31), Masami Hiramatsu wrote:
> 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).
>
> Signed-off-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
> Cc: Thomas Gleixner <tglx@linutronix.de>
> Cc: Ingo Molnar <mingo@redhat.com>
> Cc: "H. Peter Anvin" <hpa@zytor.com>
> Cc: Steven Rostedt <rostedt@goodmis.org>
This should have a below line...
Reported-by: Fengguang Wu <fengguang.wu@intel.com>
Thanks!
> ---
>
> arch/x86/kernel/kprobes.c | 42 +++++++++++++++++++++++++++++-------------
> kernel/kprobes.c | 3 ---
> 2 files changed, 29 insertions(+), 16 deletions(-)
>
> diff --git a/arch/x86/kernel/kprobes.c b/arch/x86/kernel/kprobes.c
> index f49f60c..b7c2a85 100644
> --- a/arch/x86/kernel/kprobes.c
> +++ b/arch/x86/kernel/kprobes.c
> @@ -541,6 +541,8 @@ reenter_kprobe(struct kprobe *p, struct pt_regs *regs, struct kprobe_ctlblk *kcb
> return 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);
> diff --git a/kernel/kprobes.c b/kernel/kprobes.c
> index 35b4315..098f396 100644
> --- a/kernel/kprobes.c
> +++ b/kernel/kprobes.c
> @@ -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;
>
--
Masami HIRAMATSU
Software Platform Research Dept. Linux Technology Center
Hitachi, Ltd., Yokohama Research Laboratory
E-mail: masami.hiramatsu.pt@hitachi.com
^ permalink raw reply [flat|nested] 10+ messages in thread
* [tip:perf/core] ftrace/x86: Adjust x86 regs.ip as like as x86-64
2012-09-05 14:31 ` [PATCH -tip 1/4] [BUGFIX] ftrace/x86: Adjust x86 regs.ip as like as x86-64 Masami Hiramatsu
@ 2012-09-14 11:42 ` tip-bot for Masami Hiramatsu
0 siblings, 0 replies; 10+ messages in thread
From: tip-bot for Masami Hiramatsu @ 2012-09-14 11:42 UTC (permalink / raw)
To: linux-tip-commits
Cc: linux-kernel, hpa, mingo, a.p.zijlstra, masami.hiramatsu.pt,
fweisbec, rostedt, tglx
Commit-ID: a5e37863ab31d78faddff15675c89979792bc0bd
Gitweb: http://git.kernel.org/tip/a5e37863ab31d78faddff15675c89979792bc0bd
Author: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
AuthorDate: Wed, 5 Sep 2012 23:31:00 +0900
Committer: Steven Rostedt <rostedt@goodmis.org>
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.
Link: http://lkml.kernel.org/r/20120905143100.10329.60109.stgit@localhost.localdomain
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Signed-off-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
---
arch/x86/kernel/entry_32.S | 3 +--
1 files changed, 1 insertions(+), 2 deletions(-)
diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S
index 061ac17..f438a44 100644
--- a/arch/x86/kernel/entry_32.S
+++ b/arch/x86/kernel/entry_32.S
@@ -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
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [tip:perf/core] kprobes/x86: Fix kprobes to collectly handle IP on ftrace
2012-09-05 14:31 ` [PATCH -tip 2/4] [BUGFIX] kprobes/x86: Fix kprobes to collectly handle IP on ftrace Masami Hiramatsu
@ 2012-09-14 11:43 ` tip-bot for Masami Hiramatsu
0 siblings, 0 replies; 10+ messages in thread
From: tip-bot for Masami Hiramatsu @ 2012-09-14 11:43 UTC (permalink / raw)
To: linux-tip-commits
Cc: linux-kernel, hpa, mingo, a.p.zijlstra, masami.hiramatsu.pt,
fweisbec, rostedt, tglx
Commit-ID: 4b036d54bf849a75d0103b33d92a53f89ecb9315
Gitweb: http://git.kernel.org/tip/4b036d54bf849a75d0103b33d92a53f89ecb9315
Author: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
AuthorDate: Wed, 5 Sep 2012 23:31:12 +0900
Committer: Steven Rostedt <rostedt@goodmis.org>
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.
Link: http://lkml.kernel.org/r/20120905143112.10329.72069.stgit@localhost.localdomain
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Signed-off-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
---
arch/x86/kernel/kprobes.c | 9 ++++++---
1 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/arch/x86/kernel/kprobes.c b/arch/x86/kernel/kprobes.c
index 47ae102..f49f60c 100644
--- a/arch/x86/kernel/kprobes.c
+++ b/arch/x86/kernel/kprobes.c
@@ -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);
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [tip:perf/core] ftrace/x86-64: Allow to change RIP in handlers
2012-09-05 14:31 ` [PATCH -tip 3/4] ftrace/x86-64: Allow to change RIP in handlers Masami Hiramatsu
@ 2012-09-14 11:44 ` tip-bot for Steven Rostedt
0 siblings, 0 replies; 10+ messages in thread
From: tip-bot for Steven Rostedt @ 2012-09-14 11:44 UTC (permalink / raw)
To: linux-tip-commits
Cc: linux-kernel, hpa, mingo, a.p.zijlstra, fweisbec,
masami.hiramatsu.pt, rostedt, tglx
Commit-ID: 47d5a5f88b9d25d6464c9b60c28f391e84e3ed65
Gitweb: http://git.kernel.org/tip/47d5a5f88b9d25d6464c9b60c28f391e84e3ed65
Author: Steven Rostedt <rostedt@goodmis.org>
AuthorDate: Wed, 5 Sep 2012 23:31:18 +0900
Committer: Steven Rostedt <rostedt@goodmis.org>
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.
Link: http://lkml.kernel.org/r/20120905143118.10329.5078.stgit@localhost.localdomain
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Signed-off-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
---
arch/x86/kernel/entry_64.S | 4 ++++
1 files changed, 4 insertions(+), 0 deletions(-)
diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S
index ed767b7..e9cc2b3 100644
--- a/arch/x86/kernel/entry_64.S
+++ b/arch/x86/kernel/entry_64.S
@@ -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
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [tip:perf/core] kprobes/x86: Fix to support jprobes on ftrace-based kprobe
2012-09-05 14:31 ` [PATCH -tip 4/4] [BUGFIX] kprobes/x86: Fix to support jprobes on ftrace-based kprobe Masami Hiramatsu
2012-09-07 8:44 ` Masami Hiramatsu
@ 2012-09-14 11:45 ` tip-bot for Masami Hiramatsu
1 sibling, 0 replies; 10+ messages in thread
From: tip-bot for Masami Hiramatsu @ 2012-09-14 11:45 UTC (permalink / raw)
To: linux-tip-commits
Cc: linux-kernel, hpa, mingo, a.p.zijlstra, masami.hiramatsu.pt,
fweisbec, rostedt, tglx, fengguang.wu
Commit-ID: c6aaf4d0bb86e2154ea31a33804cec300611255f
Gitweb: http://git.kernel.org/tip/c6aaf4d0bb86e2154ea31a33804cec300611255f
Author: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
AuthorDate: Wed, 5 Sep 2012 23:31:25 +0900
Committer: Steven Rostedt <rostedt@goodmis.org>
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).
Link: http://lkml.kernel.org/r/20120905143125.10329.90836.stgit@localhost.localdomain
Reported-by: Fengguang Wu <fengguang.wu@intel.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Signed-off-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
---
arch/x86/kernel/kprobes.c | 42 +++++++++++++++++++++++++++++-------------
kernel/kprobes.c | 3 ---
2 files changed, 29 insertions(+), 16 deletions(-)
diff --git a/arch/x86/kernel/kprobes.c b/arch/x86/kernel/kprobes.c
index f49f60c..b7c2a85 100644
--- a/arch/x86/kernel/kprobes.c
+++ b/arch/x86/kernel/kprobes.c
@@ -541,6 +541,8 @@ reenter_kprobe(struct kprobe *p, struct pt_regs *regs, struct kprobe_ctlblk *kcb
return 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);
diff --git a/kernel/kprobes.c b/kernel/kprobes.c
index 35b4315..098f396 100644
--- a/kernel/kprobes.c
+++ b/kernel/kprobes.c
@@ -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;
^ permalink raw reply related [flat|nested] 10+ messages in thread
end of thread, other threads:[~2012-09-14 11:45 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-09-05 14:30 [PATCH -tip 0/4][BUGFIX] Fix ftrace-based kprobes Masami Hiramatsu
2012-09-05 14:31 ` [PATCH -tip 1/4] [BUGFIX] ftrace/x86: Adjust x86 regs.ip as like as x86-64 Masami Hiramatsu
2012-09-14 11:42 ` [tip:perf/core] " tip-bot for Masami Hiramatsu
2012-09-05 14:31 ` [PATCH -tip 2/4] [BUGFIX] kprobes/x86: Fix kprobes to collectly handle IP on ftrace Masami Hiramatsu
2012-09-14 11:43 ` [tip:perf/core] " tip-bot for Masami Hiramatsu
2012-09-05 14:31 ` [PATCH -tip 3/4] ftrace/x86-64: Allow to change RIP in handlers Masami Hiramatsu
2012-09-14 11:44 ` [tip:perf/core] " tip-bot for Steven Rostedt
2012-09-05 14:31 ` [PATCH -tip 4/4] [BUGFIX] kprobes/x86: Fix to support jprobes on ftrace-based kprobe Masami Hiramatsu
2012-09-07 8:44 ` Masami Hiramatsu
2012-09-14 11:45 ` [tip:perf/core] " tip-bot for Masami Hiramatsu
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).