34
34
#include <asm/cacheflush.h>
35
35
#include <asm/sstep.h>
36
36
#include <asm/uaccess.h>
37
+ #include <asm/system.h>
38
+
39
+ #ifdef CONFIG_BOOKE
40
+ #define MSR_SINGLESTEP (MSR_DE)
41
+ #else
42
+ #define MSR_SINGLESTEP (MSR_SE)
43
+ #endif
37
44
38
45
DEFINE_PER_CPU (struct kprobe * , current_kprobe ) = NULL ;
39
46
DEFINE_PER_CPU (struct kprobe_ctlblk , kprobe_ctlblk );
@@ -53,7 +60,8 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p)
53
60
ret = - EINVAL ;
54
61
}
55
62
56
- /* insn must be on a special executable page on ppc64 */
63
+ /* insn must be on a special executable page on ppc64. This is
64
+ * not explicitly required on ppc32 (right now), but it doesn't hurt */
57
65
if (!ret ) {
58
66
p -> ainsn .insn = get_insn_slot ();
59
67
if (!p -> ainsn .insn )
@@ -100,7 +108,11 @@ static void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
100
108
* possible we'd get the single step reported for an exception handler
101
109
* like Decrementer or External Interrupt */
102
110
regs -> msr &= ~MSR_EE ;
103
- regs -> msr |= MSR_SE ;
111
+ regs -> msr |= MSR_SINGLESTEP ;
112
+ #ifdef CONFIG_BOOKE
113
+ regs -> msr &= ~MSR_CE ;
114
+ mtspr (SPRN_DBCR0 , mfspr (SPRN_DBCR0 ) | DBCR0_IC | DBCR0_IDM );
115
+ #endif
104
116
105
117
/*
106
118
* On powerpc we should single step on the original
@@ -163,7 +175,8 @@ static int __kprobes kprobe_handler(struct pt_regs *regs)
163
175
kprobe_opcode_t insn = * p -> ainsn .insn ;
164
176
if (kcb -> kprobe_status == KPROBE_HIT_SS &&
165
177
is_trap (insn )) {
166
- regs -> msr &= ~MSR_SE ;
178
+ /* Turn off 'trace' bits */
179
+ regs -> msr &= ~MSR_SINGLESTEP ;
167
180
regs -> msr |= kcb -> kprobe_saved_msr ;
168
181
goto no_kprobe ;
169
182
}
@@ -404,10 +417,10 @@ static int __kprobes post_kprobe_handler(struct pt_regs *regs)
404
417
405
418
/*
406
419
* if somebody else is singlestepping across a probe point, msr
407
- * will have SE set, in which case, continue the remaining processing
420
+ * will have DE/ SE set, in which case, continue the remaining processing
408
421
* of do_debug, as if this is not a probe hit.
409
422
*/
410
- if (regs -> msr & MSR_SE )
423
+ if (regs -> msr & MSR_SINGLESTEP )
411
424
return 0 ;
412
425
413
426
return 1 ;
@@ -430,7 +443,7 @@ int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr)
430
443
* normal page fault.
431
444
*/
432
445
regs -> nip = (unsigned long )cur -> addr ;
433
- regs -> msr &= ~MSR_SE ;
446
+ regs -> msr &= ~MSR_SINGLESTEP ; /* Turn off 'trace' bits */
434
447
regs -> msr |= kcb -> kprobe_saved_msr ;
435
448
if (kcb -> kprobe_status == KPROBE_REENTER )
436
449
restore_previous_kprobe (kcb );
0 commit comments