aboutsummaryrefslogtreecommitdiffstats
path: root/arch/i386/kernel/kprobes.c
diff options
context:
space:
mode:
authormao, bibo <bibo.mao@intel.com>2006-06-26 03:25:22 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-06-26 12:58:22 -0400
commit36721656776f177280ccb50477a02e86e6444292 (patch)
tree20cb06eb08e98636e97703d6e0df77790ede23cf /arch/i386/kernel/kprobes.c
parent585deacaca3e7bfc63580623f0344d1fa9c47f11 (diff)
[PATCH] Kprobe: multi kprobe posthandler for booster
If there are multi kprobes on the same probepoint, there will be one extra aggr_kprobe on the head of kprobe list. The aggr_kprobe has aggr_post_handler/aggr_break_handler whether the other kprobe post_hander/break_handler is NULL or not. This patch modifies this, only when there is one or more kprobe in the list whose post_handler is not NULL, post_handler of aggr_kprobe will be set as aggr_post_handler. [soshima@redhat.com: !CONFIG_PREEMPT fix] Signed-off-by: bibo, mao <bibo.mao@intel.com> Cc: Masami Hiramatsu <hiramatu@sdl.hitachi.co.jp> Cc: Ananth N Mavinakayanahalli <ananth@in.ibm.com> Cc: "Keshavamurthy, Anil S" <anil.s.keshavamurthy@intel.com> Cc: Prasanna S Panchamukhi <prasanna@in.ibm.com> Cc: Jim Keniston <jkenisto@us.ibm.com> Cc: Yumiko Sugita <sugita@sdl.hitachi.co.jp> Cc: Hideo Aoki <haoki@redhat.com> Signed-off-by: Satoshi Oshima <soshima@redhat.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/i386/kernel/kprobes.c')
-rw-r--r--arch/i386/kernel/kprobes.c16
1 files changed, 5 insertions, 11 deletions
diff --git a/arch/i386/kernel/kprobes.c b/arch/i386/kernel/kprobes.c
index 37f86234bdd7..727e419ad78a 100644
--- a/arch/i386/kernel/kprobes.c
+++ b/arch/i386/kernel/kprobes.c
@@ -259,7 +259,9 @@ static int __kprobes kprobe_handler(struct pt_regs *regs)
259 struct kprobe_ctlblk *kcb; 259 struct kprobe_ctlblk *kcb;
260#ifdef CONFIG_PREEMPT 260#ifdef CONFIG_PREEMPT
261 unsigned pre_preempt_count = preempt_count(); 261 unsigned pre_preempt_count = preempt_count();
262#endif /* CONFIG_PREEMPT */ 262#else
263 unsigned pre_preempt_count = 1;
264#endif
263 265
264 addr = (kprobe_opcode_t *)(regs->eip - sizeof(kprobe_opcode_t)); 266 addr = (kprobe_opcode_t *)(regs->eip - sizeof(kprobe_opcode_t));
265 267
@@ -336,22 +338,14 @@ static int __kprobes kprobe_handler(struct pt_regs *regs)
336 /* handler has already set things up, so skip ss setup */ 338 /* handler has already set things up, so skip ss setup */
337 return 1; 339 return 1;
338 340
339 if (p->ainsn.boostable == 1 && 341ss_probe:
340#ifdef CONFIG_PREEMPT 342 if (pre_preempt_count && p->ainsn.boostable == 1 && !p->post_handler){
341 !(pre_preempt_count) && /*
342 * This enables booster when the direct
343 * execution path aren't preempted.
344 */
345#endif /* CONFIG_PREEMPT */
346 !p->post_handler && !p->break_handler ) {
347 /* Boost up -- we can execute copied instructions directly */ 343 /* Boost up -- we can execute copied instructions directly */
348 reset_current_kprobe(); 344 reset_current_kprobe();
349 regs->eip = (unsigned long)p->ainsn.insn; 345 regs->eip = (unsigned long)p->ainsn.insn;
350 preempt_enable_no_resched(); 346 preempt_enable_no_resched();
351 return 1; 347 return 1;
352 } 348 }
353
354ss_probe:
355 prepare_singlestep(p, regs); 349 prepare_singlestep(p, regs);
356 kcb->kprobe_status = KPROBE_HIT_SS; 350 kcb->kprobe_status = KPROBE_HIT_SS;
357 return 1; 351 return 1;