1161304Snetchild/*	$NetBSD: linux_time.c,v 1.14 2006/05/14 03:40:54 christos Exp $ */
2161304Snetchild
3161304Snetchild/*-
4161304Snetchild * Copyright (c) 2001 The NetBSD Foundation, Inc.
5161304Snetchild * All rights reserved.
6161304Snetchild *
7161304Snetchild * This code is derived from software contributed to The NetBSD Foundation
8161304Snetchild * by Emmanuel Dreyfus.
9161304Snetchild *
10161304Snetchild * Redistribution and use in source and binary forms, with or without
11161304Snetchild * modification, are permitted provided that the following conditions
12161304Snetchild * are met:
13161304Snetchild * 1. Redistributions of source code must retain the above copyright
14161304Snetchild *    notice, this list of conditions and the following disclaimer.
15161304Snetchild * 2. Redistributions in binary form must reproduce the above copyright
16161304Snetchild *    notice, this list of conditions and the following disclaimer in the
17161304Snetchild *    documentation and/or other materials provided with the distribution.
18161304Snetchild *
19161304Snetchild * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20161304Snetchild * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21161304Snetchild * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22161304Snetchild * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23161304Snetchild * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24161304Snetchild * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25161304Snetchild * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26161304Snetchild * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27161304Snetchild * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28161304Snetchild * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29161304Snetchild * POSSIBILITY OF SUCH DAMAGE.
30161304Snetchild */
31161304Snetchild
32161304Snetchild#include <sys/cdefs.h>
33161304Snetchild__FBSDID("$FreeBSD$");
34161304Snetchild#if 0
35161304Snetchild__KERNEL_RCSID(0, "$NetBSD: linux_time.c,v 1.14 2006/05/14 03:40:54 christos Exp $");
36161304Snetchild#endif
37161304Snetchild
38161304Snetchild#include "opt_compat.h"
39246290Sdchagin#include "opt_kdtrace.h"
40161304Snetchild
41161304Snetchild#include <sys/param.h>
42246290Sdchagin#include <sys/kernel.h>
43161304Snetchild#include <sys/ucred.h>
44161304Snetchild#include <sys/mount.h>
45246290Sdchagin#include <sys/sdt.h>
46161304Snetchild#include <sys/signal.h>
47161304Snetchild#include <sys/stdint.h>
48161304Snetchild#include <sys/syscallsubr.h>
49161304Snetchild#include <sys/sysproto.h>
50161304Snetchild#include <sys/time.h>
51161304Snetchild#include <sys/systm.h>
52161304Snetchild#include <sys/proc.h>
53161304Snetchild
54161304Snetchild#ifdef COMPAT_LINUX32
55161304Snetchild#include <machine/../linux32/linux.h>
56161304Snetchild#include <machine/../linux32/linux32_proto.h>
57161304Snetchild#else
58161304Snetchild#include <machine/../linux/linux.h>
59161304Snetchild#include <machine/../linux/linux_proto.h>
60161304Snetchild#endif
61161304Snetchild
62246290Sdchagin#include <compat/linux/linux_dtrace.h>
63246290Sdchagin
64246290Sdchagin/* DTrace init */
65246290SdchaginLIN_SDT_PROVIDER_DECLARE(LINUX_DTRACE);
66246290Sdchagin
67246290Sdchagin/**
68246290Sdchagin * DTrace probes in this module.
69246290Sdchagin */
70246290SdchaginLIN_SDT_PROBE_DEFINE2(time, native_to_linux_timespec, entry,
71246290Sdchagin    "struct l_timespec *", "struct timespec *");
72246290SdchaginLIN_SDT_PROBE_DEFINE0(time, native_to_linux_timespec, return);
73246290SdchaginLIN_SDT_PROBE_DEFINE2(time, linux_to_native_timespec, entry,
74246290Sdchagin    "struct timespec *", "struct l_timespec *");
75246290SdchaginLIN_SDT_PROBE_DEFINE1(time, linux_to_native_timespec, return, "int");
76246290SdchaginLIN_SDT_PROBE_DEFINE2(time, linux_to_native_clockid, entry, "clockid_t *",
77246290Sdchagin    "clockid_t");
78246290SdchaginLIN_SDT_PROBE_DEFINE1(time, linux_to_native_clockid, unsupported_clockid,
79246290Sdchagin    "clockid_t");
80246290SdchaginLIN_SDT_PROBE_DEFINE1(time, linux_to_native_clockid, unknown_clockid,
81246290Sdchagin    "clockid_t");
82246290SdchaginLIN_SDT_PROBE_DEFINE1(time, linux_to_native_clockid, return, "int");
83246290SdchaginLIN_SDT_PROBE_DEFINE2(time, linux_clock_gettime, entry, "clockid_t",
84246290Sdchagin    "struct l_timespec *");
85246290SdchaginLIN_SDT_PROBE_DEFINE1(time, linux_clock_gettime, conversion_error, "int");
86246290SdchaginLIN_SDT_PROBE_DEFINE1(time, linux_clock_gettime, gettime_error, "int");
87246290SdchaginLIN_SDT_PROBE_DEFINE1(time, linux_clock_gettime, copyout_error, "int");
88246290SdchaginLIN_SDT_PROBE_DEFINE1(time, linux_clock_gettime, return, "int");
89246290SdchaginLIN_SDT_PROBE_DEFINE2(time, linux_clock_settime, entry, "clockid_t",
90246290Sdchagin    "struct l_timespec *");
91246290SdchaginLIN_SDT_PROBE_DEFINE1(time, linux_clock_settime, conversion_error, "int");
92246290SdchaginLIN_SDT_PROBE_DEFINE1(time, linux_clock_settime, settime_error, "int");
93246290SdchaginLIN_SDT_PROBE_DEFINE1(time, linux_clock_settime, copyin_error, "int");
94246290SdchaginLIN_SDT_PROBE_DEFINE1(time, linux_clock_settime, return, "int");
95246290SdchaginLIN_SDT_PROBE_DEFINE2(time, linux_clock_getres, entry, "clockid_t",
96246290Sdchagin    "struct l_timespec *");
97246290SdchaginLIN_SDT_PROBE_DEFINE0(time, linux_clock_getres, nullcall);
98246290SdchaginLIN_SDT_PROBE_DEFINE1(time, linux_clock_getres, conversion_error, "int");
99246290SdchaginLIN_SDT_PROBE_DEFINE1(time, linux_clock_getres, getres_error, "int");
100246290SdchaginLIN_SDT_PROBE_DEFINE1(time, linux_clock_getres, copyout_error, "int");
101246290SdchaginLIN_SDT_PROBE_DEFINE1(time, linux_clock_getres, return, "int");
102246290SdchaginLIN_SDT_PROBE_DEFINE2(time, linux_nanosleep, entry, "const struct l_timespec *",
103246290Sdchagin    "struct l_timespec *");
104246290SdchaginLIN_SDT_PROBE_DEFINE1(time, linux_nanosleep, conversion_error, "int");
105246290SdchaginLIN_SDT_PROBE_DEFINE1(time, linux_nanosleep, nanosleep_error, "int");
106246290SdchaginLIN_SDT_PROBE_DEFINE1(time, linux_nanosleep, copyout_error, "int");
107246290SdchaginLIN_SDT_PROBE_DEFINE1(time, linux_nanosleep, copyin_error, "int");
108246290SdchaginLIN_SDT_PROBE_DEFINE1(time, linux_nanosleep, return, "int");
109246290SdchaginLIN_SDT_PROBE_DEFINE4(time, linux_clock_nanosleep, entry, "clockid_t", "int",
110246290Sdchagin    "struct l_timespec *", "struct l_timespec *");
111246290SdchaginLIN_SDT_PROBE_DEFINE1(time, linux_clock_nanosleep, conversion_error, "int");
112246290SdchaginLIN_SDT_PROBE_DEFINE1(time, linux_clock_nanosleep, nanosleep_error, "int");
113246290SdchaginLIN_SDT_PROBE_DEFINE1(time, linux_clock_nanosleep, copyout_error, "int");
114246290SdchaginLIN_SDT_PROBE_DEFINE1(time, linux_clock_nanosleep, copyin_error, "int");
115246290SdchaginLIN_SDT_PROBE_DEFINE1(time, linux_clock_nanosleep, unsupported_flags, "int");
116246290SdchaginLIN_SDT_PROBE_DEFINE1(time, linux_clock_nanosleep, unsupported_clockid, "int");
117246290SdchaginLIN_SDT_PROBE_DEFINE1(time, linux_clock_nanosleep, return, "int");
118246290Sdchagin
119161304Snetchildstatic void native_to_linux_timespec(struct l_timespec *,
120161304Snetchild				     struct timespec *);
121165408Sjkimstatic int linux_to_native_timespec(struct timespec *,
122161304Snetchild				     struct l_timespec *);
123161304Snetchildstatic int linux_to_native_clockid(clockid_t *, clockid_t);
124161304Snetchild
125161304Snetchildstatic void
126161304Snetchildnative_to_linux_timespec(struct l_timespec *ltp, struct timespec *ntp)
127161304Snetchild{
128246290Sdchagin
129246290Sdchagin	LIN_SDT_PROBE2(time, native_to_linux_timespec, entry, ltp, ntp);
130246290Sdchagin
131161304Snetchild	ltp->tv_sec = ntp->tv_sec;
132161304Snetchild	ltp->tv_nsec = ntp->tv_nsec;
133246290Sdchagin
134246290Sdchagin	LIN_SDT_PROBE0(time, native_to_linux_timespec, return);
135161304Snetchild}
136161304Snetchild
137165408Sjkimstatic int
138161304Snetchildlinux_to_native_timespec(struct timespec *ntp, struct l_timespec *ltp)
139161304Snetchild{
140246290Sdchagin
141246290Sdchagin	LIN_SDT_PROBE2(time, linux_to_native_timespec, entry, ntp, ltp);
142246290Sdchagin
143246290Sdchagin	if (ltp->tv_sec < 0 || ltp->tv_nsec > (l_long)999999999L) {
144246290Sdchagin		LIN_SDT_PROBE1(time, linux_to_native_timespec, return, EINVAL);
145165408Sjkim		return (EINVAL);
146246290Sdchagin	}
147161304Snetchild	ntp->tv_sec = ltp->tv_sec;
148161304Snetchild	ntp->tv_nsec = ltp->tv_nsec;
149165408Sjkim
150246290Sdchagin	LIN_SDT_PROBE1(time, linux_to_native_timespec, return, 0);
151165408Sjkim	return (0);
152161304Snetchild}
153161304Snetchild
154161304Snetchildstatic int
155161304Snetchildlinux_to_native_clockid(clockid_t *n, clockid_t l)
156161304Snetchild{
157246290Sdchagin
158246290Sdchagin	LIN_SDT_PROBE2(time, linux_to_native_clockid, entry, n, l);
159246290Sdchagin
160161304Snetchild	switch (l) {
161161304Snetchild	case LINUX_CLOCK_REALTIME:
162161304Snetchild		*n = CLOCK_REALTIME;
163161304Snetchild		break;
164161304Snetchild	case LINUX_CLOCK_MONOTONIC:
165161304Snetchild		*n = CLOCK_MONOTONIC;
166161304Snetchild		break;
167161304Snetchild	case LINUX_CLOCK_PROCESS_CPUTIME_ID:
168161304Snetchild	case LINUX_CLOCK_THREAD_CPUTIME_ID:
169161304Snetchild	case LINUX_CLOCK_REALTIME_HR:
170161304Snetchild	case LINUX_CLOCK_MONOTONIC_HR:
171246290Sdchagin		LIN_SDT_PROBE1(time, linux_to_native_clockid,
172246290Sdchagin		    unsupported_clockid, l);
173246290Sdchagin		LIN_SDT_PROBE1(time, linux_to_native_clockid, return, EINVAL);
174246290Sdchagin		return (EINVAL);
175246290Sdchagin		break;
176165408Sjkim	default:
177246290Sdchagin		LIN_SDT_PROBE1(time, linux_to_native_clockid,
178246290Sdchagin		    unknown_clockid, l);
179246290Sdchagin		LIN_SDT_PROBE1(time, linux_to_native_clockid, return, EINVAL);
180165408Sjkim		return (EINVAL);
181165408Sjkim		break;
182161304Snetchild	}
183161304Snetchild
184246290Sdchagin	LIN_SDT_PROBE1(time, linux_to_native_clockid, return, 0);
185165408Sjkim	return (0);
186161304Snetchild}
187161304Snetchild
188161304Snetchildint
189161304Snetchildlinux_clock_gettime(struct thread *td, struct linux_clock_gettime_args *args)
190161304Snetchild{
191161304Snetchild	struct l_timespec lts;
192161304Snetchild	int error;
193161304Snetchild	clockid_t nwhich = 0;	/* XXX: GCC */
194161304Snetchild	struct timespec tp;
195161304Snetchild
196246290Sdchagin	LIN_SDT_PROBE2(time, linux_clock_gettime, entry, args->which, args->tp);
197246290Sdchagin
198161304Snetchild	error = linux_to_native_clockid(&nwhich, args->which);
199246290Sdchagin	if (error != 0) {
200246290Sdchagin		LIN_SDT_PROBE1(time, linux_clock_gettime, conversion_error,
201246290Sdchagin		    error);
202246290Sdchagin		LIN_SDT_PROBE1(time, linux_clock_gettime, return, error);
203165408Sjkim		return (error);
204246290Sdchagin	}
205161304Snetchild	error = kern_clock_gettime(td, nwhich, &tp);
206246290Sdchagin	if (error != 0) {
207246290Sdchagin		LIN_SDT_PROBE1(time, linux_clock_gettime, gettime_error, error);
208246290Sdchagin		LIN_SDT_PROBE1(time, linux_clock_gettime, return, error);
209165408Sjkim		return (error);
210246290Sdchagin	}
211161304Snetchild	native_to_linux_timespec(&lts, &tp);
212161304Snetchild
213246290Sdchagin	error = copyout(&lts, args->tp, sizeof lts);
214246290Sdchagin	if (error != 0)
215246290Sdchagin		LIN_SDT_PROBE1(time, linux_clock_gettime, copyout_error, error);
216246290Sdchagin
217246290Sdchagin	LIN_SDT_PROBE1(time, linux_clock_gettime, return, error);
218246290Sdchagin	return (error);
219161304Snetchild}
220161304Snetchild
221161304Snetchildint
222161304Snetchildlinux_clock_settime(struct thread *td, struct linux_clock_settime_args *args)
223161304Snetchild{
224161304Snetchild	struct timespec ts;
225161304Snetchild	struct l_timespec lts;
226161304Snetchild	int error;
227161304Snetchild	clockid_t nwhich = 0;	/* XXX: GCC */
228161304Snetchild
229246290Sdchagin	LIN_SDT_PROBE2(time, linux_clock_settime, entry, args->which, args->tp);
230246290Sdchagin
231161304Snetchild	error = linux_to_native_clockid(&nwhich, args->which);
232246290Sdchagin	if (error != 0) {
233246290Sdchagin		LIN_SDT_PROBE1(time, linux_clock_settime, conversion_error,
234246290Sdchagin		    error);
235246290Sdchagin		LIN_SDT_PROBE1(time, linux_clock_settime, return, error);
236165408Sjkim		return (error);
237246290Sdchagin	}
238161304Snetchild	error = copyin(args->tp, &lts, sizeof lts);
239246290Sdchagin	if (error != 0) {
240246290Sdchagin		LIN_SDT_PROBE1(time, linux_clock_settime, copyin_error, error);
241246290Sdchagin		LIN_SDT_PROBE1(time, linux_clock_settime, return, error);
242165408Sjkim		return (error);
243246290Sdchagin	}
244165408Sjkim	error = linux_to_native_timespec(&ts, &lts);
245246290Sdchagin	if (error != 0) {
246246290Sdchagin		LIN_SDT_PROBE1(time, linux_clock_settime, conversion_error,
247246290Sdchagin		    error);
248246290Sdchagin		LIN_SDT_PROBE1(time, linux_clock_settime, return, error);
249165408Sjkim		return (error);
250246290Sdchagin	}
251161304Snetchild
252246290Sdchagin	error = kern_clock_settime(td, nwhich, &ts);
253246290Sdchagin	if (error != 0)
254246290Sdchagin		LIN_SDT_PROBE1(time, linux_clock_settime, settime_error, error);
255246290Sdchagin
256246290Sdchagin	LIN_SDT_PROBE1(time, linux_clock_settime, return, error);
257246290Sdchagin	return (error);
258161304Snetchild}
259161304Snetchild
260161304Snetchildint
261161304Snetchildlinux_clock_getres(struct thread *td, struct linux_clock_getres_args *args)
262161304Snetchild{
263161304Snetchild	struct timespec ts;
264161304Snetchild	struct l_timespec lts;
265161304Snetchild	int error;
266161304Snetchild	clockid_t nwhich = 0;	/* XXX: GCC */
267161304Snetchild
268246290Sdchagin	LIN_SDT_PROBE2(time, linux_clock_getres, entry, args->which, args->tp);
269246290Sdchagin
270246290Sdchagin	if (args->tp == NULL) {
271246290Sdchagin		LIN_SDT_PROBE0(time, linux_clock_getres, nullcall);
272246290Sdchagin		LIN_SDT_PROBE1(time, linux_clock_getres, return, 0);
273165408Sjkim	  	return (0);
274246290Sdchagin	}
275161304Snetchild
276161304Snetchild	error = linux_to_native_clockid(&nwhich, args->which);
277246290Sdchagin	if (error != 0) {
278246290Sdchagin		LIN_SDT_PROBE1(time, linux_clock_getres, conversion_error,
279246290Sdchagin		    error);
280246290Sdchagin		LIN_SDT_PROBE1(time, linux_clock_getres, return, error);
281165408Sjkim		return (error);
282246290Sdchagin	}
283161304Snetchild	error = kern_clock_getres(td, nwhich, &ts);
284246290Sdchagin	if (error != 0) {
285246290Sdchagin		LIN_SDT_PROBE1(time, linux_clock_getres, getres_error, error);
286246290Sdchagin		LIN_SDT_PROBE1(time, linux_clock_getres, return, error);
287165408Sjkim		return (error);
288246290Sdchagin	}
289165408Sjkim	native_to_linux_timespec(&lts, &ts);
290161304Snetchild
291246290Sdchagin	error = copyout(&lts, args->tp, sizeof lts);
292246290Sdchagin	if (error != 0)
293246290Sdchagin		LIN_SDT_PROBE1(time, linux_clock_getres, copyout_error, error);
294246290Sdchagin
295246290Sdchagin	LIN_SDT_PROBE1(time, linux_clock_getres, return, error);
296246290Sdchagin	return (error);
297161304Snetchild}
298161304Snetchild
299161304Snetchildint
300165408Sjkimlinux_nanosleep(struct thread *td, struct linux_nanosleep_args *args)
301165408Sjkim{
302165408Sjkim	struct timespec *rmtp;
303165408Sjkim	struct l_timespec lrqts, lrmts;
304165408Sjkim	struct timespec rqts, rmts;
305165408Sjkim	int error;
306165408Sjkim
307246290Sdchagin	LIN_SDT_PROBE2(time, linux_nanosleep, entry, args->rqtp, args->rmtp);
308246290Sdchagin
309165408Sjkim	error = copyin(args->rqtp, &lrqts, sizeof lrqts);
310246290Sdchagin	if (error != 0) {
311246290Sdchagin		LIN_SDT_PROBE1(time, linux_nanosleep, copyin_error, error);
312246290Sdchagin		LIN_SDT_PROBE1(time, linux_nanosleep, return, error);
313165408Sjkim		return (error);
314246290Sdchagin	}
315165408Sjkim
316165408Sjkim	if (args->rmtp != NULL)
317165408Sjkim	   	rmtp = &rmts;
318165408Sjkim	else
319165408Sjkim	   	rmtp = NULL;
320165408Sjkim
321165408Sjkim	error = linux_to_native_timespec(&rqts, &lrqts);
322246290Sdchagin	if (error != 0) {
323246290Sdchagin		LIN_SDT_PROBE1(time, linux_nanosleep, conversion_error, error);
324246290Sdchagin		LIN_SDT_PROBE1(time, linux_nanosleep, return, error);
325165408Sjkim		return (error);
326246290Sdchagin	}
327165408Sjkim	error = kern_nanosleep(td, &rqts, rmtp);
328246290Sdchagin	if (error != 0) {
329246290Sdchagin		LIN_SDT_PROBE1(time, linux_nanosleep, nanosleep_error, error);
330246290Sdchagin		LIN_SDT_PROBE1(time, linux_nanosleep, return, error);
331165408Sjkim		return (error);
332246290Sdchagin	}
333165408Sjkim
334165408Sjkim	if (args->rmtp != NULL) {
335165408Sjkim	   	native_to_linux_timespec(&lrmts, rmtp);
336165408Sjkim	   	error = copyout(&lrmts, args->rmtp, sizeof(lrmts));
337246290Sdchagin		if (error != 0) {
338246290Sdchagin			LIN_SDT_PROBE1(time, linux_nanosleep, copyout_error,
339246290Sdchagin			    error);
340246290Sdchagin			LIN_SDT_PROBE1(time, linux_nanosleep, return, error);
341165408Sjkim		   	return (error);
342246290Sdchagin		}
343165408Sjkim	}
344165408Sjkim
345246290Sdchagin	LIN_SDT_PROBE1(time, linux_nanosleep, return, 0);
346165408Sjkim	return (0);
347165408Sjkim}
348165408Sjkim
349165408Sjkimint
350161304Snetchildlinux_clock_nanosleep(struct thread *td, struct linux_clock_nanosleep_args *args)
351161304Snetchild{
352161304Snetchild	struct timespec *rmtp;
353161304Snetchild	struct l_timespec lrqts, lrmts;
354161304Snetchild	struct timespec rqts, rmts;
355161304Snetchild	int error;
356161304Snetchild
357246290Sdchagin	LIN_SDT_PROBE4(time, linux_clock_nanosleep, entry, args->which,
358246290Sdchagin	    args->flags, args->rqtp, args->rmtp);
359246290Sdchagin
360246290Sdchagin	if (args->flags != 0) {
361246290Sdchagin		/* XXX deal with TIMER_ABSTIME */
362246290Sdchagin		LIN_SDT_PROBE1(time, linux_clock_nanosleep, unsupported_flags,
363246290Sdchagin		    args->flags);
364246290Sdchagin		LIN_SDT_PROBE1(time, linux_clock_nanosleep, return, EINVAL);
365165408Sjkim		return (EINVAL);	/* XXX deal with TIMER_ABSTIME */
366246290Sdchagin	}
367161304Snetchild
368246290Sdchagin	if (args->which != LINUX_CLOCK_REALTIME) {
369246290Sdchagin		LIN_SDT_PROBE1(time, linux_clock_nanosleep, unsupported_clockid,
370246290Sdchagin		    args->which);
371246290Sdchagin		LIN_SDT_PROBE1(time, linux_clock_nanosleep, return, EINVAL);
372165408Sjkim		return (EINVAL);
373246290Sdchagin	}
374161304Snetchild
375161304Snetchild	error = copyin(args->rqtp, &lrqts, sizeof lrqts);
376246290Sdchagin	if (error != 0) {
377246290Sdchagin		LIN_SDT_PROBE1(time, linux_clock_nanosleep, copyin_error,
378246290Sdchagin		    error);
379246290Sdchagin		LIN_SDT_PROBE1(time, linux_clock_nanosleep, return, error);
380165408Sjkim		return (error);
381246290Sdchagin	}
382161304Snetchild
383161304Snetchild	if (args->rmtp != NULL)
384161304Snetchild	   	rmtp = &rmts;
385161304Snetchild	else
386161304Snetchild	   	rmtp = NULL;
387161304Snetchild
388165408Sjkim	error = linux_to_native_timespec(&rqts, &lrqts);
389246290Sdchagin	if (error != 0) {
390246290Sdchagin		LIN_SDT_PROBE1(time, linux_clock_nanosleep, conversion_error,
391246290Sdchagin		    error);
392246290Sdchagin		LIN_SDT_PROBE1(time, linux_clock_nanosleep, return, error);
393165408Sjkim		return (error);
394246290Sdchagin	}
395161304Snetchild	error = kern_nanosleep(td, &rqts, rmtp);
396246290Sdchagin	if (error != 0) {
397246290Sdchagin		LIN_SDT_PROBE1(time, linux_clock_nanosleep, nanosleep_error,
398246290Sdchagin		    error);
399246290Sdchagin		LIN_SDT_PROBE1(time, linux_clock_nanosleep, return, error);
400165408Sjkim		return (error);
401246290Sdchagin	}
402165408Sjkim
403161304Snetchild	if (args->rmtp != NULL) {
404161304Snetchild	   	native_to_linux_timespec(&lrmts, rmtp);
405161304Snetchild	   	error = copyout(&lrmts, args->rmtp, sizeof lrmts );
406246290Sdchagin		if (error != 0) {
407246290Sdchagin			LIN_SDT_PROBE1(time, linux_clock_nanosleep,
408246290Sdchagin			    copyout_error, error);
409246290Sdchagin			LIN_SDT_PROBE1(time, linux_nanosleep, return, error);
410165408Sjkim		   	return (error);
411246290Sdchagin		}
412161304Snetchild	}
413161304Snetchild
414246290Sdchagin	LIN_SDT_PROBE1(time, linux_clock_nanosleep, return, 0);
415165408Sjkim	return (0);
416161304Snetchild}
417