/*ARGSUSED*/ static int sdt_enable(void *arg, dtrace_id_t id, void *parg) { sdt_probe_t *sdp = parg; # if defined(sun) ctl->mod_nenabled++; {struct modctl *ctl = sdp->sdp_ctl; /* * If this module has disappeared since we discovered its probes, * refuse to enable it. */ if (!ctl->mod_loaded) { if (sdt_verbose) { cmn_err(CE_NOTE, "sdt is failing for probe %s " "(module %s unloaded)", sdp->sdp_name, ctl->mod_modname); } return 0; } /* * Now check that our modctl has the expected load count. If it * doesn't, this module must have been unloaded and reloaded -- and * we're not going to touch it. */ if (ctl->mod_loadcnt != sdp->sdp_loadcnt) { if (sdt_verbose) { cmn_err(CE_NOTE, "sdt is failing for probe %s " "(module %s reloaded)", sdp->sdp_name, ctl->mod_modname); } return 0; } } # endif while (sdp != NULL) { /***********************************************/ /* Kernel code wil be write protected, so */ /* try and unprotect it. */ /***********************************************/ sdp->sdp_enabled = TRUE; if (memory_set_rw(sdp->sdp_patchpoint, 1, TRUE)) *sdp->sdp_patchpoint = sdp->sdp_patchval; sdp = sdp->sdp_next; } return 0; }
/*ARGSUSED*/ static int fbt_enable(void *arg, dtrace_id_t id, void *parg) { fbt_probe_t *fbt = parg; struct modctl *ctl = fbt->fbtp_ctl; struct module *mp = (struct module *) ctl; # if 0 ctl->mod_nenabled++; # endif if (mp->state != MODULE_STATE_LIVE) { if (fbt_verbose) { cmn_err(CE_NOTE, "fbt is failing for probe %s " "(module %s unloaded)", fbt->fbtp_name, mp->name); } return 0; } /* * Now check that our modctl has the expected load count. If it * doesn't, this module must have been unloaded and reloaded -- and * we're not going to touch it. */ if (get_refcount(mp) != fbt->fbtp_loadcnt) { if (fbt_verbose) { cmn_err(CE_NOTE, "fbt is failing for probe %s " "(module %s reloaded)", fbt->fbtp_name, mp->name); } return 0; } for (; fbt != NULL; fbt = fbt->fbtp_next) { fbt->fbtp_enabled = TRUE; if (dtrace_here) printk("fbt_enable:patch %p p:%02x %s\n", fbt->fbtp_patchpoint, fbt->fbtp_patchval, fbt->fbtp_name); if (memory_set_rw(fbt->fbtp_patchpoint, 1, TRUE)) { *fbt->fbtp_patchpoint = fbt->fbtp_patchval; //printk("FBT: set pp=%p:%p\n", fbt->fbtp_patchpoint, *fbt->fbtp_patchpoint); } } return 0; }
/*ARGSUSED*/ static void fbt_disable(void *arg, dtrace_id_t id, void *parg) { fbt_probe_t *fbt = parg; struct modctl *ctl = fbt->fbtp_ctl; struct module *mp = (struct module *) ctl; # if 0 ASSERT(ctl->mod_nenabled > 0); ctl->mod_nenabled--; if (!ctl->mod_loaded || (ctl->mod_loadcnt != fbt->fbtp_loadcnt)) return; # else if (mp->state != MODULE_STATE_LIVE || get_refcount(mp) != fbt->fbtp_loadcnt) return; # endif for (; fbt != NULL; fbt = fbt->fbtp_next) { if (dtrace_here) { printk("%s:%d: Disable %p:%s:%s\n", __func__, __LINE__, fbt->fbtp_patchpoint, fbt->fbtp_ctl->name, fbt->fbtp_name); } /***********************************************/ /* Memory should be writable, but if we */ /* failed in the fbt_enable code, e.g. */ /* because kernel freed an .init section, */ /* then dont try and unpatch something we */ /* didnt patch. */ /* We were trying to be clever and ensure */ /* memory is writable but this seems to GPF */ /* on us. Might be a temporary issue as I */ /* fiddle with other things tho. */ /***********************************************/ if (*fbt->fbtp_patchpoint == fbt->fbtp_patchval) { if (1 || memory_set_rw(fbt->fbtp_patchpoint, 1, TRUE)) *fbt->fbtp_patchpoint = fbt->fbtp_savedval; } } }
/*ARGSUSED*/ static void instr_disable(void *arg, dtrace_id_t id, void *parg) { instr_probe_t *fbt = parg; struct modctl *ctl = fbt->insp_ctl; struct module *mp = (struct module *) ctl; # if 0 ASSERT(ctl->mod_nenabled > 0); ctl->mod_nenabled--; if (!ctl->mod_loaded || (ctl->mod_loadcnt != fbt->insp_loadcnt)) return; # else if (mp->state != MODULE_STATE_LIVE || get_refcount(mp) != fbt->insp_loadcnt) return; # endif for (; fbt != NULL; fbt = fbt->insp_next) { if (dtrace_here) { printk("%s:%d: Disable %p:%s:%s\n", __func__, __LINE__, fbt->insp_patchpoint, fbt->insp_ctl->name, fbt->insp_name); } /***********************************************/ /* Memory should be writable, but if we */ /* failed in the instr_enable code, e.g. */ /* because kernel freed an .init section, */ /* then dont try and unpatch something we */ /* didnt patch. */ /***********************************************/ if (*fbt->insp_patchpoint == fbt->insp_patchval) { if (memory_set_rw(fbt->insp_patchpoint, 1, TRUE)) *fbt->insp_patchpoint = fbt->insp_savedval; } } }