Module Name:    src
Committed By:   thorpej
Date:           Sun Sep 19 23:01:50 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_sched.h linux_time.c
        src/sys/compat/linux32/arch/amd64: syscalls.master
        src/sys/compat/linux32/common: linux32_sched.h linux32_time.c

Log Message:
Add the POSIX timer syscalls (timer_create(), timer_settime(), timer_gettime(),
timer_getoverrun(), and timer_delete()) to COMPAT_LINUX and COMPAT_LINUX32.


To generate a diff of this commit:
cvs rdiff -u -r1.97 -r1.98 src/sys/compat/linux/arch/alpha/syscalls.master
cvs rdiff -u -r1.62 -r1.63 src/sys/compat/linux/arch/amd64/syscalls.master
cvs rdiff -u -r1.69 -r1.70 src/sys/compat/linux/arch/arm/syscalls.master
cvs rdiff -u -r1.124 -r1.125 src/sys/compat/linux/arch/i386/syscalls.master
cvs rdiff -u -r1.95 -r1.96 src/sys/compat/linux/arch/m68k/syscalls.master
cvs rdiff -u -r1.68 -r1.69 src/sys/compat/linux/arch/mips/syscalls.master
cvs rdiff -u -r1.74 -r1.75 src/sys/compat/linux/arch/powerpc/syscalls.master
cvs rdiff -u -r1.8 -r1.9 src/sys/compat/linux/common/linux_sched.h
cvs rdiff -u -r1.40 -r1.41 src/sys/compat/linux/common/linux_time.c
cvs rdiff -u -r1.71 -r1.72 src/sys/compat/linux32/arch/amd64/syscalls.master
cvs rdiff -u -r1.2 -r1.3 src/sys/compat/linux32/common/linux32_sched.h
cvs rdiff -u -r1.38 -r1.39 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.97 src/sys/compat/linux/arch/alpha/syscalls.master:1.98
--- 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	Sun Sep 19 23:01:49 2021
@@ -1,4 +1,4 @@
-	$NetBSD: syscalls.master,v 1.97 2020/04/26 18:53:32 thorpej Exp $
+	$NetBSD: syscalls.master,v 1.98 2021/09/19 23:01:49 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, \

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.63
--- 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	Sun Sep 19 23:01:49 2021
@@ -1,4 +1,4 @@
-	$NetBSD: syscalls.master,v 1.62 2020/04/26 18:53:32 thorpej Exp $
+	$NetBSD: syscalls.master,v 1.63 2021/09/19 23:01:49 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, \

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.70
--- 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	Sun Sep 19 23:01:49 2021
@@ -1,4 +1,4 @@
-	$NetBSD: syscalls.master,v 1.69 2020/04/26 18:53:32 thorpej Exp $
+	$NetBSD: syscalls.master,v 1.70 2021/09/19 23:01:49 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, \

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.125
--- 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	Sun Sep 19 23:01:50 2021
@@ -1,4 +1,4 @@
-	$NetBSD: syscalls.master,v 1.124 2020/04/26 18:53:32 thorpej Exp $
+	$NetBSD: syscalls.master,v 1.125 2021/09/19 23:01:50 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, \

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.96
--- 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	Sun Sep 19 23:01:50 2021
@@ -1,4 +1,4 @@
-	$NetBSD: syscalls.master,v 1.95 2020/04/26 18:53:32 thorpej Exp $
+	$NetBSD: syscalls.master,v 1.96 2021/09/19 23:01:50 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, \

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.69
--- 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	Sun Sep 19 23:01:50 2021
@@ -1,4 +1,4 @@
-	$NetBSD: syscalls.master,v 1.68 2020/04/26 18:53:32 thorpej Exp $  
+	$NetBSD: syscalls.master,v 1.69 2021/09/19 23:01:50 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, \

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.75
--- 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	Sun Sep 19 23:01:50 2021
@@ -1,4 +1,4 @@
-	$NetBSD: syscalls.master,v 1.74 2020/04/26 18:53:32 thorpej Exp $  
+	$NetBSD: syscalls.master,v 1.75 2021/09/19 23:01:50 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, \

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.9
--- 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	Sun Sep 19 23:01:50 2021
@@ -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.9 2021/09/19 23:01:50 thorpej Exp $	*/
 
 /*-
  * Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -74,15 +74,36 @@ 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
+#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 *);
 
-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 *);
+int	linux_to_native_timer_create_clockid(clockid_t *, clockid_t);
 
 #endif /* _LINUX_SCHED_H */

Index: src/sys/compat/linux/common/linux_time.c
diff -u src/sys/compat/linux/common/linux_time.c:1.40 src/sys/compat/linux/common/linux_time.c:1.41
--- src/sys/compat/linux/common/linux_time.c:1.40	Tue Sep  7 11:43:04 2021
+++ src/sys/compat/linux/common/linux_time.c	Sun Sep 19 23:01:50 2021
@@ -1,11 +1,11 @@
-/*	$NetBSD: linux_time.c,v 1.40 2021/09/07 11:43:04 riastradh Exp $ */
+/*	$NetBSD: linux_time.c,v 1.41 2021/09/19 23:01:50 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.40 2021/09/07 11:43:04 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: linux_time.c,v 1.41 2021/09/19 23:01:50 thorpej Exp $");
 
 #include <sys/param.h>
 #include <sys/ucred.h>
@@ -47,6 +47,7 @@ __KERNEL_RCSID(0, "$NetBSD: linux_time.c
 
 #include <compat/linux/common/linux_types.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 +57,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,7 +118,7 @@ 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)
 {
 	memset(ltp, 0, sizeof(*ltp));
 	ltp->tv_sec = ntp->tv_sec;
@@ -123,13 +126,31 @@ native_to_linux_timespec(struct linux_ti
 }
 
 void
-linux_to_native_timespec(struct timespec *ntp, struct linux_timespec *ltp)
+linux_to_native_timespec(struct timespec *ntp, const struct linux_timespec *ltp)
 {
 	memset(ntp, 0, sizeof(*ntp));
 	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)
+{
+	memset(litp, 0, sizeof(*litp));
+	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)
+{
+	memset(nitp, 0, sizeof(*nitp));
+	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)
@@ -168,11 +189,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;
@@ -265,7 +295,10 @@ linux_sys_clock_nanosleep(struct lwp *l,
 	int error, error1, flags;
 	clockid_t nwhich;
 
-	flags = SCARG(uap, flags) != 0 ? TIMER_ABSTIME : 0;
+	flags = SCARG(uap, flags);
+	if (flags & ~TIMER_ABSTIME) {
+		return EINVAL;
+	}
 
 	error = linux_to_native_clockid(&nwhich, SCARG(uap, which));
 	if (error != 0)
@@ -286,3 +319,125 @@ linux_sys_clock_nanosleep(struct lwp *l,
 	error1 = copyout(&lrmts, SCARG(uap, rmtp), sizeof lrmts);
 	return error1 ? error1 : error;
 }
+
+int
+linux_to_native_timer_create_clockid(clockid_t *nid, clockid_t lid)
+{
+	clockid_t id;
+	int error;
+
+	error = linux_to_native_clockid(&id, lid);
+	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;
+		}
+		*nid = id;
+	}
+
+	return 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_timer_create_clockid(&id, SCARG(uap, clockid));
+	if (error == 0) {
+		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.
+ */

Index: src/sys/compat/linux32/arch/amd64/syscalls.master
diff -u src/sys/compat/linux32/arch/amd64/syscalls.master:1.71 src/sys/compat/linux32/arch/amd64/syscalls.master:1.72
--- src/sys/compat/linux32/arch/amd64/syscalls.master:1.71	Sun Apr 26 18:53:33 2020
+++ src/sys/compat/linux32/arch/amd64/syscalls.master	Sun Sep 19 23:01:50 2021
@@ -1,4 +1,4 @@
-	$NetBSD: syscalls.master,v 1.71 2020/04/26 18:53:33 thorpej Exp $
+	$NetBSD: syscalls.master,v 1.72 2021/09/19 23:01:50 thorpej Exp $
 
 ; NetBSD i386 COMPAT_LINUX32 system call name/number "master" file.
 ; (See syscalls.conf to see what it is processed into.)
@@ -454,11 +454,15 @@
 256	UNIMPL	epoll_wait
 257	UNIMPL	remap_file_pages
 258	STD	{ int|linux32_sys||set_tid_address(linux32_intp_t tid); }
-259	UNIMPL	timer_create
-260	UNIMPL	timer_settime
-261	UNIMPL	timer_gettime
-262	UNIMPL	timer_getoverrun
-263	UNIMPL	timer_delete
+259	STD	{ int|linux32_sys||timer_create(clockid_t clockid, \
+		    struct linux32_sigevent *evp, timer_t *timerid); }
+260	STD	{ int|linux32_sys||timer_settime(timer_t timerid, \
+		    int flags, const struct linux32_itimerspec *tim, \
+		    struct linux32_itimerspec *otim); }
+261	STD	{ int|linux32_sys||timer_gettime(timer_t timerid, \
+		    struct linux32_itimerspec *tim); }
+262	NOARGS	{ int|sys||timer_getoverrun(timer_t timerid); }
+263	NOARGS	{ int|sys||timer_delete(timer_t timerid); }
 264	STD	{ int|linux32_sys||clock_settime(clockid_t which, \
 		    linux32_timespecp_t tp); }
 265	STD	{ int|linux32_sys||clock_gettime(clockid_t which, \

Index: src/sys/compat/linux32/common/linux32_sched.h
diff -u src/sys/compat/linux32/common/linux32_sched.h:1.2 src/sys/compat/linux32/common/linux32_sched.h:1.3
--- src/sys/compat/linux32/common/linux32_sched.h:1.2	Sun Sep 19 22:09:31 2021
+++ src/sys/compat/linux32/common/linux32_sched.h	Sun Sep 19 23:01:50 2021
@@ -1,4 +1,4 @@
-/*	$NetBSD: linux32_sched.h,v 1.2 2021/09/19 22:09:31 thorpej Exp $	*/
+/*	$NetBSD: linux32_sched.h,v 1.3 2021/09/19 23:01:50 thorpej Exp $	*/
 
 /*-
  * Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -42,8 +42,19 @@ struct linux32_timespec {
 	int		tv_nsec;	/* nanoseconds */
 };
 
-int linux32_to_native_clockid(clockid_t *, clockid_t);
-void native_to_linux32_timespec(struct linux32_timespec *, struct timespec *);
-void linux32_to_native_timespec(struct timespec *, struct linux32_timespec *);
+struct linux32_itimerspec {
+	struct linux32_timespec it_interval;
+	struct linux32_timespec it_value;
+};
+
+void	native_to_linux32_timespec(struct linux32_timespec *,
+	    const struct timespec *);
+void	linux32_to_native_timespec(struct timespec *,
+	    const struct linux32_timespec *);
+
+void	native_to_linux32_itimerspec(struct linux32_itimerspec *,
+	    const struct itimerspec *);
+void	linux32_to_native_itimerspec(struct itimerspec *,
+	    const struct linux32_itimerspec *);
 
 #endif /* _LINUX32_SCHED_H */

Index: src/sys/compat/linux32/common/linux32_time.c
diff -u src/sys/compat/linux32/common/linux32_time.c:1.38 src/sys/compat/linux32/common/linux32_time.c:1.39
--- src/sys/compat/linux32/common/linux32_time.c:1.38	Tue Sep  7 11:43:04 2021
+++ src/sys/compat/linux32/common/linux32_time.c	Sun Sep 19 23:01:50 2021
@@ -1,4 +1,4 @@
-/*	$NetBSD: linux32_time.c,v 1.38 2021/09/07 11:43:04 riastradh Exp $ */
+/*	$NetBSD: linux32_time.c,v 1.39 2021/09/19 23:01:50 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.38 2021/09/07 11:43:04 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: linux32_time.c,v 1.39 2021/09/19 23:01:50 thorpej Exp $");
 
 #include <sys/types.h>
 #include <sys/param.h>
@@ -77,10 +77,9 @@ __KERNEL_RCSID(0, "$NetBSD: linux32_time
 #include <compat/linux32/common/linux32_sched.h>
 #include <compat/linux32/linux32_syscallargs.h>
 
-extern struct timezone linux_sys_tz;
+CTASSERT(LINUX_TIMER_ABSTIME == TIMER_ABSTIME);
 
-void native_to_linux32_timespec(struct linux32_timespec *, struct timespec *);
-void linux32_to_native_timespec(struct timespec *, struct linux32_timespec *);
+extern struct timezone linux_sys_tz;
 
 int
 linux32_sys_gettimeofday(struct lwp *l, const struct linux32_sys_gettimeofday_args *uap, register_t *retval)
@@ -237,7 +236,8 @@ linux32_sys_utime(struct lwp *l, const s
 }
 
 void
-native_to_linux32_timespec(struct linux32_timespec *ltp, struct timespec *ntp)
+native_to_linux32_timespec(struct linux32_timespec *ltp,
+    const struct timespec *ntp)
 {
 
 	memset(ltp, 0, sizeof(*ltp));
@@ -246,7 +246,8 @@ native_to_linux32_timespec(struct linux3
 }
 
 void
-linux32_to_native_timespec(struct timespec *ntp, struct linux32_timespec *ltp)
+linux32_to_native_timespec(struct timespec *ntp,
+    const struct linux32_timespec *ltp)
 {
 
 	memset(ntp, 0, sizeof(*ntp));
@@ -254,6 +255,24 @@ linux32_to_native_timespec(struct timesp
 	ntp->tv_nsec = ltp->tv_nsec;
 }
 
+void
+native_to_linux32_itimerspec(struct linux32_itimerspec *litp,
+    const struct itimerspec *nitp)
+{
+	memset(litp, 0, sizeof(*litp));
+	native_to_linux32_timespec(&litp->it_interval, &nitp->it_interval);
+	native_to_linux32_timespec(&litp->it_value, &nitp->it_value);
+}
+
+void
+linux32_to_native_itimerspec(struct itimerspec *nitp,
+    const struct linux32_itimerspec *litp)
+{
+	memset(nitp, 0, sizeof(*nitp));
+	linux32_to_native_timespec(&nitp->it_interval, &litp->it_interval);
+	linux32_to_native_timespec(&nitp->it_value, &litp->it_value);
+}
+
 int
 linux32_sys_nanosleep(struct lwp *l,
     const struct linux32_sys_nanosleep_args *uap, register_t *retval)
@@ -390,3 +409,92 @@ linux32_sys_clock_nanosleep(struct lwp *
 	error1 = copyout(&lrmts, SCARG_P32(uap, rmtp), sizeof lrmts);
 	return error1 ? error1 : error;
 }
+
+int
+linux32_sys_timer_create(struct lwp *l,
+    const struct linux32_sys_timer_create_args *uap, register_t *retval)
+{
+	/* {
+		syscallarg(clockid_t) clockid;
+		syscallarg(struct linux32_sigevent *) evp;
+		syscallarg(timer_t *) timerid;
+	} */
+	clockid_t id;
+	int error;
+
+	error = linux_to_native_timer_create_clockid(&id, SCARG(uap, clockid));
+	if (error == 0) {
+		error = timer_create1(SCARG(uap, timerid), id,
+		    (void *)SCARG(uap, evp), linux32_sigevent_copyin, l);
+	}
+
+	return error;
+}
+
+int
+linux32_sys_timer_settime(struct lwp *l,
+    const struct linux32_sys_timer_settime_args *uap, register_t *retval)
+{
+	/* {
+		syscallarg(timer_t) timerid;
+		syscallarg(int) flags;
+		syscallarg(const struct linux32_itimerspec *) tim;
+		syscallarg(struct linux32_itimerspec *) otim;
+	} */
+	struct itimerspec value, ovalue, *ovp = NULL;
+	struct linux32_itimerspec tim, otim;
+	int error;
+
+	error = copyin(SCARG(uap, tim), &tim, sizeof(tim));
+	if (error) {
+		return error;
+	}
+	linux32_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_linux32_itimerspec(&otim, ovp);
+		error = copyout(&otim, SCARG(uap, otim), sizeof(otim));
+	}
+
+	return error;
+}
+
+int
+linux32_sys_timer_gettime(struct lwp *l,
+    const struct linux32_sys_timer_gettime_args *uap, register_t *retval)
+{
+	/* {
+		syscallarg(timer_t) timerid;
+		syscallarg(struct linux32_itimerspec *) tim;
+	} */
+	struct itimerspec its;
+	struct linux32_itimerspec lits;
+	int error;
+
+	error = dotimer_gettime(SCARG(uap, timerid), l->l_proc, &its);
+	if (error == 0) {
+		native_to_linux32_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.
+ */

Reply via email to