* [PATCH] kprobes/x86: Fix the return address of multiple kretprobes
@ 2010-08-15 6:18 KUMANO Syuhei
2010-08-17 15:10 ` Masami Hiramatsu
2010-08-19 11:24 ` [tip:perf/urgent] " tip-bot for KUMANO Syuhei
0 siblings, 2 replies; 3+ messages in thread
From: KUMANO Syuhei @ 2010-08-15 6:18 UTC (permalink / raw)
To: linux-kernel
Cc: Thomas Gleixner, Ingo Molnar, H. Peter Anvin, x86,
Frederic Weisbecker, Ananth N Mavinakayanahalli, Peter Zijlstra,
YOSHIFUJI Hideaki, Masami Hiramatsu
Fix the return address of subsequent kretprobes when multiple
kretprobes are set on the same function.
For example:
# cd /sys/kernel/debug/tracing
# echo "r:event1 sys_symlink" > kprobe_events
# echo "r:event2 sys_symlink" >> kprobe_events
# echo 1 > events/kprobes/enable
# ln -s /tmp/foo /tmp/bar
(without this patch)
# cat trace
ln-897 [000] 20404.133727: event1: (kretprobe_trampoline+0x0/0x4c <- sys_symlink)
ln-897 [000] 20404.133747: event2: (system_call_fastpath+0x16/0x1b <- sys_symlink)
(with this patch)
# cat trace
ln-740 [000] 13799.491076: event1: (system_call_fastpath+0x16/0x1b <- sys_symlink)
ln-740 [000] 13799.491096: event2: (system_call_fastpath+0x16/0x1b <- sys_symlink)
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: x86@kernel.org
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: linux-kernel@vger.kernel.org
Cc: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
Reviewed-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Signed-off-by: KUMANO Syuhei <kumano.prog@gmail.com>
---
arch/x86/kernel/kprobes.c | 25 ++++++++++++++++++++++---
1 files changed, 22 insertions(+), 3 deletions(-)
diff --git a/arch/x86/kernel/kprobes.c b/arch/x86/kernel/kprobes.c
index 675879b..5220e14 100644
--- a/arch/x86/kernel/kprobes.c
+++ b/arch/x86/kernel/kprobes.c
@@ -707,6 +707,7 @@ static __used __kprobes void *trampoline_handler(struct pt_regs *regs)
struct hlist_node *node, *tmp;
unsigned long flags, orig_ret_address = 0;
unsigned long trampoline_address = (unsigned long)&kretprobe_trampoline;
+ kprobe_opcode_t *correct_ret_addr = NULL;
INIT_HLIST_HEAD(&empty_rp);
kretprobe_hash_lock(current, &head, &flags);
@@ -738,14 +739,34 @@ static __used __kprobes void *trampoline_handler(struct pt_regs *regs)
/* another task is sharing our hash bucket */
continue;
+ orig_ret_address = (unsigned long)ri->ret_addr;
+
+ if (orig_ret_address != trampoline_address)
+ /*
+ * This is the real return address. Any other
+ * instances associated with this task are for
+ * other calls deeper on the call stack
+ */
+ break;
+ }
+
+ kretprobe_assert(ri, orig_ret_address, trampoline_address);
+
+ correct_ret_addr = ri->ret_addr;
+ hlist_for_each_entry_safe(ri, node, tmp, head, hlist) {
+ if (ri->task != current)
+ /* another task is sharing our hash bucket */
+ continue;
+
+ orig_ret_address = (unsigned long)ri->ret_addr;
if (ri->rp && ri->rp->handler) {
__get_cpu_var(current_kprobe) = &ri->rp->kp;
get_kprobe_ctlblk()->kprobe_status = KPROBE_HIT_ACTIVE;
+ ri->ret_addr = correct_ret_addr;
ri->rp->handler(ri, regs);
__get_cpu_var(current_kprobe) = NULL;
}
- orig_ret_address = (unsigned long)ri->ret_addr;
recycle_rp_inst(ri, &empty_rp);
if (orig_ret_address != trampoline_address)
@@ -757,8 +778,6 @@ static __used __kprobes void *trampoline_handler(struct pt_regs *regs)
break;
}
- kretprobe_assert(ri, orig_ret_address, trampoline_address);
-
kretprobe_hash_unlock(current, &flags);
hlist_for_each_entry_safe(ri, node, tmp, &empty_rp, hlist) {
--
1.7.0.4
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH] kprobes/x86: Fix the return address of multiple kretprobes
2010-08-15 6:18 [PATCH] kprobes/x86: Fix the return address of multiple kretprobes KUMANO Syuhei
@ 2010-08-17 15:10 ` Masami Hiramatsu
2010-08-19 11:24 ` [tip:perf/urgent] " tip-bot for KUMANO Syuhei
1 sibling, 0 replies; 3+ messages in thread
From: Masami Hiramatsu @ 2010-08-17 15:10 UTC (permalink / raw)
To: KUMANO Syuhei, Ingo Molnar
Cc: linux-kernel, Thomas Gleixner, H. Peter Anvin, x86,
Frederic Weisbecker, Ananth N Mavinakayanahalli, Peter Zijlstra,
YOSHIFUJI Hideaki, 2nddept-manager
KUMANO Syuhei wrote:
> Fix the return address of subsequent kretprobes when multiple
> kretprobes are set on the same function.
>
> For example:
> # cd /sys/kernel/debug/tracing
> # echo "r:event1 sys_symlink" > kprobe_events
> # echo "r:event2 sys_symlink" >> kprobe_events
> # echo 1 > events/kprobes/enable
> # ln -s /tmp/foo /tmp/bar
> (without this patch)
> # cat trace
> ln-897 [000] 20404.133727: event1: (kretprobe_trampoline+0x0/0x4c <- sys_symlink)
> ln-897 [000] 20404.133747: event2: (system_call_fastpath+0x16/0x1b <- sys_symlink)
> (with this patch)
> # cat trace
> ln-740 [000] 13799.491076: event1: (system_call_fastpath+0x16/0x1b <- sys_symlink)
> ln-740 [000] 13799.491096: event2: (system_call_fastpath+0x16/0x1b <- sys_symlink)
>
Yeah, I'm OK for this fix.
Acked-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Ingo, could you pull this on your x86/bugfix tree?
Thank you,
> Cc: Thomas Gleixner <tglx@linutronix.de>
> Cc: Ingo Molnar <mingo@redhat.com>
> Cc: "H. Peter Anvin" <hpa@zytor.com>
> Cc: x86@kernel.org
> Cc: Frederic Weisbecker <fweisbec@gmail.com>
> Cc: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
> Cc: linux-kernel@vger.kernel.org
> Cc: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
> Reviewed-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
> Signed-off-by: KUMANO Syuhei <kumano.prog@gmail.com>
> ---
> arch/x86/kernel/kprobes.c | 25 ++++++++++++++++++++++---
> 1 files changed, 22 insertions(+), 3 deletions(-)
>
> diff --git a/arch/x86/kernel/kprobes.c b/arch/x86/kernel/kprobes.c
> index 675879b..5220e14 100644
> --- a/arch/x86/kernel/kprobes.c
> +++ b/arch/x86/kernel/kprobes.c
> @@ -707,6 +707,7 @@ static __used __kprobes void *trampoline_handler(struct pt_regs *regs)
> struct hlist_node *node, *tmp;
> unsigned long flags, orig_ret_address = 0;
> unsigned long trampoline_address = (unsigned long)&kretprobe_trampoline;
> + kprobe_opcode_t *correct_ret_addr = NULL;
>
> INIT_HLIST_HEAD(&empty_rp);
> kretprobe_hash_lock(current, &head, &flags);
> @@ -738,14 +739,34 @@ static __used __kprobes void *trampoline_handler(struct pt_regs *regs)
> /* another task is sharing our hash bucket */
> continue;
>
> + orig_ret_address = (unsigned long)ri->ret_addr;
> +
> + if (orig_ret_address != trampoline_address)
> + /*
> + * This is the real return address. Any other
> + * instances associated with this task are for
> + * other calls deeper on the call stack
> + */
> + break;
> + }
> +
> + kretprobe_assert(ri, orig_ret_address, trampoline_address);
> +
> + correct_ret_addr = ri->ret_addr;
> + hlist_for_each_entry_safe(ri, node, tmp, head, hlist) {
> + if (ri->task != current)
> + /* another task is sharing our hash bucket */
> + continue;
> +
> + orig_ret_address = (unsigned long)ri->ret_addr;
> if (ri->rp && ri->rp->handler) {
> __get_cpu_var(current_kprobe) = &ri->rp->kp;
> get_kprobe_ctlblk()->kprobe_status = KPROBE_HIT_ACTIVE;
> + ri->ret_addr = correct_ret_addr;
> ri->rp->handler(ri, regs);
> __get_cpu_var(current_kprobe) = NULL;
> }
>
> - orig_ret_address = (unsigned long)ri->ret_addr;
> recycle_rp_inst(ri, &empty_rp);
>
> if (orig_ret_address != trampoline_address)
> @@ -757,8 +778,6 @@ static __used __kprobes void *trampoline_handler(struct pt_regs *regs)
> break;
> }
>
> - kretprobe_assert(ri, orig_ret_address, trampoline_address);
> -
> kretprobe_hash_unlock(current, &flags);
>
> hlist_for_each_entry_safe(ri, node, tmp, &empty_rp, hlist) {
^ permalink raw reply [flat|nested] 3+ messages in thread
* [tip:perf/urgent] kprobes/x86: Fix the return address of multiple kretprobes
2010-08-15 6:18 [PATCH] kprobes/x86: Fix the return address of multiple kretprobes KUMANO Syuhei
2010-08-17 15:10 ` Masami Hiramatsu
@ 2010-08-19 11:24 ` tip-bot for KUMANO Syuhei
1 sibling, 0 replies; 3+ messages in thread
From: tip-bot for KUMANO Syuhei @ 2010-08-19 11:24 UTC (permalink / raw)
To: linux-tip-commits
Cc: linux-kernel, hpa, mingo, a.p.zijlstra, yoshfuji, ananth,
masami.hiramatsu.pt, fweisbec, tglx, kumano.prog, mingo
Commit-ID: 737480a0d525dae13306296da08029dff545bc72
Gitweb: http://git.kernel.org/tip/737480a0d525dae13306296da08029dff545bc72
Author: KUMANO Syuhei <kumano.prog@gmail.com>
AuthorDate: Sun, 15 Aug 2010 15:18:04 +0900
Committer: Ingo Molnar <mingo@elte.hu>
CommitDate: Thu, 19 Aug 2010 12:49:56 +0200
kprobes/x86: Fix the return address of multiple kretprobes
Fix the return address of subsequent kretprobes when multiple
kretprobes are set on the same function.
For example:
# cd /sys/kernel/debug/tracing
# echo "r:event1 sys_symlink" > kprobe_events
# echo "r:event2 sys_symlink" >> kprobe_events
# echo 1 > events/kprobes/enable
# ln -s /tmp/foo /tmp/bar
(without this patch)
# cat trace
ln-897 [000] 20404.133727: event1: (kretprobe_trampoline+0x0/0x4c <- sys_symlink)
ln-897 [000] 20404.133747: event2: (system_call_fastpath+0x16/0x1b <- sys_symlink)
(with this patch)
# cat trace
ln-740 [000] 13799.491076: event1: (system_call_fastpath+0x16/0x1b <- sys_symlink)
ln-740 [000] 13799.491096: event2: (system_call_fastpath+0x16/0x1b <- sys_symlink)
Signed-off-by: KUMANO Syuhei <kumano.prog@gmail.com>
Reviewed-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
LKML-Reference: <1281853084.3254.11.camel@camp10-laptop>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
---
arch/x86/kernel/kprobes.c | 25 ++++++++++++++++++++++---
1 files changed, 22 insertions(+), 3 deletions(-)
diff --git a/arch/x86/kernel/kprobes.c b/arch/x86/kernel/kprobes.c
index 1bfb6cf..770ebfb 100644
--- a/arch/x86/kernel/kprobes.c
+++ b/arch/x86/kernel/kprobes.c
@@ -709,6 +709,7 @@ static __used __kprobes void *trampoline_handler(struct pt_regs *regs)
struct hlist_node *node, *tmp;
unsigned long flags, orig_ret_address = 0;
unsigned long trampoline_address = (unsigned long)&kretprobe_trampoline;
+ kprobe_opcode_t *correct_ret_addr = NULL;
INIT_HLIST_HEAD(&empty_rp);
kretprobe_hash_lock(current, &head, &flags);
@@ -740,14 +741,34 @@ static __used __kprobes void *trampoline_handler(struct pt_regs *regs)
/* another task is sharing our hash bucket */
continue;
+ orig_ret_address = (unsigned long)ri->ret_addr;
+
+ if (orig_ret_address != trampoline_address)
+ /*
+ * This is the real return address. Any other
+ * instances associated with this task are for
+ * other calls deeper on the call stack
+ */
+ break;
+ }
+
+ kretprobe_assert(ri, orig_ret_address, trampoline_address);
+
+ correct_ret_addr = ri->ret_addr;
+ hlist_for_each_entry_safe(ri, node, tmp, head, hlist) {
+ if (ri->task != current)
+ /* another task is sharing our hash bucket */
+ continue;
+
+ orig_ret_address = (unsigned long)ri->ret_addr;
if (ri->rp && ri->rp->handler) {
__get_cpu_var(current_kprobe) = &ri->rp->kp;
get_kprobe_ctlblk()->kprobe_status = KPROBE_HIT_ACTIVE;
+ ri->ret_addr = correct_ret_addr;
ri->rp->handler(ri, regs);
__get_cpu_var(current_kprobe) = NULL;
}
- orig_ret_address = (unsigned long)ri->ret_addr;
recycle_rp_inst(ri, &empty_rp);
if (orig_ret_address != trampoline_address)
@@ -759,8 +780,6 @@ static __used __kprobes void *trampoline_handler(struct pt_regs *regs)
break;
}
- kretprobe_assert(ri, orig_ret_address, trampoline_address);
-
kretprobe_hash_unlock(current, &flags);
hlist_for_each_entry_safe(ri, node, tmp, &empty_rp, hlist) {
^ permalink raw reply related [flat|nested] 3+ messages in thread
end of thread, other threads:[~2010-08-19 11:25 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-08-15 6:18 [PATCH] kprobes/x86: Fix the return address of multiple kretprobes KUMANO Syuhei
2010-08-17 15:10 ` Masami Hiramatsu
2010-08-19 11:24 ` [tip:perf/urgent] " tip-bot for KUMANO Syuhei
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.