Changeset View
Changeset View
Standalone View
Standalone View
sys/cddl/dev/kinst/kinst.c
Show First 20 Lines • Show All 59 Lines • ▼ Show 20 Lines | static struct cdevsw kinst_cdevsw = { | ||||
.d_close = kinst_close, | .d_close = kinst_close, | ||||
.d_ioctl = kinst_ioctl, | .d_ioctl = kinst_ioctl, | ||||
}; | }; | ||||
static dtrace_provider_id_t kinst_id; | static dtrace_provider_id_t kinst_id; | ||||
struct kinst_probe_list *kinst_probetab; | struct kinst_probe_list *kinst_probetab; | ||||
static struct cdev *kinst_cdev; | static struct cdev *kinst_cdev; | ||||
int | |||||
kinst_excluded(const char *name) | |||||
{ | |||||
if (strncmp(name, "dtrace_", strlen("dtrace_")) == 0 && | |||||
strncmp(name, "dtrace_safe_", strlen("dtrace_safe_")) != 0) { | |||||
/* | |||||
* Anything beginning with "dtrace_" may be called | |||||
* from probe context unless it explicitly indicates | |||||
* that it won't be called from probe context by | |||||
* using the prefix "dtrace_safe_". | |||||
*/ | |||||
return (1); | |||||
} | |||||
/* | |||||
* Do not allow instrumentation of exception handlers. | |||||
*/ | |||||
#ifdef __amd64__ | |||||
/* Xfast_syscall* are safe to trace. */ | |||||
if (strcmp(name, "Xdiv") == 0 || | |||||
markj: This is handled by the push rbp check. Only amd64 has that check currently, but I think riscv… | |||||
strcmp(name, "Xdbg") == 0 || | |||||
strcmp(name, "Xnmi") == 0 || | |||||
strcmp(name, "Xbpt") == 0 || | |||||
strcmp(name, "Xofl") == 0 || | |||||
strcmp(name, "Xbnd") == 0 || | |||||
strcmp(name, "Xill") == 0 || | |||||
strcmp(name, "Xdna") == 0 || | |||||
strcmp(name, "Xfpusegm") == 0 || | |||||
strcmp(name, "Xtss") == 0 || | |||||
strcmp(name, "Xmissing") == 0 || | |||||
strcmp(name, "Xstk") == 0 || | |||||
strcmp(name, "Xprot") == 0 || | |||||
strcmp(name, "Xpage") == 0 || | |||||
strcmp(name, "Xmchk") == 0 || | |||||
strcmp(name, "Xrsvd") == 0 || | |||||
strcmp(name, "Xfpu") == 0 || | |||||
strcmp(name, "Xalign") == 0 || | |||||
strcmp(name, "Xxmm") == 0 || | |||||
strcmp(name, "Xdblfault") == 0 || | |||||
strcmp(name, "Xdiv_pti") == 0 || | |||||
strcmp(name, "Xbpt_pti") == 0 || | |||||
strcmp(name, "Xofl_pti") == 0 || | |||||
strcmp(name, "Xbnd_pti") == 0 || | |||||
strcmp(name, "Xill_pti") == 0 || | |||||
strcmp(name, "Xdna_pti") == 0 || | |||||
strcmp(name, "Xfpusegm_pti") == 0 || | |||||
strcmp(name, "Xtss_pti") == 0 || | |||||
strcmp(name, "Xmissing_pti") == 0 || | |||||
strcmp(name, "Xstk_pti") == 0 || | |||||
strcmp(name, "Xprot_pti") == 0 || | |||||
strcmp(name, "Xpage_pti") == 0 || | |||||
strcmp(name, "Xrsvd_pti") == 0 || | |||||
strcmp(name, "Xfpu_pti") == 0 || | |||||
strcmp(name, "Xalign_pti") == 0 || | |||||
strcmp(name, "Xxmm_pti") == 0 || | |||||
strcmp(name, "Xdtrace_ret") == 0 || | |||||
strcmp(name, "Xdtrace_ret_pti") == 0 || | |||||
strcmp(name, "Xxen_intr_upcall") == 0 || | |||||
strcmp(name, "Xxen_intr_upcall_pti") == 0) | |||||
return (1); | |||||
#endif /* __amd64__ */ | |||||
/* | |||||
* Omit instrumentation of functions that are probably in DDB. It | |||||
* makes it too hard to debug broken kinst. | |||||
* | |||||
* NB: kdb_enter() can be excluded, but its call to printf() can't be. | |||||
* This is generally OK since we're not yet in debugging context. | |||||
*/ | |||||
if (strncmp(name, "db_", strlen("db_")) == 0 || | |||||
strncmp(name, "kdb_", strlen("kdb_")) == 0) | |||||
return (1); | |||||
/* | |||||
* Lock owner methods may be called from probe context. | |||||
*/ | |||||
if (strcmp(name, "owner_mtx") == 0 || | |||||
strcmp(name, "owner_rm") == 0 || | |||||
strcmp(name, "owner_rw") == 0 || | |||||
strcmp(name, "owner_sx") == 0) | |||||
return (1); | |||||
/* | |||||
* Stack unwinders may be called from probe context on some | |||||
* platforms. | |||||
*/ | |||||
#if defined(__aarch64__) || defined(__riscv) | |||||
if (strcmp(name, "unwind_frame") == 0) | |||||
return (1); | |||||
#endif | |||||
/* | |||||
* When DTrace is built into the kernel we need to exclude the kinst | |||||
* functions from instrumentation. | |||||
*/ | |||||
#ifndef _KLD_MODULE | |||||
if (strncmp(name, "kinst_", strlen("kinst_")) == 0) | |||||
return (1); | |||||
#endif | |||||
if (strcmp(name, "trap_check") == 0) | |||||
return (1); | |||||
return (0); | |||||
} | |||||
void | void | ||||
kinst_probe_create(struct kinst_probe *kp, linker_file_t lf) | kinst_probe_create(struct kinst_probe *kp, linker_file_t lf) | ||||
{ | { | ||||
kp->kp_id = dtrace_probe_create(kinst_id, lf->filename, | kp->kp_id = dtrace_probe_create(kinst_id, lf->filename, | ||||
kp->kp_func, kp->kp_name, 3, kp); | kp->kp_func, kp->kp_name, 3, kp); | ||||
LIST_INSERT_HEAD(KINST_GETPROBE(kp->kp_patchpoint), kp, kp_hashnext); | LIST_INSERT_HEAD(KINST_GETPROBE(kp->kp_patchpoint), kp, kp_hashnext); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 170 Lines • Show Last 20 Lines |
This is handled by the push rbp check. Only amd64 has that check currently, but I think riscv should perform that as well, see my comments in that review.