Module Name:    src
Committed By:   thorpej
Date:           Tue Dec 15 14:07:21 UTC 2020

Modified Files:
        src/sys/compat/linux/arch/alpha [thorpej-futex]: syscalls.master
        src/sys/compat/linux/arch/amd64 [thorpej-futex]: syscalls.master
        src/sys/compat/linux/arch/arm [thorpej-futex]: syscalls.master
        src/sys/compat/linux/arch/i386 [thorpej-futex]: syscalls.master
        src/sys/compat/linux/arch/m68k [thorpej-futex]: syscalls.master
        src/sys/compat/linux/arch/mips [thorpej-futex]: syscalls.master
        src/sys/compat/linux/arch/powerpc [thorpej-futex]: syscalls.master
        src/sys/compat/linux/common [thorpej-futex]: linux_ioctl.c
            linux_ioctl.h linux_misc.c linux_sched.h linux_sigevent.h
            linux_signal.c linux_time.c

Log Message:
Add Linux eventfd, timerfd, and POSIX timer calls.


To generate a diff of this commit:
cvs rdiff -u -r1.97 -r1.97.2.1 \
    src/sys/compat/linux/arch/alpha/syscalls.master
cvs rdiff -u -r1.62 -r1.62.2.1 \
    src/sys/compat/linux/arch/amd64/syscalls.master
cvs rdiff -u -r1.69 -r1.69.2.1 src/sys/compat/linux/arch/arm/syscalls.master
cvs rdiff -u -r1.124 -r1.124.2.1 \
    src/sys/compat/linux/arch/i386/syscalls.master
cvs rdiff -u -r1.95 -r1.95.2.1 src/sys/compat/linux/arch/m68k/syscalls.master
cvs rdiff -u -r1.68 -r1.68.2.1 src/sys/compat/linux/arch/mips/syscalls.master
cvs rdiff -u -r1.74 -r1.74.2.1 \
    src/sys/compat/linux/arch/powerpc/syscalls.master
cvs rdiff -u -r1.58 -r1.58.42.1 src/sys/compat/linux/common/linux_ioctl.c
cvs rdiff -u -r1.27 -r1.27.46.1 src/sys/compat/linux/common/linux_ioctl.h
cvs rdiff -u -r1.251 -r1.251.2.1 src/sys/compat/linux/common/linux_misc.c
cvs rdiff -u -r1.8 -r1.8.64.1 src/sys/compat/linux/common/linux_sched.h
cvs rdiff -u -r1.2 -r1.2.100.1 src/sys/compat/linux/common/linux_sigevent.h
cvs rdiff -u -r1.83 -r1.83.2.1 src/sys/compat/linux/common/linux_signal.c
cvs rdiff -u -r1.39 -r1.39.16.1 src/sys/compat/linux/common/linux_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.97 src/sys/compat/linux/arch/alpha/syscalls.master:1.97.2.1
--- src/sys/compat/linux/arch/alpha/syscalls.master:1.97	Sun Apr 26 18:53:32 2020
+++ src/sys/compat/linux/arch/alpha/syscalls.master	Tue Dec 15 14:07:20 2020
@@ -1,4 +1,4 @@
-	$NetBSD: syscalls.master,v 1.97 2020/04/26 18:53:32 thorpej Exp $
+	$NetBSD: syscalls.master,v 1.97.2.1 2020/12/15 14:07:20 thorpej Exp $
 ;
 ;	@(#)syscalls.master	8.1 (Berkeley) 7/19/93
 
@@ -663,11 +663,15 @@
 412	UNIMPL		restart_syscall
 413	STD		{ int|linux_sys||fadvise64(int fd, off_t offset, \
 			    size_t len, int advice); }
-414	UNIMPL		timer_create
-415	UNIMPL		timer_settime
-416	UNIMPL		timer_gettime
-417	UNIMPL		timer_getoverrun
-418	UNIMPL		timer_delete
+414	STD		{ int|linux_sys||timer_create(clockid_t clockid, \
+			    struct linux_sigevent *evp, timer_t *timerid); }
+415	STD		{ int|linux_sys||timer_settime(timer_t timerid, \
+			    int flags, const struct linux_itimerspec *tim, \
+			    struct linux_itimerspec *otim); }
+416	STD		{ int|linux_sys||timer_gettime(timer_t timerid, \
+			    struct linux_itimerspec *tim); }
+417	NOARGS		{ int|sys||timer_getoverrun(timer_t timerid); }
+418	NOARGS		{ int|sys||timer_delete(timer_t timerid); }
 419	STD		{ int|linux_sys||clock_settime(clockid_t which, \
 			    struct linux_timespec *tp); }
 420	STD		{ int|linux_sys||clock_gettime(clockid_t which, \
@@ -760,17 +764,22 @@
 			    struct linux_timespec *times, int flag); }
 476	UNIMPL		signalfd
 477	UNIMPL		timerfd
-478	UNIMPL		eventfd
+478	STD		{ int|linux_sys||eventfd(unsigned int initval); }
 479	STD		{ int|linux_sys||recvmmsg(int s, \
 			    struct linux_mmsghdr *msgvec, unsigned int vlen, \
 			    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 *new_value, \
+			    struct linux_itimerspec *old_value); }
+483	STD		{ int|linux_sys||timerfd_gettime(int fd, \
+			    struct linux_itimerspec *curr_value); }
 484	UNIMPL		signalfd4
-485	UNIMPL		eventfd2
+485	STD		{ int|linux_sys||eventfd2(unsigned int initval, \
+			    int flags); }
 486	UNIMPL		epoll_create1
 487	STD		{ int|linux_sys||dup3(int from, int to, int flags); }
 488	STD		{ int|linux_sys||pipe2(int *pfds, int flags); }

Index: src/sys/compat/linux/arch/amd64/syscalls.master
diff -u src/sys/compat/linux/arch/amd64/syscalls.master:1.62 src/sys/compat/linux/arch/amd64/syscalls.master:1.62.2.1
--- src/sys/compat/linux/arch/amd64/syscalls.master:1.62	Sun Apr 26 18:53:32 2020
+++ src/sys/compat/linux/arch/amd64/syscalls.master	Tue Dec 15 14:07:20 2020
@@ -1,4 +1,4 @@
-	$NetBSD: syscalls.master,v 1.62 2020/04/26 18:53:32 thorpej Exp $
+	$NetBSD: syscalls.master,v 1.62.2.1 2020/12/15 14:07:20 thorpej Exp $
 
 ;	@(#)syscalls.master	8.1 (Berkeley) 7/19/93
 
@@ -423,11 +423,15 @@
 220	UNIMPL		semtimedop
 221	STD		{ int|linux_sys||fadvise64(int fd, off_t offset, \
 			    size_t len, int advice); }
-222	UNIMPL		timer_create
-223	UNIMPL		timer_settime
-224	UNIMPL		timer_gettime
-225	UNIMPL		timer_getoverrun
-226	UNIMPL		timer_delete
+222	STD		{ int|linux_sys||timer_create(clockid_t clockid, \
+			    struct linux_sigevent *evp, timer_t *timerid); }
+223	STD		{ int|linux_sys||timer_settime(timer_t timerid, \
+			    int flags, const struct linux_itimerspec *tim, \
+			    struct linux_itimerspec *otim); }
+224	STD		{ int|linux_sys||timer_gettime(timer_t timerid, \
+			    struct linux_itimerspec *tim); }
+225	NOARGS		{ int|sys||timer_getoverrun(timer_t timerid); }
+226	NOARGS		{ int|sys||timer_delete(timer_t timerid); }
 227	STD		{ int|linux_sys||clock_settime(clockid_t which, \
 			    struct linux_timespec *tp); }
 228	STD		{ int|linux_sys||clock_gettime(clockid_t which, \
@@ -515,17 +519,22 @@
 			    struct linux_timespec *times, int flag); }
 281	UNIMPL		epoll_pwait
 282	UNIMPL		signalfd
-283	UNIMPL		timerfd_create
-284	UNIMPL		eventfd
+283	STD		{ int|linux_sys||timerfd_create(clockid_t clock_id, \
+			    int flags); }
+284	STD		{ int|linux_sys||eventfd(unsigned int initval); }
 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 *new_value, \
+			    struct linux_itimerspec *old_value); }
+287	STD		{ int|linux_sys||timerfd_gettime(int fd, \
+			    struct linux_itimerspec *curr_value); }
 288	STD		{ int|linux_sys||accept4(int s, \
 			    struct osockaddr *name, \
 			    int *anamelen, int flags); }
 289	UNIMPL		signalfd4
-290	UNIMPL		eventfd2
+290	STD		{ int|linux_sys||eventfd2(unsigned int initval, \
+			    int flags); }
 291	UNIMPL		epoll_create1
 292	STD		{ int|linux_sys||dup3(int from, int to, int flags); }
 293	STD		{ int|linux_sys||pipe2(int *pfds, int flags); }

Index: src/sys/compat/linux/arch/arm/syscalls.master
diff -u src/sys/compat/linux/arch/arm/syscalls.master:1.69 src/sys/compat/linux/arch/arm/syscalls.master:1.69.2.1
--- src/sys/compat/linux/arch/arm/syscalls.master:1.69	Sun Apr 26 18:53:32 2020
+++ src/sys/compat/linux/arch/arm/syscalls.master	Tue Dec 15 14:07:21 2020
@@ -1,4 +1,4 @@
-	$NetBSD: syscalls.master,v 1.69 2020/04/26 18:53:32 thorpej Exp $
+	$NetBSD: syscalls.master,v 1.69.2.1 2020/12/15 14:07:21 thorpej Exp $
 
 ; Derived from sys/compat/linux/arch/*/syscalls.master
 ; and from Linux 2.4.12 arch/arm/kernel/calls.S
@@ -431,11 +431,15 @@
 254	UNIMPL		set_thread_area
 255	UNIMPL		get_thread_area
 256	STD		{ int|linux_sys||set_tid_address(int *tid); }
-257	UNIMPL		timer_create
-258	UNIMPL		timer_settime
-259	UNIMPL		timer_gettime
-260	UNIMPL		timer_getoverrun
-261	UNIMPL		timer_delete
+257	STD		{ int|linux_sys||timer_create(clockid_t clockid, \
+			    struct linux_sigevent *evp, timer_t *timerid); }
+258	STD		{ int|linux_sys||timer_settime(timer_t timerid, \
+			    int flags, const struct linux_itimerspec *tim, \
+			    struct linux_itimerspec *otim); }
+259	STD		{ int|linux_sys||timer_gettime(timer_t timerid, \
+			    struct linux_itimerspec *tim); }
+260	NOARGS		{ int|sys||timer_getoverrun(timer_t timerid); }
+261	NOARGS		{ int|sys||timer_delete(timer_t timerid); }
 262	STD		{ int|linux_sys||clock_settime(clockid_t which, \
 			    struct linux_timespec *tp); }
 263	STD		{ int|linux_sys||clock_gettime(clockid_t which, \
@@ -558,14 +562,19 @@
 348	STD		{ int|linux_sys||utimensat(int fd, const char *path, \
 			    struct linux_timespec *times, int flag); }
 349	UNIMPL		signalfd
-350	UNIMPL		timerfd_create
-351	UNIMPL		eventfd
+350	STD		{ int|linux_sys||timerfd_create(clockid_t clock_id, \
+			    int flags); }
+351	STD		{ int|linux_sys||eventfd(unsigned int initval); }
 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 *new_value, \
+			    struct linux_itimerspec *old_value); }
+354	STD		{ int|linux_sys||timerfd_gettime(int fd, \
+			    struct linux_itimerspec *curr_value); }
 355	UNIMPL		signalfd4
-356	UNIMPL		eventfd2
+356	STD		{ int|linux_sys||eventfd2(unsigned int initval, \
+			    int flags); }
 357	UNIMPL		epoll_create1
 358	STD		{ int|linux_sys||dup3(int from, int to, int flags); }
 359	STD		{ int|linux_sys||pipe2(int *pfds, int flags); }

Index: src/sys/compat/linux/arch/i386/syscalls.master
diff -u src/sys/compat/linux/arch/i386/syscalls.master:1.124 src/sys/compat/linux/arch/i386/syscalls.master:1.124.2.1
--- src/sys/compat/linux/arch/i386/syscalls.master:1.124	Sun Apr 26 18:53:32 2020
+++ src/sys/compat/linux/arch/i386/syscalls.master	Tue Dec 15 14:07:21 2020
@@ -1,4 +1,4 @@
-	$NetBSD: syscalls.master,v 1.124 2020/04/26 18:53:32 thorpej Exp $
+	$NetBSD: syscalls.master,v 1.124.2.1 2020/12/15 14:07:21 thorpej Exp $
 
 ;	@(#)syscalls.master	8.1 (Berkeley) 7/19/93
 
@@ -433,11 +433,15 @@
 256	UNIMPL		epoll_wait
 257	UNIMPL		remap_file_pages
 258	STD		{ int|linux_sys||set_tid_address(int *tid); }
-259	UNIMPL		timer_create
-260	UNIMPL		timer_settime
-261	UNIMPL		timer_gettime
-262	UNIMPL		timer_getoverrun
-263	UNIMPL		timer_delete
+259	STD		{ int|linux_sys||timer_create(clockid_t clockid, \
+			    struct linux_sigevent *evp, timer_t *timerid); }
+260	STD		{ int|linux_sys||timer_settime(timer_t timerid, \
+			    int flags, const struct linux_itimerspec *tim, \
+			    struct linux_itimerspec *otim); }
+261	STD		{ int|linux_sys||timer_gettime(timer_t timerid, \
+			    struct linux_itimerspec *tim); }
+262	NOARGS		{ int|sys||timer_getoverrun(timer_t timerid); }
+263	NOARGS		{ int|sys||timer_delete(timer_t timerid); }
 264	STD		{ int|linux_sys||clock_settime(clockid_t which, \
 			    struct linux_timespec *tp); }
 265	STD		{ int|linux_sys||clock_gettime(clockid_t which, \
@@ -525,14 +529,19 @@
 320	STD		{ int|linux_sys||utimensat(int fd, const char *path, \
 			    struct linux_timespec *times, int flag); }
 321	UNIMPL		signalfd
-322	UNIMPL		timerfd_create
-323	UNIMPL		eventfd
+322	STD		{ int|linux_sys||timerfd_create(clockid_t clock_id, \
+			    int flags); }
+323	STD		{ int|linux_sys||eventfd(unsigned int initval); }
 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 *new_value, \
+			    struct linux_itimerspec *old_value); }
+326	STD		{ int|linux_sys||timerfd_gettime(int fd, \
+			    struct linux_itimerspec *curr_value); }
 327	UNIMPL		signalfd4
-328	UNIMPL		eventfd2
+328	STD		{ int|linux_sys||eventfd2(unsigned int initval, \
+			    int flags); }
 329	UNIMPL		epoll_create1
 330     STD             { int|linux_sys||dup3(int from, int to, int flags); }
 331     STD             { int|linux_sys||pipe2( int *pfds, int flags); }

Index: src/sys/compat/linux/arch/m68k/syscalls.master
diff -u src/sys/compat/linux/arch/m68k/syscalls.master:1.95 src/sys/compat/linux/arch/m68k/syscalls.master:1.95.2.1
--- src/sys/compat/linux/arch/m68k/syscalls.master:1.95	Sun Apr 26 18:53:32 2020
+++ src/sys/compat/linux/arch/m68k/syscalls.master	Tue Dec 15 14:07:21 2020
@@ -1,4 +1,4 @@
-	$NetBSD: syscalls.master,v 1.95 2020/04/26 18:53:32 thorpej Exp $
+	$NetBSD: syscalls.master,v 1.95.2.1 2020/12/15 14:07:21 thorpej Exp $
 
 ;	@(#)syscalls.master	8.1 (Berkeley) 7/19/93
 
@@ -443,11 +443,15 @@
 251	UNIMPL		epoll_wait
 252	UNIMPL		remap_file_pages
 253	STD		{ int|linux_sys||set_tid_address(int *tid); }
-254	UNIMPL		timer_create
-255	UNIMPL		timer_settime
-256	UNIMPL		timer_gettime
-257	UNIMPL		timer_getoverrun
-258	UNIMPL		timer_ delete
+254	STD		{ int|linux_sys||timer_create(clockid_t clockid, \
+			    struct linux_sigevent *evp, timer_t *timerid); }
+255	STD		{ int|linux_sys||timer_settime(timer_t timerid, \
+			    int flags, const struct linux_itimerspec *tim, \
+			    struct linux_itimerspec *otim); }
+256	STD		{ int|linux_sys||timer_gettime(timer_t timerid, \
+			    struct linux_itimerspec *tim); }
+257	NOARGS		{ int|sys||timer_getoverrun(timer_t timerid); }
+258	NOARGS		{ int|sys||timer_delete(timer_t timerid); }
 259	STD		{ int|linux_sys||clock_settime(clockid_t which, \
 			    struct linux_timespec *tp); }
 260	STD		{ int|linux_sys||clock_gettime(clockid_t which, \
@@ -543,14 +547,19 @@
 316	STD		{ int|linux_sys||utimensat(int fd, const char *path, \
 			    struct linux_timespec *times, int flag); }
 317	UNIMPL		signalfd
-318	UNIMPL		timerfd_create
-319	UNIMPL		eventfd
+318	STD		{ int|linux_sys||timerfd_create(clockid_t clock_id, \
+			    int flags); }
+319	STD		{ int|linux_sys||eventfd(unsigned int initval); }
 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 *new_value, \
+			    struct linux_itimerspec *old_value); }
+322	STD		{ int|linux_sys||timerfd_gettime(int fd, \
+			    struct linux_itimerspec *curr_value); }
 323	UNIMPL		signalfd4
-324	UNIMPL		eventfd2
+324	STD		{ int|linux_sys||eventfd2(unsigned int initval, \
+			    int flags); }
 325	UNIMPL		epoll_create1
 326	STD		{ int|linux_sys||dup3(int from, int to, int flags); }
 327	STD		{ int|linux_sys||pipe2(int *pfds, int flags); }

Index: src/sys/compat/linux/arch/mips/syscalls.master
diff -u src/sys/compat/linux/arch/mips/syscalls.master:1.68 src/sys/compat/linux/arch/mips/syscalls.master:1.68.2.1
--- src/sys/compat/linux/arch/mips/syscalls.master:1.68	Sun Apr 26 18:53:32 2020
+++ src/sys/compat/linux/arch/mips/syscalls.master	Tue Dec 15 14:07:21 2020
@@ -1,4 +1,4 @@
-	$NetBSD: syscalls.master,v 1.68 2020/04/26 18:53:32 thorpej Exp $  
+	$NetBSD: syscalls.master,v 1.68.2.1 2020/12/15 14:07:21 thorpej Exp $  
 
 ;	@(#)syscalls.master	8.1 (Berkeley) 7/19/93
 
@@ -439,11 +439,15 @@
 			    size_t sz, struct linux_statfs64 *sp); }
 256	STD		{ int|linux_sys||fstatfs64(int fd, \
 			    size_t sz, struct linux_statfs64 *sp); }
-257	UNIMPL		timer_create
-258	UNIMPL		timer_settime
-259	UNIMPL		timer_gettime
-260	UNIMPL		timer_getoverrun
-261	UNIMPL		timer_delete
+257	STD		{ int|linux_sys||timer_create(clockid_t clockid, \
+			    struct linux_sigevent *evp, timer_t *timerid); }
+258	STD		{ int|linux_sys||timer_settime(timer_t timerid, \
+			    int flags, const struct linux_itimerspec *tim, \
+			    struct linux_itimerspec *otim); }
+259	STD		{ int|linux_sys||timer_gettime(timer_t timerid, \
+			    struct linux_itimerspec *tim); }
+260	NOARGS		{ int|sys||timer_getoverrun(timer_t timerid); }
+261	NOARGS		{ int|sys||timer_delete(timer_t timerid); }
 262	STD		{ int|linux_sys||clock_settime(clockid_t which, \
 			    struct linux_timespec *tp); }
 263	STD		{ int|linux_sys||clock_gettime(clockid_t which, \
@@ -532,14 +536,19 @@
 			    struct linux_timespec *times, int flag); }
 317	UNIMPL		signalfd
 318	UNIMPL		timerfd
-319	UNIMPL		eventfd
+319	STD		{ int|linux_sys||eventfd(unsigned int initval); }
 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 *curr_value); }
+323	STD		{ int|linux_sys||timerfd_settime(int fd, int flags, \
+			    const struct linux_itimerspec *new_value, \
+			    struct linux_itimerspec *old_value); }
 324	UNIMPL		signalfd4
-325	UNIMPL		eventfd2
+325	STD		{ int|linux_sys||eventfd2(unsigned int initval, \
+			    int flags); }
 326	UNIMPL		epoll_create1
 327	STD		{ int|linux_sys||dup3(int from, int to, int flags); }
 328	STD		{ int|linux_sys||pipe2(int *pfds, int flags); }

Index: src/sys/compat/linux/arch/powerpc/syscalls.master
diff -u src/sys/compat/linux/arch/powerpc/syscalls.master:1.74 src/sys/compat/linux/arch/powerpc/syscalls.master:1.74.2.1
--- src/sys/compat/linux/arch/powerpc/syscalls.master:1.74	Sun Apr 26 18:53:32 2020
+++ src/sys/compat/linux/arch/powerpc/syscalls.master	Tue Dec 15 14:07:21 2020
@@ -1,4 +1,4 @@
-	$NetBSD: syscalls.master,v 1.74 2020/04/26 18:53:32 thorpej Exp $  
+	$NetBSD: syscalls.master,v 1.74.2.1 2020/12/15 14:07:21 thorpej Exp $  
 
 ;	@(#)syscalls.master	8.1 (Berkeley) 7/19/93
 
@@ -429,11 +429,15 @@
 237	UNIMPL		epoll_ctl
 238	UNIMPL		epoll_wait
 239	UNIMPL		remap_file_pages
-240	UNIMPL		timer_create
-241	UNIMPL		timer_settime
-242	UNIMPL		timer_gettime
-243	UNIMPL		timer_getoverrun
-244	UNIMPL		timer_delete
+240	STD		{ int|linux_sys||timer_create(clockid_t clockid, \
+			    struct linux_sigevent *evp, timer_t *timerid); }
+241	STD		{ int|linux_sys||timer_settime(timer_t timerid, \
+			    int flags, const struct linux_itimerspec *tim, \
+			    struct linux_itimerspec *otim); }
+242	STD		{ int|linux_sys||timer_gettime(timer_t timerid, \
+			    struct linux_itimerspec *tim); }
+243	NOARGS		{ int|sys||timer_getoverrun(timer_t timerid); }
+244	NOARGS		{ int|sys||timer_delete(timer_t timerid); }
 245	STD		{ int|linux_sys||clock_settime(clockid_t which, \
 			    struct linux_timespec *tp); }
 246	STD		{ int|linux_sys||clock_gettime(clockid_t which, \
@@ -529,16 +533,21 @@
 304	STD		{ int|linux_sys||utimensat(int fd, const char *path, \
 			    struct linux_timespec *times, int flag); }
 305	UNIMPL		signalfd
-306	UNIMPL		timerfd_create
-307	UNIMPL		eventfd
+306	STD		{ int|linux_sys||timerfd_create(clockid_t clock_id, \
+			    int flags); }
+307	STD		{ int|linux_sys||eventfd(unsigned int initval); }
 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 *new_value, \
+			    struct linux_itimerspec *old_value); }
+312	STD		{ int|linux_sys||timerfd_gettime(int fd, \
+			    struct linux_itimerspec *curr_value); }
 313	UNIMPL		signalfd4
-314	UNIMPL		eventfd2
+314	UNIMPL		{ int|linux_sys||eventfd2(unsigned int initval, \
+			    int flags); }
 315	UNIMPL		epoll_create1
 316	STD		{ int|linux_sys||dup3(int from, int to, int flags); }
 317	STD		{ int|linux_sys||pipe2(int *pfds, int flags); }

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.58.42.1
--- 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	Tue Dec 15 14:07:21 2020
@@ -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.58.42.1 2020/12/15 14:07:21 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.58.42.1 2020/12/15 14:07:21 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 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.27.46.1
--- 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	Tue Dec 15 14:07:21 2020
@@ -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.27.46.1 2020/12/15 14:07:21 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_misc.c
diff -u src/sys/compat/linux/common/linux_misc.c:1.251 src/sys/compat/linux/common/linux_misc.c:1.251.2.1
--- src/sys/compat/linux/common/linux_misc.c:1.251	Thu Jun 11 22:21:05 2020
+++ src/sys/compat/linux/common/linux_misc.c	Tue Dec 15 14:07:21 2020
@@ -1,7 +1,7 @@
-/*	$NetBSD: linux_misc.c,v 1.251 2020/06/11 22:21:05 ad Exp $	*/
+/*	$NetBSD: linux_misc.c,v 1.251.2.1 2020/12/15 14:07:21 thorpej Exp $	*/
 
 /*-
- * Copyright (c) 1995, 1998, 1999, 2008 The NetBSD Foundation, Inc.
+ * Copyright (c) 1995, 1998, 1999, 2008, 2020 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
  * This code is derived from software contributed to The NetBSD Foundation
@@ -57,13 +57,14 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: linux_misc.c,v 1.251 2020/06/11 22:21:05 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: linux_misc.c,v 1.251.2.1 2020/12/15 14:07:21 thorpej Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/namei.h>
 #include <sys/proc.h>
 #include <sys/dirent.h>
+#include <sys/eventfd.h>
 #include <sys/file.h>
 #include <sys/stat.h>
 #include <sys/filedesc.h>
@@ -1580,3 +1581,54 @@ linux_do_futex(int *uaddr, int op, int v
 	return do_futex(uaddr, op & ~FUTEX_PRIVATE_FLAG,
 			val, timeout, uaddr2, val2, val3, retval);
 }
+
+#define	LINUX_EFD_SEMAPHORE	0x0001
+#define	LINUX_EFD_CLOEXEC	LINUX_O_CLOEXEC
+#define	LINUX_EFD_NONBLOCK	LINUX_O_NONBLOCK
+
+static int
+linux_do_eventfd2(struct lwp *l, unsigned int initval, int flags,
+    register_t *retval)
+{
+	int nflags = 0;
+
+	if (flags & ~(LINUX_EFD_SEMAPHORE | LINUX_EFD_CLOEXEC |
+		      LINUX_EFD_NONBLOCK)) {
+		return EINVAL;
+	}
+	if (flags & LINUX_EFD_SEMAPHORE) {
+		nflags |= EFD_SEMAPHORE;
+	}
+	if (flags & LINUX_EFD_CLOEXEC) {
+		nflags |= EFD_CLOEXEC;
+	}
+	if (flags & LINUX_EFD_NONBLOCK) {
+		nflags |= EFD_NONBLOCK;
+	}
+
+	return do_eventfd(l, initval, nflags, retval);
+}
+
+int
+linux_sys_eventfd(struct lwp *l, const struct linux_sys_eventfd_args *uap,
+    register_t *retval)
+{
+	/* {
+		syscallarg(unsigned int) initval;
+	} */
+
+	return linux_do_eventfd2(l, SCARG(uap, initval), 0, retval);
+}
+
+int
+linux_sys_eventfd2(struct lwp *l, const struct linux_sys_eventfd2_args *uap,
+    register_t *retval)
+{
+	/* {
+		syscallarg(unsigned int) initval;
+		syscallarg(int) flags;
+	} */
+
+	return linux_do_eventfd2(l, SCARG(uap, initval), SCARG(uap, flags),
+				 retval);
+}

Index: src/sys/compat/linux/common/linux_sched.h
diff -u src/sys/compat/linux/common/linux_sched.h:1.8 src/sys/compat/linux/common/linux_sched.h:1.8.64.1
--- src/sys/compat/linux/common/linux_sched.h:1.8	Fri Nov 18 04:07:44 2011
+++ src/sys/compat/linux/common/linux_sched.h	Tue Dec 15 14:07:21 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: linux_sched.h,v 1.8 2011/11/18 04:07:44 christos Exp $	*/
+/*	$NetBSD: linux_sched.h,v 1.8.64.1 2020/12/15 14:07:21 thorpej Exp $	*/
 
 /*-
  * Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -74,15 +74,34 @@ struct linux_timespec {
 	long		tv_nsec;	/* nanoseconds */
 };
 
+struct linux_itimerspec {
+	struct linux_timespec it_interval;
+	struct linux_timespec it_value;
+};
+
 #define LINUX_CLOCK_REALTIME		0
 #define LINUX_CLOCK_MONOTONIC		1
 #define LINUX_CLOCK_PROCESS_CPUTIME_ID	2
 #define LINUX_CLOCK_THREAD_CPUTIME_ID	3
-#define LINUX_CLOCK_REALTIME_HR		4
-#define LINUX_CLOCK_MONOTONIC_HR	5
-
-int linux_to_native_clockid(clockid_t *, clockid_t);
-void native_to_linux_timespec(struct linux_timespec *, struct timespec *);
-void linux_to_native_timespec(struct timespec *, struct linux_timespec *);
+#define LINUX_CLOCK_MONOTONIC_RAW	4
+#define LINUX_CLOCK_REALTIME_COARSE	5
+#define LINUX_CLOCK_MONOTONIC_COARSE	6
+#define LINUX_CLOCK_BOOTTIME		7
+#define LINUX_CLOCK_BOOTTIME_ALARM	8
+#define LINUX_CLOCK_REALTIME_ALARM	9
+
+#define	LINUX_TIMER_ABSTIME		0x01
+
+int	linux_to_native_clockid(clockid_t *, clockid_t);
+
+void	native_to_linux_timespec(struct linux_timespec *,
+	    const struct timespec *);
+void	linux_to_native_timespec(struct timespec *,
+	    const struct linux_timespec *);
+
+void	native_to_linux_itimerspec(struct linux_itimerspec *,
+	    const struct itimerspec *);
+void	linux_to_native_itimerspec(struct itimerspec *,
+	    const struct linux_itimerspec *);
 
 #endif /* _LINUX_SCHED_H */

Index: src/sys/compat/linux/common/linux_sigevent.h
diff -u src/sys/compat/linux/common/linux_sigevent.h:1.2 src/sys/compat/linux/common/linux_sigevent.h:1.2.100.1
--- src/sys/compat/linux/common/linux_sigevent.h:1.2	Mon Apr 28 20:23:44 2008
+++ src/sys/compat/linux/common/linux_sigevent.h	Tue Dec 15 14:07:21 2020
@@ -37,7 +37,8 @@
 
 #define LINUX_SIGEV_MAX  64
 #ifndef LINUX_SIGEV_PAD
-#define LINUX_SIGEV_PAD  ((LINUX_SIGEV_MAX/sizeof(int)) - 3)
+#define LINUX_SIGEV_PAD  (LINUX_SIGEV_MAX -				\
+			  (sizeof(sigval_t) + (sizeof(int) * 2)))
 #endif
 
 typedef struct linux_sigevent {
@@ -54,4 +55,8 @@ typedef struct linux_sigevent {
 	} _sigev_un;
 } linux_sigevent_t;
 
+int	linux_to_native_sigevent(struct sigevent *,
+	    const struct linux_sigevent *);
+int	linux_sigevent_copyin(const void *, void *, size_t);
+
 #endif /* _LINUX_SIGEVENT_H */

Index: src/sys/compat/linux/common/linux_signal.c
diff -u src/sys/compat/linux/common/linux_signal.c:1.83 src/sys/compat/linux/common/linux_signal.c:1.83.2.1
--- src/sys/compat/linux/common/linux_signal.c:1.83	Sat May 23 23:42:41 2020
+++ src/sys/compat/linux/common/linux_signal.c	Tue Dec 15 14:07:21 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: linux_signal.c,v 1.83 2020/05/23 23:42:41 ad Exp $	*/
+/*	$NetBSD: linux_signal.c,v 1.83.2.1 2020/12/15 14:07:21 thorpej Exp $	*/
 
 /*-
  * Copyright (c) 1995, 1998 The NetBSD Foundation, Inc.
@@ -48,7 +48,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: linux_signal.c,v 1.83 2020/05/23 23:42:41 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: linux_signal.c,v 1.83.2.1 2020/12/15 14:07:21 thorpej Exp $");
 
 #define COMPAT_LINUX 1
 
@@ -844,3 +844,50 @@ native_to_linux_si_status(int code, int 
 
 	return sts;
 }
+
+int
+linux_to_native_sigevent(struct sigevent *nsep,
+    const struct linux_sigevent *lsep)
+{
+	memset(nsep, 0, sizeof(*nsep));
+
+	switch (lsep->sigev_notify) {
+	case LINUX_SIGEV_SIGNAL:
+		nsep->sigev_notify = SIGEV_SIGNAL;
+		break;
+
+	case LINUX_SIGEV_NONE:
+		nsep->sigev_notify = SIGEV_NONE;
+		break;
+
+	case LINUX_SIGEV_THREAD:
+	case LINUX_SIGEV_THREAD_ID:
+	default:
+		return ENOTSUP;
+	}
+
+	nsep->sigev_value = lsep->sigev_value;
+	if (lsep->sigev_signo < 0 || lsep->sigev_signo >= LINUX__NSIG) {
+		return EINVAL;
+	}
+	nsep->sigev_signo = linux_to_native_signo[lsep->sigev_signo];
+
+	return 0;
+}
+
+int
+linux_sigevent_copyin(const void *src, void *dst, size_t size)
+{
+	struct linux_sigevent lse;
+	struct sigevent *sep = dst;
+	int error;
+
+	KASSERT(size == sizeof(*sep));
+
+	error = copyin(src, &lse, sizeof(lse));
+	if (error) {
+		return error;
+	}
+
+	return linux_to_native_sigevent(sep, &lse);
+}

Index: src/sys/compat/linux/common/linux_time.c
diff -u src/sys/compat/linux/common/linux_time.c:1.39 src/sys/compat/linux/common/linux_time.c:1.39.16.1
--- src/sys/compat/linux/common/linux_time.c:1.39	Sat Jul 29 02:31:22 2017
+++ src/sys/compat/linux/common/linux_time.c	Tue Dec 15 14:07:21 2020
@@ -1,11 +1,11 @@
-/*	$NetBSD: linux_time.c,v 1.39 2017/07/29 02:31:22 riastradh Exp $ */
+/*	$NetBSD: linux_time.c,v 1.39.16.1 2020/12/15 14:07:21 thorpej Exp $ */
 
 /*-
- * Copyright (c) 2001 The NetBSD Foundation, Inc.
+ * Copyright (c) 2001, 2020 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
  * This code is derived from software contributed to The NetBSD Foundation
- * by Emmanuel Dreyfus.
+ * by Emmanuel Dreyfus, and by Jason R. Thorpe.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: linux_time.c,v 1.39 2017/07/29 02:31:22 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: linux_time.c,v 1.39.16.1 2020/12/15 14:07:21 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,7 +47,10 @@ __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>
 #include <compat/linux/common/linux_sched.h>
 #include <compat/linux/common/linux_ipc.h>
@@ -56,6 +60,8 @@ __KERNEL_RCSID(0, "$NetBSD: linux_time.c
 
 #include <compat/common/compat_util.h>
 
+CTASSERT(LINUX_TIMER_ABSTIME == TIMER_ABSTIME);
+
 /*
  * Linux keeps track of a system timezone in the kernel. It is readen
  * by gettimeofday and set by settimeofday. This emulates this behavior
@@ -115,19 +121,35 @@ linux_sys_settimeofday(struct lwp *l, co
 }
 
 void
-native_to_linux_timespec(struct linux_timespec *ltp, struct timespec *ntp)
+native_to_linux_timespec(struct linux_timespec *ltp, const struct timespec *ntp)
 {
 	ltp->tv_sec = ntp->tv_sec;
 	ltp->tv_nsec = ntp->tv_nsec;
 }
 
 void
-linux_to_native_timespec(struct timespec *ntp, struct linux_timespec *ltp)
+linux_to_native_timespec(struct timespec *ntp, const struct linux_timespec *ltp)
 {
 	ntp->tv_sec = ltp->tv_sec;
 	ntp->tv_nsec = ltp->tv_nsec;
 }
 
+void
+native_to_linux_itimerspec(struct linux_itimerspec *litp,
+    const struct itimerspec *nitp)
+{
+	native_to_linux_timespec(&litp->it_interval, &nitp->it_interval);
+	native_to_linux_timespec(&litp->it_value, &nitp->it_value);
+}
+
+void
+linux_to_native_itimerspec(struct itimerspec *nitp,
+    const struct linux_itimerspec *litp)
+{
+	linux_to_native_timespec(&nitp->it_interval, &litp->it_interval);
+	linux_to_native_timespec(&nitp->it_value, &litp->it_value);
+}
+
 int
 linux_sys_nanosleep(struct lwp *l, const struct linux_sys_nanosleep_args *uap,
     register_t *retval)
@@ -166,11 +188,20 @@ linux_to_native_clockid(clockid_t *n, cl
 		*n = CLOCK_MONOTONIC;
 		break;
 	case LINUX_CLOCK_PROCESS_CPUTIME_ID:
+		*n = CLOCK_PROCESS_CPUTIME_ID /* self */;
+		break;
 	case LINUX_CLOCK_THREAD_CPUTIME_ID:
-	case LINUX_CLOCK_REALTIME_HR:
-	case LINUX_CLOCK_MONOTONIC_HR:
+		*n = CLOCK_THREAD_CPUTIME_ID /* self */;
+		break;
+
+	case LINUX_CLOCK_MONOTONIC_RAW:
+	case LINUX_CLOCK_REALTIME_COARSE:
+	case LINUX_CLOCK_MONOTONIC_COARSE:
+	case LINUX_CLOCK_BOOTTIME:
+	case LINUX_CLOCK_BOOTTIME_ALARM:
+	case LINUX_CLOCK_REALTIME_ALARM:
 	default:
-		return EINVAL;
+		return ENOTSUP;
 	}
 
 	return 0;
@@ -260,10 +291,12 @@ linux_sys_clock_nanosleep(struct lwp *l,
 	} */
 	struct linux_timespec lrqts, lrmts;
 	struct timespec rqts, rmts;
-	int error, error1, flags;
+	int error, error1;
 	clockid_t nwhich;
 
-	flags = SCARG(uap, flags) != 0 ? TIMER_ABSTIME : 0;
+	if (SCARG(uap, flags) & ~TIMER_ABSTIME) {
+		return EINVAL;
+	}
 
 	error = linux_to_native_clockid(&nwhich, SCARG(uap, which));
 	if (error != 0)
@@ -275,7 +308,7 @@ linux_sys_clock_nanosleep(struct lwp *l,
 
 	linux_to_native_timespec(&rqts, &lrqts);
 
-	error = nanosleep1(l, nwhich, flags, &rqts,
+	error = nanosleep1(l, nwhich, SCARG(uap, flags), &rqts,
 	    SCARG(uap, rmtp) ? &rmts : NULL);
 	if (SCARG(uap, rmtp) == NULL || (error != 0 && error != EINTR))
 		return error;
@@ -284,3 +317,241 @@ linux_sys_clock_nanosleep(struct lwp *l,
 	error1 = copyout(&lrmts, SCARG(uap, rmtp), sizeof lrmts);
 	return error1 ? error1 : error;
 }
+
+int
+linux_sys_timer_create(struct lwp *l,
+    const struct linux_sys_timer_create_args *uap, register_t *retval)
+{
+	/* {
+		syscallarg(clockid_t) clockid;
+		syscallarg(struct linux_sigevent *) evp;
+		syscallarg(timer_t *) timerid;
+	} */
+	clockid_t id;
+	int error;
+
+	error = linux_to_native_clockid(&id, SCARG(uap, clockid));
+	if (error == 0) {
+		/*
+		 * We can't create a timer with every sort of clock ID
+		 * that the system understands, so filter them out.
+		 *
+		 * Map CLOCK_PROCESS_CPUTIME_ID to CLOCK_VIRTUAL.
+		 * We can't handle CLOCK_THREAD_CPUTIME_ID.
+		 */
+		switch (id) {
+		case CLOCK_REALTIME:
+		case CLOCK_MONOTONIC:
+			break;
+
+		case CLOCK_PROCESS_CPUTIME_ID:
+			id = CLOCK_VIRTUAL;
+			break;
+
+		default:
+			return ENOTSUP;
+		}
+		error = timer_create1(SCARG(uap, timerid), id,
+		    (void *)SCARG(uap, evp), linux_sigevent_copyin, l);
+	}
+
+	return error;
+}
+
+int
+linux_sys_timer_settime(struct lwp *l,
+    const struct linux_sys_timer_settime_args *uap, register_t *retval)
+{
+	/* {
+		syscallarg(timer_t) timerid;
+		syscallarg(int) flags;
+		syscallarg(const struct linux_itimerspec *) tim;
+		syscallarg(struct linux_itimerspec *) otim;
+	} */
+	struct itimerspec value, ovalue, *ovp = NULL;
+	struct linux_itimerspec tim, otim;
+	int error;
+
+	error = copyin(SCARG(uap, tim), &tim, sizeof(tim));
+	if (error) {
+		return error;
+	}
+	linux_to_native_itimerspec(&value, &tim);
+
+	if (SCARG(uap, otim)) {
+		ovp = &ovalue;
+	}
+
+	if (SCARG(uap, flags) & ~TIMER_ABSTIME) {
+		return EINVAL;
+	}
+
+	error = dotimer_settime(SCARG(uap, timerid), &value, ovp,
+	    SCARG(uap, flags), l->l_proc);
+	if (error) {
+		return error;
+	}
+
+	if (ovp) {
+		native_to_linux_itimerspec(&otim, ovp);
+		error = copyout(&otim, SCARG(uap, otim), sizeof(otim));
+	}
+
+	return error;
+}
+
+int
+linux_sys_timer_gettime(struct lwp *l,
+    const struct linux_sys_timer_gettime_args *uap, register_t *retval)
+{
+	/* {
+		syscallarg(timer_t) timerid;
+		syscallarg(struct linux_itimerspec *) tim;
+	} */
+	struct itimerspec its;
+	struct linux_itimerspec lits;
+	int error;
+
+	error = dotimer_gettime(SCARG(uap, timerid), l->l_proc, &its);
+	if (error == 0) {
+		native_to_linux_itimerspec(&lits, &its);
+		error = copyout(&lits, SCARG(uap, tim), sizeof(lits));
+	}
+
+	return error;
+}
+
+/*
+ * 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 *) curr_value;
+	} */
+	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, curr_value), sizeof(lits));
+	}
+
+	return error;
+}
+
+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 *) new_value;
+		syscallarg(struct linux_itimerspec *) old_value;
+	} */
+	struct itimerspec nits, oits, *oitsp = NULL;
+	struct linux_itimerspec lits;
+	int nflags = 0;
+	int error;
+
+	error = copyin(SCARG(uap, new_value), &lits, sizeof(lits));
+	if (error) {
+		return error;
+	}
+	linux_to_native_itimerspec(&nits, &lits);
+
+	if (SCARG(uap, flags) & ~(LINUX_TFD_TIMER_ABSTIME |
+				  LINUX_TFD_TIMER_CANCEL_ON_SET)) {
+		return EINVAL;
+	}
+	if (SCARG(uap, flags) & LINUX_TFD_TIMER_ABSTIME) {
+		nflags |= TFD_TIMER_ABSTIME;
+	}
+	if (SCARG(uap, flags) & LINUX_TFD_TIMER_CANCEL_ON_SET) {
+		nflags |= TFD_TIMER_CANCEL_ON_SET;
+	}
+
+	if (SCARG(uap, old_value)) {
+		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, old_value), 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);
+}

Reply via email to