diff options
Diffstat (limited to 'arch/ppc64/kernel/kprobes.c')
-rw-r--r-- | arch/ppc64/kernel/kprobes.c | 19 |
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) | |||
61 | void arch_copy_kprobe(struct kprobe *p) | 62 | void 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 | ||
66 | void arch_remove_kprobe(struct kprobe *p) | 68 | void 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 | ||
70 | static inline void disarm_kprobe(struct kprobe *p, struct pt_regs *regs) | 75 | void 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 | |||
82 | void arch_remove_kprobe(struct kprobe *p) | ||
83 | { | ||
74 | } | 84 | } |
75 | 85 | ||
76 | static inline void prepare_singlestep(struct kprobe *p, struct pt_regs *regs) | 86 | static 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; |