xref: /freebsd/sys/compat/linux/linux_time.c (revision 4afe4fae1bc68b7610cbd922cc52a7bb455f988a)
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>
70*4afe4faeSEdward 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_DEFINE2(time, native_to_linux_timespec, entry,
7919e252baSAlexander Leidinger     "struct l_timespec *", "struct timespec *");
8019e252baSAlexander Leidinger LIN_SDT_PROBE_DEFINE0(time, native_to_linux_timespec, return);
8119e252baSAlexander Leidinger LIN_SDT_PROBE_DEFINE2(time, linux_to_native_timespec, entry,
8219e252baSAlexander Leidinger     "struct timespec *", "struct l_timespec *");
8319e252baSAlexander Leidinger LIN_SDT_PROBE_DEFINE1(time, linux_to_native_timespec, return, "int");
8419e252baSAlexander Leidinger LIN_SDT_PROBE_DEFINE2(time, linux_to_native_clockid, entry, "clockid_t *",
8519e252baSAlexander Leidinger     "clockid_t");
8619e252baSAlexander Leidinger LIN_SDT_PROBE_DEFINE1(time, linux_to_native_clockid, unsupported_clockid,
8719e252baSAlexander Leidinger     "clockid_t");
8819e252baSAlexander Leidinger LIN_SDT_PROBE_DEFINE1(time, linux_to_native_clockid, unknown_clockid,
8919e252baSAlexander Leidinger     "clockid_t");
9019e252baSAlexander Leidinger LIN_SDT_PROBE_DEFINE1(time, linux_to_native_clockid, return, "int");
9119e252baSAlexander Leidinger LIN_SDT_PROBE_DEFINE2(time, linux_clock_gettime, entry, "clockid_t",
9219e252baSAlexander Leidinger     "struct l_timespec *");
9319e252baSAlexander Leidinger LIN_SDT_PROBE_DEFINE1(time, linux_clock_gettime, conversion_error, "int");
9419e252baSAlexander Leidinger LIN_SDT_PROBE_DEFINE1(time, linux_clock_gettime, gettime_error, "int");
9519e252baSAlexander Leidinger LIN_SDT_PROBE_DEFINE1(time, linux_clock_gettime, copyout_error, "int");
9619e252baSAlexander Leidinger LIN_SDT_PROBE_DEFINE1(time, linux_clock_gettime, return, "int");
9719e252baSAlexander Leidinger LIN_SDT_PROBE_DEFINE2(time, linux_clock_settime, entry, "clockid_t",
9819e252baSAlexander Leidinger     "struct l_timespec *");
9919e252baSAlexander Leidinger LIN_SDT_PROBE_DEFINE1(time, linux_clock_settime, conversion_error, "int");
10019e252baSAlexander Leidinger LIN_SDT_PROBE_DEFINE1(time, linux_clock_settime, settime_error, "int");
10119e252baSAlexander Leidinger LIN_SDT_PROBE_DEFINE1(time, linux_clock_settime, copyin_error, "int");
10219e252baSAlexander Leidinger LIN_SDT_PROBE_DEFINE1(time, linux_clock_settime, return, "int");
10319e252baSAlexander Leidinger LIN_SDT_PROBE_DEFINE2(time, linux_clock_getres, entry, "clockid_t",
10419e252baSAlexander Leidinger     "struct l_timespec *");
10519e252baSAlexander Leidinger LIN_SDT_PROBE_DEFINE0(time, linux_clock_getres, nullcall);
10619e252baSAlexander Leidinger LIN_SDT_PROBE_DEFINE1(time, linux_clock_getres, conversion_error, "int");
10719e252baSAlexander Leidinger LIN_SDT_PROBE_DEFINE1(time, linux_clock_getres, getres_error, "int");
10819e252baSAlexander Leidinger LIN_SDT_PROBE_DEFINE1(time, linux_clock_getres, copyout_error, "int");
10919e252baSAlexander Leidinger LIN_SDT_PROBE_DEFINE1(time, linux_clock_getres, return, "int");
11019e252baSAlexander Leidinger LIN_SDT_PROBE_DEFINE2(time, linux_nanosleep, entry, "const struct l_timespec *",
11119e252baSAlexander Leidinger     "struct l_timespec *");
11219e252baSAlexander Leidinger LIN_SDT_PROBE_DEFINE1(time, linux_nanosleep, conversion_error, "int");
11319e252baSAlexander Leidinger LIN_SDT_PROBE_DEFINE1(time, linux_nanosleep, copyout_error, "int");
11419e252baSAlexander Leidinger LIN_SDT_PROBE_DEFINE1(time, linux_nanosleep, copyin_error, "int");
11519e252baSAlexander Leidinger LIN_SDT_PROBE_DEFINE1(time, linux_nanosleep, return, "int");
11619e252baSAlexander Leidinger LIN_SDT_PROBE_DEFINE4(time, linux_clock_nanosleep, entry, "clockid_t", "int",
11719e252baSAlexander Leidinger     "struct l_timespec *", "struct l_timespec *");
11819e252baSAlexander Leidinger LIN_SDT_PROBE_DEFINE1(time, linux_clock_nanosleep, conversion_error, "int");
11919e252baSAlexander Leidinger LIN_SDT_PROBE_DEFINE1(time, linux_clock_nanosleep, copyout_error, "int");
12019e252baSAlexander Leidinger LIN_SDT_PROBE_DEFINE1(time, linux_clock_nanosleep, copyin_error, "int");
12119e252baSAlexander Leidinger LIN_SDT_PROBE_DEFINE1(time, linux_clock_nanosleep, unsupported_flags, "int");
12219e252baSAlexander Leidinger LIN_SDT_PROBE_DEFINE1(time, linux_clock_nanosleep, unsupported_clockid, "int");
12319e252baSAlexander Leidinger LIN_SDT_PROBE_DEFINE1(time, linux_clock_nanosleep, return, "int");
12419e252baSAlexander Leidinger 
12568098228SDmitry Chagin 
1260670e972SDmitry Chagin int
127ad2056f2SAlexander Leidinger native_to_linux_timespec(struct l_timespec *ltp, struct timespec *ntp)
128ad2056f2SAlexander Leidinger {
12919e252baSAlexander Leidinger 
13019e252baSAlexander Leidinger 	LIN_SDT_PROBE2(time, native_to_linux_timespec, entry, ltp, ntp);
1310670e972SDmitry Chagin #ifdef COMPAT_LINUX32
13271b50d08SDmitry Chagin 	if (ntp->tv_sec > INT_MAX || ntp->tv_sec < INT_MIN)
1330670e972SDmitry Chagin 		return (EOVERFLOW);
1340670e972SDmitry Chagin #endif
135ad2056f2SAlexander Leidinger 	ltp->tv_sec = ntp->tv_sec;
136ad2056f2SAlexander Leidinger 	ltp->tv_nsec = ntp->tv_nsec;
13719e252baSAlexander Leidinger 
13819e252baSAlexander Leidinger 	LIN_SDT_PROBE0(time, native_to_linux_timespec, return);
1390670e972SDmitry Chagin 	return (0);
140ad2056f2SAlexander Leidinger }
141ad2056f2SAlexander Leidinger 
14268098228SDmitry Chagin int
143ad2056f2SAlexander Leidinger linux_to_native_timespec(struct timespec *ntp, struct l_timespec *ltp)
144ad2056f2SAlexander Leidinger {
14519e252baSAlexander Leidinger 
14619e252baSAlexander Leidinger 	LIN_SDT_PROBE2(time, linux_to_native_timespec, entry, ntp, ltp);
14719e252baSAlexander Leidinger 
1482ac9dcedSDmitry Chagin 	if (ltp->tv_sec < 0 || ltp->tv_nsec < 0 || ltp->tv_nsec > 999999999) {
14919e252baSAlexander Leidinger 		LIN_SDT_PROBE1(time, linux_to_native_timespec, return, EINVAL);
15077424f41SJung-uk Kim 		return (EINVAL);
15119e252baSAlexander Leidinger 	}
152ad2056f2SAlexander Leidinger 	ntp->tv_sec = ltp->tv_sec;
153ad2056f2SAlexander Leidinger 	ntp->tv_nsec = ltp->tv_nsec;
15477424f41SJung-uk Kim 
15519e252baSAlexander Leidinger 	LIN_SDT_PROBE1(time, linux_to_native_timespec, return, 0);
15677424f41SJung-uk Kim 	return (0);
157ad2056f2SAlexander Leidinger }
158ad2056f2SAlexander Leidinger 
15916ac71bcSDmitry Chagin int
160dd93b628SDmitry Chagin native_to_linux_itimerspec(struct l_itimerspec *ltp, struct itimerspec *ntp)
161dd93b628SDmitry Chagin {
162dd93b628SDmitry Chagin 	int error;
163dd93b628SDmitry Chagin 
164dd93b628SDmitry Chagin 	error = native_to_linux_timespec(&ltp->it_interval, &ntp->it_interval);
165dd93b628SDmitry Chagin 	if (error == 0)
166dd93b628SDmitry Chagin 		error = native_to_linux_timespec(&ltp->it_value, &ntp->it_interval);
167dd93b628SDmitry Chagin 	return (error);
168dd93b628SDmitry Chagin }
169dd93b628SDmitry Chagin 
170dd93b628SDmitry Chagin int
171dd93b628SDmitry Chagin linux_to_native_itimerspec(struct itimerspec *ntp, struct l_itimerspec *ltp)
172dd93b628SDmitry Chagin {
173dd93b628SDmitry Chagin 	int error;
174dd93b628SDmitry Chagin 
175dd93b628SDmitry Chagin 	error = linux_to_native_timespec(&ntp->it_interval, &ltp->it_interval);
176dd93b628SDmitry Chagin 	if (error == 0)
177dd93b628SDmitry Chagin 		error = linux_to_native_timespec(&ntp->it_value, &ltp->it_value);
178dd93b628SDmitry Chagin 	return (error);
179dd93b628SDmitry Chagin }
180dd93b628SDmitry Chagin 
181dd93b628SDmitry Chagin int
182ad2056f2SAlexander Leidinger linux_to_native_clockid(clockid_t *n, clockid_t l)
183ad2056f2SAlexander Leidinger {
18419e252baSAlexander Leidinger 
18519e252baSAlexander Leidinger 	LIN_SDT_PROBE2(time, linux_to_native_clockid, entry, n, l);
18619e252baSAlexander Leidinger 
1872711aba9SDmitry Chagin 	if (l < 0) {
1882711aba9SDmitry Chagin 		/* cpu-clock */
1892711aba9SDmitry Chagin 		if ((l & LINUX_CLOCKFD_MASK) == LINUX_CLOCKFD)
1902711aba9SDmitry Chagin 			return (EINVAL);
1912711aba9SDmitry Chagin 		if (LINUX_CPUCLOCK_WHICH(l) >= LINUX_CPUCLOCK_MAX)
1922711aba9SDmitry Chagin 			return (EINVAL);
1932711aba9SDmitry Chagin 
1942711aba9SDmitry Chagin 		if (LINUX_CPUCLOCK_PERTHREAD(l))
1952711aba9SDmitry Chagin 			*n = CLOCK_THREAD_CPUTIME_ID;
1962711aba9SDmitry Chagin 		else
1972711aba9SDmitry Chagin 			*n = CLOCK_PROCESS_CPUTIME_ID;
1982711aba9SDmitry Chagin 		return (0);
1992711aba9SDmitry Chagin 	}
2002711aba9SDmitry Chagin 
201ad2056f2SAlexander Leidinger 	switch (l) {
202ad2056f2SAlexander Leidinger 	case LINUX_CLOCK_REALTIME:
203ad2056f2SAlexander Leidinger 		*n = CLOCK_REALTIME;
204ad2056f2SAlexander Leidinger 		break;
205ad2056f2SAlexander Leidinger 	case LINUX_CLOCK_MONOTONIC:
206ad2056f2SAlexander Leidinger 		*n = CLOCK_MONOTONIC;
207ad2056f2SAlexander Leidinger 		break;
2087bc05ae6SDmitry Chagin 	case LINUX_CLOCK_PROCESS_CPUTIME_ID:
2097bc05ae6SDmitry Chagin 		*n = CLOCK_PROCESS_CPUTIME_ID;
2107bc05ae6SDmitry Chagin 		break;
2117bc05ae6SDmitry Chagin 	case LINUX_CLOCK_THREAD_CPUTIME_ID:
2127bc05ae6SDmitry Chagin 		*n = CLOCK_THREAD_CPUTIME_ID;
2137bc05ae6SDmitry Chagin 		break;
2142711aba9SDmitry Chagin 	case LINUX_CLOCK_REALTIME_COARSE:
2152711aba9SDmitry Chagin 		*n = CLOCK_REALTIME_FAST;
2162711aba9SDmitry Chagin 		break;
2172711aba9SDmitry Chagin 	case LINUX_CLOCK_MONOTONIC_COARSE:
2182711aba9SDmitry Chagin 		*n = CLOCK_MONOTONIC_FAST;
2192711aba9SDmitry Chagin 		break;
2202711aba9SDmitry Chagin 	case LINUX_CLOCK_BOOTTIME:
22125ada637SDmitry Chagin 		*n = CLOCK_UPTIME;
22225ada637SDmitry Chagin 		break;
22325ada637SDmitry Chagin 	case LINUX_CLOCK_MONOTONIC_RAW:
2242711aba9SDmitry Chagin 	case LINUX_CLOCK_REALTIME_ALARM:
2252711aba9SDmitry Chagin 	case LINUX_CLOCK_BOOTTIME_ALARM:
2262711aba9SDmitry Chagin 	case LINUX_CLOCK_SGI_CYCLE:
2272711aba9SDmitry Chagin 	case LINUX_CLOCK_TAI:
22819e252baSAlexander Leidinger 		LIN_SDT_PROBE1(time, linux_to_native_clockid,
22919e252baSAlexander Leidinger 		    unsupported_clockid, l);
23019e252baSAlexander Leidinger 		LIN_SDT_PROBE1(time, linux_to_native_clockid, return, EINVAL);
23119e252baSAlexander Leidinger 		return (EINVAL);
23277424f41SJung-uk Kim 	default:
23319e252baSAlexander Leidinger 		LIN_SDT_PROBE1(time, linux_to_native_clockid,
23419e252baSAlexander Leidinger 		    unknown_clockid, l);
23519e252baSAlexander Leidinger 		LIN_SDT_PROBE1(time, linux_to_native_clockid, return, EINVAL);
23677424f41SJung-uk Kim 		return (EINVAL);
237ad2056f2SAlexander Leidinger 	}
238ad2056f2SAlexander Leidinger 
23919e252baSAlexander Leidinger 	LIN_SDT_PROBE1(time, linux_to_native_clockid, return, 0);
24077424f41SJung-uk Kim 	return (0);
241ad2056f2SAlexander Leidinger }
242ad2056f2SAlexander Leidinger 
243ad2056f2SAlexander Leidinger int
244f0f58384SDmitry Chagin linux_to_native_timerflags(int *nflags, int flags)
245f0f58384SDmitry Chagin {
246f0f58384SDmitry Chagin 
247f0f58384SDmitry Chagin 	if (flags & ~LINUX_TIMER_ABSTIME)
248f0f58384SDmitry Chagin 		return (EINVAL);
249f0f58384SDmitry Chagin 	*nflags = 0;
250f0f58384SDmitry Chagin 	if (flags & LINUX_TIMER_ABSTIME)
251f0f58384SDmitry Chagin 		*nflags |= TIMER_ABSTIME;
252f0f58384SDmitry Chagin 	return (0);
253f0f58384SDmitry Chagin }
254f0f58384SDmitry Chagin 
255f0f58384SDmitry Chagin int
256ad2056f2SAlexander Leidinger linux_clock_gettime(struct thread *td, struct linux_clock_gettime_args *args)
257ad2056f2SAlexander Leidinger {
258ad2056f2SAlexander Leidinger 	struct l_timespec lts;
259ad2056f2SAlexander Leidinger 	struct timespec tp;
2602711aba9SDmitry Chagin 	struct rusage ru;
2612711aba9SDmitry Chagin 	struct thread *targettd;
2622711aba9SDmitry Chagin 	struct proc *p;
2632711aba9SDmitry Chagin 	int error, clockwhich;
2642506c761SDmitry Chagin 	clockid_t nwhich;
2652711aba9SDmitry Chagin 	pid_t pid;
2662711aba9SDmitry Chagin 	lwpid_t tid;
267ad2056f2SAlexander Leidinger 
26819e252baSAlexander Leidinger 	LIN_SDT_PROBE2(time, linux_clock_gettime, entry, args->which, args->tp);
26919e252baSAlexander Leidinger 
270ad2056f2SAlexander Leidinger 	error = linux_to_native_clockid(&nwhich, args->which);
27119e252baSAlexander Leidinger 	if (error != 0) {
272*4afe4faeSEdward Tomasz Napierala 		linux_msg(curthread,
273*4afe4faeSEdward Tomasz Napierala 		    "unsupported clock_gettime clockid %d", args->which);
27419e252baSAlexander Leidinger 		LIN_SDT_PROBE1(time, linux_clock_gettime, conversion_error,
27519e252baSAlexander Leidinger 		    error);
27619e252baSAlexander Leidinger 		LIN_SDT_PROBE1(time, linux_clock_gettime, return, error);
27777424f41SJung-uk Kim 		return (error);
27819e252baSAlexander Leidinger 	}
2792711aba9SDmitry Chagin 
2802711aba9SDmitry Chagin 	switch (nwhich) {
2812711aba9SDmitry Chagin 	case CLOCK_PROCESS_CPUTIME_ID:
2827bc05ae6SDmitry Chagin 		if (args->which < 0) {
2832711aba9SDmitry Chagin 			clockwhich = LINUX_CPUCLOCK_WHICH(args->which);
2842711aba9SDmitry Chagin 			pid = LINUX_CPUCLOCK_ID(args->which);
2857bc05ae6SDmitry Chagin 		} else {
2867bc05ae6SDmitry Chagin 			clockwhich = LINUX_CPUCLOCK_SCHED;
2877bc05ae6SDmitry Chagin 			pid = 0;
2887bc05ae6SDmitry Chagin 		}
2892711aba9SDmitry Chagin 		if (pid == 0) {
2902711aba9SDmitry Chagin 			p = td->td_proc;
2912711aba9SDmitry Chagin 			PROC_LOCK(p);
2922711aba9SDmitry Chagin 		} else {
2932711aba9SDmitry Chagin 			error = pget(pid, PGET_CANSEE, &p);
2942711aba9SDmitry Chagin 			if (error != 0)
2952711aba9SDmitry Chagin 				return (EINVAL);
2962711aba9SDmitry Chagin 		}
2972711aba9SDmitry Chagin 		switch (clockwhich) {
2982711aba9SDmitry Chagin 		case LINUX_CPUCLOCK_PROF:
2992711aba9SDmitry Chagin 			PROC_STATLOCK(p);
3002711aba9SDmitry Chagin 			calcru(p, &ru.ru_utime, &ru.ru_stime);
3012711aba9SDmitry Chagin 			PROC_STATUNLOCK(p);
3022711aba9SDmitry Chagin 			PROC_UNLOCK(p);
3032711aba9SDmitry Chagin 			timevaladd(&ru.ru_utime, &ru.ru_stime);
3042711aba9SDmitry Chagin 			TIMEVAL_TO_TIMESPEC(&ru.ru_utime, &tp);
3052711aba9SDmitry Chagin 			break;
3062711aba9SDmitry Chagin 		case LINUX_CPUCLOCK_VIRT:
3072711aba9SDmitry Chagin 			PROC_STATLOCK(p);
3082711aba9SDmitry Chagin 			calcru(p, &ru.ru_utime, &ru.ru_stime);
3092711aba9SDmitry Chagin 			PROC_STATUNLOCK(p);
3102711aba9SDmitry Chagin 			PROC_UNLOCK(p);
3112711aba9SDmitry Chagin 			TIMEVAL_TO_TIMESPEC(&ru.ru_utime, &tp);
3122711aba9SDmitry Chagin 			break;
3132711aba9SDmitry Chagin 		case LINUX_CPUCLOCK_SCHED:
3147bc05ae6SDmitry Chagin 			kern_process_cputime(p, &tp);
3152711aba9SDmitry Chagin 			PROC_UNLOCK(p);
3162711aba9SDmitry Chagin 			break;
3172711aba9SDmitry Chagin 		default:
3182711aba9SDmitry Chagin 			PROC_UNLOCK(p);
3192711aba9SDmitry Chagin 			return (EINVAL);
3202711aba9SDmitry Chagin 		}
3212711aba9SDmitry Chagin 
3222711aba9SDmitry Chagin 		break;
3232711aba9SDmitry Chagin 
3242711aba9SDmitry Chagin 	case CLOCK_THREAD_CPUTIME_ID:
3257bc05ae6SDmitry Chagin 		if (args->which < 0) {
3262711aba9SDmitry Chagin 			clockwhich = LINUX_CPUCLOCK_WHICH(args->which);
3272711aba9SDmitry Chagin 			tid = LINUX_CPUCLOCK_ID(args->which);
3287bc05ae6SDmitry Chagin 		} else {
3297bc05ae6SDmitry Chagin 			clockwhich = LINUX_CPUCLOCK_SCHED;
3307bc05ae6SDmitry Chagin 			tid = 0;
3317bc05ae6SDmitry Chagin 		}
3327bc05ae6SDmitry Chagin 		p = td->td_proc;
3332711aba9SDmitry Chagin 		if (tid == 0) {
3342711aba9SDmitry Chagin 			targettd = td;
3352711aba9SDmitry Chagin 			PROC_LOCK(p);
3362711aba9SDmitry Chagin 		} else {
3377bc05ae6SDmitry Chagin 			targettd = linux_tdfind(td, tid, p->p_pid);
3382711aba9SDmitry Chagin 			if (targettd == NULL)
3392711aba9SDmitry Chagin 				return (EINVAL);
3402711aba9SDmitry Chagin 		}
3412711aba9SDmitry Chagin 		switch (clockwhich) {
3422711aba9SDmitry Chagin 		case LINUX_CPUCLOCK_PROF:
3432711aba9SDmitry Chagin 			PROC_STATLOCK(p);
3442711aba9SDmitry Chagin 			thread_lock(targettd);
3452711aba9SDmitry Chagin 			rufetchtd(targettd, &ru);
3462711aba9SDmitry Chagin 			thread_unlock(targettd);
3472711aba9SDmitry Chagin 			PROC_STATUNLOCK(p);
3482711aba9SDmitry Chagin 			PROC_UNLOCK(p);
3492711aba9SDmitry Chagin 			timevaladd(&ru.ru_utime, &ru.ru_stime);
3502711aba9SDmitry Chagin 			TIMEVAL_TO_TIMESPEC(&ru.ru_utime, &tp);
3512711aba9SDmitry Chagin 			break;
3522711aba9SDmitry Chagin 		case LINUX_CPUCLOCK_VIRT:
3532711aba9SDmitry Chagin 			PROC_STATLOCK(p);
3542711aba9SDmitry Chagin 			thread_lock(targettd);
3552711aba9SDmitry Chagin 			rufetchtd(targettd, &ru);
3562711aba9SDmitry Chagin 			thread_unlock(targettd);
3572711aba9SDmitry Chagin 			PROC_STATUNLOCK(p);
3582711aba9SDmitry Chagin 			PROC_UNLOCK(p);
3592711aba9SDmitry Chagin 			TIMEVAL_TO_TIMESPEC(&ru.ru_utime, &tp);
3602711aba9SDmitry Chagin 			break;
3612711aba9SDmitry Chagin 		case LINUX_CPUCLOCK_SCHED:
3627bc05ae6SDmitry Chagin 			if (td == targettd)
3637bc05ae6SDmitry Chagin 				targettd = NULL;
3647bc05ae6SDmitry Chagin 			kern_thread_cputime(targettd, &tp);
3652711aba9SDmitry Chagin 			PROC_UNLOCK(p);
3662711aba9SDmitry Chagin 			break;
3672711aba9SDmitry Chagin 		default:
3682711aba9SDmitry Chagin 			PROC_UNLOCK(p);
3692711aba9SDmitry Chagin 			return (EINVAL);
3702711aba9SDmitry Chagin 		}
3712711aba9SDmitry Chagin 		break;
3722711aba9SDmitry Chagin 
3732711aba9SDmitry Chagin 	default:
3742711aba9SDmitry Chagin 		error = kern_clock_gettime(td, nwhich, &tp);
3752711aba9SDmitry Chagin 		break;
3762711aba9SDmitry Chagin 	}
37719e252baSAlexander Leidinger 	if (error != 0) {
37819e252baSAlexander Leidinger 		LIN_SDT_PROBE1(time, linux_clock_gettime, gettime_error, error);
37919e252baSAlexander Leidinger 		LIN_SDT_PROBE1(time, linux_clock_gettime, return, error);
38077424f41SJung-uk Kim 		return (error);
38119e252baSAlexander Leidinger 	}
3820670e972SDmitry Chagin 	error = native_to_linux_timespec(&lts, &tp);
3830670e972SDmitry Chagin 	if (error != 0)
3840670e972SDmitry Chagin 		return (error);
38519e252baSAlexander Leidinger 	error = copyout(&lts, args->tp, sizeof lts);
38619e252baSAlexander Leidinger 	if (error != 0)
38719e252baSAlexander Leidinger 		LIN_SDT_PROBE1(time, linux_clock_gettime, copyout_error, error);
38819e252baSAlexander Leidinger 
38919e252baSAlexander Leidinger 	LIN_SDT_PROBE1(time, linux_clock_gettime, return, error);
39019e252baSAlexander Leidinger 	return (error);
391ad2056f2SAlexander Leidinger }
392ad2056f2SAlexander Leidinger 
393ad2056f2SAlexander Leidinger int
394ad2056f2SAlexander Leidinger linux_clock_settime(struct thread *td, struct linux_clock_settime_args *args)
395ad2056f2SAlexander Leidinger {
396ad2056f2SAlexander Leidinger 	struct timespec ts;
397ad2056f2SAlexander Leidinger 	struct l_timespec lts;
398ad2056f2SAlexander Leidinger 	int error;
3992506c761SDmitry Chagin 	clockid_t nwhich;
400ad2056f2SAlexander Leidinger 
40119e252baSAlexander Leidinger 	LIN_SDT_PROBE2(time, linux_clock_settime, entry, args->which, args->tp);
402ad2056f2SAlexander Leidinger 
40319e252baSAlexander Leidinger 	error = linux_to_native_clockid(&nwhich, args->which);
40419e252baSAlexander Leidinger 	if (error != 0) {
405*4afe4faeSEdward Tomasz Napierala 		linux_msg(curthread,
406*4afe4faeSEdward Tomasz Napierala 		    "unsupported clock_settime clockid %d", args->which);
40719e252baSAlexander Leidinger 		LIN_SDT_PROBE1(time, linux_clock_settime, conversion_error,
40819e252baSAlexander Leidinger 		    error);
40919e252baSAlexander Leidinger 		LIN_SDT_PROBE1(time, linux_clock_settime, return, error);
41019e252baSAlexander Leidinger 		return (error);
41119e252baSAlexander Leidinger 	}
41219e252baSAlexander Leidinger 	error = copyin(args->tp, &lts, sizeof lts);
41319e252baSAlexander Leidinger 	if (error != 0) {
41419e252baSAlexander Leidinger 		LIN_SDT_PROBE1(time, linux_clock_settime, copyin_error, error);
41519e252baSAlexander Leidinger 		LIN_SDT_PROBE1(time, linux_clock_settime, return, error);
41619e252baSAlexander Leidinger 		return (error);
41719e252baSAlexander Leidinger 	}
41819e252baSAlexander Leidinger 	error = linux_to_native_timespec(&ts, &lts);
41919e252baSAlexander Leidinger 	if (error != 0) {
42019e252baSAlexander Leidinger 		LIN_SDT_PROBE1(time, linux_clock_settime, conversion_error,
42119e252baSAlexander Leidinger 		    error);
42219e252baSAlexander Leidinger 		LIN_SDT_PROBE1(time, linux_clock_settime, return, error);
42319e252baSAlexander Leidinger 		return (error);
42419e252baSAlexander Leidinger 	}
42519e252baSAlexander Leidinger 
42619e252baSAlexander Leidinger 	error = kern_clock_settime(td, nwhich, &ts);
42719e252baSAlexander Leidinger 	if (error != 0)
42819e252baSAlexander Leidinger 		LIN_SDT_PROBE1(time, linux_clock_settime, settime_error, error);
42919e252baSAlexander Leidinger 
43019e252baSAlexander Leidinger 	LIN_SDT_PROBE1(time, linux_clock_settime, return, error);
43119e252baSAlexander Leidinger 	return (error);
432ad2056f2SAlexander Leidinger }
433ad2056f2SAlexander Leidinger 
434ad2056f2SAlexander Leidinger int
435ad2056f2SAlexander Leidinger linux_clock_getres(struct thread *td, struct linux_clock_getres_args *args)
436ad2056f2SAlexander Leidinger {
4372711aba9SDmitry Chagin 	struct proc *p;
438ad2056f2SAlexander Leidinger 	struct timespec ts;
439ad2056f2SAlexander Leidinger 	struct l_timespec lts;
4402711aba9SDmitry Chagin 	int error, clockwhich;
4412506c761SDmitry Chagin 	clockid_t nwhich;
4422711aba9SDmitry Chagin 	pid_t pid;
4432711aba9SDmitry Chagin 	lwpid_t tid;
444ad2056f2SAlexander Leidinger 
44519e252baSAlexander Leidinger 	LIN_SDT_PROBE2(time, linux_clock_getres, entry, args->which, args->tp);
44619e252baSAlexander Leidinger 
447ad2056f2SAlexander Leidinger 	error = linux_to_native_clockid(&nwhich, args->which);
44819e252baSAlexander Leidinger 	if (error != 0) {
449*4afe4faeSEdward Tomasz Napierala 		linux_msg(curthread,
450*4afe4faeSEdward Tomasz Napierala 		    "unsupported clock_getres clockid %d", args->which);
45119e252baSAlexander Leidinger 		LIN_SDT_PROBE1(time, linux_clock_getres, conversion_error,
45219e252baSAlexander Leidinger 		    error);
45319e252baSAlexander Leidinger 		LIN_SDT_PROBE1(time, linux_clock_getres, return, error);
45477424f41SJung-uk Kim 		return (error);
45519e252baSAlexander Leidinger 	}
4562711aba9SDmitry Chagin 
4572711aba9SDmitry Chagin 	/*
4582711aba9SDmitry Chagin 	 * Check user supplied clock id in case of per-process
4592711aba9SDmitry Chagin 	 * or thread-specific cpu-time clock.
4602711aba9SDmitry Chagin 	 */
4617bc05ae6SDmitry Chagin 	if (args->which < 0) {
4622711aba9SDmitry Chagin 		switch (nwhich) {
4632711aba9SDmitry Chagin 		case CLOCK_THREAD_CPUTIME_ID:
4642711aba9SDmitry Chagin 			tid = LINUX_CPUCLOCK_ID(args->which);
4652711aba9SDmitry Chagin 			if (tid != 0) {
4662711aba9SDmitry Chagin 				p = td->td_proc;
4677bc05ae6SDmitry Chagin 				if (linux_tdfind(td, tid, p->p_pid) == NULL)
4687bc05ae6SDmitry Chagin 					return (EINVAL);
4692711aba9SDmitry Chagin 				PROC_UNLOCK(p);
4702711aba9SDmitry Chagin 			}
4712711aba9SDmitry Chagin 			break;
4722711aba9SDmitry Chagin 		case CLOCK_PROCESS_CPUTIME_ID:
4732711aba9SDmitry Chagin 			pid = LINUX_CPUCLOCK_ID(args->which);
4742711aba9SDmitry Chagin 			if (pid != 0) {
4752711aba9SDmitry Chagin 				error = pget(pid, PGET_CANSEE, &p);
4762711aba9SDmitry Chagin 				if (error != 0)
4772711aba9SDmitry Chagin 					return (EINVAL);
4782711aba9SDmitry Chagin 				PROC_UNLOCK(p);
4792711aba9SDmitry Chagin 			}
4802711aba9SDmitry Chagin 			break;
4812711aba9SDmitry Chagin 		}
4827bc05ae6SDmitry Chagin 	}
4832711aba9SDmitry Chagin 
4842711aba9SDmitry Chagin 	if (args->tp == NULL) {
4852711aba9SDmitry Chagin 		LIN_SDT_PROBE0(time, linux_clock_getres, nullcall);
4862711aba9SDmitry Chagin 		LIN_SDT_PROBE1(time, linux_clock_getres, return, 0);
4872711aba9SDmitry Chagin 		return (0);
4882711aba9SDmitry Chagin 	}
4892711aba9SDmitry Chagin 
4902711aba9SDmitry Chagin 	switch (nwhich) {
4912711aba9SDmitry Chagin 	case CLOCK_THREAD_CPUTIME_ID:
4922711aba9SDmitry Chagin 	case CLOCK_PROCESS_CPUTIME_ID:
4932711aba9SDmitry Chagin 		clockwhich = LINUX_CPUCLOCK_WHICH(args->which);
4947bc05ae6SDmitry Chagin 		/*
4957bc05ae6SDmitry Chagin 		 * In both cases (when the clock id obtained by a call to
4967bc05ae6SDmitry Chagin 		 * clock_getcpuclockid() or using the clock
4977bc05ae6SDmitry Chagin 		 * ID CLOCK_PROCESS_CPUTIME_ID Linux hardcodes precision
4987bc05ae6SDmitry Chagin 		 * of clock. The same for the CLOCK_THREAD_CPUTIME_ID clock.
4997bc05ae6SDmitry Chagin 		 *
5007bc05ae6SDmitry Chagin 		 * See Linux posix_cpu_clock_getres() implementation.
5017bc05ae6SDmitry Chagin 		 */
5027bc05ae6SDmitry Chagin 		if (args->which > 0 || clockwhich == LINUX_CPUCLOCK_SCHED) {
5037bc05ae6SDmitry Chagin 			ts.tv_sec = 0;
5047bc05ae6SDmitry Chagin 			ts.tv_nsec = 1;
5057bc05ae6SDmitry Chagin 			goto out;
5067bc05ae6SDmitry Chagin 		}
5077bc05ae6SDmitry Chagin 
5082711aba9SDmitry Chagin 		switch (clockwhich) {
5092711aba9SDmitry Chagin 		case LINUX_CPUCLOCK_PROF:
5102711aba9SDmitry Chagin 			nwhich = CLOCK_PROF;
5112711aba9SDmitry Chagin 			break;
5122711aba9SDmitry Chagin 		case LINUX_CPUCLOCK_VIRT:
5132711aba9SDmitry Chagin 			nwhich = CLOCK_VIRTUAL;
5142711aba9SDmitry Chagin 			break;
5152711aba9SDmitry Chagin 		default:
5162711aba9SDmitry Chagin 			return (EINVAL);
5172711aba9SDmitry Chagin 		}
5182711aba9SDmitry Chagin 		break;
5192711aba9SDmitry Chagin 
5202711aba9SDmitry Chagin 	default:
5212711aba9SDmitry Chagin 		break;
5222711aba9SDmitry Chagin 	}
523ad2056f2SAlexander Leidinger 	error = kern_clock_getres(td, nwhich, &ts);
52419e252baSAlexander Leidinger 	if (error != 0) {
52519e252baSAlexander Leidinger 		LIN_SDT_PROBE1(time, linux_clock_getres, getres_error, error);
52619e252baSAlexander Leidinger 		LIN_SDT_PROBE1(time, linux_clock_getres, return, error);
52777424f41SJung-uk Kim 		return (error);
52819e252baSAlexander Leidinger 	}
5297bc05ae6SDmitry Chagin 
5307bc05ae6SDmitry Chagin out:
5310670e972SDmitry Chagin 	error = native_to_linux_timespec(&lts, &ts);
5320670e972SDmitry Chagin 	if (error != 0)
5330670e972SDmitry Chagin 		return (error);
53419e252baSAlexander Leidinger 	error = copyout(&lts, args->tp, sizeof lts);
53519e252baSAlexander Leidinger 	if (error != 0)
53619e252baSAlexander Leidinger 		LIN_SDT_PROBE1(time, linux_clock_getres, copyout_error, error);
53719e252baSAlexander Leidinger 
53819e252baSAlexander Leidinger 	LIN_SDT_PROBE1(time, linux_clock_getres, return, error);
53919e252baSAlexander Leidinger 	return (error);
54077424f41SJung-uk Kim }
54177424f41SJung-uk Kim 
54277424f41SJung-uk Kim int
54377424f41SJung-uk Kim linux_nanosleep(struct thread *td, struct linux_nanosleep_args *args)
54477424f41SJung-uk Kim {
54577424f41SJung-uk Kim 	struct timespec *rmtp;
54677424f41SJung-uk Kim 	struct l_timespec lrqts, lrmts;
54777424f41SJung-uk Kim 	struct timespec rqts, rmts;
5485c2748d5SDmitry Chagin 	int error, error2;
54977424f41SJung-uk Kim 
55019e252baSAlexander Leidinger 	LIN_SDT_PROBE2(time, linux_nanosleep, entry, args->rqtp, args->rmtp);
55119e252baSAlexander Leidinger 
55277424f41SJung-uk Kim 	error = copyin(args->rqtp, &lrqts, sizeof lrqts);
55319e252baSAlexander Leidinger 	if (error != 0) {
55419e252baSAlexander Leidinger 		LIN_SDT_PROBE1(time, linux_nanosleep, copyin_error, error);
55519e252baSAlexander Leidinger 		LIN_SDT_PROBE1(time, linux_nanosleep, return, error);
55677424f41SJung-uk Kim 		return (error);
55719e252baSAlexander Leidinger 	}
55877424f41SJung-uk Kim 
55977424f41SJung-uk Kim 	if (args->rmtp != NULL)
56077424f41SJung-uk Kim 		rmtp = &rmts;
56177424f41SJung-uk Kim 	else
56277424f41SJung-uk Kim 		rmtp = NULL;
56377424f41SJung-uk Kim 
56477424f41SJung-uk Kim 	error = linux_to_native_timespec(&rqts, &lrqts);
56519e252baSAlexander Leidinger 	if (error != 0) {
56619e252baSAlexander Leidinger 		LIN_SDT_PROBE1(time, linux_nanosleep, conversion_error, error);
56719e252baSAlexander Leidinger 		LIN_SDT_PROBE1(time, linux_nanosleep, return, error);
56877424f41SJung-uk Kim 		return (error);
56919e252baSAlexander Leidinger 	}
57077424f41SJung-uk Kim 	error = kern_nanosleep(td, &rqts, rmtp);
5714cf66812SEric van Gyzen 	if (error == EINTR && args->rmtp != NULL) {
5720670e972SDmitry Chagin 		error2 = native_to_linux_timespec(&lrmts, rmtp);
5730670e972SDmitry Chagin 		if (error2 != 0)
5740670e972SDmitry Chagin 			return (error2);
5755c2748d5SDmitry Chagin 		error2 = copyout(&lrmts, args->rmtp, sizeof(lrmts));
5765c2748d5SDmitry Chagin 		if (error2 != 0) {
57719e252baSAlexander Leidinger 			LIN_SDT_PROBE1(time, linux_nanosleep, copyout_error,
5785c2748d5SDmitry Chagin 			    error2);
5795c2748d5SDmitry Chagin 			LIN_SDT_PROBE1(time, linux_nanosleep, return, error2);
5805c2748d5SDmitry Chagin 			return (error2);
58177424f41SJung-uk Kim 		}
58219e252baSAlexander Leidinger 	}
58377424f41SJung-uk Kim 
5845c2748d5SDmitry Chagin 	LIN_SDT_PROBE1(time, linux_nanosleep, return, error);
5855c2748d5SDmitry Chagin 	return (error);
586ad2056f2SAlexander Leidinger }
587ad2056f2SAlexander Leidinger 
588ad2056f2SAlexander Leidinger int
589ad2056f2SAlexander Leidinger linux_clock_nanosleep(struct thread *td, struct linux_clock_nanosleep_args *args)
590ad2056f2SAlexander Leidinger {
591ad2056f2SAlexander Leidinger 	struct timespec *rmtp;
592ad2056f2SAlexander Leidinger 	struct l_timespec lrqts, lrmts;
593ad2056f2SAlexander Leidinger 	struct timespec rqts, rmts;
594f0f58384SDmitry Chagin 	int error, error2, flags;
595f0f58384SDmitry Chagin 	clockid_t clockid;
596ad2056f2SAlexander Leidinger 
59719e252baSAlexander Leidinger 	LIN_SDT_PROBE4(time, linux_clock_nanosleep, entry, args->which,
59819e252baSAlexander Leidinger 	    args->flags, args->rqtp, args->rmtp);
599ad2056f2SAlexander Leidinger 
600f0f58384SDmitry Chagin 	error = linux_to_native_timerflags(&flags, args->flags);
601f0f58384SDmitry Chagin 	if (error != 0) {
60219e252baSAlexander Leidinger 		LIN_SDT_PROBE1(time, linux_clock_nanosleep, unsupported_flags,
60319e252baSAlexander Leidinger 		    args->flags);
604f0f58384SDmitry Chagin 		LIN_SDT_PROBE1(time, linux_clock_nanosleep, return, error);
605f0f58384SDmitry Chagin 		return (error);
60619e252baSAlexander Leidinger 	}
60719e252baSAlexander Leidinger 
608f0f58384SDmitry Chagin 	error = linux_to_native_clockid(&clockid, args->which);
609f0f58384SDmitry Chagin 	if (error != 0) {
610*4afe4faeSEdward Tomasz Napierala 		linux_msg(curthread,
611*4afe4faeSEdward Tomasz Napierala 		    "unsupported clock_nanosleep clockid %d", args->which);
61219e252baSAlexander Leidinger 		LIN_SDT_PROBE1(time, linux_clock_nanosleep, unsupported_clockid,
61319e252baSAlexander Leidinger 		    args->which);
614f0f58384SDmitry Chagin 		LIN_SDT_PROBE1(time, linux_clock_settime, return, error);
615f0f58384SDmitry Chagin 		return (error);
61619e252baSAlexander Leidinger 	}
617ad2056f2SAlexander Leidinger 
6185c2748d5SDmitry Chagin 	error = copyin(args->rqtp, &lrqts, sizeof(lrqts));
61919e252baSAlexander Leidinger 	if (error != 0) {
62019e252baSAlexander Leidinger 		LIN_SDT_PROBE1(time, linux_clock_nanosleep, copyin_error,
62119e252baSAlexander Leidinger 		    error);
62219e252baSAlexander Leidinger 		LIN_SDT_PROBE1(time, linux_clock_nanosleep, return, error);
62377424f41SJung-uk Kim 		return (error);
62419e252baSAlexander Leidinger 	}
625ad2056f2SAlexander Leidinger 
626ad2056f2SAlexander Leidinger 	if (args->rmtp != NULL)
627ad2056f2SAlexander Leidinger 		rmtp = &rmts;
628ad2056f2SAlexander Leidinger 	else
629ad2056f2SAlexander Leidinger 		rmtp = NULL;
630ad2056f2SAlexander Leidinger 
63177424f41SJung-uk Kim 	error = linux_to_native_timespec(&rqts, &lrqts);
63219e252baSAlexander Leidinger 	if (error != 0) {
63319e252baSAlexander Leidinger 		LIN_SDT_PROBE1(time, linux_clock_nanosleep, conversion_error,
63419e252baSAlexander Leidinger 		    error);
63519e252baSAlexander Leidinger 		LIN_SDT_PROBE1(time, linux_clock_nanosleep, return, error);
63677424f41SJung-uk Kim 		return (error);
63719e252baSAlexander Leidinger 	}
638f0f58384SDmitry Chagin 	error = kern_clock_nanosleep(td, clockid, flags, &rqts, rmtp);
639f0f58384SDmitry Chagin 	if (error == EINTR && (flags & TIMER_ABSTIME) == 0 &&
640f0f58384SDmitry Chagin 	    args->rmtp != NULL) {
6410670e972SDmitry Chagin 		error2 = native_to_linux_timespec(&lrmts, rmtp);
6420670e972SDmitry Chagin 		if (error2 != 0)
6430670e972SDmitry Chagin 			return (error2);
6445c2748d5SDmitry Chagin 		error2 = copyout(&lrmts, args->rmtp, sizeof(lrmts));
6455c2748d5SDmitry Chagin 		if (error2 != 0) {
6465c2748d5SDmitry Chagin 			LIN_SDT_PROBE1(time, linux_clock_nanosleep,
6475c2748d5SDmitry Chagin 			    copyout_error, error2);
6485c2748d5SDmitry Chagin 			LIN_SDT_PROBE1(time, linux_clock_nanosleep,
6495c2748d5SDmitry Chagin 			    return, error2);
6505c2748d5SDmitry Chagin 			return (error2);
6515c2748d5SDmitry Chagin 		}
6525c2748d5SDmitry Chagin 	}
6535c2748d5SDmitry Chagin 
65419e252baSAlexander Leidinger 	LIN_SDT_PROBE1(time, linux_clock_nanosleep, return, error);
65577424f41SJung-uk Kim 	return (error);
65619e252baSAlexander Leidinger }
657