* [PATCH] arm: Make kprobes unregistration SMP safe
@ 2009-09-16 5:21 Frédéric RISS
2009-09-18 0:40 ` Nicolas Pitre
0 siblings, 1 reply; 3+ messages in thread
From: Frédéric RISS @ 2009-09-16 5:21 UTC (permalink / raw)
To: linux-arm-kernel
ARM kprobes use an illegal instruction to trigger kprobes. In the
current implementation, there's a race between the unregistration of a
kprobe and the illegal instruction exception handler if they run at the
same time on different cores.
When reading the value of the undefined instruction, the exception
handler might get the original legal instruction as just patched
concurrently by arch_disarm_kprobe(). When this happen the kprobe
handler won't run, and thus the exception handler will oops because it
believe it just hit an undefined instruction in kernel space.
The following patch synchronizes the code patching in the kprobes
unregistration using stop_machine and thus avoids the above race.
Signed-off-by: Frederic RISS <frederic.riss@gmail.com>
---
diff --git a/arch/arm/kernel/kprobes.c b/arch/arm/kernel/kprobes.c
index d28513f..6ada87d 100644
--- a/arch/arm/kernel/kprobes.c
+++ b/arch/arm/kernel/kprobes.c
@@ -22,6 +22,7 @@
#include <linux/kernel.h>
#include <linux/kprobes.h>
#include <linux/module.h>
+#include <linux/stop_machine.h>
#include <linux/stringify.h>
#include <asm/traps.h>
#include <asm/cacheflush.h>
@@ -83,10 +84,24 @@ void __kprobes arch_arm_kprobe(struct kprobe *p)
flush_insns(p->addr, 1);
}
+/*
+ * The actual disarming is done here on each CPU and synchronized using
+ * stop_machine. This synchronization is necessary on SMP to avoid removing
+ * a probe between the moment the 'Undefined Instruction' exception is raised
+ * and the moment the exception handler reads the faulting instruction from
+ * memory.
+ */
+int __kprobes __arch_disarm_kprobe(void *p)
+{
+ struct kprobe *kp = p;
+ *kp->addr = kp->opcode;
+ flush_insns(kp->addr, 1);
+ return 0;
+}
+
void __kprobes arch_disarm_kprobe(struct kprobe *p)
{
- *p->addr = p->opcode;
- flush_insns(p->addr, 1);
+ stop_machine(__arch_disarm_kprobe, p, &cpu_online_map);
}
void __kprobes arch_remove_kprobe(struct kprobe *p)
^ permalink raw reply related [flat|nested] 3+ messages in thread
* [PATCH] arm: Make kprobes unregistration SMP safe
2009-09-16 5:21 [PATCH] arm: Make kprobes unregistration SMP safe Frédéric RISS
@ 2009-09-18 0:40 ` Nicolas Pitre
2009-09-18 19:44 ` Russell King - ARM Linux
0 siblings, 1 reply; 3+ messages in thread
From: Nicolas Pitre @ 2009-09-18 0:40 UTC (permalink / raw)
To: linux-arm-kernel
On Wed, 16 Sep 2009, Fr?d?ric RISS wrote:
> ARM kprobes use an illegal instruction to trigger kprobes. In the
> current implementation, there's a race between the unregistration of a
> kprobe and the illegal instruction exception handler if they run at the
> same time on different cores.
>
> When reading the value of the undefined instruction, the exception
> handler might get the original legal instruction as just patched
> concurrently by arch_disarm_kprobe(). When this happen the kprobe
> handler won't run, and thus the exception handler will oops because it
> believe it just hit an undefined instruction in kernel space.
>
> The following patch synchronizes the code patching in the kprobes
> unregistration using stop_machine and thus avoids the above race.
>
> Signed-off-by: Frederic RISS <frederic.riss@gmail.com>
Acked-by: Nicolas Pitre <nico@fluxnic.net>
> ---
>
> diff --git a/arch/arm/kernel/kprobes.c b/arch/arm/kernel/kprobes.c
> index d28513f..6ada87d 100644
> --- a/arch/arm/kernel/kprobes.c
> +++ b/arch/arm/kernel/kprobes.c
> @@ -22,6 +22,7 @@
> #include <linux/kernel.h>
> #include <linux/kprobes.h>
> #include <linux/module.h>
> +#include <linux/stop_machine.h>
> #include <linux/stringify.h>
> #include <asm/traps.h>
> #include <asm/cacheflush.h>
> @@ -83,10 +84,24 @@ void __kprobes arch_arm_kprobe(struct kprobe *p)
> flush_insns(p->addr, 1);
> }
>
> +/*
> + * The actual disarming is done here on each CPU and synchronized using
> + * stop_machine. This synchronization is necessary on SMP to avoid removing
> + * a probe between the moment the 'Undefined Instruction' exception is raised
> + * and the moment the exception handler reads the faulting instruction from
> + * memory.
> + */
> +int __kprobes __arch_disarm_kprobe(void *p)
> +{
> + struct kprobe *kp = p;
> + *kp->addr = kp->opcode;
> + flush_insns(kp->addr, 1);
> + return 0;
> +}
> +
> void __kprobes arch_disarm_kprobe(struct kprobe *p)
> {
> - *p->addr = p->opcode;
> - flush_insns(p->addr, 1);
> + stop_machine(__arch_disarm_kprobe, p, &cpu_online_map);
> }
>
> void __kprobes arch_remove_kprobe(struct kprobe *p)
>
>
^ permalink raw reply [flat|nested] 3+ messages in thread
* [PATCH] arm: Make kprobes unregistration SMP safe
2009-09-18 0:40 ` Nicolas Pitre
@ 2009-09-18 19:44 ` Russell King - ARM Linux
0 siblings, 0 replies; 3+ messages in thread
From: Russell King - ARM Linux @ 2009-09-18 19:44 UTC (permalink / raw)
To: linux-arm-kernel
On Thu, Sep 17, 2009 at 08:40:10PM -0400, Nicolas Pitre wrote:
> On Wed, 16 Sep 2009, Fr?d?ric RISS wrote:
>
> > ARM kprobes use an illegal instruction to trigger kprobes. In the
> > current implementation, there's a race between the unregistration of a
> > kprobe and the illegal instruction exception handler if they run at the
> > same time on different cores.
> >
> > When reading the value of the undefined instruction, the exception
> > handler might get the original legal instruction as just patched
> > concurrently by arch_disarm_kprobe(). When this happen the kprobe
> > handler won't run, and thus the exception handler will oops because it
> > believe it just hit an undefined instruction in kernel space.
> >
> > The following patch synchronizes the code patching in the kprobes
> > unregistration using stop_machine and thus avoids the above race.
> >
> > Signed-off-by: Frederic RISS <frederic.riss@gmail.com>
>
> Acked-by: Nicolas Pitre <nico@fluxnic.net>
Fr?d?ric, please submit to the patch system, thanks.
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2009-09-18 19:44 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-09-16 5:21 [PATCH] arm: Make kprobes unregistration SMP safe Frédéric RISS
2009-09-18 0:40 ` Nicolas Pitre
2009-09-18 19:44 ` Russell King - ARM Linux
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).