xref: /freebsd/sys/amd64/ia32/ia32_signal.c (revision f7c4bd95ba735bd6a5454b4953945a99cefbb80c)
1 /*-
2  * Copyright (c) 2003 Peter Wemm
3  * Copyright (c) 1982, 1987, 1990 The Regents of the University of California.
4  * All rights reserved.
5  *
6  * This code is derived from software contributed to Berkeley by
7  * William Jolitz.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  * 4. Neither the name of the University nor the names of its contributors
18  *    may be used to endorse or promote products derived from this software
19  *    without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  */
33 
34 #include <sys/cdefs.h>
35 __FBSDID("$FreeBSD$");
36 
37 #include "opt_compat.h"
38 
39 #include <sys/param.h>
40 #include <sys/exec.h>
41 #include <sys/fcntl.h>
42 #include <sys/imgact.h>
43 #include <sys/kernel.h>
44 #include <sys/lock.h>
45 #include <sys/malloc.h>
46 #include <sys/mutex.h>
47 #include <sys/mman.h>
48 #include <sys/namei.h>
49 #include <sys/pioctl.h>
50 #include <sys/proc.h>
51 #include <sys/procfs.h>
52 #include <sys/resourcevar.h>
53 #include <sys/systm.h>
54 #include <sys/signalvar.h>
55 #include <sys/stat.h>
56 #include <sys/sx.h>
57 #include <sys/syscall.h>
58 #include <sys/sysctl.h>
59 #include <sys/sysent.h>
60 #include <sys/vnode.h>
61 
62 #include <vm/vm.h>
63 #include <vm/vm_kern.h>
64 #include <vm/vm_param.h>
65 #include <vm/pmap.h>
66 #include <vm/vm_map.h>
67 #include <vm/vm_object.h>
68 #include <vm/vm_extern.h>
69 
70 #include <compat/freebsd32/freebsd32_signal.h>
71 #include <compat/freebsd32/freebsd32_util.h>
72 #include <compat/freebsd32/freebsd32_proto.h>
73 #include <compat/ia32/ia32_signal.h>
74 #include <machine/psl.h>
75 #include <machine/segments.h>
76 #include <machine/specialreg.h>
77 #include <machine/frame.h>
78 #include <machine/md_var.h>
79 #include <machine/pcb.h>
80 #include <machine/cpufunc.h>
81 
82 #ifdef COMPAT_FREEBSD4
83 static void freebsd4_ia32_sendsig(sig_t, ksiginfo_t *, sigset_t *);
84 #endif
85 static void ia32_get_fpcontext(struct thread *td, struct ia32_mcontext *mcp);
86 static int ia32_set_fpcontext(struct thread *td, const struct ia32_mcontext *mcp);
87 
88 extern int _ucode32sel, _udatasel;
89 
90 #define	CS_SECURE(cs)		(ISPL(cs) == SEL_UPL)
91 #define	EFL_SECURE(ef, oef)	((((ef) ^ (oef)) & ~PSL_USERCHANGE) == 0)
92 
93 static void
94 ia32_get_fpcontext(struct thread *td, struct ia32_mcontext *mcp)
95 {
96 
97 	mcp->mc_ownedfp = fpugetregs(td, (struct savefpu *)&mcp->mc_fpstate);
98 	mcp->mc_fpformat = fpuformat();
99 }
100 
101 static int
102 ia32_set_fpcontext(struct thread *td, const struct ia32_mcontext *mcp)
103 {
104 
105 	if (mcp->mc_fpformat == _MC_FPFMT_NODEV)
106 		return (0);
107 	else if (mcp->mc_fpformat != _MC_FPFMT_XMM)
108 		return (EINVAL);
109 	else if (mcp->mc_ownedfp == _MC_FPOWNED_NONE)
110 		/* We don't care what state is left in the FPU or PCB. */
111 		fpstate_drop(td);
112 	else if (mcp->mc_ownedfp == _MC_FPOWNED_FPU ||
113 	    mcp->mc_ownedfp == _MC_FPOWNED_PCB) {
114 		/*
115 		 * XXX we violate the dubious requirement that fpusetregs()
116 		 * be called with interrupts disabled.
117 		 */
118 		fpusetregs(td, (struct savefpu *)&mcp->mc_fpstate);
119 	} else
120 		return (EINVAL);
121 	return (0);
122 }
123 
124 /*
125  * Get machine context.
126  */
127 static int
128 ia32_get_mcontext(struct thread *td, struct ia32_mcontext *mcp, int flags)
129 {
130 	struct trapframe *tp;
131 
132 	tp = td->td_frame;
133 
134 	PROC_LOCK(curthread->td_proc);
135 	mcp->mc_onstack = sigonstack(tp->tf_rsp);
136 	PROC_UNLOCK(curthread->td_proc);
137 	mcp->mc_gs = td->td_pcb->pcb_gs;
138 	mcp->mc_fs = td->td_pcb->pcb_fs;
139 	mcp->mc_es = td->td_pcb->pcb_es;
140 	mcp->mc_ds = td->td_pcb->pcb_ds;
141 	mcp->mc_edi = tp->tf_rdi;
142 	mcp->mc_esi = tp->tf_rsi;
143 	mcp->mc_ebp = tp->tf_rbp;
144 	mcp->mc_isp = tp->tf_rsp;
145 	if (flags & GET_MC_CLEAR_RET) {
146 		mcp->mc_eax = 0;
147 		mcp->mc_edx = 0;
148 	} else {
149 		mcp->mc_eax = tp->tf_rax;
150 		mcp->mc_edx = tp->tf_rdx;
151 	}
152 	mcp->mc_ebx = tp->tf_rbx;
153 	mcp->mc_ecx = tp->tf_rcx;
154 	mcp->mc_eip = tp->tf_rip;
155 	mcp->mc_cs = tp->tf_cs;
156 	mcp->mc_eflags = tp->tf_rflags;
157 	mcp->mc_esp = tp->tf_rsp;
158 	mcp->mc_ss = tp->tf_ss;
159 	mcp->mc_len = sizeof(*mcp);
160 	ia32_get_fpcontext(td, mcp);
161 	return (0);
162 }
163 
164 /*
165  * Set machine context.
166  *
167  * However, we don't set any but the user modifiable flags, and we won't
168  * touch the cs selector.
169  */
170 static int
171 ia32_set_mcontext(struct thread *td, const struct ia32_mcontext *mcp)
172 {
173 	struct trapframe *tp;
174 	long rflags;
175 	int ret;
176 
177 	tp = td->td_frame;
178 	if (mcp->mc_len != sizeof(*mcp))
179 		return (EINVAL);
180 	rflags = (mcp->mc_eflags & PSL_USERCHANGE) |
181 	    (tp->tf_rflags & ~PSL_USERCHANGE);
182 	ret = ia32_set_fpcontext(td, mcp);
183 	if (ret != 0)
184 		return (ret);
185 #if 0	/* XXX deal with load_fs() and friends */
186 	tp->tf_fs = mcp->mc_fs;
187 	tp->tf_es = mcp->mc_es;
188 	tp->tf_ds = mcp->mc_ds;
189 #endif
190 	tp->tf_rdi = mcp->mc_edi;
191 	tp->tf_rsi = mcp->mc_esi;
192 	tp->tf_rbp = mcp->mc_ebp;
193 	tp->tf_rbx = mcp->mc_ebx;
194 	tp->tf_rdx = mcp->mc_edx;
195 	tp->tf_rcx = mcp->mc_ecx;
196 	tp->tf_rax = mcp->mc_eax;
197 	/* trapno, err */
198 	tp->tf_rip = mcp->mc_eip;
199 	tp->tf_rflags = rflags;
200 	tp->tf_rsp = mcp->mc_esp;
201 	tp->tf_ss = mcp->mc_ss;
202 #if 0	/* XXX deal with load_gs() and friends */
203 	td->td_pcb->pcb_gs = mcp->mc_gs;
204 #endif
205 	td->td_pcb->pcb_flags |= PCB_FULLCTX;
206 	return (0);
207 }
208 
209 /*
210  * The first two fields of a ucontext_t are the signal mask and
211  * the machine context.  The next field is uc_link; we want to
212  * avoid destroying the link when copying out contexts.
213  */
214 #define	UC_COPY_SIZE	offsetof(struct ia32_ucontext, uc_link)
215 
216 int
217 freebsd32_getcontext(struct thread *td, struct freebsd32_getcontext_args *uap)
218 {
219 	struct ia32_ucontext uc;
220 	int ret;
221 
222 	if (uap->ucp == NULL)
223 		ret = EINVAL;
224 	else {
225 		ia32_get_mcontext(td, &uc.uc_mcontext, GET_MC_CLEAR_RET);
226 		PROC_LOCK(td->td_proc);
227 		uc.uc_sigmask = td->td_sigmask;
228 		PROC_UNLOCK(td->td_proc);
229 		ret = copyout(&uc, uap->ucp, UC_COPY_SIZE);
230 	}
231 	return (ret);
232 }
233 
234 int
235 freebsd32_setcontext(struct thread *td, struct freebsd32_setcontext_args *uap)
236 {
237 	struct ia32_ucontext uc;
238 	int ret;
239 
240 	if (uap->ucp == NULL)
241 		ret = EINVAL;
242 	else {
243 		ret = copyin(uap->ucp, &uc, UC_COPY_SIZE);
244 		if (ret == 0) {
245 			ret = ia32_set_mcontext(td, &uc.uc_mcontext);
246 			if (ret == 0) {
247 				SIG_CANTMASK(uc.uc_sigmask);
248 				PROC_LOCK(td->td_proc);
249 				td->td_sigmask = uc.uc_sigmask;
250 				PROC_UNLOCK(td->td_proc);
251 			}
252 		}
253 	}
254 	return (ret == 0 ? EJUSTRETURN : ret);
255 }
256 
257 int
258 freebsd32_swapcontext(struct thread *td, struct freebsd32_swapcontext_args *uap)
259 {
260 	struct ia32_ucontext uc;
261 	int ret;
262 
263 	if (uap->oucp == NULL || uap->ucp == NULL)
264 		ret = EINVAL;
265 	else {
266 		ia32_get_mcontext(td, &uc.uc_mcontext, GET_MC_CLEAR_RET);
267 		PROC_LOCK(td->td_proc);
268 		uc.uc_sigmask = td->td_sigmask;
269 		PROC_UNLOCK(td->td_proc);
270 		ret = copyout(&uc, uap->oucp, UC_COPY_SIZE);
271 		if (ret == 0) {
272 			ret = copyin(uap->ucp, &uc, UC_COPY_SIZE);
273 			if (ret == 0) {
274 				ret = ia32_set_mcontext(td, &uc.uc_mcontext);
275 				if (ret == 0) {
276 					SIG_CANTMASK(uc.uc_sigmask);
277 					PROC_LOCK(td->td_proc);
278 					td->td_sigmask = uc.uc_sigmask;
279 					PROC_UNLOCK(td->td_proc);
280 				}
281 			}
282 		}
283 	}
284 	return (ret == 0 ? EJUSTRETURN : ret);
285 }
286 
287 /*
288  * Send an interrupt to process.
289  *
290  * Stack is set up to allow sigcode stored
291  * at top to call routine, followed by kcall
292  * to sigreturn routine below.  After sigreturn
293  * resets the signal mask, the stack, and the
294  * frame pointer, it returns to the user
295  * specified pc, psl.
296  */
297 #ifdef COMPAT_FREEBSD4
298 static void
299 freebsd4_ia32_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
300 {
301 	struct ia32_sigframe4 sf, *sfp;
302 	struct siginfo32 siginfo;
303 	struct proc *p;
304 	struct thread *td;
305 	struct sigacts *psp;
306 	struct trapframe *regs;
307 	int oonstack;
308 	int sig;
309 
310 	td = curthread;
311 	p = td->td_proc;
312 	siginfo_to_siginfo32(&ksi->ksi_info, &siginfo);
313 
314 	PROC_LOCK_ASSERT(p, MA_OWNED);
315 	sig = siginfo.si_signo;
316 	psp = p->p_sigacts;
317 	mtx_assert(&psp->ps_mtx, MA_OWNED);
318 	regs = td->td_frame;
319 	oonstack = sigonstack(regs->tf_rsp);
320 
321 	/* Save user context. */
322 	bzero(&sf, sizeof(sf));
323 	sf.sf_uc.uc_sigmask = *mask;
324 	sf.sf_uc.uc_stack.ss_sp = (uintptr_t)td->td_sigstk.ss_sp;
325 	sf.sf_uc.uc_stack.ss_size = td->td_sigstk.ss_size;
326 	sf.sf_uc.uc_stack.ss_flags = (td->td_pflags & TDP_ALTSTACK)
327 	    ? ((oonstack) ? SS_ONSTACK : 0) : SS_DISABLE;
328 	sf.sf_uc.uc_mcontext.mc_onstack = (oonstack) ? 1 : 0;
329 	sf.sf_uc.uc_mcontext.mc_gs = rgs();
330 	sf.sf_uc.uc_mcontext.mc_fs = rfs();
331 	__asm __volatile("movl %%es,%0" : "=rm" (sf.sf_uc.uc_mcontext.mc_es));
332 	__asm __volatile("movl %%ds,%0" : "=rm" (sf.sf_uc.uc_mcontext.mc_ds));
333 	sf.sf_uc.uc_mcontext.mc_edi = regs->tf_rdi;
334 	sf.sf_uc.uc_mcontext.mc_esi = regs->tf_rsi;
335 	sf.sf_uc.uc_mcontext.mc_ebp = regs->tf_rbp;
336 	sf.sf_uc.uc_mcontext.mc_isp = regs->tf_rsp; /* XXX */
337 	sf.sf_uc.uc_mcontext.mc_ebx = regs->tf_rbx;
338 	sf.sf_uc.uc_mcontext.mc_edx = regs->tf_rdx;
339 	sf.sf_uc.uc_mcontext.mc_ecx = regs->tf_rcx;
340 	sf.sf_uc.uc_mcontext.mc_eax = regs->tf_rax;
341 	sf.sf_uc.uc_mcontext.mc_trapno = regs->tf_trapno;
342 	sf.sf_uc.uc_mcontext.mc_err = regs->tf_err;
343 	sf.sf_uc.uc_mcontext.mc_eip = regs->tf_rip;
344 	sf.sf_uc.uc_mcontext.mc_cs = regs->tf_cs;
345 	sf.sf_uc.uc_mcontext.mc_eflags = regs->tf_rflags;
346 	sf.sf_uc.uc_mcontext.mc_esp = regs->tf_rsp;
347 	sf.sf_uc.uc_mcontext.mc_ss = regs->tf_ss;
348 
349 	/* Allocate space for the signal handler context. */
350 	if ((td->td_pflags & TDP_ALTSTACK) != 0 && !oonstack &&
351 	    SIGISMEMBER(psp->ps_sigonstack, sig)) {
352 		sfp = (struct ia32_sigframe4 *)(td->td_sigstk.ss_sp +
353 		    td->td_sigstk.ss_size - sizeof(sf));
354 	} else
355 		sfp = (struct ia32_sigframe4 *)regs->tf_rsp - 1;
356 	PROC_UNLOCK(p);
357 
358 	/* Translate the signal if appropriate. */
359 	if (p->p_sysent->sv_sigtbl && sig <= p->p_sysent->sv_sigsize)
360 		sig = p->p_sysent->sv_sigtbl[_SIG_IDX(sig)];
361 
362 	/* Build the argument list for the signal handler. */
363 	sf.sf_signum = sig;
364 	sf.sf_ucontext = (register_t)&sfp->sf_uc;
365 	if (SIGISMEMBER(psp->ps_siginfo, sig)) {
366 		/* Signal handler installed with SA_SIGINFO. */
367 		sf.sf_siginfo = (u_int32_t)(uintptr_t)&sfp->sf_si;
368 		sf.sf_ah = (u_int32_t)(uintptr_t)catcher;
369 
370 		/* Fill in POSIX parts */
371 		sf.sf_si = siginfo;
372 		sf.sf_si.si_signo = sig;
373 	} else {
374 		/* Old FreeBSD-style arguments. */
375 		sf.sf_siginfo = siginfo.si_code;
376 		sf.sf_addr = (u_int32_t)siginfo.si_addr;
377 		sf.sf_ah = (u_int32_t)(uintptr_t)catcher;
378 	}
379 	mtx_unlock(&psp->ps_mtx);
380 
381 	/*
382 	 * Copy the sigframe out to the user's stack.
383 	 */
384 	if (copyout(&sf, sfp, sizeof(*sfp)) != 0) {
385 #ifdef DEBUG
386 		printf("process %ld has trashed its stack\n", (long)p->p_pid);
387 #endif
388 		PROC_LOCK(p);
389 		sigexit(td, SIGILL);
390 	}
391 
392 	regs->tf_rsp = (uintptr_t)sfp;
393 	regs->tf_rip = FREEBSD32_PS_STRINGS - sz_freebsd4_ia32_sigcode;
394 	regs->tf_rflags &= ~(PSL_T | PSL_D);
395 	regs->tf_cs = _ucode32sel;
396 	regs->tf_ss = _udatasel;
397 	load_ds(_udatasel);
398 	td->td_pcb->pcb_ds = _udatasel;
399 	load_es(_udatasel);
400 	td->td_pcb->pcb_es = _udatasel;
401 	/* leave user %fs and %gs untouched */
402 	PROC_LOCK(p);
403 	mtx_lock(&psp->ps_mtx);
404 }
405 #endif	/* COMPAT_FREEBSD4 */
406 
407 void
408 ia32_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
409 {
410 	struct ia32_sigframe sf, *sfp;
411 	struct siginfo32 siginfo;
412 	struct proc *p;
413 	struct thread *td;
414 	struct sigacts *psp;
415 	char *sp;
416 	struct trapframe *regs;
417 	int oonstack;
418 	int sig;
419 
420 	siginfo_to_siginfo32(&ksi->ksi_info, &siginfo);
421 	td = curthread;
422 	p = td->td_proc;
423 	PROC_LOCK_ASSERT(p, MA_OWNED);
424 	sig = siginfo.si_signo;
425 	psp = p->p_sigacts;
426 #ifdef COMPAT_FREEBSD4
427 	if (SIGISMEMBER(psp->ps_freebsd4, sig)) {
428 		freebsd4_ia32_sendsig(catcher, ksi, mask);
429 		return;
430 	}
431 #endif
432 	mtx_assert(&psp->ps_mtx, MA_OWNED);
433 	regs = td->td_frame;
434 	oonstack = sigonstack(regs->tf_rsp);
435 
436 	/* Save user context. */
437 	bzero(&sf, sizeof(sf));
438 	sf.sf_uc.uc_sigmask = *mask;
439 	sf.sf_uc.uc_stack.ss_sp = (uintptr_t)td->td_sigstk.ss_sp;
440 	sf.sf_uc.uc_stack.ss_size = td->td_sigstk.ss_size;
441 	sf.sf_uc.uc_stack.ss_flags = (td->td_pflags & TDP_ALTSTACK)
442 	    ? ((oonstack) ? SS_ONSTACK : 0) : SS_DISABLE;
443 	sf.sf_uc.uc_mcontext.mc_onstack = (oonstack) ? 1 : 0;
444 	sf.sf_uc.uc_mcontext.mc_gs = rgs();
445 	sf.sf_uc.uc_mcontext.mc_fs = rfs();
446 	__asm __volatile("movl %%es,%0" : "=rm" (sf.sf_uc.uc_mcontext.mc_es));
447 	__asm __volatile("movl %%ds,%0" : "=rm" (sf.sf_uc.uc_mcontext.mc_ds));
448 	sf.sf_uc.uc_mcontext.mc_edi = regs->tf_rdi;
449 	sf.sf_uc.uc_mcontext.mc_esi = regs->tf_rsi;
450 	sf.sf_uc.uc_mcontext.mc_ebp = regs->tf_rbp;
451 	sf.sf_uc.uc_mcontext.mc_isp = regs->tf_rsp; /* XXX */
452 	sf.sf_uc.uc_mcontext.mc_ebx = regs->tf_rbx;
453 	sf.sf_uc.uc_mcontext.mc_edx = regs->tf_rdx;
454 	sf.sf_uc.uc_mcontext.mc_ecx = regs->tf_rcx;
455 	sf.sf_uc.uc_mcontext.mc_eax = regs->tf_rax;
456 	sf.sf_uc.uc_mcontext.mc_trapno = regs->tf_trapno;
457 	sf.sf_uc.uc_mcontext.mc_err = regs->tf_err;
458 	sf.sf_uc.uc_mcontext.mc_eip = regs->tf_rip;
459 	sf.sf_uc.uc_mcontext.mc_cs = regs->tf_cs;
460 	sf.sf_uc.uc_mcontext.mc_eflags = regs->tf_rflags;
461 	sf.sf_uc.uc_mcontext.mc_esp = regs->tf_rsp;
462 	sf.sf_uc.uc_mcontext.mc_ss = regs->tf_ss;
463 	sf.sf_uc.uc_mcontext.mc_len = sizeof(sf.sf_uc.uc_mcontext); /* magic */
464 	ia32_get_fpcontext(td, &sf.sf_uc.uc_mcontext);
465 	fpstate_drop(td);
466 
467 	/* Allocate space for the signal handler context. */
468 	if ((td->td_pflags & TDP_ALTSTACK) != 0 && !oonstack &&
469 	    SIGISMEMBER(psp->ps_sigonstack, sig)) {
470 		sp = td->td_sigstk.ss_sp +
471 		    td->td_sigstk.ss_size - sizeof(sf);
472 	} else
473 		sp = (char *)regs->tf_rsp - sizeof(sf);
474 	/* Align to 16 bytes. */
475 	sfp = (struct ia32_sigframe *)((uintptr_t)sp & ~0xF);
476 	PROC_UNLOCK(p);
477 
478 	/* Translate the signal if appropriate. */
479 	if (p->p_sysent->sv_sigtbl && sig <= p->p_sysent->sv_sigsize)
480 		sig = p->p_sysent->sv_sigtbl[_SIG_IDX(sig)];
481 
482 	/* Build the argument list for the signal handler. */
483 	sf.sf_signum = sig;
484 	sf.sf_ucontext = (register_t)&sfp->sf_uc;
485 	if (SIGISMEMBER(psp->ps_siginfo, sig)) {
486 		/* Signal handler installed with SA_SIGINFO. */
487 		sf.sf_siginfo = (u_int32_t)(uintptr_t)&sfp->sf_si;
488 		sf.sf_ah = (u_int32_t)(uintptr_t)catcher;
489 
490 		/* Fill in POSIX parts */
491 		sf.sf_si = siginfo;
492 		sf.sf_si.si_signo = sig;
493 	} else {
494 		/* Old FreeBSD-style arguments. */
495 		sf.sf_siginfo = siginfo.si_code;
496 		sf.sf_addr = (u_int32_t)siginfo.si_addr;
497 		sf.sf_ah = (u_int32_t)(uintptr_t)catcher;
498 	}
499 	mtx_unlock(&psp->ps_mtx);
500 
501 	/*
502 	 * Copy the sigframe out to the user's stack.
503 	 */
504 	if (copyout(&sf, sfp, sizeof(*sfp)) != 0) {
505 #ifdef DEBUG
506 		printf("process %ld has trashed its stack\n", (long)p->p_pid);
507 #endif
508 		PROC_LOCK(p);
509 		sigexit(td, SIGILL);
510 	}
511 
512 	regs->tf_rsp = (uintptr_t)sfp;
513 	regs->tf_rip = FREEBSD32_PS_STRINGS - *(p->p_sysent->sv_szsigcode);
514 	regs->tf_rflags &= ~(PSL_T | PSL_D);
515 	regs->tf_cs = _ucode32sel;
516 	regs->tf_ss = _udatasel;
517 	load_ds(_udatasel);
518 	td->td_pcb->pcb_ds = _udatasel;
519 	load_es(_udatasel);
520 	td->td_pcb->pcb_es = _udatasel;
521 	/* leave user %fs and %gs untouched */
522 	PROC_LOCK(p);
523 	mtx_lock(&psp->ps_mtx);
524 }
525 
526 /*
527  * System call to cleanup state after a signal
528  * has been taken.  Reset signal mask and
529  * stack state from context left by sendsig (above).
530  * Return to previous pc and psl as specified by
531  * context left by sendsig. Check carefully to
532  * make sure that the user has not modified the
533  * state to gain improper privileges.
534  */
535 #ifdef COMPAT_FREEBSD4
536 /*
537  * MPSAFE
538  */
539 int
540 freebsd4_freebsd32_sigreturn(td, uap)
541 	struct thread *td;
542 	struct freebsd4_freebsd32_sigreturn_args /* {
543 		const struct freebsd4_freebsd32_ucontext *sigcntxp;
544 	} */ *uap;
545 {
546 	struct ia32_ucontext4 uc;
547 	struct proc *p = td->td_proc;
548 	struct trapframe *regs;
549 	const struct ia32_ucontext4 *ucp;
550 	int cs, eflags, error;
551 	ksiginfo_t ksi;
552 
553 	error = copyin(uap->sigcntxp, &uc, sizeof(uc));
554 	if (error != 0)
555 		return (error);
556 	ucp = &uc;
557 	regs = td->td_frame;
558 	eflags = ucp->uc_mcontext.mc_eflags;
559 	/*
560 	 * Don't allow users to change privileged or reserved flags.
561 	 */
562 	/*
563 	 * XXX do allow users to change the privileged flag PSL_RF.
564 	 * The cpu sets PSL_RF in tf_eflags for faults.  Debuggers
565 	 * should sometimes set it there too.  tf_eflags is kept in
566 	 * the signal context during signal handling and there is no
567 	 * other place to remember it, so the PSL_RF bit may be
568 	 * corrupted by the signal handler without us knowing.
569 	 * Corruption of the PSL_RF bit at worst causes one more or
570 	 * one less debugger trap, so allowing it is fairly harmless.
571 	 */
572 	if (!EFL_SECURE(eflags & ~PSL_RF, regs->tf_rflags & ~PSL_RF)) {
573 		printf("freebsd4_freebsd32_sigreturn: eflags = 0x%x\n", eflags);
574 		return (EINVAL);
575 	}
576 
577 	/*
578 	 * Don't allow users to load a valid privileged %cs.  Let the
579 	 * hardware check for invalid selectors, excess privilege in
580 	 * other selectors, invalid %eip's and invalid %esp's.
581 	 */
582 	cs = ucp->uc_mcontext.mc_cs;
583 	if (!CS_SECURE(cs)) {
584 		printf("freebsd4_sigreturn: cs = 0x%x\n", cs);
585 		ksiginfo_init_trap(&ksi);
586 		ksi.ksi_signo = SIGBUS;
587 		ksi.ksi_code = BUS_OBJERR;
588 		ksi.ksi_trapno = T_PROTFLT;
589 		ksi.ksi_addr = (void *)regs->tf_rip;
590 		trapsignal(td, &ksi);
591 		return (EINVAL);
592 	}
593 
594 	/* Segment selectors restored by sigtramp.S */
595 	regs->tf_rdi = ucp->uc_mcontext.mc_edi;
596 	regs->tf_rsi = ucp->uc_mcontext.mc_esi;
597 	regs->tf_rbp = ucp->uc_mcontext.mc_ebp;
598 	regs->tf_rbx = ucp->uc_mcontext.mc_ebx;
599 	regs->tf_rdx = ucp->uc_mcontext.mc_edx;
600 	regs->tf_rcx = ucp->uc_mcontext.mc_ecx;
601 	regs->tf_rax = ucp->uc_mcontext.mc_eax;
602 	regs->tf_trapno = ucp->uc_mcontext.mc_trapno;
603 	regs->tf_err = ucp->uc_mcontext.mc_err;
604 	regs->tf_rip = ucp->uc_mcontext.mc_eip;
605 	regs->tf_cs = cs;
606 	regs->tf_rflags = ucp->uc_mcontext.mc_eflags;
607 	regs->tf_rsp = ucp->uc_mcontext.mc_esp;
608 	regs->tf_ss = ucp->uc_mcontext.mc_ss;
609 
610 	PROC_LOCK(p);
611 	td->td_sigmask = ucp->uc_sigmask;
612 	SIG_CANTMASK(td->td_sigmask);
613 	signotify(td);
614 	PROC_UNLOCK(p);
615 	return (EJUSTRETURN);
616 }
617 #endif	/* COMPAT_FREEBSD4 */
618 
619 /*
620  * MPSAFE
621  */
622 int
623 freebsd32_sigreturn(td, uap)
624 	struct thread *td;
625 	struct freebsd32_sigreturn_args /* {
626 		const struct freebsd32_ucontext *sigcntxp;
627 	} */ *uap;
628 {
629 	struct ia32_ucontext uc;
630 	struct proc *p = td->td_proc;
631 	struct trapframe *regs;
632 	const struct ia32_ucontext *ucp;
633 	int cs, eflags, error, ret;
634 	ksiginfo_t ksi;
635 
636 	error = copyin(uap->sigcntxp, &uc, sizeof(uc));
637 	if (error != 0)
638 		return (error);
639 	ucp = &uc;
640 	regs = td->td_frame;
641 	eflags = ucp->uc_mcontext.mc_eflags;
642 	/*
643 	 * Don't allow users to change privileged or reserved flags.
644 	 */
645 	/*
646 	 * XXX do allow users to change the privileged flag PSL_RF.
647 	 * The cpu sets PSL_RF in tf_eflags for faults.  Debuggers
648 	 * should sometimes set it there too.  tf_eflags is kept in
649 	 * the signal context during signal handling and there is no
650 	 * other place to remember it, so the PSL_RF bit may be
651 	 * corrupted by the signal handler without us knowing.
652 	 * Corruption of the PSL_RF bit at worst causes one more or
653 	 * one less debugger trap, so allowing it is fairly harmless.
654 	 */
655 	if (!EFL_SECURE(eflags & ~PSL_RF, regs->tf_rflags & ~PSL_RF)) {
656 		printf("freebsd32_sigreturn: eflags = 0x%x\n", eflags);
657 		return (EINVAL);
658 	}
659 
660 	/*
661 	 * Don't allow users to load a valid privileged %cs.  Let the
662 	 * hardware check for invalid selectors, excess privilege in
663 	 * other selectors, invalid %eip's and invalid %esp's.
664 	 */
665 	cs = ucp->uc_mcontext.mc_cs;
666 	if (!CS_SECURE(cs)) {
667 		printf("sigreturn: cs = 0x%x\n", cs);
668 		ksiginfo_init_trap(&ksi);
669 		ksi.ksi_signo = SIGBUS;
670 		ksi.ksi_code = BUS_OBJERR;
671 		ksi.ksi_trapno = T_PROTFLT;
672 		ksi.ksi_addr = (void *)regs->tf_rip;
673 		trapsignal(td, &ksi);
674 		return (EINVAL);
675 	}
676 
677 	ret = ia32_set_fpcontext(td, &ucp->uc_mcontext);
678 	if (ret != 0)
679 		return (ret);
680 
681 	/* Segment selectors restored by sigtramp.S */
682 	regs->tf_rdi = ucp->uc_mcontext.mc_edi;
683 	regs->tf_rsi = ucp->uc_mcontext.mc_esi;
684 	regs->tf_rbp = ucp->uc_mcontext.mc_ebp;
685 	regs->tf_rbx = ucp->uc_mcontext.mc_ebx;
686 	regs->tf_rdx = ucp->uc_mcontext.mc_edx;
687 	regs->tf_rcx = ucp->uc_mcontext.mc_ecx;
688 	regs->tf_rax = ucp->uc_mcontext.mc_eax;
689 	regs->tf_trapno = ucp->uc_mcontext.mc_trapno;
690 	regs->tf_err = ucp->uc_mcontext.mc_err;
691 	regs->tf_rip = ucp->uc_mcontext.mc_eip;
692 	regs->tf_cs = cs;
693 	regs->tf_rflags = ucp->uc_mcontext.mc_eflags;
694 	regs->tf_rsp = ucp->uc_mcontext.mc_esp;
695 	regs->tf_ss = ucp->uc_mcontext.mc_ss;
696 
697 	PROC_LOCK(p);
698 	td->td_sigmask = ucp->uc_sigmask;
699 	SIG_CANTMASK(td->td_sigmask);
700 	signotify(td);
701 	PROC_UNLOCK(p);
702 	return (EJUSTRETURN);
703 }
704 
705 /*
706  * Clear registers on exec
707  */
708 void
709 ia32_setregs(td, entry, stack, ps_strings)
710 	struct thread *td;
711 	u_long entry;
712 	u_long stack;
713 	u_long ps_strings;
714 {
715 	struct trapframe *regs = td->td_frame;
716 	struct pcb *pcb = td->td_pcb;
717 
718 	critical_enter();
719 	wrmsr(MSR_FSBASE, 0);
720 	wrmsr(MSR_KGSBASE, 0);	/* User value while we're in the kernel */
721 	pcb->pcb_fsbase = 0;
722 	pcb->pcb_gsbase = 0;
723 	critical_exit();
724 	load_ds(_udatasel);
725 	load_es(_udatasel);
726 	load_fs(_udatasel);
727 	load_gs(_udatasel);
728 	pcb->pcb_ds = _udatasel;
729 	pcb->pcb_es = _udatasel;
730 	pcb->pcb_fs = _udatasel;
731 	pcb->pcb_gs = _udatasel;
732 
733 	bzero((char *)regs, sizeof(struct trapframe));
734 	regs->tf_rip = entry;
735 	regs->tf_rsp = stack;
736 	regs->tf_rflags = PSL_USER | (regs->tf_rflags & PSL_T);
737 	regs->tf_ss = _udatasel;
738 	regs->tf_cs = _ucode32sel;
739 	regs->tf_rbx = ps_strings;
740 	load_cr0(rcr0() | CR0_MP | CR0_TS);
741 	fpstate_drop(td);
742 
743 	/* Return via doreti so that we can change to a different %cs */
744 	pcb->pcb_flags |= PCB_FULLCTX | PCB_32BIT;
745 	td->td_retval[1] = 0;
746 }
747