Since the int3 itself disables the local_irq and kprobes keeps it disabled while the single step has done, the kernel preemption never happen while processing a kprobe. This means that we don't need to disable/enable preemption. Also, this changes kprobe_int3_handler to use goto-out style. Signed-off-by: Masami Hiramatsu <masami.hiramatsu.pt@xxxxxxxxxxx> Cc: Thomas Gleixner <tglx@xxxxxxxxxxxxx> Cc: Ingo Molnar <mingo@xxxxxxxxxx> Cc: "H. Peter Anvin" <hpa@xxxxxxxxx> --- arch/x86/kernel/kprobes/core.c | 24 +++++++----------------- 1 file changed, 7 insertions(+), 17 deletions(-) diff --git a/arch/x86/kernel/kprobes/core.c b/arch/x86/kernel/kprobes/core.c index 060641e..6b4d9bd 100644 --- a/arch/x86/kernel/kprobes/core.c +++ b/arch/x86/kernel/kprobes/core.c @@ -506,7 +506,6 @@ static void setup_singlestep(struct kprobe *p, struct pt_regs *regs, * stepping. */ regs->ip = (unsigned long)p->ainsn.insn; - preempt_enable_no_resched(); return; } #endif @@ -574,13 +573,6 @@ int kprobe_int3_handler(struct pt_regs *regs) struct kprobe_ctlblk *kcb; addr = (kprobe_opcode_t *)(regs->ip - sizeof(kprobe_opcode_t)); - /* - * We don't want to be preempted for the entire - * duration of kprobe processing. We conditionally - * re-enable preemption at the end of this function, - * and also in reenter_kprobe() and setup_singlestep(). - */ - preempt_disable(); kcb = get_kprobe_ctlblk(); p = get_kprobe(addr); @@ -588,7 +580,7 @@ int kprobe_int3_handler(struct pt_regs *regs) if (p) { if (kprobe_running()) { if (reenter_kprobe(p, regs, kcb)) - return 1; + goto handled; } else { set_current_kprobe(p, regs, kcb); kcb->kprobe_status = KPROBE_HIT_ACTIVE; @@ -603,7 +595,7 @@ int kprobe_int3_handler(struct pt_regs *regs) */ if (!p->pre_handler || !p->pre_handler(p, regs)) setup_singlestep(p, regs, kcb, 0); - return 1; + goto handled; } } else if (*addr != BREAKPOINT_INSTRUCTION) { /* @@ -616,19 +608,20 @@ int kprobe_int3_handler(struct pt_regs *regs) * the original instruction. */ regs->ip = (unsigned long)addr; - preempt_enable_no_resched(); - return 1; + goto handled; } else if (kprobe_running()) { p = __this_cpu_read(current_kprobe); if (p->break_handler && p->break_handler(p, regs)) { if (!skip_singlestep(p, regs, kcb)) setup_singlestep(p, regs, kcb, 0); - return 1; + goto handled; } } /* else: not a kprobe fault; let the kernel handle it */ - preempt_enable_no_resched(); return 0; + +handled: + return 1; } NOKPROBE_SYMBOL(kprobe_int3_handler); @@ -893,7 +886,6 @@ int kprobe_debug_handler(struct pt_regs *regs) } reset_current_kprobe(); out: - preempt_enable_no_resched(); /* * if somebody else is singlestepping across a probe point, flags @@ -928,7 +920,6 @@ int kprobe_fault_handler(struct pt_regs *regs, int trapnr) restore_previous_kprobe(kcb); else reset_current_kprobe(); - preempt_enable_no_resched(); break; case KPROBE_HIT_ACTIVE: case KPROBE_HIT_SSDONE: @@ -1062,7 +1053,6 @@ int longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) memcpy((kprobe_opcode_t *)(kcb->jprobe_saved_sp), kcb->jprobes_stack, MIN_STACK_SIZE(kcb->jprobe_saved_sp)); - preempt_enable_no_resched(); return 1; } return 0; -- To unsubscribe from this list: send the line "unsubscribe linux-arch" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html