kprobes: makes kprobes/enabled works correctly for optimized kprobes.
authorWang Nan <wangnan0@huawei.com>
Fri, 13 Feb 2015 22:40:26 +0000 (14:40 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sat, 14 Feb 2015 05:21:42 +0000 (21:21 -0800)
debugfs/kprobes/enabled doesn't work correctly on optimized kprobes.
Masami Hiramatsu has a test report on x86_64 platform:

https://lkml.org/lkml/2015/1/19/274

This patch forces it to unoptimize kprobe if kprobes_all_disarmed is set.
It also checks the flag in unregistering path for skipping unneeded
disarming process when kprobes globally disarmed.

Signed-off-by: Wang Nan <wangnan0@huawei.com>
Signed-off-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Cc: Ingo Molnar <mingo@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
kernel/kprobes.c

index c39790001854aed18332f9a14b80357d2e9cde2f..c90e417bb9636300e4f4fe87d2c995a6c2cdab12 100644 (file)
@@ -869,7 +869,8 @@ static void __disarm_kprobe(struct kprobe *p, bool reopt)
 {
        struct kprobe *_p;
 
-       unoptimize_kprobe(p, false);    /* Try to unoptimize */
+       /* Try to unoptimize */
+       unoptimize_kprobe(p, kprobes_all_disarmed);
 
        if (!kprobe_queued(p)) {
                arch_disarm_kprobe(p);
@@ -1571,7 +1572,13 @@ static struct kprobe *__disable_kprobe(struct kprobe *p)
 
                /* Try to disarm and disable this/parent probe */
                if (p == orig_p || aggr_kprobe_disabled(orig_p)) {
-                       disarm_kprobe(orig_p, true);
+                       /*
+                        * If kprobes_all_disarmed is set, orig_p
+                        * should have already been disarmed, so
+                        * skip unneed disarming process.
+                        */
+                       if (!kprobes_all_disarmed)
+                               disarm_kprobe(orig_p, true);
                        orig_p->flags |= KPROBE_FLAG_DISABLED;
                }
        }