aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKeshavamurthy Anil S <anil.s.keshavamurthy@intel.com>2005-12-12 03:37:34 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2005-12-12 11:57:45 -0500
commitbf8d5c52c3b6b27061e3b7d779057fd9a6cac164 (patch)
treee4371185eba27db47282410dd490b78598d20636
parent00d7c05ab168c10f9b520e07400923267bc04419 (diff)
[PATCH] kprobes: increment kprobe missed count for multiprobes
When multiple probes are registered at the same address and if due to some recursion (probe getting triggered within a probe handler), we skip calling pre_handlers and just increment nmissed field. The below patch make sure it walks the list for multiple probes case. Without the below patch we get incorrect results of nmissed count for multiple probe case. Signed-off-by: Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--arch/i386/kernel/kprobes.c2
-rw-r--r--arch/ia64/kernel/kprobes.c2
-rw-r--r--arch/powerpc/kernel/kprobes.c2
-rw-r--r--arch/sparc64/kernel/kprobes.c2
-rw-r--r--arch/x86_64/kernel/kprobes.c2
-rw-r--r--include/linux/kprobes.h1
-rw-r--r--kernel/kprobes.c13
7 files changed, 19 insertions, 5 deletions
diff --git a/arch/i386/kernel/kprobes.c b/arch/i386/kernel/kprobes.c
index 32b0c24ab9a6..19edcd526ba4 100644
--- a/arch/i386/kernel/kprobes.c
+++ b/arch/i386/kernel/kprobes.c
@@ -191,7 +191,7 @@ static int __kprobes kprobe_handler(struct pt_regs *regs)
191 */ 191 */
192 save_previous_kprobe(kcb); 192 save_previous_kprobe(kcb);
193 set_current_kprobe(p, regs, kcb); 193 set_current_kprobe(p, regs, kcb);
194 p->nmissed++; 194 kprobes_inc_nmissed_count(p);
195 prepare_singlestep(p, regs); 195 prepare_singlestep(p, regs);
196 kcb->kprobe_status = KPROBE_REENTER; 196 kcb->kprobe_status = KPROBE_REENTER;
197 return 1; 197 return 1;
diff --git a/arch/ia64/kernel/kprobes.c b/arch/ia64/kernel/kprobes.c
index 2895d6e6062f..89a70400c4f6 100644
--- a/arch/ia64/kernel/kprobes.c
+++ b/arch/ia64/kernel/kprobes.c
@@ -630,7 +630,7 @@ static int __kprobes pre_kprobes_handler(struct die_args *args)
630 */ 630 */
631 save_previous_kprobe(kcb); 631 save_previous_kprobe(kcb);
632 set_current_kprobe(p, kcb); 632 set_current_kprobe(p, kcb);
633 p->nmissed++; 633 kprobes_inc_nmissed_count(p);
634 prepare_ss(p, regs); 634 prepare_ss(p, regs);
635 kcb->kprobe_status = KPROBE_REENTER; 635 kcb->kprobe_status = KPROBE_REENTER;
636 return 1; 636 return 1;
diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c
index 511af54e6230..5368f9c2e6bf 100644
--- a/arch/powerpc/kernel/kprobes.c
+++ b/arch/powerpc/kernel/kprobes.c
@@ -177,7 +177,7 @@ static inline int kprobe_handler(struct pt_regs *regs)
177 save_previous_kprobe(kcb); 177 save_previous_kprobe(kcb);
178 set_current_kprobe(p, regs, kcb); 178 set_current_kprobe(p, regs, kcb);
179 kcb->kprobe_saved_msr = regs->msr; 179 kcb->kprobe_saved_msr = regs->msr;
180 p->nmissed++; 180 kprobes_inc_nmissed_count(p);
181 prepare_singlestep(p, regs); 181 prepare_singlestep(p, regs);
182 kcb->kprobe_status = KPROBE_REENTER; 182 kcb->kprobe_status = KPROBE_REENTER;
183 return 1; 183 return 1;
diff --git a/arch/sparc64/kernel/kprobes.c b/arch/sparc64/kernel/kprobes.c
index 96bd09b098f4..a97b0f0727ab 100644
--- a/arch/sparc64/kernel/kprobes.c
+++ b/arch/sparc64/kernel/kprobes.c
@@ -138,7 +138,7 @@ static int __kprobes kprobe_handler(struct pt_regs *regs)
138 */ 138 */
139 save_previous_kprobe(kcb); 139 save_previous_kprobe(kcb);
140 set_current_kprobe(p, regs, kcb); 140 set_current_kprobe(p, regs, kcb);
141 p->nmissed++; 141 kprobes_inc_nmissed_count(p);
142 kcb->kprobe_status = KPROBE_REENTER; 142 kcb->kprobe_status = KPROBE_REENTER;
143 prepare_singlestep(p, regs, kcb); 143 prepare_singlestep(p, regs, kcb);
144 return 1; 144 return 1;
diff --git a/arch/x86_64/kernel/kprobes.c b/arch/x86_64/kernel/kprobes.c
index dddeb678b440..afe11f4fbd1d 100644
--- a/arch/x86_64/kernel/kprobes.c
+++ b/arch/x86_64/kernel/kprobes.c
@@ -329,7 +329,7 @@ int __kprobes kprobe_handler(struct pt_regs *regs)
329 */ 329 */
330 save_previous_kprobe(kcb); 330 save_previous_kprobe(kcb);
331 set_current_kprobe(p, regs, kcb); 331 set_current_kprobe(p, regs, kcb);
332 p->nmissed++; 332 kprobes_inc_nmissed_count(p);
333 prepare_singlestep(p, regs); 333 prepare_singlestep(p, regs);
334 kcb->kprobe_status = KPROBE_REENTER; 334 kcb->kprobe_status = KPROBE_REENTER;
335 return 1; 335 return 1;
diff --git a/include/linux/kprobes.h b/include/linux/kprobes.h
index 434ecfd7cf48..c03f2dc933de 100644
--- a/include/linux/kprobes.h
+++ b/include/linux/kprobes.h
@@ -158,6 +158,7 @@ extern int arch_init_kprobes(void);
158extern void show_registers(struct pt_regs *regs); 158extern void show_registers(struct pt_regs *regs);
159extern kprobe_opcode_t *get_insn_slot(void); 159extern kprobe_opcode_t *get_insn_slot(void);
160extern void free_insn_slot(kprobe_opcode_t *slot); 160extern void free_insn_slot(kprobe_opcode_t *slot);
161extern void kprobes_inc_nmissed_count(struct kprobe *p);
161 162
162/* Get the kprobe at this addr (if any) - called with preemption disabled */ 163/* Get the kprobe at this addr (if any) - called with preemption disabled */
163struct kprobe *get_kprobe(void *addr); 164struct kprobe *get_kprobe(void *addr);
diff --git a/kernel/kprobes.c b/kernel/kprobes.c
index e4f0fc62bd3e..3bb71e63a37e 100644
--- a/kernel/kprobes.c
+++ b/kernel/kprobes.c
@@ -246,6 +246,19 @@ static int __kprobes aggr_break_handler(struct kprobe *p, struct pt_regs *regs)
246 return ret; 246 return ret;
247} 247}
248 248
249/* Walks the list and increments nmissed count for multiprobe case */
250void __kprobes kprobes_inc_nmissed_count(struct kprobe *p)
251{
252 struct kprobe *kp;
253 if (p->pre_handler != aggr_pre_handler) {
254 p->nmissed++;
255 } else {
256 list_for_each_entry_rcu(kp, &p->list, list)
257 kp->nmissed++;
258 }
259 return;
260}
261
249/* Called with kretprobe_lock held */ 262/* Called with kretprobe_lock held */
250struct kretprobe_instance __kprobes *get_free_rp_inst(struct kretprobe *rp) 263struct kretprobe_instance __kprobes *get_free_rp_inst(struct kretprobe *rp)
251{ 264{