Module Name: src Committed By: thorpej Date: Sun Sep 19 23:51:37 UTC 2021
Modified Files: src/sys/compat/linux/arch/alpha: syscalls.master src/sys/compat/linux/arch/amd64: syscalls.master src/sys/compat/linux/arch/arm: syscalls.master src/sys/compat/linux/arch/i386: syscalls.master src/sys/compat/linux/arch/m68k: syscalls.master src/sys/compat/linux/arch/mips: syscalls.master src/sys/compat/linux/arch/powerpc: syscalls.master src/sys/compat/linux/common: linux_ioctl.c linux_ioctl.h linux_sched.h linux_time.c src/sys/compat/linux32/arch/amd64: syscalls.master src/sys/compat/linux32/common: linux32_ioctl.c linux32_time.c Log Message: Add the timerfd syscalls to COMPAT_LINUX and COMPAT_LINUX32. To generate a diff of this commit: cvs rdiff -u -r1.98 -r1.99 src/sys/compat/linux/arch/alpha/syscalls.master cvs rdiff -u -r1.63 -r1.64 src/sys/compat/linux/arch/amd64/syscalls.master cvs rdiff -u -r1.70 -r1.71 src/sys/compat/linux/arch/arm/syscalls.master cvs rdiff -u -r1.125 -r1.126 src/sys/compat/linux/arch/i386/syscalls.master cvs rdiff -u -r1.96 -r1.97 src/sys/compat/linux/arch/m68k/syscalls.master cvs rdiff -u -r1.69 -r1.70 src/sys/compat/linux/arch/mips/syscalls.master cvs rdiff -u -r1.75 -r1.76 src/sys/compat/linux/arch/powerpc/syscalls.master cvs rdiff -u -r1.58 -r1.59 src/sys/compat/linux/common/linux_ioctl.c cvs rdiff -u -r1.27 -r1.28 src/sys/compat/linux/common/linux_ioctl.h cvs rdiff -u -r1.9 -r1.10 src/sys/compat/linux/common/linux_sched.h cvs rdiff -u -r1.41 -r1.42 src/sys/compat/linux/common/linux_time.c cvs rdiff -u -r1.72 -r1.73 src/sys/compat/linux32/arch/amd64/syscalls.master cvs rdiff -u -r1.14 -r1.15 src/sys/compat/linux32/common/linux32_ioctl.c cvs rdiff -u -r1.39 -r1.40 src/sys/compat/linux32/common/linux32_time.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/compat/linux/arch/alpha/syscalls.master diff -u src/sys/compat/linux/arch/alpha/syscalls.master:1.98 src/sys/compat/linux/arch/alpha/syscalls.master:1.99 --- src/sys/compat/linux/arch/alpha/syscalls.master:1.98 Sun Sep 19 23:01:49 2021 +++ src/sys/compat/linux/arch/alpha/syscalls.master Sun Sep 19 23:51:36 2021 @@ -1,4 +1,4 @@ - $NetBSD: syscalls.master,v 1.98 2021/09/19 23:01:49 thorpej Exp $ + $NetBSD: syscalls.master,v 1.99 2021/09/19 23:51:36 thorpej Exp $ ; ; @(#)syscalls.master 8.1 (Berkeley) 7/19/93 @@ -770,9 +770,13 @@ unsigned int flags, struct timespec *timeout); } 480 STD { int|linux_sys||fallocate(int fd, int mode, \ off_t offset, off_t len); } -481 UNIMPL timerfd_create -482 UNIMPL timerfd_settime -483 UNIMPL timerfd_gettime +481 STD { int|linux_sys||timerfd_create(clockid_t clock_id, \ + int flags); } +482 STD { int|linux_sys||timerfd_settime(int fd, int flags, \ + const struct linux_itimerspec *tim, \ + struct linux_itimerspec *otim); } +483 STD { int|linux_sys||timerfd_gettime(int fd, \ + struct linux_itimerspec *tim); } 484 UNIMPL signalfd4 485 UNIMPL eventfd2 486 UNIMPL epoll_create1 Index: src/sys/compat/linux/arch/amd64/syscalls.master diff -u src/sys/compat/linux/arch/amd64/syscalls.master:1.63 src/sys/compat/linux/arch/amd64/syscalls.master:1.64 --- src/sys/compat/linux/arch/amd64/syscalls.master:1.63 Sun Sep 19 23:01:49 2021 +++ src/sys/compat/linux/arch/amd64/syscalls.master Sun Sep 19 23:51:36 2021 @@ -1,4 +1,4 @@ - $NetBSD: syscalls.master,v 1.63 2021/09/19 23:01:49 thorpej Exp $ + $NetBSD: syscalls.master,v 1.64 2021/09/19 23:51:36 thorpej Exp $ ; @(#)syscalls.master 8.1 (Berkeley) 7/19/93 @@ -519,12 +519,16 @@ struct linux_timespec *times, int flag); } 281 UNIMPL epoll_pwait 282 UNIMPL signalfd -283 UNIMPL timerfd_create +283 STD { int|linux_sys||timerfd_create(clockid_t clock_id, \ + int flags); } 284 UNIMPL eventfd 285 STD { int|linux_sys||fallocate(int fd, int mode, \ off_t offset, off_t len); } -286 UNIMPL timerfd_settime -287 UNIMPL timerfd_gettime +286 STD { int|linux_sys||timerfd_settime(int fd, int flags, \ + const struct linux_itimerspec *tim, \ + struct linux_itimerspec *otim); } +287 STD { int|linux_sys||timerfd_gettime(int fd, \ + struct linux_itimerspec *tim); } 288 STD { int|linux_sys||accept4(int s, \ struct osockaddr *name, \ int *anamelen, int flags); } Index: src/sys/compat/linux/arch/arm/syscalls.master diff -u src/sys/compat/linux/arch/arm/syscalls.master:1.70 src/sys/compat/linux/arch/arm/syscalls.master:1.71 --- src/sys/compat/linux/arch/arm/syscalls.master:1.70 Sun Sep 19 23:01:49 2021 +++ src/sys/compat/linux/arch/arm/syscalls.master Sun Sep 19 23:51:36 2021 @@ -1,4 +1,4 @@ - $NetBSD: syscalls.master,v 1.70 2021/09/19 23:01:49 thorpej Exp $ + $NetBSD: syscalls.master,v 1.71 2021/09/19 23:51:36 thorpej Exp $ ; Derived from sys/compat/linux/arch/*/syscalls.master ; and from Linux 2.4.12 arch/arm/kernel/calls.S @@ -562,12 +562,16 @@ 348 STD { int|linux_sys||utimensat(int fd, const char *path, \ struct linux_timespec *times, int flag); } 349 UNIMPL signalfd -350 UNIMPL timerfd_create +350 STD { int|linux_sys||timerfd_create(clockid_t clock_id, \ + int flags); } 351 UNIMPL eventfd 352 STD { int|linux_sys||fallocate(int fd, int mode, \ off_t offset, off_t len); } -353 UNIMPL timerfd_settime -354 UNIMPL timerfd_gettime +353 STD { int|linux_sys||timerfd_settime(int fd, int flags, \ + const struct linux_itimerspec *tim, \ + struct linux_itimerspec *otim); } +354 STD { int|linux_sys||timerfd_gettime(int fd, \ + struct linux_itimerspec *tim); } 355 UNIMPL signalfd4 356 UNIMPL eventfd2 357 UNIMPL epoll_create1 Index: src/sys/compat/linux/arch/i386/syscalls.master diff -u src/sys/compat/linux/arch/i386/syscalls.master:1.125 src/sys/compat/linux/arch/i386/syscalls.master:1.126 --- src/sys/compat/linux/arch/i386/syscalls.master:1.125 Sun Sep 19 23:01:50 2021 +++ src/sys/compat/linux/arch/i386/syscalls.master Sun Sep 19 23:51:36 2021 @@ -1,4 +1,4 @@ - $NetBSD: syscalls.master,v 1.125 2021/09/19 23:01:50 thorpej Exp $ + $NetBSD: syscalls.master,v 1.126 2021/09/19 23:51:36 thorpej Exp $ ; @(#)syscalls.master 8.1 (Berkeley) 7/19/93 @@ -529,12 +529,16 @@ 320 STD { int|linux_sys||utimensat(int fd, const char *path, \ struct linux_timespec *times, int flag); } 321 UNIMPL signalfd -322 UNIMPL timerfd_create +322 STD { int|linux_sys||timerfd_create(clockid_t clock_id, \ + int flags); } 323 UNIMPL eventfd 324 STD { int|linux_sys||fallocate(int fd, int mode, \ off_t offset, off_t len); } -325 UNIMPL timerfd_settime -326 UNIMPL timerfd_gettime +325 STD { int|linux_sys||timerfd_settime(int fd, int flags, \ + const struct linux_itimerspec *tim, \ + struct linux_itimerspec *otim); } +326 STD { int|linux_sys||timerfd_gettime(int fd, \ + struct linux_itimerspec *tim); } 327 UNIMPL signalfd4 328 UNIMPL eventfd2 329 UNIMPL epoll_create1 Index: src/sys/compat/linux/arch/m68k/syscalls.master diff -u src/sys/compat/linux/arch/m68k/syscalls.master:1.96 src/sys/compat/linux/arch/m68k/syscalls.master:1.97 --- src/sys/compat/linux/arch/m68k/syscalls.master:1.96 Sun Sep 19 23:01:50 2021 +++ src/sys/compat/linux/arch/m68k/syscalls.master Sun Sep 19 23:51:36 2021 @@ -1,4 +1,4 @@ - $NetBSD: syscalls.master,v 1.96 2021/09/19 23:01:50 thorpej Exp $ + $NetBSD: syscalls.master,v 1.97 2021/09/19 23:51:36 thorpej Exp $ ; @(#)syscalls.master 8.1 (Berkeley) 7/19/93 @@ -547,12 +547,16 @@ 316 STD { int|linux_sys||utimensat(int fd, const char *path, \ struct linux_timespec *times, int flag); } 317 UNIMPL signalfd -318 UNIMPL timerfd_create +318 STD { int|linux_sys||timerfd_create(clockid_t clock_id, \ + int flags); } 319 UNIMPL eventfd 320 STD { int|linux_sys||fallocate(int fd, int mode, \ off_t offset, off_t len); } -321 UNIMPL timerfd_settime -322 UNIMPL timerfd_gettime +321 STD { int|linux_sys||timerfd_settime(int fd, int flags, \ + const struct linux_itimerspec *tim, \ + struct linux_itimerspec *otim); } +322 STD { int|linux_sys||timerfd_gettime(int fd, \ + struct linux_itimerspec *tim); } 323 UNIMPL signalfd4 324 UNIMPL eventfd2 325 UNIMPL epoll_create1 Index: src/sys/compat/linux/arch/mips/syscalls.master diff -u src/sys/compat/linux/arch/mips/syscalls.master:1.69 src/sys/compat/linux/arch/mips/syscalls.master:1.70 --- src/sys/compat/linux/arch/mips/syscalls.master:1.69 Sun Sep 19 23:01:50 2021 +++ src/sys/compat/linux/arch/mips/syscalls.master Sun Sep 19 23:51:37 2021 @@ -1,4 +1,4 @@ - $NetBSD: syscalls.master,v 1.69 2021/09/19 23:01:50 thorpej Exp $ + $NetBSD: syscalls.master,v 1.70 2021/09/19 23:51:37 thorpej Exp $ ; @(#)syscalls.master 8.1 (Berkeley) 7/19/93 @@ -539,9 +539,13 @@ 319 UNIMPL eventfd 320 STD { int|linux_sys||fallocate(int fd, int mode, \ off_t offset, off_t len); } -321 UNIMPL timerfd_create -322 UNIMPL timerfd_gettime -323 UNIMPL timerfd_settime +321 STD { int|linux_sys||timerfd_create(clockid_t clock_id, \ + int flags); } +322 STD { int|linux_sys||timerfd_gettime(int fd, \ + struct linux_itimerspec *tim); } +323 STD { int|linux_sys||timerfd_settime(int fd, int flags, \ + const struct linux_itimerspec *tim, \ + struct linux_itimerspec *otim); } 324 UNIMPL signalfd4 325 UNIMPL eventfd2 326 UNIMPL epoll_create1 Index: src/sys/compat/linux/arch/powerpc/syscalls.master diff -u src/sys/compat/linux/arch/powerpc/syscalls.master:1.75 src/sys/compat/linux/arch/powerpc/syscalls.master:1.76 --- src/sys/compat/linux/arch/powerpc/syscalls.master:1.75 Sun Sep 19 23:01:50 2021 +++ src/sys/compat/linux/arch/powerpc/syscalls.master Sun Sep 19 23:51:37 2021 @@ -1,4 +1,4 @@ - $NetBSD: syscalls.master,v 1.75 2021/09/19 23:01:50 thorpej Exp $ + $NetBSD: syscalls.master,v 1.76 2021/09/19 23:51:37 thorpej Exp $ ; @(#)syscalls.master 8.1 (Berkeley) 7/19/93 @@ -533,14 +533,18 @@ 304 STD { int|linux_sys||utimensat(int fd, const char *path, \ struct linux_timespec *times, int flag); } 305 UNIMPL signalfd -306 UNIMPL timerfd_create +306 STD { int|linux_sys||timerfd_create(clockid_t clock_id, \ + int flags); } 307 UNIMPL eventfd 308 UNIMPL sync_file_range2 309 STD { int|linux_sys||fallocate(int fd, int mode, \ off_t offset, off_t len); } 310 UNIMPL subpage_prot -311 UNIMPL timerfd_settime -312 UNIMPL timerfd_gettime +311 STD { int|linux_sys||timerfd_settime(int fd, int flags, \ + const struct linux_itimerspec *tim, \ + struct linux_itimerspec *otim); } +312 STD { int|linux_sys||timerfd_gettime(int fd, \ + struct linux_itimerspec *tim); } 313 UNIMPL signalfd4 314 UNIMPL eventfd2 315 UNIMPL epoll_create1 Index: src/sys/compat/linux/common/linux_ioctl.c diff -u src/sys/compat/linux/common/linux_ioctl.c:1.58 src/sys/compat/linux/common/linux_ioctl.c:1.59 --- src/sys/compat/linux/common/linux_ioctl.c:1.58 Sun Mar 23 06:03:38 2014 +++ src/sys/compat/linux/common/linux_ioctl.c Sun Sep 19 23:51:37 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: linux_ioctl.c,v 1.58 2014/03/23 06:03:38 dholland Exp $ */ +/* $NetBSD: linux_ioctl.c,v 1.59 2021/09/19 23:51:37 thorpej Exp $ */ /*- * Copyright (c) 1995, 1998, 2008 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: linux_ioctl.c,v 1.58 2014/03/23 06:03:38 dholland Exp $"); +__KERNEL_RCSID(0, "$NetBSD: linux_ioctl.c,v 1.59 2021/09/19 23:51:37 thorpej Exp $"); #if defined(_KERNEL_OPT) #include "sequencer.h" @@ -144,46 +144,49 @@ linux_sys_ioctl(struct lwp *l, const str error = linux_ioctl_mtio(l, uap, retval); break; case 'T': - { -#if NSEQUENCER > 0 -/* XXX XAX 2x check this. */ + { /* - * Both termios and the MIDI sequencer use 'T' to identify - * the ioctl, so we have to differentiate them in another - * way. We do it by indexing in the cdevsw with the major - * device number and check if that is the sequencer entry. + * Termios, the MIDI sequencer, and timerfd use 'T' to + * identify the ioctl, so we have to differentiate them + * in another way. + * + * XXX XAX 2x check this. */ - bool is_sequencer = false; struct file *fp; - struct vnode *vp; - struct vattr va; - extern const struct cdevsw sequencer_cdevsw; if ((fp = fd_getfile(SCARG(uap, fd))) == NULL) return EBADF; + + if (fp->f_type == DTYPE_TIMERFD) { + error = linux_ioctl_timerfd(l, uap, retval); + fd_putfile(SCARG(uap, fd)); + break; + } +#if NSEQUENCER > 0 + struct vnode *vp; + if (fp->f_type == DTYPE_VNODE && (vp = (struct vnode *)fp->f_data) != NULL && vp->v_type == VCHR) { + struct vattr va; + extern const struct cdevsw sequencer_cdevsw; + vn_lock(vp, LK_SHARED | LK_RETRY); error = VOP_GETATTR(vp, &va, l->l_cred); VOP_UNLOCK(vp); if (error == 0 && - cdevsw_lookup(va.va_rdev) == &sequencer_cdevsw) - is_sequencer = true; - } - if (is_sequencer) { - error = oss_ioctl_sequencer(l, (const void *)LINUX_TO_OSS(uap), - retval); - } - else { - error = linux_ioctl_termios(l, uap, retval); + cdevsw_lookup(va.va_rdev) == &sequencer_cdevsw) { + error = oss_ioctl_sequencer(l, + (const void *)LINUX_TO_OSS(uap), retval); + fd_putfile(SCARG(uap, fd)); + break; + } } - fd_putfile(SCARG(uap, fd)); -#else +#endif /* NSEQUENCER > 0 */ error = linux_ioctl_termios(l, uap, retval); -#endif - } + fd_putfile(SCARG(uap, fd)); break; + } case '"': error = linux_ioctl_sg(l, uap, retval); break; Index: src/sys/compat/linux/common/linux_ioctl.h diff -u src/sys/compat/linux/common/linux_ioctl.h:1.27 src/sys/compat/linux/common/linux_ioctl.h:1.28 --- src/sys/compat/linux/common/linux_ioctl.h:1.27 Sat Jun 8 12:50:32 2013 +++ src/sys/compat/linux/common/linux_ioctl.h Sun Sep 19 23:51:37 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: linux_ioctl.h,v 1.27 2013/06/08 12:50:32 stacktic Exp $ */ +/* $NetBSD: linux_ioctl.h,v 1.28 2021/09/19 23:51:37 thorpej Exp $ */ /*- * Copyright (c) 1995, 1998 The NetBSD Foundation, Inc. @@ -41,6 +41,8 @@ int linux_ioctl_cdrom(struct lwp *, cons register_t *); int linux_ioctl_termios(struct lwp *, const struct linux_sys_ioctl_args *, register_t *); +int linux_ioctl_timerfd(struct lwp *, const struct linux_sys_ioctl_args *, + register_t *); int linux_ioctl_socket(struct lwp *, const struct linux_sys_ioctl_args *, register_t *); int linux_ioctl_hdio(struct lwp *, const struct linux_sys_ioctl_args *, Index: src/sys/compat/linux/common/linux_sched.h diff -u src/sys/compat/linux/common/linux_sched.h:1.9 src/sys/compat/linux/common/linux_sched.h:1.10 --- src/sys/compat/linux/common/linux_sched.h:1.9 Sun Sep 19 23:01:50 2021 +++ src/sys/compat/linux/common/linux_sched.h Sun Sep 19 23:51:37 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: linux_sched.h,v 1.9 2021/09/19 23:01:50 thorpej Exp $ */ +/* $NetBSD: linux_sched.h,v 1.10 2021/09/19 23:51:37 thorpej Exp $ */ /*- * Copyright (c) 1999 The NetBSD Foundation, Inc. @@ -106,4 +106,6 @@ void linux_to_native_itimerspec(struct i int linux_to_native_timer_create_clockid(clockid_t *, clockid_t); +int linux_to_native_timerfd_settime_flags(int *, int); + #endif /* _LINUX_SCHED_H */ Index: src/sys/compat/linux/common/linux_time.c diff -u src/sys/compat/linux/common/linux_time.c:1.41 src/sys/compat/linux/common/linux_time.c:1.42 --- src/sys/compat/linux/common/linux_time.c:1.41 Sun Sep 19 23:01:50 2021 +++ src/sys/compat/linux/common/linux_time.c Sun Sep 19 23:51:37 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: linux_time.c,v 1.41 2021/09/19 23:01:50 thorpej Exp $ */ +/* $NetBSD: linux_time.c,v 1.42 2021/09/19 23:51:37 thorpej Exp $ */ /*- * Copyright (c) 2001, 2020 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: linux_time.c,v 1.41 2021/09/19 23:01:50 thorpej Exp $"); +__KERNEL_RCSID(0, "$NetBSD: linux_time.c,v 1.42 2021/09/19 23:51:37 thorpej Exp $"); #include <sys/param.h> #include <sys/ucred.h> @@ -39,6 +39,7 @@ __KERNEL_RCSID(0, "$NetBSD: linux_time.c #include <sys/signal.h> #include <sys/stdint.h> #include <sys/time.h> +#include <sys/timerfd.h> #include <sys/systm.h> #include <sys/sched.h> #include <sys/syscallargs.h> @@ -46,6 +47,8 @@ __KERNEL_RCSID(0, "$NetBSD: linux_time.c #include <sys/proc.h> #include <compat/linux/common/linux_types.h> +#include <compat/linux/common/linux_fcntl.h> +#include <compat/linux/common/linux_ioctl.h> #include <compat/linux/common/linux_signal.h> #include <compat/linux/common/linux_sigevent.h> #include <compat/linux/common/linux_machdep.h> @@ -441,3 +444,149 @@ linux_sys_timer_gettime(struct lwp *l, * timer_gettoverrun(2) and timer_delete(2) are handled directly * by the native calls. */ + +#define LINUX_TFD_TIMER_ABSTIME 0x0001 +#define LINUX_TFD_TIMER_CANCEL_ON_SET 0x0002 +#define LINUX_TFD_CLOEXEC LINUX_O_CLOEXEC +#define LINUX_TFD_NONBLOCK LINUX_O_NONBLOCK + +int +linux_sys_timerfd_create(struct lwp *l, + const struct linux_sys_timerfd_create_args *uap, register_t *retval) +{ + /* { + syscallarg(clockid_t) clock_id; + syscallarg(int) flags; + } */ + int nflags = 0; + clockid_t id; + int error; + + error = linux_to_native_clockid(&id, SCARG(uap, clock_id)); + if (error) { + return error; + } + + if (SCARG(uap, flags) & ~(LINUX_TFD_CLOEXEC | LINUX_TFD_NONBLOCK)) { + return EINVAL; + } + if (SCARG(uap, flags) & LINUX_TFD_CLOEXEC) { + nflags |= TFD_CLOEXEC; + } + if (SCARG(uap, flags) & LINUX_TFD_NONBLOCK) { + nflags |= TFD_NONBLOCK; + } + + return do_timerfd_create(l, id, nflags, retval); +} + +int +linux_sys_timerfd_gettime(struct lwp *l, + const struct linux_sys_timerfd_gettime_args *uap, register_t *retval) +{ + /* { + syscallarg(int) fd; + syscallarg(struct linux_itimerspec *) tim; + } */ + struct itimerspec its; + struct linux_itimerspec lits; + int error; + + error = do_timerfd_gettime(l, SCARG(uap, fd), &its, retval); + if (error == 0) { + native_to_linux_itimerspec(&lits, &its); + error = copyout(&lits, SCARG(uap, tim), sizeof(lits)); + } + + return error; +} + +int +linux_to_native_timerfd_settime_flags(int *nflagsp, int lflags) +{ + int nflags = 0; + + if (lflags & ~(LINUX_TFD_TIMER_ABSTIME | + LINUX_TFD_TIMER_CANCEL_ON_SET)) { + return EINVAL; + } + if (lflags & LINUX_TFD_TIMER_ABSTIME) { + nflags |= TFD_TIMER_ABSTIME; + } + if (lflags & LINUX_TFD_TIMER_CANCEL_ON_SET) { + nflags |= TFD_TIMER_CANCEL_ON_SET; + } + + *nflagsp = nflags; + + return 0; +} + +int +linux_sys_timerfd_settime(struct lwp *l, + const struct linux_sys_timerfd_settime_args *uap, register_t *retval) +{ + /* { + syscallarg(int) fd; + syscallarg(int) flags; + syscallarg(const struct linux_itimerspec *) tim; + syscallarg(struct linux_itimerspec *) otim; + } */ + struct itimerspec nits, oits, *oitsp = NULL; + struct linux_itimerspec lits; + int nflags; + int error; + + error = copyin(SCARG(uap, tim), &lits, sizeof(lits)); + if (error) { + return error; + } + linux_to_native_itimerspec(&nits, &lits); + + error = linux_to_native_timerfd_settime_flags(&nflags, + SCARG(uap, flags)); + if (error) { + return error; + } + + if (SCARG(uap, otim)) { + oitsp = &oits; + } + + error = do_timerfd_settime(l, SCARG(uap, fd), nflags, + &nits, oitsp, retval); + if (error == 0 && oitsp != NULL) { + native_to_linux_itimerspec(&lits, oitsp); + error = copyout(&lits, SCARG(uap, otim), sizeof(lits)); + } + + return error; +} + +#define LINUX_TFD_IOC_SET_TICKS _LINUX_IOW('T', 0, uint64_t) + +int +linux_ioctl_timerfd(struct lwp *l, const struct linux_sys_ioctl_args *uap, + register_t *retval) +{ + /* { + syscallarg(int) fd; + syscallarg(u_long) com; + syscallarg(void *) data; + } */ + struct sys_ioctl_args ua; + + SCARG(&ua, fd) = SCARG(uap, fd); + SCARG(&ua, data) = SCARG(uap, data); + + switch (SCARG(uap, com)) { + case LINUX_TFD_IOC_SET_TICKS: + SCARG(&ua, com) = TFD_IOC_SET_TICKS; + break; + + default: + return EINVAL; + } + + return sys_ioctl(l, (const void *)&ua, retval); +} Index: src/sys/compat/linux32/arch/amd64/syscalls.master diff -u src/sys/compat/linux32/arch/amd64/syscalls.master:1.72 src/sys/compat/linux32/arch/amd64/syscalls.master:1.73 --- src/sys/compat/linux32/arch/amd64/syscalls.master:1.72 Sun Sep 19 23:01:50 2021 +++ src/sys/compat/linux32/arch/amd64/syscalls.master Sun Sep 19 23:51:37 2021 @@ -1,4 +1,4 @@ - $NetBSD: syscalls.master,v 1.72 2021/09/19 23:01:50 thorpej Exp $ + $NetBSD: syscalls.master,v 1.73 2021/09/19 23:51:37 thorpej Exp $ ; NetBSD i386 COMPAT_LINUX32 system call name/number "master" file. ; (See syscalls.conf to see what it is processed into.) @@ -550,12 +550,16 @@ 320 STD { int|linux32_sys||utimensat(int fd, netbsd32_charp path, \ linux32_timespecp_t times, int flag); } 321 UNIMPL signalfd -322 UNIMPL timerfd_create +322 NOARGS { int|linux_sys||timerfd_create(clockid_t clock_id, \ + int flags); } 323 UNIMPL eventfd 324 STD { int|linux32_sys||fallocate(int fd, int mode, \ off_t offset, off_t len); } -325 UNIMPL timerfd_settime -326 UNIMPL timerfd_gettime +325 STD { int|linux32_sys||timerfd_settime(int fd, int flags, \ + const struct linux32_itimerspec *tim, \ + struct linux32_itimerspec *otim); } +326 STD { int|linux32_sys||timerfd_gettime(int fd, \ + struct linux32_itimerspec *tim); } 327 UNIMPL signalfd4 328 UNIMPL eventfd2 329 UNIMPL epoll_create1 Index: src/sys/compat/linux32/common/linux32_ioctl.c diff -u src/sys/compat/linux32/common/linux32_ioctl.c:1.14 src/sys/compat/linux32/common/linux32_ioctl.c:1.15 --- src/sys/compat/linux32/common/linux32_ioctl.c:1.14 Fri Aug 23 12:49:59 2019 +++ src/sys/compat/linux32/common/linux32_ioctl.c Sun Sep 19 23:51:37 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: linux32_ioctl.c,v 1.14 2019/08/23 12:49:59 maxv Exp $ */ +/* $NetBSD: linux32_ioctl.c,v 1.15 2021/09/19 23:51:37 thorpej Exp $ */ /*- * Copyright (c) 2006 Emmanuel Dreyfus, all rights reserved. @@ -32,13 +32,15 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: linux32_ioctl.c,v 1.14 2019/08/23 12:49:59 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: linux32_ioctl.c,v 1.15 2021/09/19 23:51:37 thorpej Exp $"); #include <sys/types.h> #include <sys/param.h> #include <sys/time.h> #include <sys/ucred.h> #include <sys/ioctl.h> +#include <sys/file.h> +#include <sys/filedesc.h> #include <compat/netbsd32/netbsd32.h> #include <compat/netbsd32/netbsd32_syscallargs.h> @@ -46,6 +48,7 @@ __KERNEL_RCSID(0, "$NetBSD: linux32_ioct #include <compat/linux/common/linux_types.h> #include <compat/linux/common/linux_signal.h> #include <compat/linux/common/linux_ipc.h> +#include <compat/linux/common/linux_ioctl.h> #include <compat/linux/common/linux_sem.h> #include <compat/linux/linux_syscallargs.h> @@ -80,8 +83,31 @@ linux32_sys_ioctl(struct lwp *l, const s switch(group) { case 'T': - error = linux32_ioctl_termios(l, uap, retval); + { + /* + * Termios, the MIDI sequencer, and timerfd use 'T' to + * identify the ioctl, so we have to differentiate them + * in another way. + * + * (XXX We don't bother with MIDI here.) + */ + struct file *fp; + + if ((fp = fd_getfile(SCARG(uap, fd))) == NULL) + return EBADF; + + if (fp->f_type == DTYPE_TIMERFD) { + struct linux_sys_ioctl_args ua; + SCARG(&ua, fd) = SCARG(uap, fd); + SCARG(&ua, com) = SCARG(uap, com); + SCARG(&ua, data) = SCARG_P32(uap, data); + error = linux_ioctl_timerfd(l, &ua, retval); + } else { + error = linux32_ioctl_termios(l, uap, retval); + } + fd_putfile(SCARG(uap, fd)); break; + } case 'M': case 'Q': case 'P': Index: src/sys/compat/linux32/common/linux32_time.c diff -u src/sys/compat/linux32/common/linux32_time.c:1.39 src/sys/compat/linux32/common/linux32_time.c:1.40 --- src/sys/compat/linux32/common/linux32_time.c:1.39 Sun Sep 19 23:01:50 2021 +++ src/sys/compat/linux32/common/linux32_time.c Sun Sep 19 23:51:37 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: linux32_time.c,v 1.39 2021/09/19 23:01:50 thorpej Exp $ */ +/* $NetBSD: linux32_time.c,v 1.40 2021/09/19 23:51:37 thorpej Exp $ */ /*- * Copyright (c) 2006 Emmanuel Dreyfus, all rights reserved. @@ -33,7 +33,7 @@ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: linux32_time.c,v 1.39 2021/09/19 23:01:50 thorpej Exp $"); +__KERNEL_RCSID(0, "$NetBSD: linux32_time.c,v 1.40 2021/09/19 23:51:37 thorpej Exp $"); #include <sys/types.h> #include <sys/param.h> @@ -45,6 +45,7 @@ __KERNEL_RCSID(0, "$NetBSD: linux32_time #include <sys/fcntl.h> #include <sys/namei.h> #include <sys/select.h> +#include <sys/timerfd.h> #include <sys/proc.h> #include <sys/resourcevar.h> #include <sys/ucred.h> @@ -498,3 +499,69 @@ linux32_sys_timer_gettime(struct lwp *l, * timer_gettoverrun(2) and timer_delete(2) are handled directly * by the native calls. */ + +/* + * timerfd_create() is handled by the standard COMPAT_LINUX call. + */ + +int +linux32_sys_timerfd_gettime(struct lwp *l, + const struct linux32_sys_timerfd_gettime_args *uap, register_t *retval) +{ + /* { + syscallarg(int) fd; + syscallarg(struct linux32_itimerspec *) tim; + } */ + struct itimerspec its; + struct linux32_itimerspec lits; + int error; + + error = do_timerfd_gettime(l, SCARG(uap, fd), &its, retval); + if (error == 0) { + native_to_linux32_itimerspec(&lits, &its); + error = copyout(&lits, SCARG(uap, tim), sizeof(lits)); + } + + return error; +} + +int +linux32_sys_timerfd_settime(struct lwp *l, + const struct linux32_sys_timerfd_settime_args *uap, register_t *retval) +{ + /* { + syscallarg(int) fd; + syscallarg(int) flags; + syscallarg(const struct linux32_itimerspec *) tim; + syscallarg(struct linux32_itimerspec *) otim; + } */ + struct itimerspec nits, oits, *oitsp = NULL; + struct linux32_itimerspec lits; + int nflags; + int error; + + error = copyin(SCARG(uap, tim), &lits, sizeof(lits)); + if (error) { + return error; + } + linux32_to_native_itimerspec(&nits, &lits); + + error = linux_to_native_timerfd_settime_flags(&nflags, + SCARG(uap, flags)); + if (error) { + return error; + } + + if (SCARG(uap, otim)) { + oitsp = &oits; + } + + error = do_timerfd_settime(l, SCARG(uap, fd), nflags, + &nits, oitsp, retval); + if (error == 0 && oitsp != NULL) { + native_to_linux32_itimerspec(&lits, oitsp); + error = copyout(&lits, SCARG(uap, otim), sizeof(lits)); + } + + return error; +}