* Process an asynchronous software trap. * This is relatively easy. * This function will return with preemption disabled. */
| 199 | * This function will return with preemption disabled. |
| 200 | */ |
| 201 | void |
| 202 | ast(struct trapframe *framep) |
| 203 | { |
| 204 | struct thread *td; |
| 205 | struct proc *p; |
| 206 | int flags, sig; |
| 207 | bool resched_sigs; |
| 208 | |
| 209 | td = curthread; |
| 210 | p = td->td_proc; |
| 211 | |
| 212 | CTR3(KTR_SYSC, "ast: thread %p (pid %d, %s)", td, p->p_pid, |
| 213 | p->p_comm); |
| 214 | KASSERT(TRAPF_USERMODE(framep), ("ast in kernel mode")); |
| 215 | WITNESS_WARN(WARN_PANIC, NULL, "Returning to user mode"); |
| 216 | mtx_assert(&Giant, MA_NOTOWNED); |
| 217 | THREAD_LOCK_ASSERT(td, MA_NOTOWNED); |
| 218 | td->td_frame = framep; |
| 219 | td->td_pticks = 0; |
| 220 | |
| 221 | /* |
| 222 | * This updates the td_flag's for the checks below in one |
| 223 | * "atomic" operation with turning off the astpending flag. |
| 224 | * If another AST is triggered while we are handling the |
| 225 | * AST's saved in flags, the astpending flag will be set and |
| 226 | * ast() will be called again. |
| 227 | */ |
| 228 | thread_lock(td); |
| 229 | flags = td->td_flags; |
| 230 | td->td_flags &= ~(TDF_ASTPENDING | TDF_NEEDSIGCHK | TDF_NEEDSUSPCHK | |
| 231 | TDF_NEEDRESCHED | TDF_ALRMPEND | TDF_PROFPEND | TDF_MACPEND); |
| 232 | thread_unlock(td); |
| 233 | VM_CNT_INC(v_trap); |
| 234 | |
| 235 | if (td->td_cowgen != p->p_cowgen) |
| 236 | thread_cow_update(td); |
| 237 | if (td->td_pflags & TDP_OWEUPC && p->p_flag & P_PROFIL) { |
| 238 | addupc_task(td, td->td_profil_addr, td->td_profil_ticks); |
| 239 | td->td_profil_ticks = 0; |
| 240 | td->td_pflags &= ~TDP_OWEUPC; |
| 241 | } |
| 242 | #ifdef HWPMC_HOOKS |
| 243 | /* Handle Software PMC callchain capture. */ |
| 244 | if (PMC_IS_PENDING_CALLCHAIN(td)) |
| 245 | PMC_CALL_HOOK_UNLOCKED(td, PMC_FN_USER_CALLCHAIN_SOFT, (void *) framep); |
| 246 | #endif |
| 247 | if (flags & TDF_ALRMPEND) { |
| 248 | PROC_LOCK(p); |
| 249 | kern_psignal(p, SIGVTALRM); |
| 250 | PROC_UNLOCK(p); |
| 251 | } |
| 252 | if (flags & TDF_PROFPEND) { |
| 253 | PROC_LOCK(p); |
| 254 | kern_psignal(p, SIGPROF); |
| 255 | PROC_UNLOCK(p); |
| 256 | } |
| 257 | #ifdef MAC |
| 258 | if (flags & TDF_MACPEND) |
nothing calls this directly
no test coverage detected