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. + */