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;
+}