aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/kprobes.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/kernel/kprobes.c')
-rw-r--r--arch/powerpc/kernel/kprobes.c18
1 files changed, 6 insertions, 12 deletions
diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c
index 3fd1af902112..bc47352deb1f 100644
--- a/arch/powerpc/kernel/kprobes.c
+++ b/arch/powerpc/kernel/kprobes.c
@@ -31,6 +31,7 @@
31#include <linux/preempt.h> 31#include <linux/preempt.h>
32#include <linux/module.h> 32#include <linux/module.h>
33#include <linux/kdebug.h> 33#include <linux/kdebug.h>
34#include <linux/slab.h>
34#include <asm/cacheflush.h> 35#include <asm/cacheflush.h>
35#include <asm/sstep.h> 36#include <asm/sstep.h>
36#include <asm/uaccess.h> 37#include <asm/uaccess.h>
@@ -113,6 +114,9 @@ static void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
113#ifdef CONFIG_PPC_ADV_DEBUG_REGS 114#ifdef CONFIG_PPC_ADV_DEBUG_REGS
114 regs->msr &= ~MSR_CE; 115 regs->msr &= ~MSR_CE;
115 mtspr(SPRN_DBCR0, mfspr(SPRN_DBCR0) | DBCR0_IC | DBCR0_IDM); 116 mtspr(SPRN_DBCR0, mfspr(SPRN_DBCR0) | DBCR0_IC | DBCR0_IDM);
117#ifdef CONFIG_PPC_47x
118 isync();
119#endif
116#endif 120#endif
117 121
118 /* 122 /*
@@ -374,17 +378,6 @@ static int __kprobes trampoline_probe_handler(struct kprobe *p,
374 * single-stepped a copy of the instruction. The address of this 378 * single-stepped a copy of the instruction. The address of this
375 * copy is p->ainsn.insn. 379 * copy is p->ainsn.insn.
376 */ 380 */
377static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs)
378{
379 int ret;
380 unsigned int insn = *p->ainsn.insn;
381
382 regs->nip = (unsigned long)p->addr;
383 ret = emulate_step(regs, insn);
384 if (ret == 0)
385 regs->nip = (unsigned long)p->addr + 4;
386}
387
388static int __kprobes post_kprobe_handler(struct pt_regs *regs) 381static int __kprobes post_kprobe_handler(struct pt_regs *regs)
389{ 382{
390 struct kprobe *cur = kprobe_running(); 383 struct kprobe *cur = kprobe_running();
@@ -402,7 +395,8 @@ static int __kprobes post_kprobe_handler(struct pt_regs *regs)
402 cur->post_handler(cur, regs, 0); 395 cur->post_handler(cur, regs, 0);
403 } 396 }
404 397
405 resume_execution(cur, regs); 398 /* Adjust nip to after the single-stepped instruction */
399 regs->nip = (unsigned long)cur->addr + 4;
406 regs->msr |= kcb->kprobe_saved_msr; 400 regs->msr |= kcb->kprobe_saved_msr;
407 401
408 /*Restore back the original saved kprobes variables and continue. */ 402 /*Restore back the original saved kprobes variables and continue. */