1 /*- 2 * Copyright (C) 1994, David Greenman 3 * Copyright (c) 1990, 1993 4 * The Regents of the University of California. All rights reserved. 5 * Copyright (c) 2007 The FreeBSD Foundation 6 * 7 * This code is derived from software contributed to Berkeley by 8 * the University of Utah, and William Jolitz. 9 * 10 * Portions of this software were developed by A. Joseph Koshy under 11 * sponsorship from the FreeBSD Foundation and Google, Inc. 12 * 13 * Redistribution and use in source and binary forms, with or without 14 * modification, are permitted provided that the following conditions 15 * are met: 16 * 1. Redistributions of source code must retain the above copyright 17 * notice, this list of conditions and the following disclaimer. 18 * 2. Redistributions in binary form must reproduce the above copyright 19 * notice, this list of conditions and the following disclaimer in the 20 * documentation and/or other materials provided with the distribution. 21 * 3. All advertising materials mentioning features or use of this software 22 * must display the following acknowledgement: 23 * This product includes software developed by the University of 24 * California, Berkeley and its contributors. 25 * 4. Neither the name of the University nor the names of its contributors 26 * may be used to endorse or promote products derived from this software 27 * without specific prior written permission. 28 * 29 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 30 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 31 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 32 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 33 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 34 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 35 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 36 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 37 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 38 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 39 * SUCH DAMAGE. 40 * 41 * from: @(#)trap.c 7.4 (Berkeley) 5/13/91 42 */ 43 44 #include <sys/cdefs.h> 45 __FBSDID("$FreeBSD$"); 46 47 #include "opt_hwpmc_hooks.h" 48 #include "opt_ktrace.h" 49 #include "opt_kdtrace.h" 50 #include "opt_sched.h" 51 52 #include <sys/param.h> 53 #include <sys/bus.h> 54 #include <sys/capability.h> 55 #include <sys/kernel.h> 56 #include <sys/lock.h> 57 #include <sys/mutex.h> 58 #include <sys/pmckern.h> 59 #include <sys/proc.h> 60 #include <sys/ktr.h> 61 #include <sys/pioctl.h> 62 #include <sys/ptrace.h> 63 #include <sys/resourcevar.h> 64 #include <sys/sched.h> 65 #include <sys/signalvar.h> 66 #include <sys/syscall.h> 67 #include <sys/syscallsubr.h> 68 #include <sys/sysent.h> 69 #include <sys/systm.h> 70 #include <sys/vmmeter.h> 71 #ifdef KTRACE 72 #include <sys/uio.h> 73 #include <sys/ktrace.h> 74 #endif 75 #include <security/audit/audit.h> 76 77 #include <machine/cpu.h> 78 79 #ifdef VIMAGE 80 #include <net/vnet.h> 81 #endif 82 83 #ifdef XEN 84 #include <vm/vm.h> 85 #include <vm/vm_param.h> 86 #include <vm/pmap.h> 87 #endif 88 89 #ifdef HWPMC_HOOKS 90 #include <sys/pmckern.h> 91 #endif 92 93 #include <security/mac/mac_framework.h> 94 95 /* 96 * Define the code needed before returning to user mode, for trap and 97 * syscall. 98 */ 99 void 100 userret(struct thread *td, struct trapframe *frame) 101 { 102 struct proc *p = td->td_proc; 103 104 CTR3(KTR_SYSC, "userret: thread %p (pid %d, %s)", td, p->p_pid, 105 td->td_name); 106 KASSERT((p->p_flag & P_WEXIT) == 0, 107 ("Exiting process returns to usermode")); 108 #if 0 109 #ifdef DIAGNOSTIC 110 /* Check that we called signotify() enough. */ 111 PROC_LOCK(p); 112 thread_lock(td); 113 if (SIGPENDING(td) && ((td->td_flags & TDF_NEEDSIGCHK) == 0 || 114 (td->td_flags & TDF_ASTPENDING) == 0)) 115 printf("failed to set signal flags properly for ast()\n"); 116 thread_unlock(td); 117 PROC_UNLOCK(p); 118 #endif 119 #endif 120 #ifdef KTRACE 121 KTRUSERRET(td); 122 #endif 123 /* 124 * If this thread tickled GEOM, we need to wait for the giggling to 125 * stop before we return to userland 126 */ 127 if (td->td_pflags & TDP_GEOM) 128 g_waitidle(); 129 130 /* 131 * Charge system time if profiling. 132 */ 133 if (p->p_flag & P_PROFIL) 134 addupc_task(td, TRAPF_PC(frame), td->td_pticks * psratio); 135 /* 136 * Let the scheduler adjust our priority etc. 137 */ 138 sched_userret(td); 139 #ifdef XEN 140 PT_UPDATES_FLUSH(); 141 #endif 142 143 /* 144 * Check for misbehavior. 145 */ 146 WITNESS_WARN(WARN_PANIC, NULL, "userret: returning"); 147 KASSERT(td->td_critnest == 0, 148 ("userret: Returning in a critical section")); 149 KASSERT(td->td_locks == 0, 150 ("userret: Returning with %d locks held", td->td_locks)); 151 KASSERT((td->td_pflags & TDP_NOFAULTING) == 0, 152 ("userret: Returning with pagefaults disabled")); 153 KASSERT((td->td_pflags & TDP_NOSLEEPING) == 0, 154 ("userret: Returning with sleep disabled")); 155 KASSERT(td->td_pinned == 0, 156 ("userret: Returning with with pinned thread")); 157 #ifdef VIMAGE 158 /* Unfortunately td_vnet_lpush needs VNET_DEBUG. */ 159 VNET_ASSERT(curvnet == NULL, 160 ("%s: Returning on td %p (pid %d, %s) with vnet %p set in %s", 161 __func__, td, p->p_pid, td->td_name, curvnet, 162 (td->td_vnet_lpush != NULL) ? td->td_vnet_lpush : "N/A")); 163 #endif 164 } 165 166 /* 167 * Process an asynchronous software trap. 168 * This is relatively easy. 169 * This function will return with preemption disabled. 170 */ 171 void 172 ast(struct trapframe *framep) 173 { 174 struct thread *td; 175 struct proc *p; 176 int flags; 177 int sig; 178 179 td = curthread; 180 p = td->td_proc; 181 182 CTR3(KTR_SYSC, "ast: thread %p (pid %d, %s)", td, p->p_pid, 183 p->p_comm); 184 KASSERT(TRAPF_USERMODE(framep), ("ast in kernel mode")); 185 WITNESS_WARN(WARN_PANIC, NULL, "Returning to user mode"); 186 mtx_assert(&Giant, MA_NOTOWNED); 187 THREAD_LOCK_ASSERT(td, MA_NOTOWNED); 188 td->td_frame = framep; 189 td->td_pticks = 0; 190 191 /* 192 * This updates the td_flag's for the checks below in one 193 * "atomic" operation with turning off the astpending flag. 194 * If another AST is triggered while we are handling the 195 * AST's saved in flags, the astpending flag will be set and 196 * ast() will be called again. 197 */ 198 thread_lock(td); 199 flags = td->td_flags; 200 td->td_flags &= ~(TDF_ASTPENDING | TDF_NEEDSIGCHK | TDF_NEEDSUSPCHK | 201 TDF_NEEDRESCHED | TDF_ALRMPEND | TDF_PROFPEND | TDF_MACPEND); 202 thread_unlock(td); 203 PCPU_INC(cnt.v_trap); 204 205 if (td->td_ucred != p->p_ucred) 206 cred_update_thread(td); 207 if (td->td_pflags & TDP_OWEUPC && p->p_flag & P_PROFIL) { 208 addupc_task(td, td->td_profil_addr, td->td_profil_ticks); 209 td->td_profil_ticks = 0; 210 td->td_pflags &= ~TDP_OWEUPC; 211 } 212 #ifdef HWPMC_HOOKS 213 /* Handle Software PMC callchain capture. */ 214 if (PMC_IS_PENDING_CALLCHAIN(td)) 215 PMC_CALL_HOOK_UNLOCKED(td, PMC_FN_USER_CALLCHAIN_SOFT, (void *) framep); 216 #endif 217 if (flags & TDF_ALRMPEND) { 218 PROC_LOCK(p); 219 kern_psignal(p, SIGVTALRM); 220 PROC_UNLOCK(p); 221 } 222 if (flags & TDF_PROFPEND) { 223 PROC_LOCK(p); 224 kern_psignal(p, SIGPROF); 225 PROC_UNLOCK(p); 226 } 227 #ifdef MAC 228 if (flags & TDF_MACPEND) 229 mac_thread_userret(td); 230 #endif 231 if (flags & TDF_NEEDRESCHED) { 232 #ifdef KTRACE 233 if (KTRPOINT(td, KTR_CSW)) 234 ktrcsw(1, 1, __func__); 235 #endif 236 thread_lock(td); 237 sched_prio(td, td->td_user_pri); 238 mi_switch(SW_INVOL | SWT_NEEDRESCHED, NULL); 239 thread_unlock(td); 240 #ifdef KTRACE 241 if (KTRPOINT(td, KTR_CSW)) 242 ktrcsw(0, 1, __func__); 243 #endif 244 } 245 246 /* 247 * Check for signals. Unlocked reads of p_pendingcnt or 248 * p_siglist might cause process-directed signal to be handled 249 * later. 250 */ 251 if (flags & TDF_NEEDSIGCHK || p->p_pendingcnt > 0 || 252 !SIGISEMPTY(p->p_siglist)) { 253 PROC_LOCK(p); 254 mtx_lock(&p->p_sigacts->ps_mtx); 255 while ((sig = cursig(td, SIG_STOP_ALLOWED)) != 0) 256 postsig(sig); 257 mtx_unlock(&p->p_sigacts->ps_mtx); 258 PROC_UNLOCK(p); 259 } 260 /* 261 * We need to check to see if we have to exit or wait due to a 262 * single threading requirement or some other STOP condition. 263 */ 264 if (flags & TDF_NEEDSUSPCHK) { 265 PROC_LOCK(p); 266 thread_suspend_check(0); 267 PROC_UNLOCK(p); 268 } 269 270 if (td->td_pflags & TDP_OLDMASK) { 271 td->td_pflags &= ~TDP_OLDMASK; 272 kern_sigprocmask(td, SIG_SETMASK, &td->td_oldsigmask, NULL, 0); 273 } 274 275 userret(td, framep); 276 } 277 278 const char * 279 syscallname(struct proc *p, u_int code) 280 { 281 static const char unknown[] = "unknown"; 282 struct sysentvec *sv; 283 284 sv = p->p_sysent; 285 if (sv->sv_syscallnames == NULL || code >= sv->sv_size) 286 return (unknown); 287 return (sv->sv_syscallnames[code]); 288 } 289