Subject: Re: kern/33671: getpriority(2) under COMPAT_LINUX return wrong values
To: None <kern-bug-people@netbsd.org, gnats-admin@netbsd.org,>
From: David Laight <david@l8s.co.uk>
List: netbsd-bugs
Date: 06/10/2006 09:00:05
The following reply was made to PR kern/33671; it has been noted by GNATS.
From: David Laight <david@l8s.co.uk>
To: gnats-bugs@netbsd.org
Cc:
Subject: Re: kern/33671: getpriority(2) under COMPAT_LINUX return wrong values
Date: Sat, 10 Jun 2006 10:05:37 +0100
> 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.
> 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 */
Since the argument layout is the same, and that is usually assumed for
syscall emulation, isn't it enough to do:
int
linux_sys_getpriority(struct lwp *l, void *v, register_t retval)
{
int error = sys_getpriority(l, v, retval);
*retval = 20 - *retval;
return error;
}
David
--
David Laight: david@l8s.co.uk