[BACK]Return to linux_machdep.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / compat / linux / arch / i386

Annotation of src/sys/compat/linux/arch/i386/linux_machdep.c, Revision 1.20

1.20    ! mycroft     1: /*     $NetBSD: linux_machdep.c,v 1.19 1995/09/19 22:56:37 thorpej Exp $       */
1.1       fvdl        2:
                      3: /*
                      4:  * Copyright (c) 1995 Frank van der Linden
                      5:  * All rights reserved.
                      6:  *
                      7:  * Redistribution and use in source and binary forms, with or without
                      8:  * modification, are permitted provided that the following conditions
                      9:  * are met:
                     10:  * 1. Redistributions of source code must retain the above copyright
                     11:  *    notice, this list of conditions and the following disclaimer.
                     12:  * 2. Redistributions in binary form must reproduce the above copyright
                     13:  *    notice, this list of conditions and the following disclaimer in the
                     14:  *    documentation and/or other materials provided with the distribution.
                     15:  * 3. All advertising materials mentioning features or use of this software
                     16:  *    must display the following acknowledgement:
                     17:  *      This product includes software developed for the NetBSD Project
                     18:  *      by Frank van der Linden
                     19:  * 4. The name of the author may not be used to endorse or promote products
                     20:  *    derived from this software without specific prior written permission
                     21:  *
                     22:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
                     23:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
                     24:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
                     25:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
                     26:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
                     27:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
                     28:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
                     29:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
                     30:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
                     31:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
                     32:  */
                     33:
                     34: #include <sys/param.h>
                     35: #include <sys/systm.h>
                     36: #include <sys/signalvar.h>
                     37: #include <sys/kernel.h>
                     38: #include <sys/map.h>
                     39: #include <sys/proc.h>
                     40: #include <sys/user.h>
                     41: #include <sys/buf.h>
                     42: #include <sys/reboot.h>
                     43: #include <sys/conf.h>
                     44: #include <sys/file.h>
                     45: #include <sys/callout.h>
                     46: #include <sys/malloc.h>
                     47: #include <sys/mbuf.h>
                     48: #include <sys/msgbuf.h>
                     49: #include <sys/mount.h>
                     50: #include <sys/vnode.h>
                     51: #include <sys/device.h>
                     52: #include <sys/sysctl.h>
                     53: #include <sys/syscallargs.h>
1.13      fvdl       54: #include <sys/filedesc.h>
1.7       mycroft    55:
1.1       fvdl       56: #include <compat/linux/linux_types.h>
1.11      mycroft    57: #include <compat/linux/linux_signal.h>
1.1       fvdl       58: #include <compat/linux/linux_syscallargs.h>
1.7       mycroft    59: #include <compat/linux/linux_util.h>
1.1       fvdl       60:
                     61: #include <machine/cpu.h>
                     62: #include <machine/cpufunc.h>
                     63: #include <machine/psl.h>
                     64: #include <machine/reg.h>
1.7       mycroft    65: #include <machine/segments.h>
1.1       fvdl       66: #include <machine/specialreg.h>
1.7       mycroft    67: #include <machine/sysarch.h>
1.1       fvdl       68: #include <machine/linux_machdep.h>
                     69:
                     70: /*
1.13      fvdl       71:  * To see whether pcvt is configured (for virtual console ioctl calls).
                     72:  */
                     73: #include "vt.h"
                     74: #if NVT > 0
                     75: #include <arch/i386/isa/pcvt/pcvt_ioctl.h>
                     76: #endif
                     77:
                     78: /*
1.1       fvdl       79:  * Deal with some i386-specific things in the Linux emulation code.
                     80:  * This means just signals for now, will include stuff like
                     81:  * I/O map permissions and V86 mode sometime.
                     82:  */
                     83:
                     84: /*
                     85:  * Send an interrupt to process.
                     86:  *
                     87:  * Stack is set up to allow sigcode stored
                     88:  * in u. to call routine, followed by kcall
                     89:  * to sigreturn routine below.  After sigreturn
                     90:  * resets the signal mask, the stack, and the
                     91:  * frame pointer, it returns to the user
                     92:  * specified pc, psl.
                     93:  */
                     94:
                     95: void
                     96: linux_sendsig(catcher, sig, mask, code)
                     97:        sig_t catcher;
                     98:        int sig, mask;
                     99:        u_long code;
                    100: {
                    101:        register struct proc *p = curproc;
                    102:        register struct trapframe *tf;
                    103:        struct linux_sigframe *fp, frame;
                    104:        struct sigacts *psp = p->p_sigacts;
                    105:        int oonstack;
                    106:        extern char linux_sigcode[], linux_esigcode[];
                    107:
1.3       mycroft   108:        tf = p->p_md.md_regs;
1.16      mycroft   109:        oonstack = psp->ps_sigstk.ss_flags & SS_ONSTACK;
1.1       fvdl      110:
                    111:        /*
                    112:         * Allocate space for the signal handler context.
                    113:         */
                    114:        if ((psp->ps_flags & SAS_ALTSTACK) && !oonstack &&
                    115:            (psp->ps_sigonstack & sigmask(sig))) {
                    116:                fp = (struct linux_sigframe *)(psp->ps_sigstk.ss_base +
                    117:                    psp->ps_sigstk.ss_size - sizeof(struct linux_sigframe));
1.16      mycroft   118:                psp->ps_sigstk.ss_flags |= SS_ONSTACK;
1.1       fvdl      119:        } else {
                    120:                fp = (struct linux_sigframe *)tf->tf_esp - 1;
                    121:        }
                    122:
1.7       mycroft   123:        frame.sf_handler = catcher;
1.12      mycroft   124:        frame.sf_sig = bsd_to_linux_sig[sig];
1.1       fvdl      125:
                    126:        /*
                    127:         * Build the signal context to be used by sigreturn.
                    128:         */
1.7       mycroft   129:        frame.sf_sc.sc_mask   = mask;
1.4       mycroft   130: #ifdef VM86
                    131:        if (tf->tf_eflags & PSL_VM) {
1.7       mycroft   132:                frame.sf_sc.sc_gs = tf->tf_vm86_gs;
                    133:                frame.sf_sc.sc_fs = tf->tf_vm86_fs;
                    134:                frame.sf_sc.sc_es = tf->tf_vm86_es;
                    135:                frame.sf_sc.sc_ds = tf->tf_vm86_ds;
1.4       mycroft   136:        } else
1.18      fvdl      137: #endif
1.4       mycroft   138:        {
1.7       mycroft   139:                __asm("movl %%gs,%w0" : "=r" (frame.sf_sc.sc_gs));
                    140:                __asm("movl %%fs,%w0" : "=r" (frame.sf_sc.sc_fs));
                    141:                frame.sf_sc.sc_es = tf->tf_es;
                    142:                frame.sf_sc.sc_ds = tf->tf_ds;
1.4       mycroft   143:        }
1.7       mycroft   144:        frame.sf_sc.sc_edi    = tf->tf_edi;
                    145:        frame.sf_sc.sc_esi    = tf->tf_esi;
                    146:        frame.sf_sc.sc_ebp    = tf->tf_ebp;
                    147:        frame.sf_sc.sc_ebx    = tf->tf_ebx;
                    148:        frame.sf_sc.sc_edx    = tf->tf_edx;
                    149:        frame.sf_sc.sc_ecx    = tf->tf_ecx;
                    150:        frame.sf_sc.sc_eax    = tf->tf_eax;
                    151:        frame.sf_sc.sc_eip    = tf->tf_eip;
                    152:        frame.sf_sc.sc_cs     = tf->tf_cs;
                    153:        frame.sf_sc.sc_eflags = tf->tf_eflags;
                    154:        frame.sf_sc.sc_esp_at_signal = tf->tf_esp;
                    155:        frame.sf_sc.sc_ss     = tf->tf_ss;
                    156:        frame.sf_sc.sc_err    = tf->tf_err;
                    157:        frame.sf_sc.sc_trapno = tf->tf_trapno;
1.1       fvdl      158:
                    159:        if (copyout(&frame, fp, sizeof(frame)) != 0) {
                    160:                /*
                    161:                 * Process has trashed its stack; give it an illegal
                    162:                 * instruction to halt it in its tracks.
                    163:                 */
                    164:                sigexit(p, SIGILL);
                    165:                /* NOTREACHED */
                    166:        }
                    167:
                    168:        /*
                    169:         * Build context to run handler in.
                    170:         */
                    171:        tf->tf_esp = (int)fp;
                    172:        tf->tf_eip = (int)(((char *)PS_STRINGS) -
                    173:             (linux_esigcode - linux_sigcode));
1.3       mycroft   174: #ifdef VM86
1.1       fvdl      175:        tf->tf_eflags &= ~PSL_VM;
1.3       mycroft   176: #endif
1.2       christos  177:        tf->tf_cs = LSEL(LUCODE_SEL, SEL_UPL);
                    178:        tf->tf_ds = LSEL(LUDATA_SEL, SEL_UPL);
                    179:        tf->tf_es = LSEL(LUDATA_SEL, SEL_UPL);
                    180:        tf->tf_ss = LSEL(LUDATA_SEL, SEL_UPL);
1.1       fvdl      181: }
                    182:
                    183: /*
                    184:  * System call to cleanup state after a signal
                    185:  * has been taken.  Reset signal mask and
                    186:  * stack state from context left by sendsig (above).
                    187:  * Return to previous pc and psl as specified by
                    188:  * context left by sendsig. Check carefully to
                    189:  * make sure that the user has not modified the
                    190:  * psl to gain improper privileges or to cause
                    191:  * a machine fault.
                    192:  */
                    193: int
1.20    ! mycroft   194: linux_sys_sigreturn(p, v, retval)
1.1       fvdl      195:        struct proc *p;
1.19      thorpej   196:        void *v;
                    197:        register_t *retval;
                    198: {
1.20    ! mycroft   199:        struct linux_sys_sigreturn_args /* {
1.1       fvdl      200:                syscallarg(struct linux_sigcontext *) scp;
1.19      thorpej   201:        } */ *uap = v;
1.1       fvdl      202:        struct linux_sigcontext *scp, context;
                    203:        register struct trapframe *tf;
                    204:
1.3       mycroft   205:        tf = p->p_md.md_regs;
1.1       fvdl      206:
                    207:        /*
                    208:         * The trampoline code hands us the context.
                    209:         * It is unsafe to keep track of it ourselves, in the event that a
                    210:         * program jumps out of a signal handler.
                    211:         */
                    212:        scp = SCARG(uap, scp);
                    213:        if (copyin((caddr_t)scp, &context, sizeof(*scp)) != 0)
                    214:                return (EFAULT);
                    215:
                    216:        /*
                    217:         * Check for security violations.
                    218:         */
1.7       mycroft   219:        if (((context.sc_eflags ^ tf->tf_eflags) & PSL_USERSTATIC) != 0 ||
                    220:            ISPL(context.sc_cs) != SEL_UPL)
1.1       fvdl      221:                return (EINVAL);
                    222:
1.16      mycroft   223:        p->p_sigacts->ps_sigstk.ss_flags &= ~SS_ONSTACK;
1.7       mycroft   224:        p->p_sigmask = context.sc_mask & ~sigcantmask;
1.1       fvdl      225:
                    226:        /*
                    227:         * Restore signal context.
                    228:         */
1.4       mycroft   229: #ifdef VM86
1.7       mycroft   230:        if (context.sc_eflags & PSL_VM) {
                    231:                tf->tf_vm86_gs = context.sc_gs;
                    232:                tf->tf_vm86_fs = context.sc_fs;
                    233:                tf->tf_vm86_es = context.sc_es;
                    234:                tf->tf_vm86_ds = context.sc_ds;
1.4       mycroft   235:        } else
                    236: #endif
                    237:        {
                    238:                /* %fs and %gs were restored by the trampoline. */
1.7       mycroft   239:                tf->tf_es = context.sc_es;
                    240:                tf->tf_ds = context.sc_ds;
1.4       mycroft   241:        }
1.7       mycroft   242:        tf->tf_edi    = context.sc_edi;
                    243:        tf->tf_esi    = context.sc_esi;
                    244:        tf->tf_ebp    = context.sc_ebp;
                    245:        tf->tf_ebx    = context.sc_ebx;
                    246:        tf->tf_edx    = context.sc_edx;
                    247:        tf->tf_ecx    = context.sc_ecx;
                    248:        tf->tf_eax    = context.sc_eax;
                    249:        tf->tf_eip    = context.sc_eip;
                    250:        tf->tf_cs     = context.sc_cs;
                    251:        tf->tf_eflags = context.sc_eflags;
                    252:        tf->tf_esp    = context.sc_esp_at_signal;
                    253:        tf->tf_ss     = context.sc_ss;
1.1       fvdl      254:
                    255:        return (EJUSTRETURN);
1.6       mycroft   256: }
                    257:
1.7       mycroft   258: #ifdef USER_LDT
                    259:
                    260: int
                    261: linux_read_ldt(p, uap, retval)
                    262:        struct proc *p;
1.20    ! mycroft   263:        struct linux_sys_modify_ldt_args /* {
1.7       mycroft   264:                syscallarg(int) func;
                    265:                syscallarg(void *) ptr;
                    266:                syscallarg(size_t) bytecount;
                    267:        } */ *uap;
                    268:        register_t *retval;
                    269: {
                    270:        struct i386_get_ldt_args gl;
                    271:        int error;
                    272:        caddr_t sg;
                    273:        char *parms;
                    274:
1.10      christos  275:        sg = stackgap_init(p->p_emul);
1.7       mycroft   276:
                    277:        gl.start = 0;
                    278:        gl.desc = SCARG(uap, ptr);
                    279:        gl.num = SCARG(uap, bytecount) / sizeof(union descriptor);
                    280:
                    281:        parms = stackgap_alloc(&sg, sizeof(gl));
                    282:
                    283:        if (error = copyout(&gl, parms, sizeof(gl)))
                    284:                return (error);
                    285:
                    286:        if (error = i386_get_ldt(p, parms, retval))
                    287:                return (error);
                    288:
                    289:        *retval *= sizeof(union descriptor);
                    290:        return (0);
                    291: }
                    292:
                    293: struct linux_ldt_info {
                    294:        u_int entry_number;
                    295:        u_long base_addr;
                    296:        u_int limit;
                    297:        u_int seg_32bit:1;
                    298:        u_int contents:2;
                    299:        u_int read_exec_only:1;
                    300:        u_int limit_in_pages:1;
                    301:        u_int seg_not_present:1;
                    302: };
                    303:
                    304: int
                    305: linux_write_ldt(p, uap, retval)
                    306:        struct proc *p;
1.20    ! mycroft   307:        struct linux_sys_modify_ldt_args /* {
1.7       mycroft   308:                syscallarg(int) func;
                    309:                syscallarg(void *) ptr;
                    310:                syscallarg(size_t) bytecount;
                    311:        } */ *uap;
                    312:        register_t *retval;
                    313: {
                    314:        struct linux_ldt_info ldt_info;
                    315:        struct segment_descriptor sd;
                    316:        struct i386_set_ldt_args sl;
                    317:        int error;
                    318:        caddr_t sg;
                    319:        char *parms;
                    320:
                    321:        if (SCARG(uap, bytecount) != sizeof(ldt_info))
                    322:                return (EINVAL);
                    323:        if (error = copyin(SCARG(uap, ptr), &ldt_info, sizeof(ldt_info)))
                    324:                return error;
                    325:        if (ldt_info.contents == 3)
                    326:                return (EINVAL);
                    327:
1.10      christos  328:        sg = stackgap_init(p->p_emul);
1.7       mycroft   329:
                    330:        sd.sd_lobase = ldt_info.base_addr & 0xffffff;
                    331:        sd.sd_hibase = (ldt_info.base_addr >> 24) & 0xff;
                    332:        sd.sd_lolimit = ldt_info.limit & 0xffff;
                    333:        sd.sd_hilimit = (ldt_info.limit >> 16) & 0xf;
                    334:        sd.sd_type =
                    335:            16 | (ldt_info.contents << 2) | (!ldt_info.read_exec_only << 1);
                    336:        sd.sd_dpl = SEL_UPL;
                    337:        sd.sd_p = !ldt_info.seg_not_present;
                    338:        sd.sd_def32 = ldt_info.seg_32bit;
                    339:        sd.sd_gran = ldt_info.limit_in_pages;
                    340:
                    341:        sl.start = ldt_info.entry_number;
                    342:        sl.desc = stackgap_alloc(&sg, sizeof(sd));
                    343:        sl.num = 1;
                    344:
1.8       mycroft   345: #if 0
1.7       mycroft   346:        printf("linux_write_ldt: idx=%d, base=%x, limit=%x\n",
                    347:            ldt_info.entry_number, ldt_info.base_addr, ldt_info.limit);
1.8       mycroft   348: #endif
1.7       mycroft   349:
                    350:        parms = stackgap_alloc(&sg, sizeof(sl));
                    351:
                    352:        if (error = copyout(&sd, sl.desc, sizeof(sd)))
                    353:                return (error);
                    354:        if (error = copyout(&sl, parms, sizeof(sl)))
                    355:                return (error);
                    356:
                    357:        if (error = i386_set_ldt(p, parms, retval))
                    358:                return (error);
                    359:
                    360:        *retval = 0;
                    361:        return (0);
                    362: }
                    363:
                    364: #endif /* USER_LDT */
                    365:
1.6       mycroft   366: int
1.20    ! mycroft   367: linux_sys_modify_ldt(p, v, retval)
1.6       mycroft   368:        struct proc *p;
1.19      thorpej   369:        void *v;
                    370:        register_t *retval;
                    371: {
1.20    ! mycroft   372:        struct linux_sys_modify_ldt_args /* {
1.6       mycroft   373:                syscallarg(int) func;
                    374:                syscallarg(void *) ptr;
                    375:                syscallarg(size_t) bytecount;
1.19      thorpej   376:        } */ *uap = v;
1.6       mycroft   377:
                    378:        switch (SCARG(uap, func)) {
1.7       mycroft   379: #ifdef USER_LDT
1.6       mycroft   380:        case 0:
1.7       mycroft   381:                return (linux_read_ldt(p, uap, retval));
                    382:
1.6       mycroft   383:        case 1:
1.7       mycroft   384:                return (linux_write_ldt(p, uap, retval));
                    385: #endif /* USER_LDT */
                    386:
1.6       mycroft   387:        default:
                    388:                return (ENOSYS);
                    389:        }
1.13      fvdl      390: }
                    391:
                    392: /*
                    393:  * XXX Pathetic hack to make svgalib work. This will fake the major
                    394:  * device number of an opened VT so that svgalib likes it. grmbl.
                    395:  * Should probably do it 'wrong the right way' and use a mapping
                    396:  * array for all major device numbers, and map linux_mknod too.
                    397:  */
                    398: dev_t
                    399: linux_fakedev(dev)
                    400:        dev_t dev;
                    401: {
1.20    ! mycroft   402:
1.13      fvdl      403:        if (major(dev) == NETBSD_CONS_MAJOR)
1.17      fvdl      404:                return makedev(LINUX_CONS_MAJOR, (minor(dev) + 1));
1.13      fvdl      405:        return dev;
                    406: }
                    407:
                    408: /*
                    409:  * We come here in a last attempt to satisfy a Linux ioctl() call
                    410:  */
                    411: int
1.19      thorpej   412: linux_machdepioctl(p, v, retval)
1.13      fvdl      413:        struct proc *p;
1.19      thorpej   414:        void *v;
                    415:        register_t *retval;
                    416: {
1.20    ! mycroft   417:        struct linux_sys_ioctl_args /* {
1.13      fvdl      418:                syscallarg(int) fd;
                    419:                syscallarg(u_long) com;
                    420:                syscallarg(caddr_t) data;
1.19      thorpej   421:        } */ *uap = v;
1.20    ! mycroft   422:        struct sys_ioctl_args bia, tmparg;
1.15      fvdl      423:        u_long com;
                    424: #if NVT > 0
1.13      fvdl      425:        int error, mode;
                    426:        struct vt_mode lvt;
                    427:        caddr_t bvtp, sg;
                    428:        u_int fd;
                    429:        struct file *fp;
                    430:        struct filedesc *fdp;
1.15      fvdl      431: #endif
1.13      fvdl      432:
                    433:        SCARG(&bia, fd) = SCARG(uap, fd);
                    434:        SCARG(&bia, data) = SCARG(uap, data);
                    435:        com = SCARG(uap, com);
                    436:
                    437:        switch (com) {
                    438: #if NVT > 0
                    439:        case LINUX_KDGKBMODE:
                    440:                /*
1.14      fvdl      441:                 * Could be implemented but somehow KDGKBMODE is the
                    442:                 * same as KBDGLEDS.
1.13      fvdl      443:                 */
                    444:                mode = K_XLATE;
                    445:                return copyout(&mode, SCARG(uap, data), sizeof mode);
                    446:        case LINUX_KDSKBMODE:
                    447:                com = KDSKBMODE;
                    448:                if ((unsigned)SCARG(uap, data) == LINUX_K_MEDIUMRAW)
                    449:                        SCARG(&bia, data) = (caddr_t)K_RAW;
                    450:                break;
                    451:        case LINUX_KDMKTONE:
                    452:                com = KDMKTONE;
                    453:                break;
                    454:        case LINUX_KDSETMODE:
                    455:                com = KDSETMODE;
                    456:                break;
                    457:        case LINUX_KDENABIO:
                    458:                com = KDENABIO;
                    459:                break;
                    460:        case LINUX_KDDISABIO:
                    461:                com = KDDISABIO;
                    462:                break;
                    463:        case LINUX_KDGETLED:
                    464:                com = KDGETLED;
                    465:                break;
                    466:        case LINUX_KDSETLED:
                    467:                com = KDSETLED;
                    468:                break;
                    469:        case LINUX_VT_OPENQRY:
                    470:                com = VT_OPENQRY;
                    471:                break;
                    472:        case LINUX_VT_GETMODE:
                    473:                SCARG(&bia, com) = VT_GETMODE;
1.20    ! mycroft   474:                if ((error = sys_ioctl(p, &bia, retval)))
1.13      fvdl      475:                        return error;
                    476:                if ((error = copyin(SCARG(uap, data), (caddr_t)&lvt,
                    477:                    sizeof (struct vt_mode))))
                    478:                        return error;
                    479:                lvt.relsig = bsd_to_linux_sig[lvt.relsig];
                    480:                lvt.acqsig = bsd_to_linux_sig[lvt.acqsig];
                    481:                lvt.frsig = bsd_to_linux_sig[lvt.frsig];
                    482:                return copyout((caddr_t)&lvt, SCARG(uap, data),
                    483:                    sizeof (struct vt_mode));
                    484:        case LINUX_VT_SETMODE:
                    485:                com = VT_SETMODE;
                    486:                if ((error = copyin(SCARG(uap, data), (caddr_t)&lvt,
                    487:                    sizeof (struct vt_mode))))
                    488:                        return error;
                    489:                lvt.relsig = linux_to_bsd_sig[lvt.relsig];
                    490:                lvt.acqsig = linux_to_bsd_sig[lvt.acqsig];
                    491:                lvt.frsig = linux_to_bsd_sig[lvt.frsig];
                    492:                sg = stackgap_init(p->p_emul);
                    493:                bvtp = stackgap_alloc(&sg, sizeof (struct vt_mode));
                    494:                if ((error = copyout(&lvt, bvtp, sizeof (struct vt_mode))))
                    495:                        return error;
                    496:                SCARG(&bia, data) = bvtp;
                    497:                break;
                    498:        case LINUX_VT_RELDISP:
                    499:                com = VT_RELDISP;
                    500:                break;
                    501:        case LINUX_VT_ACTIVATE:
                    502:                com = VT_ACTIVATE;
                    503:                break;
                    504:        case LINUX_VT_WAITACTIVE:
                    505:                com = VT_WAITACTIVE;
                    506:                break;
                    507: #endif
                    508:        default:
                    509:                return EINVAL;
                    510:        }
                    511:        SCARG(&bia, com) = com;
1.20    ! mycroft   512:        return sys_ioctl(p, &bia, retval);
1.13      fvdl      513: }
                    514:
                    515: /*
                    516:  * Set I/O permissions for a process. Just set the maximum level
                    517:  * right away (ignoring the argument), otherwise we would have
                    518:  * to rely on I/O permission maps, which are not implemented.
                    519:  */
                    520: int
1.20    ! mycroft   521: linux_sys_iopl(p, v, retval)
1.13      fvdl      522:        struct proc *p;
1.19      thorpej   523:        void *v;
                    524:        register_t *retval;
                    525: {
1.20    ! mycroft   526:        struct linux_sys_iopl_args /* {
1.13      fvdl      527:                syscallarg(int) level;
1.19      thorpej   528:        } */ *uap = v;
1.13      fvdl      529:        struct trapframe *fp = p->p_md.md_regs;
                    530:
                    531:        if (suser(p->p_ucred, &p->p_acflag) != 0)
                    532:                return EPERM;
                    533:        fp->tf_eflags |= PSL_IOPL;
                    534:        *retval = 0;
                    535:        return 0;
                    536: }
                    537:
                    538: /*
                    539:  * See above. If a root process tries to set access to an I/O port,
                    540:  * just let it have the whole range.
                    541:  */
                    542: int
1.20    ! mycroft   543: linux_sys_ioperm(p, v, retval)
1.13      fvdl      544:        struct proc *p;
1.19      thorpej   545:        void *v;
                    546:        register_t *retval;
                    547: {
1.20    ! mycroft   548:        struct linux_sys_ioperm_args /* {
1.13      fvdl      549:                syscallarg(unsigned int) lo;
                    550:                syscallarg(unsigned int) hi;
                    551:                syscallarg(int) val;
1.19      thorpej   552:        } */ *uap = v;
1.13      fvdl      553:        struct trapframe *fp = p->p_md.md_regs;
                    554:
                    555:        if (suser(p->p_ucred, &p->p_acflag) != 0)
                    556:                return EPERM;
                    557:        if (SCARG(uap, val))
                    558:                fp->tf_eflags |= PSL_IOPL;
                    559:        *retval = 0;
                    560:        return 0;
1.1       fvdl      561: }

CVSweb <webmaster@jp.NetBSD.org>