1 /* $OpenBSD: kern_time.c,v 1.12 1998/02/20 14:51:56 niklas Exp $ */ 2 /* $NetBSD: kern_time.c,v 1.20 1996/02/18 11:57:06 fvdl Exp $ */ 3 4 /* 5 * Copyright (c) 1982, 1986, 1989, 1993 6 * The Regents of the University of California. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. All advertising materials mentioning features or use of this software 17 * must display the following acknowledgement: 18 * This product includes software developed by the University of 19 * California, Berkeley and its contributors. 20 * 4. Neither the name of the University nor the names of its contributors 21 * may be used to endorse or promote products derived from this software 22 * without specific prior written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 * SUCH DAMAGE. 35 * 36 * @(#)kern_time.c 8.4 (Berkeley) 5/26/95 37 */ 38 39 #include <sys/param.h> 40 #include <sys/resourcevar.h> 41 #include <sys/kernel.h> 42 #include <sys/systm.h> 43 #include <sys/proc.h> 44 #include <sys/vnode.h> 45 #include <sys/signalvar.h> 46 47 #include <sys/mount.h> 48 #include <sys/syscallargs.h> 49 50 #if defined(NFSCLIENT) || defined(NFSSERVER) 51 #include <nfs/rpcv2.h> 52 #include <nfs/nfsproto.h> 53 #include <nfs/nfs_var.h> 54 #endif 55 56 #include <machine/cpu.h> 57 58 static void settime __P((struct timeval *)); 59 60 /* 61 * Time of day and interval timer support. 62 * 63 * These routines provide the kernel entry points to get and set 64 * the time-of-day and per-process interval timers. Subroutines 65 * here provide support for adding and subtracting timeval structures 66 * and decrementing interval timers, optionally reloading the interval 67 * timers when they expire. 68 */ 69 70 /* This function is used by clock_settime and settimeofday */ 71 static void 72 settime(tv) 73 struct timeval *tv; 74 { 75 struct timeval delta; 76 int s; 77 78 /* WHAT DO WE DO ABOUT PENDING REAL-TIME TIMEOUTS??? */ 79 s = splclock(); 80 timersub(tv, &time, &delta); 81 time = *tv; 82 (void) splsoftclock(); 83 timeradd(&boottime, &delta, &boottime); 84 timeradd(&runtime, &delta, &runtime); 85 # if defined(NFS) || defined(NFSSERVER) 86 nqnfs_lease_updatetime(delta.tv_sec); 87 # endif 88 splx(s); 89 resettodr(); 90 } 91 92 /* ARGSUSED */ 93 int 94 sys_clock_gettime(p, v, retval) 95 struct proc *p; 96 void *v; 97 register_t *retval; 98 { 99 register struct sys_clock_gettime_args /* { 100 syscallarg(clockid_t) clock_id; 101 syscallarg(struct timespec *) tp; 102 } */ *uap = v; 103 clockid_t clock_id; 104 struct timeval atv; 105 struct timespec ats; 106 107 clock_id = SCARG(uap, clock_id); 108 if (clock_id != CLOCK_REALTIME) 109 return (EINVAL); 110 111 microtime(&atv); 112 TIMEVAL_TO_TIMESPEC(&atv,&ats); 113 114 return copyout(&ats, SCARG(uap, tp), sizeof(ats)); 115 } 116 117 /* ARGSUSED */ 118 int 119 sys_clock_settime(p, v, retval) 120 struct proc *p; 121 void *v; 122 register_t *retval; 123 { 124 register struct sys_clock_settime_args /* { 125 syscallarg(clockid_t) clock_id; 126 syscallarg(const struct timespec *) tp; 127 } */ *uap = v; 128 clockid_t clock_id; 129 struct timeval atv; 130 struct timespec ats; 131 int error; 132 133 if ((error = suser(p->p_ucred, &p->p_acflag)) != 0) 134 return (error); 135 136 clock_id = SCARG(uap, clock_id); 137 if (clock_id != CLOCK_REALTIME) 138 return (EINVAL); 139 140 if ((error = copyin(SCARG(uap, tp), &ats, sizeof(ats))) != 0) 141 return (error); 142 143 TIMESPEC_TO_TIMEVAL(&atv,&ats); 144 145 /* 146 * If the system is secure, we do not allow the time to be 147 * set to an earlier value (it may be slowed using adjtime, 148 * but not set back). This feature prevent interlopers from 149 * setting arbitrary time stamps on files. 150 */ 151 if (securelevel > 1 && timercmp(&atv, &time, <)) 152 return (EPERM); 153 settime(&atv); 154 155 return (0); 156 } 157 158 int 159 sys_clock_getres(p, v, retval) 160 struct proc *p; 161 void *v; 162 register_t *retval; 163 { 164 register struct sys_clock_getres_args /* { 165 syscallarg(clockid_t) clock_id; 166 syscallarg(struct timespec *) tp; 167 } */ *uap = v; 168 clockid_t clock_id; 169 struct timespec ts; 170 int error = 0; 171 172 clock_id = SCARG(uap, clock_id); 173 if (clock_id != CLOCK_REALTIME) 174 return (EINVAL); 175 176 if (SCARG(uap, tp)) { 177 ts.tv_sec = 0; 178 ts.tv_nsec = 1000000000 / hz; 179 180 error = copyout(&ts, SCARG(uap, tp), sizeof (ts)); 181 } 182 183 return error; 184 } 185 186 /* ARGSUSED */ 187 int 188 sys_nanosleep(p, v, retval) 189 struct proc *p; 190 void *v; 191 register_t *retval; 192 { 193 static int nanowait; 194 register struct sys_nanosleep_args/* { 195 syscallarg(const struct timespec *) rqtp; 196 syscallarg(struct timespec *) rmtp; 197 } */ *uap = v; 198 struct timespec rqt; 199 struct timespec rmt; 200 struct timeval atv, utv; 201 int error, s, timo; 202 203 error = copyin((const void *)SCARG(uap, rqtp), (void *)&rqt, 204 sizeof(struct timespec)); 205 if (error) 206 return (error); 207 208 TIMESPEC_TO_TIMEVAL(&atv,&rqt) 209 if (itimerfix(&atv)) 210 return (EINVAL); 211 212 s = splclock(); 213 timeradd(&atv,&time,&atv); 214 timo = hzto(&atv); 215 /* 216 * Avoid inadvertantly sleeping forever 217 */ 218 if (timo == 0) 219 timo = 1; 220 splx(s); 221 222 error = tsleep(&nanowait, PWAIT | PCATCH, "nanosleep", timo); 223 if (error == ERESTART) 224 error = EINTR; 225 if (error == EWOULDBLOCK) 226 error = 0; 227 228 if (SCARG(uap, rmtp)) { 229 int error; 230 231 s = splclock(); 232 utv = time; 233 splx(s); 234 235 timersub(&atv, &utv, &utv); 236 if (utv.tv_sec < 0) 237 timerclear(&utv); 238 239 TIMEVAL_TO_TIMESPEC(&utv, &rmt); 240 error = copyout((void *)&rmt, (void *)SCARG(uap,rmtp), 241 sizeof(rmt)); 242 if (error) 243 return (error); 244 } 245 246 return error; 247 } 248 249 /* ARGSUSED */ 250 int 251 sys_gettimeofday(p, v, retval) 252 struct proc *p; 253 void *v; 254 register_t *retval; 255 { 256 register struct sys_gettimeofday_args /* { 257 syscallarg(struct timeval *) tp; 258 syscallarg(struct timezone *) tzp; 259 } */ *uap = v; 260 struct timeval atv; 261 int error = 0; 262 263 if (SCARG(uap, tp)) { 264 microtime(&atv); 265 if ((error = copyout((void *)&atv, (void *)SCARG(uap, tp), 266 sizeof (atv)))) 267 return (error); 268 } 269 if (SCARG(uap, tzp)) 270 error = copyout((void *)&tz, (void *)SCARG(uap, tzp), 271 sizeof (tz)); 272 return (error); 273 } 274 275 /* ARGSUSED */ 276 int 277 sys_settimeofday(p, v, retval) 278 struct proc *p; 279 void *v; 280 register_t *retval; 281 { 282 struct sys_settimeofday_args /* { 283 syscallarg(struct timeval *) tv; 284 syscallarg(struct timezone *) tzp; 285 } */ *uap = v; 286 struct timeval atv; 287 struct timezone atz; 288 int error; 289 290 if ((error = suser(p->p_ucred, &p->p_acflag))) 291 return (error); 292 /* Verify all parameters before changing time. */ 293 if (SCARG(uap, tv) && (error = copyin((void *)SCARG(uap, tv), 294 (void *)&atv, sizeof(atv)))) 295 return (error); 296 if (SCARG(uap, tzp) && (error = copyin((void *)SCARG(uap, tzp), 297 (void *)&atz, sizeof(atz)))) 298 return (error); 299 if (SCARG(uap, tv)) { 300 /* 301 * If the system is secure, we do not allow the time to be 302 * set to an earlier value (it may be slowed using adjtime, 303 * but not set back). This feature prevent interlopers from 304 * setting arbitrary time stamps on files. 305 */ 306 if (securelevel > 1 && timercmp(&atv, &time, <)) 307 return (EPERM); 308 settime(&atv); 309 } 310 if (SCARG(uap, tzp)) 311 tz = atz; 312 return (0); 313 } 314 315 int tickdelta; /* current clock skew, us. per tick */ 316 long timedelta; /* unapplied time correction, us. */ 317 long bigadj = 1000000; /* use 10x skew above bigadj us. */ 318 319 /* ARGSUSED */ 320 int 321 sys_adjtime(p, v, retval) 322 struct proc *p; 323 void *v; 324 register_t *retval; 325 { 326 register struct sys_adjtime_args /* { 327 syscallarg(struct timeval *) delta; 328 syscallarg(struct timeval *) olddelta; 329 } */ *uap = v; 330 struct timeval atv; 331 register long ndelta, ntickdelta, odelta; 332 int s, error; 333 334 if ((error = suser(p->p_ucred, &p->p_acflag))) 335 return (error); 336 if ((error = copyin((void *)SCARG(uap, delta), (void *)&atv, 337 sizeof(struct timeval)))) 338 return (error); 339 340 /* 341 * Compute the total correction and the rate at which to apply it. 342 * Round the adjustment down to a whole multiple of the per-tick 343 * delta, so that after some number of incremental changes in 344 * hardclock(), tickdelta will become zero, lest the correction 345 * overshoot and start taking us away from the desired final time. 346 */ 347 ndelta = atv.tv_sec * 1000000 + atv.tv_usec; 348 if (ndelta > bigadj) 349 ntickdelta = 10 * tickadj; 350 else 351 ntickdelta = tickadj; 352 if (ndelta % ntickdelta) 353 ndelta = ndelta / ntickdelta * ntickdelta; 354 355 /* 356 * To make hardclock()'s job easier, make the per-tick delta negative 357 * if we want time to run slower; then hardclock can simply compute 358 * tick + tickdelta, and subtract tickdelta from timedelta. 359 */ 360 if (ndelta < 0) 361 ntickdelta = -ntickdelta; 362 s = splclock(); 363 odelta = timedelta; 364 timedelta = ndelta; 365 tickdelta = ntickdelta; 366 splx(s); 367 368 if (SCARG(uap, olddelta)) { 369 atv.tv_sec = odelta / 1000000; 370 atv.tv_usec = odelta % 1000000; 371 (void)copyout((void *)&atv, (void *)SCARG(uap, olddelta), 372 sizeof(struct timeval)); 373 } 374 return (0); 375 } 376 377 /* 378 * Get value of an interval timer. The process virtual and 379 * profiling virtual time timers are kept in the p_stats area, since 380 * they can be swapped out. These are kept internally in the 381 * way they are specified externally: in time until they expire. 382 * 383 * The real time interval timer is kept in the process table slot 384 * for the process, and its value (it_value) is kept as an 385 * absolute time rather than as a delta, so that it is easy to keep 386 * periodic real-time signals from drifting. 387 * 388 * Virtual time timers are processed in the hardclock() routine of 389 * kern_clock.c. The real time timer is processed by a timeout 390 * routine, called from the softclock() routine. Since a callout 391 * may be delayed in real time due to interrupt processing in the system, 392 * it is possible for the real time timeout routine (realitexpire, given below), 393 * to be delayed in real time past when it is supposed to occur. It 394 * does not suffice, therefore, to reload the real timer .it_value from the 395 * real time timers .it_interval. Rather, we compute the next time in 396 * absolute time the timer should go off. 397 */ 398 /* ARGSUSED */ 399 int 400 sys_getitimer(p, v, retval) 401 struct proc *p; 402 void *v; 403 register_t *retval; 404 { 405 register struct sys_getitimer_args /* { 406 syscallarg(u_int) which; 407 syscallarg(struct itimerval *) itv; 408 } */ *uap = v; 409 struct itimerval aitv; 410 int s; 411 412 if (SCARG(uap, which) > ITIMER_PROF) 413 return (EINVAL); 414 s = splclock(); 415 if (SCARG(uap, which) == ITIMER_REAL) { 416 /* 417 * Convert from absolute to relative time in .it_value 418 * part of real time timer. If time for real time timer 419 * has passed return 0, else return difference between 420 * current time and time for the timer to go off. 421 */ 422 aitv = p->p_realtimer; 423 if (timerisset(&aitv.it_value)) { 424 if (timercmp(&aitv.it_value, &time, <)) 425 timerclear(&aitv.it_value); 426 else 427 timersub(&aitv.it_value, &time, 428 &aitv.it_value); 429 } 430 } else 431 aitv = p->p_stats->p_timer[SCARG(uap, which)]; 432 splx(s); 433 return (copyout((void *)&aitv, (void *)SCARG(uap, itv), 434 sizeof (struct itimerval))); 435 } 436 437 /* ARGSUSED */ 438 int 439 sys_setitimer(p, v, retval) 440 struct proc *p; 441 register void *v; 442 register_t *retval; 443 { 444 register struct sys_setitimer_args /* { 445 syscallarg(u_int) which; 446 syscallarg(struct itimerval *) itv; 447 syscallarg(struct itimerval *) oitv; 448 } */ *uap = v; 449 struct itimerval aitv; 450 register const struct itimerval *itvp; 451 int s, error; 452 453 if (SCARG(uap, which) > ITIMER_PROF) 454 return (EINVAL); 455 itvp = SCARG(uap, itv); 456 if (itvp && (error = copyin((void *)itvp, (void *)&aitv, 457 sizeof(struct itimerval)))) 458 return (error); 459 if ((SCARG(uap, itv) = SCARG(uap, oitv)) && 460 (error = sys_getitimer(p, uap, retval))) 461 return (error); 462 if (itvp == 0) 463 return (0); 464 if (itimerfix(&aitv.it_value) || itimerfix(&aitv.it_interval)) 465 return (EINVAL); 466 s = splclock(); 467 if (SCARG(uap, which) == ITIMER_REAL) { 468 untimeout(realitexpire, (void *)p); 469 if (timerisset(&aitv.it_value)) { 470 timeradd(&aitv.it_value, &time, &aitv.it_value); 471 timeout(realitexpire, (void *)p, hzto(&aitv.it_value)); 472 } 473 p->p_realtimer = aitv; 474 } else 475 p->p_stats->p_timer[SCARG(uap, which)] = aitv; 476 splx(s); 477 return (0); 478 } 479 480 /* 481 * Real interval timer expired: 482 * send process whose timer expired an alarm signal. 483 * If time is not set up to reload, then just return. 484 * Else compute next time timer should go off which is > current time. 485 * This is where delay in processing this timeout causes multiple 486 * SIGALRM calls to be compressed into one. 487 */ 488 void 489 realitexpire(arg) 490 void *arg; 491 { 492 register struct proc *p; 493 int s; 494 495 p = (struct proc *)arg; 496 psignal(p, SIGALRM); 497 if (!timerisset(&p->p_realtimer.it_interval)) { 498 timerclear(&p->p_realtimer.it_value); 499 return; 500 } 501 for (;;) { 502 s = splclock(); 503 timeradd(&p->p_realtimer.it_value, 504 &p->p_realtimer.it_interval, &p->p_realtimer.it_value); 505 if (timercmp(&p->p_realtimer.it_value, &time, >)) { 506 timeout(realitexpire, (void *)p, 507 hzto(&p->p_realtimer.it_value)); 508 splx(s); 509 return; 510 } 511 splx(s); 512 } 513 } 514 515 /* 516 * Check that a proposed value to load into the .it_value or 517 * .it_interval part of an interval timer is acceptable, and 518 * fix it to have at least minimal value (i.e. if it is less 519 * than the resolution of the clock, round it up.) 520 */ 521 int 522 itimerfix(tv) 523 struct timeval *tv; 524 { 525 526 if (tv->tv_sec < 0 || tv->tv_sec > 100000000 || 527 tv->tv_usec < 0 || tv->tv_usec >= 1000000) 528 return (EINVAL); 529 if (tv->tv_sec == 0 && tv->tv_usec != 0 && tv->tv_usec < tick) 530 tv->tv_usec = tick; 531 return (0); 532 } 533 534 /* 535 * Decrement an interval timer by a specified number 536 * of microseconds, which must be less than a second, 537 * i.e. < 1000000. If the timer expires, then reload 538 * it. In this case, carry over (usec - old value) to 539 * reduce the value reloaded into the timer so that 540 * the timer does not drift. This routine assumes 541 * that it is called in a context where the timers 542 * on which it is operating cannot change in value. 543 */ 544 int 545 itimerdecr(itp, usec) 546 register struct itimerval *itp; 547 int usec; 548 { 549 550 if (itp->it_value.tv_usec < usec) { 551 if (itp->it_value.tv_sec == 0) { 552 /* expired, and already in next interval */ 553 usec -= itp->it_value.tv_usec; 554 goto expire; 555 } 556 itp->it_value.tv_usec += 1000000; 557 itp->it_value.tv_sec--; 558 } 559 itp->it_value.tv_usec -= usec; 560 usec = 0; 561 if (timerisset(&itp->it_value)) 562 return (1); 563 /* expired, exactly at end of interval */ 564 expire: 565 if (timerisset(&itp->it_interval)) { 566 itp->it_value = itp->it_interval; 567 itp->it_value.tv_usec -= usec; 568 if (itp->it_value.tv_usec < 0) { 569 itp->it_value.tv_usec += 1000000; 570 itp->it_value.tv_sec--; 571 } 572 } else 573 itp->it_value.tv_usec = 0; /* sec is already 0 */ 574 return (0); 575 } 576