|
@@ -594,7 +594,6 @@ static void setup_singlestep(struct kprobe *p, struct pt_regs *regs,
|
|
* stepping.
|
|
* stepping.
|
|
*/
|
|
*/
|
|
regs->ip = (unsigned long)p->ainsn.insn;
|
|
regs->ip = (unsigned long)p->ainsn.insn;
|
|
- preempt_enable_no_resched();
|
|
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
#endif
|
|
#endif
|
|
@@ -667,12 +666,10 @@ int kprobe_int3_handler(struct pt_regs *regs)
|
|
|
|
|
|
addr = (kprobe_opcode_t *)(regs->ip - sizeof(kprobe_opcode_t));
|
|
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().
|
|
|
|
|
|
+ * We don't want to be preempted for the entire duration of kprobe
|
|
|
|
+ * processing. Since int3 and debug trap disables irqs and we clear
|
|
|
|
+ * IF while singlestepping, it must be no preemptible.
|
|
*/
|
|
*/
|
|
- preempt_disable();
|
|
|
|
|
|
|
|
kcb = get_kprobe_ctlblk();
|
|
kcb = get_kprobe_ctlblk();
|
|
p = get_kprobe(addr);
|
|
p = get_kprobe(addr);
|
|
@@ -694,10 +691,8 @@ int kprobe_int3_handler(struct pt_regs *regs)
|
|
*/
|
|
*/
|
|
if (!p->pre_handler || !p->pre_handler(p, regs))
|
|
if (!p->pre_handler || !p->pre_handler(p, regs))
|
|
setup_singlestep(p, regs, kcb, 0);
|
|
setup_singlestep(p, regs, kcb, 0);
|
|
- else {
|
|
|
|
|
|
+ else
|
|
reset_current_kprobe();
|
|
reset_current_kprobe();
|
|
- preempt_enable_no_resched();
|
|
|
|
- }
|
|
|
|
return 1;
|
|
return 1;
|
|
}
|
|
}
|
|
} else if (*addr != BREAKPOINT_INSTRUCTION) {
|
|
} else if (*addr != BREAKPOINT_INSTRUCTION) {
|
|
@@ -711,11 +706,9 @@ int kprobe_int3_handler(struct pt_regs *regs)
|
|
* the original instruction.
|
|
* the original instruction.
|
|
*/
|
|
*/
|
|
regs->ip = (unsigned long)addr;
|
|
regs->ip = (unsigned long)addr;
|
|
- preempt_enable_no_resched();
|
|
|
|
return 1;
|
|
return 1;
|
|
} /* else: not a kprobe fault; let the kernel handle it */
|
|
} /* else: not a kprobe fault; let the kernel handle it */
|
|
|
|
|
|
- preempt_enable_no_resched();
|
|
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
NOKPROBE_SYMBOL(kprobe_int3_handler);
|
|
NOKPROBE_SYMBOL(kprobe_int3_handler);
|
|
@@ -966,8 +959,6 @@ int kprobe_debug_handler(struct pt_regs *regs)
|
|
}
|
|
}
|
|
reset_current_kprobe();
|
|
reset_current_kprobe();
|
|
out:
|
|
out:
|
|
- preempt_enable_no_resched();
|
|
|
|
-
|
|
|
|
/*
|
|
/*
|
|
* if somebody else is singlestepping across a probe point, flags
|
|
* if somebody else is singlestepping across a probe point, flags
|
|
* will have TF set, in which case, continue the remaining processing
|
|
* will have TF set, in which case, continue the remaining processing
|
|
@@ -1014,7 +1005,6 @@ int kprobe_fault_handler(struct pt_regs *regs, int trapnr)
|
|
restore_previous_kprobe(kcb);
|
|
restore_previous_kprobe(kcb);
|
|
else
|
|
else
|
|
reset_current_kprobe();
|
|
reset_current_kprobe();
|
|
- preempt_enable_no_resched();
|
|
|
|
} else if (kcb->kprobe_status == KPROBE_HIT_ACTIVE ||
|
|
} else if (kcb->kprobe_status == KPROBE_HIT_ACTIVE ||
|
|
kcb->kprobe_status == KPROBE_HIT_SSDONE) {
|
|
kcb->kprobe_status == KPROBE_HIT_SSDONE) {
|
|
/*
|
|
/*
|