[PATCH] kprobe-booster: disable in preemptible kernel
The kprobe-booster's safety check against preemption does not work well now, because the preemption count has been modified by read_rcu_lock() in atomic_notifier_call_chain() before we check it. So, I'd like to prevent boosting kprobe temporarily if the kernel is preemptable. Now we are searching for the good solution. Signed-off-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com> Cc: Ananth N Mavinakayanahalli <ananth@in.ibm.com> Cc: Prasanna S Panchamukhi <prasanna@in.ibm.com> Cc: Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
committed by
Linus Torvalds
parent
2a8a3d5b65
commit
c39df470e0
@@ -256,11 +256,6 @@ static int __kprobes kprobe_handler(struct pt_regs *regs)
|
|||||||
int ret = 0;
|
int ret = 0;
|
||||||
kprobe_opcode_t *addr;
|
kprobe_opcode_t *addr;
|
||||||
struct kprobe_ctlblk *kcb;
|
struct kprobe_ctlblk *kcb;
|
||||||
#ifdef CONFIG_PREEMPT
|
|
||||||
unsigned pre_preempt_count = preempt_count();
|
|
||||||
#else
|
|
||||||
unsigned pre_preempt_count = 1;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
addr = (kprobe_opcode_t *)(regs->eip - sizeof(kprobe_opcode_t));
|
addr = (kprobe_opcode_t *)(regs->eip - sizeof(kprobe_opcode_t));
|
||||||
|
|
||||||
@@ -338,13 +333,15 @@ static int __kprobes kprobe_handler(struct pt_regs *regs)
|
|||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
ss_probe:
|
ss_probe:
|
||||||
if (pre_preempt_count && p->ainsn.boostable == 1 && !p->post_handler){
|
#ifndef CONFIG_PREEMPT
|
||||||
|
if (p->ainsn.boostable == 1 && !p->post_handler){
|
||||||
/* Boost up -- we can execute copied instructions directly */
|
/* Boost up -- we can execute copied instructions directly */
|
||||||
reset_current_kprobe();
|
reset_current_kprobe();
|
||||||
regs->eip = (unsigned long)p->ainsn.insn;
|
regs->eip = (unsigned long)p->ainsn.insn;
|
||||||
preempt_enable_no_resched();
|
preempt_enable_no_resched();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
prepare_singlestep(p, regs);
|
prepare_singlestep(p, regs);
|
||||||
kcb->kprobe_status = KPROBE_HIT_SS;
|
kcb->kprobe_status = KPROBE_HIT_SS;
|
||||||
return 1;
|
return 1;
|
||||||
|
Reference in New Issue
Block a user