diff options
Diffstat (limited to 'arch/powerpc/kernel/kprobes.c')
| -rw-r--r-- | arch/powerpc/kernel/kprobes.c | 36 |
1 files changed, 35 insertions, 1 deletions
diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c index dd2886f97e98..ef647e7a9dc3 100644 --- a/arch/powerpc/kernel/kprobes.c +++ b/arch/powerpc/kernel/kprobes.c | |||
| @@ -59,12 +59,14 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p) | |||
| 59 | } | 59 | } |
| 60 | 60 | ||
| 61 | if (!ret) { | 61 | if (!ret) { |
| 62 | memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t)); | 62 | memcpy(p->ainsn.insn, p->addr, |
| 63 | MAX_INSN_SIZE * sizeof(kprobe_opcode_t)); | ||
| 63 | p->opcode = *p->addr; | 64 | p->opcode = *p->addr; |
| 64 | flush_icache_range((unsigned long)p->ainsn.insn, | 65 | flush_icache_range((unsigned long)p->ainsn.insn, |
| 65 | (unsigned long)p->ainsn.insn + sizeof(kprobe_opcode_t)); | 66 | (unsigned long)p->ainsn.insn + sizeof(kprobe_opcode_t)); |
| 66 | } | 67 | } |
| 67 | 68 | ||
| 69 | p->ainsn.boostable = 0; | ||
| 68 | return ret; | 70 | return ret; |
| 69 | } | 71 | } |
| 70 | 72 | ||
| @@ -232,6 +234,38 @@ static int __kprobes kprobe_handler(struct pt_regs *regs) | |||
| 232 | return 1; | 234 | return 1; |
| 233 | 235 | ||
| 234 | ss_probe: | 236 | ss_probe: |
| 237 | if (p->ainsn.boostable >= 0) { | ||
| 238 | unsigned int insn = *p->ainsn.insn; | ||
| 239 | |||
| 240 | /* regs->nip is also adjusted if emulate_step returns 1 */ | ||
| 241 | ret = emulate_step(regs, insn); | ||
| 242 | if (ret > 0) { | ||
| 243 | /* | ||
| 244 | * Once this instruction has been boosted | ||
| 245 | * successfully, set the boostable flag | ||
| 246 | */ | ||
| 247 | if (unlikely(p->ainsn.boostable == 0)) | ||
| 248 | p->ainsn.boostable = 1; | ||
| 249 | |||
| 250 | if (p->post_handler) | ||
| 251 | p->post_handler(p, regs, 0); | ||
| 252 | |||
| 253 | kcb->kprobe_status = KPROBE_HIT_SSDONE; | ||
| 254 | reset_current_kprobe(); | ||
| 255 | preempt_enable_no_resched(); | ||
| 256 | return 1; | ||
| 257 | } else if (ret < 0) { | ||
| 258 | /* | ||
| 259 | * We don't allow kprobes on mtmsr(d)/rfi(d), etc. | ||
| 260 | * So, we should never get here... but, its still | ||
| 261 | * good to catch them, just in case... | ||
| 262 | */ | ||
| 263 | printk("Can't step on instruction %x\n", insn); | ||
| 264 | BUG(); | ||
| 265 | } else if (ret == 0) | ||
| 266 | /* This instruction can't be boosted */ | ||
| 267 | p->ainsn.boostable = -1; | ||
| 268 | } | ||
| 235 | prepare_singlestep(p, regs); | 269 | prepare_singlestep(p, regs); |
| 236 | kcb->kprobe_status = KPROBE_HIT_SS; | 270 | kcb->kprobe_status = KPROBE_HIT_SS; |
| 237 | return 1; | 271 | return 1; |
