Fri Nov 30 10:28:46 2018 UTC ()
Additionally pull up following revision(s) (requested by maxv in ticket #1110):

	sys/compat/linux/common/linux_misc_notalpha.c: revision 1.110
	sys/kern/kern_time.c: revision 1.193

Improve my kern_time.c::rev1.192, systematically clear the buffers we get
from 'ptimer_pool' to prevent more leaks.


(martin)
diff -r1.109 -r1.109.12.1 src/sys/compat/linux/common/linux_misc_notalpha.c
diff -r1.189.8.1 -r1.189.8.2 src/sys/kern/kern_time.c

cvs diff -r1.109 -r1.109.12.1 src/sys/compat/linux/common/linux_misc_notalpha.c (switch to unified diff)

--- src/sys/compat/linux/common/linux_misc_notalpha.c 2014/11/09 17:48:08 1.109
+++ src/sys/compat/linux/common/linux_misc_notalpha.c 2018/11/30 10:28:46 1.109.12.1
@@ -1,460 +1,461 @@ @@ -1,460 +1,461 @@
1/* $NetBSD: linux_misc_notalpha.c,v 1.109 2014/11/09 17:48:08 maxv Exp $ */ 1/* $NetBSD: linux_misc_notalpha.c,v 1.109.12.1 2018/11/30 10:28:46 martin Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 1995, 1998, 2008 The NetBSD Foundation, Inc. 4 * Copyright (c) 1995, 1998, 2008 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Frank van der Linden and Eric Haszlakiewicz; by Jason R. Thorpe 8 * by Frank van der Linden and Eric Haszlakiewicz; by Jason R. Thorpe
9 * of the Numerical Aerospace Simulation Facility, NASA Ames Research Center. 9 * of the Numerical Aerospace Simulation Facility, NASA Ames Research Center.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions 12 * modification, are permitted provided that the following conditions
13 * are met: 13 * are met:
14 * 1. Redistributions of source code must retain the above copyright 14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer. 15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright 16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the 17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution. 18 * documentation and/or other materials provided with the distribution.
19 * 19 *
20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE. 30 * POSSIBILITY OF SUCH DAMAGE.
31 */ 31 */
32 32
33#include <sys/cdefs.h> 33#include <sys/cdefs.h>
34__KERNEL_RCSID(0, "$NetBSD: linux_misc_notalpha.c,v 1.109 2014/11/09 17:48:08 maxv Exp $"); 34__KERNEL_RCSID(0, "$NetBSD: linux_misc_notalpha.c,v 1.109.12.1 2018/11/30 10:28:46 martin Exp $");
35 35
36/* 36/*
37 * Note that we must NOT include "opt_compat_linux32.h" here, 37 * Note that we must NOT include "opt_compat_linux32.h" here,
38 * the maze of ifdefs below relies on COMPAT_LINUX32 only being 38 * the maze of ifdefs below relies on COMPAT_LINUX32 only being
39 * defined when this file is built for linux32. 39 * defined when this file is built for linux32.
40 */ 40 */
41 41
42#include <sys/param.h> 42#include <sys/param.h>
43#include <sys/systm.h> 43#include <sys/systm.h>
44#include <sys/kernel.h> 44#include <sys/kernel.h>
45#include <sys/mman.h> 45#include <sys/mman.h>
46#include <sys/mount.h> 46#include <sys/mount.h>
47#include <sys/mbuf.h> 47#include <sys/mbuf.h>
48#include <sys/namei.h> 48#include <sys/namei.h>
49#include <sys/proc.h> 49#include <sys/proc.h>
50#include <sys/prot.h> 50#include <sys/prot.h>
51#include <sys/ptrace.h> 51#include <sys/ptrace.h>
52#include <sys/resource.h> 52#include <sys/resource.h>
53#include <sys/resourcevar.h> 53#include <sys/resourcevar.h>
54#include <sys/time.h> 54#include <sys/time.h>
55#include <sys/vfs_syscalls.h> 55#include <sys/vfs_syscalls.h>
56#include <sys/wait.h> 56#include <sys/wait.h>
57#include <sys/kauth.h> 57#include <sys/kauth.h>
58 58
59#include <sys/syscallargs.h> 59#include <sys/syscallargs.h>
60 60
61#include <compat/linux/common/linux_types.h> 61#include <compat/linux/common/linux_types.h>
62#include <compat/linux/common/linux_fcntl.h> 62#include <compat/linux/common/linux_fcntl.h>
63#include <compat/linux/common/linux_misc.h> 63#include <compat/linux/common/linux_misc.h>
64#include <compat/linux/common/linux_mmap.h> 64#include <compat/linux/common/linux_mmap.h>
65#include <compat/linux/common/linux_signal.h> 65#include <compat/linux/common/linux_signal.h>
66#include <compat/linux/common/linux_util.h> 66#include <compat/linux/common/linux_util.h>
67#include <compat/linux/common/linux_ipc.h> 67#include <compat/linux/common/linux_ipc.h>
68#include <compat/linux/common/linux_sem.h> 68#include <compat/linux/common/linux_sem.h>
69#include <compat/linux/common/linux_statfs.h> 69#include <compat/linux/common/linux_statfs.h>
70 70
71#include <compat/linux/linux_syscallargs.h> 71#include <compat/linux/linux_syscallargs.h>
72 72
73/* 73/*
74 * This file contains routines which are used 74 * This file contains routines which are used
75 * on every linux architechture except the Alpha. 75 * on every linux architechture except the Alpha.
76 */ 76 */
77 77
78/* Used on: arm, i386, m68k, mips, ppc, sparc, sparc64 */ 78/* Used on: arm, i386, m68k, mips, ppc, sparc, sparc64 */
79/* Not used on: alpha */ 79/* Not used on: alpha */
80 80
81#ifdef DEBUG_LINUX 81#ifdef DEBUG_LINUX
82#define DPRINTF(a) uprintf a 82#define DPRINTF(a) uprintf a
83#else 83#else
84#define DPRINTF(a) 84#define DPRINTF(a)
85#endif 85#endif
86 86
87#ifndef COMPAT_LINUX32 87#ifndef COMPAT_LINUX32
88 88
89/* 89/*
90 * Alarm. This is a libc call which uses setitimer(2) in NetBSD. 90 * Alarm. This is a libc call which uses setitimer(2) in NetBSD.
91 * Fiddle with the timers to make it work. 91 * Fiddle with the timers to make it work.
92 * 92 *
93 * XXX This shouldn't be dicking about with the ptimer stuff directly. 93 * XXX This shouldn't be dicking about with the ptimer stuff directly.
94 */ 94 */
95int 95int
96linux_sys_alarm(struct lwp *l, const struct linux_sys_alarm_args *uap, register_t *retval) 96linux_sys_alarm(struct lwp *l, const struct linux_sys_alarm_args *uap, register_t *retval)
97{ 97{
98 /* { 98 /* {
99 syscallarg(unsigned int) secs; 99 syscallarg(unsigned int) secs;
100 } */ 100 } */
101 struct proc *p = l->l_proc; 101 struct proc *p = l->l_proc;
102 struct timespec now; 102 struct timespec now;
103 struct itimerspec *itp, it; 103 struct itimerspec *itp, it;
104 struct ptimer *ptp, *spare; 104 struct ptimer *ptp, *spare;
105 extern kmutex_t timer_lock; 105 extern kmutex_t timer_lock;
106 struct ptimers *pts; 106 struct ptimers *pts;
107 107
108 if ((pts = p->p_timers) == NULL) 108 if ((pts = p->p_timers) == NULL)
109 pts = timers_alloc(p); 109 pts = timers_alloc(p);
110 spare = NULL; 110 spare = NULL;
111 111
112 retry: 112 retry:
113 mutex_spin_enter(&timer_lock); 113 mutex_spin_enter(&timer_lock);
114 if (pts && pts->pts_timers[ITIMER_REAL]) 114 if (pts && pts->pts_timers[ITIMER_REAL])
115 itp = &pts->pts_timers[ITIMER_REAL]->pt_time; 115 itp = &pts->pts_timers[ITIMER_REAL]->pt_time;
116 else 116 else
117 itp = NULL; 117 itp = NULL;
118 /* 118 /*
119 * Clear any pending timer alarms. 119 * Clear any pending timer alarms.
120 */ 120 */
121 if (itp) { 121 if (itp) {
122 callout_stop(&pts->pts_timers[ITIMER_REAL]->pt_ch); 122 callout_stop(&pts->pts_timers[ITIMER_REAL]->pt_ch);
123 timespecclear(&itp->it_interval); 123 timespecclear(&itp->it_interval);
124 getnanotime(&now); 124 getnanotime(&now);
125 if (timespecisset(&itp->it_value) && 125 if (timespecisset(&itp->it_value) &&
126 timespeccmp(&itp->it_value, &now, >)) 126 timespeccmp(&itp->it_value, &now, >))
127 timespecsub(&itp->it_value, &now, &itp->it_value); 127 timespecsub(&itp->it_value, &now, &itp->it_value);
128 /* 128 /*
129 * Return how many seconds were left (rounded up) 129 * Return how many seconds were left (rounded up)
130 */ 130 */
131 retval[0] = itp->it_value.tv_sec; 131 retval[0] = itp->it_value.tv_sec;
132 if (itp->it_value.tv_nsec) 132 if (itp->it_value.tv_nsec)
133 retval[0]++; 133 retval[0]++;
134 } else { 134 } else {
135 retval[0] = 0; 135 retval[0] = 0;
136 } 136 }
137 137
138 /* 138 /*
139 * alarm(0) just resets the timer. 139 * alarm(0) just resets the timer.
140 */ 140 */
141 if (SCARG(uap, secs) == 0) { 141 if (SCARG(uap, secs) == 0) {
142 if (itp) 142 if (itp)
143 timespecclear(&itp->it_value); 143 timespecclear(&itp->it_value);
144 mutex_spin_exit(&timer_lock); 144 mutex_spin_exit(&timer_lock);
145 return 0; 145 return 0;
146 } 146 }
147 147
148 /* 148 /*
149 * Check the new alarm time for sanity, and set it. 149 * Check the new alarm time for sanity, and set it.
150 */ 150 */
151 timespecclear(&it.it_interval); 151 timespecclear(&it.it_interval);
152 it.it_value.tv_sec = SCARG(uap, secs); 152 it.it_value.tv_sec = SCARG(uap, secs);
153 it.it_value.tv_nsec = 0; 153 it.it_value.tv_nsec = 0;
154 if (itimespecfix(&it.it_value) || itimespecfix(&it.it_interval)) { 154 if (itimespecfix(&it.it_value) || itimespecfix(&it.it_interval)) {
155 mutex_spin_exit(&timer_lock); 155 mutex_spin_exit(&timer_lock);
156 return (EINVAL); 156 return (EINVAL);
157 } 157 }
158 158
159 ptp = pts->pts_timers[ITIMER_REAL]; 159 ptp = pts->pts_timers[ITIMER_REAL];
160 if (ptp == NULL) { 160 if (ptp == NULL) {
161 if (spare == NULL) { 161 if (spare == NULL) {
162 mutex_spin_exit(&timer_lock); 162 mutex_spin_exit(&timer_lock);
163 spare = pool_get(&ptimer_pool, PR_WAITOK); 163 spare = pool_get(&ptimer_pool, PR_WAITOK);
 164 memset(spare, 0, sizeof(*spare));
164 goto retry; 165 goto retry;
165 } 166 }
166 ptp = spare; 167 ptp = spare;
167 spare = NULL; 168 spare = NULL;
168 ptp->pt_ev.sigev_notify = SIGEV_SIGNAL; 169 ptp->pt_ev.sigev_notify = SIGEV_SIGNAL;
169 ptp->pt_ev.sigev_signo = SIGALRM; 170 ptp->pt_ev.sigev_signo = SIGALRM;
170 ptp->pt_overruns = 0; 171 ptp->pt_overruns = 0;
171 ptp->pt_proc = p; 172 ptp->pt_proc = p;
172 ptp->pt_type = CLOCK_REALTIME; 173 ptp->pt_type = CLOCK_REALTIME;
173 ptp->pt_entry = CLOCK_REALTIME; 174 ptp->pt_entry = CLOCK_REALTIME;
174 ptp->pt_active = 0; 175 ptp->pt_active = 0;
175 ptp->pt_queued = 0; 176 ptp->pt_queued = 0;
176 callout_init(&ptp->pt_ch, CALLOUT_MPSAFE); 177 callout_init(&ptp->pt_ch, CALLOUT_MPSAFE);
177 pts->pts_timers[ITIMER_REAL] = ptp; 178 pts->pts_timers[ITIMER_REAL] = ptp;
178 } 179 }
179 180
180 if (timespecisset(&it.it_value)) { 181 if (timespecisset(&it.it_value)) {
181 /* 182 /*
182 * Don't need to check tvhzto() return value, here. 183 * Don't need to check tvhzto() return value, here.
183 * callout_reset() does it for us. 184 * callout_reset() does it for us.
184 */ 185 */
185 getnanotime(&now); 186 getnanotime(&now);
186 timespecadd(&it.it_value, &now, &it.it_value); 187 timespecadd(&it.it_value, &now, &it.it_value);
187 callout_reset(&ptp->pt_ch, tshzto(&it.it_value), 188 callout_reset(&ptp->pt_ch, tshzto(&it.it_value),
188 realtimerexpire, ptp); 189 realtimerexpire, ptp);
189 } 190 }
190 ptp->pt_time = it; 191 ptp->pt_time = it;
191 mutex_spin_exit(&timer_lock); 192 mutex_spin_exit(&timer_lock);
192 193
193 return 0; 194 return 0;
194} 195}
195#endif /* !COMPAT_LINUX32 */ 196#endif /* !COMPAT_LINUX32 */
196 197
197#if !defined(__amd64__) 198#if !defined(__amd64__)
198int 199int
199linux_sys_nice(struct lwp *l, const struct linux_sys_nice_args *uap, register_t *retval) 200linux_sys_nice(struct lwp *l, const struct linux_sys_nice_args *uap, register_t *retval)
200{ 201{
201 /* { 202 /* {
202 syscallarg(int) incr; 203 syscallarg(int) incr;
203 } */ 204 } */
204 struct proc *p = l->l_proc; 205 struct proc *p = l->l_proc;
205 struct sys_setpriority_args bsa; 206 struct sys_setpriority_args bsa;
206 int error; 207 int error;
207 208
208 SCARG(&bsa, which) = PRIO_PROCESS; 209 SCARG(&bsa, which) = PRIO_PROCESS;
209 SCARG(&bsa, who) = 0; 210 SCARG(&bsa, who) = 0;
210 SCARG(&bsa, prio) = p->p_nice - NZERO + SCARG(uap, incr); 211 SCARG(&bsa, prio) = p->p_nice - NZERO + SCARG(uap, incr);
211 212
212 error = sys_setpriority(l, &bsa, retval); 213 error = sys_setpriority(l, &bsa, retval);
213 return (error) ? EPERM : 0; 214 return (error) ? EPERM : 0;
214} 215}
215#endif /* !__amd64__ */ 216#endif /* !__amd64__ */
216 217
217#ifndef COMPAT_LINUX32 218#ifndef COMPAT_LINUX32
218#ifndef __amd64__ 219#ifndef __amd64__
219/* 220/*
220 * The old Linux readdir was only able to read one entry at a time, 221 * The old Linux readdir was only able to read one entry at a time,
221 * even though it had a 'count' argument. In fact, the emulation 222 * even though it had a 'count' argument. In fact, the emulation
222 * of the old call was better than the original, because it did handle 223 * of the old call was better than the original, because it did handle
223 * the count arg properly. Don't bother with it anymore now, and use 224 * the count arg properly. Don't bother with it anymore now, and use
224 * it to distinguish between old and new. The difference is that the 225 * it to distinguish between old and new. The difference is that the
225 * newer one actually does multiple entries, and the reclen field 226 * newer one actually does multiple entries, and the reclen field
226 * really is the reclen, not the namelength. 227 * really is the reclen, not the namelength.
227 */ 228 */
228int 229int
229linux_sys_readdir(struct lwp *l, const struct linux_sys_readdir_args *uap, register_t *retval) 230linux_sys_readdir(struct lwp *l, const struct linux_sys_readdir_args *uap, register_t *retval)
230{ 231{
231 /* { 232 /* {
232 syscallarg(int) fd; 233 syscallarg(int) fd;
233 syscallarg(struct linux_dirent *) dent; 234 syscallarg(struct linux_dirent *) dent;
234 syscallarg(unsigned int) count; 235 syscallarg(unsigned int) count;
235 } */ 236 } */
236 int error; 237 int error;
237 struct linux_sys_getdents_args da; 238 struct linux_sys_getdents_args da;
238 239
239 SCARG(&da, fd) = SCARG(uap, fd); 240 SCARG(&da, fd) = SCARG(uap, fd);
240 SCARG(&da, dent) = SCARG(uap, dent); 241 SCARG(&da, dent) = SCARG(uap, dent);
241 SCARG(&da, count) = 1; 242 SCARG(&da, count) = 1;
242 243
243 error = linux_sys_getdents(l, &da, retval); 244 error = linux_sys_getdents(l, &da, retval);
244 if (error == 0 && *retval > 1) 245 if (error == 0 && *retval > 1)
245 *retval = 1; 246 *retval = 1;
246 247
247 return error; 248 return error;
248} 249}
249#endif /* !amd64 */ 250#endif /* !amd64 */
250 251
251/* 252/*
252 * I wonder why Linux has gettimeofday() _and_ time().. Still, we 253 * I wonder why Linux has gettimeofday() _and_ time().. Still, we
253 * need to deal with it. 254 * need to deal with it.
254 */ 255 */
255int 256int
256linux_sys_time(struct lwp *l, const struct linux_sys_time_args *uap, register_t *retval) 257linux_sys_time(struct lwp *l, const struct linux_sys_time_args *uap, register_t *retval)
257{ 258{
258 /* { 259 /* {
259 syscallarg(linux_time_t) *t; 260 syscallarg(linux_time_t) *t;
260 } */ 261 } */
261 struct timeval atv; 262 struct timeval atv;
262 linux_time_t tt; 263 linux_time_t tt;
263 int error; 264 int error;
264 265
265 microtime(&atv); 266 microtime(&atv);
266 267
267 tt = atv.tv_sec; 268 tt = atv.tv_sec;
268 if (SCARG(uap, t) && (error = copyout(&tt, SCARG(uap, t), sizeof tt))) 269 if (SCARG(uap, t) && (error = copyout(&tt, SCARG(uap, t), sizeof tt)))
269 return error; 270 return error;
270 271
271 retval[0] = tt; 272 retval[0] = tt;
272 return 0; 273 return 0;
273} 274}
274 275
275/* 276/*
276 * utime(). Do conversion to things that utimes() understands, 277 * utime(). Do conversion to things that utimes() understands,
277 * and pass it on. 278 * and pass it on.
278 */ 279 */
279int 280int
280linux_sys_utime(struct lwp *l, const struct linux_sys_utime_args *uap, register_t *retval) 281linux_sys_utime(struct lwp *l, const struct linux_sys_utime_args *uap, register_t *retval)
281{ 282{
282 /* { 283 /* {
283 syscallarg(const char *) path; 284 syscallarg(const char *) path;
284 syscallarg(struct linux_utimbuf *)times; 285 syscallarg(struct linux_utimbuf *)times;
285 } */ 286 } */
286 int error; 287 int error;
287 struct timeval tv[2], *tvp; 288 struct timeval tv[2], *tvp;
288 struct linux_utimbuf lut; 289 struct linux_utimbuf lut;
289 290
290 if (SCARG(uap, times) != NULL) { 291 if (SCARG(uap, times) != NULL) {
291 if ((error = copyin(SCARG(uap, times), &lut, sizeof lut))) 292 if ((error = copyin(SCARG(uap, times), &lut, sizeof lut)))
292 return error; 293 return error;
293 tv[0].tv_usec = tv[1].tv_usec = 0; 294 tv[0].tv_usec = tv[1].tv_usec = 0;
294 tv[0].tv_sec = lut.l_actime; 295 tv[0].tv_sec = lut.l_actime;
295 tv[1].tv_sec = lut.l_modtime; 296 tv[1].tv_sec = lut.l_modtime;
296 tvp = tv; 297 tvp = tv;
297 } else 298 } else
298 tvp = NULL; 299 tvp = NULL;
299 300
300 return do_sys_utimes(l, NULL, SCARG(uap, path), FOLLOW, 301 return do_sys_utimes(l, NULL, SCARG(uap, path), FOLLOW,
301 tvp, UIO_SYSSPACE); 302 tvp, UIO_SYSSPACE);
302} 303}
303 304
304#ifndef __amd64__ 305#ifndef __amd64__
305/* 306/*
306 * waitpid(2). Just forward on to linux_sys_wait4 with a NULL rusage. 307 * waitpid(2). Just forward on to linux_sys_wait4 with a NULL rusage.
307 */ 308 */
308int 309int
309linux_sys_waitpid(struct lwp *l, const struct linux_sys_waitpid_args *uap, register_t *retval) 310linux_sys_waitpid(struct lwp *l, const struct linux_sys_waitpid_args *uap, register_t *retval)
310{ 311{
311 /* { 312 /* {
312 syscallarg(int) pid; 313 syscallarg(int) pid;
313 syscallarg(int *) status; 314 syscallarg(int *) status;
314 syscallarg(int) options; 315 syscallarg(int) options;
315 } */ 316 } */
316 struct linux_sys_wait4_args linux_w4a; 317 struct linux_sys_wait4_args linux_w4a;
317 318
318 SCARG(&linux_w4a, pid) = SCARG(uap, pid); 319 SCARG(&linux_w4a, pid) = SCARG(uap, pid);
319 SCARG(&linux_w4a, status) = SCARG(uap, status); 320 SCARG(&linux_w4a, status) = SCARG(uap, status);
320 SCARG(&linux_w4a, options) = SCARG(uap, options); 321 SCARG(&linux_w4a, options) = SCARG(uap, options);
321 SCARG(&linux_w4a, rusage) = NULL; 322 SCARG(&linux_w4a, rusage) = NULL;
322 323
323 return linux_sys_wait4(l, &linux_w4a, retval); 324 return linux_sys_wait4(l, &linux_w4a, retval);
324} 325}
325#endif /* !amd64 */ 326#endif /* !amd64 */
326 327
327int 328int
328linux_sys_setresgid(struct lwp *l, const struct linux_sys_setresgid_args *uap, register_t *retval) 329linux_sys_setresgid(struct lwp *l, const struct linux_sys_setresgid_args *uap, register_t *retval)
329{ 330{
330 /* { 331 /* {
331 syscallarg(gid_t) rgid; 332 syscallarg(gid_t) rgid;
332 syscallarg(gid_t) egid; 333 syscallarg(gid_t) egid;
333 syscallarg(gid_t) sgid; 334 syscallarg(gid_t) sgid;
334 } */ 335 } */
335 336
336 /* 337 /*
337 * Note: These checks are a little different than the NetBSD 338 * Note: These checks are a little different than the NetBSD
338 * setregid(2) call performs. This precisely follows the 339 * setregid(2) call performs. This precisely follows the
339 * behavior of the Linux kernel. 340 * behavior of the Linux kernel.
340 */ 341 */
341 return do_setresgid(l, SCARG(uap,rgid), SCARG(uap, egid), 342 return do_setresgid(l, SCARG(uap,rgid), SCARG(uap, egid),
342 SCARG(uap, sgid), 343 SCARG(uap, sgid),
343 ID_R_EQ_R | ID_R_EQ_E | ID_R_EQ_S | 344 ID_R_EQ_R | ID_R_EQ_E | ID_R_EQ_S |
344 ID_E_EQ_R | ID_E_EQ_E | ID_E_EQ_S | 345 ID_E_EQ_R | ID_E_EQ_E | ID_E_EQ_S |
345 ID_S_EQ_R | ID_S_EQ_E | ID_S_EQ_S ); 346 ID_S_EQ_R | ID_S_EQ_E | ID_S_EQ_S );
346} 347}
347 348
348int 349int
349linux_sys_getresgid(struct lwp *l, const struct linux_sys_getresgid_args *uap, register_t *retval) 350linux_sys_getresgid(struct lwp *l, const struct linux_sys_getresgid_args *uap, register_t *retval)
350{ 351{
351 /* { 352 /* {
352 syscallarg(gid_t *) rgid; 353 syscallarg(gid_t *) rgid;
353 syscallarg(gid_t *) egid; 354 syscallarg(gid_t *) egid;
354 syscallarg(gid_t *) sgid; 355 syscallarg(gid_t *) sgid;
355 } */ 356 } */
356 kauth_cred_t pc = l->l_cred; 357 kauth_cred_t pc = l->l_cred;
357 int error; 358 int error;
358 gid_t gid; 359 gid_t gid;
359 360
360 /* 361 /*
361 * Linux copies these values out to userspace like so: 362 * Linux copies these values out to userspace like so:
362 * 363 *
363 * 1. Copy out rgid. 364 * 1. Copy out rgid.
364 * 2. If that succeeds, copy out egid. 365 * 2. If that succeeds, copy out egid.
365 * 3. If both of those succeed, copy out sgid. 366 * 3. If both of those succeed, copy out sgid.
366 */ 367 */
367 gid = kauth_cred_getgid(pc); 368 gid = kauth_cred_getgid(pc);
368 if ((error = copyout(&gid, SCARG(uap, rgid), sizeof(gid_t))) != 0) 369 if ((error = copyout(&gid, SCARG(uap, rgid), sizeof(gid_t))) != 0)
369 return (error); 370 return (error);
370 371
371 gid = kauth_cred_getegid(pc); 372 gid = kauth_cred_getegid(pc);
372 if ((error = copyout(&gid, SCARG(uap, egid), sizeof(gid_t))) != 0) 373 if ((error = copyout(&gid, SCARG(uap, egid), sizeof(gid_t))) != 0)
373 return (error); 374 return (error);
374 375
375 gid = kauth_cred_getsvgid(pc); 376 gid = kauth_cred_getsvgid(pc);
376 377
377 return (copyout(&gid, SCARG(uap, sgid), sizeof(gid_t))); 378 return (copyout(&gid, SCARG(uap, sgid), sizeof(gid_t)));
378} 379}
379 380
380#ifndef __amd64__ 381#ifndef __amd64__
381/* 382/*
382 * I wonder why Linux has settimeofday() _and_ stime().. Still, we 383 * I wonder why Linux has settimeofday() _and_ stime().. Still, we
383 * need to deal with it. 384 * need to deal with it.
384 */ 385 */
385int 386int
386linux_sys_stime(struct lwp *l, const struct linux_sys_stime_args *uap, register_t *retval) 387linux_sys_stime(struct lwp *l, const struct linux_sys_stime_args *uap, register_t *retval)
387{ 388{
388 /* { 389 /* {
389 syscallarg(linux_time_t) *t; 390 syscallarg(linux_time_t) *t;
390 } */ 391 } */
391 struct timespec ats; 392 struct timespec ats;
392 linux_time_t tt; 393 linux_time_t tt;
393 int error; 394 int error;
394 395
395 if ((error = copyin(SCARG(uap, t), &tt, sizeof tt)) != 0) 396 if ((error = copyin(SCARG(uap, t), &tt, sizeof tt)) != 0)
396 return error; 397 return error;
397 398
398 ats.tv_sec = tt; 399 ats.tv_sec = tt;
399 ats.tv_nsec = 0; 400 ats.tv_nsec = 0;
400 401
401 if ((error = settime(l->l_proc, &ats))) 402 if ((error = settime(l->l_proc, &ats)))
402 return (error); 403 return (error);
403 404
404 return 0; 405 return 0;
405} 406}
406 407
407/* 408/*
408 * Implement the fs stat functions. Straightforward. 409 * Implement the fs stat functions. Straightforward.
409 */ 410 */
410int 411int
411linux_sys_statfs64(struct lwp *l, const struct linux_sys_statfs64_args *uap, register_t *retval) 412linux_sys_statfs64(struct lwp *l, const struct linux_sys_statfs64_args *uap, register_t *retval)
412{ 413{
413 /* { 414 /* {
414 syscallarg(const char *) path; 415 syscallarg(const char *) path;
415 syscallarg(size_t) sz; 416 syscallarg(size_t) sz;
416 syscallarg(struct linux_statfs64 *) sp; 417 syscallarg(struct linux_statfs64 *) sp;
417 } */ 418 } */
418 struct statvfs *sb; 419 struct statvfs *sb;
419 struct linux_statfs64 ltmp; 420 struct linux_statfs64 ltmp;
420 int error; 421 int error;
421 422
422 if (SCARG(uap, sz) != sizeof ltmp) 423 if (SCARG(uap, sz) != sizeof ltmp)
423 return (EINVAL); 424 return (EINVAL);
424 425
425 sb = STATVFSBUF_GET(); 426 sb = STATVFSBUF_GET();
426 error = do_sys_pstatvfs(l, SCARG(uap, path), ST_WAIT, sb); 427 error = do_sys_pstatvfs(l, SCARG(uap, path), ST_WAIT, sb);
427 if (error == 0) { 428 if (error == 0) {
428 bsd_to_linux_statfs64(sb, &ltmp); 429 bsd_to_linux_statfs64(sb, &ltmp);
429 error = copyout(&ltmp, SCARG(uap, sp), sizeof ltmp); 430 error = copyout(&ltmp, SCARG(uap, sp), sizeof ltmp);
430 } 431 }
431 STATVFSBUF_PUT(sb); 432 STATVFSBUF_PUT(sb);
432 return error; 433 return error;
433} 434}
434 435
435int 436int
436linux_sys_fstatfs64(struct lwp *l, const struct linux_sys_fstatfs64_args *uap, register_t *retval) 437linux_sys_fstatfs64(struct lwp *l, const struct linux_sys_fstatfs64_args *uap, register_t *retval)
437{ 438{
438 /* { 439 /* {
439 syscallarg(int) fd; 440 syscallarg(int) fd;
440 syscallarg(size_t) sz; 441 syscallarg(size_t) sz;
441 syscallarg(struct linux_statfs64 *) sp; 442 syscallarg(struct linux_statfs64 *) sp;
442 } */ 443 } */
443 struct statvfs *sb; 444 struct statvfs *sb;
444 struct linux_statfs64 ltmp; 445 struct linux_statfs64 ltmp;
445 int error; 446 int error;
446 447
447 if (SCARG(uap, sz) != sizeof ltmp) 448 if (SCARG(uap, sz) != sizeof ltmp)
448 return (EINVAL); 449 return (EINVAL);
449 450
450 sb = STATVFSBUF_GET(); 451 sb = STATVFSBUF_GET();
451 error = do_sys_fstatvfs(l, SCARG(uap, fd), ST_WAIT, sb); 452 error = do_sys_fstatvfs(l, SCARG(uap, fd), ST_WAIT, sb);
452 if (error == 0) { 453 if (error == 0) {
453 bsd_to_linux_statfs64(sb, &ltmp); 454 bsd_to_linux_statfs64(sb, &ltmp);
454 error = copyout(&ltmp, SCARG(uap, sp), sizeof ltmp); 455 error = copyout(&ltmp, SCARG(uap, sp), sizeof ltmp);
455 } 456 }
456 STATVFSBUF_PUT(sb); 457 STATVFSBUF_PUT(sb);
457 return error; 458 return error;
458} 459}
459#endif /* !__amd64__ */ 460#endif /* !__amd64__ */
460#endif /* !COMPAT_LINUX32 */ 461#endif /* !COMPAT_LINUX32 */

cvs diff -r1.189.8.1 -r1.189.8.2 src/sys/kern/kern_time.c (switch to unified diff)

--- src/sys/kern/kern_time.c 2018/11/29 08:48:38 1.189.8.1
+++ src/sys/kern/kern_time.c 2018/11/30 10:28:46 1.189.8.2
@@ -1,1494 +1,1495 @@ @@ -1,1494 +1,1495 @@
1/* $NetBSD: kern_time.c,v 1.189.8.1 2018/11/29 08:48:38 martin Exp $ */ 1/* $NetBSD: kern_time.c,v 1.189.8.2 2018/11/30 10:28:46 martin Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2000, 2004, 2005, 2007, 2008, 2009 The NetBSD Foundation, Inc. 4 * Copyright (c) 2000, 2004, 2005, 2007, 2008, 2009 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Christopher G. Demetriou, and by Andrew Doran. 8 * by Christopher G. Demetriou, and by Andrew Doran.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright 15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the 16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution. 17 * documentation and/or other materials provided with the distribution.
18 * 18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
32/* 32/*
33 * Copyright (c) 1982, 1986, 1989, 1993 33 * Copyright (c) 1982, 1986, 1989, 1993
34 * The Regents of the University of California. All rights reserved. 34 * The Regents of the University of California. All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions 37 * modification, are permitted provided that the following conditions
38 * are met: 38 * are met:
39 * 1. Redistributions of source code must retain the above copyright 39 * 1. Redistributions of source code must retain the above copyright
40 * notice, this list of conditions and the following disclaimer. 40 * notice, this list of conditions and the following disclaimer.
41 * 2. Redistributions in binary form must reproduce the above copyright 41 * 2. Redistributions in binary form must reproduce the above copyright
42 * notice, this list of conditions and the following disclaimer in the 42 * notice, this list of conditions and the following disclaimer in the
43 * documentation and/or other materials provided with the distribution. 43 * documentation and/or other materials provided with the distribution.
44 * 3. Neither the name of the University nor the names of its contributors 44 * 3. Neither the name of the University nor the names of its contributors
45 * may be used to endorse or promote products derived from this software 45 * may be used to endorse or promote products derived from this software
46 * without specific prior written permission. 46 * without specific prior written permission.
47 * 47 *
48 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 48 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
49 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 49 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
50 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 50 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
51 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 51 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
52 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 52 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
53 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 53 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
54 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 54 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
55 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 55 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
56 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 56 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
57 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 57 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
58 * SUCH DAMAGE. 58 * SUCH DAMAGE.
59 * 59 *
60 * @(#)kern_time.c 8.4 (Berkeley) 5/26/95 60 * @(#)kern_time.c 8.4 (Berkeley) 5/26/95
61 */ 61 */
62 62
63#include <sys/cdefs.h> 63#include <sys/cdefs.h>
64__KERNEL_RCSID(0, "$NetBSD: kern_time.c,v 1.189.8.1 2018/11/29 08:48:38 martin Exp $"); 64__KERNEL_RCSID(0, "$NetBSD: kern_time.c,v 1.189.8.2 2018/11/30 10:28:46 martin Exp $");
65 65
66#include <sys/param.h> 66#include <sys/param.h>
67#include <sys/resourcevar.h> 67#include <sys/resourcevar.h>
68#include <sys/kernel.h> 68#include <sys/kernel.h>
69#include <sys/systm.h> 69#include <sys/systm.h>
70#include <sys/proc.h> 70#include <sys/proc.h>
71#include <sys/vnode.h> 71#include <sys/vnode.h>
72#include <sys/signalvar.h> 72#include <sys/signalvar.h>
73#include <sys/syslog.h> 73#include <sys/syslog.h>
74#include <sys/timetc.h> 74#include <sys/timetc.h>
75#include <sys/timex.h> 75#include <sys/timex.h>
76#include <sys/kauth.h> 76#include <sys/kauth.h>
77#include <sys/mount.h> 77#include <sys/mount.h>
78#include <sys/syscallargs.h> 78#include <sys/syscallargs.h>
79#include <sys/cpu.h> 79#include <sys/cpu.h>
80 80
81static void timer_intr(void *); 81static void timer_intr(void *);
82static void itimerfire(struct ptimer *); 82static void itimerfire(struct ptimer *);
83static void itimerfree(struct ptimers *, int); 83static void itimerfree(struct ptimers *, int);
84 84
85kmutex_t timer_lock; 85kmutex_t timer_lock;
86 86
87static void *timer_sih; 87static void *timer_sih;
88static TAILQ_HEAD(, ptimer) timer_queue; 88static TAILQ_HEAD(, ptimer) timer_queue;
89 89
90struct pool ptimer_pool, ptimers_pool; 90struct pool ptimer_pool, ptimers_pool;
91 91
92#define CLOCK_VIRTUAL_P(clockid) \ 92#define CLOCK_VIRTUAL_P(clockid) \
93 ((clockid) == CLOCK_VIRTUAL || (clockid) == CLOCK_PROF) 93 ((clockid) == CLOCK_VIRTUAL || (clockid) == CLOCK_PROF)
94 94
95CTASSERT(ITIMER_REAL == CLOCK_REALTIME); 95CTASSERT(ITIMER_REAL == CLOCK_REALTIME);
96CTASSERT(ITIMER_VIRTUAL == CLOCK_VIRTUAL); 96CTASSERT(ITIMER_VIRTUAL == CLOCK_VIRTUAL);
97CTASSERT(ITIMER_PROF == CLOCK_PROF); 97CTASSERT(ITIMER_PROF == CLOCK_PROF);
98CTASSERT(ITIMER_MONOTONIC == CLOCK_MONOTONIC); 98CTASSERT(ITIMER_MONOTONIC == CLOCK_MONOTONIC);
99 99
100#define DELAYTIMER_MAX 32 100#define DELAYTIMER_MAX 32
101 101
102/* 102/*
103 * Initialize timekeeping. 103 * Initialize timekeeping.
104 */ 104 */
105void 105void
106time_init(void) 106time_init(void)
107{ 107{
108 108
109 pool_init(&ptimer_pool, sizeof(struct ptimer), 0, 0, 0, "ptimerpl", 109 pool_init(&ptimer_pool, sizeof(struct ptimer), 0, 0, 0, "ptimerpl",
110 &pool_allocator_nointr, IPL_NONE); 110 &pool_allocator_nointr, IPL_NONE);
111 pool_init(&ptimers_pool, sizeof(struct ptimers), 0, 0, 0, "ptimerspl", 111 pool_init(&ptimers_pool, sizeof(struct ptimers), 0, 0, 0, "ptimerspl",
112 &pool_allocator_nointr, IPL_NONE); 112 &pool_allocator_nointr, IPL_NONE);
113} 113}
114 114
115void 115void
116time_init2(void) 116time_init2(void)
117{ 117{
118 118
119 TAILQ_INIT(&timer_queue); 119 TAILQ_INIT(&timer_queue);
120 mutex_init(&timer_lock, MUTEX_DEFAULT, IPL_SCHED); 120 mutex_init(&timer_lock, MUTEX_DEFAULT, IPL_SCHED);
121 timer_sih = softint_establish(SOFTINT_CLOCK | SOFTINT_MPSAFE, 121 timer_sih = softint_establish(SOFTINT_CLOCK | SOFTINT_MPSAFE,
122 timer_intr, NULL); 122 timer_intr, NULL);
123} 123}
124 124
125/* Time of day and interval timer support. 125/* Time of day and interval timer support.
126 * 126 *
127 * These routines provide the kernel entry points to get and set 127 * These routines provide the kernel entry points to get and set
128 * the time-of-day and per-process interval timers. Subroutines 128 * the time-of-day and per-process interval timers. Subroutines
129 * here provide support for adding and subtracting timeval structures 129 * here provide support for adding and subtracting timeval structures
130 * and decrementing interval timers, optionally reloading the interval 130 * and decrementing interval timers, optionally reloading the interval
131 * timers when they expire. 131 * timers when they expire.
132 */ 132 */
133 133
134/* This function is used by clock_settime and settimeofday */ 134/* This function is used by clock_settime and settimeofday */
135static int 135static int
136settime1(struct proc *p, const struct timespec *ts, bool check_kauth) 136settime1(struct proc *p, const struct timespec *ts, bool check_kauth)
137{ 137{
138 struct timespec delta, now; 138 struct timespec delta, now;
139 int s; 139 int s;
140 140
141 /* WHAT DO WE DO ABOUT PENDING REAL-TIME TIMEOUTS??? */ 141 /* WHAT DO WE DO ABOUT PENDING REAL-TIME TIMEOUTS??? */
142 s = splclock(); 142 s = splclock();
143 nanotime(&now); 143 nanotime(&now);
144 timespecsub(ts, &now, &delta); 144 timespecsub(ts, &now, &delta);
145 145
146 if (check_kauth && kauth_authorize_system(kauth_cred_get(), 146 if (check_kauth && kauth_authorize_system(kauth_cred_get(),
147 KAUTH_SYSTEM_TIME, KAUTH_REQ_SYSTEM_TIME_SYSTEM, __UNCONST(ts), 147 KAUTH_SYSTEM_TIME, KAUTH_REQ_SYSTEM_TIME_SYSTEM, __UNCONST(ts),
148 &delta, KAUTH_ARG(check_kauth ? false : true)) != 0) { 148 &delta, KAUTH_ARG(check_kauth ? false : true)) != 0) {
149 splx(s); 149 splx(s);
150 return (EPERM); 150 return (EPERM);
151 } 151 }
152 152
153#ifdef notyet 153#ifdef notyet
154 if ((delta.tv_sec < 86400) && securelevel > 0) { /* XXX elad - notyet */ 154 if ((delta.tv_sec < 86400) && securelevel > 0) { /* XXX elad - notyet */
155 splx(s); 155 splx(s);
156 return (EPERM); 156 return (EPERM);
157 } 157 }
158#endif 158#endif
159 159
160 tc_setclock(ts); 160 tc_setclock(ts);
161 161
162 timespecadd(&boottime, &delta, &boottime); 162 timespecadd(&boottime, &delta, &boottime);
163 163
164 resettodr(); 164 resettodr();
165 splx(s); 165 splx(s);
166 166
167 return (0); 167 return (0);
168} 168}
169 169
170int 170int
171settime(struct proc *p, struct timespec *ts) 171settime(struct proc *p, struct timespec *ts)
172{ 172{
173 return (settime1(p, ts, true)); 173 return (settime1(p, ts, true));
174} 174}
175 175
176/* ARGSUSED */ 176/* ARGSUSED */
177int 177int
178sys___clock_gettime50(struct lwp *l, 178sys___clock_gettime50(struct lwp *l,
179 const struct sys___clock_gettime50_args *uap, register_t *retval) 179 const struct sys___clock_gettime50_args *uap, register_t *retval)
180{ 180{
181 /* { 181 /* {
182 syscallarg(clockid_t) clock_id; 182 syscallarg(clockid_t) clock_id;
183 syscallarg(struct timespec *) tp; 183 syscallarg(struct timespec *) tp;
184 } */ 184 } */
185 int error; 185 int error;
186 struct timespec ats; 186 struct timespec ats;
187 187
188 error = clock_gettime1(SCARG(uap, clock_id), &ats); 188 error = clock_gettime1(SCARG(uap, clock_id), &ats);
189 if (error != 0) 189 if (error != 0)
190 return error; 190 return error;
191 191
192 return copyout(&ats, SCARG(uap, tp), sizeof(ats)); 192 return copyout(&ats, SCARG(uap, tp), sizeof(ats));
193} 193}
194 194
195/* ARGSUSED */ 195/* ARGSUSED */
196int 196int
197sys___clock_settime50(struct lwp *l, 197sys___clock_settime50(struct lwp *l,
198 const struct sys___clock_settime50_args *uap, register_t *retval) 198 const struct sys___clock_settime50_args *uap, register_t *retval)
199{ 199{
200 /* { 200 /* {
201 syscallarg(clockid_t) clock_id; 201 syscallarg(clockid_t) clock_id;
202 syscallarg(const struct timespec *) tp; 202 syscallarg(const struct timespec *) tp;
203 } */ 203 } */
204 int error; 204 int error;
205 struct timespec ats; 205 struct timespec ats;
206 206
207 if ((error = copyin(SCARG(uap, tp), &ats, sizeof(ats))) != 0) 207 if ((error = copyin(SCARG(uap, tp), &ats, sizeof(ats))) != 0)
208 return error; 208 return error;
209 209
210 return clock_settime1(l->l_proc, SCARG(uap, clock_id), &ats, true); 210 return clock_settime1(l->l_proc, SCARG(uap, clock_id), &ats, true);
211} 211}
212 212
213 213
214int 214int
215clock_settime1(struct proc *p, clockid_t clock_id, const struct timespec *tp, 215clock_settime1(struct proc *p, clockid_t clock_id, const struct timespec *tp,
216 bool check_kauth) 216 bool check_kauth)
217{ 217{
218 int error; 218 int error;
219 219
220 switch (clock_id) { 220 switch (clock_id) {
221 case CLOCK_REALTIME: 221 case CLOCK_REALTIME:
222 if ((error = settime1(p, tp, check_kauth)) != 0) 222 if ((error = settime1(p, tp, check_kauth)) != 0)
223 return (error); 223 return (error);
224 break; 224 break;
225 case CLOCK_MONOTONIC: 225 case CLOCK_MONOTONIC:
226 return (EINVAL); /* read-only clock */ 226 return (EINVAL); /* read-only clock */
227 default: 227 default:
228 return (EINVAL); 228 return (EINVAL);
229 } 229 }
230 230
231 return 0; 231 return 0;
232} 232}
233 233
234int 234int
235sys___clock_getres50(struct lwp *l, const struct sys___clock_getres50_args *uap, 235sys___clock_getres50(struct lwp *l, const struct sys___clock_getres50_args *uap,
236 register_t *retval) 236 register_t *retval)
237{ 237{
238 /* { 238 /* {
239 syscallarg(clockid_t) clock_id; 239 syscallarg(clockid_t) clock_id;
240 syscallarg(struct timespec *) tp; 240 syscallarg(struct timespec *) tp;
241 } */ 241 } */
242 struct timespec ts; 242 struct timespec ts;
243 int error; 243 int error;
244 244
245 if ((error = clock_getres1(SCARG(uap, clock_id), &ts)) != 0) 245 if ((error = clock_getres1(SCARG(uap, clock_id), &ts)) != 0)
246 return error; 246 return error;
247 247
248 if (SCARG(uap, tp)) 248 if (SCARG(uap, tp))
249 error = copyout(&ts, SCARG(uap, tp), sizeof(ts)); 249 error = copyout(&ts, SCARG(uap, tp), sizeof(ts));
250 250
251 return error; 251 return error;
252} 252}
253 253
254int 254int
255clock_getres1(clockid_t clock_id, struct timespec *ts) 255clock_getres1(clockid_t clock_id, struct timespec *ts)
256{ 256{
257 257
258 switch (clock_id) { 258 switch (clock_id) {
259 case CLOCK_REALTIME: 259 case CLOCK_REALTIME:
260 case CLOCK_MONOTONIC: 260 case CLOCK_MONOTONIC:
261 ts->tv_sec = 0; 261 ts->tv_sec = 0;
262 if (tc_getfrequency() > 1000000000) 262 if (tc_getfrequency() > 1000000000)
263 ts->tv_nsec = 1; 263 ts->tv_nsec = 1;
264 else 264 else
265 ts->tv_nsec = 1000000000 / tc_getfrequency(); 265 ts->tv_nsec = 1000000000 / tc_getfrequency();
266 break; 266 break;
267 default: 267 default:
268 return EINVAL; 268 return EINVAL;
269 } 269 }
270 270
271 return 0; 271 return 0;
272} 272}
273 273
274/* ARGSUSED */ 274/* ARGSUSED */
275int 275int
276sys___nanosleep50(struct lwp *l, const struct sys___nanosleep50_args *uap, 276sys___nanosleep50(struct lwp *l, const struct sys___nanosleep50_args *uap,
277 register_t *retval) 277 register_t *retval)
278{ 278{
279 /* { 279 /* {
280 syscallarg(struct timespec *) rqtp; 280 syscallarg(struct timespec *) rqtp;
281 syscallarg(struct timespec *) rmtp; 281 syscallarg(struct timespec *) rmtp;
282 } */ 282 } */
283 struct timespec rmt, rqt; 283 struct timespec rmt, rqt;
284 int error, error1; 284 int error, error1;
285 285
286 error = copyin(SCARG(uap, rqtp), &rqt, sizeof(struct timespec)); 286 error = copyin(SCARG(uap, rqtp), &rqt, sizeof(struct timespec));
287 if (error) 287 if (error)
288 return (error); 288 return (error);
289 289
290 error = nanosleep1(l, CLOCK_MONOTONIC, 0, &rqt, 290 error = nanosleep1(l, CLOCK_MONOTONIC, 0, &rqt,
291 SCARG(uap, rmtp) ? &rmt : NULL); 291 SCARG(uap, rmtp) ? &rmt : NULL);
292 if (SCARG(uap, rmtp) == NULL || (error != 0 && error != EINTR)) 292 if (SCARG(uap, rmtp) == NULL || (error != 0 && error != EINTR))
293 return error; 293 return error;
294 294
295 error1 = copyout(&rmt, SCARG(uap, rmtp), sizeof(rmt)); 295 error1 = copyout(&rmt, SCARG(uap, rmtp), sizeof(rmt));
296 return error1 ? error1 : error; 296 return error1 ? error1 : error;
297} 297}
298 298
299/* ARGSUSED */ 299/* ARGSUSED */
300int 300int
301sys_clock_nanosleep(struct lwp *l, const struct sys_clock_nanosleep_args *uap, 301sys_clock_nanosleep(struct lwp *l, const struct sys_clock_nanosleep_args *uap,
302 register_t *retval) 302 register_t *retval)
303{ 303{
304 /* { 304 /* {
305 syscallarg(clockid_t) clock_id; 305 syscallarg(clockid_t) clock_id;
306 syscallarg(int) flags; 306 syscallarg(int) flags;
307 syscallarg(struct timespec *) rqtp; 307 syscallarg(struct timespec *) rqtp;
308 syscallarg(struct timespec *) rmtp; 308 syscallarg(struct timespec *) rmtp;
309 } */ 309 } */
310 struct timespec rmt, rqt; 310 struct timespec rmt, rqt;
311 int error, error1; 311 int error, error1;
312 312
313 error = copyin(SCARG(uap, rqtp), &rqt, sizeof(struct timespec)); 313 error = copyin(SCARG(uap, rqtp), &rqt, sizeof(struct timespec));
314 if (error) 314 if (error)
315 goto out; 315 goto out;
316 316
317 error = nanosleep1(l, SCARG(uap, clock_id), SCARG(uap, flags), &rqt, 317 error = nanosleep1(l, SCARG(uap, clock_id), SCARG(uap, flags), &rqt,
318 SCARG(uap, rmtp) ? &rmt : NULL); 318 SCARG(uap, rmtp) ? &rmt : NULL);
319 if (SCARG(uap, rmtp) == NULL || (error != 0 && error != EINTR)) 319 if (SCARG(uap, rmtp) == NULL || (error != 0 && error != EINTR))
320 goto out; 320 goto out;
321 321
322 if ((SCARG(uap, flags) & TIMER_ABSTIME) == 0 && 322 if ((SCARG(uap, flags) & TIMER_ABSTIME) == 0 &&
323 (error1 = copyout(&rmt, SCARG(uap, rmtp), sizeof(rmt))) != 0) 323 (error1 = copyout(&rmt, SCARG(uap, rmtp), sizeof(rmt))) != 0)
324 error = error1; 324 error = error1;
325out: 325out:
326 *retval = error; 326 *retval = error;
327 return 0; 327 return 0;
328} 328}
329 329
330int 330int
331nanosleep1(struct lwp *l, clockid_t clock_id, int flags, struct timespec *rqt, 331nanosleep1(struct lwp *l, clockid_t clock_id, int flags, struct timespec *rqt,
332 struct timespec *rmt) 332 struct timespec *rmt)
333{ 333{
334 struct timespec rmtstart; 334 struct timespec rmtstart;
335 int error, timo; 335 int error, timo;
336 336
337 if ((error = ts2timo(clock_id, flags, rqt, &timo, &rmtstart)) != 0) { 337 if ((error = ts2timo(clock_id, flags, rqt, &timo, &rmtstart)) != 0) {
338 if (error == ETIMEDOUT) { 338 if (error == ETIMEDOUT) {
339 error = 0; 339 error = 0;
340 if (rmt != NULL) 340 if (rmt != NULL)
341 rmt->tv_sec = rmt->tv_nsec = 0; 341 rmt->tv_sec = rmt->tv_nsec = 0;
342 } 342 }
343 return error; 343 return error;
344 } 344 }
345 345
346 /* 346 /*
347 * Avoid inadvertently sleeping forever 347 * Avoid inadvertently sleeping forever
348 */ 348 */
349 if (timo == 0) 349 if (timo == 0)
350 timo = 1; 350 timo = 1;
351again: 351again:
352 error = kpause("nanoslp", true, timo, NULL); 352 error = kpause("nanoslp", true, timo, NULL);
353 if (rmt != NULL || error == 0) { 353 if (rmt != NULL || error == 0) {
354 struct timespec rmtend; 354 struct timespec rmtend;
355 struct timespec t0; 355 struct timespec t0;
356 struct timespec *t; 356 struct timespec *t;
357 357
358 (void)clock_gettime1(clock_id, &rmtend); 358 (void)clock_gettime1(clock_id, &rmtend);
359 t = (rmt != NULL) ? rmt : &t0; 359 t = (rmt != NULL) ? rmt : &t0;
360 if (flags & TIMER_ABSTIME) { 360 if (flags & TIMER_ABSTIME) {
361 timespecsub(rqt, &rmtend, t); 361 timespecsub(rqt, &rmtend, t);
362 } else { 362 } else {
363 timespecsub(&rmtend, &rmtstart, t); 363 timespecsub(&rmtend, &rmtstart, t);
364 timespecsub(rqt, t, t); 364 timespecsub(rqt, t, t);
365 } 365 }
366 if (t->tv_sec < 0) 366 if (t->tv_sec < 0)
367 timespecclear(t); 367 timespecclear(t);
368 if (error == 0) { 368 if (error == 0) {
369 timo = tstohz(t); 369 timo = tstohz(t);
370 if (timo > 0) 370 if (timo > 0)
371 goto again; 371 goto again;
372 } 372 }
373 } 373 }
374 374
375 if (error == ERESTART) 375 if (error == ERESTART)
376 error = EINTR; 376 error = EINTR;
377 if (error == EWOULDBLOCK) 377 if (error == EWOULDBLOCK)
378 error = 0; 378 error = 0;
379 379
380 return error; 380 return error;
381} 381}
382 382
383int 383int
384sys_clock_getcpuclockid2(struct lwp *l, 384sys_clock_getcpuclockid2(struct lwp *l,
385 const struct sys_clock_getcpuclockid2_args *uap, 385 const struct sys_clock_getcpuclockid2_args *uap,
386 register_t *retval) 386 register_t *retval)
387{ 387{
388 /* { 388 /* {
389 syscallarg(idtype_t idtype; 389 syscallarg(idtype_t idtype;
390 syscallarg(id_t id); 390 syscallarg(id_t id);
391 syscallarg(clockid_t *)clock_id; 391 syscallarg(clockid_t *)clock_id;
392 } */ 392 } */
393 pid_t pid; 393 pid_t pid;
394 lwpid_t lid; 394 lwpid_t lid;
395 clockid_t clock_id; 395 clockid_t clock_id;
396 id_t id = SCARG(uap, id); 396 id_t id = SCARG(uap, id);
397 397
398 switch (SCARG(uap, idtype)) { 398 switch (SCARG(uap, idtype)) {
399 case P_PID: 399 case P_PID:
400 pid = id == 0 ? l->l_proc->p_pid : id; 400 pid = id == 0 ? l->l_proc->p_pid : id;
401 clock_id = CLOCK_PROCESS_CPUTIME_ID | pid; 401 clock_id = CLOCK_PROCESS_CPUTIME_ID | pid;
402 break; 402 break;
403 case P_LWPID: 403 case P_LWPID:
404 lid = id == 0 ? l->l_lid : id; 404 lid = id == 0 ? l->l_lid : id;
405 clock_id = CLOCK_THREAD_CPUTIME_ID | lid; 405 clock_id = CLOCK_THREAD_CPUTIME_ID | lid;
406 break; 406 break;
407 default: 407 default:
408 return EINVAL; 408 return EINVAL;
409 } 409 }
410 return copyout(&clock_id, SCARG(uap, clock_id), sizeof(clock_id)); 410 return copyout(&clock_id, SCARG(uap, clock_id), sizeof(clock_id));
411} 411}
412 412
413/* ARGSUSED */ 413/* ARGSUSED */
414int 414int
415sys___gettimeofday50(struct lwp *l, const struct sys___gettimeofday50_args *uap, 415sys___gettimeofday50(struct lwp *l, const struct sys___gettimeofday50_args *uap,
416 register_t *retval) 416 register_t *retval)
417{ 417{
418 /* { 418 /* {
419 syscallarg(struct timeval *) tp; 419 syscallarg(struct timeval *) tp;
420 syscallarg(void *) tzp; really "struct timezone *"; 420 syscallarg(void *) tzp; really "struct timezone *";
421 } */ 421 } */
422 struct timeval atv; 422 struct timeval atv;
423 int error = 0; 423 int error = 0;
424 struct timezone tzfake; 424 struct timezone tzfake;
425 425
426 if (SCARG(uap, tp)) { 426 if (SCARG(uap, tp)) {
427 microtime(&atv); 427 microtime(&atv);
428 error = copyout(&atv, SCARG(uap, tp), sizeof(atv)); 428 error = copyout(&atv, SCARG(uap, tp), sizeof(atv));
429 if (error) 429 if (error)
430 return (error); 430 return (error);
431 } 431 }
432 if (SCARG(uap, tzp)) { 432 if (SCARG(uap, tzp)) {
433 /* 433 /*
434 * NetBSD has no kernel notion of time zone, so we just 434 * NetBSD has no kernel notion of time zone, so we just
435 * fake up a timezone struct and return it if demanded. 435 * fake up a timezone struct and return it if demanded.
436 */ 436 */
437 tzfake.tz_minuteswest = 0; 437 tzfake.tz_minuteswest = 0;
438 tzfake.tz_dsttime = 0; 438 tzfake.tz_dsttime = 0;
439 error = copyout(&tzfake, SCARG(uap, tzp), sizeof(tzfake)); 439 error = copyout(&tzfake, SCARG(uap, tzp), sizeof(tzfake));
440 } 440 }
441 return (error); 441 return (error);
442} 442}
443 443
444/* ARGSUSED */ 444/* ARGSUSED */
445int 445int
446sys___settimeofday50(struct lwp *l, const struct sys___settimeofday50_args *uap, 446sys___settimeofday50(struct lwp *l, const struct sys___settimeofday50_args *uap,
447 register_t *retval) 447 register_t *retval)
448{ 448{
449 /* { 449 /* {
450 syscallarg(const struct timeval *) tv; 450 syscallarg(const struct timeval *) tv;
451 syscallarg(const void *) tzp; really "const struct timezone *"; 451 syscallarg(const void *) tzp; really "const struct timezone *";
452 } */ 452 } */
453 453
454 return settimeofday1(SCARG(uap, tv), true, SCARG(uap, tzp), l, true); 454 return settimeofday1(SCARG(uap, tv), true, SCARG(uap, tzp), l, true);
455} 455}
456 456
457int 457int
458settimeofday1(const struct timeval *utv, bool userspace, 458settimeofday1(const struct timeval *utv, bool userspace,
459 const void *utzp, struct lwp *l, bool check_kauth) 459 const void *utzp, struct lwp *l, bool check_kauth)
460{ 460{
461 struct timeval atv; 461 struct timeval atv;
462 struct timespec ts; 462 struct timespec ts;
463 int error; 463 int error;
464 464
465 /* Verify all parameters before changing time. */ 465 /* Verify all parameters before changing time. */
466 466
467 /* 467 /*
468 * NetBSD has no kernel notion of time zone, and only an 468 * NetBSD has no kernel notion of time zone, and only an
469 * obsolete program would try to set it, so we log a warning. 469 * obsolete program would try to set it, so we log a warning.
470 */ 470 */
471 if (utzp) 471 if (utzp)
472 log(LOG_WARNING, "pid %d attempted to set the " 472 log(LOG_WARNING, "pid %d attempted to set the "
473 "(obsolete) kernel time zone\n", l->l_proc->p_pid); 473 "(obsolete) kernel time zone\n", l->l_proc->p_pid);
474 474
475 if (utv == NULL)  475 if (utv == NULL)
476 return 0; 476 return 0;
477 477
478 if (userspace) { 478 if (userspace) {
479 if ((error = copyin(utv, &atv, sizeof(atv))) != 0) 479 if ((error = copyin(utv, &atv, sizeof(atv))) != 0)
480 return error; 480 return error;
481 utv = &atv; 481 utv = &atv;
482 } 482 }
483 483
484 TIMEVAL_TO_TIMESPEC(utv, &ts); 484 TIMEVAL_TO_TIMESPEC(utv, &ts);
485 return settime1(l->l_proc, &ts, check_kauth); 485 return settime1(l->l_proc, &ts, check_kauth);
486} 486}
487 487
488int time_adjusted; /* set if an adjustment is made */ 488int time_adjusted; /* set if an adjustment is made */
489 489
490/* ARGSUSED */ 490/* ARGSUSED */
491int 491int
492sys___adjtime50(struct lwp *l, const struct sys___adjtime50_args *uap, 492sys___adjtime50(struct lwp *l, const struct sys___adjtime50_args *uap,
493 register_t *retval) 493 register_t *retval)
494{ 494{
495 /* { 495 /* {
496 syscallarg(const struct timeval *) delta; 496 syscallarg(const struct timeval *) delta;
497 syscallarg(struct timeval *) olddelta; 497 syscallarg(struct timeval *) olddelta;
498 } */ 498 } */
499 int error; 499 int error;
500 struct timeval atv, oldatv; 500 struct timeval atv, oldatv;
501 501
502 if ((error = kauth_authorize_system(l->l_cred, KAUTH_SYSTEM_TIME, 502 if ((error = kauth_authorize_system(l->l_cred, KAUTH_SYSTEM_TIME,
503 KAUTH_REQ_SYSTEM_TIME_ADJTIME, NULL, NULL, NULL)) != 0) 503 KAUTH_REQ_SYSTEM_TIME_ADJTIME, NULL, NULL, NULL)) != 0)
504 return error; 504 return error;
505 505
506 if (SCARG(uap, delta)) { 506 if (SCARG(uap, delta)) {
507 error = copyin(SCARG(uap, delta), &atv, 507 error = copyin(SCARG(uap, delta), &atv,
508 sizeof(*SCARG(uap, delta))); 508 sizeof(*SCARG(uap, delta)));
509 if (error) 509 if (error)
510 return (error); 510 return (error);
511 } 511 }
512 adjtime1(SCARG(uap, delta) ? &atv : NULL, 512 adjtime1(SCARG(uap, delta) ? &atv : NULL,
513 SCARG(uap, olddelta) ? &oldatv : NULL, l->l_proc); 513 SCARG(uap, olddelta) ? &oldatv : NULL, l->l_proc);
514 if (SCARG(uap, olddelta)) 514 if (SCARG(uap, olddelta))
515 error = copyout(&oldatv, SCARG(uap, olddelta), 515 error = copyout(&oldatv, SCARG(uap, olddelta),
516 sizeof(*SCARG(uap, olddelta))); 516 sizeof(*SCARG(uap, olddelta)));
517 return error; 517 return error;
518} 518}
519 519
520void 520void
521adjtime1(const struct timeval *delta, struct timeval *olddelta, struct proc *p) 521adjtime1(const struct timeval *delta, struct timeval *olddelta, struct proc *p)
522{ 522{
523 extern int64_t time_adjtime; /* in kern_ntptime.c */ 523 extern int64_t time_adjtime; /* in kern_ntptime.c */
524 524
525 if (olddelta) { 525 if (olddelta) {
526 mutex_spin_enter(&timecounter_lock); 526 mutex_spin_enter(&timecounter_lock);
527 olddelta->tv_sec = time_adjtime / 1000000; 527 olddelta->tv_sec = time_adjtime / 1000000;
528 olddelta->tv_usec = time_adjtime % 1000000; 528 olddelta->tv_usec = time_adjtime % 1000000;
529 if (olddelta->tv_usec < 0) { 529 if (olddelta->tv_usec < 0) {
530 olddelta->tv_usec += 1000000; 530 olddelta->tv_usec += 1000000;
531 olddelta->tv_sec--; 531 olddelta->tv_sec--;
532 } 532 }
533 mutex_spin_exit(&timecounter_lock); 533 mutex_spin_exit(&timecounter_lock);
534 } 534 }
535  535
536 if (delta) { 536 if (delta) {
537 mutex_spin_enter(&timecounter_lock); 537 mutex_spin_enter(&timecounter_lock);
538 time_adjtime = delta->tv_sec * 1000000 + delta->tv_usec; 538 time_adjtime = delta->tv_sec * 1000000 + delta->tv_usec;
539 539
540 if (time_adjtime) { 540 if (time_adjtime) {
541 /* We need to save the system time during shutdown */ 541 /* We need to save the system time during shutdown */
542 time_adjusted |= 1; 542 time_adjusted |= 1;
543 } 543 }
544 mutex_spin_exit(&timecounter_lock); 544 mutex_spin_exit(&timecounter_lock);
545 } 545 }
546} 546}
547 547
548/* 548/*
549 * Interval timer support. Both the BSD getitimer() family and the POSIX 549 * Interval timer support. Both the BSD getitimer() family and the POSIX
550 * timer_*() family of routines are supported. 550 * timer_*() family of routines are supported.
551 * 551 *
552 * All timers are kept in an array pointed to by p_timers, which is 552 * All timers are kept in an array pointed to by p_timers, which is
553 * allocated on demand - many processes don't use timers at all. The 553 * allocated on demand - many processes don't use timers at all. The
554 * first four elements in this array are reserved for the BSD timers: 554 * first four elements in this array are reserved for the BSD timers:
555 * element 0 is ITIMER_REAL, element 1 is ITIMER_VIRTUAL, element 555 * element 0 is ITIMER_REAL, element 1 is ITIMER_VIRTUAL, element
556 * 2 is ITIMER_PROF, and element 3 is ITIMER_MONOTONIC. The rest may be 556 * 2 is ITIMER_PROF, and element 3 is ITIMER_MONOTONIC. The rest may be
557 * allocated by the timer_create() syscall. 557 * allocated by the timer_create() syscall.
558 * 558 *
559 * Realtime timers are kept in the ptimer structure as an absolute 559 * Realtime timers are kept in the ptimer structure as an absolute
560 * time; virtual time timers are kept as a linked list of deltas. 560 * time; virtual time timers are kept as a linked list of deltas.
561 * Virtual time timers are processed in the hardclock() routine of 561 * Virtual time timers are processed in the hardclock() routine of
562 * kern_clock.c. The real time timer is processed by a callout 562 * kern_clock.c. The real time timer is processed by a callout
563 * routine, called from the softclock() routine. Since a callout may 563 * routine, called from the softclock() routine. Since a callout may
564 * be delayed in real time due to interrupt processing in the system, 564 * be delayed in real time due to interrupt processing in the system,
565 * it is possible for the real time timeout routine (realtimeexpire, 565 * it is possible for the real time timeout routine (realtimeexpire,
566 * given below), to be delayed in real time past when it is supposed 566 * given below), to be delayed in real time past when it is supposed
567 * to occur. It does not suffice, therefore, to reload the real timer 567 * to occur. It does not suffice, therefore, to reload the real timer
568 * .it_value from the real time timers .it_interval. Rather, we 568 * .it_value from the real time timers .it_interval. Rather, we
569 * compute the next time in absolute time the timer should go off. */ 569 * compute the next time in absolute time the timer should go off. */
570 570
571/* Allocate a POSIX realtime timer. */ 571/* Allocate a POSIX realtime timer. */
572int 572int
573sys_timer_create(struct lwp *l, const struct sys_timer_create_args *uap, 573sys_timer_create(struct lwp *l, const struct sys_timer_create_args *uap,
574 register_t *retval) 574 register_t *retval)
575{ 575{
576 /* { 576 /* {
577 syscallarg(clockid_t) clock_id; 577 syscallarg(clockid_t) clock_id;
578 syscallarg(struct sigevent *) evp; 578 syscallarg(struct sigevent *) evp;
579 syscallarg(timer_t *) timerid; 579 syscallarg(timer_t *) timerid;
580 } */ 580 } */
581 581
582 return timer_create1(SCARG(uap, timerid), SCARG(uap, clock_id), 582 return timer_create1(SCARG(uap, timerid), SCARG(uap, clock_id),
583 SCARG(uap, evp), copyin, l); 583 SCARG(uap, evp), copyin, l);
584} 584}
585 585
586int 586int
587timer_create1(timer_t *tid, clockid_t id, struct sigevent *evp, 587timer_create1(timer_t *tid, clockid_t id, struct sigevent *evp,
588 copyin_t fetch_event, struct lwp *l) 588 copyin_t fetch_event, struct lwp *l)
589{ 589{
590 int error; 590 int error;
591 timer_t timerid; 591 timer_t timerid;
592 struct ptimers *pts; 592 struct ptimers *pts;
593 struct ptimer *pt; 593 struct ptimer *pt;
594 struct proc *p; 594 struct proc *p;
595 595
596 p = l->l_proc; 596 p = l->l_proc;
597 597
598 if ((u_int)id > CLOCK_MONOTONIC) 598 if ((u_int)id > CLOCK_MONOTONIC)
599 return (EINVAL); 599 return (EINVAL);
600 600
601 if ((pts = p->p_timers) == NULL) 601 if ((pts = p->p_timers) == NULL)
602 pts = timers_alloc(p); 602 pts = timers_alloc(p);
603 603
604 pt = pool_get(&ptimer_pool, PR_WAITOK); 604 pt = pool_get(&ptimer_pool, PR_WAITOK);
605 memset(pt, 0, sizeof(*pt)); 605 memset(pt, 0, sizeof(*pt));
606 if (evp != NULL) { 606 if (evp != NULL) {
607 if (((error = 607 if (((error =
608 (*fetch_event)(evp, &pt->pt_ev, sizeof(pt->pt_ev))) != 0) || 608 (*fetch_event)(evp, &pt->pt_ev, sizeof(pt->pt_ev))) != 0) ||
609 ((pt->pt_ev.sigev_notify < SIGEV_NONE) || 609 ((pt->pt_ev.sigev_notify < SIGEV_NONE) ||
610 (pt->pt_ev.sigev_notify > SIGEV_SA)) || 610 (pt->pt_ev.sigev_notify > SIGEV_SA)) ||
611 (pt->pt_ev.sigev_notify == SIGEV_SIGNAL && 611 (pt->pt_ev.sigev_notify == SIGEV_SIGNAL &&
612 (pt->pt_ev.sigev_signo <= 0 || 612 (pt->pt_ev.sigev_signo <= 0 ||
613 pt->pt_ev.sigev_signo >= NSIG))) { 613 pt->pt_ev.sigev_signo >= NSIG))) {
614 pool_put(&ptimer_pool, pt); 614 pool_put(&ptimer_pool, pt);
615 return (error ? error : EINVAL); 615 return (error ? error : EINVAL);
616 } 616 }
617 } 617 }
618 618
619 /* Find a free timer slot, skipping those reserved for setitimer(). */ 619 /* Find a free timer slot, skipping those reserved for setitimer(). */
620 mutex_spin_enter(&timer_lock); 620 mutex_spin_enter(&timer_lock);
621 for (timerid = TIMER_MIN; timerid < TIMER_MAX; timerid++) 621 for (timerid = TIMER_MIN; timerid < TIMER_MAX; timerid++)
622 if (pts->pts_timers[timerid] == NULL) 622 if (pts->pts_timers[timerid] == NULL)
623 break; 623 break;
624 if (timerid == TIMER_MAX) { 624 if (timerid == TIMER_MAX) {
625 mutex_spin_exit(&timer_lock); 625 mutex_spin_exit(&timer_lock);
626 pool_put(&ptimer_pool, pt); 626 pool_put(&ptimer_pool, pt);
627 return EAGAIN; 627 return EAGAIN;
628 } 628 }
629 if (evp == NULL) { 629 if (evp == NULL) {
630 pt->pt_ev.sigev_notify = SIGEV_SIGNAL; 630 pt->pt_ev.sigev_notify = SIGEV_SIGNAL;
631 switch (id) { 631 switch (id) {
632 case CLOCK_REALTIME: 632 case CLOCK_REALTIME:
633 case CLOCK_MONOTONIC: 633 case CLOCK_MONOTONIC:
634 pt->pt_ev.sigev_signo = SIGALRM; 634 pt->pt_ev.sigev_signo = SIGALRM;
635 break; 635 break;
636 case CLOCK_VIRTUAL: 636 case CLOCK_VIRTUAL:
637 pt->pt_ev.sigev_signo = SIGVTALRM; 637 pt->pt_ev.sigev_signo = SIGVTALRM;
638 break; 638 break;
639 case CLOCK_PROF: 639 case CLOCK_PROF:
640 pt->pt_ev.sigev_signo = SIGPROF; 640 pt->pt_ev.sigev_signo = SIGPROF;
641 break; 641 break;
642 } 642 }
643 pt->pt_ev.sigev_value.sival_int = timerid; 643 pt->pt_ev.sigev_value.sival_int = timerid;
644 } 644 }
645 pt->pt_info.ksi_signo = pt->pt_ev.sigev_signo; 645 pt->pt_info.ksi_signo = pt->pt_ev.sigev_signo;
646 pt->pt_info.ksi_errno = 0; 646 pt->pt_info.ksi_errno = 0;
647 pt->pt_info.ksi_code = 0; 647 pt->pt_info.ksi_code = 0;
648 pt->pt_info.ksi_pid = p->p_pid; 648 pt->pt_info.ksi_pid = p->p_pid;
649 pt->pt_info.ksi_uid = kauth_cred_getuid(l->l_cred); 649 pt->pt_info.ksi_uid = kauth_cred_getuid(l->l_cred);
650 pt->pt_info.ksi_value = pt->pt_ev.sigev_value; 650 pt->pt_info.ksi_value = pt->pt_ev.sigev_value;
651 pt->pt_type = id; 651 pt->pt_type = id;
652 pt->pt_proc = p; 652 pt->pt_proc = p;
653 pt->pt_overruns = 0; 653 pt->pt_overruns = 0;
654 pt->pt_poverruns = 0; 654 pt->pt_poverruns = 0;
655 pt->pt_entry = timerid; 655 pt->pt_entry = timerid;
656 pt->pt_queued = false; 656 pt->pt_queued = false;
657 timespecclear(&pt->pt_time.it_value); 657 timespecclear(&pt->pt_time.it_value);
658 if (!CLOCK_VIRTUAL_P(id)) 658 if (!CLOCK_VIRTUAL_P(id))
659 callout_init(&pt->pt_ch, CALLOUT_MPSAFE); 659 callout_init(&pt->pt_ch, CALLOUT_MPSAFE);
660 else 660 else
661 pt->pt_active = 0; 661 pt->pt_active = 0;
662 662
663 pts->pts_timers[timerid] = pt; 663 pts->pts_timers[timerid] = pt;
664 mutex_spin_exit(&timer_lock); 664 mutex_spin_exit(&timer_lock);
665 665
666 return copyout(&timerid, tid, sizeof(timerid)); 666 return copyout(&timerid, tid, sizeof(timerid));
667} 667}
668 668
669/* Delete a POSIX realtime timer */ 669/* Delete a POSIX realtime timer */
670int 670int
671sys_timer_delete(struct lwp *l, const struct sys_timer_delete_args *uap, 671sys_timer_delete(struct lwp *l, const struct sys_timer_delete_args *uap,
672 register_t *retval) 672 register_t *retval)
673{ 673{
674 /* { 674 /* {
675 syscallarg(timer_t) timerid; 675 syscallarg(timer_t) timerid;
676 } */ 676 } */
677 struct proc *p = l->l_proc; 677 struct proc *p = l->l_proc;
678 timer_t timerid; 678 timer_t timerid;
679 struct ptimers *pts; 679 struct ptimers *pts;
680 struct ptimer *pt, *ptn; 680 struct ptimer *pt, *ptn;
681 681
682 timerid = SCARG(uap, timerid); 682 timerid = SCARG(uap, timerid);
683 pts = p->p_timers; 683 pts = p->p_timers;
684  684
685 if (pts == NULL || timerid < 2 || timerid >= TIMER_MAX) 685 if (pts == NULL || timerid < 2 || timerid >= TIMER_MAX)
686 return (EINVAL); 686 return (EINVAL);
687 687
688 mutex_spin_enter(&timer_lock); 688 mutex_spin_enter(&timer_lock);
689 if ((pt = pts->pts_timers[timerid]) == NULL) { 689 if ((pt = pts->pts_timers[timerid]) == NULL) {
690 mutex_spin_exit(&timer_lock); 690 mutex_spin_exit(&timer_lock);
691 return (EINVAL); 691 return (EINVAL);
692 } 692 }
693 if (CLOCK_VIRTUAL_P(pt->pt_type)) { 693 if (CLOCK_VIRTUAL_P(pt->pt_type)) {
694 if (pt->pt_active) { 694 if (pt->pt_active) {
695 ptn = LIST_NEXT(pt, pt_list); 695 ptn = LIST_NEXT(pt, pt_list);
696 LIST_REMOVE(pt, pt_list); 696 LIST_REMOVE(pt, pt_list);
697 for ( ; ptn; ptn = LIST_NEXT(ptn, pt_list)) 697 for ( ; ptn; ptn = LIST_NEXT(ptn, pt_list))
698 timespecadd(&pt->pt_time.it_value, 698 timespecadd(&pt->pt_time.it_value,
699 &ptn->pt_time.it_value, 699 &ptn->pt_time.it_value,
700 &ptn->pt_time.it_value); 700 &ptn->pt_time.it_value);
701 pt->pt_active = 0; 701 pt->pt_active = 0;
702 } 702 }
703 } 703 }
704 itimerfree(pts, timerid); 704 itimerfree(pts, timerid);
705 705
706 return (0); 706 return (0);
707} 707}
708 708
709/* 709/*
710 * Set up the given timer. The value in pt->pt_time.it_value is taken 710 * Set up the given timer. The value in pt->pt_time.it_value is taken
711 * to be an absolute time for CLOCK_REALTIME/CLOCK_MONOTONIC timers and 711 * to be an absolute time for CLOCK_REALTIME/CLOCK_MONOTONIC timers and
712 * a relative time for CLOCK_VIRTUAL/CLOCK_PROF timers. 712 * a relative time for CLOCK_VIRTUAL/CLOCK_PROF timers.
713 */ 713 */
714void 714void
715timer_settime(struct ptimer *pt) 715timer_settime(struct ptimer *pt)
716{ 716{
717 struct ptimer *ptn, *pptn; 717 struct ptimer *ptn, *pptn;
718 struct ptlist *ptl; 718 struct ptlist *ptl;
719 719
720 KASSERT(mutex_owned(&timer_lock)); 720 KASSERT(mutex_owned(&timer_lock));
721 721
722 if (!CLOCK_VIRTUAL_P(pt->pt_type)) { 722 if (!CLOCK_VIRTUAL_P(pt->pt_type)) {
723 callout_halt(&pt->pt_ch, &timer_lock); 723 callout_halt(&pt->pt_ch, &timer_lock);
724 if (timespecisset(&pt->pt_time.it_value)) { 724 if (timespecisset(&pt->pt_time.it_value)) {
725 /* 725 /*
726 * Don't need to check tshzto() return value, here. 726 * Don't need to check tshzto() return value, here.
727 * callout_reset() does it for us. 727 * callout_reset() does it for us.
728 */ 728 */
729 callout_reset(&pt->pt_ch, 729 callout_reset(&pt->pt_ch,
730 pt->pt_type == CLOCK_MONOTONIC ? 730 pt->pt_type == CLOCK_MONOTONIC ?
731 tshztoup(&pt->pt_time.it_value) : 731 tshztoup(&pt->pt_time.it_value) :
732 tshzto(&pt->pt_time.it_value), 732 tshzto(&pt->pt_time.it_value),
733 realtimerexpire, pt); 733 realtimerexpire, pt);
734 } 734 }
735 } else { 735 } else {
736 if (pt->pt_active) { 736 if (pt->pt_active) {
737 ptn = LIST_NEXT(pt, pt_list); 737 ptn = LIST_NEXT(pt, pt_list);
738 LIST_REMOVE(pt, pt_list); 738 LIST_REMOVE(pt, pt_list);
739 for ( ; ptn; ptn = LIST_NEXT(ptn, pt_list)) 739 for ( ; ptn; ptn = LIST_NEXT(ptn, pt_list))
740 timespecadd(&pt->pt_time.it_value, 740 timespecadd(&pt->pt_time.it_value,
741 &ptn->pt_time.it_value, 741 &ptn->pt_time.it_value,
742 &ptn->pt_time.it_value); 742 &ptn->pt_time.it_value);
743 } 743 }
744 if (timespecisset(&pt->pt_time.it_value)) { 744 if (timespecisset(&pt->pt_time.it_value)) {
745 if (pt->pt_type == CLOCK_VIRTUAL) 745 if (pt->pt_type == CLOCK_VIRTUAL)
746 ptl = &pt->pt_proc->p_timers->pts_virtual; 746 ptl = &pt->pt_proc->p_timers->pts_virtual;
747 else 747 else
748 ptl = &pt->pt_proc->p_timers->pts_prof; 748 ptl = &pt->pt_proc->p_timers->pts_prof;
749 749
750 for (ptn = LIST_FIRST(ptl), pptn = NULL; 750 for (ptn = LIST_FIRST(ptl), pptn = NULL;
751 ptn && timespeccmp(&pt->pt_time.it_value, 751 ptn && timespeccmp(&pt->pt_time.it_value,
752 &ptn->pt_time.it_value, >); 752 &ptn->pt_time.it_value, >);
753 pptn = ptn, ptn = LIST_NEXT(ptn, pt_list)) 753 pptn = ptn, ptn = LIST_NEXT(ptn, pt_list))
754 timespecsub(&pt->pt_time.it_value, 754 timespecsub(&pt->pt_time.it_value,
755 &ptn->pt_time.it_value, 755 &ptn->pt_time.it_value,
756 &pt->pt_time.it_value); 756 &pt->pt_time.it_value);
757 757
758 if (pptn) 758 if (pptn)
759 LIST_INSERT_AFTER(pptn, pt, pt_list); 759 LIST_INSERT_AFTER(pptn, pt, pt_list);
760 else 760 else
761 LIST_INSERT_HEAD(ptl, pt, pt_list); 761 LIST_INSERT_HEAD(ptl, pt, pt_list);
762 762
763 for ( ; ptn ; ptn = LIST_NEXT(ptn, pt_list)) 763 for ( ; ptn ; ptn = LIST_NEXT(ptn, pt_list))
764 timespecsub(&ptn->pt_time.it_value, 764 timespecsub(&ptn->pt_time.it_value,
765 &pt->pt_time.it_value, 765 &pt->pt_time.it_value,
766 &ptn->pt_time.it_value); 766 &ptn->pt_time.it_value);
767 767
768 pt->pt_active = 1; 768 pt->pt_active = 1;
769 } else 769 } else
770 pt->pt_active = 0; 770 pt->pt_active = 0;
771 } 771 }
772} 772}
773 773
774void 774void
775timer_gettime(struct ptimer *pt, struct itimerspec *aits) 775timer_gettime(struct ptimer *pt, struct itimerspec *aits)
776{ 776{
777 struct timespec now; 777 struct timespec now;
778 struct ptimer *ptn; 778 struct ptimer *ptn;
779 779
780 KASSERT(mutex_owned(&timer_lock)); 780 KASSERT(mutex_owned(&timer_lock));
781 781
782 *aits = pt->pt_time; 782 *aits = pt->pt_time;
783 if (!CLOCK_VIRTUAL_P(pt->pt_type)) { 783 if (!CLOCK_VIRTUAL_P(pt->pt_type)) {
784 /* 784 /*
785 * Convert from absolute to relative time in .it_value 785 * Convert from absolute to relative time in .it_value
786 * part of real time timer. If time for real time 786 * part of real time timer. If time for real time
787 * timer has passed return 0, else return difference 787 * timer has passed return 0, else return difference
788 * between current time and time for the timer to go 788 * between current time and time for the timer to go
789 * off. 789 * off.
790 */ 790 */
791 if (timespecisset(&aits->it_value)) { 791 if (timespecisset(&aits->it_value)) {
792 if (pt->pt_type == CLOCK_REALTIME) { 792 if (pt->pt_type == CLOCK_REALTIME) {
793 getnanotime(&now); 793 getnanotime(&now);
794 } else { /* CLOCK_MONOTONIC */ 794 } else { /* CLOCK_MONOTONIC */
795 getnanouptime(&now); 795 getnanouptime(&now);
796 } 796 }
797 if (timespeccmp(&aits->it_value, &now, <)) 797 if (timespeccmp(&aits->it_value, &now, <))
798 timespecclear(&aits->it_value); 798 timespecclear(&aits->it_value);
799 else 799 else
800 timespecsub(&aits->it_value, &now, 800 timespecsub(&aits->it_value, &now,
801 &aits->it_value); 801 &aits->it_value);
802 } 802 }
803 } else if (pt->pt_active) { 803 } else if (pt->pt_active) {
804 if (pt->pt_type == CLOCK_VIRTUAL) 804 if (pt->pt_type == CLOCK_VIRTUAL)
805 ptn = LIST_FIRST(&pt->pt_proc->p_timers->pts_virtual); 805 ptn = LIST_FIRST(&pt->pt_proc->p_timers->pts_virtual);
806 else 806 else
807 ptn = LIST_FIRST(&pt->pt_proc->p_timers->pts_prof); 807 ptn = LIST_FIRST(&pt->pt_proc->p_timers->pts_prof);
808 for ( ; ptn && ptn != pt; ptn = LIST_NEXT(ptn, pt_list)) 808 for ( ; ptn && ptn != pt; ptn = LIST_NEXT(ptn, pt_list))
809 timespecadd(&aits->it_value, 809 timespecadd(&aits->it_value,
810 &ptn->pt_time.it_value, &aits->it_value); 810 &ptn->pt_time.it_value, &aits->it_value);
811 KASSERT(ptn != NULL); /* pt should be findable on the list */ 811 KASSERT(ptn != NULL); /* pt should be findable on the list */
812 } else 812 } else
813 timespecclear(&aits->it_value); 813 timespecclear(&aits->it_value);
814} 814}
815 815
816 816
817 817
818/* Set and arm a POSIX realtime timer */ 818/* Set and arm a POSIX realtime timer */
819int 819int
820sys___timer_settime50(struct lwp *l, 820sys___timer_settime50(struct lwp *l,
821 const struct sys___timer_settime50_args *uap, 821 const struct sys___timer_settime50_args *uap,
822 register_t *retval) 822 register_t *retval)
823{ 823{
824 /* { 824 /* {
825 syscallarg(timer_t) timerid; 825 syscallarg(timer_t) timerid;
826 syscallarg(int) flags; 826 syscallarg(int) flags;
827 syscallarg(const struct itimerspec *) value; 827 syscallarg(const struct itimerspec *) value;
828 syscallarg(struct itimerspec *) ovalue; 828 syscallarg(struct itimerspec *) ovalue;
829 } */ 829 } */
830 int error; 830 int error;
831 struct itimerspec value, ovalue, *ovp = NULL; 831 struct itimerspec value, ovalue, *ovp = NULL;
832 832
833 if ((error = copyin(SCARG(uap, value), &value, 833 if ((error = copyin(SCARG(uap, value), &value,
834 sizeof(struct itimerspec))) != 0) 834 sizeof(struct itimerspec))) != 0)
835 return (error); 835 return (error);
836 836
837 if (SCARG(uap, ovalue)) 837 if (SCARG(uap, ovalue))
838 ovp = &ovalue; 838 ovp = &ovalue;
839 839
840 if ((error = dotimer_settime(SCARG(uap, timerid), &value, ovp, 840 if ((error = dotimer_settime(SCARG(uap, timerid), &value, ovp,
841 SCARG(uap, flags), l->l_proc)) != 0) 841 SCARG(uap, flags), l->l_proc)) != 0)
842 return error; 842 return error;
843 843
844 if (ovp) 844 if (ovp)
845 return copyout(&ovalue, SCARG(uap, ovalue), 845 return copyout(&ovalue, SCARG(uap, ovalue),
846 sizeof(struct itimerspec)); 846 sizeof(struct itimerspec));
847 return 0; 847 return 0;
848} 848}
849 849
850int 850int
851dotimer_settime(int timerid, struct itimerspec *value, 851dotimer_settime(int timerid, struct itimerspec *value,
852 struct itimerspec *ovalue, int flags, struct proc *p) 852 struct itimerspec *ovalue, int flags, struct proc *p)
853{ 853{
854 struct timespec now; 854 struct timespec now;
855 struct itimerspec val, oval; 855 struct itimerspec val, oval;
856 struct ptimers *pts; 856 struct ptimers *pts;
857 struct ptimer *pt; 857 struct ptimer *pt;
858 int error; 858 int error;
859 859
860 pts = p->p_timers; 860 pts = p->p_timers;
861 861
862 if (pts == NULL || timerid < 2 || timerid >= TIMER_MAX) 862 if (pts == NULL || timerid < 2 || timerid >= TIMER_MAX)
863 return EINVAL; 863 return EINVAL;
864 val = *value; 864 val = *value;
865 if ((error = itimespecfix(&val.it_value)) != 0 || 865 if ((error = itimespecfix(&val.it_value)) != 0 ||
866 (error = itimespecfix(&val.it_interval)) != 0) 866 (error = itimespecfix(&val.it_interval)) != 0)
867 return error; 867 return error;
868 868
869 mutex_spin_enter(&timer_lock); 869 mutex_spin_enter(&timer_lock);
870 if ((pt = pts->pts_timers[timerid]) == NULL) { 870 if ((pt = pts->pts_timers[timerid]) == NULL) {
871 mutex_spin_exit(&timer_lock); 871 mutex_spin_exit(&timer_lock);
872 return EINVAL; 872 return EINVAL;
873 } 873 }
874 874
875 oval = pt->pt_time; 875 oval = pt->pt_time;
876 pt->pt_time = val; 876 pt->pt_time = val;
877 877
878 /* 878 /*
879 * If we've been passed a relative time for a realtime timer, 879 * If we've been passed a relative time for a realtime timer,
880 * convert it to absolute; if an absolute time for a virtual 880 * convert it to absolute; if an absolute time for a virtual
881 * timer, convert it to relative and make sure we don't set it 881 * timer, convert it to relative and make sure we don't set it
882 * to zero, which would cancel the timer, or let it go 882 * to zero, which would cancel the timer, or let it go
883 * negative, which would confuse the comparison tests. 883 * negative, which would confuse the comparison tests.
884 */ 884 */
885 if (timespecisset(&pt->pt_time.it_value)) { 885 if (timespecisset(&pt->pt_time.it_value)) {
886 if (!CLOCK_VIRTUAL_P(pt->pt_type)) { 886 if (!CLOCK_VIRTUAL_P(pt->pt_type)) {
887 if ((flags & TIMER_ABSTIME) == 0) { 887 if ((flags & TIMER_ABSTIME) == 0) {
888 if (pt->pt_type == CLOCK_REALTIME) { 888 if (pt->pt_type == CLOCK_REALTIME) {
889 getnanotime(&now); 889 getnanotime(&now);
890 } else { /* CLOCK_MONOTONIC */ 890 } else { /* CLOCK_MONOTONIC */
891 getnanouptime(&now); 891 getnanouptime(&now);
892 } 892 }
893 timespecadd(&pt->pt_time.it_value, &now, 893 timespecadd(&pt->pt_time.it_value, &now,
894 &pt->pt_time.it_value); 894 &pt->pt_time.it_value);
895 } 895 }
896 } else { 896 } else {
897 if ((flags & TIMER_ABSTIME) != 0) { 897 if ((flags & TIMER_ABSTIME) != 0) {
898 getnanotime(&now); 898 getnanotime(&now);
899 timespecsub(&pt->pt_time.it_value, &now, 899 timespecsub(&pt->pt_time.it_value, &now,
900 &pt->pt_time.it_value); 900 &pt->pt_time.it_value);
901 if (!timespecisset(&pt->pt_time.it_value) || 901 if (!timespecisset(&pt->pt_time.it_value) ||
902 pt->pt_time.it_value.tv_sec < 0) { 902 pt->pt_time.it_value.tv_sec < 0) {
903 pt->pt_time.it_value.tv_sec = 0; 903 pt->pt_time.it_value.tv_sec = 0;
904 pt->pt_time.it_value.tv_nsec = 1; 904 pt->pt_time.it_value.tv_nsec = 1;
905 } 905 }
906 } 906 }
907 } 907 }
908 } 908 }
909 909
910 timer_settime(pt); 910 timer_settime(pt);
911 mutex_spin_exit(&timer_lock); 911 mutex_spin_exit(&timer_lock);
912 912
913 if (ovalue) 913 if (ovalue)
914 *ovalue = oval; 914 *ovalue = oval;
915 915
916 return (0); 916 return (0);
917} 917}
918 918
919/* Return the time remaining until a POSIX timer fires. */ 919/* Return the time remaining until a POSIX timer fires. */
920int 920int
921sys___timer_gettime50(struct lwp *l, 921sys___timer_gettime50(struct lwp *l,
922 const struct sys___timer_gettime50_args *uap, register_t *retval) 922 const struct sys___timer_gettime50_args *uap, register_t *retval)
923{ 923{
924 /* { 924 /* {
925 syscallarg(timer_t) timerid; 925 syscallarg(timer_t) timerid;
926 syscallarg(struct itimerspec *) value; 926 syscallarg(struct itimerspec *) value;
927 } */ 927 } */
928 struct itimerspec its; 928 struct itimerspec its;
929 int error; 929 int error;
930 930
931 if ((error = dotimer_gettime(SCARG(uap, timerid), l->l_proc, 931 if ((error = dotimer_gettime(SCARG(uap, timerid), l->l_proc,
932 &its)) != 0) 932 &its)) != 0)
933 return error; 933 return error;
934 934
935 return copyout(&its, SCARG(uap, value), sizeof(its)); 935 return copyout(&its, SCARG(uap, value), sizeof(its));
936} 936}
937 937
938int 938int
939dotimer_gettime(int timerid, struct proc *p, struct itimerspec *its) 939dotimer_gettime(int timerid, struct proc *p, struct itimerspec *its)
940{ 940{
941 struct ptimer *pt; 941 struct ptimer *pt;
942 struct ptimers *pts; 942 struct ptimers *pts;
943 943
944 pts = p->p_timers; 944 pts = p->p_timers;
945 if (pts == NULL || timerid < 2 || timerid >= TIMER_MAX) 945 if (pts == NULL || timerid < 2 || timerid >= TIMER_MAX)
946 return (EINVAL); 946 return (EINVAL);
947 mutex_spin_enter(&timer_lock); 947 mutex_spin_enter(&timer_lock);
948 if ((pt = pts->pts_timers[timerid]) == NULL) { 948 if ((pt = pts->pts_timers[timerid]) == NULL) {
949 mutex_spin_exit(&timer_lock); 949 mutex_spin_exit(&timer_lock);
950 return (EINVAL); 950 return (EINVAL);
951 } 951 }
952 timer_gettime(pt, its); 952 timer_gettime(pt, its);
953 mutex_spin_exit(&timer_lock); 953 mutex_spin_exit(&timer_lock);
954 954
955 return 0; 955 return 0;
956} 956}
957 957
958/* 958/*
959 * Return the count of the number of times a periodic timer expired 959 * Return the count of the number of times a periodic timer expired
960 * while a notification was already pending. The counter is reset when 960 * while a notification was already pending. The counter is reset when
961 * a timer expires and a notification can be posted. 961 * a timer expires and a notification can be posted.
962 */ 962 */
963int 963int
964sys_timer_getoverrun(struct lwp *l, const struct sys_timer_getoverrun_args *uap, 964sys_timer_getoverrun(struct lwp *l, const struct sys_timer_getoverrun_args *uap,
965 register_t *retval) 965 register_t *retval)
966{ 966{
967 /* { 967 /* {
968 syscallarg(timer_t) timerid; 968 syscallarg(timer_t) timerid;
969 } */ 969 } */
970 struct proc *p = l->l_proc; 970 struct proc *p = l->l_proc;
971 struct ptimers *pts; 971 struct ptimers *pts;
972 int timerid; 972 int timerid;
973 struct ptimer *pt; 973 struct ptimer *pt;
974 974
975 timerid = SCARG(uap, timerid); 975 timerid = SCARG(uap, timerid);
976 976
977 pts = p->p_timers; 977 pts = p->p_timers;
978 if (pts == NULL || timerid < 2 || timerid >= TIMER_MAX) 978 if (pts == NULL || timerid < 2 || timerid >= TIMER_MAX)
979 return (EINVAL); 979 return (EINVAL);
980 mutex_spin_enter(&timer_lock); 980 mutex_spin_enter(&timer_lock);
981 if ((pt = pts->pts_timers[timerid]) == NULL) { 981 if ((pt = pts->pts_timers[timerid]) == NULL) {
982 mutex_spin_exit(&timer_lock); 982 mutex_spin_exit(&timer_lock);
983 return (EINVAL); 983 return (EINVAL);
984 } 984 }
985 *retval = pt->pt_poverruns; 985 *retval = pt->pt_poverruns;
986 if (*retval >= DELAYTIMER_MAX) 986 if (*retval >= DELAYTIMER_MAX)
987 *retval = DELAYTIMER_MAX; 987 *retval = DELAYTIMER_MAX;
988 mutex_spin_exit(&timer_lock); 988 mutex_spin_exit(&timer_lock);
989 989
990 return (0); 990 return (0);
991} 991}
992 992
993/* 993/*
994 * Real interval timer expired: 994 * Real interval timer expired:
995 * send process whose timer expired an alarm signal. 995 * send process whose timer expired an alarm signal.
996 * If time is not set up to reload, then just return. 996 * If time is not set up to reload, then just return.
997 * Else compute next time timer should go off which is > current time. 997 * Else compute next time timer should go off which is > current time.
998 * This is where delay in processing this timeout causes multiple 998 * This is where delay in processing this timeout causes multiple
999 * SIGALRM calls to be compressed into one. 999 * SIGALRM calls to be compressed into one.
1000 */ 1000 */
1001void 1001void
1002realtimerexpire(void *arg) 1002realtimerexpire(void *arg)
1003{ 1003{
1004 uint64_t last_val, next_val, interval, now_ns; 1004 uint64_t last_val, next_val, interval, now_ns;
1005 struct timespec now, next; 1005 struct timespec now, next;
1006 struct ptimer *pt; 1006 struct ptimer *pt;
1007 int backwards; 1007 int backwards;
1008 1008
1009 pt = arg; 1009 pt = arg;
1010 1010
1011 mutex_spin_enter(&timer_lock); 1011 mutex_spin_enter(&timer_lock);
1012 itimerfire(pt); 1012 itimerfire(pt);
1013 1013
1014 if (!timespecisset(&pt->pt_time.it_interval)) { 1014 if (!timespecisset(&pt->pt_time.it_interval)) {
1015 timespecclear(&pt->pt_time.it_value); 1015 timespecclear(&pt->pt_time.it_value);
1016 mutex_spin_exit(&timer_lock); 1016 mutex_spin_exit(&timer_lock);
1017 return; 1017 return;
1018 } 1018 }
1019 1019
1020 if (pt->pt_type == CLOCK_MONOTONIC) { 1020 if (pt->pt_type == CLOCK_MONOTONIC) {
1021 getnanouptime(&now); 1021 getnanouptime(&now);
1022 } else { 1022 } else {
1023 getnanotime(&now); 1023 getnanotime(&now);
1024 } 1024 }
1025 backwards = (timespeccmp(&pt->pt_time.it_value, &now, >)); 1025 backwards = (timespeccmp(&pt->pt_time.it_value, &now, >));
1026 timespecadd(&pt->pt_time.it_value, &pt->pt_time.it_interval, &next); 1026 timespecadd(&pt->pt_time.it_value, &pt->pt_time.it_interval, &next);
1027 /* Handle the easy case of non-overflown timers first. */ 1027 /* Handle the easy case of non-overflown timers first. */
1028 if (!backwards && timespeccmp(&next, &now, >)) { 1028 if (!backwards && timespeccmp(&next, &now, >)) {
1029 pt->pt_time.it_value = next; 1029 pt->pt_time.it_value = next;
1030 } else { 1030 } else {
1031 now_ns = timespec2ns(&now); 1031 now_ns = timespec2ns(&now);
1032 last_val = timespec2ns(&pt->pt_time.it_value); 1032 last_val = timespec2ns(&pt->pt_time.it_value);
1033 interval = timespec2ns(&pt->pt_time.it_interval); 1033 interval = timespec2ns(&pt->pt_time.it_interval);
1034 1034
1035 next_val = now_ns + 1035 next_val = now_ns +
1036 (now_ns - last_val + interval - 1) % interval; 1036 (now_ns - last_val + interval - 1) % interval;
1037 1037
1038 if (backwards) 1038 if (backwards)
1039 next_val += interval; 1039 next_val += interval;
1040 else 1040 else
1041 pt->pt_overruns += (now_ns - last_val) / interval; 1041 pt->pt_overruns += (now_ns - last_val) / interval;
1042 1042
1043 pt->pt_time.it_value.tv_sec = next_val / 1000000000; 1043 pt->pt_time.it_value.tv_sec = next_val / 1000000000;
1044 pt->pt_time.it_value.tv_nsec = next_val % 1000000000; 1044 pt->pt_time.it_value.tv_nsec = next_val % 1000000000;
1045 } 1045 }
1046 1046
1047 /* 1047 /*
1048 * Don't need to check tshzto() return value, here. 1048 * Don't need to check tshzto() return value, here.
1049 * callout_reset() does it for us. 1049 * callout_reset() does it for us.
1050 */ 1050 */
1051 callout_reset(&pt->pt_ch, pt->pt_type == CLOCK_MONOTONIC ? 1051 callout_reset(&pt->pt_ch, pt->pt_type == CLOCK_MONOTONIC ?
1052 tshztoup(&pt->pt_time.it_value) : tshzto(&pt->pt_time.it_value), 1052 tshztoup(&pt->pt_time.it_value) : tshzto(&pt->pt_time.it_value),
1053 realtimerexpire, pt); 1053 realtimerexpire, pt);
1054 mutex_spin_exit(&timer_lock); 1054 mutex_spin_exit(&timer_lock);
1055} 1055}
1056 1056
1057/* BSD routine to get the value of an interval timer. */ 1057/* BSD routine to get the value of an interval timer. */
1058/* ARGSUSED */ 1058/* ARGSUSED */
1059int 1059int
1060sys___getitimer50(struct lwp *l, const struct sys___getitimer50_args *uap, 1060sys___getitimer50(struct lwp *l, const struct sys___getitimer50_args *uap,
1061 register_t *retval) 1061 register_t *retval)
1062{ 1062{
1063 /* { 1063 /* {
1064 syscallarg(int) which; 1064 syscallarg(int) which;
1065 syscallarg(struct itimerval *) itv; 1065 syscallarg(struct itimerval *) itv;
1066 } */ 1066 } */
1067 struct proc *p = l->l_proc; 1067 struct proc *p = l->l_proc;
1068 struct itimerval aitv; 1068 struct itimerval aitv;
1069 int error; 1069 int error;
1070 1070
1071 error = dogetitimer(p, SCARG(uap, which), &aitv); 1071 error = dogetitimer(p, SCARG(uap, which), &aitv);
1072 if (error) 1072 if (error)
1073 return error; 1073 return error;
1074 return (copyout(&aitv, SCARG(uap, itv), sizeof(struct itimerval))); 1074 return (copyout(&aitv, SCARG(uap, itv), sizeof(struct itimerval)));
1075} 1075}
1076 1076
1077int 1077int
1078dogetitimer(struct proc *p, int which, struct itimerval *itvp) 1078dogetitimer(struct proc *p, int which, struct itimerval *itvp)
1079{ 1079{
1080 struct ptimers *pts; 1080 struct ptimers *pts;
1081 struct ptimer *pt; 1081 struct ptimer *pt;
1082 struct itimerspec its; 1082 struct itimerspec its;
1083 1083
1084 if ((u_int)which > ITIMER_MONOTONIC) 1084 if ((u_int)which > ITIMER_MONOTONIC)
1085 return (EINVAL); 1085 return (EINVAL);
1086 1086
1087 mutex_spin_enter(&timer_lock); 1087 mutex_spin_enter(&timer_lock);
1088 pts = p->p_timers; 1088 pts = p->p_timers;
1089 if (pts == NULL || (pt = pts->pts_timers[which]) == NULL) { 1089 if (pts == NULL || (pt = pts->pts_timers[which]) == NULL) {
1090 timerclear(&itvp->it_value); 1090 timerclear(&itvp->it_value);
1091 timerclear(&itvp->it_interval); 1091 timerclear(&itvp->it_interval);
1092 } else { 1092 } else {
1093 timer_gettime(pt, &its); 1093 timer_gettime(pt, &its);
1094 TIMESPEC_TO_TIMEVAL(&itvp->it_value, &its.it_value); 1094 TIMESPEC_TO_TIMEVAL(&itvp->it_value, &its.it_value);
1095 TIMESPEC_TO_TIMEVAL(&itvp->it_interval, &its.it_interval); 1095 TIMESPEC_TO_TIMEVAL(&itvp->it_interval, &its.it_interval);
1096 } 1096 }
1097 mutex_spin_exit(&timer_lock); 1097 mutex_spin_exit(&timer_lock);
1098 1098
1099 return 0; 1099 return 0;
1100} 1100}
1101 1101
1102/* BSD routine to set/arm an interval timer. */ 1102/* BSD routine to set/arm an interval timer. */
1103/* ARGSUSED */ 1103/* ARGSUSED */
1104int 1104int
1105sys___setitimer50(struct lwp *l, const struct sys___setitimer50_args *uap, 1105sys___setitimer50(struct lwp *l, const struct sys___setitimer50_args *uap,
1106 register_t *retval) 1106 register_t *retval)
1107{ 1107{
1108 /* { 1108 /* {
1109 syscallarg(int) which; 1109 syscallarg(int) which;
1110 syscallarg(const struct itimerval *) itv; 1110 syscallarg(const struct itimerval *) itv;
1111 syscallarg(struct itimerval *) oitv; 1111 syscallarg(struct itimerval *) oitv;
1112 } */ 1112 } */
1113 struct proc *p = l->l_proc; 1113 struct proc *p = l->l_proc;
1114 int which = SCARG(uap, which); 1114 int which = SCARG(uap, which);
1115 struct sys___getitimer50_args getargs; 1115 struct sys___getitimer50_args getargs;
1116 const struct itimerval *itvp; 1116 const struct itimerval *itvp;
1117 struct itimerval aitv; 1117 struct itimerval aitv;
1118 int error; 1118 int error;
1119 1119
1120 if ((u_int)which > ITIMER_MONOTONIC) 1120 if ((u_int)which > ITIMER_MONOTONIC)
1121 return (EINVAL); 1121 return (EINVAL);
1122 itvp = SCARG(uap, itv); 1122 itvp = SCARG(uap, itv);
1123 if (itvp && 1123 if (itvp &&
1124 (error = copyin(itvp, &aitv, sizeof(struct itimerval))) != 0) 1124 (error = copyin(itvp, &aitv, sizeof(struct itimerval))) != 0)
1125 return (error); 1125 return (error);
1126 if (SCARG(uap, oitv) != NULL) { 1126 if (SCARG(uap, oitv) != NULL) {
1127 SCARG(&getargs, which) = which; 1127 SCARG(&getargs, which) = which;
1128 SCARG(&getargs, itv) = SCARG(uap, oitv); 1128 SCARG(&getargs, itv) = SCARG(uap, oitv);
1129 if ((error = sys___getitimer50(l, &getargs, retval)) != 0) 1129 if ((error = sys___getitimer50(l, &getargs, retval)) != 0)
1130 return (error); 1130 return (error);
1131 } 1131 }
1132 if (itvp == 0) 1132 if (itvp == 0)
1133 return (0); 1133 return (0);
1134 1134
1135 return dosetitimer(p, which, &aitv); 1135 return dosetitimer(p, which, &aitv);
1136} 1136}
1137 1137
1138int 1138int
1139dosetitimer(struct proc *p, int which, struct itimerval *itvp) 1139dosetitimer(struct proc *p, int which, struct itimerval *itvp)
1140{ 1140{
1141 struct timespec now; 1141 struct timespec now;
1142 struct ptimers *pts; 1142 struct ptimers *pts;
1143 struct ptimer *pt, *spare; 1143 struct ptimer *pt, *spare;
1144 1144
1145 KASSERT((u_int)which <= CLOCK_MONOTONIC); 1145 KASSERT((u_int)which <= CLOCK_MONOTONIC);
1146 if (itimerfix(&itvp->it_value) || itimerfix(&itvp->it_interval)) 1146 if (itimerfix(&itvp->it_value) || itimerfix(&itvp->it_interval))
1147 return (EINVAL); 1147 return (EINVAL);
1148 1148
1149 /* 1149 /*
1150 * Don't bother allocating data structures if the process just 1150 * Don't bother allocating data structures if the process just
1151 * wants to clear the timer. 1151 * wants to clear the timer.
1152 */ 1152 */
1153 spare = NULL; 1153 spare = NULL;
1154 pts = p->p_timers; 1154 pts = p->p_timers;
1155 retry: 1155 retry:
1156 if (!timerisset(&itvp->it_value) && (pts == NULL || 1156 if (!timerisset(&itvp->it_value) && (pts == NULL ||
1157 pts->pts_timers[which] == NULL)) 1157 pts->pts_timers[which] == NULL))
1158 return (0); 1158 return (0);
1159 if (pts == NULL) 1159 if (pts == NULL)
1160 pts = timers_alloc(p); 1160 pts = timers_alloc(p);
1161 mutex_spin_enter(&timer_lock); 1161 mutex_spin_enter(&timer_lock);
1162 pt = pts->pts_timers[which]; 1162 pt = pts->pts_timers[which];
1163 if (pt == NULL) { 1163 if (pt == NULL) {
1164 if (spare == NULL) { 1164 if (spare == NULL) {
1165 mutex_spin_exit(&timer_lock); 1165 mutex_spin_exit(&timer_lock);
1166 spare = pool_get(&ptimer_pool, PR_WAITOK); 1166 spare = pool_get(&ptimer_pool, PR_WAITOK);
 1167 memset(spare, 0, sizeof(*spare));
1167 goto retry; 1168 goto retry;
1168 } 1169 }
1169 pt = spare; 1170 pt = spare;
1170 spare = NULL; 1171 spare = NULL;
1171 pt->pt_ev.sigev_notify = SIGEV_SIGNAL; 1172 pt->pt_ev.sigev_notify = SIGEV_SIGNAL;
1172 pt->pt_ev.sigev_value.sival_int = which; 1173 pt->pt_ev.sigev_value.sival_int = which;
1173 pt->pt_overruns = 0; 1174 pt->pt_overruns = 0;
1174 pt->pt_proc = p; 1175 pt->pt_proc = p;
1175 pt->pt_type = which; 1176 pt->pt_type = which;
1176 pt->pt_entry = which; 1177 pt->pt_entry = which;
1177 pt->pt_queued = false; 1178 pt->pt_queued = false;
1178 if (pt->pt_type == CLOCK_REALTIME) 1179 if (pt->pt_type == CLOCK_REALTIME)
1179 callout_init(&pt->pt_ch, CALLOUT_MPSAFE); 1180 callout_init(&pt->pt_ch, CALLOUT_MPSAFE);
1180 else 1181 else
1181 pt->pt_active = 0; 1182 pt->pt_active = 0;
1182 1183
1183 switch (which) { 1184 switch (which) {
1184 case ITIMER_REAL: 1185 case ITIMER_REAL:
1185 case ITIMER_MONOTONIC: 1186 case ITIMER_MONOTONIC:
1186 pt->pt_ev.sigev_signo = SIGALRM; 1187 pt->pt_ev.sigev_signo = SIGALRM;
1187 break; 1188 break;
1188 case ITIMER_VIRTUAL: 1189 case ITIMER_VIRTUAL:
1189 pt->pt_ev.sigev_signo = SIGVTALRM; 1190 pt->pt_ev.sigev_signo = SIGVTALRM;
1190 break; 1191 break;
1191 case ITIMER_PROF: 1192 case ITIMER_PROF:
1192 pt->pt_ev.sigev_signo = SIGPROF; 1193 pt->pt_ev.sigev_signo = SIGPROF;
1193 break; 1194 break;
1194 } 1195 }
1195 pts->pts_timers[which] = pt; 1196 pts->pts_timers[which] = pt;
1196 } 1197 }
1197 1198
1198 TIMEVAL_TO_TIMESPEC(&itvp->it_value, &pt->pt_time.it_value); 1199 TIMEVAL_TO_TIMESPEC(&itvp->it_value, &pt->pt_time.it_value);
1199 TIMEVAL_TO_TIMESPEC(&itvp->it_interval, &pt->pt_time.it_interval); 1200 TIMEVAL_TO_TIMESPEC(&itvp->it_interval, &pt->pt_time.it_interval);
1200 1201
1201 if (timespecisset(&pt->pt_time.it_value)) { 1202 if (timespecisset(&pt->pt_time.it_value)) {
1202 /* Convert to absolute time */ 1203 /* Convert to absolute time */
1203 /* XXX need to wrap in splclock for timecounters case? */ 1204 /* XXX need to wrap in splclock for timecounters case? */
1204 switch (which) { 1205 switch (which) {
1205 case ITIMER_REAL: 1206 case ITIMER_REAL:
1206 getnanotime(&now); 1207 getnanotime(&now);
1207 timespecadd(&pt->pt_time.it_value, &now, 1208 timespecadd(&pt->pt_time.it_value, &now,
1208 &pt->pt_time.it_value); 1209 &pt->pt_time.it_value);
1209 break; 1210 break;
1210 case ITIMER_MONOTONIC: 1211 case ITIMER_MONOTONIC:
1211 getnanouptime(&now); 1212 getnanouptime(&now);
1212 timespecadd(&pt->pt_time.it_value, &now, 1213 timespecadd(&pt->pt_time.it_value, &now,
1213 &pt->pt_time.it_value); 1214 &pt->pt_time.it_value);
1214 break; 1215 break;
1215 default: 1216 default:
1216 break; 1217 break;
1217 } 1218 }
1218 } 1219 }
1219 timer_settime(pt); 1220 timer_settime(pt);
1220 mutex_spin_exit(&timer_lock); 1221 mutex_spin_exit(&timer_lock);
1221 if (spare != NULL) 1222 if (spare != NULL)
1222 pool_put(&ptimer_pool, spare); 1223 pool_put(&ptimer_pool, spare);
1223 1224
1224 return (0); 1225 return (0);
1225} 1226}
1226 1227
1227/* Utility routines to manage the array of pointers to timers. */ 1228/* Utility routines to manage the array of pointers to timers. */
1228struct ptimers * 1229struct ptimers *
1229timers_alloc(struct proc *p) 1230timers_alloc(struct proc *p)
1230{ 1231{
1231 struct ptimers *pts; 1232 struct ptimers *pts;
1232 int i; 1233 int i;
1233 1234
1234 pts = pool_get(&ptimers_pool, PR_WAITOK); 1235 pts = pool_get(&ptimers_pool, PR_WAITOK);
1235 LIST_INIT(&pts->pts_virtual); 1236 LIST_INIT(&pts->pts_virtual);
1236 LIST_INIT(&pts->pts_prof); 1237 LIST_INIT(&pts->pts_prof);
1237 for (i = 0; i < TIMER_MAX; i++) 1238 for (i = 0; i < TIMER_MAX; i++)
1238 pts->pts_timers[i] = NULL; 1239 pts->pts_timers[i] = NULL;
1239 mutex_spin_enter(&timer_lock); 1240 mutex_spin_enter(&timer_lock);
1240 if (p->p_timers == NULL) { 1241 if (p->p_timers == NULL) {
1241 p->p_timers = pts; 1242 p->p_timers = pts;
1242 mutex_spin_exit(&timer_lock); 1243 mutex_spin_exit(&timer_lock);
1243 return pts; 1244 return pts;
1244 } 1245 }
1245 mutex_spin_exit(&timer_lock); 1246 mutex_spin_exit(&timer_lock);
1246 pool_put(&ptimers_pool, pts); 1247 pool_put(&ptimers_pool, pts);
1247 return p->p_timers; 1248 return p->p_timers;
1248} 1249}
1249 1250
1250/* 1251/*
1251 * Clean up the per-process timers. If "which" is set to TIMERS_ALL, 1252 * Clean up the per-process timers. If "which" is set to TIMERS_ALL,
1252 * then clean up all timers and free all the data structures. If 1253 * then clean up all timers and free all the data structures. If
1253 * "which" is set to TIMERS_POSIX, only clean up the timers allocated 1254 * "which" is set to TIMERS_POSIX, only clean up the timers allocated
1254 * by timer_create(), not the BSD setitimer() timers, and only free the 1255 * by timer_create(), not the BSD setitimer() timers, and only free the
1255 * structure if none of those remain. 1256 * structure if none of those remain.
1256 */ 1257 */
1257void 1258void
1258timers_free(struct proc *p, int which) 1259timers_free(struct proc *p, int which)
1259{ 1260{
1260 struct ptimers *pts; 1261 struct ptimers *pts;
1261 struct ptimer *ptn; 1262 struct ptimer *ptn;
1262 struct timespec ts; 1263 struct timespec ts;
1263 int i; 1264 int i;
1264 1265
1265 if (p->p_timers == NULL) 1266 if (p->p_timers == NULL)
1266 return; 1267 return;
1267 1268
1268 pts = p->p_timers; 1269 pts = p->p_timers;
1269 mutex_spin_enter(&timer_lock); 1270 mutex_spin_enter(&timer_lock);
1270 if (which == TIMERS_ALL) { 1271 if (which == TIMERS_ALL) {
1271 p->p_timers = NULL; 1272 p->p_timers = NULL;
1272 i = 0; 1273 i = 0;
1273 } else { 1274 } else {
1274 timespecclear(&ts); 1275 timespecclear(&ts);
1275 for (ptn = LIST_FIRST(&pts->pts_virtual); 1276 for (ptn = LIST_FIRST(&pts->pts_virtual);
1276 ptn && ptn != pts->pts_timers[ITIMER_VIRTUAL]; 1277 ptn && ptn != pts->pts_timers[ITIMER_VIRTUAL];
1277 ptn = LIST_NEXT(ptn, pt_list)) { 1278 ptn = LIST_NEXT(ptn, pt_list)) {
1278 KASSERT(ptn->pt_type == CLOCK_VIRTUAL); 1279 KASSERT(ptn->pt_type == CLOCK_VIRTUAL);
1279 timespecadd(&ts, &ptn->pt_time.it_value, &ts); 1280 timespecadd(&ts, &ptn->pt_time.it_value, &ts);
1280 } 1281 }
1281 LIST_FIRST(&pts->pts_virtual) = NULL; 1282 LIST_FIRST(&pts->pts_virtual) = NULL;
1282 if (ptn) { 1283 if (ptn) {
1283 KASSERT(ptn->pt_type == CLOCK_VIRTUAL); 1284 KASSERT(ptn->pt_type == CLOCK_VIRTUAL);
1284 timespecadd(&ts, &ptn->pt_time.it_value, 1285 timespecadd(&ts, &ptn->pt_time.it_value,
1285 &ptn->pt_time.it_value); 1286 &ptn->pt_time.it_value);
1286 LIST_INSERT_HEAD(&pts->pts_virtual, ptn, pt_list); 1287 LIST_INSERT_HEAD(&pts->pts_virtual, ptn, pt_list);
1287 } 1288 }
1288 timespecclear(&ts); 1289 timespecclear(&ts);
1289 for (ptn = LIST_FIRST(&pts->pts_prof); 1290 for (ptn = LIST_FIRST(&pts->pts_prof);
1290 ptn && ptn != pts->pts_timers[ITIMER_PROF]; 1291 ptn && ptn != pts->pts_timers[ITIMER_PROF];
1291 ptn = LIST_NEXT(ptn, pt_list)) { 1292 ptn = LIST_NEXT(ptn, pt_list)) {
1292 KASSERT(ptn->pt_type == CLOCK_PROF); 1293 KASSERT(ptn->pt_type == CLOCK_PROF);
1293 timespecadd(&ts, &ptn->pt_time.it_value, &ts); 1294 timespecadd(&ts, &ptn->pt_time.it_value, &ts);
1294 } 1295 }
1295 LIST_FIRST(&pts->pts_prof) = NULL; 1296 LIST_FIRST(&pts->pts_prof) = NULL;
1296 if (ptn) { 1297 if (ptn) {
1297 KASSERT(ptn->pt_type == CLOCK_PROF); 1298 KASSERT(ptn->pt_type == CLOCK_PROF);
1298 timespecadd(&ts, &ptn->pt_time.it_value, 1299 timespecadd(&ts, &ptn->pt_time.it_value,
1299 &ptn->pt_time.it_value); 1300 &ptn->pt_time.it_value);
1300 LIST_INSERT_HEAD(&pts->pts_prof, ptn, pt_list); 1301 LIST_INSERT_HEAD(&pts->pts_prof, ptn, pt_list);
1301 } 1302 }
1302 i = TIMER_MIN; 1303 i = TIMER_MIN;
1303 } 1304 }
1304 for ( ; i < TIMER_MAX; i++) { 1305 for ( ; i < TIMER_MAX; i++) {
1305 if (pts->pts_timers[i] != NULL) { 1306 if (pts->pts_timers[i] != NULL) {
1306 itimerfree(pts, i); 1307 itimerfree(pts, i);
1307 mutex_spin_enter(&timer_lock); 1308 mutex_spin_enter(&timer_lock);
1308 } 1309 }
1309 } 1310 }
1310 if (pts->pts_timers[0] == NULL && pts->pts_timers[1] == NULL && 1311 if (pts->pts_timers[0] == NULL && pts->pts_timers[1] == NULL &&
1311 pts->pts_timers[2] == NULL && pts->pts_timers[3] == NULL) { 1312 pts->pts_timers[2] == NULL && pts->pts_timers[3] == NULL) {
1312 p->p_timers = NULL; 1313 p->p_timers = NULL;
1313 mutex_spin_exit(&timer_lock); 1314 mutex_spin_exit(&timer_lock);
1314 pool_put(&ptimers_pool, pts); 1315 pool_put(&ptimers_pool, pts);
1315 } else 1316 } else
1316 mutex_spin_exit(&timer_lock); 1317 mutex_spin_exit(&timer_lock);
1317} 1318}
1318 1319
1319static void 1320static void
1320itimerfree(struct ptimers *pts, int index) 1321itimerfree(struct ptimers *pts, int index)
1321{ 1322{
1322 struct ptimer *pt; 1323 struct ptimer *pt;
1323 1324
1324 KASSERT(mutex_owned(&timer_lock)); 1325 KASSERT(mutex_owned(&timer_lock));
1325 1326
1326 pt = pts->pts_timers[index]; 1327 pt = pts->pts_timers[index];
1327 pts->pts_timers[index] = NULL; 1328 pts->pts_timers[index] = NULL;
1328 if (!CLOCK_VIRTUAL_P(pt->pt_type)) 1329 if (!CLOCK_VIRTUAL_P(pt->pt_type))
1329 callout_halt(&pt->pt_ch, &timer_lock); 1330 callout_halt(&pt->pt_ch, &timer_lock);
1330 if (pt->pt_queued) 1331 if (pt->pt_queued)
1331 TAILQ_REMOVE(&timer_queue, pt, pt_chain); 1332 TAILQ_REMOVE(&timer_queue, pt, pt_chain);
1332 mutex_spin_exit(&timer_lock); 1333 mutex_spin_exit(&timer_lock);
1333 if (!CLOCK_VIRTUAL_P(pt->pt_type)) 1334 if (!CLOCK_VIRTUAL_P(pt->pt_type))
1334 callout_destroy(&pt->pt_ch); 1335 callout_destroy(&pt->pt_ch);
1335 pool_put(&ptimer_pool, pt); 1336 pool_put(&ptimer_pool, pt);
1336} 1337}
1337 1338
1338/* 1339/*
1339 * Decrement an interval timer by a specified number 1340 * Decrement an interval timer by a specified number
1340 * of nanoseconds, which must be less than a second, 1341 * of nanoseconds, which must be less than a second,
1341 * i.e. < 1000000000. If the timer expires, then reload 1342 * i.e. < 1000000000. If the timer expires, then reload
1342 * it. In this case, carry over (nsec - old value) to 1343 * it. In this case, carry over (nsec - old value) to
1343 * reduce the value reloaded into the timer so that 1344 * reduce the value reloaded into the timer so that
1344 * the timer does not drift. This routine assumes 1345 * the timer does not drift. This routine assumes
1345 * that it is called in a context where the timers 1346 * that it is called in a context where the timers
1346 * on which it is operating cannot change in value. 1347 * on which it is operating cannot change in value.
1347 */ 1348 */
1348static int 1349static int
1349itimerdecr(struct ptimer *pt, int nsec) 1350itimerdecr(struct ptimer *pt, int nsec)
1350{ 1351{
1351 struct itimerspec *itp; 1352 struct itimerspec *itp;
1352 1353
1353 KASSERT(mutex_owned(&timer_lock)); 1354 KASSERT(mutex_owned(&timer_lock));
1354 KASSERT(CLOCK_VIRTUAL_P(pt->pt_type)); 1355 KASSERT(CLOCK_VIRTUAL_P(pt->pt_type));
1355 1356
1356 itp = &pt->pt_time; 1357 itp = &pt->pt_time;
1357 if (itp->it_value.tv_nsec < nsec) { 1358 if (itp->it_value.tv_nsec < nsec) {
1358 if (itp->it_value.tv_sec == 0) { 1359 if (itp->it_value.tv_sec == 0) {
1359 /* expired, and already in next interval */ 1360 /* expired, and already in next interval */
1360 nsec -= itp->it_value.tv_nsec; 1361 nsec -= itp->it_value.tv_nsec;
1361 goto expire; 1362 goto expire;
1362 } 1363 }
1363 itp->it_value.tv_nsec += 1000000000; 1364 itp->it_value.tv_nsec += 1000000000;
1364 itp->it_value.tv_sec--; 1365 itp->it_value.tv_sec--;
1365 } 1366 }
1366 itp->it_value.tv_nsec -= nsec; 1367 itp->it_value.tv_nsec -= nsec;
1367 nsec = 0; 1368 nsec = 0;
1368 if (timespecisset(&itp->it_value)) 1369 if (timespecisset(&itp->it_value))
1369 return (1); 1370 return (1);
1370 /* expired, exactly at end of interval */ 1371 /* expired, exactly at end of interval */
1371expire: 1372expire:
1372 if (timespecisset(&itp->it_interval)) { 1373 if (timespecisset(&itp->it_interval)) {
1373 itp->it_value = itp->it_interval; 1374 itp->it_value = itp->it_interval;
1374 itp->it_value.tv_nsec -= nsec; 1375 itp->it_value.tv_nsec -= nsec;
1375 if (itp->it_value.tv_nsec < 0) { 1376 if (itp->it_value.tv_nsec < 0) {
1376 itp->it_value.tv_nsec += 1000000000; 1377 itp->it_value.tv_nsec += 1000000000;
1377 itp->it_value.tv_sec--; 1378 itp->it_value.tv_sec--;
1378 } 1379 }
1379 timer_settime(pt); 1380 timer_settime(pt);
1380 } else 1381 } else
1381 itp->it_value.tv_nsec = 0; /* sec is already 0 */ 1382 itp->it_value.tv_nsec = 0; /* sec is already 0 */
1382 return (0); 1383 return (0);
1383} 1384}
1384 1385
1385static void 1386static void
1386itimerfire(struct ptimer *pt) 1387itimerfire(struct ptimer *pt)
1387{ 1388{
1388 1389
1389 KASSERT(mutex_owned(&timer_lock)); 1390 KASSERT(mutex_owned(&timer_lock));
1390 1391
1391 /* 1392 /*
1392 * XXX Can overrun, but we don't do signal queueing yet, anyway. 1393 * XXX Can overrun, but we don't do signal queueing yet, anyway.
1393 * XXX Relying on the clock interrupt is stupid. 1394 * XXX Relying on the clock interrupt is stupid.
1394 */ 1395 */
1395 if (pt->pt_ev.sigev_notify != SIGEV_SIGNAL || pt->pt_queued) { 1396 if (pt->pt_ev.sigev_notify != SIGEV_SIGNAL || pt->pt_queued) {
1396 return; 1397 return;
1397 } 1398 }
1398 TAILQ_INSERT_TAIL(&timer_queue, pt, pt_chain); 1399 TAILQ_INSERT_TAIL(&timer_queue, pt, pt_chain);
1399 pt->pt_queued = true; 1400 pt->pt_queued = true;
1400 softint_schedule(timer_sih); 1401 softint_schedule(timer_sih);
1401} 1402}
1402 1403
1403void 1404void
1404timer_tick(lwp_t *l, bool user) 1405timer_tick(lwp_t *l, bool user)
1405{ 1406{
1406 struct ptimers *pts; 1407 struct ptimers *pts;
1407 struct ptimer *pt; 1408 struct ptimer *pt;
1408 proc_t *p; 1409 proc_t *p;
1409 1410
1410 p = l->l_proc; 1411 p = l->l_proc;
1411 if (p->p_timers == NULL) 1412 if (p->p_timers == NULL)
1412 return; 1413 return;
1413 1414
1414 mutex_spin_enter(&timer_lock); 1415 mutex_spin_enter(&timer_lock);
1415 if ((pts = l->l_proc->p_timers) != NULL) { 1416 if ((pts = l->l_proc->p_timers) != NULL) {
1416 /* 1417 /*
1417 * Run current process's virtual and profile time, as needed. 1418 * Run current process's virtual and profile time, as needed.
1418 */ 1419 */
1419 if (user && (pt = LIST_FIRST(&pts->pts_virtual)) != NULL) 1420 if (user && (pt = LIST_FIRST(&pts->pts_virtual)) != NULL)
1420 if (itimerdecr(pt, tick * 1000) == 0) 1421 if (itimerdecr(pt, tick * 1000) == 0)
1421 itimerfire(pt); 1422 itimerfire(pt);
1422 if ((pt = LIST_FIRST(&pts->pts_prof)) != NULL) 1423 if ((pt = LIST_FIRST(&pts->pts_prof)) != NULL)
1423 if (itimerdecr(pt, tick * 1000) == 0) 1424 if (itimerdecr(pt, tick * 1000) == 0)
1424 itimerfire(pt); 1425 itimerfire(pt);
1425 } 1426 }
1426 mutex_spin_exit(&timer_lock); 1427 mutex_spin_exit(&timer_lock);
1427} 1428}
1428 1429
1429static void 1430static void
1430timer_intr(void *cookie) 1431timer_intr(void *cookie)
1431{ 1432{
1432 ksiginfo_t ksi; 1433 ksiginfo_t ksi;
1433 struct ptimer *pt; 1434 struct ptimer *pt;
1434 proc_t *p; 1435 proc_t *p;
1435  1436
1436 mutex_enter(proc_lock); 1437 mutex_enter(proc_lock);
1437 mutex_spin_enter(&timer_lock); 1438 mutex_spin_enter(&timer_lock);
1438 while ((pt = TAILQ_FIRST(&timer_queue)) != NULL) { 1439 while ((pt = TAILQ_FIRST(&timer_queue)) != NULL) {
1439 TAILQ_REMOVE(&timer_queue, pt, pt_chain); 1440 TAILQ_REMOVE(&timer_queue, pt, pt_chain);
1440 KASSERT(pt->pt_queued); 1441 KASSERT(pt->pt_queued);
1441 pt->pt_queued = false; 1442 pt->pt_queued = false;
1442 1443
1443 if (pt->pt_proc->p_timers == NULL) { 1444 if (pt->pt_proc->p_timers == NULL) {
1444 /* Process is dying. */ 1445 /* Process is dying. */
1445 continue; 1446 continue;
1446 } 1447 }
1447 p = pt->pt_proc; 1448 p = pt->pt_proc;
1448 if (pt->pt_ev.sigev_notify != SIGEV_SIGNAL) { 1449 if (pt->pt_ev.sigev_notify != SIGEV_SIGNAL) {
1449 continue; 1450 continue;
1450 } 1451 }
1451 if (sigismember(&p->p_sigpend.sp_set, pt->pt_ev.sigev_signo)) { 1452 if (sigismember(&p->p_sigpend.sp_set, pt->pt_ev.sigev_signo)) {
1452 pt->pt_overruns++; 1453 pt->pt_overruns++;
1453 continue; 1454 continue;
1454 } 1455 }
1455 1456
1456 KSI_INIT(&ksi); 1457 KSI_INIT(&ksi);
1457 ksi.ksi_signo = pt->pt_ev.sigev_signo; 1458 ksi.ksi_signo = pt->pt_ev.sigev_signo;
1458 ksi.ksi_code = SI_TIMER; 1459 ksi.ksi_code = SI_TIMER;
1459 ksi.ksi_value = pt->pt_ev.sigev_value; 1460 ksi.ksi_value = pt->pt_ev.sigev_value;
1460 pt->pt_poverruns = pt->pt_overruns; 1461 pt->pt_poverruns = pt->pt_overruns;
1461 pt->pt_overruns = 0; 1462 pt->pt_overruns = 0;
1462 mutex_spin_exit(&timer_lock); 1463 mutex_spin_exit(&timer_lock);
1463 kpsignal(p, &ksi, NULL); 1464 kpsignal(p, &ksi, NULL);
1464 mutex_spin_enter(&timer_lock); 1465 mutex_spin_enter(&timer_lock);
1465 } 1466 }
1466 mutex_spin_exit(&timer_lock); 1467 mutex_spin_exit(&timer_lock);
1467 mutex_exit(proc_lock); 1468 mutex_exit(proc_lock);
1468} 1469}
1469 1470
1470/* 1471/*
1471 * Check if the time will wrap if set to ts. 1472 * Check if the time will wrap if set to ts.
1472 * 1473 *
1473 * ts - timespec describing the new time 1474 * ts - timespec describing the new time
1474 * delta - the delta between the current time and ts 1475 * delta - the delta between the current time and ts
1475 */ 1476 */
1476bool 1477bool
1477time_wraps(struct timespec *ts, struct timespec *delta) 1478time_wraps(struct timespec *ts, struct timespec *delta)
1478{ 1479{
1479 1480
1480 /* 1481 /*
1481 * Don't allow the time to be set forward so far it 1482 * Don't allow the time to be set forward so far it
1482 * will wrap and become negative, thus allowing an 1483 * will wrap and become negative, thus allowing an
1483 * attacker to bypass the next check below. The 1484 * attacker to bypass the next check below. The
1484 * cutoff is 1 year before rollover occurs, so even 1485 * cutoff is 1 year before rollover occurs, so even
1485 * if the attacker uses adjtime(2) to move the time 1486 * if the attacker uses adjtime(2) to move the time
1486 * past the cutoff, it will take a very long time 1487 * past the cutoff, it will take a very long time
1487 * to get to the wrap point. 1488 * to get to the wrap point.
1488 */ 1489 */
1489 if ((ts->tv_sec > LLONG_MAX - 365*24*60*60) || 1490 if ((ts->tv_sec > LLONG_MAX - 365*24*60*60) ||
1490 (delta->tv_sec < 0 || delta->tv_nsec < 0)) 1491 (delta->tv_sec < 0 || delta->tv_nsec < 0))
1491 return true; 1492 return true;
1492 1493
1493 return false; 1494 return false;
1494} 1495}