xref: /freebsd/sys/amd64/ia32/ia32_signal.c (revision aa64588d28258aef88cc33b8043112e8856948d0)
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 #define	CS_SECURE(cs)		(ISPL(cs) == SEL_UPL)
89 #define	EFL_SECURE(ef, oef)	((((ef) ^ (oef)) & ~PSL_USERCHANGE) == 0)
90 
91 static void
92 ia32_get_fpcontext(struct thread *td, struct ia32_mcontext *mcp)
93 {
94 
95 	mcp->mc_ownedfp = fpugetregs(td, (struct savefpu *)&mcp->mc_fpstate);
96 	mcp->mc_fpformat = fpuformat();
97 }
98 
99 static int
100 ia32_set_fpcontext(struct thread *td, const struct ia32_mcontext *mcp)
101 {
102 
103 	if (mcp->mc_fpformat == _MC_FPFMT_NODEV)
104 		return (0);
105 	else if (mcp->mc_fpformat != _MC_FPFMT_XMM)
106 		return (EINVAL);
107 	else if (mcp->mc_ownedfp == _MC_FPOWNED_NONE)
108 		/* We don't care what state is left in the FPU or PCB. */
109 		fpstate_drop(td);
110 	else if (mcp->mc_ownedfp == _MC_FPOWNED_FPU ||
111 	    mcp->mc_ownedfp == _MC_FPOWNED_PCB) {
112 		/*
113 		 * XXX we violate the dubious requirement that fpusetregs()
114 		 * be called with interrupts disabled.
115 		 */
116 		fpusetregs(td, (struct savefpu *)&mcp->mc_fpstate);
117 	} else
118 		return (EINVAL);
119 	return (0);
120 }
121 
122 /*
123  * Get machine context.
124  */
125 static int
126 ia32_get_mcontext(struct thread *td, struct ia32_mcontext *mcp, int flags)
127 {
128 	struct trapframe *tp;
129 
130 	tp = td->td_frame;
131 
132 	PROC_LOCK(curthread->td_proc);
133 	mcp->mc_onstack = sigonstack(tp->tf_rsp);
134 	PROC_UNLOCK(curthread->td_proc);
135 	/* Entry into kernel always sets TF_HASSEGS */
136 	mcp->mc_gs = tp->tf_gs;
137 	mcp->mc_fs = tp->tf_fs;
138 	mcp->mc_es = tp->tf_es;
139 	mcp->mc_ds = tp->tf_ds;
140 	mcp->mc_edi = tp->tf_rdi;
141 	mcp->mc_esi = tp->tf_rsi;
142 	mcp->mc_ebp = tp->tf_rbp;
143 	mcp->mc_isp = tp->tf_rsp;
144 	mcp->mc_eflags = tp->tf_rflags;
145 	if (flags & GET_MC_CLEAR_RET) {
146 		mcp->mc_eax = 0;
147 		mcp->mc_edx = 0;
148 		mcp->mc_eflags &= ~PSL_C;
149 	} else {
150 		mcp->mc_eax = tp->tf_rax;
151 		mcp->mc_edx = tp->tf_rdx;
152 	}
153 	mcp->mc_ebx = tp->tf_rbx;
154 	mcp->mc_ecx = tp->tf_rcx;
155 	mcp->mc_eip = tp->tf_rip;
156 	mcp->mc_cs = tp->tf_cs;
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 	mcp->mc_fsbase = td->td_pcb->pcb_fsbase;
162 	mcp->mc_gsbase = td->td_pcb->pcb_gsbase;
163 	td->td_pcb->pcb_full_iret = 1;
164 	return (0);
165 }
166 
167 /*
168  * Set machine context.
169  *
170  * However, we don't set any but the user modifiable flags, and we won't
171  * touch the cs selector.
172  */
173 static int
174 ia32_set_mcontext(struct thread *td, const struct ia32_mcontext *mcp)
175 {
176 	struct trapframe *tp;
177 	long rflags;
178 	int ret;
179 
180 	tp = td->td_frame;
181 	if (mcp->mc_len != sizeof(*mcp))
182 		return (EINVAL);
183 	rflags = (mcp->mc_eflags & PSL_USERCHANGE) |
184 	    (tp->tf_rflags & ~PSL_USERCHANGE);
185 	ret = ia32_set_fpcontext(td, mcp);
186 	if (ret != 0)
187 		return (ret);
188 	tp->tf_gs = mcp->mc_gs;
189 	tp->tf_fs = mcp->mc_fs;
190 	tp->tf_es = mcp->mc_es;
191 	tp->tf_ds = mcp->mc_ds;
192 	tp->tf_flags = TF_HASSEGS;
193 	tp->tf_rdi = mcp->mc_edi;
194 	tp->tf_rsi = mcp->mc_esi;
195 	tp->tf_rbp = mcp->mc_ebp;
196 	tp->tf_rbx = mcp->mc_ebx;
197 	tp->tf_rdx = mcp->mc_edx;
198 	tp->tf_rcx = mcp->mc_ecx;
199 	tp->tf_rax = mcp->mc_eax;
200 	/* trapno, err */
201 	tp->tf_rip = mcp->mc_eip;
202 	tp->tf_rflags = rflags;
203 	tp->tf_rsp = mcp->mc_esp;
204 	tp->tf_ss = mcp->mc_ss;
205 	td->td_pcb->pcb_flags |= PCB_FULLCTX;
206 	td->td_pcb->pcb_full_iret = 1;
207 	return (0);
208 }
209 
210 /*
211  * The first two fields of a ucontext_t are the signal mask and
212  * the machine context.  The next field is uc_link; we want to
213  * avoid destroying the link when copying out contexts.
214  */
215 #define	UC_COPY_SIZE	offsetof(struct ia32_ucontext, uc_link)
216 
217 int
218 freebsd32_getcontext(struct thread *td, struct freebsd32_getcontext_args *uap)
219 {
220 	struct ia32_ucontext uc;
221 	int ret;
222 
223 	if (uap->ucp == NULL)
224 		ret = EINVAL;
225 	else {
226 		ia32_get_mcontext(td, &uc.uc_mcontext, GET_MC_CLEAR_RET);
227 		PROC_LOCK(td->td_proc);
228 		uc.uc_sigmask = td->td_sigmask;
229 		PROC_UNLOCK(td->td_proc);
230 		ret = copyout(&uc, uap->ucp, UC_COPY_SIZE);
231 	}
232 	return (ret);
233 }
234 
235 int
236 freebsd32_setcontext(struct thread *td, struct freebsd32_setcontext_args *uap)
237 {
238 	struct ia32_ucontext uc;
239 	int ret;
240 
241 	if (uap->ucp == NULL)
242 		ret = EINVAL;
243 	else {
244 		ret = copyin(uap->ucp, &uc, UC_COPY_SIZE);
245 		if (ret == 0) {
246 			ret = ia32_set_mcontext(td, &uc.uc_mcontext);
247 			if (ret == 0) {
248 				kern_sigprocmask(td, SIG_SETMASK,
249 				    &uc.uc_sigmask, NULL, 0);
250 			}
251 		}
252 	}
253 	return (ret == 0 ? EJUSTRETURN : ret);
254 }
255 
256 int
257 freebsd32_swapcontext(struct thread *td, struct freebsd32_swapcontext_args *uap)
258 {
259 	struct ia32_ucontext uc;
260 	int ret;
261 
262 	if (uap->oucp == NULL || uap->ucp == NULL)
263 		ret = EINVAL;
264 	else {
265 		ia32_get_mcontext(td, &uc.uc_mcontext, GET_MC_CLEAR_RET);
266 		PROC_LOCK(td->td_proc);
267 		uc.uc_sigmask = td->td_sigmask;
268 		PROC_UNLOCK(td->td_proc);
269 		ret = copyout(&uc, uap->oucp, UC_COPY_SIZE);
270 		if (ret == 0) {
271 			ret = copyin(uap->ucp, &uc, UC_COPY_SIZE);
272 			if (ret == 0) {
273 				ret = ia32_set_mcontext(td, &uc.uc_mcontext);
274 				if (ret == 0) {
275 					kern_sigprocmask(td, SIG_SETMASK,
276 					    &uc.uc_sigmask, NULL, 0);
277 				}
278 			}
279 		}
280 	}
281 	return (ret == 0 ? EJUSTRETURN : ret);
282 }
283 
284 /*
285  * Send an interrupt to process.
286  *
287  * Stack is set up to allow sigcode stored
288  * at top to call routine, followed by kcall
289  * to sigreturn routine below.  After sigreturn
290  * resets the signal mask, the stack, and the
291  * frame pointer, it returns to the user
292  * specified pc, psl.
293  */
294 #ifdef COMPAT_FREEBSD4
295 static void
296 freebsd4_ia32_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
297 {
298 	struct ia32_sigframe4 sf, *sfp;
299 	struct siginfo32 siginfo;
300 	struct proc *p;
301 	struct thread *td;
302 	struct sigacts *psp;
303 	struct trapframe *regs;
304 	int oonstack;
305 	int sig;
306 
307 	td = curthread;
308 	p = td->td_proc;
309 	siginfo_to_siginfo32(&ksi->ksi_info, &siginfo);
310 
311 	PROC_LOCK_ASSERT(p, MA_OWNED);
312 	sig = siginfo.si_signo;
313 	psp = p->p_sigacts;
314 	mtx_assert(&psp->ps_mtx, MA_OWNED);
315 	regs = td->td_frame;
316 	oonstack = sigonstack(regs->tf_rsp);
317 
318 	/* Save user context. */
319 	bzero(&sf, sizeof(sf));
320 	sf.sf_uc.uc_sigmask = *mask;
321 	sf.sf_uc.uc_stack.ss_sp = (uintptr_t)td->td_sigstk.ss_sp;
322 	sf.sf_uc.uc_stack.ss_size = td->td_sigstk.ss_size;
323 	sf.sf_uc.uc_stack.ss_flags = (td->td_pflags & TDP_ALTSTACK)
324 	    ? ((oonstack) ? SS_ONSTACK : 0) : SS_DISABLE;
325 	sf.sf_uc.uc_mcontext.mc_onstack = (oonstack) ? 1 : 0;
326 	sf.sf_uc.uc_mcontext.mc_edi = regs->tf_rdi;
327 	sf.sf_uc.uc_mcontext.mc_esi = regs->tf_rsi;
328 	sf.sf_uc.uc_mcontext.mc_ebp = regs->tf_rbp;
329 	sf.sf_uc.uc_mcontext.mc_isp = regs->tf_rsp; /* XXX */
330 	sf.sf_uc.uc_mcontext.mc_ebx = regs->tf_rbx;
331 	sf.sf_uc.uc_mcontext.mc_edx = regs->tf_rdx;
332 	sf.sf_uc.uc_mcontext.mc_ecx = regs->tf_rcx;
333 	sf.sf_uc.uc_mcontext.mc_eax = regs->tf_rax;
334 	sf.sf_uc.uc_mcontext.mc_trapno = regs->tf_trapno;
335 	sf.sf_uc.uc_mcontext.mc_err = regs->tf_err;
336 	sf.sf_uc.uc_mcontext.mc_eip = regs->tf_rip;
337 	sf.sf_uc.uc_mcontext.mc_cs = regs->tf_cs;
338 	sf.sf_uc.uc_mcontext.mc_eflags = regs->tf_rflags;
339 	sf.sf_uc.uc_mcontext.mc_esp = regs->tf_rsp;
340 	sf.sf_uc.uc_mcontext.mc_ss = regs->tf_ss;
341 	sf.sf_uc.uc_mcontext.mc_ds = regs->tf_ds;
342 	sf.sf_uc.uc_mcontext.mc_es = regs->tf_es;
343 	sf.sf_uc.uc_mcontext.mc_fs = regs->tf_fs;
344 	sf.sf_uc.uc_mcontext.mc_gs = regs->tf_gs;
345 
346 	/* Allocate space for the signal handler context. */
347 	if ((td->td_pflags & TDP_ALTSTACK) != 0 && !oonstack &&
348 	    SIGISMEMBER(psp->ps_sigonstack, sig)) {
349 		sfp = (struct ia32_sigframe4 *)(td->td_sigstk.ss_sp +
350 		    td->td_sigstk.ss_size - sizeof(sf));
351 	} else
352 		sfp = (struct ia32_sigframe4 *)regs->tf_rsp - 1;
353 	PROC_UNLOCK(p);
354 
355 	/* Translate the signal if appropriate. */
356 	if (p->p_sysent->sv_sigtbl && sig <= p->p_sysent->sv_sigsize)
357 		sig = p->p_sysent->sv_sigtbl[_SIG_IDX(sig)];
358 
359 	/* Build the argument list for the signal handler. */
360 	sf.sf_signum = sig;
361 	sf.sf_ucontext = (register_t)&sfp->sf_uc;
362 	if (SIGISMEMBER(psp->ps_siginfo, sig)) {
363 		/* Signal handler installed with SA_SIGINFO. */
364 		sf.sf_siginfo = (u_int32_t)(uintptr_t)&sfp->sf_si;
365 		sf.sf_ah = (u_int32_t)(uintptr_t)catcher;
366 
367 		/* Fill in POSIX parts */
368 		sf.sf_si = siginfo;
369 		sf.sf_si.si_signo = sig;
370 	} else {
371 		/* Old FreeBSD-style arguments. */
372 		sf.sf_siginfo = siginfo.si_code;
373 		sf.sf_addr = (u_int32_t)siginfo.si_addr;
374 		sf.sf_ah = (u_int32_t)(uintptr_t)catcher;
375 	}
376 	mtx_unlock(&psp->ps_mtx);
377 
378 	/*
379 	 * Copy the sigframe out to the user's stack.
380 	 */
381 	if (copyout(&sf, sfp, sizeof(*sfp)) != 0) {
382 #ifdef DEBUG
383 		printf("process %ld has trashed its stack\n", (long)p->p_pid);
384 #endif
385 		PROC_LOCK(p);
386 		sigexit(td, SIGILL);
387 	}
388 
389 	regs->tf_rsp = (uintptr_t)sfp;
390 	regs->tf_rip = FREEBSD32_PS_STRINGS - sz_freebsd4_ia32_sigcode;
391 	regs->tf_rflags &= ~(PSL_T | PSL_D);
392 	regs->tf_cs = _ucode32sel;
393 	regs->tf_ss = _udatasel;
394 	regs->tf_ds = _udatasel;
395 	regs->tf_es = _udatasel;
396 	td->td_pcb->pcb_full_iret = 1;
397 	/* leave user %fs and %gs untouched */
398 	PROC_LOCK(p);
399 	mtx_lock(&psp->ps_mtx);
400 }
401 #endif	/* COMPAT_FREEBSD4 */
402 
403 void
404 ia32_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
405 {
406 	struct ia32_sigframe sf, *sfp;
407 	struct siginfo32 siginfo;
408 	struct proc *p;
409 	struct thread *td;
410 	struct sigacts *psp;
411 	char *sp;
412 	struct trapframe *regs;
413 	int oonstack;
414 	int sig;
415 
416 	siginfo_to_siginfo32(&ksi->ksi_info, &siginfo);
417 	td = curthread;
418 	p = td->td_proc;
419 	PROC_LOCK_ASSERT(p, MA_OWNED);
420 	sig = siginfo.si_signo;
421 	psp = p->p_sigacts;
422 #ifdef COMPAT_FREEBSD4
423 	if (SIGISMEMBER(psp->ps_freebsd4, sig)) {
424 		freebsd4_ia32_sendsig(catcher, ksi, mask);
425 		return;
426 	}
427 #endif
428 	mtx_assert(&psp->ps_mtx, MA_OWNED);
429 	regs = td->td_frame;
430 	oonstack = sigonstack(regs->tf_rsp);
431 
432 	/* Save user context. */
433 	bzero(&sf, sizeof(sf));
434 	sf.sf_uc.uc_sigmask = *mask;
435 	sf.sf_uc.uc_stack.ss_sp = (uintptr_t)td->td_sigstk.ss_sp;
436 	sf.sf_uc.uc_stack.ss_size = td->td_sigstk.ss_size;
437 	sf.sf_uc.uc_stack.ss_flags = (td->td_pflags & TDP_ALTSTACK)
438 	    ? ((oonstack) ? SS_ONSTACK : 0) : SS_DISABLE;
439 	sf.sf_uc.uc_mcontext.mc_onstack = (oonstack) ? 1 : 0;
440 	sf.sf_uc.uc_mcontext.mc_edi = regs->tf_rdi;
441 	sf.sf_uc.uc_mcontext.mc_esi = regs->tf_rsi;
442 	sf.sf_uc.uc_mcontext.mc_ebp = regs->tf_rbp;
443 	sf.sf_uc.uc_mcontext.mc_isp = regs->tf_rsp; /* XXX */
444 	sf.sf_uc.uc_mcontext.mc_ebx = regs->tf_rbx;
445 	sf.sf_uc.uc_mcontext.mc_edx = regs->tf_rdx;
446 	sf.sf_uc.uc_mcontext.mc_ecx = regs->tf_rcx;
447 	sf.sf_uc.uc_mcontext.mc_eax = regs->tf_rax;
448 	sf.sf_uc.uc_mcontext.mc_trapno = regs->tf_trapno;
449 	sf.sf_uc.uc_mcontext.mc_err = regs->tf_err;
450 	sf.sf_uc.uc_mcontext.mc_eip = regs->tf_rip;
451 	sf.sf_uc.uc_mcontext.mc_cs = regs->tf_cs;
452 	sf.sf_uc.uc_mcontext.mc_eflags = regs->tf_rflags;
453 	sf.sf_uc.uc_mcontext.mc_esp = regs->tf_rsp;
454 	sf.sf_uc.uc_mcontext.mc_ss = regs->tf_ss;
455 	sf.sf_uc.uc_mcontext.mc_ds = regs->tf_ds;
456 	sf.sf_uc.uc_mcontext.mc_es = regs->tf_es;
457 	sf.sf_uc.uc_mcontext.mc_fs = regs->tf_fs;
458 	sf.sf_uc.uc_mcontext.mc_gs = regs->tf_gs;
459 	sf.sf_uc.uc_mcontext.mc_len = sizeof(sf.sf_uc.uc_mcontext); /* magic */
460 	ia32_get_fpcontext(td, &sf.sf_uc.uc_mcontext);
461 	fpstate_drop(td);
462 	sf.sf_uc.uc_mcontext.mc_fsbase = td->td_pcb->pcb_fsbase;
463 	sf.sf_uc.uc_mcontext.mc_gsbase = td->td_pcb->pcb_gsbase;
464 
465 	/* Allocate space for the signal handler context. */
466 	if ((td->td_pflags & TDP_ALTSTACK) != 0 && !oonstack &&
467 	    SIGISMEMBER(psp->ps_sigonstack, sig)) {
468 		sp = td->td_sigstk.ss_sp +
469 		    td->td_sigstk.ss_size - sizeof(sf);
470 	} else
471 		sp = (char *)regs->tf_rsp - sizeof(sf);
472 	/* Align to 16 bytes. */
473 	sfp = (struct ia32_sigframe *)((uintptr_t)sp & ~0xF);
474 	PROC_UNLOCK(p);
475 
476 	/* Translate the signal if appropriate. */
477 	if (p->p_sysent->sv_sigtbl && sig <= p->p_sysent->sv_sigsize)
478 		sig = p->p_sysent->sv_sigtbl[_SIG_IDX(sig)];
479 
480 	/* Build the argument list for the signal handler. */
481 	sf.sf_signum = sig;
482 	sf.sf_ucontext = (register_t)&sfp->sf_uc;
483 	if (SIGISMEMBER(psp->ps_siginfo, sig)) {
484 		/* Signal handler installed with SA_SIGINFO. */
485 		sf.sf_siginfo = (u_int32_t)(uintptr_t)&sfp->sf_si;
486 		sf.sf_ah = (u_int32_t)(uintptr_t)catcher;
487 
488 		/* Fill in POSIX parts */
489 		sf.sf_si = siginfo;
490 		sf.sf_si.si_signo = sig;
491 	} else {
492 		/* Old FreeBSD-style arguments. */
493 		sf.sf_siginfo = siginfo.si_code;
494 		sf.sf_addr = (u_int32_t)siginfo.si_addr;
495 		sf.sf_ah = (u_int32_t)(uintptr_t)catcher;
496 	}
497 	mtx_unlock(&psp->ps_mtx);
498 
499 	/*
500 	 * Copy the sigframe out to the user's stack.
501 	 */
502 	if (copyout(&sf, sfp, sizeof(*sfp)) != 0) {
503 #ifdef DEBUG
504 		printf("process %ld has trashed its stack\n", (long)p->p_pid);
505 #endif
506 		PROC_LOCK(p);
507 		sigexit(td, SIGILL);
508 	}
509 
510 	regs->tf_rsp = (uintptr_t)sfp;
511 	regs->tf_rip = FREEBSD32_PS_STRINGS - *(p->p_sysent->sv_szsigcode);
512 	regs->tf_rflags &= ~(PSL_T | PSL_D);
513 	regs->tf_cs = _ucode32sel;
514 	regs->tf_ss = _udatasel;
515 	regs->tf_ds = _udatasel;
516 	regs->tf_es = _udatasel;
517 	td->td_pcb->pcb_full_iret = 1;
518 	/* XXXKIB leave user %fs and %gs untouched */
519 	PROC_LOCK(p);
520 	mtx_lock(&psp->ps_mtx);
521 }
522 
523 /*
524  * System call to cleanup state after a signal
525  * has been taken.  Reset signal mask and
526  * stack state from context left by sendsig (above).
527  * Return to previous pc and psl as specified by
528  * context left by sendsig. Check carefully to
529  * make sure that the user has not modified the
530  * state to gain improper privileges.
531  */
532 #ifdef COMPAT_FREEBSD4
533 /*
534  * MPSAFE
535  */
536 int
537 freebsd4_freebsd32_sigreturn(td, uap)
538 	struct thread *td;
539 	struct freebsd4_freebsd32_sigreturn_args /* {
540 		const struct freebsd4_freebsd32_ucontext *sigcntxp;
541 	} */ *uap;
542 {
543 	struct ia32_ucontext4 uc;
544 	struct trapframe *regs;
545 	struct ia32_ucontext4 *ucp;
546 	int cs, eflags, error;
547 	ksiginfo_t ksi;
548 
549 	error = copyin(uap->sigcntxp, &uc, sizeof(uc));
550 	if (error != 0)
551 		return (error);
552 	ucp = &uc;
553 	regs = td->td_frame;
554 	eflags = ucp->uc_mcontext.mc_eflags;
555 	/*
556 	 * Don't allow users to change privileged or reserved flags.
557 	 */
558 	/*
559 	 * XXX do allow users to change the privileged flag PSL_RF.
560 	 * The cpu sets PSL_RF in tf_eflags for faults.  Debuggers
561 	 * should sometimes set it there too.  tf_eflags is kept in
562 	 * the signal context during signal handling and there is no
563 	 * other place to remember it, so the PSL_RF bit may be
564 	 * corrupted by the signal handler without us knowing.
565 	 * Corruption of the PSL_RF bit at worst causes one more or
566 	 * one less debugger trap, so allowing it is fairly harmless.
567 	 */
568 	if (!EFL_SECURE(eflags & ~PSL_RF, regs->tf_rflags & ~PSL_RF)) {
569 		uprintf("pid %d (%s): freebsd4_freebsd32_sigreturn eflags = 0x%x\n",
570 		    td->td_proc->p_pid, td->td_name, eflags);
571 		return (EINVAL);
572 	}
573 
574 	/*
575 	 * Don't allow users to load a valid privileged %cs.  Let the
576 	 * hardware check for invalid selectors, excess privilege in
577 	 * other selectors, invalid %eip's and invalid %esp's.
578 	 */
579 	cs = ucp->uc_mcontext.mc_cs;
580 	if (!CS_SECURE(cs)) {
581 		uprintf("pid %d (%s): freebsd4_sigreturn cs = 0x%x\n",
582 		    td->td_proc->p_pid, td->td_name, cs);
583 		ksiginfo_init_trap(&ksi);
584 		ksi.ksi_signo = SIGBUS;
585 		ksi.ksi_code = BUS_OBJERR;
586 		ksi.ksi_trapno = T_PROTFLT;
587 		ksi.ksi_addr = (void *)regs->tf_rip;
588 		trapsignal(td, &ksi);
589 		return (EINVAL);
590 	}
591 
592 	regs->tf_rdi = ucp->uc_mcontext.mc_edi;
593 	regs->tf_rsi = ucp->uc_mcontext.mc_esi;
594 	regs->tf_rbp = ucp->uc_mcontext.mc_ebp;
595 	regs->tf_rbx = ucp->uc_mcontext.mc_ebx;
596 	regs->tf_rdx = ucp->uc_mcontext.mc_edx;
597 	regs->tf_rcx = ucp->uc_mcontext.mc_ecx;
598 	regs->tf_rax = ucp->uc_mcontext.mc_eax;
599 	regs->tf_trapno = ucp->uc_mcontext.mc_trapno;
600 	regs->tf_err = ucp->uc_mcontext.mc_err;
601 	regs->tf_rip = ucp->uc_mcontext.mc_eip;
602 	regs->tf_cs = cs;
603 	regs->tf_rflags = ucp->uc_mcontext.mc_eflags;
604 	regs->tf_rsp = ucp->uc_mcontext.mc_esp;
605 	regs->tf_ss = ucp->uc_mcontext.mc_ss;
606 	regs->tf_ds = ucp->uc_mcontext.mc_ds;
607 	regs->tf_es = ucp->uc_mcontext.mc_es;
608 	regs->tf_fs = ucp->uc_mcontext.mc_fs;
609 	regs->tf_gs = ucp->uc_mcontext.mc_gs;
610 
611 	kern_sigprocmask(td, SIG_SETMASK, &ucp->uc_sigmask, NULL, 0);
612 	td->td_pcb->pcb_full_iret = 1;
613 	return (EJUSTRETURN);
614 }
615 #endif	/* COMPAT_FREEBSD4 */
616 
617 /*
618  * MPSAFE
619  */
620 int
621 freebsd32_sigreturn(td, uap)
622 	struct thread *td;
623 	struct freebsd32_sigreturn_args /* {
624 		const struct freebsd32_ucontext *sigcntxp;
625 	} */ *uap;
626 {
627 	struct ia32_ucontext uc;
628 	struct trapframe *regs;
629 	struct ia32_ucontext *ucp;
630 	int cs, eflags, error, ret;
631 	ksiginfo_t ksi;
632 
633 	error = copyin(uap->sigcntxp, &uc, sizeof(uc));
634 	if (error != 0)
635 		return (error);
636 	ucp = &uc;
637 	regs = td->td_frame;
638 	eflags = ucp->uc_mcontext.mc_eflags;
639 	/*
640 	 * Don't allow users to change privileged or reserved flags.
641 	 */
642 	/*
643 	 * XXX do allow users to change the privileged flag PSL_RF.
644 	 * The cpu sets PSL_RF in tf_eflags for faults.  Debuggers
645 	 * should sometimes set it there too.  tf_eflags is kept in
646 	 * the signal context during signal handling and there is no
647 	 * other place to remember it, so the PSL_RF bit may be
648 	 * corrupted by the signal handler without us knowing.
649 	 * Corruption of the PSL_RF bit at worst causes one more or
650 	 * one less debugger trap, so allowing it is fairly harmless.
651 	 */
652 	if (!EFL_SECURE(eflags & ~PSL_RF, regs->tf_rflags & ~PSL_RF)) {
653 		uprintf("pid %d (%s): freebsd32_sigreturn eflags = 0x%x\n",
654 		    td->td_proc->p_pid, td->td_name, eflags);
655 		return (EINVAL);
656 	}
657 
658 	/*
659 	 * Don't allow users to load a valid privileged %cs.  Let the
660 	 * hardware check for invalid selectors, excess privilege in
661 	 * other selectors, invalid %eip's and invalid %esp's.
662 	 */
663 	cs = ucp->uc_mcontext.mc_cs;
664 	if (!CS_SECURE(cs)) {
665 		uprintf("pid %d (%s): sigreturn cs = 0x%x\n",
666 		    td->td_proc->p_pid, td->td_name, cs);
667 		ksiginfo_init_trap(&ksi);
668 		ksi.ksi_signo = SIGBUS;
669 		ksi.ksi_code = BUS_OBJERR;
670 		ksi.ksi_trapno = T_PROTFLT;
671 		ksi.ksi_addr = (void *)regs->tf_rip;
672 		trapsignal(td, &ksi);
673 		return (EINVAL);
674 	}
675 
676 	ret = ia32_set_fpcontext(td, &ucp->uc_mcontext);
677 	if (ret != 0)
678 		return (ret);
679 
680 	regs->tf_rdi = ucp->uc_mcontext.mc_edi;
681 	regs->tf_rsi = ucp->uc_mcontext.mc_esi;
682 	regs->tf_rbp = ucp->uc_mcontext.mc_ebp;
683 	regs->tf_rbx = ucp->uc_mcontext.mc_ebx;
684 	regs->tf_rdx = ucp->uc_mcontext.mc_edx;
685 	regs->tf_rcx = ucp->uc_mcontext.mc_ecx;
686 	regs->tf_rax = ucp->uc_mcontext.mc_eax;
687 	regs->tf_trapno = ucp->uc_mcontext.mc_trapno;
688 	regs->tf_err = ucp->uc_mcontext.mc_err;
689 	regs->tf_rip = ucp->uc_mcontext.mc_eip;
690 	regs->tf_cs = cs;
691 	regs->tf_rflags = ucp->uc_mcontext.mc_eflags;
692 	regs->tf_rsp = ucp->uc_mcontext.mc_esp;
693 	regs->tf_ss = ucp->uc_mcontext.mc_ss;
694 	regs->tf_ds = ucp->uc_mcontext.mc_ds;
695 	regs->tf_es = ucp->uc_mcontext.mc_es;
696 	regs->tf_fs = ucp->uc_mcontext.mc_fs;
697 	regs->tf_gs = ucp->uc_mcontext.mc_gs;
698 	regs->tf_flags = TF_HASSEGS;
699 
700 	kern_sigprocmask(td, SIG_SETMASK, &ucp->uc_sigmask, NULL, 0);
701 	td->td_pcb->pcb_full_iret = 1;
702 	return (EJUSTRETURN);
703 }
704 
705 /*
706  * Clear registers on exec
707  */
708 void
709 ia32_setregs(struct thread *td, struct image_params *imgp, u_long stack)
710 {
711 	struct trapframe *regs = td->td_frame;
712 	struct pcb *pcb = td->td_pcb;
713 
714 	mtx_lock(&dt_lock);
715 	if (td->td_proc->p_md.md_ldt != NULL)
716 		user_ldt_free(td);
717 	else
718 		mtx_unlock(&dt_lock);
719 
720 	pcb->pcb_fsbase = 0;
721 	pcb->pcb_gsbase = 0;
722 	pcb->pcb_initial_fpucw = __INITIAL_FPUCW_I386__;
723 
724 	bzero((char *)regs, sizeof(struct trapframe));
725 	regs->tf_rip = imgp->entry_addr;
726 	regs->tf_rsp = stack;
727 	regs->tf_rflags = PSL_USER | (regs->tf_rflags & PSL_T);
728 	regs->tf_ss = _udatasel;
729 	regs->tf_cs = _ucode32sel;
730 	regs->tf_rbx = imgp->ps_strings;
731 	regs->tf_ds = _udatasel;
732 	regs->tf_es = _udatasel;
733 	regs->tf_fs = _ufssel;
734 	regs->tf_gs = _ugssel;
735 	regs->tf_flags = TF_HASSEGS;
736 
737 	load_cr0(rcr0() | CR0_MP | CR0_TS);
738 	fpstate_drop(td);
739 
740 	/* Return via doreti so that we can change to a different %cs */
741 	pcb->pcb_flags |= PCB_FULLCTX | PCB_32BIT;
742 	pcb->pcb_flags &= ~PCB_GS32BIT;
743 	td->td_pcb->pcb_full_iret = 1;
744 	td->td_retval[1] = 0;
745 }
746