/*ARGSUSED*/ static void fbt_suspend(void *arg, dtrace_id_t id, void *parg) { #pragma unused(arg,id) fbt_probe_t *fbt = parg; struct modctl *ctl = NULL; for (; fbt != NULL; fbt = fbt->fbtp_next) { ctl = fbt->fbtp_ctl; ASSERT(ctl->mod_nenabled > 0); if (!ctl->mod_loaded || (ctl->mod_loadcnt != fbt->fbtp_loadcnt)) continue; (void)ml_nofault_copy( (vm_offset_t)&fbt->fbtp_savedval, (vm_offset_t)fbt->fbtp_patchpoint, sizeof(fbt->fbtp_savedval)); /* * Make the patched instruction visible via a data + instruction * cache flush for the platforms that need it */ flush_dcache((vm_offset_t)fbt->fbtp_patchpoint,(vm_size_t)sizeof(fbt->fbtp_savedval), 0); invalidate_icache((vm_offset_t)fbt->fbtp_patchpoint,(vm_size_t)sizeof(fbt->fbtp_savedval), 0); fbt->fbtp_currentval = fbt->fbtp_savedval; } dtrace_membar_consumer(); }
/*ARGSUSED*/ static void fbt_resume(void *arg, dtrace_id_t id, void *parg) { #pragma unused(arg,id) fbt_probe_t *fbt = parg; struct modctl *ctl = fbt->fbtp_ctl; #if defined (__ppc__) || defined (__ppc64__) dtrace_casptr(&tempDTraceIntHook, NULL, fbt_perfIntCallback); if (tempDTraceIntHook != (perfCallback)fbt_perfIntCallback) { if (fbt_verbose) { cmn_err(CE_NOTE, "fbt_enable is failing for probe %s " "in module %s: tempDTraceIntHook already occupied.", fbt->fbtp_name, ctl->mod_modname); } return; } #endif dtrace_casptr(&tempDTraceTrapHook, NULL, fbt_perfCallback); if (tempDTraceTrapHook != (perfCallback)fbt_perfCallback) { if (fbt_verbose) { cmn_err(CE_NOTE, "fbt_resume is failing for probe %s " "in module %s: tempDTraceTrapHook already occupied.", fbt->fbtp_name, ctl->mod_modname); } return; } for (; fbt != NULL; fbt = fbt->fbtp_next) (void)ml_nofault_copy( (vm_offset_t)&fbt->fbtp_patchval, (vm_offset_t)fbt->fbtp_patchpoint, sizeof(fbt->fbtp_patchval)); dtrace_membar_consumer(); }
/*ARGSUSED*/ static void fbt_suspend(void *arg, dtrace_id_t id, void *parg) { #pragma unused(arg,id) fbt_probe_t *fbt = parg; for (; fbt != NULL; fbt = fbt->fbtp_next) (void)ml_nofault_copy( (vm_offset_t)&fbt->fbtp_savedval, (vm_offset_t)fbt->fbtp_patchpoint, sizeof(fbt->fbtp_savedval)); dtrace_membar_consumer(); }
/*ARGSUSED*/ static void fbt_resume(void *arg, dtrace_id_t id, void *parg) { #pragma unused(arg,id) fbt_probe_t *fbt = parg; struct modctl *ctl = NULL; for (; fbt != NULL; fbt = fbt->fbtp_next) { ctl = fbt->fbtp_ctl; ASSERT(ctl->mod_nenabled > 0); if (!ctl->mod_loaded || (ctl->mod_loadcnt != fbt->fbtp_loadcnt)) continue; dtrace_casptr(&tempDTraceTrapHook, NULL, fbt_perfCallback); if (tempDTraceTrapHook != (perfCallback)fbt_perfCallback) { if (fbt_verbose) { cmn_err(CE_NOTE, "fbt_resume is failing for probe %s " "in module %s: tempDTraceTrapHook already occupied.", fbt->fbtp_name, ctl->mod_modname); } return; } (void)ml_nofault_copy( (vm_offset_t)&fbt->fbtp_patchval, (vm_offset_t)fbt->fbtp_patchpoint, sizeof(fbt->fbtp_patchval)); #if CONFIG_EMBEDDED /* * Make the patched instruction visible via a data + instruction cache flush. */ flush_dcache((vm_offset_t)fbt->fbtp_patchpoint,(vm_size_t)sizeof(fbt->fbtp_patchval), 0); invalidate_icache((vm_offset_t)fbt->fbtp_patchpoint,(vm_size_t)sizeof(fbt->fbtp_patchval), 0); #endif fbt->fbtp_currentval = fbt->fbtp_patchval; } dtrace_membar_consumer(); }
/*ARGSUSED*/ int fbt_enable(void *arg, dtrace_id_t id, void *parg) { #pragma unused(arg,id) fbt_probe_t *fbt = parg; struct modctl *ctl = NULL; for (; fbt != NULL; fbt = fbt->fbtp_next) { ctl = fbt->fbtp_ctl; if (!ctl->mod_loaded) { if (fbt_verbose) { cmn_err(CE_NOTE, "fbt is failing for probe %s " "(module %s unloaded)", fbt->fbtp_name, ctl->mod_modname); } continue; } /* * 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 != fbt->fbtp_loadcnt) { if (fbt_verbose) { cmn_err(CE_NOTE, "fbt is failing for probe %s " "(module %s reloaded)", fbt->fbtp_name, ctl->mod_modname); } continue; } dtrace_casptr(&tempDTraceTrapHook, NULL, fbt_perfCallback); if (tempDTraceTrapHook != (perfCallback)fbt_perfCallback) { if (fbt_verbose) { cmn_err(CE_NOTE, "fbt_enable is failing for probe %s " "in module %s: tempDTraceTrapHook already occupied.", fbt->fbtp_name, ctl->mod_modname); } continue; } if (fbt->fbtp_currentval != fbt->fbtp_patchval) { (void)ml_nofault_copy( (vm_offset_t)&fbt->fbtp_patchval, (vm_offset_t)fbt->fbtp_patchpoint, sizeof(fbt->fbtp_patchval)); /* * Make the patched instruction visible via a data + instruction * cache flush for the platforms that need it */ flush_dcache((vm_offset_t)fbt->fbtp_patchpoint,(vm_size_t)sizeof(fbt->fbtp_patchval), 0); invalidate_icache((vm_offset_t)fbt->fbtp_patchpoint,(vm_size_t)sizeof(fbt->fbtp_patchval), 0); fbt->fbtp_currentval = fbt->fbtp_patchval; ctl->mod_nenabled++; } } dtrace_membar_consumer(); return (0); }