1 /* $OpenBSD: kern_time.c,v 1.163 2023/02/15 10:07:50 claudio 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. Neither the name of the University nor the names of its contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 * 32 * @(#)kern_time.c 8.4 (Berkeley) 5/26/95 33 */ 34 35 #include <sys/param.h> 36 #include <sys/kernel.h> 37 #include <sys/systm.h> 38 #include <sys/mutex.h> 39 #include <sys/rwlock.h> 40 #include <sys/proc.h> 41 #include <sys/ktrace.h> 42 #include <sys/signalvar.h> 43 #include <sys/stdint.h> 44 #include <sys/pledge.h> 45 #include <sys/task.h> 46 #include <sys/timeout.h> 47 #include <sys/timetc.h> 48 49 #include <sys/mount.h> 50 #include <sys/syscallargs.h> 51 52 #include <dev/clock_subr.h> 53 54 int itimerfix(struct itimerval *); 55 56 /* 57 * Time of day and interval timer support. 58 * 59 * These routines provide the kernel entry points to get and set 60 * the time-of-day and per-process interval timers. Subroutines 61 * here provide support for adding and subtracting timeval structures 62 * and decrementing interval timers, optionally reloading the interval 63 * timers when they expire. 64 */ 65 66 /* This function is used by clock_settime and settimeofday */ 67 int 68 settime(const struct timespec *ts) 69 { 70 struct timespec now; 71 72 /* 73 * Don't allow the time to be set forward so far it will wrap 74 * and become negative, thus allowing an attacker to bypass 75 * the next check below. The cutoff is 1 year before rollover 76 * occurs, so even if the attacker uses adjtime(2) to move 77 * the time past the cutoff, it will take a very long time 78 * to get to the wrap point. 79 * 80 * XXX: we check against UINT_MAX until we can figure out 81 * how to deal with the hardware RTCs. 82 */ 83 if (ts->tv_sec > UINT_MAX - 365*24*60*60) { 84 printf("denied attempt to set clock forward to %lld\n", 85 (long long)ts->tv_sec); 86 return (EPERM); 87 } 88 /* 89 * If the system is secure, we do not allow the time to be 90 * set to an earlier value (it may be slowed using adjtime, 91 * but not set back). This feature prevent interlopers from 92 * setting arbitrary time stamps on files. 93 */ 94 nanotime(&now); 95 if (securelevel > 1 && timespeccmp(ts, &now, <=)) { 96 printf("denied attempt to set clock back %lld seconds\n", 97 (long long)now.tv_sec - ts->tv_sec); 98 return (EPERM); 99 } 100 101 tc_setrealtimeclock(ts); 102 KERNEL_LOCK(); 103 resettodr(); 104 KERNEL_UNLOCK(); 105 106 return (0); 107 } 108 109 int 110 clock_gettime(struct proc *p, clockid_t clock_id, struct timespec *tp) 111 { 112 struct proc *q; 113 int error = 0; 114 115 switch (clock_id) { 116 case CLOCK_REALTIME: 117 nanotime(tp); 118 break; 119 case CLOCK_UPTIME: 120 nanoruntime(tp); 121 break; 122 case CLOCK_MONOTONIC: 123 case CLOCK_BOOTTIME: 124 nanouptime(tp); 125 break; 126 case CLOCK_PROCESS_CPUTIME_ID: 127 nanouptime(tp); 128 timespecsub(tp, &curcpu()->ci_schedstate.spc_runtime, tp); 129 timespecadd(tp, &p->p_p->ps_tu.tu_runtime, tp); 130 timespecadd(tp, &p->p_rtime, tp); 131 break; 132 case CLOCK_THREAD_CPUTIME_ID: 133 nanouptime(tp); 134 timespecsub(tp, &curcpu()->ci_schedstate.spc_runtime, tp); 135 timespecadd(tp, &p->p_tu.tu_runtime, tp); 136 timespecadd(tp, &p->p_rtime, tp); 137 break; 138 default: 139 /* check for clock from pthread_getcpuclockid() */ 140 if (__CLOCK_TYPE(clock_id) == CLOCK_THREAD_CPUTIME_ID) { 141 KERNEL_LOCK(); 142 q = tfind_user(__CLOCK_PTID(clock_id), p->p_p); 143 if (q == NULL) 144 error = ESRCH; 145 else 146 *tp = q->p_tu.tu_runtime; 147 KERNEL_UNLOCK(); 148 } else 149 error = EINVAL; 150 break; 151 } 152 return (error); 153 } 154 155 int 156 sys_clock_gettime(struct proc *p, void *v, register_t *retval) 157 { 158 struct sys_clock_gettime_args /* { 159 syscallarg(clockid_t) clock_id; 160 syscallarg(struct timespec *) tp; 161 } */ *uap = v; 162 struct timespec ats; 163 int error; 164 165 memset(&ats, 0, sizeof(ats)); 166 if ((error = clock_gettime(p, SCARG(uap, clock_id), &ats)) != 0) 167 return (error); 168 169 error = copyout(&ats, SCARG(uap, tp), sizeof(ats)); 170 #ifdef KTRACE 171 if (error == 0 && KTRPOINT(p, KTR_STRUCT)) 172 ktrabstimespec(p, &ats); 173 #endif 174 return (error); 175 } 176 177 int 178 sys_clock_settime(struct proc *p, void *v, register_t *retval) 179 { 180 struct sys_clock_settime_args /* { 181 syscallarg(clockid_t) clock_id; 182 syscallarg(const struct timespec *) tp; 183 } */ *uap = v; 184 struct timespec ats; 185 clockid_t clock_id; 186 int error; 187 188 if ((error = suser(p)) != 0) 189 return (error); 190 191 if ((error = copyin(SCARG(uap, tp), &ats, sizeof(ats))) != 0) 192 return (error); 193 194 clock_id = SCARG(uap, clock_id); 195 switch (clock_id) { 196 case CLOCK_REALTIME: 197 if (!timespecisvalid(&ats)) 198 return (EINVAL); 199 if ((error = settime(&ats)) != 0) 200 return (error); 201 break; 202 default: /* Other clocks are read-only */ 203 return (EINVAL); 204 } 205 206 return (0); 207 } 208 209 int 210 sys_clock_getres(struct proc *p, void *v, register_t *retval) 211 { 212 struct sys_clock_getres_args /* { 213 syscallarg(clockid_t) clock_id; 214 syscallarg(struct timespec *) tp; 215 } */ *uap = v; 216 clockid_t clock_id; 217 struct bintime bt; 218 struct timespec ts; 219 struct proc *q; 220 u_int64_t scale; 221 int error = 0; 222 223 memset(&ts, 0, sizeof(ts)); 224 clock_id = SCARG(uap, clock_id); 225 226 switch (clock_id) { 227 case CLOCK_REALTIME: 228 case CLOCK_MONOTONIC: 229 case CLOCK_BOOTTIME: 230 case CLOCK_UPTIME: 231 memset(&bt, 0, sizeof(bt)); 232 rw_enter_read(&tc_lock); 233 scale = ((1ULL << 63) / tc_getfrequency()) * 2; 234 bt.frac = tc_getprecision() * scale; 235 rw_exit_read(&tc_lock); 236 BINTIME_TO_TIMESPEC(&bt, &ts); 237 break; 238 case CLOCK_PROCESS_CPUTIME_ID: 239 case CLOCK_THREAD_CPUTIME_ID: 240 ts.tv_nsec = 1000000000 / stathz; 241 break; 242 default: 243 /* check for clock from pthread_getcpuclockid() */ 244 if (__CLOCK_TYPE(clock_id) == CLOCK_THREAD_CPUTIME_ID) { 245 KERNEL_LOCK(); 246 q = tfind_user(__CLOCK_PTID(clock_id), p->p_p); 247 if (q == NULL) 248 error = ESRCH; 249 else 250 ts.tv_nsec = 1000000000 / stathz; 251 KERNEL_UNLOCK(); 252 } else 253 error = EINVAL; 254 break; 255 } 256 257 if (error == 0 && SCARG(uap, tp)) { 258 ts.tv_nsec = MAX(ts.tv_nsec, 1); 259 error = copyout(&ts, SCARG(uap, tp), sizeof(ts)); 260 #ifdef KTRACE 261 if (error == 0 && KTRPOINT(p, KTR_STRUCT)) 262 ktrreltimespec(p, &ts); 263 #endif 264 } 265 266 return error; 267 } 268 269 int 270 sys_nanosleep(struct proc *p, void *v, register_t *retval) 271 { 272 struct sys_nanosleep_args/* { 273 syscallarg(const struct timespec *) rqtp; 274 syscallarg(struct timespec *) rmtp; 275 } */ *uap = v; 276 struct timespec elapsed, remainder, request, start, stop; 277 uint64_t nsecs; 278 struct timespec *rmtp; 279 int copyout_error, error; 280 281 rmtp = SCARG(uap, rmtp); 282 error = copyin(SCARG(uap, rqtp), &request, sizeof(request)); 283 if (error) 284 return (error); 285 #ifdef KTRACE 286 if (KTRPOINT(p, KTR_STRUCT)) 287 ktrreltimespec(p, &request); 288 #endif 289 290 if (request.tv_sec < 0 || !timespecisvalid(&request)) 291 return (EINVAL); 292 293 do { 294 getnanouptime(&start); 295 nsecs = MAX(1, MIN(TIMESPEC_TO_NSEC(&request), MAXTSLP)); 296 error = tsleep_nsec(&nowake, PWAIT | PCATCH, "nanoslp", nsecs); 297 getnanouptime(&stop); 298 timespecsub(&stop, &start, &elapsed); 299 timespecsub(&request, &elapsed, &request); 300 if (request.tv_sec < 0) 301 timespecclear(&request); 302 if (error != EWOULDBLOCK) 303 break; 304 } while (timespecisset(&request)); 305 306 if (error == ERESTART) 307 error = EINTR; 308 if (error == EWOULDBLOCK) 309 error = 0; 310 311 if (rmtp) { 312 memset(&remainder, 0, sizeof(remainder)); 313 remainder = request; 314 copyout_error = copyout(&remainder, rmtp, sizeof(remainder)); 315 if (copyout_error) 316 error = copyout_error; 317 #ifdef KTRACE 318 if (copyout_error == 0 && KTRPOINT(p, KTR_STRUCT)) 319 ktrreltimespec(p, &remainder); 320 #endif 321 } 322 323 return error; 324 } 325 326 int 327 sys_gettimeofday(struct proc *p, void *v, register_t *retval) 328 { 329 struct sys_gettimeofday_args /* { 330 syscallarg(struct timeval *) tp; 331 syscallarg(struct timezone *) tzp; 332 } */ *uap = v; 333 struct timeval atv; 334 static const struct timezone zerotz = { 0, 0 }; 335 struct timeval *tp; 336 struct timezone *tzp; 337 int error = 0; 338 339 tp = SCARG(uap, tp); 340 tzp = SCARG(uap, tzp); 341 342 if (tp) { 343 memset(&atv, 0, sizeof(atv)); 344 microtime(&atv); 345 if ((error = copyout(&atv, tp, sizeof (atv)))) 346 return (error); 347 #ifdef KTRACE 348 if (KTRPOINT(p, KTR_STRUCT)) 349 ktrabstimeval(p, &atv); 350 #endif 351 } 352 if (tzp) 353 error = copyout(&zerotz, tzp, sizeof(zerotz)); 354 return (error); 355 } 356 357 int 358 sys_settimeofday(struct proc *p, void *v, register_t *retval) 359 { 360 struct sys_settimeofday_args /* { 361 syscallarg(const struct timeval *) tv; 362 syscallarg(const struct timezone *) tzp; 363 } */ *uap = v; 364 struct timezone atz; 365 struct timeval atv; 366 const struct timeval *tv; 367 const struct timezone *tzp; 368 int error; 369 370 tv = SCARG(uap, tv); 371 tzp = SCARG(uap, tzp); 372 373 if ((error = suser(p))) 374 return (error); 375 /* Verify all parameters before changing time. */ 376 if (tv && (error = copyin(tv, &atv, sizeof(atv)))) 377 return (error); 378 if (tzp && (error = copyin(tzp, &atz, sizeof(atz)))) 379 return (error); 380 if (tv) { 381 struct timespec ts; 382 383 #ifdef KTRACE 384 if (KTRPOINT(p, KTR_STRUCT)) 385 ktrabstimeval(p, &atv); 386 #endif 387 if (!timerisvalid(&atv)) 388 return (EINVAL); 389 TIMEVAL_TO_TIMESPEC(&atv, &ts); 390 if ((error = settime(&ts)) != 0) 391 return (error); 392 } 393 394 return (0); 395 } 396 397 #define ADJFREQ_MAX (500000000LL << 32) 398 #define ADJFREQ_MIN (-ADJFREQ_MAX) 399 400 int 401 sys_adjfreq(struct proc *p, void *v, register_t *retval) 402 { 403 struct sys_adjfreq_args /* { 404 syscallarg(const int64_t *) freq; 405 syscallarg(int64_t *) oldfreq; 406 } */ *uap = v; 407 int error = 0; 408 int64_t f, oldf; 409 const int64_t *freq = SCARG(uap, freq); 410 int64_t *oldfreq = SCARG(uap, oldfreq); 411 412 if (freq) { 413 if ((error = suser(p))) 414 return (error); 415 if ((error = copyin(freq, &f, sizeof(f)))) 416 return (error); 417 if (f < ADJFREQ_MIN || f > ADJFREQ_MAX) 418 return (EINVAL); 419 } 420 421 rw_enter(&tc_lock, (freq == NULL) ? RW_READ : RW_WRITE); 422 if (oldfreq) { 423 tc_adjfreq(&oldf, NULL); 424 if ((error = copyout(&oldf, oldfreq, sizeof(oldf)))) 425 goto out; 426 } 427 if (freq) 428 tc_adjfreq(NULL, &f); 429 out: 430 rw_exit(&tc_lock); 431 return (error); 432 } 433 434 int 435 sys_adjtime(struct proc *p, void *v, register_t *retval) 436 { 437 struct sys_adjtime_args /* { 438 syscallarg(const struct timeval *) delta; 439 syscallarg(struct timeval *) olddelta; 440 } */ *uap = v; 441 struct timeval atv; 442 const struct timeval *delta = SCARG(uap, delta); 443 struct timeval *olddelta = SCARG(uap, olddelta); 444 int64_t adjustment, remaining; 445 int error; 446 447 error = pledge_adjtime(p, delta); 448 if (error) 449 return error; 450 451 if (delta) { 452 if ((error = suser(p))) 453 return (error); 454 if ((error = copyin(delta, &atv, sizeof(struct timeval)))) 455 return (error); 456 #ifdef KTRACE 457 if (KTRPOINT(p, KTR_STRUCT)) 458 ktrreltimeval(p, &atv); 459 #endif 460 if (!timerisvalid(&atv)) 461 return (EINVAL); 462 463 if (atv.tv_sec > INT64_MAX / 1000000) 464 return EINVAL; 465 if (atv.tv_sec < INT64_MIN / 1000000) 466 return EINVAL; 467 adjustment = atv.tv_sec * 1000000; 468 if (adjustment > INT64_MAX - atv.tv_usec) 469 return EINVAL; 470 adjustment += atv.tv_usec; 471 472 rw_enter_write(&tc_lock); 473 } 474 475 if (olddelta) { 476 tc_adjtime(&remaining, NULL); 477 memset(&atv, 0, sizeof(atv)); 478 atv.tv_sec = remaining / 1000000; 479 atv.tv_usec = remaining % 1000000; 480 if (atv.tv_usec < 0) { 481 atv.tv_usec += 1000000; 482 atv.tv_sec--; 483 } 484 485 if ((error = copyout(&atv, olddelta, sizeof(struct timeval)))) 486 goto out; 487 } 488 489 if (delta) 490 tc_adjtime(NULL, &adjustment); 491 out: 492 if (delta) 493 rw_exit_write(&tc_lock); 494 return (error); 495 } 496 497 498 struct mutex itimer_mtx = MUTEX_INITIALIZER(IPL_CLOCK); 499 500 /* 501 * Get or set value of an interval timer. The process virtual and 502 * profiling virtual time timers are kept internally in the 503 * way they are specified externally: in time until they expire. 504 * 505 * The real time interval timer's it_value, in contrast, is kept as an 506 * absolute time rather than as a delta, so that it is easy to keep 507 * periodic real-time signals from drifting. 508 * 509 * Virtual time timers are processed in the hardclock() routine of 510 * kern_clock.c. The real time timer is processed by a timeout 511 * routine, called from the softclock() routine. Since a callout 512 * may be delayed in real time due to interrupt processing in the system, 513 * it is possible for the real time timeout routine (realitexpire, given below), 514 * to be delayed in real time past when it is supposed to occur. It 515 * does not suffice, therefore, to reload the real timer .it_value from the 516 * real time timers .it_interval. Rather, we compute the next time in 517 * absolute time the timer should go off. 518 */ 519 void 520 setitimer(int which, const struct itimerval *itv, struct itimerval *olditv) 521 { 522 struct itimerspec its, oldits; 523 struct timespec now; 524 struct itimerspec *itimer; 525 struct process *pr; 526 527 KASSERT(which >= ITIMER_REAL && which <= ITIMER_PROF); 528 529 pr = curproc->p_p; 530 itimer = &pr->ps_timer[which]; 531 532 if (itv != NULL) { 533 TIMEVAL_TO_TIMESPEC(&itv->it_value, &its.it_value); 534 TIMEVAL_TO_TIMESPEC(&itv->it_interval, &its.it_interval); 535 } 536 537 if (which == ITIMER_REAL) { 538 mtx_enter(&pr->ps_mtx); 539 nanouptime(&now); 540 } else 541 mtx_enter(&itimer_mtx); 542 543 if (olditv != NULL) 544 oldits = *itimer; 545 if (itv != NULL) { 546 if (which == ITIMER_REAL) { 547 if (timespecisset(&its.it_value)) { 548 timespecadd(&its.it_value, &now, &its.it_value); 549 timeout_abs_ts(&pr->ps_realit_to,&its.it_value); 550 } else 551 timeout_del(&pr->ps_realit_to); 552 } 553 *itimer = its; 554 } 555 556 if (which == ITIMER_REAL) 557 mtx_leave(&pr->ps_mtx); 558 else 559 mtx_leave(&itimer_mtx); 560 561 if (olditv != NULL) { 562 if (which == ITIMER_REAL && timespecisset(&oldits.it_value)) { 563 if (timespeccmp(&oldits.it_value, &now, <)) 564 timespecclear(&oldits.it_value); 565 else { 566 timespecsub(&oldits.it_value, &now, 567 &oldits.it_value); 568 } 569 } 570 TIMESPEC_TO_TIMEVAL(&olditv->it_value, &oldits.it_value); 571 TIMESPEC_TO_TIMEVAL(&olditv->it_interval, &oldits.it_interval); 572 } 573 } 574 575 void 576 cancel_all_itimers(void) 577 { 578 struct itimerval itv; 579 int i; 580 581 timerclear(&itv.it_value); 582 timerclear(&itv.it_interval); 583 584 for (i = 0; i < nitems(curproc->p_p->ps_timer); i++) 585 setitimer(i, &itv, NULL); 586 } 587 588 int 589 sys_getitimer(struct proc *p, void *v, register_t *retval) 590 { 591 struct sys_getitimer_args /* { 592 syscallarg(int) which; 593 syscallarg(struct itimerval *) itv; 594 } */ *uap = v; 595 struct itimerval aitv; 596 int which; 597 598 which = SCARG(uap, which); 599 if (which < ITIMER_REAL || which > ITIMER_PROF) 600 return EINVAL; 601 602 memset(&aitv, 0, sizeof(aitv)); 603 604 setitimer(which, NULL, &aitv); 605 606 return copyout(&aitv, SCARG(uap, itv), sizeof(aitv)); 607 } 608 609 int 610 sys_setitimer(struct proc *p, void *v, register_t *retval) 611 { 612 struct sys_setitimer_args /* { 613 syscallarg(int) which; 614 syscallarg(const struct itimerval *) itv; 615 syscallarg(struct itimerval *) oitv; 616 } */ *uap = v; 617 struct itimerval aitv, olditv; 618 struct itimerval *newitvp, *olditvp; 619 int error, which; 620 621 which = SCARG(uap, which); 622 if (which < ITIMER_REAL || which > ITIMER_PROF) 623 return EINVAL; 624 625 newitvp = olditvp = NULL; 626 if (SCARG(uap, itv) != NULL) { 627 error = copyin(SCARG(uap, itv), &aitv, sizeof(aitv)); 628 if (error) 629 return error; 630 error = itimerfix(&aitv); 631 if (error) 632 return error; 633 newitvp = &aitv; 634 } 635 if (SCARG(uap, oitv) != NULL) { 636 memset(&olditv, 0, sizeof(olditv)); 637 olditvp = &olditv; 638 } 639 if (newitvp == NULL && olditvp == NULL) 640 return 0; 641 642 setitimer(which, newitvp, olditvp); 643 644 if (SCARG(uap, oitv) != NULL) 645 return copyout(&olditv, SCARG(uap, oitv), sizeof(olditv)); 646 647 return 0; 648 } 649 650 /* 651 * Real interval timer expired: 652 * send process whose timer expired an alarm signal. 653 * If time is not set up to reload, then just return. 654 * Else compute next time timer should go off which is > current time. 655 * This is where delay in processing this timeout causes multiple 656 * SIGALRM calls to be compressed into one. 657 */ 658 void 659 realitexpire(void *arg) 660 { 661 struct timespec cts; 662 struct process *pr = arg; 663 struct itimerspec *tp = &pr->ps_timer[ITIMER_REAL]; 664 int need_signal = 0; 665 666 mtx_enter(&pr->ps_mtx); 667 668 /* 669 * Do nothing if the timer was cancelled or rescheduled while we 670 * were entering the mutex. 671 */ 672 if (!timespecisset(&tp->it_value) || timeout_pending(&pr->ps_realit_to)) 673 goto out; 674 675 /* The timer expired. We need to send the signal. */ 676 need_signal = 1; 677 678 /* One-shot timers are not reloaded. */ 679 if (!timespecisset(&tp->it_interval)) { 680 timespecclear(&tp->it_value); 681 goto out; 682 } 683 684 /* 685 * Find the nearest future expiration point and restart 686 * the timeout. 687 */ 688 nanouptime(&cts); 689 while (timespeccmp(&tp->it_value, &cts, <=)) 690 timespecadd(&tp->it_value, &tp->it_interval, &tp->it_value); 691 if ((pr->ps_flags & PS_EXITING) == 0) 692 timeout_abs_ts(&pr->ps_realit_to, &tp->it_value); 693 694 out: 695 mtx_leave(&pr->ps_mtx); 696 697 if (need_signal) 698 prsignal(pr, SIGALRM); 699 } 700 701 /* 702 * Check if the given setitimer(2) input is valid. Clear it_interval 703 * if it_value is unset. Round it_interval up to the minimum interval 704 * if necessary. 705 */ 706 int 707 itimerfix(struct itimerval *itv) 708 { 709 static const struct timeval max = { .tv_sec = UINT_MAX, .tv_usec = 0 }; 710 struct timeval min_interval = { .tv_sec = 0, .tv_usec = tick }; 711 712 if (itv->it_value.tv_sec < 0 || !timerisvalid(&itv->it_value)) 713 return EINVAL; 714 if (timercmp(&itv->it_value, &max, >)) 715 return EINVAL; 716 if (itv->it_interval.tv_sec < 0 || !timerisvalid(&itv->it_interval)) 717 return EINVAL; 718 if (timercmp(&itv->it_interval, &max, >)) 719 return EINVAL; 720 721 if (!timerisset(&itv->it_value)) 722 timerclear(&itv->it_interval); 723 if (timerisset(&itv->it_interval)) { 724 if (timercmp(&itv->it_interval, &min_interval, <)) 725 itv->it_interval = min_interval; 726 } 727 728 return 0; 729 } 730 731 /* 732 * Decrement an interval timer by the given number of nanoseconds. 733 * If the timer expires and it is periodic then reload it. When reloading 734 * the timer we subtract any overrun from the next period so that the timer 735 * does not drift. 736 */ 737 int 738 itimerdecr(struct itimerspec *itp, long nsec) 739 { 740 struct timespec decrement; 741 742 NSEC_TO_TIMESPEC(nsec, &decrement); 743 744 mtx_enter(&itimer_mtx); 745 746 /* 747 * Double-check that the timer is enabled. A different thread 748 * in setitimer(2) may have disabled it while we were entering 749 * the mutex. 750 */ 751 if (!timespecisset(&itp->it_value)) { 752 mtx_leave(&itimer_mtx); 753 return (1); 754 } 755 756 /* 757 * The timer is enabled. Update and reload it as needed. 758 */ 759 timespecsub(&itp->it_value, &decrement, &itp->it_value); 760 if (itp->it_value.tv_sec >= 0 && timespecisset(&itp->it_value)) { 761 mtx_leave(&itimer_mtx); 762 return (1); 763 } 764 if (!timespecisset(&itp->it_interval)) { 765 timespecclear(&itp->it_value); 766 mtx_leave(&itimer_mtx); 767 return (0); 768 } 769 while (itp->it_value.tv_sec < 0 || !timespecisset(&itp->it_value)) 770 timespecadd(&itp->it_value, &itp->it_interval, &itp->it_value); 771 mtx_leave(&itimer_mtx); 772 return (0); 773 } 774 775 struct mutex ratecheck_mtx = MUTEX_INITIALIZER(IPL_HIGH); 776 777 /* 778 * ratecheck(): simple time-based rate-limit checking. see ratecheck(9) 779 * for usage and rationale. 780 */ 781 int 782 ratecheck(struct timeval *lasttime, const struct timeval *mininterval) 783 { 784 struct timeval tv, delta; 785 int rv = 0; 786 787 getmicrouptime(&tv); 788 789 mtx_enter(&ratecheck_mtx); 790 timersub(&tv, lasttime, &delta); 791 792 /* 793 * check for 0,0 is so that the message will be seen at least once, 794 * even if interval is huge. 795 */ 796 if (timercmp(&delta, mininterval, >=) || 797 (lasttime->tv_sec == 0 && lasttime->tv_usec == 0)) { 798 *lasttime = tv; 799 rv = 1; 800 } 801 mtx_leave(&ratecheck_mtx); 802 803 return (rv); 804 } 805 806 struct mutex ppsratecheck_mtx = MUTEX_INITIALIZER(IPL_HIGH); 807 808 /* 809 * ppsratecheck(): packets (or events) per second limitation. 810 */ 811 int 812 ppsratecheck(struct timeval *lasttime, int *curpps, int maxpps) 813 { 814 struct timeval tv, delta; 815 int rv; 816 817 microuptime(&tv); 818 819 mtx_enter(&ppsratecheck_mtx); 820 timersub(&tv, lasttime, &delta); 821 822 /* 823 * check for 0,0 is so that the message will be seen at least once. 824 * if more than one second have passed since the last update of 825 * lasttime, reset the counter. 826 * 827 * we do increment *curpps even in *curpps < maxpps case, as some may 828 * try to use *curpps for stat purposes as well. 829 */ 830 if (maxpps == 0) 831 rv = 0; 832 else if ((lasttime->tv_sec == 0 && lasttime->tv_usec == 0) || 833 delta.tv_sec >= 1) { 834 *lasttime = tv; 835 *curpps = 0; 836 rv = 1; 837 } else if (maxpps < 0) 838 rv = 1; 839 else if (*curpps < maxpps) 840 rv = 1; 841 else 842 rv = 0; 843 844 /* be careful about wrap-around */ 845 if (*curpps + 1 > *curpps) 846 *curpps = *curpps + 1; 847 848 mtx_leave(&ppsratecheck_mtx); 849 850 return (rv); 851 } 852 853 todr_chip_handle_t todr_handle; 854 int inittodr_done; 855 856 #define MINYEAR ((OpenBSD / 100) - 1) /* minimum plausible year */ 857 858 /* 859 * inittodr: 860 * 861 * Initialize time from the time-of-day register. 862 */ 863 void 864 inittodr(time_t base) 865 { 866 time_t deltat; 867 struct timeval rtctime; 868 struct timespec ts; 869 int badbase; 870 871 inittodr_done = 1; 872 873 if (base < (MINYEAR - 1970) * SECYR) { 874 printf("WARNING: preposterous time in file system\n"); 875 /* read the system clock anyway */ 876 base = (MINYEAR - 1970) * SECYR; 877 badbase = 1; 878 } else 879 badbase = 0; 880 881 rtctime.tv_sec = base; 882 rtctime.tv_usec = 0; 883 884 if (todr_handle == NULL || 885 todr_gettime(todr_handle, &rtctime) != 0 || 886 rtctime.tv_sec < (MINYEAR - 1970) * SECYR) { 887 /* 888 * Believe the time in the file system for lack of 889 * anything better, resetting the TODR. 890 */ 891 rtctime.tv_sec = base; 892 rtctime.tv_usec = 0; 893 if (todr_handle != NULL && !badbase) 894 printf("WARNING: bad clock chip time\n"); 895 ts.tv_sec = rtctime.tv_sec; 896 ts.tv_nsec = rtctime.tv_usec * 1000; 897 tc_setclock(&ts); 898 goto bad; 899 } else { 900 ts.tv_sec = rtctime.tv_sec; 901 ts.tv_nsec = rtctime.tv_usec * 1000; 902 tc_setclock(&ts); 903 } 904 905 if (!badbase) { 906 /* 907 * See if we gained/lost two or more days; if 908 * so, assume something is amiss. 909 */ 910 deltat = rtctime.tv_sec - base; 911 if (deltat < 0) 912 deltat = -deltat; 913 if (deltat < 2 * SECDAY) 914 return; /* all is well */ 915 #ifndef SMALL_KERNEL 916 printf("WARNING: clock %s %lld days\n", 917 rtctime.tv_sec < base ? "lost" : "gained", 918 (long long)(deltat / SECDAY)); 919 #endif 920 } 921 bad: 922 printf("WARNING: CHECK AND RESET THE DATE!\n"); 923 } 924 925 /* 926 * resettodr: 927 * 928 * Reset the time-of-day register with the current time. 929 */ 930 void 931 resettodr(void) 932 { 933 struct timeval rtctime; 934 935 /* 936 * Skip writing the RTC if inittodr(9) never ran. We don't 937 * want to overwrite a reasonable value with a nonsense value. 938 */ 939 if (!inittodr_done) 940 return; 941 942 microtime(&rtctime); 943 944 if (todr_handle != NULL && 945 todr_settime(todr_handle, &rtctime) != 0) 946 printf("WARNING: can't update clock chip time\n"); 947 } 948 949 void 950 todr_attach(struct todr_chip_handle *todr) 951 { 952 if (todr_handle == NULL || 953 todr->todr_quality > todr_handle->todr_quality) 954 todr_handle = todr; 955 } 956 957 #define RESETTODR_PERIOD 1800 958 959 void periodic_resettodr(void *); 960 void perform_resettodr(void *); 961 962 struct timeout resettodr_to = TIMEOUT_INITIALIZER(periodic_resettodr, NULL); 963 struct task resettodr_task = TASK_INITIALIZER(perform_resettodr, NULL); 964 965 void 966 periodic_resettodr(void *arg __unused) 967 { 968 task_add(systq, &resettodr_task); 969 } 970 971 void 972 perform_resettodr(void *arg __unused) 973 { 974 resettodr(); 975 timeout_add_sec(&resettodr_to, RESETTODR_PERIOD); 976 } 977 978 void 979 start_periodic_resettodr(void) 980 { 981 timeout_add_sec(&resettodr_to, RESETTODR_PERIOD); 982 } 983 984 void 985 stop_periodic_resettodr(void) 986 { 987 timeout_del(&resettodr_to); 988 task_del(systq, &resettodr_task); 989 } 990