static int stapkp_arch_register_kprobe(struct stap_kprobe_probe *skp) { int ret = 0; struct kprobe *kp = &skp->kprobe->u.kp; #ifndef __ia64__ ret = register_kprobe(kp); if (ret == 0) { if (skp->symbol_name) dbug_stapkp("+kprobe %s+%u\n", kp->symbol_name, kp->offset); else dbug_stapkp("+kprobe %p\n", kp->addr); } #else // PR6028 ret = register_kprobe(&skp->kprobe->dummy); if (ret == 0) { ret = register_kprobe(kp); if (ret != 0) unregister_kprobe(&skp->kprobe->dummy); } dbug_stapkp_cond(ret == 0, "+kprobe %p\n", skp->kprobe->dummy.addr); dbug_stapkp_cond(ret == 0, "+kprobe %p\n", kp->addr); #endif skp->registered_p = (ret ? 0 : 1); return ret; }
static void stapkp_batch_unregister_probes(struct stap_kprobe_probe *probes, size_t nprobes) { size_t i, n; n = stapkp_collect_registered_probes(probes, nprobes, COLLECT_KPROBES); unregister_kprobes((struct kprobe **)stap_unreg_kprobes, n); dbug_stapkp_cond(n > 0, "-kprobe * %zd\n", n); n = stapkp_collect_registered_probes(probes, nprobes, COLLECT_KRETPROBES); unregister_kretprobes((struct kretprobe **)stap_unreg_kprobes, n); dbug_stapkp_cond(n > 0, "-kretprobe * %zd\n", n); #ifdef __ia64__ n = stapkp_collect_registered_probes(probes, nprobes, COLLECT_DUMMYS); unregister_kprobes((struct kprobe **)stap_unreg_kprobes, n); dbug_stapkp_cond(n > 0, "-kprobe * %zd\n", n); #endif // Now for all of those we just unregistered, we need to update registered_p // and account for (and possibly report) missed hits. for (i = 0; i < nprobes; i++) { struct stap_kprobe_probe *skp = &probes[i]; if (!skp->registered_p) continue; skp->registered_p = 0; stapkp_add_missed(skp); #if LINUX_VERSION_CODE < KERNEL_VERSION(3,11,0) if (skp->symbol_name != NULL) { if (skp->return_p) { if (skp->kprobe->u.krp.kp.symbol_name != NULL) kfree(skp->kprobe->u.krp.kp.symbol_name); } else { if (skp->kprobe->u.kp.symbol_name != NULL) kfree(skp->kprobe->u.kp.symbol_name); } } #endif // PR16861: kprobes may have left some things in the k[ret]probe struct. // Let's reset it to be sure it's safe for re-use. memset(skp->kprobe, 0, sizeof(struct stap_kprobe)); } }
static void stapkp_batch_unregister_probes(struct stap_dwarf_probe *probes, size_t nprobes) { size_t i, n; n = stapkp_collect_registered_probes(probes, nprobes, COLLECT_KPROBES); unregister_kprobes((struct kprobe **)stap_unreg_kprobes, n); dbug_stapkp_cond(n > 0, "-kprobe * %zd\n", n); n = stapkp_collect_registered_probes(probes, nprobes, COLLECT_KRETPROBES); unregister_kretprobes((struct kretprobe **)stap_unreg_kprobes, n); dbug_stapkp_cond(n > 0, "-kretprobe * %zd\n", n); #ifdef __ia64__ n = stapkp_collect_registered_probes(probes, nprobes, COLLECT_DUMMYS); unregister_kprobes((struct kprobe **)stap_unreg_kprobes, n); dbug_stapkp_cond(n > 0, "-kprobe * %zd\n", n); #endif // Now for all of those we just unregistered, we need to update registered_p // and account for (and possibly report) missed hits. for (i = 0; i < nprobes; i++) { struct stap_dwarf_probe *sdp = &probes[i]; if (!sdp->registered_p) continue; sdp->registered_p = 0; stapkp_add_missed(sdp); // PR16861: kprobes may have left some things in the k[ret]probe struct. // Let's reset it to be sure it's safe for re-use. memset(sdp->kprobe, 0, sizeof(struct stap_dwarf_kprobe)); } }
static int stapkp_arch_register_kretprobe(struct stap_dwarf_probe *sdp) { int ret = 0; struct kretprobe *krp = &sdp->kprobe->u.krp; #ifndef __ia64__ ret = register_kretprobe(krp); dbug_stapkp_cond(ret == 0, "+kretprobe %p\n", krp->kp.addr); #else // PR6028 ret = register_kprobe(&sdp->kprobe->dummy); if (ret == 0) { ret = register_kretprobe(krp); if (ret != 0) unregister_kprobe(&sdp->kprobe->dummy); } dbug_stapkp_cond(ret == 0, "+kprobe %p\n", sdp->kprobe->dummy.addr); dbug_stapkp_cond(ret == 0, "+kretprobe %p\n", krp->kp.addr); #endif sdp->registered_p = (ret ? 0 : 1); return ret; }