| From foo@baz Wed Dec 6 18:04:41 CET 2017 |
| From: Masami Hiramatsu <mhiramat@kernel.org> |
| Date: Fri, 20 Oct 2017 08:43:39 +0900 |
| Subject: kprobes: Use synchronize_rcu_tasks() for optprobe with CONFIG_PREEMPT=y |
| |
| From: Masami Hiramatsu <mhiramat@kernel.org> |
| |
| |
| [ Upstream commit a30b85df7d599f626973e9cd3056fe755bd778e0 ] |
| |
| We want to wait for all potentially preempted kprobes trampoline |
| execution to have completed. This guarantees that any freed |
| trampoline memory is not in use by any task in the system anymore. |
| synchronize_rcu_tasks() gives such a guarantee, so use it. |
| |
| Also, this guarantees to wait for all potentially preempted tasks |
| on the instructions which will be replaced with a jump. |
| |
| Since this becomes a problem only when CONFIG_PREEMPT=y, enable |
| CONFIG_TASKS_RCU=y for synchronize_rcu_tasks() in that case. |
| |
| Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org> |
| Acked-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com> |
| Cc: Ananth N Mavinakayanahalli <ananth@linux.vnet.ibm.com> |
| Cc: Linus Torvalds <torvalds@linux-foundation.org> |
| Cc: Naveen N . Rao <naveen.n.rao@linux.vnet.ibm.com> |
| Cc: Paul E . McKenney <paulmck@linux.vnet.ibm.com> |
| Cc: Peter Zijlstra <peterz@infradead.org> |
| Cc: Steven Rostedt <rostedt@goodmis.org> |
| Cc: Thomas Gleixner <tglx@linutronix.de> |
| Link: http://lkml.kernel.org/r/150845661962.5443.17724352636247312231.stgit@devbox |
| Signed-off-by: Ingo Molnar <mingo@kernel.org> |
| Signed-off-by: Sasha Levin <alexander.levin@verizon.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| arch/Kconfig | 2 +- |
| kernel/kprobes.c | 14 ++++++++------ |
| 2 files changed, 9 insertions(+), 7 deletions(-) |
| |
| --- a/arch/Kconfig |
| +++ b/arch/Kconfig |
| @@ -91,7 +91,7 @@ config STATIC_KEYS_SELFTEST |
| config OPTPROBES |
| def_bool y |
| depends on KPROBES && HAVE_OPTPROBES |
| - depends on !PREEMPT |
| + select TASKS_RCU if PREEMPT |
| |
| config KPROBES_ON_FTRACE |
| def_bool y |
| --- a/kernel/kprobes.c |
| +++ b/kernel/kprobes.c |
| @@ -573,13 +573,15 @@ static void kprobe_optimizer(struct work |
| do_unoptimize_kprobes(); |
| |
| /* |
| - * Step 2: Wait for quiesence period to ensure all running interrupts |
| - * are done. Because optprobe may modify multiple instructions |
| - * there is a chance that Nth instruction is interrupted. In that |
| - * case, running interrupt can return to 2nd-Nth byte of jump |
| - * instruction. This wait is for avoiding it. |
| + * Step 2: Wait for quiesence period to ensure all potentially |
| + * preempted tasks to have normally scheduled. Because optprobe |
| + * may modify multiple instructions, there is a chance that Nth |
| + * instruction is preempted. In that case, such tasks can return |
| + * to 2nd-Nth byte of jump instruction. This wait is for avoiding it. |
| + * Note that on non-preemptive kernel, this is transparently converted |
| + * to synchronoze_sched() to wait for all interrupts to have completed. |
| */ |
| - synchronize_sched(); |
| + synchronize_rcu_tasks(); |
| |
| /* Step 3: Optimize kprobes after quiesence period */ |
| do_optimize_kprobes(); |