X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/3e170ce000f1506b7b5d2c5c7faec85ceabb573d..cc8bc92ae4a8e9f1a1ab61bf83d34ad8150b3405:/bsd/dev/dtrace/dtrace_glue.c?ds=inline diff --git a/bsd/dev/dtrace/dtrace_glue.c b/bsd/dev/dtrace/dtrace_glue.c index 4e7ede1d2..57f0f3207 100644 --- a/bsd/dev/dtrace/dtrace_glue.c +++ b/bsd/dev/dtrace/dtrace_glue.c @@ -297,6 +297,16 @@ typedef struct wrap_timer_call { #define WAKEUP_REAPER 0x7FFFFFFFFFFFFFFFLL #define NEARLY_FOREVER 0x7FFFFFFFFFFFFFFELL + +typedef struct cyc_list { + cyc_omni_handler_t cyl_omni; + wrap_timer_call_t cyl_wrap_by_cpus[]; +#if __arm__ && (__BIGGEST_ALIGNMENT__ > 4) +} __attribute__ ((aligned (8))) cyc_list_t; +#else +} cyc_list_t; +#endif + /* CPU going online/offline notifications */ void (*dtrace_cpu_state_changed_hook)(int, boolean_t) = NULL; void dtrace_cpu_state_changed(int, boolean_t); @@ -386,10 +396,8 @@ timer_call_add_cyclic(wrap_timer_call_t *wrapTC, cyc_handler_t *handler, cyc_tim * Executed on the CPU the timer is running on. */ static void -timer_call_remove_cyclic(cyclic_id_t cyclic) +timer_call_remove_cyclic(wrap_timer_call_t *wrapTC) { - wrap_timer_call_t *wrapTC = (wrap_timer_call_t *)cyclic; - assert(wrapTC); assert(cpu_number() == wrapTC->cpuid); @@ -400,12 +408,10 @@ timer_call_remove_cyclic(cyclic_id_t cyclic) } static void * -timer_call_get_cyclic_arg(cyclic_id_t cyclic) -{ - wrap_timer_call_t *wrapTC = (wrap_timer_call_t *)cyclic; - +timer_call_get_cyclic_arg(wrap_timer_call_t *wrapTC) +{ return (wrapTC ? wrapTC->hdlr.cyh_arg : NULL); -} +} cyclic_id_t cyclic_timer_add(cyc_handler_t *handler, cyc_time_t *when) @@ -430,62 +436,48 @@ cyclic_timer_remove(cyclic_id_t cyclic) } static void -_cyclic_add_omni(cyclic_id_list_t cyc_list) +_cyclic_add_omni(cyc_list_t *cyc_list) { cyc_time_t cT; cyc_handler_t cH; - wrap_timer_call_t *wrapTC; - cyc_omni_handler_t *omni = (cyc_omni_handler_t *)cyc_list; - char *t; - - (omni->cyo_online)(omni->cyo_arg, CPU, &cH, &cT); + cyc_omni_handler_t *omni = &cyc_list->cyl_omni; - t = (char *)cyc_list; - t += sizeof(cyc_omni_handler_t); - cyc_list = (cyclic_id_list_t)(uintptr_t)t; + (omni->cyo_online)(omni->cyo_arg, CPU, &cH, &cT); - t += sizeof(cyclic_id_t)*NCPU; - t += (sizeof(wrap_timer_call_t))*cpu_number(); - wrapTC = (wrap_timer_call_t *)(uintptr_t)t; - - cyc_list[cpu_number()] = timer_call_add_cyclic(wrapTC, &cH, &cT); + wrap_timer_call_t *wrapTC = &cyc_list->cyl_wrap_by_cpus[cpu_number()]; + timer_call_add_cyclic(wrapTC, &cH, &cT); } cyclic_id_list_t cyclic_add_omni(cyc_omni_handler_t *omni) { - cyclic_id_list_t cyc_list = - _MALLOC( (sizeof(wrap_timer_call_t))*NCPU + - sizeof(cyclic_id_t)*NCPU + - sizeof(cyc_omni_handler_t), M_TEMP, M_ZERO | M_WAITOK); + cyc_list_t *cyc_list = + _MALLOC(sizeof(cyc_list_t) + NCPU * sizeof(wrap_timer_call_t), M_TEMP, M_ZERO | M_WAITOK); + if (NULL == cyc_list) - return (cyclic_id_list_t)CYCLIC_NONE; + return NULL; + + cyc_list->cyl_omni = *omni; - *(cyc_omni_handler_t *)cyc_list = *omni; dtrace_xcall(DTRACE_CPUALL, (dtrace_xcall_t)_cyclic_add_omni, (void *)cyc_list); - return cyc_list; + return (cyclic_id_list_t)cyc_list; } static void -_cyclic_remove_omni(cyclic_id_list_t cyc_list) +_cyclic_remove_omni(cyc_list_t *cyc_list) { - cyc_omni_handler_t *omni = (cyc_omni_handler_t *)cyc_list; + cyc_omni_handler_t *omni = &cyc_list->cyl_omni; void *oarg; - cyclic_id_t cid; - char *t; - - t = (char *)cyc_list; - t += sizeof(cyc_omni_handler_t); - cyc_list = (cyclic_id_list_t)(uintptr_t)t; + wrap_timer_call_t *wrapTC; /* * If the processor was offline when dtrace started, we did not allocate * a cyclic timer for this CPU. */ - if ((cid = cyc_list[cpu_number()]) != CYCLIC_NONE) { - oarg = timer_call_get_cyclic_arg(cid); - timer_call_remove_cyclic(cid); + if ((wrapTC = &cyc_list->cyl_wrap_by_cpus[cpu_number()]) != NULL) { + oarg = timer_call_get_cyclic_arg(wrapTC); + timer_call_remove_cyclic(wrapTC); (omni->cyo_offline)(omni->cyo_arg, CPU, oarg); } } @@ -493,7 +485,7 @@ _cyclic_remove_omni(cyclic_id_list_t cyc_list) void cyclic_remove_omni(cyclic_id_list_t cyc_list) { - ASSERT( cyc_list != (cyclic_id_list_t)CYCLIC_NONE ); + ASSERT(cyc_list != NULL); dtrace_xcall(DTRACE_CPUALL, (dtrace_xcall_t)_cyclic_remove_omni, (void *)cyc_list); _FREE(cyc_list, M_TEMP); @@ -585,29 +577,6 @@ cyclic_remove(cyclic_id_t cyclic) } } -/* - * timeout / untimeout (converted to dtrace_timeout / dtrace_untimeout due to name collision) - */ - -thread_call_t -dtrace_timeout(void (*func)(void *, void *), void* arg, uint64_t nanos) -{ -#pragma unused(arg) - thread_call_t call = thread_call_allocate(func, NULL); - - nanoseconds_to_absolutetime(nanos, &nanos); - - /* - * This method does not use clock_deadline_for_periodic_event() because it is a one-shot, - * and clock drift on later invocations is not a worry. - */ - uint64_t deadline = mach_absolute_time() + nanos; - /* DRK: consider using a lower priority callout here */ - thread_call_enter_delayed(call, deadline); - - return call; -} - /* * ddi */ @@ -617,54 +586,6 @@ ddi_report_dev(dev_info_t *devi) #pragma unused(devi) } -#define NSOFT_STATES 32 /* XXX No more than 32 clients at a time, please. */ -static void *soft[NSOFT_STATES]; - -int -ddi_soft_state_init(void **state_p, size_t size, size_t n_items) -{ -#pragma unused(n_items) - int i; - - for (i = 0; i < NSOFT_STATES; ++i) soft[i] = _MALLOC(size, M_TEMP, M_ZERO | M_WAITOK); - *(size_t *)state_p = size; - return 0; -} - -int -ddi_soft_state_zalloc(void *state, int item) -{ -#pragma unused(state) - if (item < NSOFT_STATES) - return DDI_SUCCESS; - else - return DDI_FAILURE; -} - -void * -ddi_get_soft_state(void *state, int item) -{ -#pragma unused(state) - ASSERT(item < NSOFT_STATES); - return soft[item]; -} - -int -ddi_soft_state_free(void *state, int item) -{ - ASSERT(item < NSOFT_STATES); - bzero( soft[item], (size_t)state ); - return DDI_SUCCESS; -} - -void -ddi_soft_state_fini(void **state_p) -{ -#pragma unused(state_p) - int i; - - for (i = 0; i < NSOFT_STATES; ++i) _FREE( soft[i], M_TEMP ); -} static unsigned int gRegisteredProps = 0; static struct { @@ -1309,6 +1230,30 @@ dtrace_copyoutstr(uintptr_t src, user_addr_t dst, size_t len, volatile uint16_t } } +extern const int copysize_limit_panic; + +int +dtrace_buffer_copyout(const void *kaddr, user_addr_t uaddr, vm_size_t nbytes) +{ + /* + * Partition the copyout in copysize_limit_panic-sized chunks + */ + while (nbytes >= (vm_size_t)copysize_limit_panic) { + if (copyout(kaddr, uaddr, copysize_limit_panic) != 0) + return (EFAULT); + + nbytes -= copysize_limit_panic; + uaddr += copysize_limit_panic; + kaddr += copysize_limit_panic; + } + if (nbytes > 0) { + if (copyout(kaddr, uaddr, nbytes) != 0) + return (EFAULT); + } + + return (0); +} + uint8_t dtrace_fuword8(user_addr_t uaddr) { @@ -1543,6 +1488,8 @@ strstr(const char *in, const char *str) { char c; size_t len; + if (!in || !str) + return in; c = *str++; if (!c) @@ -1562,6 +1509,26 @@ strstr(const char *in, const char *str) return (const char *) (in - 1); } +const void* +bsearch(const void *key, const void *base0, size_t nmemb, size_t size, int (*compar)(const void *, const void *)) +{ + const char *base = base0; + size_t lim; + int cmp; + const void *p; + for (lim = nmemb; lim != 0; lim >>= 1) { + p = base + (lim >> 1) * size; + cmp = (*compar)(key, p); + if (cmp == 0) + return p; + if (cmp > 0) { /* key > p: move right */ + base = (const char *)p + size; + lim--; + } /* else move left */ + } + return (NULL); +} + /* * Runtime and ABI */