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