xref: /freebsd/sys/compat/linux/linux_time.c (revision ad2056f2c46cd6f28b2f7a4bd0e1a72198b19eee)
1ad2056f2SAlexander Leidinger /*	$NetBSD: linux_time.c,v 1.14 2006/05/14 03:40:54 christos Exp $ */
2ad2056f2SAlexander Leidinger 
3ad2056f2SAlexander Leidinger /*-
4ad2056f2SAlexander Leidinger  * Copyright (c) 2001 The NetBSD Foundation, Inc.
5ad2056f2SAlexander Leidinger  * All rights reserved.
6ad2056f2SAlexander Leidinger  *
7ad2056f2SAlexander Leidinger  * This code is derived from software contributed to The NetBSD Foundation
8ad2056f2SAlexander Leidinger  * by Emmanuel Dreyfus.
9ad2056f2SAlexander Leidinger  *
10ad2056f2SAlexander Leidinger  * Redistribution and use in source and binary forms, with or without
11ad2056f2SAlexander Leidinger  * modification, are permitted provided that the following conditions
12ad2056f2SAlexander Leidinger  * are met:
13ad2056f2SAlexander Leidinger  * 1. Redistributions of source code must retain the above copyright
14ad2056f2SAlexander Leidinger  *    notice, this list of conditions and the following disclaimer.
15ad2056f2SAlexander Leidinger  * 2. Redistributions in binary form must reproduce the above copyright
16ad2056f2SAlexander Leidinger  *    notice, this list of conditions and the following disclaimer in the
17ad2056f2SAlexander Leidinger  *    documentation and/or other materials provided with the distribution.
18ad2056f2SAlexander Leidinger  * 3. All advertising materials mentioning features or use of this software
19ad2056f2SAlexander Leidinger  *    must display the following acknowledgement:
20ad2056f2SAlexander Leidinger  *      This product includes software developed by the NetBSD
21ad2056f2SAlexander Leidinger  *      Foundation, Inc. and its contributors.
22ad2056f2SAlexander Leidinger  * 4. Neither the name of The NetBSD Foundation nor the names of its
23ad2056f2SAlexander Leidinger  *    contributors may be used to endorse or promote products derived
24ad2056f2SAlexander Leidinger  *    from this software without specific prior written permission.
25ad2056f2SAlexander Leidinger  *
26ad2056f2SAlexander Leidinger  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27ad2056f2SAlexander Leidinger  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28ad2056f2SAlexander Leidinger  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29ad2056f2SAlexander Leidinger  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30ad2056f2SAlexander Leidinger  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31ad2056f2SAlexander Leidinger  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32ad2056f2SAlexander Leidinger  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33ad2056f2SAlexander Leidinger  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34ad2056f2SAlexander Leidinger  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35ad2056f2SAlexander Leidinger  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36ad2056f2SAlexander Leidinger  * POSSIBILITY OF SUCH DAMAGE.
37ad2056f2SAlexander Leidinger  */
38ad2056f2SAlexander Leidinger 
39ad2056f2SAlexander Leidinger #include <sys/cdefs.h>
40ad2056f2SAlexander Leidinger __FBSDID("$FreeBSD$");
41ad2056f2SAlexander Leidinger #if 0
42ad2056f2SAlexander Leidinger __KERNEL_RCSID(0, "$NetBSD: linux_time.c,v 1.14 2006/05/14 03:40:54 christos Exp $");
43ad2056f2SAlexander Leidinger #endif
44ad2056f2SAlexander Leidinger 
45ad2056f2SAlexander Leidinger #include "opt_compat.h"
46ad2056f2SAlexander Leidinger 
47ad2056f2SAlexander Leidinger #include <sys/param.h>
48ad2056f2SAlexander Leidinger #include <sys/ucred.h>
49ad2056f2SAlexander Leidinger #include <sys/mount.h>
50ad2056f2SAlexander Leidinger #include <sys/signal.h>
51ad2056f2SAlexander Leidinger #include <sys/stdint.h>
52ad2056f2SAlexander Leidinger #include <sys/syscallsubr.h>
53ad2056f2SAlexander Leidinger #include <sys/sysproto.h>
54ad2056f2SAlexander Leidinger #include <sys/time.h>
55ad2056f2SAlexander Leidinger #include <sys/systm.h>
56ad2056f2SAlexander Leidinger #include <sys/proc.h>
57ad2056f2SAlexander Leidinger 
58ad2056f2SAlexander Leidinger #ifdef COMPAT_LINUX32
59ad2056f2SAlexander Leidinger #include <machine/../linux32/linux.h>
60ad2056f2SAlexander Leidinger #include <machine/../linux32/linux32_proto.h>
61ad2056f2SAlexander Leidinger #else
62ad2056f2SAlexander Leidinger #include <machine/../linux/linux.h>
63ad2056f2SAlexander Leidinger #include <machine/../linux/linux_proto.h>
64ad2056f2SAlexander Leidinger #endif
65ad2056f2SAlexander Leidinger 
66ad2056f2SAlexander Leidinger static void native_to_linux_timespec(struct l_timespec *,
67ad2056f2SAlexander Leidinger 				     struct timespec *);
68ad2056f2SAlexander Leidinger static void linux_to_native_timespec(struct timespec *,
69ad2056f2SAlexander Leidinger 				     struct l_timespec *);
70ad2056f2SAlexander Leidinger static int linux_to_native_clockid(clockid_t *, clockid_t);
71ad2056f2SAlexander Leidinger 
72ad2056f2SAlexander Leidinger static void
73ad2056f2SAlexander Leidinger native_to_linux_timespec(struct l_timespec *ltp, struct timespec *ntp)
74ad2056f2SAlexander Leidinger {
75ad2056f2SAlexander Leidinger 	ltp->tv_sec = ntp->tv_sec;
76ad2056f2SAlexander Leidinger 	ltp->tv_nsec = ntp->tv_nsec;
77ad2056f2SAlexander Leidinger }
78ad2056f2SAlexander Leidinger 
79ad2056f2SAlexander Leidinger static void
80ad2056f2SAlexander Leidinger linux_to_native_timespec(struct timespec *ntp, struct l_timespec *ltp)
81ad2056f2SAlexander Leidinger {
82ad2056f2SAlexander Leidinger 	ntp->tv_sec = ltp->tv_sec;
83ad2056f2SAlexander Leidinger 	ntp->tv_nsec = ltp->tv_nsec;
84ad2056f2SAlexander Leidinger }
85ad2056f2SAlexander Leidinger 
86ad2056f2SAlexander Leidinger static int
87ad2056f2SAlexander Leidinger linux_to_native_clockid(clockid_t *n, clockid_t l)
88ad2056f2SAlexander Leidinger {
89ad2056f2SAlexander Leidinger 	switch (l) {
90ad2056f2SAlexander Leidinger 	case LINUX_CLOCK_REALTIME:
91ad2056f2SAlexander Leidinger 		*n = CLOCK_REALTIME;
92ad2056f2SAlexander Leidinger 		break;
93ad2056f2SAlexander Leidinger 	case LINUX_CLOCK_MONOTONIC:
94ad2056f2SAlexander Leidinger 		*n = CLOCK_MONOTONIC;
95ad2056f2SAlexander Leidinger 		break;
96ad2056f2SAlexander Leidinger 	case LINUX_CLOCK_PROCESS_CPUTIME_ID:
97ad2056f2SAlexander Leidinger 	case LINUX_CLOCK_THREAD_CPUTIME_ID:
98ad2056f2SAlexander Leidinger 	case LINUX_CLOCK_REALTIME_HR:
99ad2056f2SAlexander Leidinger 	case LINUX_CLOCK_MONOTONIC_HR:
100ad2056f2SAlexander Leidinger 		return EINVAL;
101ad2056f2SAlexander Leidinger 	}
102ad2056f2SAlexander Leidinger 
103ad2056f2SAlexander Leidinger 	return 0;
104ad2056f2SAlexander Leidinger }
105ad2056f2SAlexander Leidinger 
106ad2056f2SAlexander Leidinger int
107ad2056f2SAlexander Leidinger linux_clock_gettime(struct thread *td, struct linux_clock_gettime_args *args)
108ad2056f2SAlexander Leidinger {
109ad2056f2SAlexander Leidinger 	struct l_timespec lts;
110ad2056f2SAlexander Leidinger 	int error;
111ad2056f2SAlexander Leidinger 	clockid_t nwhich = 0;	/* XXX: GCC */
112ad2056f2SAlexander Leidinger 	struct timespec tp;
113ad2056f2SAlexander Leidinger 
114ad2056f2SAlexander Leidinger 	error = linux_to_native_clockid(&nwhich, args->which);
115ad2056f2SAlexander Leidinger 	if (error != 0)
116ad2056f2SAlexander Leidinger 		return error;
117ad2056f2SAlexander Leidinger 
118ad2056f2SAlexander Leidinger 	error = kern_clock_gettime(td, nwhich, &tp);
119ad2056f2SAlexander Leidinger 	if (error != 0)
120ad2056f2SAlexander Leidinger 		return error;
121ad2056f2SAlexander Leidinger 
122ad2056f2SAlexander Leidinger 	native_to_linux_timespec(&lts, &tp);
123ad2056f2SAlexander Leidinger 
124ad2056f2SAlexander Leidinger 	return copyout(&lts, args->tp, sizeof lts);
125ad2056f2SAlexander Leidinger }
126ad2056f2SAlexander Leidinger 
127ad2056f2SAlexander Leidinger int
128ad2056f2SAlexander Leidinger linux_clock_settime(struct thread *td, struct linux_clock_settime_args *args)
129ad2056f2SAlexander Leidinger {
130ad2056f2SAlexander Leidinger 	struct timespec ts;
131ad2056f2SAlexander Leidinger 	struct l_timespec lts;
132ad2056f2SAlexander Leidinger 	int error;
133ad2056f2SAlexander Leidinger 	clockid_t nwhich = 0;	/* XXX: GCC */
134ad2056f2SAlexander Leidinger 
135ad2056f2SAlexander Leidinger 	error = linux_to_native_clockid(&nwhich, args->which);
136ad2056f2SAlexander Leidinger 	if (error != 0)
137ad2056f2SAlexander Leidinger 		return error;
138ad2056f2SAlexander Leidinger 
139ad2056f2SAlexander Leidinger 	error = copyin(args->tp, &lts, sizeof lts);
140ad2056f2SAlexander Leidinger 	if (error != 0)
141ad2056f2SAlexander Leidinger 		return error;
142ad2056f2SAlexander Leidinger 
143ad2056f2SAlexander Leidinger 	linux_to_native_timespec(&ts, &lts);
144ad2056f2SAlexander Leidinger 
145ad2056f2SAlexander Leidinger 	return kern_clock_settime(td, nwhich, &ts);
146ad2056f2SAlexander Leidinger }
147ad2056f2SAlexander Leidinger 
148ad2056f2SAlexander Leidinger int
149ad2056f2SAlexander Leidinger linux_clock_getres(struct thread *td, struct linux_clock_getres_args *args)
150ad2056f2SAlexander Leidinger {
151ad2056f2SAlexander Leidinger 	struct timespec ts;
152ad2056f2SAlexander Leidinger 	struct l_timespec lts;
153ad2056f2SAlexander Leidinger 	int error;
154ad2056f2SAlexander Leidinger 	clockid_t nwhich = 0;	/* XXX: GCC */
155ad2056f2SAlexander Leidinger 
156ad2056f2SAlexander Leidinger 	if (args->tp == NULL)
157ad2056f2SAlexander Leidinger 	  	return (0);
158ad2056f2SAlexander Leidinger 
159ad2056f2SAlexander Leidinger 	error = linux_to_native_clockid(&nwhich, args->which);
160ad2056f2SAlexander Leidinger 	if (error != 0)
161ad2056f2SAlexander Leidinger 		return error;
162ad2056f2SAlexander Leidinger 
163ad2056f2SAlexander Leidinger 	error = kern_clock_getres(td, nwhich, &ts);
164ad2056f2SAlexander Leidinger 	if (error != 0)
165ad2056f2SAlexander Leidinger 		return error;
166ad2056f2SAlexander Leidinger 
167ad2056f2SAlexander Leidinger 	native_to_linux_timespec(&lts, &ts);
168ad2056f2SAlexander Leidinger 
169ad2056f2SAlexander Leidinger 	return copyout(&lts, args->tp, sizeof lts);
170ad2056f2SAlexander Leidinger }
171ad2056f2SAlexander Leidinger 
172ad2056f2SAlexander Leidinger int
173ad2056f2SAlexander Leidinger linux_clock_nanosleep(struct thread *td, struct linux_clock_nanosleep_args *args)
174ad2056f2SAlexander Leidinger {
175ad2056f2SAlexander Leidinger 	struct timespec *rmtp;
176ad2056f2SAlexander Leidinger 	struct l_timespec lrqts, lrmts;
177ad2056f2SAlexander Leidinger 	struct timespec rqts, rmts;
178ad2056f2SAlexander Leidinger 	int error;
179ad2056f2SAlexander Leidinger 
180ad2056f2SAlexander Leidinger 	if (args->flags != 0)
181ad2056f2SAlexander Leidinger 		return EINVAL;		/* XXX deal with TIMER_ABSTIME */
182ad2056f2SAlexander Leidinger 
183ad2056f2SAlexander Leidinger 	if (args->which != LINUX_CLOCK_REALTIME)
184ad2056f2SAlexander Leidinger 		return EINVAL;
185ad2056f2SAlexander Leidinger 
186ad2056f2SAlexander Leidinger 	error = copyin(args->rqtp, &lrqts, sizeof lrqts);
187ad2056f2SAlexander Leidinger 	if (error != 0)
188ad2056f2SAlexander Leidinger 		return error;
189ad2056f2SAlexander Leidinger 
190ad2056f2SAlexander Leidinger 	if (args->rmtp != NULL)
191ad2056f2SAlexander Leidinger 	   	rmtp = &rmts;
192ad2056f2SAlexander Leidinger 	else
193ad2056f2SAlexander Leidinger 	   	rmtp = NULL;
194ad2056f2SAlexander Leidinger 
195ad2056f2SAlexander Leidinger 	linux_to_native_timespec(&rqts, &lrqts);
196ad2056f2SAlexander Leidinger 
197ad2056f2SAlexander Leidinger 	error = kern_nanosleep(td, &rqts, rmtp);
198ad2056f2SAlexander Leidinger 	if (error != 0)
199ad2056f2SAlexander Leidinger 		return error;
200ad2056f2SAlexander Leidinger 	if (args->rmtp != NULL) {
201ad2056f2SAlexander Leidinger 	   	native_to_linux_timespec(&lrmts, rmtp);
202ad2056f2SAlexander Leidinger 	   	error = copyout(&lrmts, args->rmtp, sizeof lrmts );
203ad2056f2SAlexander Leidinger 		if (error != 0)
204ad2056f2SAlexander Leidinger 		   	return error;
205ad2056f2SAlexander Leidinger 	}
206ad2056f2SAlexander Leidinger 
207ad2056f2SAlexander Leidinger 	return 0;
208ad2056f2SAlexander Leidinger }
209