[tip:perf/urgent] kprobes: Propagate error from disarm_kprobe_ftrace()

2018-02-16 Thread tip-bot for Jessica Yu
Commit-ID:  297f9233b53a08fd457815e19f1d6f2c3389857b
Gitweb: https://git.kernel.org/tip/297f9233b53a08fd457815e19f1d6f2c3389857b
Author: Jessica Yu 
AuthorDate: Wed, 10 Jan 2018 00:51:24 +0100
Committer:  Ingo Molnar 
CommitDate: Fri, 16 Feb 2018 09:12:58 +0100

kprobes: Propagate error from disarm_kprobe_ftrace()

Improve error handling when disarming ftrace-based kprobes. Like with
arm_kprobe_ftrace(), propagate any errors from disarm_kprobe_ftrace() so
that we do not disable/unregister kprobes that are still armed. In other
words, unregister_kprobe() and disable_kprobe() should not report success
if the kprobe could not be disarmed.

disarm_all_kprobes() keeps its current behavior and attempts to
disarm all kprobes. It returns the last encountered error and gives a
warning if not all probes could be disarmed.

This patch is based on Petr Mladek's original patchset (patches 2 and 3)
back in 2015, which improved kprobes error handling, found here:

   https://lkml.org/lkml/2015/2/26/452

However, further work on this had been paused since then and the patches
were not upstreamed.

Based-on-patches-by: Petr Mladek 
Signed-off-by: Jessica Yu 
Acked-by: Masami Hiramatsu 
Cc: Ananth N Mavinakayanahalli 
Cc: Anil S Keshavamurthy 
Cc: David S . Miller 
Cc: Jiri Kosina 
Cc: Joe Lawrence 
Cc: Josh Poimboeuf 
Cc: Linus Torvalds 
Cc: Miroslav Benes 
Cc: Peter Zijlstra 
Cc: Petr Mladek 
Cc: Steven Rostedt 
Cc: Thomas Gleixner 
Cc: live-patch...@vger.kernel.org
Link: http://lkml.kernel.org/r/20180109235124.30886-3-j...@kernel.org
Signed-off-by: Ingo Molnar 
---
 kernel/kprobes.c | 78 ++--
 1 file changed, 53 insertions(+), 25 deletions(-)

diff --git a/kernel/kprobes.c b/kernel/kprobes.c
index 2d98814..102160f 100644
--- a/kernel/kprobes.c
+++ b/kernel/kprobes.c
@@ -1011,23 +1011,27 @@ err_ftrace:
 }
 
 /* Caller must lock kprobe_mutex */
-static void disarm_kprobe_ftrace(struct kprobe *p)
+static int disarm_kprobe_ftrace(struct kprobe *p)
 {
-   int ret;
+   int ret = 0;
 
-   kprobe_ftrace_enabled--;
-   if (kprobe_ftrace_enabled == 0) {
+   if (kprobe_ftrace_enabled == 1) {
ret = unregister_ftrace_function(_ftrace_ops);
-   WARN(ret < 0, "Failed to init kprobe-ftrace (%d)\n", ret);
+   if (WARN(ret < 0, "Failed to unregister kprobe-ftrace (%d)\n", 
ret))
+   return ret;
}
+
+   kprobe_ftrace_enabled--;
+
ret = ftrace_set_filter_ip(_ftrace_ops,
   (unsigned long)p->addr, 1, 0);
WARN(ret < 0, "Failed to disarm kprobe-ftrace at %p (%d)\n", p->addr, 
ret);
+   return ret;
 }
 #else  /* !CONFIG_KPROBES_ON_FTRACE */
 #define prepare_kprobe(p)  arch_prepare_kprobe(p)
 #define arm_kprobe_ftrace(p)   (-ENODEV)
-#define disarm_kprobe_ftrace(p)do {} while (0)
+#define disarm_kprobe_ftrace(p)(-ENODEV)
 #endif
 
 /* Arm a kprobe with text_mutex */
@@ -1046,18 +1050,18 @@ static int arm_kprobe(struct kprobe *kp)
 }
 
 /* Disarm a kprobe with text_mutex */
-static void disarm_kprobe(struct kprobe *kp, bool reopt)
+static int disarm_kprobe(struct kprobe *kp, bool reopt)
 {
-   if (unlikely(kprobe_ftrace(kp))) {
-   disarm_kprobe_ftrace(kp);
-   return;
-   }
+   if (unlikely(kprobe_ftrace(kp)))
+   return disarm_kprobe_ftrace(kp);
 
cpus_read_lock();
mutex_lock(_mutex);
__disarm_kprobe(kp, reopt);
mutex_unlock(_mutex);
cpus_read_unlock();
+
+   return 0;
 }
 
 /*
@@ -1639,11 +1643,12 @@ static int aggr_kprobe_disabled(struct kprobe *ap)
 static struct kprobe *__disable_kprobe(struct kprobe *p)
 {
struct kprobe *orig_p;
+   int ret;
 
/* Get an original kprobe for return */
orig_p = __get_valid_kprobe(p);
if (unlikely(orig_p == NULL))
-   return NULL;
+   return ERR_PTR(-EINVAL);
 
if (!kprobe_disabled(p)) {
/* Disable probe if it is a child probe */
@@ -1657,8 +1662,13 @@ static struct kprobe *__disable_kprobe(struct kprobe *p)
 * should have already been disarmed, so
 * skip unneed disarming process.
 */
-   if (!kprobes_all_disarmed)
-   disarm_kprobe(orig_p, true);
+   if (!kprobes_all_disarmed) {
+   ret = disarm_kprobe(orig_p, true);
+   if (ret) {
+ 

[tip:perf/urgent] kprobes: Propagate error from disarm_kprobe_ftrace()

2018-02-16 Thread tip-bot for Jessica Yu
Commit-ID:  297f9233b53a08fd457815e19f1d6f2c3389857b
Gitweb: https://git.kernel.org/tip/297f9233b53a08fd457815e19f1d6f2c3389857b
Author: Jessica Yu 
AuthorDate: Wed, 10 Jan 2018 00:51:24 +0100
Committer:  Ingo Molnar 
CommitDate: Fri, 16 Feb 2018 09:12:58 +0100

kprobes: Propagate error from disarm_kprobe_ftrace()

Improve error handling when disarming ftrace-based kprobes. Like with
arm_kprobe_ftrace(), propagate any errors from disarm_kprobe_ftrace() so
that we do not disable/unregister kprobes that are still armed. In other
words, unregister_kprobe() and disable_kprobe() should not report success
if the kprobe could not be disarmed.

disarm_all_kprobes() keeps its current behavior and attempts to
disarm all kprobes. It returns the last encountered error and gives a
warning if not all probes could be disarmed.

This patch is based on Petr Mladek's original patchset (patches 2 and 3)
back in 2015, which improved kprobes error handling, found here:

   https://lkml.org/lkml/2015/2/26/452

However, further work on this had been paused since then and the patches
were not upstreamed.

Based-on-patches-by: Petr Mladek 
Signed-off-by: Jessica Yu 
Acked-by: Masami Hiramatsu 
Cc: Ananth N Mavinakayanahalli 
Cc: Anil S Keshavamurthy 
Cc: David S . Miller 
Cc: Jiri Kosina 
Cc: Joe Lawrence 
Cc: Josh Poimboeuf 
Cc: Linus Torvalds 
Cc: Miroslav Benes 
Cc: Peter Zijlstra 
Cc: Petr Mladek 
Cc: Steven Rostedt 
Cc: Thomas Gleixner 
Cc: live-patch...@vger.kernel.org
Link: http://lkml.kernel.org/r/20180109235124.30886-3-j...@kernel.org
Signed-off-by: Ingo Molnar 
---
 kernel/kprobes.c | 78 ++--
 1 file changed, 53 insertions(+), 25 deletions(-)

diff --git a/kernel/kprobes.c b/kernel/kprobes.c
index 2d98814..102160f 100644
--- a/kernel/kprobes.c
+++ b/kernel/kprobes.c
@@ -1011,23 +1011,27 @@ err_ftrace:
 }
 
 /* Caller must lock kprobe_mutex */
-static void disarm_kprobe_ftrace(struct kprobe *p)
+static int disarm_kprobe_ftrace(struct kprobe *p)
 {
-   int ret;
+   int ret = 0;
 
-   kprobe_ftrace_enabled--;
-   if (kprobe_ftrace_enabled == 0) {
+   if (kprobe_ftrace_enabled == 1) {
ret = unregister_ftrace_function(_ftrace_ops);
-   WARN(ret < 0, "Failed to init kprobe-ftrace (%d)\n", ret);
+   if (WARN(ret < 0, "Failed to unregister kprobe-ftrace (%d)\n", 
ret))
+   return ret;
}
+
+   kprobe_ftrace_enabled--;
+
ret = ftrace_set_filter_ip(_ftrace_ops,
   (unsigned long)p->addr, 1, 0);
WARN(ret < 0, "Failed to disarm kprobe-ftrace at %p (%d)\n", p->addr, 
ret);
+   return ret;
 }
 #else  /* !CONFIG_KPROBES_ON_FTRACE */
 #define prepare_kprobe(p)  arch_prepare_kprobe(p)
 #define arm_kprobe_ftrace(p)   (-ENODEV)
-#define disarm_kprobe_ftrace(p)do {} while (0)
+#define disarm_kprobe_ftrace(p)(-ENODEV)
 #endif
 
 /* Arm a kprobe with text_mutex */
@@ -1046,18 +1050,18 @@ static int arm_kprobe(struct kprobe *kp)
 }
 
 /* Disarm a kprobe with text_mutex */
-static void disarm_kprobe(struct kprobe *kp, bool reopt)
+static int disarm_kprobe(struct kprobe *kp, bool reopt)
 {
-   if (unlikely(kprobe_ftrace(kp))) {
-   disarm_kprobe_ftrace(kp);
-   return;
-   }
+   if (unlikely(kprobe_ftrace(kp)))
+   return disarm_kprobe_ftrace(kp);
 
cpus_read_lock();
mutex_lock(_mutex);
__disarm_kprobe(kp, reopt);
mutex_unlock(_mutex);
cpus_read_unlock();
+
+   return 0;
 }
 
 /*
@@ -1639,11 +1643,12 @@ static int aggr_kprobe_disabled(struct kprobe *ap)
 static struct kprobe *__disable_kprobe(struct kprobe *p)
 {
struct kprobe *orig_p;
+   int ret;
 
/* Get an original kprobe for return */
orig_p = __get_valid_kprobe(p);
if (unlikely(orig_p == NULL))
-   return NULL;
+   return ERR_PTR(-EINVAL);
 
if (!kprobe_disabled(p)) {
/* Disable probe if it is a child probe */
@@ -1657,8 +1662,13 @@ static struct kprobe *__disable_kprobe(struct kprobe *p)
 * should have already been disarmed, so
 * skip unneed disarming process.
 */
-   if (!kprobes_all_disarmed)
-   disarm_kprobe(orig_p, true);
+   if (!kprobes_all_disarmed) {
+   ret = disarm_kprobe(orig_p, true);
+   if (ret) {
+   p->flags &= ~KPROBE_FLAG_DISABLED;
+   return ERR_PTR(ret);
+   }
+   }
orig_p->flags |= KPROBE_FLAG_DISABLED;
}
}
@@ -1675,8 +1685,8 @@ static int __unregister_kprobe_top(struct kprobe *p)
 
/* Disable kprobe. This will 

[tip:perf/urgent] kprobes: Propagate error from disarm_kprobe_ftrace()

2018-02-13 Thread tip-bot for Jessica Yu
Commit-ID:  cea1e51c8357feb0e98464a82e1ad3ca2d0382a6
Gitweb: https://git.kernel.org/tip/cea1e51c8357feb0e98464a82e1ad3ca2d0382a6
Author: Jessica Yu 
AuthorDate: Wed, 10 Jan 2018 00:51:24 +0100
Committer:  Ingo Molnar 
CommitDate: Tue, 13 Feb 2018 18:20:00 +0100

kprobes: Propagate error from disarm_kprobe_ftrace()

Improve error handling when disarming ftrace-based kprobes. Like with
arm_kprobe_ftrace(), propagate any errors from disarm_kprobe_ftrace() so
that we do not disable/unregister kprobes that are still armed. In other
words, unregister_kprobe() and disable_kprobe() should not report success
if the kprobe could not be disarmed.

disarm_all_kprobes() keeps its current behavior and attempts to
disarm all kprobes. It returns the last encountered error and gives a
warning if not all probes could be disarmed.

This patch is based on Petr Mladek's original patchset (patches 2 and 3)
back in 2015, which improved kprobes error handling, found here:

   https://lkml.org/lkml/2015/2/26/452

However, further work on this had been paused since then and the patches
were not upstreamed.

Based-on-patches-by: Petr Mladek 
Signed-off-by: Jessica Yu 
Acked-by: Masami Hiramatsu 
Cc: Ananth N Mavinakayanahalli 
Cc: Anil S Keshavamurthy 
Cc: David S . Miller 
Cc: Jiri Kosina 
Cc: Joe Lawrence 
Cc: Josh Poimboeuf 
Cc: Linus Torvalds 
Cc: Miroslav Benes 
Cc: Peter Zijlstra 
Cc: Petr Mladek 
Cc: Steven Rostedt 
Cc: Thomas Gleixner 
Cc: live-patch...@vger.kernel.org
Link: http://lkml.kernel.org/r/20180109235124.30886-3-j...@kernel.org
Signed-off-by: Ingo Molnar 
---
 kernel/kprobes.c | 78 ++--
 1 file changed, 53 insertions(+), 25 deletions(-)

diff --git a/kernel/kprobes.c b/kernel/kprobes.c
index 2d98814..102160f 100644
--- a/kernel/kprobes.c
+++ b/kernel/kprobes.c
@@ -1011,23 +1011,27 @@ err_ftrace:
 }
 
 /* Caller must lock kprobe_mutex */
-static void disarm_kprobe_ftrace(struct kprobe *p)
+static int disarm_kprobe_ftrace(struct kprobe *p)
 {
-   int ret;
+   int ret = 0;
 
-   kprobe_ftrace_enabled--;
-   if (kprobe_ftrace_enabled == 0) {
+   if (kprobe_ftrace_enabled == 1) {
ret = unregister_ftrace_function(_ftrace_ops);
-   WARN(ret < 0, "Failed to init kprobe-ftrace (%d)\n", ret);
+   if (WARN(ret < 0, "Failed to unregister kprobe-ftrace (%d)\n", 
ret))
+   return ret;
}
+
+   kprobe_ftrace_enabled--;
+
ret = ftrace_set_filter_ip(_ftrace_ops,
   (unsigned long)p->addr, 1, 0);
WARN(ret < 0, "Failed to disarm kprobe-ftrace at %p (%d)\n", p->addr, 
ret);
+   return ret;
 }
 #else  /* !CONFIG_KPROBES_ON_FTRACE */
 #define prepare_kprobe(p)  arch_prepare_kprobe(p)
 #define arm_kprobe_ftrace(p)   (-ENODEV)
-#define disarm_kprobe_ftrace(p)do {} while (0)
+#define disarm_kprobe_ftrace(p)(-ENODEV)
 #endif
 
 /* Arm a kprobe with text_mutex */
@@ -1046,18 +1050,18 @@ static int arm_kprobe(struct kprobe *kp)
 }
 
 /* Disarm a kprobe with text_mutex */
-static void disarm_kprobe(struct kprobe *kp, bool reopt)
+static int disarm_kprobe(struct kprobe *kp, bool reopt)
 {
-   if (unlikely(kprobe_ftrace(kp))) {
-   disarm_kprobe_ftrace(kp);
-   return;
-   }
+   if (unlikely(kprobe_ftrace(kp)))
+   return disarm_kprobe_ftrace(kp);
 
cpus_read_lock();
mutex_lock(_mutex);
__disarm_kprobe(kp, reopt);
mutex_unlock(_mutex);
cpus_read_unlock();
+
+   return 0;
 }
 
 /*
@@ -1639,11 +1643,12 @@ static int aggr_kprobe_disabled(struct kprobe *ap)
 static struct kprobe *__disable_kprobe(struct kprobe *p)
 {
struct kprobe *orig_p;
+   int ret;
 
/* Get an original kprobe for return */
orig_p = __get_valid_kprobe(p);
if (unlikely(orig_p == NULL))
-   return NULL;
+   return ERR_PTR(-EINVAL);
 
if (!kprobe_disabled(p)) {
/* Disable probe if it is a child probe */
@@ -1657,8 +1662,13 @@ static struct kprobe *__disable_kprobe(struct kprobe *p)
 * should have already been disarmed, so
 * skip unneed disarming process.
 */
-   if (!kprobes_all_disarmed)
-   disarm_kprobe(orig_p, true);
+   if (!kprobes_all_disarmed) {
+   ret = disarm_kprobe(orig_p, true);
+   if (ret) {
+ 

[tip:perf/urgent] kprobes: Propagate error from disarm_kprobe_ftrace()

2018-02-13 Thread tip-bot for Jessica Yu
Commit-ID:  cea1e51c8357feb0e98464a82e1ad3ca2d0382a6
Gitweb: https://git.kernel.org/tip/cea1e51c8357feb0e98464a82e1ad3ca2d0382a6
Author: Jessica Yu 
AuthorDate: Wed, 10 Jan 2018 00:51:24 +0100
Committer:  Ingo Molnar 
CommitDate: Tue, 13 Feb 2018 18:20:00 +0100

kprobes: Propagate error from disarm_kprobe_ftrace()

Improve error handling when disarming ftrace-based kprobes. Like with
arm_kprobe_ftrace(), propagate any errors from disarm_kprobe_ftrace() so
that we do not disable/unregister kprobes that are still armed. In other
words, unregister_kprobe() and disable_kprobe() should not report success
if the kprobe could not be disarmed.

disarm_all_kprobes() keeps its current behavior and attempts to
disarm all kprobes. It returns the last encountered error and gives a
warning if not all probes could be disarmed.

This patch is based on Petr Mladek's original patchset (patches 2 and 3)
back in 2015, which improved kprobes error handling, found here:

   https://lkml.org/lkml/2015/2/26/452

However, further work on this had been paused since then and the patches
were not upstreamed.

Based-on-patches-by: Petr Mladek 
Signed-off-by: Jessica Yu 
Acked-by: Masami Hiramatsu 
Cc: Ananth N Mavinakayanahalli 
Cc: Anil S Keshavamurthy 
Cc: David S . Miller 
Cc: Jiri Kosina 
Cc: Joe Lawrence 
Cc: Josh Poimboeuf 
Cc: Linus Torvalds 
Cc: Miroslav Benes 
Cc: Peter Zijlstra 
Cc: Petr Mladek 
Cc: Steven Rostedt 
Cc: Thomas Gleixner 
Cc: live-patch...@vger.kernel.org
Link: http://lkml.kernel.org/r/20180109235124.30886-3-j...@kernel.org
Signed-off-by: Ingo Molnar 
---
 kernel/kprobes.c | 78 ++--
 1 file changed, 53 insertions(+), 25 deletions(-)

diff --git a/kernel/kprobes.c b/kernel/kprobes.c
index 2d98814..102160f 100644
--- a/kernel/kprobes.c
+++ b/kernel/kprobes.c
@@ -1011,23 +1011,27 @@ err_ftrace:
 }
 
 /* Caller must lock kprobe_mutex */
-static void disarm_kprobe_ftrace(struct kprobe *p)
+static int disarm_kprobe_ftrace(struct kprobe *p)
 {
-   int ret;
+   int ret = 0;
 
-   kprobe_ftrace_enabled--;
-   if (kprobe_ftrace_enabled == 0) {
+   if (kprobe_ftrace_enabled == 1) {
ret = unregister_ftrace_function(_ftrace_ops);
-   WARN(ret < 0, "Failed to init kprobe-ftrace (%d)\n", ret);
+   if (WARN(ret < 0, "Failed to unregister kprobe-ftrace (%d)\n", 
ret))
+   return ret;
}
+
+   kprobe_ftrace_enabled--;
+
ret = ftrace_set_filter_ip(_ftrace_ops,
   (unsigned long)p->addr, 1, 0);
WARN(ret < 0, "Failed to disarm kprobe-ftrace at %p (%d)\n", p->addr, 
ret);
+   return ret;
 }
 #else  /* !CONFIG_KPROBES_ON_FTRACE */
 #define prepare_kprobe(p)  arch_prepare_kprobe(p)
 #define arm_kprobe_ftrace(p)   (-ENODEV)
-#define disarm_kprobe_ftrace(p)do {} while (0)
+#define disarm_kprobe_ftrace(p)(-ENODEV)
 #endif
 
 /* Arm a kprobe with text_mutex */
@@ -1046,18 +1050,18 @@ static int arm_kprobe(struct kprobe *kp)
 }
 
 /* Disarm a kprobe with text_mutex */
-static void disarm_kprobe(struct kprobe *kp, bool reopt)
+static int disarm_kprobe(struct kprobe *kp, bool reopt)
 {
-   if (unlikely(kprobe_ftrace(kp))) {
-   disarm_kprobe_ftrace(kp);
-   return;
-   }
+   if (unlikely(kprobe_ftrace(kp)))
+   return disarm_kprobe_ftrace(kp);
 
cpus_read_lock();
mutex_lock(_mutex);
__disarm_kprobe(kp, reopt);
mutex_unlock(_mutex);
cpus_read_unlock();
+
+   return 0;
 }
 
 /*
@@ -1639,11 +1643,12 @@ static int aggr_kprobe_disabled(struct kprobe *ap)
 static struct kprobe *__disable_kprobe(struct kprobe *p)
 {
struct kprobe *orig_p;
+   int ret;
 
/* Get an original kprobe for return */
orig_p = __get_valid_kprobe(p);
if (unlikely(orig_p == NULL))
-   return NULL;
+   return ERR_PTR(-EINVAL);
 
if (!kprobe_disabled(p)) {
/* Disable probe if it is a child probe */
@@ -1657,8 +1662,13 @@ static struct kprobe *__disable_kprobe(struct kprobe *p)
 * should have already been disarmed, so
 * skip unneed disarming process.
 */
-   if (!kprobes_all_disarmed)
-   disarm_kprobe(orig_p, true);
+   if (!kprobes_all_disarmed) {
+   ret = disarm_kprobe(orig_p, true);
+   if (ret) {
+   p->flags &= ~KPROBE_FLAG_DISABLED;
+   return ERR_PTR(ret);
+   }
+   }
orig_p->flags |= KPROBE_FLAG_DISABLED;
}
}
@@ -1675,8 +1685,8 @@ static int __unregister_kprobe_top(struct kprobe *p)
 
/* Disable kprobe. This will