]> nv-tegra.nvidia Code Review - linux-2.6.git/blobdiff - arch/i386/kernel/kprobes.c
[PATCH] Move kprobe [dis]arming into arch specific code
[linux-2.6.git] / arch / i386 / kernel / kprobes.c
index 048f754bbe2337441d19d269d6d35e407121e965..2314d8d306fd09da6ad6f07610ba155f8d5f6062 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/ptrace.h>
 #include <linux/spinlock.h>
 #include <linux/preempt.h>
+#include <asm/cacheflush.h>
 #include <asm/kdebug.h>
 #include <asm/desc.h>
 
@@ -71,16 +72,25 @@ int arch_prepare_kprobe(struct kprobe *p)
 void arch_copy_kprobe(struct kprobe *p)
 {
        memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
+       p->opcode = *p->addr;
 }
 
-void arch_remove_kprobe(struct kprobe *p)
+void arch_arm_kprobe(struct kprobe *p)
 {
+       *p->addr = BREAKPOINT_INSTRUCTION;
+       flush_icache_range((unsigned long) p->addr,
+                          (unsigned long) p->addr + sizeof(kprobe_opcode_t));
 }
 
-static inline void disarm_kprobe(struct kprobe *p, struct pt_regs *regs)
+void arch_disarm_kprobe(struct kprobe *p)
 {
        *p->addr = p->opcode;
-       regs->eip = (unsigned long)p->addr;
+       flush_icache_range((unsigned long) p->addr,
+                          (unsigned long) p->addr + sizeof(kprobe_opcode_t));
+}
+
+void arch_remove_kprobe(struct kprobe *p)
+{
 }
 
 static inline void prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
@@ -177,7 +187,8 @@ static int kprobe_handler(struct pt_regs *regs)
                                unlock_kprobes();
                                goto no_kprobe;
                        }
-                       disarm_kprobe(p, regs);
+                       arch_disarm_kprobe(p);
+                       regs->eip = (unsigned long)p->addr;
                        ret = 1;
                } else {
                        p = current_kprobe;