Home | History | Annotate | Line # | Download | only in i386
linux_machdep.c revision 1.107
      1 /*	$NetBSD: linux_machdep.c,v 1.107 2005/05/20 12:48:27 fvdl Exp $	*/
      2 
      3 /*-
      4  * Copyright (c) 1995, 2000 The NetBSD Foundation, Inc.
      5  * All rights reserved.
      6  *
      7  * This code is derived from software contributed to The NetBSD Foundation
      8  * by Frank van der Linden.
      9  *
     10  * Redistribution and use in source and binary forms, with or without
     11  * modification, are permitted provided that the following conditions
     12  * are met:
     13  * 1. Redistributions of source code must retain the above copyright
     14  *    notice, this list of conditions and the following disclaimer.
     15  * 2. Redistributions in binary form must reproduce the above copyright
     16  *    notice, this list of conditions and the following disclaimer in the
     17  *    documentation and/or other materials provided with the distribution.
     18  * 3. All advertising materials mentioning features or use of this software
     19  *    must display the following acknowledgement:
     20  *	This product includes software developed by the NetBSD
     21  *	Foundation, Inc. and its contributors.
     22  * 4. Neither the name of The NetBSD Foundation nor the names of its
     23  *    contributors may be used to endorse or promote products derived
     24  *    from this software without specific prior written permission.
     25  *
     26  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     27  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     28  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     29  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     30  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     31  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     32  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     33  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     34  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     35  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     36  * POSSIBILITY OF SUCH DAMAGE.
     37  */
     38 
     39 #include <sys/cdefs.h>
     40 __KERNEL_RCSID(0, "$NetBSD: linux_machdep.c,v 1.107 2005/05/20 12:48:27 fvdl Exp $");
     41 
     42 #if defined(_KERNEL_OPT)
     43 #include "opt_vm86.h"
     44 #include "opt_user_ldt.h"
     45 #endif
     46 
     47 #include <sys/param.h>
     48 #include <sys/systm.h>
     49 #include <sys/signalvar.h>
     50 #include <sys/kernel.h>
     51 #include <sys/proc.h>
     52 #include <sys/user.h>
     53 #include <sys/buf.h>
     54 #include <sys/reboot.h>
     55 #include <sys/conf.h>
     56 #include <sys/exec.h>
     57 #include <sys/file.h>
     58 #include <sys/callout.h>
     59 #include <sys/malloc.h>
     60 #include <sys/mbuf.h>
     61 #include <sys/msgbuf.h>
     62 #include <sys/mount.h>
     63 #include <sys/vnode.h>
     64 #include <sys/device.h>
     65 #include <sys/sa.h>
     66 #include <sys/syscallargs.h>
     67 #include <sys/filedesc.h>
     68 #include <sys/exec_elf.h>
     69 #include <sys/disklabel.h>
     70 #include <sys/ioctl.h>
     71 #include <miscfs/specfs/specdev.h>
     72 
     73 #include <compat/linux/common/linux_types.h>
     74 #include <compat/linux/common/linux_signal.h>
     75 #include <compat/linux/common/linux_util.h>
     76 #include <compat/linux/common/linux_ioctl.h>
     77 #include <compat/linux/common/linux_hdio.h>
     78 #include <compat/linux/common/linux_exec.h>
     79 #include <compat/linux/common/linux_machdep.h>
     80 #include <compat/linux/common/linux_errno.h>
     81 
     82 #include <compat/linux/linux_syscallargs.h>
     83 
     84 #include <machine/cpu.h>
     85 #include <machine/cpufunc.h>
     86 #include <machine/psl.h>
     87 #include <machine/reg.h>
     88 #include <machine/segments.h>
     89 #include <machine/specialreg.h>
     90 #include <machine/sysarch.h>
     91 #include <machine/vm86.h>
     92 #include <machine/vmparam.h>
     93 
     94 /*
     95  * To see whether wscons is configured (for virtual console ioctl calls).
     96  */
     97 #if defined(_KERNEL_OPT)
     98 #include "wsdisplay.h"
     99 #endif
    100 #if (NWSDISPLAY > 0)
    101 #include <dev/wscons/wsconsio.h>
    102 #include <dev/wscons/wsdisplay_usl_io.h>
    103 #if defined(_KERNEL_OPT)
    104 #include "opt_xserver.h"
    105 #endif
    106 #endif
    107 
    108 #ifdef USER_LDT
    109 #include <machine/cpu.h>
    110 int linux_read_ldt __P((struct lwp *, struct linux_sys_modify_ldt_args *,
    111     register_t *));
    112 int linux_write_ldt __P((struct lwp *, struct linux_sys_modify_ldt_args *,
    113     register_t *));
    114 #endif
    115 
    116 #ifdef DEBUG_LINUX
    117 #define DPRINTF(a) uprintf a
    118 #else
    119 #define DPRINTF(a)
    120 #endif
    121 
    122 static struct biosdisk_info *fd2biosinfo __P((struct proc *, struct file *));
    123 extern struct disklist *x86_alldisks;
    124 static void linux_save_ucontext __P((struct lwp *, struct trapframe *,
    125     const sigset_t *, struct sigaltstack *, struct linux_ucontext *));
    126 static void linux_save_sigcontext __P((struct lwp *, struct trapframe *,
    127     const sigset_t *, struct linux_sigcontext *));
    128 static int linux_restore_sigcontext __P((struct lwp *,
    129     struct linux_sigcontext *, register_t *));
    130 static void linux_rt_sendsig __P((const ksiginfo_t *, const sigset_t *));
    131 static void linux_old_sendsig __P((const ksiginfo_t *, const sigset_t *));
    132 
    133 extern char linux_sigcode[], linux_rt_sigcode[];
    134 /*
    135  * Deal with some i386-specific things in the Linux emulation code.
    136  */
    137 
    138 void
    139 linux_setregs(l, epp, stack)
    140 	struct lwp *l;
    141 	struct exec_package *epp;
    142 	u_long stack;
    143 {
    144 	struct pcb *pcb = &l->l_addr->u_pcb;
    145 	struct trapframe *tf;
    146 
    147 #if NNPX > 0
    148 	/* If we were using the FPU, forget about it. */
    149 	if (npxproc == l)
    150 		npxdrop();
    151 #endif
    152 
    153 #ifdef USER_LDT
    154 	pmap_ldt_cleanup(l);
    155 #endif
    156 
    157 	l->l_md.md_flags &= ~MDL_USEDFPU;
    158 
    159 	if (i386_use_fxsave) {
    160 		pcb->pcb_savefpu.sv_xmm.sv_env.en_cw = __Linux_NPXCW__;
    161 		pcb->pcb_savefpu.sv_xmm.sv_env.en_mxcsr = __INITIAL_MXCSR__;
    162 	} else
    163 		pcb->pcb_savefpu.sv_87.sv_env.en_cw = __Linux_NPXCW__;
    164 
    165 	tf = l->l_md.md_regs;
    166 	tf->tf_gs = GSEL(GUDATA_SEL, SEL_UPL);
    167 	tf->tf_fs = GSEL(GUDATA_SEL, SEL_UPL);
    168 	tf->tf_es = GSEL(GUDATA_SEL, SEL_UPL);
    169 	tf->tf_ds = GSEL(GUDATA_SEL, SEL_UPL);
    170 	tf->tf_edi = 0;
    171 	tf->tf_esi = 0;
    172 	tf->tf_ebp = 0;
    173 	tf->tf_ebx = (int)l->l_proc->p_psstr;
    174 	tf->tf_edx = 0;
    175 	tf->tf_ecx = 0;
    176 	tf->tf_eax = 0;
    177 	tf->tf_eip = epp->ep_entry;
    178 	tf->tf_cs = GSEL(GUCODEBIG_SEL, SEL_UPL);
    179 	tf->tf_eflags = PSL_USERSET;
    180 	tf->tf_esp = stack;
    181 	tf->tf_ss = GSEL(GUDATA_SEL, SEL_UPL);
    182 }
    183 
    184 /*
    185  * Send an interrupt to process.
    186  *
    187  * Stack is set up to allow sigcode stored
    188  * in u. to call routine, followed by kcall
    189  * to sigreturn routine below.  After sigreturn
    190  * resets the signal mask, the stack, and the
    191  * frame pointer, it returns to the user
    192  * specified pc, psl.
    193  */
    194 
    195 void
    196 linux_sendsig(const ksiginfo_t *ksi, const sigset_t *mask)
    197 {
    198 	if (SIGACTION(curproc, ksi->ksi_signo).sa_flags & SA_SIGINFO)
    199 		linux_rt_sendsig(ksi, mask);
    200 	else
    201 		linux_old_sendsig(ksi, mask);
    202 }
    203 
    204 
    205 static void
    206 linux_save_ucontext(l, tf, mask, sas, uc)
    207 	struct lwp *l;
    208 	struct trapframe *tf;
    209 	const sigset_t *mask;
    210 	struct sigaltstack *sas;
    211 	struct linux_ucontext *uc;
    212 {
    213 	uc->uc_flags = 0;
    214 	uc->uc_link = NULL;
    215 	native_to_linux_sigaltstack(&uc->uc_stack, sas);
    216 	linux_save_sigcontext(l, tf, mask, &uc->uc_mcontext);
    217 	native_to_linux_sigset(&uc->uc_sigmask, mask);
    218 	(void)memset(&uc->uc_fpregs_mem, 0, sizeof(uc->uc_fpregs_mem));
    219 }
    220 
    221 static void
    222 linux_save_sigcontext(l, tf, mask, sc)
    223 	struct lwp *l;
    224 	struct trapframe *tf;
    225 	const sigset_t *mask;
    226 	struct linux_sigcontext *sc;
    227 {
    228 	/* Save register context. */
    229 #ifdef VM86
    230 	if (tf->tf_eflags & PSL_VM) {
    231 		sc->sc_gs = tf->tf_vm86_gs;
    232 		sc->sc_fs = tf->tf_vm86_fs;
    233 		sc->sc_es = tf->tf_vm86_es;
    234 		sc->sc_ds = tf->tf_vm86_ds;
    235 		sc->sc_eflags = get_vflags(l);
    236 	} else
    237 #endif
    238 	{
    239 		sc->sc_gs = tf->tf_gs;
    240 		sc->sc_fs = tf->tf_fs;
    241 		sc->sc_es = tf->tf_es;
    242 		sc->sc_ds = tf->tf_ds;
    243 		sc->sc_eflags = tf->tf_eflags;
    244 	}
    245 	sc->sc_edi = tf->tf_edi;
    246 	sc->sc_esi = tf->tf_esi;
    247 	sc->sc_esp = tf->tf_esp;
    248 	sc->sc_ebp = tf->tf_ebp;
    249 	sc->sc_ebx = tf->tf_ebx;
    250 	sc->sc_edx = tf->tf_edx;
    251 	sc->sc_ecx = tf->tf_ecx;
    252 	sc->sc_eax = tf->tf_eax;
    253 	sc->sc_eip = tf->tf_eip;
    254 	sc->sc_cs = tf->tf_cs;
    255 	sc->sc_esp_at_signal = tf->tf_esp;
    256 	sc->sc_ss = tf->tf_ss;
    257 	sc->sc_err = tf->tf_err;
    258 	sc->sc_trapno = tf->tf_trapno;
    259 	sc->sc_cr2 = l->l_addr->u_pcb.pcb_cr2;
    260 	sc->sc_387 = NULL;
    261 
    262 	/* Save signal stack. */
    263 	/* Linux doesn't save the onstack flag in sigframe */
    264 
    265 	/* Save signal mask. */
    266 	native_to_linux_old_sigset(&sc->sc_mask, mask);
    267 }
    268 
    269 static void
    270 linux_rt_sendsig(const ksiginfo_t *ksi, const sigset_t *mask)
    271 {
    272 	struct lwp *l = curlwp;
    273 	struct proc *p = l->l_proc;
    274 	struct trapframe *tf;
    275 	struct linux_rt_sigframe *fp, frame;
    276 	int onstack;
    277 	linux_siginfo_t *lsi;
    278 	int sig = ksi->ksi_signo;
    279 	sig_t catcher = SIGACTION(p, sig).sa_handler;
    280 	struct sigaltstack *sas = &p->p_sigctx.ps_sigstk;
    281 
    282 	tf = l->l_md.md_regs;
    283 	/* Do we need to jump onto the signal stack? */
    284 	onstack = (sas->ss_flags & (SS_DISABLE | SS_ONSTACK)) == 0 &&
    285 	    (SIGACTION(p, sig).sa_flags & SA_ONSTACK) != 0;
    286 
    287 
    288 	/* Allocate space for the signal handler context. */
    289 	if (onstack)
    290 		fp = (struct linux_rt_sigframe *)((caddr_t)sas->ss_sp +
    291 		    sas->ss_size);
    292 	else
    293 		fp = (struct linux_rt_sigframe *)tf->tf_esp;
    294 	fp--;
    295 
    296 	DPRINTF(("rt: onstack = %d, fp = %p sig = %d eip = 0x%x cr2 = 0x%x\n",
    297 	    onstack, fp, sig, tf->tf_eip, l->l_addr->u_pcb.pcb_cr2));
    298 
    299 	/* Build stack frame for signal trampoline. */
    300 	frame.sf_handler = catcher;
    301 	frame.sf_sig = native_to_linux_signo[sig];
    302 	frame.sf_sip = &fp->sf_si;
    303 	frame.sf_ucp = &fp->sf_uc;
    304 
    305 	/*
    306 	 * XXX: the following code assumes that the constants for
    307 	 * siginfo are the same between linux and NetBSD.
    308 	 */
    309 	(void)memset(lsi = &frame.sf_si, 0, sizeof(frame.sf_si));
    310 	lsi->lsi_errno = native_to_linux_errno[ksi->ksi_errno];
    311 	lsi->lsi_code = ksi->ksi_code;
    312 	switch (lsi->lsi_signo = frame.sf_sig) {
    313 	case LINUX_SIGILL:
    314 	case LINUX_SIGFPE:
    315 	case LINUX_SIGSEGV:
    316 	case LINUX_SIGBUS:
    317 	case LINUX_SIGTRAP:
    318 		lsi->lsi_addr = ksi->ksi_addr;
    319 		break;
    320 	case LINUX_SIGCHLD:
    321 		lsi->lsi_uid = ksi->ksi_uid;
    322 		lsi->lsi_pid = ksi->ksi_pid;
    323 		lsi->lsi_status = ksi->ksi_status;
    324 		lsi->lsi_utime = ksi->ksi_utime;
    325 		lsi->lsi_stime = ksi->ksi_stime;
    326 		break;
    327 	case LINUX_SIGIO:
    328 		lsi->lsi_band = ksi->ksi_band;
    329 		lsi->lsi_fd = ksi->ksi_fd;
    330 		break;
    331 	default:
    332 		lsi->lsi_uid = ksi->ksi_uid;
    333 		lsi->lsi_pid = ksi->ksi_pid;
    334 		if (lsi->lsi_signo == LINUX_SIGALRM ||
    335 		    lsi->lsi_signo >= LINUX_SIGRTMIN)
    336 			lsi->lsi_value.sival_ptr = ksi->ksi_sigval.sival_ptr;
    337 		break;
    338 	}
    339 
    340 	/* Save register context. */
    341 	linux_save_ucontext(l, tf, mask, sas, &frame.sf_uc);
    342 
    343 	if (copyout(&frame, fp, sizeof(frame)) != 0) {
    344 		/*
    345 		 * Process has trashed its stack; give it an illegal
    346 		 * instruction to halt it in its tracks.
    347 		 */
    348 		sigexit(l, SIGILL);
    349 		/* NOTREACHED */
    350 	}
    351 
    352 	/*
    353 	 * Build context to run handler in.
    354 	 */
    355 	tf->tf_gs = GSEL(GUDATA_SEL, SEL_UPL);
    356 	tf->tf_fs = GSEL(GUDATA_SEL, SEL_UPL);
    357 	tf->tf_es = GSEL(GUDATA_SEL, SEL_UPL);
    358 	tf->tf_ds = GSEL(GUDATA_SEL, SEL_UPL);
    359 	tf->tf_eip = ((int)p->p_sigctx.ps_sigcode) +
    360 	    (linux_rt_sigcode - linux_sigcode);
    361 	tf->tf_cs = GSEL(GUCODE_SEL, SEL_UPL);
    362 	tf->tf_eflags &= ~(PSL_T|PSL_VM|PSL_AC);
    363 	tf->tf_esp = (int)fp;
    364 	tf->tf_ss = GSEL(GUDATA_SEL, SEL_UPL);
    365 
    366 	/* Remember that we're now on the signal stack. */
    367 	if (onstack)
    368 		sas->ss_flags |= SS_ONSTACK;
    369 }
    370 
    371 static void
    372 linux_old_sendsig(const ksiginfo_t *ksi, const sigset_t *mask)
    373 {
    374 	struct lwp *l = curlwp;
    375 	struct proc *p = l->l_proc;
    376 	struct trapframe *tf;
    377 	struct linux_sigframe *fp, frame;
    378 	int onstack;
    379 	int sig = ksi->ksi_signo;
    380 	sig_t catcher = SIGACTION(p, sig).sa_handler;
    381 	struct sigaltstack *sas = &p->p_sigctx.ps_sigstk;
    382 
    383 	tf = l->l_md.md_regs;
    384 
    385 	/* Do we need to jump onto the signal stack? */
    386 	onstack = (sas->ss_flags & (SS_DISABLE | SS_ONSTACK)) == 0 &&
    387 	    (SIGACTION(p, sig).sa_flags & SA_ONSTACK) != 0;
    388 
    389 	/* Allocate space for the signal handler context. */
    390 	if (onstack)
    391 		fp = (struct linux_sigframe *) ((caddr_t)sas->ss_sp +
    392 		    sas->ss_size);
    393 	else
    394 		fp = (struct linux_sigframe *)tf->tf_esp;
    395 	fp--;
    396 
    397 	DPRINTF(("old: onstack = %d, fp = %p sig = %d eip = 0x%x cr2 = 0x%x\n",
    398 	    onstack, fp, sig, tf->tf_eip, l->l_addr->u_pcb.pcb_cr2));
    399 
    400 	/* Build stack frame for signal trampoline. */
    401 	frame.sf_handler = catcher;
    402 	frame.sf_sig = native_to_linux_signo[sig];
    403 
    404 	linux_save_sigcontext(l, tf, mask, &frame.sf_sc);
    405 
    406 	if (copyout(&frame, fp, sizeof(frame)) != 0) {
    407 		/*
    408 		 * Process has trashed its stack; give it an illegal
    409 		 * instruction to halt it in its tracks.
    410 		 */
    411 		sigexit(l, SIGILL);
    412 		/* NOTREACHED */
    413 	}
    414 
    415 	/*
    416 	 * Build context to run handler in.
    417 	 */
    418 	tf->tf_gs = GSEL(GUDATA_SEL, SEL_UPL);
    419 	tf->tf_fs = GSEL(GUDATA_SEL, SEL_UPL);
    420 	tf->tf_es = GSEL(GUDATA_SEL, SEL_UPL);
    421 	tf->tf_ds = GSEL(GUDATA_SEL, SEL_UPL);
    422 	tf->tf_eip = (int)p->p_sigctx.ps_sigcode;
    423 	tf->tf_cs = GSEL(GUCODEBIG_SEL, SEL_UPL);
    424 	tf->tf_eflags &= ~(PSL_T|PSL_VM|PSL_AC);
    425 	tf->tf_esp = (int)fp;
    426 	tf->tf_ss = GSEL(GUDATA_SEL, SEL_UPL);
    427 
    428 	/* Remember that we're now on the signal stack. */
    429 	if (onstack)
    430 		sas->ss_flags |= SS_ONSTACK;
    431 }
    432 
    433 /*
    434  * System call to cleanup state after a signal
    435  * has been taken.  Reset signal mask and
    436  * stack state from context left by sendsig (above).
    437  * Return to previous pc and psl as specified by
    438  * context left by sendsig. Check carefully to
    439  * make sure that the user has not modified the
    440  * psl to gain improper privileges or to cause
    441  * a machine fault.
    442  */
    443 int
    444 linux_sys_rt_sigreturn(l, v, retval)
    445 	struct lwp *l;
    446 	void *v;
    447 	register_t *retval;
    448 {
    449 	struct linux_sys_rt_sigreturn_args /* {
    450 		syscallarg(struct linux_ucontext *) ucp;
    451 	} */ *uap = v;
    452 	struct linux_ucontext context, *ucp = SCARG(uap, ucp);
    453 	int error;
    454 
    455 	/*
    456 	 * The trampoline code hands us the context.
    457 	 * It is unsafe to keep track of it ourselves, in the event that a
    458 	 * program jumps out of a signal handler.
    459 	 */
    460 	if ((error = copyin(ucp, &context, sizeof(*ucp))) != 0)
    461 		return error;
    462 
    463 	/* XXX XAX we can do better here by using more of the ucontext */
    464 	return linux_restore_sigcontext(l, &context.uc_mcontext, retval);
    465 }
    466 
    467 int
    468 linux_sys_sigreturn(l, v, retval)
    469 	struct lwp *l;
    470 	void *v;
    471 	register_t *retval;
    472 {
    473 	struct linux_sys_sigreturn_args /* {
    474 		syscallarg(struct linux_sigcontext *) scp;
    475 	} */ *uap = v;
    476 	struct linux_sigcontext context, *scp = SCARG(uap, scp);
    477 	int error;
    478 
    479 	/*
    480 	 * The trampoline code hands us the context.
    481 	 * It is unsafe to keep track of it ourselves, in the event that a
    482 	 * program jumps out of a signal handler.
    483 	 */
    484 	if ((error = copyin((caddr_t)scp, &context, sizeof(*scp))) != 0)
    485 		return error;
    486 	return linux_restore_sigcontext(l, &context, retval);
    487 }
    488 
    489 static int
    490 linux_restore_sigcontext(l, scp, retval)
    491 	struct lwp *l;
    492 	struct linux_sigcontext *scp;
    493 	register_t *retval;
    494 {
    495 	struct proc *p = l->l_proc;
    496 	struct sigaltstack *sas = &p->p_sigctx.ps_sigstk;
    497 	struct trapframe *tf;
    498 	sigset_t mask;
    499 	ssize_t ss_gap;
    500 	/* Restore register context. */
    501 	tf = l->l_md.md_regs;
    502 
    503 	DPRINTF(("sigreturn enter esp=%x eip=%x\n", tf->tf_esp, tf->tf_eip));
    504 #ifdef VM86
    505 	if (scp->sc_eflags & PSL_VM) {
    506 		void syscall_vm86 __P((struct trapframe *));
    507 
    508 		tf->tf_vm86_gs = scp->sc_gs;
    509 		tf->tf_vm86_fs = scp->sc_fs;
    510 		tf->tf_vm86_es = scp->sc_es;
    511 		tf->tf_vm86_ds = scp->sc_ds;
    512 		set_vflags(l, scp->sc_eflags);
    513 		p->p_md.md_syscall = syscall_vm86;
    514 	} else
    515 #endif
    516 	{
    517 		/*
    518 		 * Check for security violations.  If we're returning to
    519 		 * protected mode, the CPU will validate the segment registers
    520 		 * automatically and generate a trap on violations.  We handle
    521 		 * the trap, rather than doing all of the checking here.
    522 		 */
    523 		if (((scp->sc_eflags ^ tf->tf_eflags) & PSL_USERSTATIC) != 0 ||
    524 		    !USERMODE(scp->sc_cs, scp->sc_eflags))
    525 			return EINVAL;
    526 
    527 		tf->tf_gs = scp->sc_gs;
    528 		tf->tf_fs = scp->sc_fs;
    529 		tf->tf_es = scp->sc_es;
    530 		tf->tf_ds = scp->sc_ds;
    531 #ifdef VM86
    532 		if (tf->tf_eflags & PSL_VM)
    533 			(*p->p_emul->e_syscall_intern)(p);
    534 #endif
    535 		tf->tf_eflags = scp->sc_eflags;
    536 	}
    537 	tf->tf_edi = scp->sc_edi;
    538 	tf->tf_esi = scp->sc_esi;
    539 	tf->tf_ebp = scp->sc_ebp;
    540 	tf->tf_ebx = scp->sc_ebx;
    541 	tf->tf_edx = scp->sc_edx;
    542 	tf->tf_ecx = scp->sc_ecx;
    543 	tf->tf_eax = scp->sc_eax;
    544 	tf->tf_eip = scp->sc_eip;
    545 	tf->tf_cs = scp->sc_cs;
    546 	tf->tf_esp = scp->sc_esp_at_signal;
    547 	tf->tf_ss = scp->sc_ss;
    548 
    549 	/* Restore signal stack. */
    550 	/*
    551 	 * Linux really does it this way; it doesn't have space in sigframe
    552 	 * to save the onstack flag.
    553 	 */
    554 	ss_gap = (ssize_t)
    555 	    ((caddr_t) scp->sc_esp_at_signal - (caddr_t) sas->ss_sp);
    556 	if (ss_gap >= 0 && ss_gap < sas->ss_size)
    557 		sas->ss_flags |= SS_ONSTACK;
    558 	else
    559 		sas->ss_flags &= ~SS_ONSTACK;
    560 
    561 	/* Restore signal mask. */
    562 	linux_old_to_native_sigset(&mask, &scp->sc_mask);
    563 	(void) sigprocmask1(p, SIG_SETMASK, &mask, 0);
    564 	DPRINTF(("sigreturn exit esp=%x eip=%x\n", tf->tf_esp, tf->tf_eip));
    565 	return EJUSTRETURN;
    566 }
    567 
    568 #ifdef USER_LDT
    569 
    570 int
    571 linux_read_ldt(l, uap, retval)
    572 	struct lwp *l;
    573 	struct linux_sys_modify_ldt_args /* {
    574 		syscallarg(int) func;
    575 		syscallarg(void *) ptr;
    576 		syscallarg(size_t) bytecount;
    577 	} */ *uap;
    578 	register_t *retval;
    579 {
    580 	struct proc *p = l->l_proc;
    581 	struct i386_get_ldt_args gl;
    582 	int error;
    583 	caddr_t sg;
    584 	char *parms;
    585 
    586 	DPRINTF(("linux_read_ldt!"));
    587 	sg = stackgap_init(p, 0);
    588 
    589 	gl.start = 0;
    590 	gl.desc = SCARG(uap, ptr);
    591 	gl.num = SCARG(uap, bytecount) / sizeof(union descriptor);
    592 
    593 	parms = stackgap_alloc(p, &sg, sizeof(gl));
    594 
    595 	if ((error = copyout(&gl, parms, sizeof(gl))) != 0)
    596 		return (error);
    597 
    598 	if ((error = i386_get_ldt(l, parms, retval)) != 0)
    599 		return (error);
    600 
    601 	*retval *= sizeof(union descriptor);
    602 	return (0);
    603 }
    604 
    605 struct linux_ldt_info {
    606 	u_int entry_number;
    607 	u_long base_addr;
    608 	u_int limit;
    609 	u_int seg_32bit:1;
    610 	u_int contents:2;
    611 	u_int read_exec_only:1;
    612 	u_int limit_in_pages:1;
    613 	u_int seg_not_present:1;
    614 	u_int useable:1;
    615 };
    616 
    617 int
    618 linux_write_ldt(l, uap, retval)
    619 	struct lwp *l;
    620 	struct linux_sys_modify_ldt_args /* {
    621 		syscallarg(int) func;
    622 		syscallarg(void *) ptr;
    623 		syscallarg(size_t) bytecount;
    624 	} */ *uap;
    625 	register_t *retval;
    626 {
    627 	struct proc *p = l->l_proc;
    628 	struct linux_ldt_info ldt_info;
    629 	struct segment_descriptor sd;
    630 	struct i386_set_ldt_args sl;
    631 	int error;
    632 	caddr_t sg;
    633 	char *parms;
    634 	int oldmode = (int)retval[0];
    635 
    636 	DPRINTF(("linux_write_ldt %d\n", oldmode));
    637 	if (SCARG(uap, bytecount) != sizeof(ldt_info))
    638 		return (EINVAL);
    639 	if ((error = copyin(SCARG(uap, ptr), &ldt_info, sizeof(ldt_info))) != 0)
    640 		return error;
    641 	if (ldt_info.entry_number >= 8192)
    642 		return (EINVAL);
    643 	if (ldt_info.contents == 3) {
    644 		if (oldmode)
    645 			return (EINVAL);
    646 		if (ldt_info.seg_not_present)
    647 			return (EINVAL);
    648 	}
    649 
    650 	if (ldt_info.base_addr == 0 && ldt_info.limit == 0 &&
    651 	    (oldmode || (ldt_info.contents == 0 &&
    652 	    ldt_info.read_exec_only == 1 && ldt_info.seg_32bit == 0 &&
    653 	    ldt_info.limit_in_pages == 0 && ldt_info.seg_not_present == 1 &&
    654 	    ldt_info.useable == 0))) {
    655 		/* this means you should zero the ldt */
    656 		(void)memset(&sd, 0, sizeof(sd));
    657 	} else {
    658 		sd.sd_lobase = ldt_info.base_addr & 0xffffff;
    659 		sd.sd_hibase = (ldt_info.base_addr >> 24) & 0xff;
    660 		sd.sd_lolimit = ldt_info.limit & 0xffff;
    661 		sd.sd_hilimit = (ldt_info.limit >> 16) & 0xf;
    662 		sd.sd_type = 16 | (ldt_info.contents << 2) |
    663 		    (!ldt_info.read_exec_only << 1);
    664 		sd.sd_dpl = SEL_UPL;
    665 		sd.sd_p = !ldt_info.seg_not_present;
    666 		sd.sd_def32 = ldt_info.seg_32bit;
    667 		sd.sd_gran = ldt_info.limit_in_pages;
    668 		if (!oldmode)
    669 			sd.sd_xx = ldt_info.useable;
    670 		else
    671 			sd.sd_xx = 0;
    672 	}
    673 	sg = stackgap_init(p, 0);
    674 	sl.start = ldt_info.entry_number;
    675 	sl.desc = stackgap_alloc(p, &sg, sizeof(sd));
    676 	sl.num = 1;
    677 
    678 	DPRINTF(("linux_write_ldt: idx=%d, base=0x%lx, limit=0x%x\n",
    679 	    ldt_info.entry_number, ldt_info.base_addr, ldt_info.limit));
    680 
    681 	parms = stackgap_alloc(p, &sg, sizeof(sl));
    682 
    683 	if ((error = copyout(&sd, sl.desc, sizeof(sd))) != 0)
    684 		return (error);
    685 	if ((error = copyout(&sl, parms, sizeof(sl))) != 0)
    686 		return (error);
    687 
    688 	if ((error = i386_set_ldt(l, parms, retval)) != 0)
    689 		return (error);
    690 
    691 	*retval = 0;
    692 	return (0);
    693 }
    694 
    695 #endif /* USER_LDT */
    696 
    697 int
    698 linux_sys_modify_ldt(l, v, retval)
    699 	struct lwp *l;
    700 	void *v;
    701 	register_t *retval;
    702 {
    703 	struct linux_sys_modify_ldt_args /* {
    704 		syscallarg(int) func;
    705 		syscallarg(void *) ptr;
    706 		syscallarg(size_t) bytecount;
    707 	} */ *uap = v;
    708 
    709 	switch (SCARG(uap, func)) {
    710 #ifdef USER_LDT
    711 	case 0:
    712 		return linux_read_ldt(l, uap, retval);
    713 	case 1:
    714 		retval[0] = 1;
    715 		return linux_write_ldt(l, uap, retval);
    716 	case 2:
    717 #ifdef notyet
    718 		return (linux_read_default_ldt(l, uap, retval);
    719 #else
    720 		return (ENOSYS);
    721 #endif
    722 	case 0x11:
    723 		retval[0] = 0;
    724 		return linux_write_ldt(l, uap, retval);
    725 #endif /* USER_LDT */
    726 
    727 	default:
    728 		return (ENOSYS);
    729 	}
    730 }
    731 
    732 /*
    733  * XXX Pathetic hack to make svgalib work. This will fake the major
    734  * device number of an opened VT so that svgalib likes it. grmbl.
    735  * Should probably do it 'wrong the right way' and use a mapping
    736  * array for all major device numbers, and map linux_mknod too.
    737  */
    738 dev_t
    739 linux_fakedev(dev, raw)
    740 	dev_t dev;
    741 	int raw;
    742 {
    743 	extern const struct cdevsw ptc_cdevsw, pts_cdevsw;
    744 	const struct cdevsw *cd = cdevsw_lookup(dev);
    745 
    746 	if (raw) {
    747 #if (NWSDISPLAY > 0)
    748 		extern const struct cdevsw wsdisplay_cdevsw;
    749 		if (cd == &wsdisplay_cdevsw)
    750 			return makedev(LINUX_CONS_MAJOR, (minor(dev) + 1));
    751 #endif
    752 	}
    753 
    754 	if (cd == &ptc_cdevsw)
    755 		return makedev(LINUX_PTC_MAJOR, minor(dev));
    756 	if (cd == &pts_cdevsw)
    757 		return makedev(LINUX_PTS_MAJOR, minor(dev));
    758 
    759 	return dev;
    760 }
    761 
    762 #if (NWSDISPLAY > 0)
    763 /*
    764  * That's not complete, but enough to get an X server running.
    765  */
    766 #define NR_KEYS 128
    767 static const u_short plain_map[NR_KEYS] = {
    768 	0x0200,	0x001b,	0x0031,	0x0032,	0x0033,	0x0034,	0x0035,	0x0036,
    769 	0x0037,	0x0038,	0x0039,	0x0030,	0x002d,	0x003d,	0x007f,	0x0009,
    770 	0x0b71,	0x0b77,	0x0b65,	0x0b72,	0x0b74,	0x0b79,	0x0b75,	0x0b69,
    771 	0x0b6f,	0x0b70,	0x005b,	0x005d,	0x0201,	0x0702,	0x0b61,	0x0b73,
    772 	0x0b64,	0x0b66,	0x0b67,	0x0b68,	0x0b6a,	0x0b6b,	0x0b6c,	0x003b,
    773 	0x0027,	0x0060,	0x0700,	0x005c,	0x0b7a,	0x0b78,	0x0b63,	0x0b76,
    774 	0x0b62,	0x0b6e,	0x0b6d,	0x002c,	0x002e,	0x002f,	0x0700,	0x030c,
    775 	0x0703,	0x0020,	0x0207,	0x0100,	0x0101,	0x0102,	0x0103,	0x0104,
    776 	0x0105,	0x0106,	0x0107,	0x0108,	0x0109,	0x0208,	0x0209,	0x0307,
    777 	0x0308,	0x0309,	0x030b,	0x0304,	0x0305,	0x0306,	0x030a,	0x0301,
    778 	0x0302,	0x0303,	0x0300,	0x0310,	0x0206,	0x0200,	0x003c,	0x010a,
    779 	0x010b,	0x0200,	0x0200,	0x0200,	0x0200,	0x0200,	0x0200,	0x0200,
    780 	0x030e,	0x0702,	0x030d,	0x001c,	0x0701,	0x0205,	0x0114,	0x0603,
    781 	0x0118,	0x0601,	0x0602,	0x0117,	0x0600,	0x0119,	0x0115,	0x0116,
    782 	0x011a,	0x010c,	0x010d,	0x011b,	0x011c,	0x0110,	0x0311,	0x011d,
    783 	0x0200,	0x0200,	0x0200,	0x0200,	0x0200,	0x0200,	0x0200,	0x0200,
    784 }, shift_map[NR_KEYS] = {
    785 	0x0200,	0x001b,	0x0021,	0x0040,	0x0023,	0x0024,	0x0025,	0x005e,
    786 	0x0026,	0x002a,	0x0028,	0x0029,	0x005f,	0x002b,	0x007f,	0x0009,
    787 	0x0b51,	0x0b57,	0x0b45,	0x0b52,	0x0b54,	0x0b59,	0x0b55,	0x0b49,
    788 	0x0b4f,	0x0b50,	0x007b,	0x007d,	0x0201,	0x0702,	0x0b41,	0x0b53,
    789 	0x0b44,	0x0b46,	0x0b47,	0x0b48,	0x0b4a,	0x0b4b,	0x0b4c,	0x003a,
    790 	0x0022,	0x007e,	0x0700,	0x007c,	0x0b5a,	0x0b58,	0x0b43,	0x0b56,
    791 	0x0b42,	0x0b4e,	0x0b4d,	0x003c,	0x003e,	0x003f,	0x0700,	0x030c,
    792 	0x0703,	0x0020,	0x0207,	0x010a,	0x010b,	0x010c,	0x010d,	0x010e,
    793 	0x010f,	0x0110,	0x0111,	0x0112,	0x0113,	0x0213,	0x0203,	0x0307,
    794 	0x0308,	0x0309,	0x030b,	0x0304,	0x0305,	0x0306,	0x030a,	0x0301,
    795 	0x0302,	0x0303,	0x0300,	0x0310,	0x0206,	0x0200,	0x003e,	0x010a,
    796 	0x010b,	0x0200,	0x0200,	0x0200,	0x0200,	0x0200,	0x0200,	0x0200,
    797 	0x030e,	0x0702,	0x030d,	0x0200,	0x0701,	0x0205,	0x0114,	0x0603,
    798 	0x020b,	0x0601,	0x0602,	0x0117,	0x0600,	0x020a,	0x0115,	0x0116,
    799 	0x011a,	0x010c,	0x010d,	0x011b,	0x011c,	0x0110,	0x0311,	0x011d,
    800 	0x0200,	0x0200,	0x0200,	0x0200,	0x0200,	0x0200,	0x0200,	0x0200,
    801 }, altgr_map[NR_KEYS] = {
    802 	0x0200,	0x0200,	0x0200,	0x0040,	0x0200,	0x0024,	0x0200,	0x0200,
    803 	0x007b,	0x005b,	0x005d,	0x007d,	0x005c,	0x0200,	0x0200,	0x0200,
    804 	0x0b71,	0x0b77,	0x0918,	0x0b72,	0x0b74,	0x0b79,	0x0b75,	0x0b69,
    805 	0x0b6f,	0x0b70,	0x0200,	0x007e,	0x0201,	0x0702,	0x0914,	0x0b73,
    806 	0x0917,	0x0919,	0x0b67,	0x0b68,	0x0b6a,	0x0b6b,	0x0b6c,	0x0200,
    807 	0x0200,	0x0200,	0x0700,	0x0200,	0x0b7a,	0x0b78,	0x0916,	0x0b76,
    808 	0x0915,	0x0b6e,	0x0b6d,	0x0200,	0x0200,	0x0200,	0x0700,	0x030c,
    809 	0x0703,	0x0200,	0x0207,	0x050c,	0x050d,	0x050e,	0x050f,	0x0510,
    810 	0x0511,	0x0512,	0x0513,	0x0514,	0x0515,	0x0208,	0x0202,	0x0911,
    811 	0x0912,	0x0913,	0x030b,	0x090e,	0x090f,	0x0910,	0x030a,	0x090b,
    812 	0x090c,	0x090d,	0x090a,	0x0310,	0x0206,	0x0200,	0x007c,	0x0516,
    813 	0x0517,	0x0200,	0x0200,	0x0200,	0x0200,	0x0200,	0x0200,	0x0200,
    814 	0x030e,	0x0702,	0x030d,	0x0200,	0x0701,	0x0205,	0x0114,	0x0603,
    815 	0x0118,	0x0601,	0x0602,	0x0117,	0x0600,	0x0119,	0x0115,	0x0116,
    816 	0x011a,	0x010c,	0x010d,	0x011b,	0x011c,	0x0110,	0x0311,	0x011d,
    817 	0x0200,	0x0200,	0x0200,	0x0200,	0x0200,	0x0200,	0x0200,	0x0200,
    818 }, ctrl_map[NR_KEYS] = {
    819 	0x0200,	0x0200,	0x0200,	0x0000,	0x001b,	0x001c,	0x001d,	0x001e,
    820 	0x001f,	0x007f,	0x0200,	0x0200,	0x001f,	0x0200,	0x0008,	0x0200,
    821 	0x0011,	0x0017,	0x0005,	0x0012,	0x0014,	0x0019,	0x0015,	0x0009,
    822 	0x000f,	0x0010,	0x001b,	0x001d,	0x0201,	0x0702,	0x0001,	0x0013,
    823 	0x0004,	0x0006,	0x0007,	0x0008,	0x000a,	0x000b,	0x000c,	0x0200,
    824 	0x0007,	0x0000,	0x0700,	0x001c,	0x001a,	0x0018,	0x0003,	0x0016,
    825 	0x0002,	0x000e,	0x000d,	0x0200,	0x020e,	0x007f,	0x0700,	0x030c,
    826 	0x0703,	0x0000,	0x0207,	0x0100,	0x0101,	0x0102,	0x0103,	0x0104,
    827 	0x0105,	0x0106,	0x0107,	0x0108,	0x0109,	0x0208,	0x0204,	0x0307,
    828 	0x0308,	0x0309,	0x030b,	0x0304,	0x0305,	0x0306,	0x030a,	0x0301,
    829 	0x0302,	0x0303,	0x0300,	0x0310,	0x0206,	0x0200,	0x0200,	0x010a,
    830 	0x010b,	0x0200,	0x0200,	0x0200,	0x0200,	0x0200,	0x0200,	0x0200,
    831 	0x030e,	0x0702,	0x030d,	0x001c,	0x0701,	0x0205,	0x0114,	0x0603,
    832 	0x0118,	0x0601,	0x0602,	0x0117,	0x0600,	0x0119,	0x0115,	0x0116,
    833 	0x011a,	0x010c,	0x010d,	0x011b,	0x011c,	0x0110,	0x0311,	0x011d,
    834 	0x0200,	0x0200,	0x0200,	0x0200,	0x0200,	0x0200,	0x0200,	0x0200,
    835 };
    836 
    837 const u_short * const linux_keytabs[] = {
    838 	plain_map, shift_map, altgr_map, altgr_map, ctrl_map
    839 };
    840 #endif
    841 
    842 static struct biosdisk_info *
    843 fd2biosinfo(p, fp)
    844 	struct proc *p;
    845 	struct file *fp;
    846 {
    847 	struct vnode *vp;
    848 	const char *blkname;
    849 	char diskname[16];
    850 	int i;
    851 	struct nativedisk_info *nip;
    852 	struct disklist *dl = x86_alldisks;
    853 
    854 	if (fp->f_type != DTYPE_VNODE)
    855 		return NULL;
    856 	vp = (struct vnode *)fp->f_data;
    857 
    858 	if (vp->v_type != VBLK)
    859 		return NULL;
    860 
    861 	blkname = devsw_blk2name(major(vp->v_rdev));
    862 	snprintf(diskname, sizeof diskname, "%s%u", blkname,
    863 	    DISKUNIT(vp->v_rdev));
    864 
    865 	for (i = 0; i < dl->dl_nnativedisks; i++) {
    866 		nip = &dl->dl_nativedisks[i];
    867 		if (strcmp(diskname, nip->ni_devname))
    868 			continue;
    869 		if (nip->ni_nmatches != 0)
    870 			return &dl->dl_biosdisks[nip->ni_biosmatches[0]];
    871 	}
    872 
    873 	return NULL;
    874 }
    875 
    876 
    877 /*
    878  * We come here in a last attempt to satisfy a Linux ioctl() call
    879  */
    880 int
    881 linux_machdepioctl(p, v, retval)
    882 	struct proc *p;
    883 	void *v;
    884 	register_t *retval;
    885 {
    886 	struct linux_sys_ioctl_args /* {
    887 		syscallarg(int) fd;
    888 		syscallarg(u_long) com;
    889 		syscallarg(caddr_t) data;
    890 	} */ *uap = v;
    891 	struct sys_ioctl_args bia;
    892 	u_long com;
    893 	int error, error1;
    894 #if (NWSDISPLAY > 0)
    895 	struct vt_mode lvt;
    896 	caddr_t bvtp, sg;
    897 	struct kbentry kbe;
    898 #endif
    899 	struct linux_hd_geometry hdg;
    900 	struct linux_hd_big_geometry hdg_big;
    901 	struct biosdisk_info *bip;
    902 	struct filedesc *fdp;
    903 	struct file *fp;
    904 	int fd;
    905 	struct disklabel label, *labp;
    906 	struct partinfo partp;
    907 	int (*ioctlf)(struct file *, u_long, void *, struct proc *);
    908 	u_long start, biostotal, realtotal;
    909 	u_char heads, sectors;
    910 	u_int cylinders;
    911 	struct ioctl_pt pt;
    912 
    913 	fd = SCARG(uap, fd);
    914 	SCARG(&bia, fd) = fd;
    915 	SCARG(&bia, data) = SCARG(uap, data);
    916 	com = SCARG(uap, com);
    917 
    918 	fdp = p->p_fd;
    919 
    920 	if ((fp = fd_getfile(fdp, fd)) == NULL)
    921 		return (EBADF);
    922 
    923 	FILE_USE(fp);
    924 
    925 	switch (com) {
    926 #if (NWSDISPLAY > 0)
    927 	case LINUX_KDGKBMODE:
    928 		com = KDGKBMODE;
    929 		break;
    930 	case LINUX_KDSKBMODE:
    931 		com = KDSKBMODE;
    932 		if ((unsigned)SCARG(uap, data) == LINUX_K_MEDIUMRAW)
    933 			SCARG(&bia, data) = (caddr_t)K_RAW;
    934 		break;
    935 	case LINUX_KIOCSOUND:
    936 		SCARG(&bia, data) =
    937 		    (caddr_t)(((unsigned long)SCARG(&bia, data)) & 0xffff);
    938 		/* fall through */
    939 	case LINUX_KDMKTONE:
    940 		com = KDMKTONE;
    941 		break;
    942 	case LINUX_KDSETMODE:
    943 		com = KDSETMODE;
    944 		break;
    945 	case LINUX_KDGETMODE:
    946 		/* KD_* values are equal to the wscons numbers */
    947 		com = WSDISPLAYIO_GMODE;
    948 		break;
    949 	case LINUX_KDENABIO:
    950 		com = KDENABIO;
    951 		break;
    952 	case LINUX_KDDISABIO:
    953 		com = KDDISABIO;
    954 		break;
    955 	case LINUX_KDGETLED:
    956 		com = KDGETLED;
    957 		break;
    958 	case LINUX_KDSETLED:
    959 		com = KDSETLED;
    960 		break;
    961 	case LINUX_VT_OPENQRY:
    962 		com = VT_OPENQRY;
    963 		break;
    964 	case LINUX_VT_GETMODE:
    965 		SCARG(&bia, com) = VT_GETMODE;
    966 		/* XXX NJWLWP */
    967 		if ((error = sys_ioctl(curlwp, &bia, retval)))
    968 			goto out;
    969 		if ((error = copyin(SCARG(uap, data), (caddr_t)&lvt,
    970 		    sizeof (struct vt_mode))))
    971 			goto out;
    972 		lvt.relsig = native_to_linux_signo[lvt.relsig];
    973 		lvt.acqsig = native_to_linux_signo[lvt.acqsig];
    974 		lvt.frsig = native_to_linux_signo[lvt.frsig];
    975 		error = copyout((caddr_t)&lvt, SCARG(uap, data),
    976 		    sizeof (struct vt_mode));
    977 		goto out;
    978 	case LINUX_VT_SETMODE:
    979 		com = VT_SETMODE;
    980 		if ((error = copyin(SCARG(uap, data), (caddr_t)&lvt,
    981 		    sizeof (struct vt_mode))))
    982 			goto out;
    983 		lvt.relsig = linux_to_native_signo[lvt.relsig];
    984 		lvt.acqsig = linux_to_native_signo[lvt.acqsig];
    985 		lvt.frsig = linux_to_native_signo[lvt.frsig];
    986 		sg = stackgap_init(p, 0);
    987 		bvtp = stackgap_alloc(p, &sg, sizeof (struct vt_mode));
    988 		if ((error = copyout(&lvt, bvtp, sizeof (struct vt_mode))))
    989 			goto out;
    990 		SCARG(&bia, data) = bvtp;
    991 		break;
    992 	case LINUX_VT_DISALLOCATE:
    993 		/* XXX should use WSDISPLAYIO_DELSCREEN */
    994 		error = 0;
    995 		goto out;
    996 	case LINUX_VT_RELDISP:
    997 		com = VT_RELDISP;
    998 		break;
    999 	case LINUX_VT_ACTIVATE:
   1000 		com = VT_ACTIVATE;
   1001 		break;
   1002 	case LINUX_VT_WAITACTIVE:
   1003 		com = VT_WAITACTIVE;
   1004 		break;
   1005 	case LINUX_VT_GETSTATE:
   1006 		com = VT_GETSTATE;
   1007 		break;
   1008 	case LINUX_KDGKBTYPE:
   1009 	    {
   1010 		static const u_int8_t kb101 = KB_101;
   1011 
   1012 		/* This is what Linux does. */
   1013 		error = copyout(&kb101, SCARG(uap, data), 1);
   1014 		goto out;
   1015 	    }
   1016 	case LINUX_KDGKBENT:
   1017 		/*
   1018 		 * The Linux KDGKBENT ioctl is different from the
   1019 		 * SYSV original. So we handle it in machdep code.
   1020 		 * XXX We should use keyboard mapping information
   1021 		 * from wsdisplay, but this would be expensive.
   1022 		 */
   1023 		if ((error = copyin(SCARG(uap, data), &kbe,
   1024 				    sizeof(struct kbentry))))
   1025 			goto out;
   1026 		if (kbe.kb_table >= sizeof(linux_keytabs) / sizeof(u_short *)
   1027 		    || kbe.kb_index >= NR_KEYS) {
   1028 			error = EINVAL;
   1029 			goto out;
   1030 		}
   1031 		kbe.kb_value = linux_keytabs[kbe.kb_table][kbe.kb_index];
   1032 		error = copyout(&kbe, SCARG(uap, data),
   1033 				sizeof(struct kbentry));
   1034 		goto out;
   1035 #endif
   1036 	case LINUX_HDIO_GETGEO:
   1037 	case LINUX_HDIO_GETGEO_BIG:
   1038 		/*
   1039 		 * Try to mimic Linux behaviour: return the BIOS geometry
   1040 		 * if possible (extending its # of cylinders if it's beyond
   1041 		 * the 1023 limit), fall back to the MI geometry (i.e.
   1042 		 * the real geometry) if not found, by returning an
   1043 		 * error. See common/linux_hdio.c
   1044 		 */
   1045 		bip = fd2biosinfo(p, fp);
   1046 		ioctlf = fp->f_ops->fo_ioctl;
   1047 		error = ioctlf(fp, DIOCGDEFLABEL, (caddr_t)&label, p);
   1048 		error1 = ioctlf(fp, DIOCGPART, (caddr_t)&partp, p);
   1049 		if (error != 0 && error1 != 0) {
   1050 			error = error1;
   1051 			goto out;
   1052 		}
   1053 		labp = error != 0 ? &label : partp.disklab;
   1054 		start = error1 != 0 ? partp.part->p_offset : 0;
   1055 		if (bip != NULL && bip->bi_head != 0 && bip->bi_sec != 0
   1056 		    && bip->bi_cyl != 0) {
   1057 			heads = bip->bi_head;
   1058 			sectors = bip->bi_sec;
   1059 			cylinders = bip->bi_cyl;
   1060 			biostotal = heads * sectors * cylinders;
   1061 			realtotal = labp->d_ntracks * labp->d_nsectors *
   1062 			    labp->d_ncylinders;
   1063 			if (realtotal > biostotal)
   1064 				cylinders = realtotal / (heads * sectors);
   1065 		} else {
   1066 			heads = labp->d_ntracks;
   1067 			cylinders = labp->d_ncylinders;
   1068 			sectors = labp->d_nsectors;
   1069 		}
   1070 		if (com == LINUX_HDIO_GETGEO) {
   1071 			hdg.start = start;
   1072 			hdg.heads = heads;
   1073 			hdg.cylinders = cylinders;
   1074 			hdg.sectors = sectors;
   1075 			error = copyout(&hdg, SCARG(uap, data), sizeof hdg);
   1076 			goto out;
   1077 		} else {
   1078 			hdg_big.start = start;
   1079 			hdg_big.heads = heads;
   1080 			hdg_big.cylinders = cylinders;
   1081 			hdg_big.sectors = sectors;
   1082 			error = copyout(&hdg_big, SCARG(uap, data),
   1083 			    sizeof hdg_big);
   1084 			goto out;
   1085 		}
   1086 
   1087 	default:
   1088 		/*
   1089 		 * Unknown to us. If it's on a device, just pass it through
   1090 		 * using PTIOCLINUX, the device itself might be able to
   1091 		 * make some sense of it.
   1092 		 * XXX hack: if the function returns EJUSTRETURN,
   1093 		 * it has stuffed a sysctl return value in pt.data.
   1094 		 */
   1095 		FILE_USE(fp);
   1096 		ioctlf = fp->f_ops->fo_ioctl;
   1097 		pt.com = SCARG(uap, com);
   1098 		pt.data = SCARG(uap, data);
   1099 		error = ioctlf(fp, PTIOCLINUX, (caddr_t)&pt, p);
   1100 		FILE_UNUSE(fp, p);
   1101 		if (error == EJUSTRETURN) {
   1102 			retval[0] = (register_t)pt.data;
   1103 			error = 0;
   1104 		}
   1105 
   1106 		if (error == ENOTTY)
   1107 			DPRINTF(("linux_machdepioctl: invalid ioctl %08lx\n",
   1108 			    com));
   1109 		goto out;
   1110 	}
   1111 	SCARG(&bia, com) = com;
   1112 	/* XXX NJWLWP */
   1113 	error = sys_ioctl(curlwp, &bia, retval);
   1114 out:
   1115 	FILE_UNUSE(fp ,p);
   1116 	return error;
   1117 }
   1118 
   1119 /*
   1120  * Set I/O permissions for a process. Just set the maximum level
   1121  * right away (ignoring the argument), otherwise we would have
   1122  * to rely on I/O permission maps, which are not implemented.
   1123  */
   1124 int
   1125 linux_sys_iopl(l, v, retval)
   1126 	struct lwp *l;
   1127 	void *v;
   1128 	register_t *retval;
   1129 {
   1130 #if 0
   1131 	struct linux_sys_iopl_args /* {
   1132 		syscallarg(int) level;
   1133 	} */ *uap = v;
   1134 #endif
   1135 	struct proc *p = l->l_proc;
   1136 	struct trapframe *fp = l->l_md.md_regs;
   1137 
   1138 	if (suser(p->p_ucred, &p->p_acflag) != 0)
   1139 		return EPERM;
   1140 	fp->tf_eflags |= PSL_IOPL;
   1141 	*retval = 0;
   1142 	return 0;
   1143 }
   1144 
   1145 /*
   1146  * See above. If a root process tries to set access to an I/O port,
   1147  * just let it have the whole range.
   1148  */
   1149 int
   1150 linux_sys_ioperm(l, v, retval)
   1151 	struct lwp *l;
   1152 	void *v;
   1153 	register_t *retval;
   1154 {
   1155 	struct linux_sys_ioperm_args /* {
   1156 		syscallarg(unsigned int) lo;
   1157 		syscallarg(unsigned int) hi;
   1158 		syscallarg(int) val;
   1159 	} */ *uap = v;
   1160 	struct proc *p = l->l_proc;
   1161 	struct trapframe *fp = l->l_md.md_regs;
   1162 
   1163 	if (suser(p->p_ucred, &p->p_acflag) != 0)
   1164 		return EPERM;
   1165 	if (SCARG(uap, val))
   1166 		fp->tf_eflags |= PSL_IOPL;
   1167 	*retval = 0;
   1168 	return 0;
   1169 }
   1170 
   1171 int
   1172 linux_usertrap(struct lwp *l, vaddr_t trapaddr, void *arg)
   1173 {
   1174 	return 0;
   1175 }
   1176