/* * Note that multiple bits may be set in a single settoxic operation. * May be called without the page locked. */ void page_settoxic(page_t *pp, uchar_t bits) { atomic_or_8(&pp->p_toxic, bits); }
static void fasttrap_return_common(proc_t *p, arm_saved_state_t *regs, user_addr_t pc, user_addr_t new_pc) { pid_t pid = p->p_pid; fasttrap_tracepoint_t *tp; fasttrap_bucket_t *bucket; fasttrap_id_t *id; lck_mtx_t *pid_mtx; int retire_tp = 1; pid_mtx = &cpu_core[CPU->cpu_id].cpuc_pid_lock; lck_mtx_lock(pid_mtx); bucket = &fasttrap_tpoints.fth_table[FASTTRAP_TPOINTS_INDEX(pid, pc)]; for (tp = bucket->ftb_data; tp != NULL; tp = tp->ftt_next) { if (pid == tp->ftt_pid && pc == tp->ftt_pc && tp->ftt_proc->ftpc_acount != 0) break; } /* * Don't sweat it if we can't find the tracepoint again; unlike * when we're in fasttrap_pid_probe(), finding the tracepoint here * is not essential to the correct execution of the process. */ if (tp == NULL) { lck_mtx_unlock(pid_mtx); return; } for (id = tp->ftt_retids; id != NULL; id = id->fti_next) { fasttrap_probe_t *probe = id->fti_probe; /* * If there's a branch that could act as a return site, we * need to trace it, and check here if the program counter is * external to the function. */ if (tp->ftt_type != FASTTRAP_T_LDM_PC && tp->ftt_type != FASTTRAP_T_POP_PC && new_pc - probe->ftp_faddr < probe->ftp_fsize) continue; if (probe->ftp_prov->ftp_provider_type == DTFTP_PROVIDER_ONESHOT) { uint8_t already_triggered = atomic_or_8(&probe->ftp_triggered, 1); if (already_triggered) { continue; } } /* * If we have at least one probe associated that * is not a oneshot probe, don't remove the * tracepoint */ else { retire_tp = 0; } #ifndef CONFIG_EMBEDDED if (ISSET(current_proc()->p_lflag, P_LNOATTACH)) { dtrace_probe(dtrace_probeid_error, 0 /* state */, id->fti_probe->ftp_id, 1 /* ndx */, -1 /* offset */, DTRACEFLT_UPRIV); #else if (FALSE) { #endif } else { dtrace_probe(id->fti_probe->ftp_id, pc - id->fti_probe->ftp_faddr, regs->r[0], 0, 0, 0); } } if (retire_tp) { fasttrap_tracepoint_retire(p, tp); } lck_mtx_unlock(pid_mtx); } static void fasttrap_sigsegv(proc_t *p, uthread_t t, user_addr_t addr, arm_saved_state_t *regs) { /* TODO: This function isn't implemented yet. In debug mode, panic the system to * find out why we're hitting this point. In other modes, kill the process. */ #if DEBUG #pragma unused(p,t,addr,arm_saved_state) panic("fasttrap: sigsegv not yet implemented"); #else #pragma unused(p,t,addr) /* Kill the process */ regs->pc = 0; #endif #if 0 proc_lock(p); /* Set fault address and mark signal */ t->uu_code = addr; t->uu_siglist |= sigmask(SIGSEGV); /* * XXX These two line may be redundant; if not, then we need * XXX to potentially set the data address in the machine * XXX specific thread state structure to indicate the address. */ t->uu_exception = KERN_INVALID_ADDRESS; /* SIGSEGV */ t->uu_subcode = 0; /* XXX pad */ proc_unlock(p); /* raise signal */ signal_setast(t->uu_context.vc_thread); #endif }