aboutsummaryrefslogtreecommitdiffstats
path: root/arch/i386/kernel/kprobes.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/i386/kernel/kprobes.c')
-rw-r--r--arch/i386/kernel/kprobes.c19
1 files changed, 15 insertions, 4 deletions
diff --git a/arch/i386/kernel/kprobes.c b/arch/i386/kernel/kprobes.c
index 048f754bbe23..2314d8d306fd 100644
--- a/arch/i386/kernel/kprobes.c
+++ b/arch/i386/kernel/kprobes.c
@@ -33,6 +33,7 @@
33#include <linux/ptrace.h> 33#include <linux/ptrace.h>
34#include <linux/spinlock.h> 34#include <linux/spinlock.h>
35#include <linux/preempt.h> 35#include <linux/preempt.h>
36#include <asm/cacheflush.h>
36#include <asm/kdebug.h> 37#include <asm/kdebug.h>
37#include <asm/desc.h> 38#include <asm/desc.h>
38 39
@@ -71,16 +72,25 @@ int arch_prepare_kprobe(struct kprobe *p)
71void arch_copy_kprobe(struct kprobe *p) 72void arch_copy_kprobe(struct kprobe *p)
72{ 73{
73 memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t)); 74 memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
75 p->opcode = *p->addr;
74} 76}
75 77
76void arch_remove_kprobe(struct kprobe *p) 78void arch_arm_kprobe(struct kprobe *p)
77{ 79{
80 *p->addr = BREAKPOINT_INSTRUCTION;
81 flush_icache_range((unsigned long) p->addr,
82 (unsigned long) p->addr + sizeof(kprobe_opcode_t));
78} 83}
79 84
80static inline void disarm_kprobe(struct kprobe *p, struct pt_regs *regs) 85void arch_disarm_kprobe(struct kprobe *p)
81{ 86{
82 *p->addr = p->opcode; 87 *p->addr = p->opcode;
83 regs->eip = (unsigned long)p->addr; 88 flush_icache_range((unsigned long) p->addr,
89 (unsigned long) p->addr + sizeof(kprobe_opcode_t));
90}
91
92void arch_remove_kprobe(struct kprobe *p)
93{
84} 94}
85 95
86static inline void prepare_singlestep(struct kprobe *p, struct pt_regs *regs) 96static inline void prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
@@ -177,7 +187,8 @@ static int kprobe_handler(struct pt_regs *regs)
177 unlock_kprobes(); 187 unlock_kprobes();
178 goto no_kprobe; 188 goto no_kprobe;
179 } 189 }
180 disarm_kprobe(p, regs); 190 arch_disarm_kprobe(p);
191 regs->eip = (unsigned long)p->addr;
181 ret = 1; 192 ret = 1;
182 } else { 193 } else {
183 p = current_kprobe; 194 p = current_kprobe;