diff options
author | mao, bibo <bibo.mao@intel.com> | 2006-06-26 03:25:22 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-06-26 12:58:22 -0400 |
commit | 36721656776f177280ccb50477a02e86e6444292 (patch) | |
tree | 20cb06eb08e98636e97703d6e0df77790ede23cf /arch/i386/kernel | |
parent | 585deacaca3e7bfc63580623f0344d1fa9c47f11 (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')
-rw-r--r-- | arch/i386/kernel/kprobes.c | 16 |
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 && | 341 | ss_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 | |||
354 | ss_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; |