aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ppc64/kernel/kprobes.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/ppc64/kernel/kprobes.c')
-rw-r--r--arch/ppc64/kernel/kprobes.c19
1 files changed, 15 insertions, 4 deletions
diff --git a/arch/ppc64/kernel/kprobes.c b/arch/ppc64/kernel/kprobes.c
index e950a2058a19..8c0920a6d03e 100644
--- a/arch/ppc64/kernel/kprobes.c
+++ b/arch/ppc64/kernel/kprobes.c
@@ -32,6 +32,7 @@
32#include <linux/ptrace.h> 32#include <linux/ptrace.h>
33#include <linux/spinlock.h> 33#include <linux/spinlock.h>
34#include <linux/preempt.h> 34#include <linux/preempt.h>
35#include <asm/cacheflush.h>
35#include <asm/kdebug.h> 36#include <asm/kdebug.h>
36#include <asm/sstep.h> 37#include <asm/sstep.h>
37 38
@@ -61,16 +62,25 @@ int arch_prepare_kprobe(struct kprobe *p)
61void arch_copy_kprobe(struct kprobe *p) 62void arch_copy_kprobe(struct kprobe *p)
62{ 63{
63 memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t)); 64 memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
65 p->opcode = *p->addr;
64} 66}
65 67
66void arch_remove_kprobe(struct kprobe *p) 68void arch_arm_kprobe(struct kprobe *p)
67{ 69{
70 *p->addr = BREAKPOINT_INSTRUCTION;
71 flush_icache_range((unsigned long) p->addr,
72 (unsigned long) p->addr + sizeof(kprobe_opcode_t));
68} 73}
69 74
70static inline void disarm_kprobe(struct kprobe *p, struct pt_regs *regs) 75void arch_disarm_kprobe(struct kprobe *p)
71{ 76{
72 *p->addr = p->opcode; 77 *p->addr = p->opcode;
73 regs->nip = (unsigned long)p->addr; 78 flush_icache_range((unsigned long) p->addr,
79 (unsigned long) p->addr + sizeof(kprobe_opcode_t));
80}
81
82void arch_remove_kprobe(struct kprobe *p)
83{
74} 84}
75 85
76static inline void prepare_singlestep(struct kprobe *p, struct pt_regs *regs) 86static inline void prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
@@ -101,7 +111,8 @@ static inline int kprobe_handler(struct pt_regs *regs)
101 unlock_kprobes(); 111 unlock_kprobes();
102 goto no_kprobe; 112 goto no_kprobe;
103 } 113 }
104 disarm_kprobe(p, regs); 114 arch_disarm_kprobe(p);
115 regs->nip = (unsigned long)p->addr;
105 ret = 1; 116 ret = 1;
106 } else { 117 } else {
107 p = current_kprobe; 118 p = current_kprobe;