From 2323686abc308fce1a297292c20dcdea0171ed4e Mon Sep 17 00:00:00 2001 From: Luoqi Chen Date: Wed, 22 Sep 1999 22:01:51 +0000 Subject: [PATCH] Implement linux_ioperm() syscall. Fix linux_iopl() to use the level argument. SVGAlib should now work. Reviewed by: marcel --- sys/alpha/linux/linux_dummy.c | 1 - sys/alpha/linux/syscalls.master | 4 ++-- sys/compat/linux/linux_misc.c | 31 +++++++++++++++++++++++++------ sys/i386/linux/linux_dummy.c | 1 - sys/i386/linux/linux_misc.c | 31 +++++++++++++++++++++++++------ sys/i386/linux/syscalls.master | 4 ++-- 6 files changed, 54 insertions(+), 18 deletions(-) diff --git a/sys/alpha/linux/linux_dummy.c b/sys/alpha/linux/linux_dummy.c index 67e3a1afbb9..018446d1619 100644 --- a/sys/alpha/linux/linux_dummy.c +++ b/sys/alpha/linux/linux_dummy.c @@ -69,7 +69,6 @@ DUMMY(mpx); DUMMY(ulimit); DUMMY(olduname); DUMMY(ustat); -DUMMY(ioperm); DUMMY(ksyslog); DUMMY(uname); DUMMY(vhangup); diff --git a/sys/alpha/linux/syscalls.master b/sys/alpha/linux/syscalls.master index 5e6ce0719a2..ab7c20949f6 100644 --- a/sys/alpha/linux/syscalls.master +++ b/sys/alpha/linux/syscalls.master @@ -150,8 +150,8 @@ struct linux_statfs_buf *buf); } 100 STD LINUX { int linux_fstatfs(int fd, \ struct linux_statfs_buf *buf); } -101 STD LINUX { int linux_ioperm(unsigned int lo, \ - unsigned int hi, int val); } +101 STD LINUX { int linux_ioperm(unsigned int start, \ + unsigned int length, int enable); } 102 STD LINUX { int linux_socketcall(int what, void *args); } 103 STD LINUX { int linux_ksyslog(int what); } 104 STD LINUX { int linux_setitimer(u_int which, \ diff --git a/sys/compat/linux/linux_misc.c b/sys/compat/linux/linux_misc.c index 3bca8cfc3ad..919a5e74850 100644 --- a/sys/compat/linux/linux_misc.c +++ b/sys/compat/linux/linux_misc.c @@ -1121,18 +1121,37 @@ linux_getitimer(struct proc *p, struct linux_getitimer_args *args) return getitimer(p, &bsa); } +int +linux_ioperm(struct proc *p, struct linux_ioperm_args *args) +{ + struct sysarch_args sa; + struct i386_ioperm_args *iia; + caddr_t sg; + + sg = stackgap_init(); + iia = stackgap_alloc(&sg, sizeof(struct i386_ioperm_args)); + iia->start = args->start; + iia->length = args->length; + iia->enable = args->enable; + sa.op = I386_SET_IOPERM; + sa.parms = (char *)iia; + return sysarch(p, &sa); +} + int linux_iopl(struct proc *p, struct linux_iopl_args *args) { int error; - error = suser(p); - if (error != 0) - return error; + if (args->level < 0 || args->level > 3) + return (EINVAL); + if ((error = suser(p)) != 0) + return (error); if (securelevel > 0) - return EPERM; - p->p_md.md_regs->tf_eflags |= PSL_IOPL; - return 0; + return (EPERM); + p->p_md.md_regs->tf_eflags = (p->p_md.md_regs->tf_eflags & ~PSL_IOPL) | + (args->level * (PSL_IOPL / 3)); + return (0); } int diff --git a/sys/i386/linux/linux_dummy.c b/sys/i386/linux/linux_dummy.c index 67e3a1afbb9..018446d1619 100644 --- a/sys/i386/linux/linux_dummy.c +++ b/sys/i386/linux/linux_dummy.c @@ -69,7 +69,6 @@ DUMMY(mpx); DUMMY(ulimit); DUMMY(olduname); DUMMY(ustat); -DUMMY(ioperm); DUMMY(ksyslog); DUMMY(uname); DUMMY(vhangup); diff --git a/sys/i386/linux/linux_misc.c b/sys/i386/linux/linux_misc.c index 3bca8cfc3ad..919a5e74850 100644 --- a/sys/i386/linux/linux_misc.c +++ b/sys/i386/linux/linux_misc.c @@ -1121,18 +1121,37 @@ linux_getitimer(struct proc *p, struct linux_getitimer_args *args) return getitimer(p, &bsa); } +int +linux_ioperm(struct proc *p, struct linux_ioperm_args *args) +{ + struct sysarch_args sa; + struct i386_ioperm_args *iia; + caddr_t sg; + + sg = stackgap_init(); + iia = stackgap_alloc(&sg, sizeof(struct i386_ioperm_args)); + iia->start = args->start; + iia->length = args->length; + iia->enable = args->enable; + sa.op = I386_SET_IOPERM; + sa.parms = (char *)iia; + return sysarch(p, &sa); +} + int linux_iopl(struct proc *p, struct linux_iopl_args *args) { int error; - error = suser(p); - if (error != 0) - return error; + if (args->level < 0 || args->level > 3) + return (EINVAL); + if ((error = suser(p)) != 0) + return (error); if (securelevel > 0) - return EPERM; - p->p_md.md_regs->tf_eflags |= PSL_IOPL; - return 0; + return (EPERM); + p->p_md.md_regs->tf_eflags = (p->p_md.md_regs->tf_eflags & ~PSL_IOPL) | + (args->level * (PSL_IOPL / 3)); + return (0); } int diff --git a/sys/i386/linux/syscalls.master b/sys/i386/linux/syscalls.master index 5e6ce0719a2..ab7c20949f6 100644 --- a/sys/i386/linux/syscalls.master +++ b/sys/i386/linux/syscalls.master @@ -150,8 +150,8 @@ struct linux_statfs_buf *buf); } 100 STD LINUX { int linux_fstatfs(int fd, \ struct linux_statfs_buf *buf); } -101 STD LINUX { int linux_ioperm(unsigned int lo, \ - unsigned int hi, int val); } +101 STD LINUX { int linux_ioperm(unsigned int start, \ + unsigned int length, int enable); } 102 STD LINUX { int linux_socketcall(int what, void *args); } 103 STD LINUX { int linux_ksyslog(int what); } 104 STD LINUX { int linux_setitimer(u_int which, \