1ad2056f2SAlexander Leidinger /* $NetBSD: linux_time.c,v 1.14 2006/05/14 03:40:54 christos Exp $ */ 2ad2056f2SAlexander Leidinger 3ad2056f2SAlexander Leidinger /*- 47f2d13d6SPedro F. Giffuni * SPDX-License-Identifier: BSD-2-Clause-NetBSD 57f2d13d6SPedro F. Giffuni * 6ad2056f2SAlexander Leidinger * Copyright (c) 2001 The NetBSD Foundation, Inc. 7ad2056f2SAlexander Leidinger * All rights reserved. 8ad2056f2SAlexander Leidinger * 9ad2056f2SAlexander Leidinger * This code is derived from software contributed to The NetBSD Foundation 10ad2056f2SAlexander Leidinger * by Emmanuel Dreyfus. 11ad2056f2SAlexander Leidinger * 12ad2056f2SAlexander Leidinger * Redistribution and use in source and binary forms, with or without 13ad2056f2SAlexander Leidinger * modification, are permitted provided that the following conditions 14ad2056f2SAlexander Leidinger * are met: 15ad2056f2SAlexander Leidinger * 1. Redistributions of source code must retain the above copyright 16ad2056f2SAlexander Leidinger * notice, this list of conditions and the following disclaimer. 17ad2056f2SAlexander Leidinger * 2. Redistributions in binary form must reproduce the above copyright 18ad2056f2SAlexander Leidinger * notice, this list of conditions and the following disclaimer in the 19ad2056f2SAlexander Leidinger * documentation and/or other materials provided with the distribution. 20ad2056f2SAlexander Leidinger * 21ad2056f2SAlexander Leidinger * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 22ad2056f2SAlexander Leidinger * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 23ad2056f2SAlexander Leidinger * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 24ad2056f2SAlexander Leidinger * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 25ad2056f2SAlexander Leidinger * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26ad2056f2SAlexander Leidinger * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27ad2056f2SAlexander Leidinger * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28ad2056f2SAlexander Leidinger * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 29ad2056f2SAlexander Leidinger * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30ad2056f2SAlexander Leidinger * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31ad2056f2SAlexander Leidinger * POSSIBILITY OF SUCH DAMAGE. 32ad2056f2SAlexander Leidinger */ 33ad2056f2SAlexander Leidinger 34ad2056f2SAlexander Leidinger #include <sys/cdefs.h> 35ad2056f2SAlexander Leidinger __FBSDID("$FreeBSD$"); 36ad2056f2SAlexander Leidinger #if 0 37ad2056f2SAlexander Leidinger __KERNEL_RCSID(0, "$NetBSD: linux_time.c,v 1.14 2006/05/14 03:40:54 christos Exp $"); 38ad2056f2SAlexander Leidinger #endif 39ad2056f2SAlexander Leidinger 40ad2056f2SAlexander Leidinger #include "opt_compat.h" 41ad2056f2SAlexander Leidinger 42ad2056f2SAlexander Leidinger #include <sys/param.h> 4319e252baSAlexander Leidinger #include <sys/kernel.h> 442711aba9SDmitry Chagin #include <sys/lock.h> 45ad2056f2SAlexander Leidinger #include <sys/ucred.h> 460670e972SDmitry Chagin #include <sys/limits.h> 47ad2056f2SAlexander Leidinger #include <sys/mount.h> 482711aba9SDmitry Chagin #include <sys/mutex.h> 492711aba9SDmitry Chagin #include <sys/resourcevar.h> 5019e252baSAlexander Leidinger #include <sys/sdt.h> 51ad2056f2SAlexander Leidinger #include <sys/signal.h> 52ad2056f2SAlexander Leidinger #include <sys/stdint.h> 53ad2056f2SAlexander Leidinger #include <sys/syscallsubr.h> 54ad2056f2SAlexander Leidinger #include <sys/sysproto.h> 55ad2056f2SAlexander Leidinger #include <sys/time.h> 56ad2056f2SAlexander Leidinger #include <sys/systm.h> 57ad2056f2SAlexander Leidinger #include <sys/proc.h> 58ad2056f2SAlexander Leidinger 59ad2056f2SAlexander Leidinger #ifdef COMPAT_LINUX32 60ad2056f2SAlexander Leidinger #include <machine/../linux32/linux.h> 61ad2056f2SAlexander Leidinger #include <machine/../linux32/linux32_proto.h> 62ad2056f2SAlexander Leidinger #else 63ad2056f2SAlexander Leidinger #include <machine/../linux/linux.h> 64ad2056f2SAlexander Leidinger #include <machine/../linux/linux_proto.h> 65ad2056f2SAlexander Leidinger #endif 66ad2056f2SAlexander Leidinger 6719e252baSAlexander Leidinger #include <compat/linux/linux_dtrace.h> 687bc05ae6SDmitry Chagin #include <compat/linux/linux_misc.h> 692711aba9SDmitry Chagin #include <compat/linux/linux_timer.h> 704afe4faeSEdward Tomasz Napierala #include <compat/linux/linux_util.h> 7119e252baSAlexander Leidinger 7219e252baSAlexander Leidinger /* DTrace init */ 7319e252baSAlexander Leidinger LIN_SDT_PROVIDER_DECLARE(LINUX_DTRACE); 7419e252baSAlexander Leidinger 7519e252baSAlexander Leidinger /** 7619e252baSAlexander Leidinger * DTrace probes in this module. 7719e252baSAlexander Leidinger */ 7819e252baSAlexander Leidinger LIN_SDT_PROBE_DEFINE1(time, linux_to_native_clockid, unsupported_clockid, 7919e252baSAlexander Leidinger "clockid_t"); 8019e252baSAlexander Leidinger LIN_SDT_PROBE_DEFINE1(time, linux_to_native_clockid, unknown_clockid, 8119e252baSAlexander Leidinger "clockid_t"); 8299b6f430SDmitry Chagin LIN_SDT_PROBE_DEFINE1(time, linux_common_clock_gettime, conversion_error, "int"); 8319e252baSAlexander Leidinger LIN_SDT_PROBE_DEFINE1(time, linux_clock_gettime, gettime_error, "int"); 8419e252baSAlexander Leidinger LIN_SDT_PROBE_DEFINE1(time, linux_clock_gettime, copyout_error, "int"); 8599b6f430SDmitry Chagin #if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32)) 8699b6f430SDmitry Chagin LIN_SDT_PROBE_DEFINE1(time, linux_clock_gettime64, gettime_error, "int"); 8799b6f430SDmitry Chagin LIN_SDT_PROBE_DEFINE1(time, linux_clock_gettime64, copyout_error, "int"); 8899b6f430SDmitry Chagin #endif 8919e252baSAlexander Leidinger LIN_SDT_PROBE_DEFINE1(time, linux_clock_settime, conversion_error, "int"); 9019f9a0e4SDmitry Chagin LIN_SDT_PROBE_DEFINE1(time, linux_common_clock_settime, settime_error, "int"); 9119f9a0e4SDmitry Chagin LIN_SDT_PROBE_DEFINE1(time, linux_common_clock_settime, conversion_error, "int"); 9219e252baSAlexander Leidinger LIN_SDT_PROBE_DEFINE1(time, linux_clock_settime, copyin_error, "int"); 9319f9a0e4SDmitry Chagin #if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32)) 9419f9a0e4SDmitry Chagin LIN_SDT_PROBE_DEFINE1(time, linux_clock_settime64, conversion_error, "int"); 9519f9a0e4SDmitry Chagin LIN_SDT_PROBE_DEFINE1(time, linux_clock_settime64, copyin_error, "int"); 9619f9a0e4SDmitry Chagin #endif 97*187715a4SDmitry Chagin LIN_SDT_PROBE_DEFINE0(time, linux_common_clock_getres, nullcall); 98*187715a4SDmitry Chagin LIN_SDT_PROBE_DEFINE1(time, linux_common_clock_getres, conversion_error, "int"); 99*187715a4SDmitry Chagin LIN_SDT_PROBE_DEFINE1(time, linux_common_clock_getres, getres_error, "int"); 10019e252baSAlexander Leidinger LIN_SDT_PROBE_DEFINE1(time, linux_clock_getres, copyout_error, "int"); 101*187715a4SDmitry Chagin #if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32)) 102*187715a4SDmitry Chagin LIN_SDT_PROBE_DEFINE1(time, linux_clock_getres_time64, copyout_error, "int"); 103*187715a4SDmitry Chagin #endif 10419e252baSAlexander Leidinger LIN_SDT_PROBE_DEFINE1(time, linux_nanosleep, conversion_error, "int"); 10519e252baSAlexander Leidinger LIN_SDT_PROBE_DEFINE1(time, linux_nanosleep, copyout_error, "int"); 10619e252baSAlexander Leidinger LIN_SDT_PROBE_DEFINE1(time, linux_nanosleep, copyin_error, "int"); 10719e252baSAlexander Leidinger LIN_SDT_PROBE_DEFINE1(time, linux_clock_nanosleep, conversion_error, "int"); 10819e252baSAlexander Leidinger LIN_SDT_PROBE_DEFINE1(time, linux_clock_nanosleep, copyout_error, "int"); 10919e252baSAlexander Leidinger LIN_SDT_PROBE_DEFINE1(time, linux_clock_nanosleep, copyin_error, "int"); 11019e252baSAlexander Leidinger LIN_SDT_PROBE_DEFINE1(time, linux_clock_nanosleep, unsupported_flags, "int"); 11119e252baSAlexander Leidinger LIN_SDT_PROBE_DEFINE1(time, linux_clock_nanosleep, unsupported_clockid, "int"); 11219e252baSAlexander Leidinger 11399b6f430SDmitry Chagin static int linux_common_clock_gettime(struct thread *, clockid_t, 11499b6f430SDmitry Chagin struct timespec *); 11519f9a0e4SDmitry Chagin static int linux_common_clock_settime(struct thread *, clockid_t, 11619f9a0e4SDmitry Chagin struct timespec *); 117*187715a4SDmitry Chagin static int linux_common_clock_getres(struct thread *, clockid_t, 118*187715a4SDmitry Chagin struct timespec *); 11999b6f430SDmitry Chagin 1200670e972SDmitry Chagin int 121ad2056f2SAlexander Leidinger native_to_linux_timespec(struct l_timespec *ltp, struct timespec *ntp) 122ad2056f2SAlexander Leidinger { 12319e252baSAlexander Leidinger 1240670e972SDmitry Chagin #ifdef COMPAT_LINUX32 12571b50d08SDmitry Chagin if (ntp->tv_sec > INT_MAX || ntp->tv_sec < INT_MIN) 1260670e972SDmitry Chagin return (EOVERFLOW); 1270670e972SDmitry Chagin #endif 128ad2056f2SAlexander Leidinger ltp->tv_sec = ntp->tv_sec; 129ad2056f2SAlexander Leidinger ltp->tv_nsec = ntp->tv_nsec; 13019e252baSAlexander Leidinger 1310670e972SDmitry Chagin return (0); 132ad2056f2SAlexander Leidinger } 133ad2056f2SAlexander Leidinger 13468098228SDmitry Chagin int 135ad2056f2SAlexander Leidinger linux_to_native_timespec(struct timespec *ntp, struct l_timespec *ltp) 136ad2056f2SAlexander Leidinger { 13719e252baSAlexander Leidinger 1385e8caee2SEdward Tomasz Napierala if (ltp->tv_sec < 0 || ltp->tv_nsec < 0 || ltp->tv_nsec > 999999999) 13977424f41SJung-uk Kim return (EINVAL); 140ad2056f2SAlexander Leidinger ntp->tv_sec = ltp->tv_sec; 141ad2056f2SAlexander Leidinger ntp->tv_nsec = ltp->tv_nsec; 14277424f41SJung-uk Kim 14377424f41SJung-uk Kim return (0); 144ad2056f2SAlexander Leidinger } 145ad2056f2SAlexander Leidinger 146bfcce1a9SDmitry Chagin #if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32)) 147bfcce1a9SDmitry Chagin int 148bfcce1a9SDmitry Chagin native_to_linux_timespec64(struct l_timespec64 *ltp64, struct timespec *ntp) 149bfcce1a9SDmitry Chagin { 150bfcce1a9SDmitry Chagin 151bfcce1a9SDmitry Chagin ltp64->tv_sec = ntp->tv_sec; 152bfcce1a9SDmitry Chagin ltp64->tv_nsec = ntp->tv_nsec; 153bfcce1a9SDmitry Chagin 154bfcce1a9SDmitry Chagin return (0); 155bfcce1a9SDmitry Chagin } 156bfcce1a9SDmitry Chagin 157bfcce1a9SDmitry Chagin int 158bfcce1a9SDmitry Chagin linux_to_native_timespec64(struct timespec *ntp, struct l_timespec64 *ltp64) 159bfcce1a9SDmitry Chagin { 160bfcce1a9SDmitry Chagin 161bfcce1a9SDmitry Chagin if (ltp64->tv_sec < 0 || ltp64->tv_nsec < 0 || ltp64->tv_nsec > 999999999) 162bfcce1a9SDmitry Chagin return (EINVAL); 163bfcce1a9SDmitry Chagin ntp->tv_sec = ltp64->tv_sec; 164bfcce1a9SDmitry Chagin ntp->tv_nsec = ltp64->tv_nsec; 165bfcce1a9SDmitry Chagin 166bfcce1a9SDmitry Chagin return (0); 167bfcce1a9SDmitry Chagin } 168bfcce1a9SDmitry Chagin #endif 169bfcce1a9SDmitry Chagin 17016ac71bcSDmitry Chagin int 171dd93b628SDmitry Chagin native_to_linux_itimerspec(struct l_itimerspec *ltp, struct itimerspec *ntp) 172dd93b628SDmitry Chagin { 173dd93b628SDmitry Chagin int error; 174dd93b628SDmitry Chagin 175dd93b628SDmitry Chagin error = native_to_linux_timespec(<p->it_interval, &ntp->it_interval); 176dd93b628SDmitry Chagin if (error == 0) 177dd93b628SDmitry Chagin error = native_to_linux_timespec(<p->it_value, &ntp->it_interval); 178dd93b628SDmitry Chagin return (error); 179dd93b628SDmitry Chagin } 180dd93b628SDmitry Chagin 181dd93b628SDmitry Chagin int 182dd93b628SDmitry Chagin linux_to_native_itimerspec(struct itimerspec *ntp, struct l_itimerspec *ltp) 183dd93b628SDmitry Chagin { 184dd93b628SDmitry Chagin int error; 185dd93b628SDmitry Chagin 186dd93b628SDmitry Chagin error = linux_to_native_timespec(&ntp->it_interval, <p->it_interval); 187dd93b628SDmitry Chagin if (error == 0) 188dd93b628SDmitry Chagin error = linux_to_native_timespec(&ntp->it_value, <p->it_value); 189dd93b628SDmitry Chagin return (error); 190dd93b628SDmitry Chagin } 191dd93b628SDmitry Chagin 192dd93b628SDmitry Chagin int 193ad2056f2SAlexander Leidinger linux_to_native_clockid(clockid_t *n, clockid_t l) 194ad2056f2SAlexander Leidinger { 19519e252baSAlexander Leidinger 1962711aba9SDmitry Chagin if (l < 0) { 1972711aba9SDmitry Chagin /* cpu-clock */ 1982711aba9SDmitry Chagin if ((l & LINUX_CLOCKFD_MASK) == LINUX_CLOCKFD) 1992711aba9SDmitry Chagin return (EINVAL); 2002711aba9SDmitry Chagin if (LINUX_CPUCLOCK_WHICH(l) >= LINUX_CPUCLOCK_MAX) 2012711aba9SDmitry Chagin return (EINVAL); 2022711aba9SDmitry Chagin 2032711aba9SDmitry Chagin if (LINUX_CPUCLOCK_PERTHREAD(l)) 2042711aba9SDmitry Chagin *n = CLOCK_THREAD_CPUTIME_ID; 2052711aba9SDmitry Chagin else 2062711aba9SDmitry Chagin *n = CLOCK_PROCESS_CPUTIME_ID; 2072711aba9SDmitry Chagin return (0); 2082711aba9SDmitry Chagin } 2092711aba9SDmitry Chagin 210ad2056f2SAlexander Leidinger switch (l) { 211ad2056f2SAlexander Leidinger case LINUX_CLOCK_REALTIME: 212ad2056f2SAlexander Leidinger *n = CLOCK_REALTIME; 213ad2056f2SAlexander Leidinger break; 214ad2056f2SAlexander Leidinger case LINUX_CLOCK_MONOTONIC: 215ad2056f2SAlexander Leidinger *n = CLOCK_MONOTONIC; 216ad2056f2SAlexander Leidinger break; 2177bc05ae6SDmitry Chagin case LINUX_CLOCK_PROCESS_CPUTIME_ID: 2187bc05ae6SDmitry Chagin *n = CLOCK_PROCESS_CPUTIME_ID; 2197bc05ae6SDmitry Chagin break; 2207bc05ae6SDmitry Chagin case LINUX_CLOCK_THREAD_CPUTIME_ID: 2217bc05ae6SDmitry Chagin *n = CLOCK_THREAD_CPUTIME_ID; 2227bc05ae6SDmitry Chagin break; 2232711aba9SDmitry Chagin case LINUX_CLOCK_REALTIME_COARSE: 2242711aba9SDmitry Chagin *n = CLOCK_REALTIME_FAST; 2252711aba9SDmitry Chagin break; 2262711aba9SDmitry Chagin case LINUX_CLOCK_MONOTONIC_COARSE: 227e37db348SAlexander Leidinger case LINUX_CLOCK_MONOTONIC_RAW: 2282711aba9SDmitry Chagin *n = CLOCK_MONOTONIC_FAST; 2292711aba9SDmitry Chagin break; 2302711aba9SDmitry Chagin case LINUX_CLOCK_BOOTTIME: 23125ada637SDmitry Chagin *n = CLOCK_UPTIME; 23225ada637SDmitry Chagin break; 2332711aba9SDmitry Chagin case LINUX_CLOCK_REALTIME_ALARM: 2342711aba9SDmitry Chagin case LINUX_CLOCK_BOOTTIME_ALARM: 2352711aba9SDmitry Chagin case LINUX_CLOCK_SGI_CYCLE: 2362711aba9SDmitry Chagin case LINUX_CLOCK_TAI: 23719e252baSAlexander Leidinger LIN_SDT_PROBE1(time, linux_to_native_clockid, 23819e252baSAlexander Leidinger unsupported_clockid, l); 23919e252baSAlexander Leidinger return (EINVAL); 24077424f41SJung-uk Kim default: 24119e252baSAlexander Leidinger LIN_SDT_PROBE1(time, linux_to_native_clockid, 24219e252baSAlexander Leidinger unknown_clockid, l); 24377424f41SJung-uk Kim return (EINVAL); 244ad2056f2SAlexander Leidinger } 245ad2056f2SAlexander Leidinger 24677424f41SJung-uk Kim return (0); 247ad2056f2SAlexander Leidinger } 248ad2056f2SAlexander Leidinger 249ad2056f2SAlexander Leidinger int 250f0f58384SDmitry Chagin linux_to_native_timerflags(int *nflags, int flags) 251f0f58384SDmitry Chagin { 252f0f58384SDmitry Chagin 253f0f58384SDmitry Chagin if (flags & ~LINUX_TIMER_ABSTIME) 254f0f58384SDmitry Chagin return (EINVAL); 255f0f58384SDmitry Chagin *nflags = 0; 256f0f58384SDmitry Chagin if (flags & LINUX_TIMER_ABSTIME) 257f0f58384SDmitry Chagin *nflags |= TIMER_ABSTIME; 258f0f58384SDmitry Chagin return (0); 259f0f58384SDmitry Chagin } 260f0f58384SDmitry Chagin 26199b6f430SDmitry Chagin static int 26299b6f430SDmitry Chagin linux_common_clock_gettime(struct thread *td, clockid_t which, 26399b6f430SDmitry Chagin struct timespec *tp) 264ad2056f2SAlexander Leidinger { 2652711aba9SDmitry Chagin struct rusage ru; 2662711aba9SDmitry Chagin struct thread *targettd; 2672711aba9SDmitry Chagin struct proc *p; 2682711aba9SDmitry Chagin int error, clockwhich; 2692506c761SDmitry Chagin clockid_t nwhich; 2702711aba9SDmitry Chagin pid_t pid; 2712711aba9SDmitry Chagin lwpid_t tid; 272ad2056f2SAlexander Leidinger 27399b6f430SDmitry Chagin error = linux_to_native_clockid(&nwhich, which); 27419e252baSAlexander Leidinger if (error != 0) { 2754afe4faeSEdward Tomasz Napierala linux_msg(curthread, 27699b6f430SDmitry Chagin "unsupported clock_gettime clockid %d", which); 27799b6f430SDmitry Chagin LIN_SDT_PROBE1(time, linux_common_clock_gettime, 27899b6f430SDmitry Chagin conversion_error, error); 27977424f41SJung-uk Kim return (error); 28019e252baSAlexander Leidinger } 2812711aba9SDmitry Chagin 2822711aba9SDmitry Chagin switch (nwhich) { 2832711aba9SDmitry Chagin case CLOCK_PROCESS_CPUTIME_ID: 28499b6f430SDmitry Chagin if (which < 0) { 28599b6f430SDmitry Chagin clockwhich = LINUX_CPUCLOCK_WHICH(which); 28699b6f430SDmitry Chagin pid = LINUX_CPUCLOCK_ID(which); 2877bc05ae6SDmitry Chagin } else { 2887bc05ae6SDmitry Chagin clockwhich = LINUX_CPUCLOCK_SCHED; 2897bc05ae6SDmitry Chagin pid = 0; 2907bc05ae6SDmitry Chagin } 2912711aba9SDmitry Chagin if (pid == 0) { 2922711aba9SDmitry Chagin p = td->td_proc; 2932711aba9SDmitry Chagin PROC_LOCK(p); 2942711aba9SDmitry Chagin } else { 2952711aba9SDmitry Chagin error = pget(pid, PGET_CANSEE, &p); 2962711aba9SDmitry Chagin if (error != 0) 2972711aba9SDmitry Chagin return (EINVAL); 2982711aba9SDmitry Chagin } 2992711aba9SDmitry Chagin switch (clockwhich) { 3002711aba9SDmitry Chagin case LINUX_CPUCLOCK_PROF: 3012711aba9SDmitry Chagin PROC_STATLOCK(p); 3022711aba9SDmitry Chagin calcru(p, &ru.ru_utime, &ru.ru_stime); 3032711aba9SDmitry Chagin PROC_STATUNLOCK(p); 3042711aba9SDmitry Chagin PROC_UNLOCK(p); 3052711aba9SDmitry Chagin timevaladd(&ru.ru_utime, &ru.ru_stime); 30699b6f430SDmitry Chagin TIMEVAL_TO_TIMESPEC(&ru.ru_utime, tp); 3072711aba9SDmitry Chagin break; 3082711aba9SDmitry Chagin case LINUX_CPUCLOCK_VIRT: 3092711aba9SDmitry Chagin PROC_STATLOCK(p); 3102711aba9SDmitry Chagin calcru(p, &ru.ru_utime, &ru.ru_stime); 3112711aba9SDmitry Chagin PROC_STATUNLOCK(p); 3122711aba9SDmitry Chagin PROC_UNLOCK(p); 31399b6f430SDmitry Chagin TIMEVAL_TO_TIMESPEC(&ru.ru_utime, tp); 3142711aba9SDmitry Chagin break; 3152711aba9SDmitry Chagin case LINUX_CPUCLOCK_SCHED: 31699b6f430SDmitry Chagin kern_process_cputime(p, tp); 3172711aba9SDmitry Chagin PROC_UNLOCK(p); 3182711aba9SDmitry Chagin break; 3192711aba9SDmitry Chagin default: 3202711aba9SDmitry Chagin PROC_UNLOCK(p); 3212711aba9SDmitry Chagin return (EINVAL); 3222711aba9SDmitry Chagin } 3232711aba9SDmitry Chagin 3242711aba9SDmitry Chagin break; 3252711aba9SDmitry Chagin 3262711aba9SDmitry Chagin case CLOCK_THREAD_CPUTIME_ID: 32799b6f430SDmitry Chagin if (which < 0) { 32899b6f430SDmitry Chagin clockwhich = LINUX_CPUCLOCK_WHICH(which); 32999b6f430SDmitry Chagin tid = LINUX_CPUCLOCK_ID(which); 3307bc05ae6SDmitry Chagin } else { 3317bc05ae6SDmitry Chagin clockwhich = LINUX_CPUCLOCK_SCHED; 3327bc05ae6SDmitry Chagin tid = 0; 3337bc05ae6SDmitry Chagin } 3347bc05ae6SDmitry Chagin p = td->td_proc; 3352711aba9SDmitry Chagin if (tid == 0) { 3362711aba9SDmitry Chagin targettd = td; 3372711aba9SDmitry Chagin PROC_LOCK(p); 3382711aba9SDmitry Chagin } else { 3397bc05ae6SDmitry Chagin targettd = linux_tdfind(td, tid, p->p_pid); 3402711aba9SDmitry Chagin if (targettd == NULL) 3412711aba9SDmitry Chagin return (EINVAL); 3422711aba9SDmitry Chagin } 3432711aba9SDmitry Chagin switch (clockwhich) { 3442711aba9SDmitry Chagin case LINUX_CPUCLOCK_PROF: 3452711aba9SDmitry Chagin PROC_STATLOCK(p); 3462711aba9SDmitry Chagin thread_lock(targettd); 3472711aba9SDmitry Chagin rufetchtd(targettd, &ru); 3482711aba9SDmitry Chagin thread_unlock(targettd); 3492711aba9SDmitry Chagin PROC_STATUNLOCK(p); 3502711aba9SDmitry Chagin PROC_UNLOCK(p); 3512711aba9SDmitry Chagin timevaladd(&ru.ru_utime, &ru.ru_stime); 35299b6f430SDmitry Chagin TIMEVAL_TO_TIMESPEC(&ru.ru_utime, tp); 3532711aba9SDmitry Chagin break; 3542711aba9SDmitry Chagin case LINUX_CPUCLOCK_VIRT: 3552711aba9SDmitry Chagin PROC_STATLOCK(p); 3562711aba9SDmitry Chagin thread_lock(targettd); 3572711aba9SDmitry Chagin rufetchtd(targettd, &ru); 3582711aba9SDmitry Chagin thread_unlock(targettd); 3592711aba9SDmitry Chagin PROC_STATUNLOCK(p); 3602711aba9SDmitry Chagin PROC_UNLOCK(p); 36199b6f430SDmitry Chagin TIMEVAL_TO_TIMESPEC(&ru.ru_utime, tp); 3622711aba9SDmitry Chagin break; 3632711aba9SDmitry Chagin case LINUX_CPUCLOCK_SCHED: 3647bc05ae6SDmitry Chagin if (td == targettd) 3657bc05ae6SDmitry Chagin targettd = NULL; 36699b6f430SDmitry Chagin kern_thread_cputime(targettd, tp); 3672711aba9SDmitry Chagin PROC_UNLOCK(p); 3682711aba9SDmitry Chagin break; 3692711aba9SDmitry Chagin default: 3702711aba9SDmitry Chagin PROC_UNLOCK(p); 3712711aba9SDmitry Chagin return (EINVAL); 3722711aba9SDmitry Chagin } 3732711aba9SDmitry Chagin break; 3742711aba9SDmitry Chagin 3752711aba9SDmitry Chagin default: 37699b6f430SDmitry Chagin error = kern_clock_gettime(td, nwhich, tp); 3772711aba9SDmitry Chagin break; 3782711aba9SDmitry Chagin } 37999b6f430SDmitry Chagin 38099b6f430SDmitry Chagin return (error); 38199b6f430SDmitry Chagin } 38299b6f430SDmitry Chagin 38399b6f430SDmitry Chagin int 38499b6f430SDmitry Chagin linux_clock_gettime(struct thread *td, struct linux_clock_gettime_args *args) 38599b6f430SDmitry Chagin { 38699b6f430SDmitry Chagin struct l_timespec lts; 38799b6f430SDmitry Chagin struct timespec tp; 38899b6f430SDmitry Chagin int error; 38999b6f430SDmitry Chagin 39099b6f430SDmitry Chagin error = linux_common_clock_gettime(td, args->which, &tp); 39119e252baSAlexander Leidinger if (error != 0) { 39219e252baSAlexander Leidinger LIN_SDT_PROBE1(time, linux_clock_gettime, gettime_error, error); 39377424f41SJung-uk Kim return (error); 39419e252baSAlexander Leidinger } 3950670e972SDmitry Chagin error = native_to_linux_timespec(<s, &tp); 3960670e972SDmitry Chagin if (error != 0) 3970670e972SDmitry Chagin return (error); 39899b6f430SDmitry Chagin error = copyout(<s, args->tp, sizeof(lts)); 39919e252baSAlexander Leidinger if (error != 0) 40019e252baSAlexander Leidinger LIN_SDT_PROBE1(time, linux_clock_gettime, copyout_error, error); 40119e252baSAlexander Leidinger 40219e252baSAlexander Leidinger return (error); 403ad2056f2SAlexander Leidinger } 404ad2056f2SAlexander Leidinger 40599b6f430SDmitry Chagin #if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32)) 40699b6f430SDmitry Chagin int 40799b6f430SDmitry Chagin linux_clock_gettime64(struct thread *td, struct linux_clock_gettime64_args *args) 40899b6f430SDmitry Chagin { 40999b6f430SDmitry Chagin struct l_timespec64 lts; 41099b6f430SDmitry Chagin struct timespec tp; 41199b6f430SDmitry Chagin int error; 41299b6f430SDmitry Chagin 41399b6f430SDmitry Chagin error = linux_common_clock_gettime(td, args->which, &tp); 41499b6f430SDmitry Chagin if (error != 0) { 41599b6f430SDmitry Chagin LIN_SDT_PROBE1(time, linux_clock_gettime64, gettime_error, error); 41699b6f430SDmitry Chagin return (error); 41799b6f430SDmitry Chagin } 41899b6f430SDmitry Chagin error = native_to_linux_timespec64(<s, &tp); 41999b6f430SDmitry Chagin if (error != 0) 42099b6f430SDmitry Chagin return (error); 42199b6f430SDmitry Chagin error = copyout(<s, args->tp, sizeof(lts)); 42299b6f430SDmitry Chagin if (error != 0) 42399b6f430SDmitry Chagin LIN_SDT_PROBE1(time, linux_clock_gettime64, copyout_error, error); 42499b6f430SDmitry Chagin 42599b6f430SDmitry Chagin return (error); 42699b6f430SDmitry Chagin } 42799b6f430SDmitry Chagin #endif 42899b6f430SDmitry Chagin 42919f9a0e4SDmitry Chagin static int 43019f9a0e4SDmitry Chagin linux_common_clock_settime(struct thread *td, clockid_t which, 43119f9a0e4SDmitry Chagin struct timespec *ts) 43219f9a0e4SDmitry Chagin { 43319f9a0e4SDmitry Chagin int error; 43419f9a0e4SDmitry Chagin clockid_t nwhich; 43519f9a0e4SDmitry Chagin 43619f9a0e4SDmitry Chagin error = linux_to_native_clockid(&nwhich, which); 43719f9a0e4SDmitry Chagin if (error != 0) { 43819f9a0e4SDmitry Chagin linux_msg(curthread, 43919f9a0e4SDmitry Chagin "unsupported clock_settime clockid %d", which); 44019f9a0e4SDmitry Chagin LIN_SDT_PROBE1(time, linux_common_clock_settime, conversion_error, 44119f9a0e4SDmitry Chagin error); 44219f9a0e4SDmitry Chagin return (error); 44319f9a0e4SDmitry Chagin } 44419f9a0e4SDmitry Chagin 44519f9a0e4SDmitry Chagin error = kern_clock_settime(td, nwhich, ts); 44619f9a0e4SDmitry Chagin if (error != 0) 44719f9a0e4SDmitry Chagin LIN_SDT_PROBE1(time, linux_common_clock_settime, 44819f9a0e4SDmitry Chagin settime_error, error); 44919f9a0e4SDmitry Chagin 45019f9a0e4SDmitry Chagin return (error); 45119f9a0e4SDmitry Chagin } 45219f9a0e4SDmitry Chagin 453ad2056f2SAlexander Leidinger int 454ad2056f2SAlexander Leidinger linux_clock_settime(struct thread *td, struct linux_clock_settime_args *args) 455ad2056f2SAlexander Leidinger { 456ad2056f2SAlexander Leidinger struct timespec ts; 457ad2056f2SAlexander Leidinger struct l_timespec lts; 458ad2056f2SAlexander Leidinger int error; 459ad2056f2SAlexander Leidinger 46019f9a0e4SDmitry Chagin error = copyin(args->tp, <s, sizeof(lts)); 46119e252baSAlexander Leidinger if (error != 0) { 46219e252baSAlexander Leidinger LIN_SDT_PROBE1(time, linux_clock_settime, copyin_error, error); 46319e252baSAlexander Leidinger return (error); 46419e252baSAlexander Leidinger } 46519e252baSAlexander Leidinger error = linux_to_native_timespec(&ts, <s); 46619f9a0e4SDmitry Chagin if (error != 0) 46719e252baSAlexander Leidinger LIN_SDT_PROBE1(time, linux_clock_settime, conversion_error, 46819e252baSAlexander Leidinger error); 46919f9a0e4SDmitry Chagin 47019f9a0e4SDmitry Chagin return (linux_common_clock_settime(td, args->which, &ts)); 47119e252baSAlexander Leidinger } 47219e252baSAlexander Leidinger 47319f9a0e4SDmitry Chagin #if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32)) 47419f9a0e4SDmitry Chagin int 47519f9a0e4SDmitry Chagin linux_clock_settime64(struct thread *td, struct linux_clock_settime64_args *args) 47619f9a0e4SDmitry Chagin { 47719f9a0e4SDmitry Chagin struct timespec ts; 47819f9a0e4SDmitry Chagin struct l_timespec64 lts; 47919f9a0e4SDmitry Chagin int error; 48019f9a0e4SDmitry Chagin 48119f9a0e4SDmitry Chagin error = copyin(args->tp, <s, sizeof(lts)); 48219f9a0e4SDmitry Chagin if (error != 0) { 48319f9a0e4SDmitry Chagin LIN_SDT_PROBE1(time, linux_clock_settime64, copyin_error, error); 48419f9a0e4SDmitry Chagin return (error); 48519f9a0e4SDmitry Chagin } 48619f9a0e4SDmitry Chagin error = linux_to_native_timespec64(&ts, <s); 48719e252baSAlexander Leidinger if (error != 0) 48819f9a0e4SDmitry Chagin LIN_SDT_PROBE1(time, linux_clock_settime64, conversion_error, 48919f9a0e4SDmitry Chagin error); 49019f9a0e4SDmitry Chagin return (linux_common_clock_settime(td, args->which, &ts)); 491ad2056f2SAlexander Leidinger } 49219f9a0e4SDmitry Chagin #endif 493ad2056f2SAlexander Leidinger 494*187715a4SDmitry Chagin static int 495*187715a4SDmitry Chagin linux_common_clock_getres(struct thread *td, clockid_t which, 496*187715a4SDmitry Chagin struct timespec *ts) 497ad2056f2SAlexander Leidinger { 4982711aba9SDmitry Chagin struct proc *p; 4992711aba9SDmitry Chagin int error, clockwhich; 5002506c761SDmitry Chagin clockid_t nwhich; 5012711aba9SDmitry Chagin pid_t pid; 5022711aba9SDmitry Chagin lwpid_t tid; 503ad2056f2SAlexander Leidinger 504*187715a4SDmitry Chagin error = linux_to_native_clockid(&nwhich, which); 50519e252baSAlexander Leidinger if (error != 0) { 5064afe4faeSEdward Tomasz Napierala linux_msg(curthread, 507*187715a4SDmitry Chagin "unsupported clock_getres clockid %d", which); 508*187715a4SDmitry Chagin LIN_SDT_PROBE1(time, linux_common_clock_getres, 509*187715a4SDmitry Chagin conversion_error, error); 51077424f41SJung-uk Kim return (error); 51119e252baSAlexander Leidinger } 5122711aba9SDmitry Chagin 5132711aba9SDmitry Chagin /* 5142711aba9SDmitry Chagin * Check user supplied clock id in case of per-process 5152711aba9SDmitry Chagin * or thread-specific cpu-time clock. 5162711aba9SDmitry Chagin */ 517*187715a4SDmitry Chagin if (which < 0) { 5182711aba9SDmitry Chagin switch (nwhich) { 5192711aba9SDmitry Chagin case CLOCK_THREAD_CPUTIME_ID: 520*187715a4SDmitry Chagin tid = LINUX_CPUCLOCK_ID(which); 5212711aba9SDmitry Chagin if (tid != 0) { 5222711aba9SDmitry Chagin p = td->td_proc; 5237bc05ae6SDmitry Chagin if (linux_tdfind(td, tid, p->p_pid) == NULL) 5247bc05ae6SDmitry Chagin return (EINVAL); 5252711aba9SDmitry Chagin PROC_UNLOCK(p); 5262711aba9SDmitry Chagin } 5272711aba9SDmitry Chagin break; 5282711aba9SDmitry Chagin case CLOCK_PROCESS_CPUTIME_ID: 529*187715a4SDmitry Chagin pid = LINUX_CPUCLOCK_ID(which); 5302711aba9SDmitry Chagin if (pid != 0) { 5312711aba9SDmitry Chagin error = pget(pid, PGET_CANSEE, &p); 5322711aba9SDmitry Chagin if (error != 0) 5332711aba9SDmitry Chagin return (EINVAL); 5342711aba9SDmitry Chagin PROC_UNLOCK(p); 5352711aba9SDmitry Chagin } 5362711aba9SDmitry Chagin break; 5372711aba9SDmitry Chagin } 5387bc05ae6SDmitry Chagin } 5392711aba9SDmitry Chagin 540*187715a4SDmitry Chagin if (ts == NULL) { 541*187715a4SDmitry Chagin LIN_SDT_PROBE0(time, linux_common_clock_getres, nullcall); 5422711aba9SDmitry Chagin return (0); 5432711aba9SDmitry Chagin } 5442711aba9SDmitry Chagin 5452711aba9SDmitry Chagin switch (nwhich) { 5462711aba9SDmitry Chagin case CLOCK_THREAD_CPUTIME_ID: 5472711aba9SDmitry Chagin case CLOCK_PROCESS_CPUTIME_ID: 548*187715a4SDmitry Chagin clockwhich = LINUX_CPUCLOCK_WHICH(which); 5497bc05ae6SDmitry Chagin /* 5507bc05ae6SDmitry Chagin * In both cases (when the clock id obtained by a call to 5517bc05ae6SDmitry Chagin * clock_getcpuclockid() or using the clock 5527bc05ae6SDmitry Chagin * ID CLOCK_PROCESS_CPUTIME_ID Linux hardcodes precision 5537bc05ae6SDmitry Chagin * of clock. The same for the CLOCK_THREAD_CPUTIME_ID clock. 5547bc05ae6SDmitry Chagin * 5557bc05ae6SDmitry Chagin * See Linux posix_cpu_clock_getres() implementation. 5567bc05ae6SDmitry Chagin */ 557*187715a4SDmitry Chagin if (which > 0 || clockwhich == LINUX_CPUCLOCK_SCHED) { 558*187715a4SDmitry Chagin ts->tv_sec = 0; 559*187715a4SDmitry Chagin ts->tv_nsec = 1; 5607bc05ae6SDmitry Chagin goto out; 5617bc05ae6SDmitry Chagin } 5627bc05ae6SDmitry Chagin 5632711aba9SDmitry Chagin switch (clockwhich) { 5642711aba9SDmitry Chagin case LINUX_CPUCLOCK_PROF: 5652711aba9SDmitry Chagin nwhich = CLOCK_PROF; 5662711aba9SDmitry Chagin break; 5672711aba9SDmitry Chagin case LINUX_CPUCLOCK_VIRT: 5682711aba9SDmitry Chagin nwhich = CLOCK_VIRTUAL; 5692711aba9SDmitry Chagin break; 5702711aba9SDmitry Chagin default: 5712711aba9SDmitry Chagin return (EINVAL); 5722711aba9SDmitry Chagin } 5732711aba9SDmitry Chagin break; 5742711aba9SDmitry Chagin 5752711aba9SDmitry Chagin default: 5762711aba9SDmitry Chagin break; 5772711aba9SDmitry Chagin } 578*187715a4SDmitry Chagin error = kern_clock_getres(td, nwhich, ts); 57919e252baSAlexander Leidinger if (error != 0) { 580*187715a4SDmitry Chagin LIN_SDT_PROBE1(time, linux_common_clock_getres, 581*187715a4SDmitry Chagin getres_error, error); 58277424f41SJung-uk Kim return (error); 58319e252baSAlexander Leidinger } 5847bc05ae6SDmitry Chagin 5857bc05ae6SDmitry Chagin out: 586*187715a4SDmitry Chagin return (error); 587*187715a4SDmitry Chagin } 588*187715a4SDmitry Chagin 589*187715a4SDmitry Chagin int 590*187715a4SDmitry Chagin linux_clock_getres(struct thread *td, 591*187715a4SDmitry Chagin struct linux_clock_getres_args *args) 592*187715a4SDmitry Chagin { 593*187715a4SDmitry Chagin struct timespec ts; 594*187715a4SDmitry Chagin struct l_timespec lts; 595*187715a4SDmitry Chagin int error; 596*187715a4SDmitry Chagin 597*187715a4SDmitry Chagin error = linux_common_clock_getres(td, args->which, &ts); 598*187715a4SDmitry Chagin if (error != 0 || args->tp == NULL) 599*187715a4SDmitry Chagin return (error); 600*187715a4SDmitry Chagin 6010670e972SDmitry Chagin error = native_to_linux_timespec(<s, &ts); 6020670e972SDmitry Chagin if (error != 0) 6030670e972SDmitry Chagin return (error); 604*187715a4SDmitry Chagin error = copyout(<s, args->tp, sizeof(lts)); 60519e252baSAlexander Leidinger if (error != 0) 606*187715a4SDmitry Chagin LIN_SDT_PROBE1(time, linux_clock_getres, 607*187715a4SDmitry Chagin copyout_error, error); 60819e252baSAlexander Leidinger return (error); 60977424f41SJung-uk Kim } 61077424f41SJung-uk Kim 611*187715a4SDmitry Chagin #if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32)) 612*187715a4SDmitry Chagin int 613*187715a4SDmitry Chagin linux_clock_getres_time64(struct thread *td, 614*187715a4SDmitry Chagin struct linux_clock_getres_time64_args *args) 615*187715a4SDmitry Chagin { 616*187715a4SDmitry Chagin struct timespec ts; 617*187715a4SDmitry Chagin struct l_timespec64 lts; 618*187715a4SDmitry Chagin int error; 619*187715a4SDmitry Chagin 620*187715a4SDmitry Chagin error = linux_common_clock_getres(td, args->which, &ts); 621*187715a4SDmitry Chagin if (error != 0 || args->tp == NULL) 622*187715a4SDmitry Chagin return (error); 623*187715a4SDmitry Chagin 624*187715a4SDmitry Chagin error = native_to_linux_timespec64(<s, &ts); 625*187715a4SDmitry Chagin if (error != 0) 626*187715a4SDmitry Chagin return (error); 627*187715a4SDmitry Chagin error = copyout(<s, args->tp, sizeof(lts)); 628*187715a4SDmitry Chagin if (error != 0) 629*187715a4SDmitry Chagin LIN_SDT_PROBE1(time, linux_clock_getres_time64, 630*187715a4SDmitry Chagin copyout_error, error); 631*187715a4SDmitry Chagin return (error); 632*187715a4SDmitry Chagin } 633*187715a4SDmitry Chagin #endif 634*187715a4SDmitry Chagin 63577424f41SJung-uk Kim int 63677424f41SJung-uk Kim linux_nanosleep(struct thread *td, struct linux_nanosleep_args *args) 63777424f41SJung-uk Kim { 63877424f41SJung-uk Kim struct timespec *rmtp; 63977424f41SJung-uk Kim struct l_timespec lrqts, lrmts; 64077424f41SJung-uk Kim struct timespec rqts, rmts; 6415c2748d5SDmitry Chagin int error, error2; 64277424f41SJung-uk Kim 64377424f41SJung-uk Kim error = copyin(args->rqtp, &lrqts, sizeof lrqts); 64419e252baSAlexander Leidinger if (error != 0) { 64519e252baSAlexander Leidinger LIN_SDT_PROBE1(time, linux_nanosleep, copyin_error, error); 64677424f41SJung-uk Kim return (error); 64719e252baSAlexander Leidinger } 64877424f41SJung-uk Kim 64977424f41SJung-uk Kim if (args->rmtp != NULL) 65077424f41SJung-uk Kim rmtp = &rmts; 65177424f41SJung-uk Kim else 65277424f41SJung-uk Kim rmtp = NULL; 65377424f41SJung-uk Kim 65477424f41SJung-uk Kim error = linux_to_native_timespec(&rqts, &lrqts); 65519e252baSAlexander Leidinger if (error != 0) { 65619e252baSAlexander Leidinger LIN_SDT_PROBE1(time, linux_nanosleep, conversion_error, error); 65777424f41SJung-uk Kim return (error); 65819e252baSAlexander Leidinger } 65977424f41SJung-uk Kim error = kern_nanosleep(td, &rqts, rmtp); 6604cf66812SEric van Gyzen if (error == EINTR && args->rmtp != NULL) { 6610670e972SDmitry Chagin error2 = native_to_linux_timespec(&lrmts, rmtp); 6620670e972SDmitry Chagin if (error2 != 0) 6630670e972SDmitry Chagin return (error2); 6645c2748d5SDmitry Chagin error2 = copyout(&lrmts, args->rmtp, sizeof(lrmts)); 6655c2748d5SDmitry Chagin if (error2 != 0) { 66619e252baSAlexander Leidinger LIN_SDT_PROBE1(time, linux_nanosleep, copyout_error, 6675c2748d5SDmitry Chagin error2); 6685c2748d5SDmitry Chagin return (error2); 66977424f41SJung-uk Kim } 67019e252baSAlexander Leidinger } 67177424f41SJung-uk Kim 6725c2748d5SDmitry Chagin return (error); 673ad2056f2SAlexander Leidinger } 674ad2056f2SAlexander Leidinger 675ad2056f2SAlexander Leidinger int 676ad2056f2SAlexander Leidinger linux_clock_nanosleep(struct thread *td, struct linux_clock_nanosleep_args *args) 677ad2056f2SAlexander Leidinger { 678ad2056f2SAlexander Leidinger struct timespec *rmtp; 679ad2056f2SAlexander Leidinger struct l_timespec lrqts, lrmts; 680ad2056f2SAlexander Leidinger struct timespec rqts, rmts; 681f0f58384SDmitry Chagin int error, error2, flags; 682f0f58384SDmitry Chagin clockid_t clockid; 683ad2056f2SAlexander Leidinger 684f0f58384SDmitry Chagin error = linux_to_native_timerflags(&flags, args->flags); 685f0f58384SDmitry Chagin if (error != 0) { 68619e252baSAlexander Leidinger LIN_SDT_PROBE1(time, linux_clock_nanosleep, unsupported_flags, 68719e252baSAlexander Leidinger args->flags); 688f0f58384SDmitry Chagin return (error); 68919e252baSAlexander Leidinger } 69019e252baSAlexander Leidinger 691f0f58384SDmitry Chagin error = linux_to_native_clockid(&clockid, args->which); 692f0f58384SDmitry Chagin if (error != 0) { 6934afe4faeSEdward Tomasz Napierala linux_msg(curthread, 6944afe4faeSEdward Tomasz Napierala "unsupported clock_nanosleep clockid %d", args->which); 69519e252baSAlexander Leidinger LIN_SDT_PROBE1(time, linux_clock_nanosleep, unsupported_clockid, 69619e252baSAlexander Leidinger args->which); 697f0f58384SDmitry Chagin return (error); 69819e252baSAlexander Leidinger } 699ad2056f2SAlexander Leidinger 7005c2748d5SDmitry Chagin error = copyin(args->rqtp, &lrqts, sizeof(lrqts)); 70119e252baSAlexander Leidinger if (error != 0) { 70219e252baSAlexander Leidinger LIN_SDT_PROBE1(time, linux_clock_nanosleep, copyin_error, 70319e252baSAlexander Leidinger error); 70477424f41SJung-uk Kim return (error); 70519e252baSAlexander Leidinger } 706ad2056f2SAlexander Leidinger 707ad2056f2SAlexander Leidinger if (args->rmtp != NULL) 708ad2056f2SAlexander Leidinger rmtp = &rmts; 709ad2056f2SAlexander Leidinger else 710ad2056f2SAlexander Leidinger rmtp = NULL; 711ad2056f2SAlexander Leidinger 71277424f41SJung-uk Kim error = linux_to_native_timespec(&rqts, &lrqts); 71319e252baSAlexander Leidinger if (error != 0) { 71419e252baSAlexander Leidinger LIN_SDT_PROBE1(time, linux_clock_nanosleep, conversion_error, 71519e252baSAlexander Leidinger error); 71677424f41SJung-uk Kim return (error); 71719e252baSAlexander Leidinger } 718f0f58384SDmitry Chagin error = kern_clock_nanosleep(td, clockid, flags, &rqts, rmtp); 719f0f58384SDmitry Chagin if (error == EINTR && (flags & TIMER_ABSTIME) == 0 && 720f0f58384SDmitry Chagin args->rmtp != NULL) { 7210670e972SDmitry Chagin error2 = native_to_linux_timespec(&lrmts, rmtp); 7220670e972SDmitry Chagin if (error2 != 0) 7230670e972SDmitry Chagin return (error2); 7245c2748d5SDmitry Chagin error2 = copyout(&lrmts, args->rmtp, sizeof(lrmts)); 7255c2748d5SDmitry Chagin if (error2 != 0) { 7265c2748d5SDmitry Chagin LIN_SDT_PROBE1(time, linux_clock_nanosleep, 7275c2748d5SDmitry Chagin copyout_error, error2); 7285c2748d5SDmitry Chagin return (error2); 7295c2748d5SDmitry Chagin } 7305c2748d5SDmitry Chagin } 7315c2748d5SDmitry Chagin 73277424f41SJung-uk Kim return (error); 73319e252baSAlexander Leidinger } 734