Subject: Re: kern/33671: getpriority(2) under COMPAT_LINUX return wrong values
To: None <kern-bug-people@NetBSD.org, gnats-admin@NetBSD.org,>
From: Nicolas Joly <njoly@pasteur.fr>
List: netbsd-bugs
Date: 06/10/2006 10:41:47
--3V7upXqbjpZ4EhLz
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

On Thu, Jun 08, 2006 at 06:25:00PM +0000, Nicolas Joly wrote:
> >Number:         33671
> >Category:       kern
> >Synopsis:       getpriority(2) under COMPAT_LINUX return wrong values
[...]
> >Description:
> While running some linux binaries on my -current NetBSD/amd64, i
> noticed that getpriority(2) return wrong values. According to the
> linux man page (notes section), this syscall returns values in 40..1
> interval instead of the expected -20 to 20 range.

I just got some time to take a closer look ... And made the attached
patch. I successfully tested it on -current amd64 and i386 boxes, but
i suspect all other platforms with COMPAT_LINUX need to be fixed too.

-- 
Nicolas Joly

Biological Software and Databanks.
Institut Pasteur, Paris.

--3V7upXqbjpZ4EhLz
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="netbsd-linuxgetpriority.diff"

Index: sys/compat/linux/arch/amd64/syscalls.master
===================================================================
RCS file: /cvsroot/src/sys/compat/linux/arch/amd64/syscalls.master,v
retrieving revision 1.10
diff -u -r1.10 syscalls.master
--- sys/compat/linux/arch/amd64/syscalls.master	9 Feb 2006 19:18:56 -0000	1.10
+++ sys/compat/linux/arch/amd64/syscalls.master	9 Jun 2006 14:31:39 -0000
@@ -304,7 +304,7 @@
 138	STD		{ int linux_sys_fstatfs64(int fd, \
 			    size_t sz, struct linux_statfs64 *sp); }
 139	UNIMPL		sysfs
-140	NOARGS		{ int sys_getpriority(int which, int who); }
+140	STD		{ int linux_sys_getpriority(int which, int who); }
 141	NOARGS		{ int sys_setpriority(int which, int who, int prio); }
 142	STD		{ int linux_sys_sched_setparam(pid_t pid, \
 			    const struct linux_sched_param *sp); }
Index: sys/compat/linux/arch/i386/syscalls.master
===================================================================
RCS file: /cvsroot/src/sys/compat/linux/arch/i386/syscalls.master,v
retrieving revision 1.77
diff -u -r1.77 syscalls.master
--- sys/compat/linux/arch/i386/syscalls.master	11 Dec 2005 12:20:14 -0000	1.77
+++ sys/compat/linux/arch/i386/syscalls.master	9 Jun 2006 14:31:39 -0000
@@ -184,7 +184,7 @@
 93	NOARGS		{ int compat_43_sys_ftruncate(int fd, long length); }
 94	NOARGS		{ int sys_fchmod(int fd, int mode); }
 95	STD		{ int linux_sys_fchown16(int fd, int uid, int gid); }
-96	NOARGS		{ int sys_getpriority(int which, int who); }
+96	STD		{ int linux_sys_getpriority(int which, int who); }
 97	NOARGS		{ int sys_setpriority(int which, int who, int prio); }
 98	NOARGS		{ int sys_profil(caddr_t samples, u_int size, \
 			    u_int offset, u_int scale); }
Index: sys/compat/linux/common/linux_misc.c
===================================================================
RCS file: /cvsroot/src/sys/compat/linux/common/linux_misc.c,v
retrieving revision 1.155
diff -u -r1.155 linux_misc.c
--- sys/compat/linux/common/linux_misc.c	7 Jun 2006 22:33:33 -0000	1.155
+++ sys/compat/linux/common/linux_misc.c	9 Jun 2006 14:31:40 -0000
@@ -1745,4 +1745,28 @@
 	return (ENOSYS);
 }
 
+int
+linux_sys_getpriority(l, v, retval)
+        struct lwp *l;
+        void *v;
+        register_t *retval;
+{
+        struct linux_sys_getpriority_args /* {
+                syscallarg(int) which;
+                syscallarg(int) who;
+        } */ *uap = v;
+        struct sys_getpriority_args bsa;
+        int error;
+
+        SCARG(&bsa, which) = SCARG(uap, which);
+        SCARG(&bsa, who) = SCARG(uap, who);
+
+        if ((error = sys_getpriority(l, &bsa, retval)))
+                return error;
+
+        *retval = 20 - *retval;
+
+        return 0;
+}
+
 #endif /* !COMPAT_LINUX32 */

--3V7upXqbjpZ4EhLz--