Commit bf8d5c52c3b6b27061e3b7d779057fd9a6cac164

Authored by Keshavamurthy Anil S
Committed by Linus Torvalds
1 parent 00d7c05ab1

[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>

Showing 7 changed files with 19 additions and 5 deletions Side-by-side Diff

arch/i386/kernel/kprobes.c
... ... @@ -191,7 +191,7 @@
191 191 */
192 192 save_previous_kprobe(kcb);
193 193 set_current_kprobe(p, regs, kcb);
194   - p->nmissed++;
  194 + kprobes_inc_nmissed_count(p);
195 195 prepare_singlestep(p, regs);
196 196 kcb->kprobe_status = KPROBE_REENTER;
197 197 return 1;
arch/ia64/kernel/kprobes.c
... ... @@ -630,7 +630,7 @@
630 630 */
631 631 save_previous_kprobe(kcb);
632 632 set_current_kprobe(p, kcb);
633   - p->nmissed++;
  633 + kprobes_inc_nmissed_count(p);
634 634 prepare_ss(p, regs);
635 635 kcb->kprobe_status = KPROBE_REENTER;
636 636 return 1;
arch/powerpc/kernel/kprobes.c
... ... @@ -177,7 +177,7 @@
177 177 save_previous_kprobe(kcb);
178 178 set_current_kprobe(p, regs, kcb);
179 179 kcb->kprobe_saved_msr = regs->msr;
180   - p->nmissed++;
  180 + kprobes_inc_nmissed_count(p);
181 181 prepare_singlestep(p, regs);
182 182 kcb->kprobe_status = KPROBE_REENTER;
183 183 return 1;
arch/sparc64/kernel/kprobes.c
... ... @@ -138,7 +138,7 @@
138 138 */
139 139 save_previous_kprobe(kcb);
140 140 set_current_kprobe(p, regs, kcb);
141   - p->nmissed++;
  141 + kprobes_inc_nmissed_count(p);
142 142 kcb->kprobe_status = KPROBE_REENTER;
143 143 prepare_singlestep(p, regs, kcb);
144 144 return 1;
arch/x86_64/kernel/kprobes.c
... ... @@ -329,7 +329,7 @@
329 329 */
330 330 save_previous_kprobe(kcb);
331 331 set_current_kprobe(p, regs, kcb);
332   - p->nmissed++;
  332 + kprobes_inc_nmissed_count(p);
333 333 prepare_singlestep(p, regs);
334 334 kcb->kprobe_status = KPROBE_REENTER;
335 335 return 1;
include/linux/kprobes.h
... ... @@ -158,6 +158,7 @@
158 158 extern void show_registers(struct pt_regs *regs);
159 159 extern kprobe_opcode_t *get_insn_slot(void);
160 160 extern void free_insn_slot(kprobe_opcode_t *slot);
  161 +extern void kprobes_inc_nmissed_count(struct kprobe *p);
161 162  
162 163 /* Get the kprobe at this addr (if any) - called with preemption disabled */
163 164 struct kprobe *get_kprobe(void *addr);
... ... @@ -246,6 +246,19 @@
246 246 return ret;
247 247 }
248 248  
  249 +/* Walks the list and increments nmissed count for multiprobe case */
  250 +void __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 262 /* Called with kretprobe_lock held */
250 263 struct kretprobe_instance __kprobes *get_free_rp_inst(struct kretprobe *rp)
251 264 {