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));
    }
}
Example #3
0
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));
   }
}
Example #4
0
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;
}