Messages in this thread | | | Date | Mon, 11 Sep 2017 21:04:35 -0700 | From | "Paul E. McKenney" <> | Subject | Re: [PATCH -tip v2] kprobes: Use synchronize_rcu_tasks() for optprobe with CONFIG_PREEMPT |
| |
On Tue, Sep 12, 2017 at 10:10:51AM +0900, Masami Hiramatsu wrote: > To enable jump optimized probe with CONFIG_PREEMPT, use > synchronize_rcu_tasks() to wait for all tasks preempted > on trampoline code back on track. > > Since the jump optimized kprobes can replace multiple > instructions, there can be tasks which are interrupted > on the 2nd (or 3rd) instructions. If the kprobe > replaces those instructions by a jump instruction, > when those tasks back to the interrupted place, it is > a middle of the jump instruction and causes a kernel > panic. > To avoid such tragedies in advance, kprobe optimizer > prepare a detour route using normal kprobe (e.g. > int3 breakpoint on x86), and wait for the tasks which > is interrrupted on such place by synchronize_sched() > when CONFIG_PREEMPT=n. > If CONFIG_PREEMPT=y, things be more complicated, because > such interrupted thread can be preempted (other thread > can be scheduled in interrupt handler.) So, kprobes > optimizer has to wait for those tasks scheduled normally. > In this case we can use synchronize_rcu_tasks() which > ensures that all preempted tasks back on track and > schedule it. > > Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
Reviewed-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
> --- > arch/Kconfig | 2 +- > kernel/kprobes.c | 18 +++++++++++++----- > 2 files changed, 14 insertions(+), 6 deletions(-) > > diff --git a/arch/Kconfig b/arch/Kconfig > index 2520ca5b42eb..d495c06ae961 100644 > --- a/arch/Kconfig > +++ b/arch/Kconfig > @@ -90,7 +90,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 > diff --git a/kernel/kprobes.c b/kernel/kprobes.c > index a1606a4224e1..6243b8b02511 100644 > --- a/kernel/kprobes.c > +++ b/kernel/kprobes.c > @@ -574,12 +574,20 @@ static void kprobe_optimizer(struct work_struct *work) > > /* > * 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. > + * are done. Because optprobe may modify multiple instructions, > + * there is a chance that the Nth instruction is interrupted. In that > + * case, running interrupt can return to the Nth byte of jump > + * instruction. This can be avoided by waiting for returning of > + * such interrupts, since (until here) the first byte of the optimized > + * probe is already replaced with normal kprobe (sw breakpoint) and > + * all threads which reach to the probed address will hit it and > + * bypass the copied instructions instead of executing the original. > + * With CONFIG_PREEMPT, such interrupts can be preepmted. To wait > + * for such thread, we will use synchronize_rcu_tasks() which ensures > + * all preeempted tasks are scheduled normally (= not preempted.) > + * So we can ensure there is no threads preempted at probed address. > */ > - synchronize_sched(); > + synchronize_rcu_tasks(); > > /* Step 3: Optimize kprobes after quiesence period */ > do_optimize_kprobes(); >
| |