Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 101671
b: refs/heads/master
c: f827962
h: refs/heads/master
i:
  101669: 3842119
  101667: 05fcab7
  101663: 5db0e9a
v: v3
  • Loading branch information
Kumar Gala committed Jun 26, 2008
1 parent 61dd098 commit 00ac879
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 16 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: b76e59d1fb086c2fdac5d243e09786d6581f2026
refs/heads/master: f82796214a95b1ec00c2f121c1080d10f2b099a1
1 change: 1 addition & 0 deletions trunk/Documentation/kprobes.txt
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ architectures:
- ia64 (Does not support probes on instruction slot1.)
- sparc64 (Return probes not yet implemented.)
- arm
- ppc

3. Configuring Kprobes

Expand Down
25 changes: 19 additions & 6 deletions trunk/arch/powerpc/kernel/kprobes.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,13 @@
#include <asm/cacheflush.h>
#include <asm/sstep.h>
#include <asm/uaccess.h>
#include <asm/system.h>

#ifdef CONFIG_BOOKE
#define MSR_SINGLESTEP (MSR_DE)
#else
#define MSR_SINGLESTEP (MSR_SE)
#endif

DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
Expand All @@ -53,7 +60,8 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p)
ret = -EINVAL;
}

/* insn must be on a special executable page on ppc64 */
/* insn must be on a special executable page on ppc64. This is
* not explicitly required on ppc32 (right now), but it doesn't hurt */
if (!ret) {
p->ainsn.insn = get_insn_slot();
if (!p->ainsn.insn)
Expand Down Expand Up @@ -100,7 +108,11 @@ static void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
* possible we'd get the single step reported for an exception handler
* like Decrementer or External Interrupt */
regs->msr &= ~MSR_EE;
regs->msr |= MSR_SE;
regs->msr |= MSR_SINGLESTEP;
#ifdef CONFIG_BOOKE
regs->msr &= ~MSR_CE;
mtspr(SPRN_DBCR0, mfspr(SPRN_DBCR0) | DBCR0_IC | DBCR0_IDM);
#endif

/*
* On powerpc we should single step on the original
Expand Down Expand Up @@ -163,7 +175,8 @@ static int __kprobes kprobe_handler(struct pt_regs *regs)
kprobe_opcode_t insn = *p->ainsn.insn;
if (kcb->kprobe_status == KPROBE_HIT_SS &&
is_trap(insn)) {
regs->msr &= ~MSR_SE;
/* Turn off 'trace' bits */
regs->msr &= ~MSR_SINGLESTEP;
regs->msr |= kcb->kprobe_saved_msr;
goto no_kprobe;
}
Expand Down Expand Up @@ -404,10 +417,10 @@ static int __kprobes post_kprobe_handler(struct pt_regs *regs)

/*
* if somebody else is singlestepping across a probe point, msr
* will have SE set, in which case, continue the remaining processing
* will have DE/SE set, in which case, continue the remaining processing
* of do_debug, as if this is not a probe hit.
*/
if (regs->msr & MSR_SE)
if (regs->msr & MSR_SINGLESTEP)
return 0;

return 1;
Expand All @@ -430,7 +443,7 @@ int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr)
* normal page fault.
*/
regs->nip = (unsigned long)cur->addr;
regs->msr &= ~MSR_SE;
regs->msr &= ~MSR_SINGLESTEP; /* Turn off 'trace' bits */
regs->msr |= kcb->kprobe_saved_msr;
if (kcb->kprobe_status == KPROBE_REENTER)
restore_previous_kprobe(kcb);
Expand Down
26 changes: 17 additions & 9 deletions trunk/arch/powerpc/kernel/traps.c
Original file line number Diff line number Diff line change
Expand Up @@ -1030,21 +1030,29 @@ void SoftwareEmulation(struct pt_regs *regs)

#if defined(CONFIG_40x) || defined(CONFIG_BOOKE)

void DebugException(struct pt_regs *regs, unsigned long debug_status)
void __kprobes DebugException(struct pt_regs *regs, unsigned long debug_status)
{
if (debug_status & DBSR_IC) { /* instruction completion */
regs->msr &= ~MSR_DE;

/* Disable instruction completion */
mtspr(SPRN_DBCR0, mfspr(SPRN_DBCR0) & ~DBCR0_IC);
/* Clear the instruction completion event */
mtspr(SPRN_DBSR, DBSR_IC);

if (notify_die(DIE_SSTEP, "single_step", regs, 5,
5, SIGTRAP) == NOTIFY_STOP) {
return;
}

if (debugger_sstep(regs))
return;

if (user_mode(regs)) {
current->thread.dbcr0 &= ~DBCR0_IC;
} else {
/* Disable instruction completion */
mtspr(SPRN_DBCR0, mfspr(SPRN_DBCR0) & ~DBCR0_IC);
/* Clear the instruction completion event */
mtspr(SPRN_DBSR, DBSR_IC);
if (debugger_sstep(regs))
return;
}
_exception(SIGTRAP, regs, TRAP_TRACE, 0);

_exception(SIGTRAP, regs, TRAP_TRACE, regs->nip);
}
}
#endif /* CONFIG_4xx || CONFIG_BOOKE */
Expand Down

0 comments on commit 00ac879

Please sign in to comment.