Home | History | Annotate | Line # | Download | only in amd64
linux32_machdep.c revision 1.5.2.3
      1  1.5.2.3      yamt /*	$NetBSD: linux32_machdep.c,v 1.5.2.3 2007/03/24 14:55:10 yamt Exp $ */
      2      1.1      manu 
      3      1.1      manu /*-
      4      1.1      manu  * Copyright (c) 2006 Emmanuel Dreyfus, all rights reserved.
      5      1.1      manu  *
      6      1.1      manu  * Redistribution and use in source and binary forms, with or without
      7      1.1      manu  * modification, are permitted provided that the following conditions
      8      1.1      manu  * are met:
      9      1.1      manu  * 1. Redistributions of source code must retain the above copyright
     10      1.1      manu  *    notice, this list of conditions and the following disclaimer.
     11      1.1      manu  * 2. Redistributions in binary form must reproduce the above copyright
     12      1.1      manu  *    notice, this list of conditions and the following disclaimer in the
     13      1.1      manu  *    documentation and/or other materials provided with the distribution.
     14      1.1      manu  * 3. All advertising materials mentioning features or use of this software
     15      1.1      manu  *    must display the following acknowledgement:
     16      1.1      manu  *	This product includes software developed by Emmanuel Dreyfus
     17      1.1      manu  * 4. The name of the author may not be used to endorse or promote
     18      1.1      manu  *    products derived from this software without specific prior written
     19      1.1      manu  *    permission.
     20      1.1      manu  *
     21      1.1      manu  * THIS SOFTWARE IS PROVIDED BY THE THE AUTHOR AND CONTRIBUTORS ``AS IS''
     22      1.1      manu  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     23      1.1      manu  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     24      1.1      manu  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS
     25      1.1      manu  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     26      1.1      manu  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     27      1.1      manu  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     28      1.1      manu  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     29      1.1      manu  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     30      1.1      manu  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     31      1.1      manu  * POSSIBILITY OF SUCH DAMAGE.
     32      1.1      manu  */
     33      1.1      manu #include <sys/cdefs.h>
     34  1.5.2.3      yamt __KERNEL_RCSID(0, "$NetBSD: linux32_machdep.c,v 1.5.2.3 2007/03/24 14:55:10 yamt Exp $");
     35      1.1      manu 
     36      1.1      manu #include <sys/param.h>
     37      1.1      manu #include <sys/systm.h>
     38      1.1      manu #include <sys/signalvar.h>
     39      1.1      manu #include <sys/kernel.h>
     40      1.1      manu #include <sys/proc.h>
     41      1.1      manu #include <sys/user.h>
     42      1.1      manu #include <sys/buf.h>
     43      1.1      manu #include <sys/reboot.h>
     44      1.1      manu #include <sys/conf.h>
     45      1.1      manu #include <sys/exec.h>
     46      1.1      manu #include <sys/file.h>
     47      1.1      manu #include <sys/callout.h>
     48      1.1      manu #include <sys/malloc.h>
     49      1.1      manu #include <sys/mbuf.h>
     50      1.1      manu #include <sys/msgbuf.h>
     51      1.1      manu #include <sys/mount.h>
     52      1.1      manu #include <sys/vnode.h>
     53      1.1      manu #include <sys/device.h>
     54      1.1      manu #include <sys/syscallargs.h>
     55      1.1      manu #include <sys/filedesc.h>
     56      1.1      manu #include <sys/exec_elf.h>
     57      1.1      manu #include <sys/disklabel.h>
     58      1.1      manu #include <sys/ioctl.h>
     59      1.1      manu #include <sys/wait.h>
     60      1.1      manu #include <miscfs/specfs/specdev.h>
     61      1.1      manu 
     62      1.1      manu #include <machine/netbsd32_machdep.h>
     63      1.1      manu 
     64      1.1      manu #include <compat/netbsd32/netbsd32.h>
     65      1.1      manu #include <compat/netbsd32/netbsd32_syscallargs.h>
     66      1.1      manu 
     67      1.1      manu #include <compat/linux/common/linux_signal.h>
     68      1.1      manu #include <compat/linux/common/linux_errno.h>
     69      1.1      manu 
     70      1.1      manu #include <compat/linux32/common/linux32_types.h>
     71      1.1      manu #include <compat/linux32/common/linux32_errno.h>
     72      1.1      manu #include <compat/linux32/common/linux32_machdep.h>
     73      1.1      manu #include <compat/linux32/common/linux32_signal.h>
     74      1.1      manu #include <compat/linux32/common/linux32_exec.h>
     75      1.1      manu #include <compat/linux32/linux32_syscallargs.h>
     76      1.1      manu 
     77      1.1      manu #include <machine/cpu.h>
     78      1.1      manu #include <machine/cpufunc.h>
     79      1.1      manu #include <machine/psl.h>
     80      1.1      manu #include <machine/reg.h>
     81      1.1      manu #include <machine/segments.h>
     82      1.1      manu #include <machine/specialreg.h>
     83      1.1      manu #include <machine/sysarch.h>
     84      1.1      manu #include <machine/vmparam.h>
     85      1.1      manu 
     86      1.1      manu extern char linux32_sigcode[1];
     87      1.1      manu extern char linux32_rt_sigcode[1];
     88      1.1      manu extern char linux32_esigcode[1];
     89      1.1      manu 
     90      1.1      manu extern void (osyscall_return) __P((void));
     91      1.1      manu 
     92      1.1      manu static void linux32_save_ucontext __P((struct lwp *, struct trapframe *,
     93      1.1      manu     const sigset_t *, struct sigaltstack *, struct linux32_ucontext *));
     94      1.1      manu static void linux32_save_sigcontext __P((struct lwp *, struct trapframe *,
     95      1.1      manu     const sigset_t *, struct linux32_sigcontext *));
     96      1.1      manu static void linux32_rt_sendsig __P((const ksiginfo_t *, const sigset_t *));
     97      1.1      manu static void linux32_old_sendsig __P((const ksiginfo_t *, const sigset_t *));
     98      1.1      manu static int linux32_restore_sigcontext __P((struct lwp *,
     99      1.1      manu     struct linux32_sigcontext *, register_t *));
    100      1.1      manu 
    101      1.1      manu void
    102      1.1      manu linux32_sendsig(const ksiginfo_t *ksi, const sigset_t *mask)
    103      1.1      manu {
    104      1.1      manu 	if (SIGACTION(curproc, ksi->ksi_signo).sa_flags & SA_SIGINFO)
    105      1.1      manu 		linux32_rt_sendsig(ksi, mask);
    106      1.1      manu 	else
    107      1.1      manu 		linux32_old_sendsig(ksi, mask);
    108      1.1      manu 	return;
    109      1.1      manu }
    110      1.1      manu 
    111      1.1      manu void
    112      1.1      manu linux32_old_sendsig(const ksiginfo_t *ksi, const sigset_t *mask)
    113      1.1      manu {
    114      1.1      manu 	struct lwp *l = curlwp;
    115      1.1      manu 	struct proc *p = l->l_proc;
    116      1.1      manu 	struct trapframe *tf;
    117      1.1      manu 	struct linux32_sigframe *fp, frame;
    118      1.4        ad 	int onstack, error;
    119      1.1      manu 	int sig = ksi->ksi_signo;
    120      1.1      manu 	sig_t catcher = SIGACTION(p, sig).sa_handler;
    121      1.5        ad 	struct sigaltstack *sas = &l->l_sigstk;
    122      1.1      manu 
    123      1.1      manu 	tf = l->l_md.md_regs;
    124      1.1      manu 	/* Do we need to jump onto the signal stack? */
    125      1.1      manu 	onstack = (sas->ss_flags & (SS_DISABLE | SS_ONSTACK)) == 0 &&
    126      1.1      manu 	    (SIGACTION(p, sig).sa_flags & SA_ONSTACK) != 0;
    127      1.1      manu 
    128      1.1      manu 
    129      1.1      manu 	/* Allocate space for the signal handler context. */
    130      1.1      manu 	if (onstack)
    131  1.5.2.2     rmind 		fp = (struct linux32_sigframe *)((char *)sas->ss_sp +
    132      1.1      manu 		    sas->ss_size);
    133      1.1      manu 	else
    134      1.1      manu 		fp = (struct linux32_sigframe *)tf->tf_rsp;
    135      1.1      manu 	fp--;
    136      1.1      manu 
    137      1.1      manu 	/* Build stack frame for signal trampoline. */
    138  1.5.2.3      yamt 	NETBSD32PTR32(frame.sf_handler, catcher);
    139      1.1      manu 	frame.sf_sig = native_to_linux32_signo[sig];
    140      1.1      manu 
    141      1.1      manu 	linux32_save_sigcontext(l, tf, mask, &frame.sf_sc);
    142      1.1      manu 
    143      1.4        ad 	sendsig_reset(l, sig);
    144      1.4        ad 	mutex_exit(&p->p_smutex);
    145      1.4        ad 	error = copyout(&frame, fp, sizeof(frame));
    146      1.4        ad 	mutex_enter(&p->p_smutex);
    147      1.4        ad 
    148      1.4        ad 	if (error != 0) {
    149      1.1      manu 		/*
    150      1.1      manu 		 * Process has trashed its stack; give it an illegal
    151      1.1      manu 		 * instruction to halt it in its tracks.
    152      1.1      manu 		 */
    153      1.1      manu 		sigexit(l, SIGILL);
    154      1.1      manu 		/* NOTREACHED */
    155      1.1      manu 	}
    156      1.1      manu 
    157      1.1      manu 	/*
    158      1.1      manu 	 * Build context to run handler in.
    159      1.1      manu 	 */
    160      1.1      manu 	tf->tf_gs = GSEL(GUDATA32_SEL, SEL_UPL) & 0xffffffff;
    161      1.1      manu 	tf->tf_fs = GSEL(GUDATA32_SEL, SEL_UPL) & 0xffffffff;
    162      1.1      manu 	tf->tf_es = GSEL(GUDATA32_SEL, SEL_UPL) & 0xffffffff;
    163      1.1      manu 	tf->tf_ds = GSEL(GUDATA32_SEL, SEL_UPL) & 0xffffffff;
    164      1.1      manu 	tf->tf_rip = ((long)p->p_sigctx.ps_sigcode) & 0xffffffff;
    165      1.1      manu 	tf->tf_cs = GSEL(GUCODE32_SEL, SEL_UPL) & 0xffffffff;
    166      1.1      manu 	tf->tf_rflags &= ~(PSL_T|PSL_VM|PSL_AC) & 0xffffffff;
    167      1.1      manu 	tf->tf_rsp = (long)fp & 0xffffffff;
    168      1.1      manu 	tf->tf_ss = GSEL(GUDATA32_SEL, SEL_UPL) & 0xffffffff;
    169      1.1      manu 
    170      1.1      manu 	/* Remember that we're now on the signal stack. */
    171      1.1      manu 	if (onstack)
    172      1.1      manu 		sas->ss_flags |= SS_ONSTACK;
    173      1.1      manu 
    174      1.1      manu 	return;
    175      1.1      manu }
    176      1.1      manu 
    177      1.1      manu void
    178      1.1      manu linux32_rt_sendsig(const ksiginfo_t *ksi, const sigset_t *mask)
    179      1.1      manu {
    180      1.1      manu 	struct lwp *l = curlwp;
    181      1.1      manu 	struct proc *p = l->l_proc;
    182      1.1      manu 	struct trapframe *tf;
    183      1.1      manu 	struct linux32_rt_sigframe *fp, frame;
    184      1.4        ad 	int onstack, error;
    185      1.1      manu 	linux32_siginfo_t *lsi;
    186      1.5        ad 	int sig = ksi->ksi_signo;
    187      1.1      manu 	sig_t catcher = SIGACTION(p, sig).sa_handler;
    188      1.5        ad 	struct sigaltstack *sas = &l->l_sigstk;
    189      1.1      manu 
    190      1.1      manu 	tf = l->l_md.md_regs;
    191      1.1      manu 	/* Do we need to jump onto the signal stack? */
    192      1.1      manu 	onstack = (sas->ss_flags & (SS_DISABLE | SS_ONSTACK)) == 0 &&
    193      1.1      manu 	    (SIGACTION(p, sig).sa_flags & SA_ONSTACK) != 0;
    194      1.1      manu 
    195      1.1      manu 
    196      1.1      manu 	/* Allocate space for the signal handler context. */
    197      1.1      manu 	if (onstack)
    198  1.5.2.2     rmind 		fp = (struct linux32_rt_sigframe *)((char *)sas->ss_sp +
    199      1.1      manu 		    sas->ss_size);
    200      1.1      manu 	else
    201      1.1      manu 		fp = (struct linux32_rt_sigframe *)tf->tf_rsp;
    202      1.1      manu 	fp--;
    203      1.1      manu 
    204      1.1      manu 	/* Build stack frame for signal trampoline. */
    205  1.5.2.3      yamt 	NETBSD32PTR32(frame.sf_handler, catcher);
    206      1.1      manu 	frame.sf_sig = native_to_linux32_signo[sig];
    207  1.5.2.3      yamt 	NETBSD32PTR32(frame.sf_sip, &fp->sf_si);
    208  1.5.2.3      yamt 	NETBSD32PTR32(frame.sf_ucp, &fp->sf_uc);
    209      1.1      manu 
    210      1.1      manu 	lsi = &frame.sf_si;
    211      1.1      manu 	(void)memset(lsi, 0, sizeof(frame.sf_si));
    212      1.1      manu 	lsi->lsi_errno = native_to_linux32_errno[ksi->ksi_errno];
    213      1.1      manu 	lsi->lsi_code = ksi->ksi_code;
    214      1.1      manu 	lsi->lsi_signo = native_to_linux32_signo[frame.sf_sig];
    215      1.1      manu 	switch (lsi->lsi_signo) {
    216      1.1      manu 	case LINUX32_SIGILL:
    217      1.1      manu 	case LINUX32_SIGFPE:
    218      1.1      manu 	case LINUX32_SIGSEGV:
    219      1.1      manu 	case LINUX32_SIGBUS:
    220      1.1      manu 	case LINUX32_SIGTRAP:
    221  1.5.2.3      yamt 		NETBSD32PTR32(lsi->lsi_addr, ksi->ksi_addr);
    222      1.1      manu 		break;
    223      1.1      manu 	case LINUX32_SIGCHLD:
    224      1.1      manu 		lsi->lsi_uid = ksi->ksi_uid;
    225      1.1      manu 		lsi->lsi_pid = ksi->ksi_pid;
    226      1.1      manu 		lsi->lsi_utime = ksi->ksi_utime;
    227      1.1      manu 		lsi->lsi_stime = ksi->ksi_stime;
    228      1.1      manu 
    229      1.1      manu 		/* We use the same codes */
    230      1.1      manu 		lsi->lsi_code = ksi->ksi_code;
    231      1.1      manu 		/* XXX is that right? */
    232      1.1      manu 		lsi->lsi_status = WEXITSTATUS(ksi->ksi_status);
    233      1.1      manu 		break;
    234      1.1      manu 	case LINUX32_SIGIO:
    235      1.1      manu 		lsi->lsi_band = ksi->ksi_band;
    236      1.1      manu 		lsi->lsi_fd = ksi->ksi_fd;
    237      1.1      manu 		break;
    238      1.1      manu 	default:
    239      1.1      manu 		lsi->lsi_uid = ksi->ksi_uid;
    240      1.1      manu 		lsi->lsi_pid = ksi->ksi_pid;
    241      1.1      manu 		if (lsi->lsi_signo == LINUX32_SIGALRM ||
    242      1.1      manu 		    lsi->lsi_signo >= LINUX32_SIGRTMIN)
    243  1.5.2.3      yamt 			NETBSD32PTR32(lsi->lsi_value.sival_ptr,
    244  1.5.2.3      yamt 			     ksi->ksi_sigval.sival_ptr);
    245      1.1      manu 		break;
    246      1.1      manu 	}
    247      1.1      manu 
    248      1.1      manu 	/* Save register context. */
    249      1.4        ad 	sendsig_reset(l, sig);
    250      1.4        ad 	mutex_exit(&p->p_smutex);
    251      1.1      manu 	linux32_save_ucontext(l, tf, mask, sas, &frame.sf_uc);
    252      1.4        ad 	error = copyout(&frame, fp, sizeof(frame));
    253      1.5        ad 	mutex_enter(&p->p_smutex);
    254      1.1      manu 
    255      1.4        ad 	if (error != 0) {
    256      1.1      manu 		/*
    257      1.1      manu 		 * Process has trashed its stack; give it an illegal
    258      1.1      manu 		 * instruction to halt it in its tracks.
    259      1.1      manu 		 */
    260      1.1      manu 		sigexit(l, SIGILL);
    261      1.1      manu 		/* NOTREACHED */
    262      1.1      manu 	}
    263      1.1      manu 
    264      1.1      manu 	/*
    265      1.1      manu 	 * Build context to run handler in.
    266      1.1      manu 	 */
    267      1.1      manu 	tf->tf_gs = GSEL(GUDATA32_SEL, SEL_UPL) & 0xffffffff;
    268      1.1      manu 	tf->tf_fs = GSEL(GUDATA32_SEL, SEL_UPL) & 0xffffffff;
    269      1.1      manu 	tf->tf_es = GSEL(GUDATA32_SEL, SEL_UPL) & 0xffffffff;
    270      1.1      manu 	tf->tf_ds = GSEL(GUDATA32_SEL, SEL_UPL) & 0xffffffff;
    271      1.1      manu 	tf->tf_rip = (((long)p->p_sigctx.ps_sigcode) +
    272      1.1      manu 	    (linux32_rt_sigcode - linux32_sigcode)) & 0xffffffff;
    273      1.1      manu 	tf->tf_cs = GSEL(GUCODE32_SEL, SEL_UPL) & 0xffffffff;
    274      1.1      manu 	tf->tf_rflags &= ~(PSL_T|PSL_VM|PSL_AC) & 0xffffffff;
    275      1.1      manu 	tf->tf_rsp = (long)fp & 0xffffffff;
    276      1.1      manu 	tf->tf_ss = GSEL(GUDATA32_SEL, SEL_UPL) & 0xffffffff;
    277      1.1      manu 
    278      1.1      manu 	/* Remember that we're now on the signal stack. */
    279      1.1      manu 	if (onstack)
    280      1.1      manu 		sas->ss_flags |= SS_ONSTACK;
    281      1.1      manu 
    282      1.1      manu 	return;
    283      1.1      manu }
    284      1.1      manu 
    285      1.1      manu void
    286      1.1      manu linux32_setregs(struct lwp *l, struct exec_package *pack, u_long stack)
    287      1.1      manu {
    288      1.1      manu 	struct pcb *pcb = &l->l_addr->u_pcb;
    289      1.1      manu 	struct trapframe *tf;
    290      1.1      manu 	struct proc *p = l->l_proc;
    291      1.1      manu 	void **retaddr;
    292      1.1      manu 
    293      1.1      manu 	/* If we were using the FPU, forget about it. */
    294      1.1      manu 	if (l->l_addr->u_pcb.pcb_fpcpu != NULL)
    295      1.1      manu 		fpusave_lwp(l, 0);
    296      1.1      manu 
    297      1.1      manu #if defined(USER_LDT) && 0
    298      1.1      manu 	pmap_ldt_cleanup(p);
    299      1.1      manu #endif
    300      1.1      manu 
    301      1.3  christos 	netbsd32_adjust_limits(p);
    302      1.1      manu 
    303      1.1      manu 	l->l_md.md_flags &= ~MDP_USEDFPU;
    304      1.1      manu 	pcb->pcb_flags = 0;
    305      1.1      manu 	pcb->pcb_savefpu.fp_fxsave.fx_fcw = __Linux_NPXCW__;
    306      1.1      manu 	pcb->pcb_savefpu.fp_fxsave.fx_mxcsr = __INITIAL_MXCSR__;
    307      1.1      manu 	pcb->pcb_savefpu.fp_fxsave.fx_mxcsr_mask = __INITIAL_MXCSR_MASK__;
    308      1.1      manu 	pcb->pcb_fs = 0;
    309      1.1      manu 	pcb->pcb_gs = 0;
    310      1.1      manu 
    311      1.1      manu 
    312  1.5.2.1      yamt 	p->p_flag |= PK_32;
    313      1.1      manu 
    314      1.1      manu 	tf = l->l_md.md_regs;
    315      1.1      manu 	tf->tf_rax = 0;
    316      1.2  christos 	tf->tf_rbx = (u_int64_t)p->p_psstr & 0xffffffff;
    317      1.1      manu 	tf->tf_rcx = pack->ep_entry & 0xffffffff;
    318      1.1      manu 	tf->tf_rdx = 0;
    319      1.1      manu 	tf->tf_rsi = 0;
    320      1.1      manu 	tf->tf_rdi = 0;
    321      1.1      manu 	tf->tf_rbp = 0;
    322      1.1      manu 	tf->tf_rsp = stack & 0xffffffff;
    323      1.1      manu 	tf->tf_r8 = 0;
    324      1.1      manu 	tf->tf_r9 = 0;
    325      1.1      manu 	tf->tf_r10 = 0;
    326      1.1      manu 	tf->tf_r11 = 0;
    327      1.1      manu 	tf->tf_r12 = 0;
    328      1.1      manu 	tf->tf_r13 = 0;
    329      1.1      manu 	tf->tf_r14 = 0;
    330      1.1      manu 	tf->tf_r15 = 0;
    331      1.1      manu 	tf->tf_rip = pack->ep_entry & 0xffffffff;
    332      1.1      manu 	tf->tf_rflags = PSL_USERSET;
    333      1.1      manu 	tf->tf_cs = GSEL(GUCODE32_SEL, SEL_UPL) & 0xffffffff;
    334      1.1      manu 	tf->tf_ss = GSEL(GUDATA32_SEL, SEL_UPL) & 0xffffffff;
    335      1.1      manu 	tf->tf_ds = GSEL(GUDATA32_SEL, SEL_UPL) & 0xffffffff;
    336      1.1      manu 	tf->tf_es = GSEL(GUDATA32_SEL, SEL_UPL) & 0xffffffff;
    337      1.1      manu 	tf->tf_fs = GSEL(GUDATA32_SEL, SEL_UPL) & 0xffffffff;
    338      1.1      manu 	tf->tf_gs = GSEL(GUDATA32_SEL, SEL_UPL) & 0xffffffff;
    339      1.1      manu 
    340      1.1      manu 	/* XXX frob return address to return via old iret method, not sysret */
    341      1.1      manu 	retaddr = (void **)tf - 1;
    342      1.1      manu 	*retaddr = (void *)osyscall_return;
    343      1.1      manu 	return;
    344      1.1      manu }
    345      1.1      manu 
    346      1.1      manu static void
    347      1.1      manu linux32_save_ucontext(l, tf, mask, sas, uc)
    348      1.1      manu 	struct lwp *l;
    349      1.1      manu 	struct trapframe *tf;
    350      1.1      manu 	const sigset_t *mask;
    351      1.1      manu 	struct sigaltstack *sas;
    352      1.1      manu 	struct linux32_ucontext *uc;
    353      1.1      manu {
    354      1.1      manu 	uc->uc_flags = 0;
    355  1.5.2.3      yamt 	NETBSD32PTR32(uc->uc_link, NULL);
    356      1.1      manu 	native_to_linux32_sigaltstack(&uc->uc_stack, sas);
    357      1.1      manu 	linux32_save_sigcontext(l, tf, mask, &uc->uc_mcontext);
    358      1.1      manu 	native_to_linux32_sigset(&uc->uc_sigmask, mask);
    359      1.1      manu 	(void)memset(&uc->uc_fpregs_mem, 0, sizeof(uc->uc_fpregs_mem));
    360      1.1      manu }
    361      1.1      manu 
    362      1.1      manu static void
    363      1.1      manu linux32_save_sigcontext(l, tf, mask, sc)
    364      1.1      manu 	struct lwp *l;
    365      1.1      manu 	struct trapframe *tf;
    366      1.1      manu 	const sigset_t *mask;
    367      1.1      manu 	struct linux32_sigcontext *sc;
    368      1.1      manu {
    369      1.1      manu 	/* Save register context. */
    370      1.1      manu 	sc->sc_gs = tf->tf_gs;
    371      1.1      manu 	sc->sc_fs = tf->tf_fs;
    372      1.1      manu 	sc->sc_es = tf->tf_es;
    373      1.1      manu 	sc->sc_ds = tf->tf_ds;
    374      1.1      manu 	sc->sc_eflags = tf->tf_rflags;
    375      1.1      manu 	sc->sc_edi = tf->tf_rdi;
    376      1.1      manu 	sc->sc_esi = tf->tf_rsi;
    377      1.1      manu 	sc->sc_esp = tf->tf_rsp;
    378      1.1      manu 	sc->sc_ebp = tf->tf_rbp;
    379      1.1      manu 	sc->sc_ebx = tf->tf_rbx;
    380      1.1      manu 	sc->sc_edx = tf->tf_rdx;
    381      1.1      manu 	sc->sc_ecx = tf->tf_rcx;
    382      1.1      manu 	sc->sc_eax = tf->tf_rax;
    383      1.1      manu 	sc->sc_eip = tf->tf_rip;
    384      1.1      manu 	sc->sc_cs = tf->tf_cs;
    385      1.1      manu 	sc->sc_esp_at_signal = tf->tf_rsp;
    386      1.1      manu 	sc->sc_ss = tf->tf_ss;
    387      1.1      manu 	sc->sc_err = tf->tf_err;
    388      1.1      manu 	sc->sc_trapno = tf->tf_trapno;
    389      1.1      manu 	/* sc->sc_cr2 = l->l_addr->u_pcb.pcb_cr2; */ /* XXX */
    390  1.5.2.3      yamt 	NETBSD32PTR32(sc->sc_387, NULL);
    391      1.1      manu 
    392      1.1      manu 	/* Save signal stack. */
    393      1.1      manu 	/* Linux doesn't save the onstack flag in sigframe */
    394      1.1      manu 
    395      1.1      manu 	/* Save signal mask. */
    396      1.1      manu 	native_to_linux32_old_sigset(&sc->sc_mask, mask);
    397      1.1      manu }
    398      1.1      manu 
    399      1.1      manu int
    400      1.1      manu linux32_sys_sigreturn(l, v, retval)
    401      1.1      manu 	struct lwp *l;
    402      1.1      manu 	void *v;
    403      1.1      manu 	register_t *retval;
    404      1.1      manu {
    405      1.1      manu 	struct linux32_sys_sigreturn_args /* {
    406      1.1      manu 		syscallarg(linux32_sigcontextp_t) scp;
    407      1.1      manu 	} */ *uap = v;
    408      1.1      manu 	struct linux32_sigcontext ctx;
    409      1.1      manu 	int error;
    410      1.1      manu 
    411  1.5.2.3      yamt 	if ((error = copyin(SCARG_P32(uap, scp), &ctx, sizeof(ctx))) != 0)
    412      1.1      manu 		return error;
    413      1.1      manu 
    414      1.1      manu 	return linux32_restore_sigcontext(l, &ctx, retval);
    415      1.1      manu }
    416      1.1      manu 
    417      1.1      manu int
    418      1.1      manu linux32_sys_rt_sigreturn(l, v, retval)
    419      1.1      manu 	struct lwp *l;
    420      1.1      manu 	void *v;
    421      1.1      manu 	register_t *retval;
    422      1.1      manu {
    423      1.1      manu 	struct linux32_sys_rt_sigreturn_args /* {
    424      1.1      manu 		syscallarg(linux32_ucontextp_t) ucp;
    425      1.1      manu 	} */ *uap = v;
    426      1.1      manu 	struct linux32_ucontext ctx;
    427      1.1      manu 	int error;
    428      1.1      manu 
    429  1.5.2.3      yamt 	if ((error = copyin(SCARG_P32(uap, ucp), &ctx, sizeof(ctx))) != 0)
    430      1.1      manu 		return error;
    431      1.1      manu 
    432      1.1      manu 	return linux32_restore_sigcontext(l, &ctx.uc_mcontext, retval);
    433      1.1      manu }
    434      1.1      manu 
    435      1.1      manu static int
    436      1.1      manu linux32_restore_sigcontext(l, scp, retval)
    437      1.1      manu 	struct lwp *l;
    438      1.1      manu 	struct linux32_sigcontext *scp;
    439      1.1      manu 	register_t *retval;
    440      1.1      manu {
    441      1.1      manu 	struct trapframe *tf;
    442      1.1      manu 	struct proc *p = l->l_proc;
    443      1.5        ad 	struct sigaltstack *sas = &l->l_sigstk;
    444      1.1      manu 	sigset_t mask;
    445      1.1      manu 	ssize_t ss_gap;
    446      1.1      manu 
    447      1.1      manu 	/* Restore register context. */
    448      1.1      manu 	tf = l->l_md.md_regs;
    449      1.1      manu 
    450      1.1      manu 	/*
    451      1.1      manu 	 * Check for security violations.  If we're returning to
    452      1.1      manu 	 * protected mode, the CPU will validate the segment registers
    453      1.1      manu 	 * automatically and generate a trap on violations.  We handle
    454      1.1      manu 	 * the trap, rather than doing all of the checking here.
    455      1.1      manu 	 */
    456      1.1      manu 	if (((scp->sc_eflags ^ tf->tf_rflags) & PSL_USERSTATIC) != 0 ||
    457      1.1      manu 	    !USERMODE(scp->sc_cs, scp->sc_eflags))
    458      1.1      manu 		return EINVAL;
    459      1.1      manu 
    460      1.1      manu 	if (scp->sc_fs != 0 && !VALID_USER_DSEL32(scp->sc_fs))
    461      1.1      manu 		return EINVAL;
    462      1.1      manu 
    463      1.1      manu 	if (scp->sc_gs != 0 && !VALID_USER_DSEL32(scp->sc_gs))
    464      1.1      manu 		return EINVAL;
    465      1.1      manu 
    466      1.1      manu 	if (scp->sc_es != 0 && !VALID_USER_DSEL32(scp->sc_es))
    467      1.1      manu 		return EINVAL;
    468      1.1      manu 
    469      1.1      manu 	if (!VALID_USER_DSEL32(scp->sc_ds) ||
    470      1.1      manu 	    !VALID_USER_DSEL32(scp->sc_ss))
    471      1.1      manu 		return EINVAL;
    472      1.1      manu 
    473      1.1      manu 	if (scp->sc_eip >= VM_MAXUSER_ADDRESS32)
    474      1.1      manu 		return EINVAL;
    475      1.1      manu 
    476      1.1      manu 	tf->tf_gs = (register_t)scp->sc_gs & 0xffffffff;
    477      1.1      manu 	tf->tf_fs = (register_t)scp->sc_fs & 0xffffffff;
    478      1.1      manu 	tf->tf_es = (register_t)scp->sc_es & 0xffffffff;
    479      1.1      manu 	tf->tf_ds = (register_t)scp->sc_ds & 0xffffffff;
    480      1.1      manu 	tf->tf_rflags &= ~PSL_USER;
    481      1.1      manu 	tf->tf_rflags |= ((register_t)scp->sc_eflags & PSL_USER);
    482      1.1      manu 	tf->tf_rdi = (register_t)scp->sc_edi & 0xffffffff;
    483      1.1      manu 	tf->tf_rsi = (register_t)scp->sc_esi & 0xffffffff;
    484      1.1      manu 	tf->tf_rbp = (register_t)scp->sc_ebp & 0xffffffff;
    485      1.1      manu 	tf->tf_rbx = (register_t)scp->sc_ebx & 0xffffffff;
    486      1.1      manu 	tf->tf_rdx = (register_t)scp->sc_edx & 0xffffffff;
    487      1.1      manu 	tf->tf_rcx = (register_t)scp->sc_ecx & 0xffffffff;
    488      1.1      manu 	tf->tf_rax = (register_t)scp->sc_eax & 0xffffffff;
    489      1.1      manu 	tf->tf_rip = (register_t)scp->sc_eip & 0xffffffff;
    490      1.1      manu 	tf->tf_cs = (register_t)scp->sc_cs & 0xffffffff;
    491      1.1      manu 	tf->tf_rsp = (register_t)scp->sc_esp_at_signal & 0xffffffff;
    492      1.1      manu 	tf->tf_ss = (register_t)scp->sc_ss & 0xffffffff;
    493      1.1      manu 
    494      1.5        ad 	mutex_enter(&p->p_smutex);
    495      1.5        ad 
    496      1.1      manu 	/* Restore signal stack. */
    497      1.1      manu 	ss_gap = (ssize_t)
    498  1.5.2.3      yamt 	    ((char *)NETBSD32IPTR64(scp->sc_esp_at_signal)
    499  1.5.2.2     rmind 	     - (char *)sas->ss_sp);
    500      1.1      manu 	if (ss_gap >= 0 && ss_gap < sas->ss_size)
    501      1.1      manu 		sas->ss_flags |= SS_ONSTACK;
    502      1.1      manu 	else
    503      1.1      manu 		sas->ss_flags &= ~SS_ONSTACK;
    504      1.1      manu 
    505      1.1      manu 	/* Restore signal mask. */
    506      1.1      manu 	linux32_old_to_native_sigset(&mask, &scp->sc_mask);
    507      1.5        ad 	(void) sigprocmask1(l, SIG_SETMASK, &mask, 0);
    508      1.5        ad 
    509      1.5        ad 	mutex_exit(&p->p_smutex);
    510      1.5        ad 
    511      1.1      manu #ifdef DEBUG_LINUX
    512      1.1      manu 	printf("linux32_sigreturn: rip = 0x%lx, rsp = 0x%lx, flags = 0x%lx\n",
    513      1.1      manu 	    tf->tf_rip, tf->tf_rsp, tf->tf_rflags);
    514      1.1      manu #endif
    515      1.1      manu 	return EJUSTRETURN;
    516      1.1      manu }
    517