1 /* $NetBSD: netbsd32_time.c,v 1.22 2006/06/07 22:33:33 kardel Exp $ */ 2 3 /* 4 * Copyright (c) 1998, 2001 Matthew R. Green 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. The name of the author may not be used to endorse or promote products 16 * derived from this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 23 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 25 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * SUCH DAMAGE. 29 */ 30 31 #include <sys/cdefs.h> 32 __KERNEL_RCSID(0, "$NetBSD: netbsd32_time.c,v 1.22 2006/06/07 22:33:33 kardel Exp $"); 33 34 #if defined(_KERNEL_OPT) 35 #include "opt_ntp.h" 36 #include "opt_compat_netbsd.h" 37 #endif 38 39 #include <sys/param.h> 40 #include <sys/systm.h> 41 #include <sys/mount.h> 42 #include <sys/time.h> 43 #include <sys/timex.h> 44 #include <sys/timevar.h> 45 #include <sys/timetc.h> 46 #include <sys/proc.h> 47 #include <sys/pool.h> 48 #include <sys/resourcevar.h> 49 #include <sys/dirent.h> 50 #include <sys/kauth.h> 51 52 #include <compat/netbsd32/netbsd32.h> 53 #include <compat/netbsd32/netbsd32_syscallargs.h> 54 #include <compat/netbsd32/netbsd32_conv.h> 55 56 #ifdef NTP 57 58 int 59 netbsd32_ntp_gettime(l, v, retval) 60 struct lwp *l; 61 void *v; 62 register_t *retval; 63 { 64 struct netbsd32_ntp_gettime_args /* { 65 syscallarg(netbsd32_ntptimevalp_t) ntvp; 66 } */ *uap = v; 67 struct netbsd32_ntptimeval ntv32; 68 struct ntptimeval ntv; 69 int error = 0; 70 71 if (SCARG(uap, ntvp)) { 72 ntp_gettime(&ntv); 73 74 ntv32.time.tv_sec = ntv.time.tv_sec; 75 ntv32.time.tv_nsec = ntv.time.tv_nsec; 76 ntv32.maxerror = (netbsd32_long)ntv.maxerror; 77 ntv32.esterror = (netbsd32_long)ntv.esterror; 78 ntv32.tai = (netbsd32_long)ntv.tai; 79 ntv32.time_state = ntv.time_state; 80 error = copyout((caddr_t)&ntv32, 81 (caddr_t)NETBSD32PTR64(SCARG(uap, ntvp)), sizeof(ntv32)); 82 } 83 if (!error) { 84 *retval = ntp_timestatus(); 85 } 86 87 return (error); 88 } 89 90 #ifdef COMPAT_30 91 int 92 compat_30_netbsd32_ntp_gettime(l, v, retval) 93 struct lwp *l; 94 void *v; 95 register_t *retval; 96 { 97 struct compat_30_netbsd32_ntp_gettime_args /* { 98 syscallarg(netbsd32_ntptimevalp_t) ntvp; 99 } */ *uap = v; 100 struct netbsd32_ntptimeval30 ntv32; 101 struct ntptimeval ntv; 102 int error = 0; 103 104 if (SCARG(uap, ntvp)) { 105 ntp_gettime(&ntv); 106 107 ntv32.time.tv_sec = ntv.time.tv_sec; 108 ntv32.time.tv_usec = ntv.time.tv_nsec / 1000; 109 ntv32.maxerror = (netbsd32_long)ntv.maxerror; 110 ntv32.esterror = (netbsd32_long)ntv.esterror; 111 error = copyout((caddr_t)&ntv32, 112 (caddr_t)NETBSD32PTR64(SCARG(uap, ntvp)), sizeof(ntv32)); 113 } 114 if (!error) { 115 *retval = ntp_timestatus(); 116 } 117 118 return (error); 119 } 120 #endif 121 122 int 123 netbsd32_ntp_adjtime(l, v, retval) 124 struct lwp *l; 125 void *v; 126 register_t *retval; 127 { 128 struct netbsd32_ntp_adjtime_args /* { 129 syscallarg(netbsd32_timexp_t) tp; 130 } */ *uap = v; 131 struct netbsd32_timex ntv32; 132 struct timex ntv; 133 int error = 0; 134 int modes; 135 struct proc *p = l->l_proc; 136 137 if ((error = copyin((caddr_t)NETBSD32PTR64(SCARG(uap, tp)), 138 (caddr_t)&ntv32, sizeof(ntv32)))) 139 return (error); 140 141 netbsd32_to_timex(&ntv32, &ntv); 142 143 /* 144 * Update selected clock variables - only the superuser can 145 * change anything. Note that there is no error checking here on 146 * the assumption the superuser should know what it is doing. 147 */ 148 modes = ntv.modes; 149 if (modes != 0 && (error = kauth_authorize_generic(p->p_cred, KAUTH_GENERIC_ISSUSER, &p->p_acflag))) 150 return (error); 151 152 ntp_adjtime1(&ntv); 153 154 netbsd32_from_timex(&ntv, &ntv32); 155 error = copyout((caddr_t)&ntv32, (caddr_t)NETBSD32PTR64(SCARG(uap, tp)), 156 sizeof(ntv32)); 157 if (!error) { 158 *retval = ntp_timestatus(); 159 } 160 return error; 161 } 162 #else /* !NTP */ 163 int 164 netbsd32_ntp_gettime(l, v, retval) 165 struct lwp *l; 166 void *v; 167 register_t *retval; 168 { 169 170 return (ENOSYS); 171 } 172 173 #ifdef COMPAT_30 174 int 175 compat_30_netbsd32_ntp_gettime(l, v, retval) 176 struct lwp *l; 177 void *v; 178 register_t *retval; 179 { 180 181 return (ENOSYS); 182 } 183 #endif 184 185 int 186 netbsd32_ntp_adjtime(l, v, retval) 187 struct lwp *l; 188 void *v; 189 register_t *retval; 190 { 191 192 return (ENOSYS); 193 } 194 #endif /* NTP */ 195 196 int 197 netbsd32_setitimer(l, v, retval) 198 struct lwp *l; 199 void *v; 200 register_t *retval; 201 { 202 struct netbsd32_setitimer_args /* { 203 syscallarg(int) which; 204 syscallarg(const netbsd32_itimervalp_t) itv; 205 syscallarg(netbsd32_itimervalp_t) oitv; 206 } */ *uap = v; 207 struct proc *p = l->l_proc; 208 struct netbsd32_itimerval s32it, *itv32; 209 int which = SCARG(uap, which); 210 struct netbsd32_getitimer_args getargs; 211 struct itimerval aitv; 212 int error; 213 214 if ((u_int)which > ITIMER_PROF) 215 return (EINVAL); 216 itv32 = (struct netbsd32_itimerval *)NETBSD32PTR64(SCARG(uap, itv)); 217 if (itv32) { 218 if ((error = copyin(itv32, &s32it, sizeof(s32it)))) 219 return (error); 220 netbsd32_to_itimerval(&s32it, &aitv); 221 } 222 if (SCARG(uap, oitv) != 0) { 223 SCARG(&getargs, which) = which; 224 SCARG(&getargs, itv) = SCARG(uap, oitv); 225 if ((error = netbsd32_getitimer(l, &getargs, retval)) != 0) 226 return (error); 227 } 228 if (itv32 == 0) 229 return 0; 230 231 return dosetitimer(p, which, &aitv); 232 } 233 234 int 235 netbsd32_getitimer(l, v, retval) 236 struct lwp *l; 237 void *v; 238 register_t *retval; 239 { 240 struct netbsd32_getitimer_args /* { 241 syscallarg(int) which; 242 syscallarg(netbsd32_itimervalp_t) itv; 243 } */ *uap = v; 244 struct proc *p = l->l_proc; 245 struct netbsd32_itimerval s32it; 246 struct itimerval aitv; 247 int error; 248 249 error = dogetitimer(p, SCARG(uap, which), &aitv); 250 if (error) 251 return error; 252 253 netbsd32_from_itimerval(&aitv, &s32it); 254 return (copyout(&s32it, (caddr_t)NETBSD32PTR64(SCARG(uap, itv)), 255 sizeof(s32it))); 256 } 257 258 int 259 netbsd32_gettimeofday(l, v, retval) 260 struct lwp *l; 261 void *v; 262 register_t *retval; 263 { 264 struct netbsd32_gettimeofday_args /* { 265 syscallarg(netbsd32_timevalp_t) tp; 266 syscallarg(netbsd32_timezonep_t) tzp; 267 } */ *uap = v; 268 struct timeval atv; 269 struct netbsd32_timeval tv32; 270 int error = 0; 271 struct netbsd32_timezone tzfake; 272 273 if (SCARG(uap, tp)) { 274 microtime(&atv); 275 netbsd32_from_timeval(&atv, &tv32); 276 error = copyout(&tv32, (caddr_t)NETBSD32PTR64(SCARG(uap, tp)), 277 sizeof(tv32)); 278 if (error) 279 return (error); 280 } 281 if (SCARG(uap, tzp)) { 282 /* 283 * NetBSD has no kernel notion of time zone, so we just 284 * fake up a timezone struct and return it if demanded. 285 */ 286 tzfake.tz_minuteswest = 0; 287 tzfake.tz_dsttime = 0; 288 error = copyout(&tzfake, 289 (caddr_t)NETBSD32PTR64(SCARG(uap, tzp)), sizeof(tzfake)); 290 } 291 return (error); 292 } 293 294 int 295 netbsd32_settimeofday(l, v, retval) 296 struct lwp *l; 297 void *v; 298 register_t *retval; 299 { 300 struct netbsd32_settimeofday_args /* { 301 syscallarg(const netbsd32_timevalp_t) tv; 302 syscallarg(const netbsd32_timezonep_t) tzp; 303 } */ *uap = v; 304 struct netbsd32_timeval atv32; 305 struct timeval atv; 306 struct timespec ats; 307 int error; 308 struct proc *p = l->l_proc; 309 310 /* Verify all parameters before changing time. */ 311 if ((error = kauth_authorize_generic(p->p_cred, KAUTH_GENERIC_ISSUSER, &p->p_acflag)) != 0) 312 return error; 313 314 /* 315 * NetBSD has no kernel notion of time zone, and only an 316 * obsolete program would try to set it, so we log a warning. 317 */ 318 if (SCARG(uap, tzp)) 319 printf("pid %d attempted to set the " 320 "(obsolete) kernel time zone\n", p->p_pid); 321 322 if (SCARG(uap, tv) == 0) 323 return 0; 324 325 if ((error = copyin((caddr_t)NETBSD32PTR64(SCARG(uap, tv)), &atv32, 326 sizeof(atv32))) != 0) 327 return error; 328 329 netbsd32_to_timeval(&atv32, &atv); 330 TIMEVAL_TO_TIMESPEC(&atv, &ats); 331 return settime(p, &ats); 332 } 333 334 int 335 netbsd32_adjtime(l, v, retval) 336 struct lwp *l; 337 void *v; 338 register_t *retval; 339 { 340 struct netbsd32_adjtime_args /* { 341 syscallarg(const netbsd32_timevalp_t) delta; 342 syscallarg(netbsd32_timevalp_t) olddelta; 343 } */ *uap = v; 344 struct netbsd32_timeval atv; 345 int error; 346 struct proc *p = l->l_proc; 347 348 if ((error = kauth_authorize_generic(p->p_cred, KAUTH_GENERIC_ISSUSER, &p->p_acflag)) != 0) 349 return (error); 350 #ifdef __HAVE_TIMECOUNTER 351 { 352 extern int time_adjusted; /* in kern_ntptime.c */ 353 extern int64_t time_adjtime; /* in kern_ntptime.c */ 354 if (SCARG(uap, olddelta)) { 355 atv.tv_sec = time_adjtime / 1000000; 356 atv.tv_usec = time_adjtime % 1000000; 357 if (atv.tv_usec < 0) { 358 atv.tv_usec += 1000000; 359 atv.tv_sec--; 360 } 361 (void) copyout(&atv, 362 (caddr_t)NETBSD32PTR64(SCARG(uap, olddelta)), 363 sizeof(atv)); 364 if (error) 365 return (error); 366 } 367 368 if (SCARG(uap, delta)) { 369 error = copyin((caddr_t)NETBSD32PTR64(SCARG(uap, delta)), &atv, 370 sizeof(struct timeval)); 371 if (error) 372 return (error); 373 374 time_adjtime = (int64_t)atv.tv_sec * 1000000 + 375 atv.tv_usec; 376 377 if (time_adjtime) 378 /* We need to save the system time during shutdown */ 379 time_adjusted |= 1; 380 } 381 } 382 #else /* !__HAVE_TIMECOUNTER */ 383 { 384 int32_t ndelta, ntickdelta, odelta; 385 extern long bigadj, timedelta; 386 extern int tickdelta; 387 int s; 388 error = copyin((caddr_t)NETBSD32PTR64(SCARG(uap, delta)), &atv, 389 sizeof(struct timeval)); 390 if (error) 391 return (error); 392 /* 393 * Compute the total correction and the rate at which to apply it. 394 * Round the adjustment down to a whole multiple of the per-tick 395 * delta, so that after some number of incremental changes in 396 * hardclock(), tickdelta will become zero, lest the correction 397 * overshoot and start taking us away from the desired final time. 398 */ 399 ndelta = atv.tv_sec * 1000000 + atv.tv_usec; 400 if (ndelta > bigadj) 401 ntickdelta = 10 * tickadj; 402 else 403 ntickdelta = tickadj; 404 if (ndelta % ntickdelta) 405 ndelta = ndelta / ntickdelta * ntickdelta; 406 407 /* 408 * To make hardclock()'s job easier, make the per-tick delta negative 409 * if we want time to run slower; then hardclock can simply compute 410 * tick + tickdelta, and subtract tickdelta from timedelta. 411 */ 412 if (ndelta < 0) 413 ntickdelta = -ntickdelta; 414 s = splclock(); 415 odelta = timedelta; 416 timedelta = ndelta; 417 tickdelta = ntickdelta; 418 splx(s); 419 420 if (SCARG(uap, olddelta)) { 421 atv.tv_sec = odelta / 1000000; 422 atv.tv_usec = odelta % 1000000; 423 (void) copyout(&atv, 424 (caddr_t)NETBSD32PTR64(SCARG(uap, olddelta)), sizeof(atv)); 425 } 426 } 427 #endif /* !__HAVE_TIMECOUNTER */ 428 return (0); 429 } 430 431 int 432 netbsd32_clock_gettime(l, v, retval) 433 struct lwp *l; 434 void *v; 435 register_t *retval; 436 { 437 struct netbsd32_clock_gettime_args /* { 438 syscallarg(netbsd32_clockid_t) clock_id; 439 syscallarg(netbsd32_timespecp_t) tp; 440 } */ *uap = v; 441 clockid_t clock_id; 442 struct timespec ats; 443 struct netbsd32_timespec ts32; 444 445 clock_id = SCARG(uap, clock_id); 446 if (clock_id != CLOCK_REALTIME) 447 return (EINVAL); 448 449 nanotime(&ats); 450 netbsd32_from_timespec(&ats, &ts32); 451 452 return copyout(&ts32, (caddr_t)NETBSD32PTR64(SCARG(uap, tp)), 453 sizeof(ts32)); 454 } 455 456 int 457 netbsd32_clock_settime(l, v, retval) 458 struct lwp *l; 459 void *v; 460 register_t *retval; 461 { 462 struct netbsd32_clock_settime_args /* { 463 syscallarg(netbsd32_clockid_t) clock_id; 464 syscallarg(const netbsd32_timespecp_t) tp; 465 } */ *uap = v; 466 struct netbsd32_timespec ts32; 467 clockid_t clock_id; 468 struct timespec ats; 469 int error; 470 struct proc *p = l->l_proc; 471 472 if ((error = kauth_authorize_generic(p->p_cred, KAUTH_GENERIC_ISSUSER, &p->p_acflag)) != 0) 473 return (error); 474 475 clock_id = SCARG(uap, clock_id); 476 if (clock_id != CLOCK_REALTIME) 477 return (EINVAL); 478 479 if ((error = copyin((caddr_t)NETBSD32PTR64(SCARG(uap, tp)), &ts32, 480 sizeof(ts32))) != 0) 481 return (error); 482 483 netbsd32_to_timespec(&ts32, &ats); 484 return settime(p, &ats); 485 } 486 487 int 488 netbsd32_clock_getres(l, v, retval) 489 struct lwp *l; 490 void *v; 491 register_t *retval; 492 { 493 struct netbsd32_clock_getres_args /* { 494 syscallarg(netbsd32_clockid_t) clock_id; 495 syscallarg(netbsd32_timespecp_t) tp; 496 } */ *uap = v; 497 struct netbsd32_timespec ts32; 498 clockid_t clock_id; 499 struct timespec ts; 500 int error = 0; 501 502 clock_id = SCARG(uap, clock_id); 503 if (clock_id != CLOCK_REALTIME) 504 return (EINVAL); 505 506 if (SCARG(uap, tp)) { 507 ts.tv_sec = 0; 508 ts.tv_nsec = 1000000000 / hz; 509 510 netbsd32_from_timespec(&ts, &ts32); 511 error = copyout(&ts, (caddr_t)NETBSD32PTR64(SCARG(uap, tp)), 512 sizeof(ts)); 513 } 514 515 return error; 516 } 517 518 int 519 netbsd32_nanosleep(l, v, retval) 520 struct lwp *l; 521 void *v; 522 register_t *retval; 523 { 524 struct netbsd32_nanosleep_args /* { 525 syscallarg(const netbsd32_timespecp_t) rqtp; 526 syscallarg(netbsd32_timespecp_t) rmtp; 527 } */ *uap = v; 528 static int nanowait; 529 struct netbsd32_timespec ts32; 530 struct timespec rqt; 531 struct timespec rmt; 532 struct timeval atv, utv, ctime; 533 int error, timo; 534 535 error = copyin((caddr_t)NETBSD32PTR64(SCARG(uap, rqtp)), (caddr_t)&ts32, 536 sizeof(ts32)); 537 if (error) 538 return (error); 539 540 netbsd32_to_timespec(&ts32, &rqt); 541 TIMESPEC_TO_TIMEVAL(&atv,&rqt); 542 if (itimerfix(&atv)) 543 return (EINVAL); 544 545 getmicrotime(&ctime); 546 timeradd(&atv,&ctime,&atv); 547 timo = hzto(&atv); 548 /* 549 * Avoid inadvertantly sleeping forever 550 */ 551 if (timo == 0) 552 timo = 1; 553 554 error = tsleep(&nanowait, PWAIT | PCATCH, "nanosleep", timo); 555 if (error == ERESTART) 556 error = EINTR; 557 if (error == EWOULDBLOCK) 558 error = 0; 559 560 if (SCARG(uap, rmtp)) { 561 int error1; 562 563 getmicrotime(&utv); 564 565 timersub(&atv, &utv, &utv); 566 if (utv.tv_sec < 0) 567 timerclear(&utv); 568 569 TIMEVAL_TO_TIMESPEC(&utv,&rmt); 570 netbsd32_from_timespec(&rmt, &ts32); 571 error1 = copyout(&ts32, 572 NETBSD32PTR64(SCARG(uap,rmtp)), sizeof(ts32)); 573 if (error1) 574 return (error1); 575 } 576 577 return error; 578 } 579 580 static int 581 netbsd32_timer_create_fetch(const void *src, void *dst, size_t size) 582 { 583 struct sigevent *evp = dst; 584 struct netbsd32_sigevent ev32; 585 int error; 586 587 error = copyin(src, &ev32, sizeof(ev32)); 588 if (error) 589 return error; 590 591 netbsd32_to_sigevent(&ev32, evp); 592 return 0; 593 } 594 595 int 596 netbsd32_timer_create(struct lwp *l, void *v, register_t *retval) 597 { 598 struct netbsd32_timer_create_args /* { 599 syscallarg(netbsd32_clockid_t) clock_id; 600 syscallarg(netbsd32_sigeventp_t) evp; 601 syscallarg(netbsd32_timerp_t) timerid; 602 } */ *uap = v; 603 604 return timer_create1(NETBSD32PTR64(SCARG(uap, timerid)), 605 SCARG(uap, clock_id), NETBSD32PTR64(SCARG(uap, evp)), 606 netbsd32_timer_create_fetch, l->l_proc); 607 } 608 609 int 610 netbsd32_timer_delete(struct lwp *l, void *v, register_t *retval) 611 { 612 struct netbsd32_timer_delete_args /* { 613 syscallarg(netbsd32_timer_t) timerid; 614 } */ *uap = v; 615 struct sys_timer_delete_args ua; 616 617 NETBSD32TO64_UAP(timerid); 618 return sys_timer_delete(l, (void *)&ua, retval); 619 } 620 621 int 622 netbsd32_timer_settime(struct lwp *l, void *v, register_t *retval) 623 { 624 struct netbsd32_timer_settime_args /* { 625 syscallarg(netbsd32_timer_t) timerid; 626 syscallarg(int) flags; 627 syscallarg(const netbsd32_itimerspecp_t) value; 628 syscallarg(netbsd32_itimerspecp_t) ovalue; 629 } */ *uap = v; 630 int error; 631 struct itimerspec value, ovalue, *ovp = NULL; 632 struct netbsd32_itimerspec its32; 633 634 if ((error = copyin(NETBSD32PTR64(SCARG(uap, value)), &its32, 635 sizeof(its32))) != 0) 636 return (error); 637 netbsd32_to_timespec(&its32.it_interval, &value.it_interval); 638 netbsd32_to_timespec(&its32.it_value, &value.it_value); 639 640 if (SCARG(uap, ovalue)) 641 ovp = &ovalue; 642 643 if ((error = dotimer_settime(SCARG(uap, timerid), &value, ovp, 644 SCARG(uap, flags), l->l_proc)) != 0) 645 return error; 646 647 if (ovp) { 648 netbsd32_from_timespec(&ovp->it_interval, &its32.it_interval); 649 netbsd32_from_timespec(&ovp->it_value, &its32.it_value); 650 return copyout(&its32, NETBSD32PTR64(SCARG(uap, ovalue)), 651 sizeof(its32)); 652 } 653 return 0; 654 } 655 656 int 657 netbsd32_timer_gettime(struct lwp *l, void *v, register_t *retval) 658 { 659 struct netbsd32_timer_gettime_args /* { 660 syscallarg(netbsd32_timer_t) timerid; 661 syscallarg(netbsd32_itimerspecp_t) value; 662 } */ *uap = v; 663 int error; 664 struct itimerspec its; 665 struct netbsd32_itimerspec its32; 666 667 if ((error = dotimer_gettime(SCARG(uap, timerid), l->l_proc, 668 &its)) != 0) 669 return error; 670 671 netbsd32_from_timespec(&its.it_interval, &its32.it_interval); 672 netbsd32_from_timespec(&its.it_value, &its32.it_value); 673 674 return copyout(&its32, (caddr_t)NETBSD32PTR64(SCARG(uap, value)), 675 sizeof(its32)); 676 } 677 678 int 679 netbsd32_timer_getoverrun(struct lwp *l, void *v, register_t *retval) 680 { 681 struct netbsd32_timer_getoverrun_args /* { 682 syscallarg(netbsd32_timer_t) timerid; 683 } */ *uap = v; 684 struct sys_timer_getoverrun_args ua; 685 686 NETBSD32TO64_UAP(timerid); 687 return sys_timer_getoverrun(l, (void *)&ua, retval); 688 } 689