Date: Fri, 28 Mar 2008 02:38:23 GMT From: John Birrell <jb@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 138787 for review Message-ID: <200803280238.m2S2cNTo010245@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=138787 Change 138787 by jb@jb_freebsd1 on 2008/03/28 02:38:01 Yes more merges int the moved files. Affected files ... .. //depot/projects/dtrace/src/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c#2 edit .. //depot/projects/dtrace/src/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c#2 edit .. //depot/projects/dtrace/src/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c#2 edit .. //depot/projects/dtrace/src/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c#2 edit .. //depot/projects/dtrace/src/sys/cddl/contrib/opensolaris/uts/common/sys/ctf.h#2 edit .. //depot/projects/dtrace/src/sys/cddl/contrib/opensolaris/uts/common/sys/ctf_api.h#2 edit .. //depot/projects/dtrace/src/sys/cddl/contrib/opensolaris/uts/common/sys/debug.h#2 edit .. //depot/projects/dtrace/src/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h#2 edit .. //depot/projects/dtrace/src/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace_impl.h#2 edit .. //depot/projects/dtrace/src/sys/cddl/contrib/opensolaris/uts/common/sys/isa_defs.h#3 edit Differences ... ==== //depot/projects/dtrace/src/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c#2 (text) ==== @@ -66,34 +66,66 @@ * on capital-f functions. */ #include <sys/errno.h> +#if !defined(sun) +#include <sys/time.h> +#endif #include <sys/stat.h> #include <sys/modctl.h> #include <sys/conf.h> #include <sys/systm.h> +#if defined(sun) #include <sys/ddi.h> #include <sys/sunddi.h> +#endif #include <sys/cpuvar.h> #include <sys/kmem.h> +#if defined(sun) #include <sys/strsubr.h> +#endif #include <sys/sysmacros.h> #include <sys/dtrace_impl.h> #include <sys/atomic.h> #include <sys/cmn_err.h> +#if defined(sun) #include <sys/mutex_impl.h> #include <sys/rwlock_impl.h> +#endif #include <sys/ctf_api.h> +#if defined(sun) #include <sys/panic.h> #include <sys/priv_impl.h> +#endif #include <sys/policy.h> +#if defined(sun) #include <sys/cred_impl.h> #include <sys/procfs_isa.h> +#endif #include <sys/taskq.h> +#if defined(sun) #include <sys/mkdev.h> #include <sys/kdi.h> +#endif #include <sys/zone.h> #include <sys/socket.h> #include <netinet/in.h> +/* FreeBSD includes: */ +#if !defined(sun) +#include <sys/ctype.h> +#include <sys/limits.h> +#include <sys/kdb.h> +#include <sys/kernel.h> +#include <sys/malloc.h> +#include <sys/sysctl.h> +#include <sys/lock.h> +#include <sys/mutex.h> +#include <sys/sx.h> +#include <sys/dtrace_bsd.h> +#include <netinet/in.h> +#include "dtrace_cddl.h" +#include "dtrace_debug.c" +#endif + /* * DTrace Tunable Variables * @@ -161,17 +193,25 @@ /* * DTrace Internal Variables */ +#if defined(sun) static dev_info_t *dtrace_devi; /* device info */ +#endif +#if defined(sun) static vmem_t *dtrace_arena; /* probe ID arena */ static vmem_t *dtrace_minor; /* minor number arena */ static taskq_t *dtrace_taskq; /* task queue */ +#else +static struct unrhdr *dtrace_arena; /* Probe ID number. */ +#endif static dtrace_probe_t **dtrace_probes; /* array of all probes */ static int dtrace_nprobes; /* number of probes */ static dtrace_provider_t *dtrace_provider; /* provider list */ static dtrace_meta_t *dtrace_meta_pid; /* user-land meta provider */ static int dtrace_opens; /* number of opens */ static int dtrace_helpers; /* number of helpers */ +#if defined(sun) static void *dtrace_softstate; /* softstate pointer */ +#endif static dtrace_hash_t *dtrace_bymod; /* probes hashed by module */ static dtrace_hash_t *dtrace_byfunc; /* probes hashed by function */ static dtrace_hash_t *dtrace_byname; /* probes hashed by name */ @@ -187,6 +227,14 @@ static dtrace_helpers_t *dtrace_deferred_pid; /* deferred helper list */ static dtrace_enabling_t *dtrace_retained; /* list of retained enablings */ static dtrace_dynvar_t dtrace_dynhash_sink; /* end of dynamic hash chains */ +#if !defined(sun) +static struct mtx dtrace_unr_mtx; +MTX_SYSINIT(dtrace_unr_mtx, &dtrace_unr_mtx, "Unique resource identifier", MTX_DEF); +int dtrace_in_probe; /* non-zero if executing a probe */ +#if defined(__i386__) || defined(__amd64__) +uintptr_t dtrace_in_probe_addr; /* Address of invop when already in probe */ +#endif +#endif /* * DTrace Locking @@ -222,6 +270,37 @@ static kmutex_t dtrace_provider_lock; /* provider state lock */ static kmutex_t dtrace_meta_lock; /* meta-provider state lock */ +#if !defined(sun) +/* XXX FreeBSD hacks. */ +static kmutex_t mod_lock; + +#define cr_suid cr_svuid +#define cr_sgid cr_svgid +#define ipaddr_t in_addr_t +#define mod_modname pathname +#define vuprintf vprintf +#define ttoproc(_a) ((_a)->td_proc) +#define crgetzoneid(_a) 0 +#define NCPU MAXCPU +#define SNOCD 0 +#define CPU_ON_INTR(_a) 0 + +#define PRIV_EFFECTIVE (1 << 0) +#define PRIV_DTRACE_KERNEL (1 << 1) +#define PRIV_DTRACE_PROC (1 << 2) +#define PRIV_DTRACE_USER (1 << 3) +#define PRIV_PROC_OWNER (1 << 4) +#define PRIV_PROC_ZONE (1 << 5) +#define PRIV_ALL ~0 + +SYSCTL_NODE(_debug, OID_AUTO, dtrace, CTLFLAG_RD, 0, "DTrace Information"); +#endif + +#if defined(sun) +#define curcpu CPU->cpu_id +#endif + + /* * DTrace Provider Variables * @@ -241,8 +320,8 @@ {} static dtrace_pops_t dtrace_provider_ops = { - (void (*)(void *, const dtrace_probedesc_t *))dtrace_nullop, - (void (*)(void *, struct modctl *))dtrace_nullop, + (void (*)(void *, dtrace_probedesc_t *))dtrace_nullop, + (void (*)(void *, modctl_t *))dtrace_nullop, (void (*)(void *, dtrace_id_t, void *))dtrace_nullop, (void (*)(void *, dtrace_id_t, void *))dtrace_nullop, (void (*)(void *, dtrace_id_t, void *))dtrace_nullop, @@ -327,6 +406,7 @@ * no way for a global variable key signature to match a thread-local key * signature. */ +#if defined(sun) #define DTRACE_TLS_THRKEY(where) { \ uint_t intr = 0; \ uint_t actv = CPU->cpu_intr_actv >> (LOCK_LEVEL + 1); \ @@ -336,6 +416,18 @@ (where) = ((curthread->t_did + DIF_VARIABLE_MAX) & \ (((uint64_t)1 << 61) - 1)) | ((uint64_t)intr << 61); \ } +#else +#define DTRACE_TLS_THRKEY(where) { \ + solaris_cpu_t *_c = &solaris_cpu[curcpu]; \ + uint_t intr = 0; \ + uint_t actv = _c->cpu_intr_actv; \ + for (; actv; actv >>= 1) \ + intr++; \ + ASSERT(intr < (1 << 3)); \ + (where) = ((curthread->td_tid + DIF_VARIABLE_MAX) & \ + (((uint64_t)1 << 61) - 1)) | ((uint64_t)intr << 61); \ +} +#endif #define DT_BSWAP_8(x) ((x) & 0xff) #define DT_BSWAP_16(x) ((DT_BSWAP_8(x) << 8) | DT_BSWAP_8((x) >> 8)) @@ -351,7 +443,7 @@ #define DTRACE_ALIGNCHECK(addr, size, flags) \ if (addr & (size - 1)) { \ *flags |= CPU_DTRACE_BADALIGN; \ - cpu_core[CPU->cpu_id].cpuc_dtrace_illval = addr; \ + cpu_core[curcpu].cpuc_dtrace_illval = addr; \ return (0); \ } #else @@ -390,7 +482,7 @@ uint##bits##_t rval; \ int i; \ volatile uint16_t *flags = (volatile uint16_t *) \ - &cpu_core[CPU->cpu_id].cpuc_dtrace_flags; \ + &cpu_core[curcpu].cpuc_dtrace_flags; \ \ DTRACE_ALIGNCHECK(addr, size, flags); \ \ @@ -405,7 +497,7 @@ * This address falls within a toxic region; return 0. \ */ \ *flags |= CPU_DTRACE_BADADDR; \ - cpu_core[CPU->cpu_id].cpuc_dtrace_illval = addr; \ + cpu_core[curcpu].cpuc_dtrace_illval = addr; \ return (0); \ } \ \ @@ -448,22 +540,35 @@ ((act)->dta_kind == DTRACEACT_DIFEXPR && \ (act)->dta_difo->dtdo_rtype.dtdt_kind == DIF_TYPE_STRING) +/* Function prototype definitions: */ static size_t dtrace_strlen(const char *, size_t); static dtrace_probe_t *dtrace_probe_lookup_id(dtrace_id_t id); static void dtrace_enabling_provide(dtrace_provider_t *); static int dtrace_enabling_match(dtrace_enabling_t *, int *); static void dtrace_enabling_matchall(void); static dtrace_state_t *dtrace_anon_grab(void); +#if defined(sun) static uint64_t dtrace_helper(int, dtrace_mstate_t *, dtrace_state_t *, uint64_t, uint64_t); static dtrace_helpers_t *dtrace_helpers_create(proc_t *); +#endif static void dtrace_buffer_drop(dtrace_buffer_t *); static intptr_t dtrace_buffer_reserve(dtrace_buffer_t *, size_t, size_t, dtrace_state_t *, dtrace_mstate_t *); static int dtrace_state_option(dtrace_state_t *, dtrace_optid_t, dtrace_optval_t); static int dtrace_ecb_create_enable(dtrace_probe_t *, void *); +#if defined(sun) static void dtrace_helper_provider_destroy(dtrace_helper_provider_t *); +#endif +uint16_t dtrace_load16(uintptr_t); +uint32_t dtrace_load32(uintptr_t); +uint64_t dtrace_load64(uintptr_t); +uint8_t dtrace_load8(uintptr_t); +void dtrace_dynvar_clean(dtrace_dstate_t *); +dtrace_dynvar_t *dtrace_dynvar(dtrace_dstate_t *, uint_t, dtrace_key_t *, + size_t, dtrace_dynvar_op_t, dtrace_mstate_t *, dtrace_vstate_t *); +uintptr_t dtrace_dif_varstr(uintptr_t, dtrace_state_t *, dtrace_mstate_t *); /* * DTrace Probe Context Functions @@ -674,7 +779,7 @@ dtrace_canload(uint64_t addr, size_t sz, dtrace_mstate_t *mstate, dtrace_vstate_t *vstate) { - volatile uintptr_t *illval = &cpu_core[CPU->cpu_id].cpuc_dtrace_illval; + volatile uintptr_t *illval = &cpu_core[curcpu].cpuc_dtrace_illval; /* * If we hold the privilege to read from kernel memory, then @@ -766,7 +871,7 @@ if (s1 == s2 || limit == 0) return (0); - flags = (volatile uint16_t *)&cpu_core[CPU->cpu_id].cpuc_dtrace_flags; + flags = (volatile uint16_t *)&cpu_core[curcpu].cpuc_dtrace_flags; do { if (s1 == NULL) { @@ -820,13 +925,13 @@ if (kaddr - taddr < tsize) { DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR); - cpu_core[CPU->cpu_id].cpuc_dtrace_illval = kaddr; + cpu_core[curcpu].cpuc_dtrace_illval = kaddr; return (1); } if (taddr - kaddr < size) { DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR); - cpu_core[CPU->cpu_id].cpuc_dtrace_illval = taddr; + cpu_core[curcpu].cpuc_dtrace_illval = taddr; return (1); } } @@ -910,7 +1015,7 @@ { volatile uint16_t *flags; - flags = (volatile uint16_t *)&cpu_core[CPU->cpu_id].cpuc_dtrace_flags; + flags = (volatile uint16_t *)&cpu_core[curcpu].cpuc_dtrace_flags; if (s1 == s2) return (0); @@ -1066,6 +1171,7 @@ static int dtrace_priv_proc_common_zone(dtrace_state_t *state) { +#if defined(sun) cred_t *cr, *s_cr = state->dts_cred.dcr_cred; /* @@ -1079,6 +1185,9 @@ return (1); return (0); +#else + return (1); +#endif } /* @@ -1086,7 +1195,7 @@ * verify that the process has not setuid or changed credentials. */ static int -dtrace_priv_proc_common_nocd() +dtrace_priv_proc_common_nocd(void) { proc_t *proc; @@ -1117,7 +1226,7 @@ return (1); bad: - cpu_core[CPU->cpu_id].cpuc_dtrace_flags |= CPU_DTRACE_UPRIV; + cpu_core[curcpu].cpuc_dtrace_flags |= CPU_DTRACE_UPRIV; return (0); } @@ -1133,7 +1242,7 @@ dtrace_priv_proc_common_nocd()) return (1); - cpu_core[CPU->cpu_id].cpuc_dtrace_flags |= CPU_DTRACE_UPRIV; + cpu_core[curcpu].cpuc_dtrace_flags |= CPU_DTRACE_UPRIV; return (0); } @@ -1144,7 +1253,7 @@ if (state->dts_cred.dcr_action & DTRACE_CRA_PROC) return (1); - cpu_core[CPU->cpu_id].cpuc_dtrace_flags |= CPU_DTRACE_UPRIV; + cpu_core[curcpu].cpuc_dtrace_flags |= CPU_DTRACE_UPRIV; return (0); } @@ -1155,7 +1264,7 @@ if (state->dts_cred.dcr_action & DTRACE_CRA_KERNEL) return (1); - cpu_core[CPU->cpu_id].cpuc_dtrace_flags |= CPU_DTRACE_KPRIV; + cpu_core[curcpu].cpuc_dtrace_flags |= CPU_DTRACE_KPRIV; return (0); } @@ -1166,7 +1275,7 @@ if (state->dts_cred.dcr_action & DTRACE_CRA_KERNEL_DESTRUCTIVE) return (1); - cpu_core[CPU->cpu_id].cpuc_dtrace_flags |= CPU_DTRACE_KPRIV; + cpu_core[curcpu].cpuc_dtrace_flags |= CPU_DTRACE_KPRIV; return (0); } @@ -1277,7 +1386,7 @@ uint64_t hashval = DTRACE_DYNHASH_VALID; dtrace_dynhash_t *hash = dstate->dtds_hash; dtrace_dynvar_t *free, *new_free, *next, *dvar, *start, *prev = NULL; - processorid_t me = CPU->cpu_id, cpu = me; + processorid_t me = curcpu, cpu = me; dtrace_dstate_percpu_t *dcpu = &dstate->dtds_percpu[me]; size_t bucket, ksize; size_t chunksize = dstate->dtds_chunksize; @@ -1368,8 +1477,8 @@ while ((lock = *lockp) & 1) continue; - if (dtrace_casptr((void *)lockp, - (void *)lock, (void *)(lock + 1)) == (void *)lock) + if (dtrace_casptr((volatile void *)lockp, + (volatile void *)lock, (volatile void *)(lock + 1)) == (void *)lock) break; } @@ -2165,7 +2274,7 @@ dtrace_speculation_t *spec; dtrace_buffer_t *src, *dest; uintptr_t daddr, saddr, dlimit; - dtrace_speculation_state_t current, new; + dtrace_speculation_state_t current, new = 0; intptr_t offs; if (which == 0) @@ -2301,7 +2410,7 @@ dtrace_specid_t which) { dtrace_speculation_t *spec; - dtrace_speculation_state_t current, new; + dtrace_speculation_state_t current, new = 0; dtrace_buffer_t *buf; if (which == 0) @@ -2359,7 +2468,7 @@ dtrace_speculation_clean_here(dtrace_state_t *state) { dtrace_icookie_t cookie; - processorid_t cpu = CPU->cpu_id; + processorid_t cpu = curcpu; dtrace_buffer_t *dest = &state->dts_buffer[cpu]; dtrace_specid_t i; @@ -2463,7 +2572,7 @@ dtrace_specid_t which) { dtrace_speculation_t *spec; - dtrace_speculation_state_t current, new; + dtrace_speculation_state_t current, new = 0; dtrace_buffer_t *buf; if (which == 0) @@ -2556,7 +2665,7 @@ if (mstate->dtms_scratch_ptr + strsz > mstate->dtms_scratch_base + mstate->dtms_scratch_size) { DTRACE_CPUFLAG_SET(CPU_DTRACE_NOSCRATCH); - return (NULL); + return (0); } dtrace_strcpy((const void *)addr, (void *)mstate->dtms_scratch_ptr, @@ -2567,6 +2676,44 @@ } /* + * Return a string from a memoy address which is known to have one or + * more concatenated, individually zero terminated, sub-strings. + * In the event that the user lacks the privilege to access + * arbitrary kernel memory, we copy the string out to scratch memory so that we + * don't fail access checking. + * + * dtrace_dif_variable() uses this routine as a helper for various + * builtin values such as 'execargs'. + */ +static uintptr_t +dtrace_dif_varstrz(uintptr_t addr, size_t strsz, dtrace_state_t *state, + dtrace_mstate_t *mstate) +{ + char *p; + size_t i; + uintptr_t ret; + + if (mstate->dtms_scratch_ptr + strsz > + mstate->dtms_scratch_base + mstate->dtms_scratch_size) { + DTRACE_CPUFLAG_SET(CPU_DTRACE_NOSCRATCH); + return (0); + } + + dtrace_bcopy((const void *)addr, (void *)mstate->dtms_scratch_ptr, + strsz); + + /* Replace sub-string termination characters with a space. */ + for (p = (char *) mstate->dtms_scratch_ptr, i = 0; i < strsz - 1; + p++, i++) + if (*p == '\0') + *p = ' '; + + ret = mstate->dtms_scratch_ptr; + mstate->dtms_scratch_ptr += strsz; + return (ret); +} + +/* * This function implements the DIF emulator's variable lookups. The emulator * passes a reserved variable identifier and optional built-in array index. */ @@ -2617,6 +2764,7 @@ return (mstate->dtms_arg[ndx]); +#if defined(sun) case DIF_VAR_UREGS: { klwp_t *lwp; @@ -2625,12 +2773,14 @@ if ((lwp = curthread->t_lwp) == NULL) { DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR); - cpu_core[CPU->cpu_id].cpuc_dtrace_illval = NULL; + cpu_core[curcpu].cpuc_dtrace_illval = NULL; return (0); } return (dtrace_getreg(lwp->lwp_regs, ndx)); + return (0); } +#endif case DIF_VAR_CURTHREAD: if (!dtrace_priv_kernel(state)) @@ -2655,6 +2805,7 @@ } return (mstate->dtms_walltimestamp); +#if defined(sun) case DIF_VAR_IPL: if (!dtrace_priv_kernel(state)) return (0); @@ -2663,6 +2814,7 @@ mstate->dtms_present |= DTRACE_MSTATE_IPL; } return (mstate->dtms_ipl); +#endif case DIF_VAR_EPID: ASSERT(mstate->dtms_present & DTRACE_MSTATE_EPID); @@ -2683,6 +2835,7 @@ } return (mstate->dtms_stackdepth); +#if defined(sun) case DIF_VAR_USTACKDEPTH: if (!dtrace_priv_proc(state)) return (0); @@ -2702,6 +2855,7 @@ mstate->dtms_present |= DTRACE_MSTATE_USTACKDEPTH; } return (mstate->dtms_ustackdepth); +#endif case DIF_VAR_CALLER: if (!dtrace_priv_kernel(state)) @@ -2716,7 +2870,7 @@ * dtrace_caller() only guarantees correct * results for anchored probes. */ - pc_t caller[2]; + pc_t caller[2] = {0, 0}; dtrace_getpcstack(caller, 2, aframes, (uint32_t *)(uintptr_t)mstate->dtms_arg[0]); @@ -2728,7 +2882,7 @@ * we must resort to the slower approach of * calling dtrace_getpcstack(). */ - pc_t caller; + pc_t caller = 0; dtrace_getpcstack(&caller, 1, aframes, NULL); mstate->dtms_caller = caller; @@ -2738,6 +2892,7 @@ } return (mstate->dtms_caller); +#if defined(sun) case DIF_VAR_UCALLER: if (!dtrace_priv_proc(state)) return (0); @@ -2752,7 +2907,7 @@ * uint64_t will contain the caller, which is what * we're after. */ - ustack[2] = NULL; + ustack[2] = 0; DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT); dtrace_getupcstack(ustack, 3); DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT); @@ -2761,6 +2916,7 @@ } return (mstate->dtms_ucaller); +#endif case DIF_VAR_PROBEPROV: ASSERT(mstate->dtms_present & DTRACE_MSTATE_PROBE); @@ -2790,6 +2946,7 @@ if (!dtrace_priv_proc(state)) return (0); +#if defined(sun) /* * Note that we are assuming that an unanchored probe is * always due to a high-level interrupt. (And we're assuming @@ -2807,11 +2964,15 @@ * they leave that task to whomever reaps them.) */ return ((uint64_t)curthread->t_procp->p_pidp->pid_id); +#else + return ((uint64_t)curproc->p_pid); +#endif case DIF_VAR_PPID: if (!dtrace_priv_proc(state)) return (0); +#if defined(sun) /* * See comment in DIF_VAR_PID. */ @@ -2825,17 +2986,30 @@ * state -- they leave that task to whomever reaps them.) */ return ((uint64_t)curthread->t_procp->p_ppid); +#else + return ((uint64_t)curproc->p_pptr->p_pid); +#endif case DIF_VAR_TID: +#if defined(sun) /* * See comment in DIF_VAR_PID. */ if (DTRACE_ANCHORED(mstate->dtms_probe) && CPU_ON_INTR(CPU)) return (0); +#endif return ((uint64_t)curthread->t_tid); + case DIF_VAR_EXECARGS: { + struct pargs *p_args = curthread->td_proc->p_args; + + return (dtrace_dif_varstrz( + (uintptr_t) p_args->ar_args, p_args->ar_length, state, mstate)); + } + case DIF_VAR_EXECNAME: +#if defined(sun) if (!dtrace_priv_proc(state)) return (0); @@ -2854,8 +3028,13 @@ return (dtrace_dif_varstr( (uintptr_t)curthread->t_procp->p_user.u_comm, state, mstate)); +#else + return (dtrace_dif_varstr( + (uintptr_t) curthread->td_proc->p_comm, state, mstate)); +#endif case DIF_VAR_ZONENAME: +#if defined(sun) if (!dtrace_priv_proc(state)) return (0); @@ -2874,16 +3053,21 @@ return (dtrace_dif_varstr( (uintptr_t)curthread->t_procp->p_zone->zone_name, state, mstate)); +#else + return (0); +#endif case DIF_VAR_UID: if (!dtrace_priv_proc(state)) return (0); +#if defined(sun) /* * See comment in DIF_VAR_PID. */ if (DTRACE_ANCHORED(mstate->dtms_probe) && CPU_ON_INTR(CPU)) return ((uint64_t)p0.p_cred->cr_uid); +#endif /* * It is always safe to dereference one's own t_procp pointer: @@ -2900,11 +3084,13 @@ if (!dtrace_priv_proc(state)) return (0); +#if defined(sun) /* * See comment in DIF_VAR_PID. */ if (DTRACE_ANCHORED(mstate->dtms_probe) && CPU_ON_INTR(CPU)) return ((uint64_t)p0.p_cred->cr_gid); +#endif /* * It is always safe to dereference one's own t_procp pointer: @@ -2918,6 +3104,7 @@ return ((uint64_t)curthread->t_procp->p_cred->cr_gid); case DIF_VAR_ERRNO: { +#if defined(sun) klwp_t *lwp; if (!dtrace_priv_proc(state)) return (0); @@ -2938,6 +3125,9 @@ return (0); return ((uint64_t)lwp->lwp_errno); +#else + return (curthread->td_errno); +#endif } default: DTRACE_CPUFLAG_SET(CPU_DTRACE_ILLOP); @@ -2957,10 +3147,11 @@ dtrace_key_t *tupregs, int nargs, dtrace_mstate_t *mstate, dtrace_state_t *state) { - volatile uint16_t *flags = &cpu_core[CPU->cpu_id].cpuc_dtrace_flags; - volatile uintptr_t *illval = &cpu_core[CPU->cpu_id].cpuc_dtrace_illval; + volatile uint16_t *flags = &cpu_core[curcpu].cpuc_dtrace_flags; + volatile uintptr_t *illval = &cpu_core[curcpu].cpuc_dtrace_illval; dtrace_vstate_t *vstate = &state->dts_vstate; +#if defined(sun) union { mutex_impl_t mi; uint64_t mx; @@ -2970,16 +3161,27 @@ krwlock_t ri; uintptr_t rw; } r; +#else + union { + struct mtx *mi; + uintptr_t mx; + } m; + union { + struct sx *si; + uintptr_t sx; + } s; +#endif switch (subr) { case DIF_SUBR_RAND: regs[rd] = (dtrace_gethrtime() * 2416 + 374441) % 1771875; break; +#if defined(sun) case DIF_SUBR_MUTEX_OWNED: if (!dtrace_canload(tupregs[0].dttk_value, sizeof (kmutex_t), mstate, vstate)) { - regs[rd] = NULL; + regs[rd] = 0; break; } @@ -2993,7 +3195,7 @@ case DIF_SUBR_MUTEX_OWNER: if (!dtrace_canload(tupregs[0].dttk_value, sizeof (kmutex_t), mstate, vstate)) { - regs[rd] = NULL; + regs[rd] = 0; break; } @@ -3008,7 +3210,7 @@ case DIF_SUBR_MUTEX_TYPE_ADAPTIVE: if (!dtrace_canload(tupregs[0].dttk_value, sizeof (kmutex_t), mstate, vstate)) { - regs[rd] = NULL; + regs[rd] = 0; break; } @@ -3019,7 +3221,7 @@ case DIF_SUBR_MUTEX_TYPE_SPIN: if (!dtrace_canload(tupregs[0].dttk_value, sizeof (kmutex_t), mstate, vstate)) { - regs[rd] = NULL; + regs[rd] = 0; break; } @@ -3032,7 +3234,7 @@ if (!dtrace_canload(tupregs[0].dttk_value, sizeof (uintptr_t), mstate, vstate)) { - regs[rd] = NULL; + regs[rd] = 0; break; } @@ -3044,7 +3246,7 @@ case DIF_SUBR_RW_WRITE_HELD: if (!dtrace_canload(tupregs[0].dttk_value, sizeof (krwlock_t), mstate, vstate)) { - regs[rd] = NULL; + regs[rd] = 0; break; } @@ -3055,7 +3257,7 @@ case DIF_SUBR_RW_ISWRITER: if (!dtrace_canload(tupregs[0].dttk_value, sizeof (krwlock_t), mstate, vstate)) { - regs[rd] = NULL; + regs[rd] = 0; break; } @@ -3063,6 +3265,77 @@ regs[rd] = _RW_ISWRITER(&r.ri); break; +#else + /* + * XXX - The following code works because mutex, rwlocks, & sxlocks + * all have similar data structures in FreeBSD. This may not be + * good if someone changes one of the lock data structures. + * Ideally, it would be nice if all these shared a common lock + * object. + */ + case DIF_SUBR_MUTEX_OWNED: + /* XXX - need to use dtrace_canload() and dtrace_loadptr() */ + m.mx = tupregs[0].dttk_value; + + if (LO_CLASSINDEX(&(m.mi->lock_object)) < 2) { + regs[rd] = !(m.mi->mtx_lock & MTX_UNOWNED); + } else { + regs[rd] = !(m.mi->mtx_lock & SX_UNLOCKED); + } + break; + + case DIF_SUBR_MUTEX_OWNER: + /* XXX - need to use dtrace_canload() and dtrace_loadptr() */ + m.mx = tupregs[0].dttk_value; + + if (LO_CLASSINDEX(&(m.mi->lock_object)) < 2) { + regs[rd] = m.mi->mtx_lock & ~MTX_FLAGMASK; + } else { + if (!(m.mi->mtx_lock & SX_LOCK_SHARED)) + regs[rd] = SX_OWNER(m.mi->mtx_lock); + else + regs[rd] = 0; + } + break; + + case DIF_SUBR_MUTEX_TYPE_ADAPTIVE: + /* XXX - need to use dtrace_canload() and dtrace_loadptr() */ + m.mx = tupregs[0].dttk_value; + + regs[rd] = (LO_CLASSINDEX(&(m.mi->lock_object)) != 0); + break; + + case DIF_SUBR_MUTEX_TYPE_SPIN: + /* XXX - need to use dtrace_canload() and dtrace_loadptr() */ + m.mx = tupregs[0].dttk_value; + + regs[rd] = (LO_CLASSINDEX(&(m.mi->lock_object)) == 0); + break; + + case DIF_SUBR_RW_READ_HELD: + case DIF_SUBR_SX_SHARED_HELD: + /* XXX - need to use dtrace_canload() and dtrace_loadptr() */ + s.sx = tupregs[0].dttk_value; + regs[rd] = ((s.si->sx_lock & SX_LOCK_SHARED) && + (SX_OWNER(s.si->sx_lock) >> SX_SHARERS_SHIFT) != 0); + break; + + case DIF_SUBR_RW_WRITE_HELD: + case DIF_SUBR_SX_EXCLUSIVE_HELD: + /* XXX - need to use dtrace_canload() and dtrace_loadptr() */ + s.sx = tupregs[0].dttk_value; + regs[rd] = (SX_OWNER(s.si->sx_lock) == (uintptr_t) curthread); + break; + + case DIF_SUBR_RW_ISWRITER: + case DIF_SUBR_SX_ISEXCLUSIVE: + /* XXX - need to use dtrace_canload() and dtrace_loadptr() */ + s.sx = tupregs[0].dttk_value; + regs[rd] = ((s.si->sx_lock & SX_LOCK_EXCLUSIVE_WAITERS) || + !(s.si->sx_lock & SX_LOCK_SHARED)); + break; +#endif /* ! defined(sun) */ + case DIF_SUBR_BCOPY: { /* * We need to be sure that the destination is in the scratch @@ -3079,7 +3352,7 @@ } if (!dtrace_canload(src, size, mstate, vstate)) { - regs[rd] = NULL; + regs[rd] = 0; break; } @@ -3107,7 +3380,7 @@ if (scratch_size < size || !DTRACE_INSCRATCH(mstate, scratch_size)) { DTRACE_CPUFLAG_SET(CPU_DTRACE_NOSCRATCH); - regs[rd] = NULL; + regs[rd] = 0; break; } @@ -3157,7 +3430,7 @@ */ if (!DTRACE_INSCRATCH(mstate, size)) { DTRACE_CPUFLAG_SET(CPU_DTRACE_NOSCRATCH); - regs[rd] = NULL; + regs[rd] = 0; break; } @@ -3171,6 +3444,7 @@ break; } +#if defined(sun) case DIF_SUBR_MSGSIZE: case DIF_SUBR_MSGDSIZE: { uintptr_t baddr = tupregs[0].dttk_value, daddr; @@ -3178,11 +3452,11 @@ size_t count = 0; int cont = 0; - while (baddr != NULL && !(*flags & CPU_DTRACE_FAULT)) { + while (baddr != 0 && !(*flags & CPU_DTRACE_FAULT)) { if (!dtrace_canload(baddr, sizeof (mblk_t), mstate, vstate)) { - regs[rd] = NULL; + regs[rd] = 0; break; } @@ -3228,6 +3502,7 @@ break; } +#endif case DIF_SUBR_PROGENYOF: { pid_t pid = tupregs[0].dttk_value; @@ -3237,7 +3512,11 @@ DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT); for (p = curthread->t_procp; p != NULL; p = p->p_parent) { +#if defined(sun) if (p->p_pidp->pid_id == pid) { +#else + if (p->p_pid == pid) { +#endif rval = 1; break; } @@ -3290,7 +3569,7 @@ state->dts_options[DTRACEOPT_STRSIZE]); if (!dtrace_canload(addr, sz + 1, mstate, vstate)) { - regs[rd] = NULL; + regs[rd] = 0; break; } @@ -3313,7 +3592,7 @@ uintptr_t limit = addr + state->dts_options[DTRACEOPT_STRSIZE]; char c, target = (char)tupregs[1].dttk_value; - for (regs[rd] = NULL; addr < limit; addr++) { + for (regs[rd] = 0; addr < limit; addr++) { if ((c = dtrace_load8(addr)) == target) { regs[rd] = addr; @@ -3326,7 +3605,7 @@ } if (!dtrace_canload(saddr, addr - saddr, mstate, vstate)) { - regs[rd] = NULL; + regs[rd] = 0; break; } @@ -3357,13 +3636,13 @@ regs[rd] = notfound; if (!dtrace_canload((uintptr_t)addr, len + 1, mstate, vstate)) { - regs[rd] = NULL; + regs[rd] = 0; break; } if (!dtrace_canload((uintptr_t)substr, sublen + 1, mstate, vstate)) { - regs[rd] = NULL; + regs[rd] = 0; break; >>> TRUNCATED FOR MAIL (1000 lines) <<<
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200803280238.m2S2cNTo010245>