diff options
Diffstat (limited to 'arch/x86/kernel/kprobes.c')
-rw-r--r-- | arch/x86/kernel/kprobes.c | 27 |
1 files changed, 13 insertions, 14 deletions
diff --git a/arch/x86/kernel/kprobes.c b/arch/x86/kernel/kprobes.c index f2f56c0967b6..345a4b1fe144 100644 --- a/arch/x86/kernel/kprobes.c +++ b/arch/x86/kernel/kprobes.c | |||
@@ -542,20 +542,6 @@ static int __kprobes kprobe_handler(struct pt_regs *regs) | |||
542 | struct kprobe_ctlblk *kcb; | 542 | struct kprobe_ctlblk *kcb; |
543 | 543 | ||
544 | addr = (kprobe_opcode_t *)(regs->ip - sizeof(kprobe_opcode_t)); | 544 | addr = (kprobe_opcode_t *)(regs->ip - sizeof(kprobe_opcode_t)); |
545 | if (*addr != BREAKPOINT_INSTRUCTION) { | ||
546 | /* | ||
547 | * The breakpoint instruction was removed right | ||
548 | * after we hit it. Another cpu has removed | ||
549 | * either a probepoint or a debugger breakpoint | ||
550 | * at this address. In either case, no further | ||
551 | * handling of this interrupt is appropriate. | ||
552 | * Back up over the (now missing) int3 and run | ||
553 | * the original instruction. | ||
554 | */ | ||
555 | regs->ip = (unsigned long)addr; | ||
556 | return 1; | ||
557 | } | ||
558 | |||
559 | /* | 545 | /* |
560 | * We don't want to be preempted for the entire | 546 | * We don't want to be preempted for the entire |
561 | * duration of kprobe processing. We conditionally | 547 | * duration of kprobe processing. We conditionally |
@@ -587,6 +573,19 @@ static int __kprobes kprobe_handler(struct pt_regs *regs) | |||
587 | setup_singlestep(p, regs, kcb, 0); | 573 | setup_singlestep(p, regs, kcb, 0); |
588 | return 1; | 574 | return 1; |
589 | } | 575 | } |
576 | } else if (*addr != BREAKPOINT_INSTRUCTION) { | ||
577 | /* | ||
578 | * The breakpoint instruction was removed right | ||
579 | * after we hit it. Another cpu has removed | ||
580 | * either a probepoint or a debugger breakpoint | ||
581 | * at this address. In either case, no further | ||
582 | * handling of this interrupt is appropriate. | ||
583 | * Back up over the (now missing) int3 and run | ||
584 | * the original instruction. | ||
585 | */ | ||
586 | regs->ip = (unsigned long)addr; | ||
587 | preempt_enable_no_resched(); | ||
588 | return 1; | ||
590 | } else if (kprobe_running()) { | 589 | } else if (kprobe_running()) { |
591 | p = __get_cpu_var(current_kprobe); | 590 | p = __get_cpu_var(current_kprobe); |
592 | if (p->break_handler && p->break_handler(p, regs)) { | 591 | if (p->break_handler && p->break_handler(p, regs)) { |