1 /* $NetBSD: netbsd32_time.c,v 1.24 2006/11/14 13:34:30 elad 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.24 2006/11/14 13:34:30 elad 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 136 if ((error = copyin((caddr_t)NETBSD32PTR64(SCARG(uap, tp)), 137 (caddr_t)&ntv32, sizeof(ntv32)))) 138 return (error); 139 140 netbsd32_to_timex(&ntv32, &ntv); 141 142 /* 143 * Update selected clock variables - only the superuser can 144 * change anything. Note that there is no error checking here on 145 * the assumption the superuser should know what it is doing. 146 */ 147 modes = ntv.modes; 148 if (modes != 0 && (error = kauth_authorize_system(l->l_cred, 149 KAUTH_SYSTEM_TIME, KAUTH_REQ_SYSTEM_TIME_NTPADJTIME, NULL, NULL, 150 NULL))) 151 return (error); 152 153 ntp_adjtime1(&ntv); 154 155 netbsd32_from_timex(&ntv, &ntv32); 156 error = copyout((caddr_t)&ntv32, (caddr_t)NETBSD32PTR64(SCARG(uap, tp)), 157 sizeof(ntv32)); 158 if (!error) { 159 *retval = ntp_timestatus(); 160 } 161 return error; 162 } 163 #else /* !NTP */ 164 int 165 netbsd32_ntp_gettime(l, v, retval) 166 struct lwp *l; 167 void *v; 168 register_t *retval; 169 { 170 171 return (ENOSYS); 172 } 173 174 #ifdef COMPAT_30 175 int 176 compat_30_netbsd32_ntp_gettime(l, v, retval) 177 struct lwp *l; 178 void *v; 179 register_t *retval; 180 { 181 182 return (ENOSYS); 183 } 184 #endif 185 186 int 187 netbsd32_ntp_adjtime(l, v, retval) 188 struct lwp *l; 189 void *v; 190 register_t *retval; 191 { 192 193 return (ENOSYS); 194 } 195 #endif /* NTP */ 196 197 int 198 netbsd32_setitimer(l, v, retval) 199 struct lwp *l; 200 void *v; 201 register_t *retval; 202 { 203 struct netbsd32_setitimer_args /* { 204 syscallarg(int) which; 205 syscallarg(const netbsd32_itimervalp_t) itv; 206 syscallarg(netbsd32_itimervalp_t) oitv; 207 } */ *uap = v; 208 struct proc *p = l->l_proc; 209 struct netbsd32_itimerval s32it, *itv32; 210 int which = SCARG(uap, which); 211 struct netbsd32_getitimer_args getargs; 212 struct itimerval aitv; 213 int error; 214 215 if ((u_int)which > ITIMER_PROF) 216 return (EINVAL); 217 itv32 = (struct netbsd32_itimerval *)NETBSD32PTR64(SCARG(uap, itv)); 218 if (itv32) { 219 if ((error = copyin(itv32, &s32it, sizeof(s32it)))) 220 return (error); 221 netbsd32_to_itimerval(&s32it, &aitv); 222 } 223 if (SCARG(uap, oitv) != 0) { 224 SCARG(&getargs, which) = which; 225 SCARG(&getargs, itv) = SCARG(uap, oitv); 226 if ((error = netbsd32_getitimer(l, &getargs, retval)) != 0) 227 return (error); 228 } 229 if (itv32 == 0) 230 return 0; 231 232 return dosetitimer(p, which, &aitv); 233 } 234 235 int 236 netbsd32_getitimer(l, v, retval) 237 struct lwp *l; 238 void *v; 239 register_t *retval; 240 { 241 struct netbsd32_getitimer_args /* { 242 syscallarg(int) which; 243 syscallarg(netbsd32_itimervalp_t) itv; 244 } */ *uap = v; 245 struct proc *p = l->l_proc; 246 struct netbsd32_itimerval s32it; 247 struct itimerval aitv; 248 int error; 249 250 error = dogetitimer(p, SCARG(uap, which), &aitv); 251 if (error) 252 return error; 253 254 netbsd32_from_itimerval(&aitv, &s32it); 255 return (copyout(&s32it, (caddr_t)NETBSD32PTR64(SCARG(uap, itv)), 256 sizeof(s32it))); 257 } 258 259 int 260 netbsd32_gettimeofday(l, v, retval) 261 struct lwp *l; 262 void *v; 263 register_t *retval; 264 { 265 struct netbsd32_gettimeofday_args /* { 266 syscallarg(netbsd32_timevalp_t) tp; 267 syscallarg(netbsd32_timezonep_t) tzp; 268 } */ *uap = v; 269 struct timeval atv; 270 struct netbsd32_timeval tv32; 271 int error = 0; 272 struct netbsd32_timezone tzfake; 273 274 if (SCARG(uap, tp)) { 275 microtime(&atv); 276 netbsd32_from_timeval(&atv, &tv32); 277 error = copyout(&tv32, (caddr_t)NETBSD32PTR64(SCARG(uap, tp)), 278 sizeof(tv32)); 279 if (error) 280 return (error); 281 } 282 if (SCARG(uap, tzp)) { 283 /* 284 * NetBSD has no kernel notion of time zone, so we just 285 * fake up a timezone struct and return it if demanded. 286 */ 287 tzfake.tz_minuteswest = 0; 288 tzfake.tz_dsttime = 0; 289 error = copyout(&tzfake, 290 (caddr_t)NETBSD32PTR64(SCARG(uap, tzp)), sizeof(tzfake)); 291 } 292 return (error); 293 } 294 295 int 296 netbsd32_settimeofday(l, v, retval) 297 struct lwp *l; 298 void *v; 299 register_t *retval; 300 { 301 struct netbsd32_settimeofday_args /* { 302 syscallarg(const netbsd32_timevalp_t) tv; 303 syscallarg(const netbsd32_timezonep_t) tzp; 304 } */ *uap = v; 305 struct netbsd32_timeval atv32; 306 struct timeval atv; 307 struct timespec ats; 308 int error; 309 struct proc *p = l->l_proc; 310 311 /* Verify all parameters before changing time. */ 312 if ((error = kauth_authorize_system(l->l_cred, 313 KAUTH_SYSTEM_TIME, KAUTH_REQ_SYSTEM_TIME_SYSTEM, NULL, NULL, 314 NULL)) != 0) 315 return error; 316 317 /* 318 * NetBSD has no kernel notion of time zone, and only an 319 * obsolete program would try to set it, so we log a warning. 320 */ 321 if (SCARG(uap, tzp)) 322 printf("pid %d attempted to set the " 323 "(obsolete) kernel time zone\n", p->p_pid); 324 325 if (SCARG(uap, tv) == 0) 326 return 0; 327 328 if ((error = copyin((caddr_t)NETBSD32PTR64(SCARG(uap, tv)), &atv32, 329 sizeof(atv32))) != 0) 330 return error; 331 332 netbsd32_to_timeval(&atv32, &atv); 333 TIMEVAL_TO_TIMESPEC(&atv, &ats); 334 return settime(p, &ats); 335 } 336 337 int 338 netbsd32_adjtime(l, v, retval) 339 struct lwp *l; 340 void *v; 341 register_t *retval; 342 { 343 struct netbsd32_adjtime_args /* { 344 syscallarg(const netbsd32_timevalp_t) delta; 345 syscallarg(netbsd32_timevalp_t) olddelta; 346 } */ *uap = v; 347 struct netbsd32_timeval atv; 348 int error; 349 350 if ((error = kauth_authorize_system(l->l_cred, 351 KAUTH_SYSTEM_TIME, KAUTH_REQ_SYSTEM_TIME_ADJTIME, NULL, NULL, 352 NULL)) != 0) 353 return (error); 354 355 #ifdef __HAVE_TIMECOUNTER 356 { 357 extern int time_adjusted; /* in kern_ntptime.c */ 358 extern int64_t time_adjtime; /* in kern_ntptime.c */ 359 if (SCARG(uap, olddelta)) { 360 atv.tv_sec = time_adjtime / 1000000; 361 atv.tv_usec = time_adjtime % 1000000; 362 if (atv.tv_usec < 0) { 363 atv.tv_usec += 1000000; 364 atv.tv_sec--; 365 } 366 (void) copyout(&atv, 367 (caddr_t)NETBSD32PTR64(SCARG(uap, olddelta)), 368 sizeof(atv)); 369 if (error) 370 return (error); 371 } 372 373 if (SCARG(uap, delta)) { 374 error = copyin((caddr_t)NETBSD32PTR64(SCARG(uap, delta)), &atv, 375 sizeof(struct timeval)); 376 if (error) 377 return (error); 378 379 time_adjtime = (int64_t)atv.tv_sec * 1000000 + 380 atv.tv_usec; 381 382 if (time_adjtime) 383 /* We need to save the system time during shutdown */ 384 time_adjusted |= 1; 385 } 386 } 387 #else /* !__HAVE_TIMECOUNTER */ 388 { 389 int32_t ndelta, ntickdelta, odelta; 390 extern long bigadj, timedelta; 391 extern int tickdelta; 392 int s; 393 error = copyin((caddr_t)NETBSD32PTR64(SCARG(uap, delta)), &atv, 394 sizeof(struct timeval)); 395 if (error) 396 return (error); 397 /* 398 * Compute the total correction and the rate at which to apply it. 399 * Round the adjustment down to a whole multiple of the per-tick 400 * delta, so that after some number of incremental changes in 401 * hardclock(), tickdelta will become zero, lest the correction 402 * overshoot and start taking us away from the desired final time. 403 */ 404 ndelta = atv.tv_sec * 1000000 + atv.tv_usec; 405 if (ndelta > bigadj) 406 ntickdelta = 10 * tickadj; 407 else 408 ntickdelta = tickadj; 409 if (ndelta % ntickdelta) 410 ndelta = ndelta / ntickdelta * ntickdelta; 411 412 /* 413 * To make hardclock()'s job easier, make the per-tick delta negative 414 * if we want time to run slower; then hardclock can simply compute 415 * tick + tickdelta, and subtract tickdelta from timedelta. 416 */ 417 if (ndelta < 0) 418 ntickdelta = -ntickdelta; 419 s = splclock(); 420 odelta = timedelta; 421 timedelta = ndelta; 422 tickdelta = ntickdelta; 423 splx(s); 424 425 if (SCARG(uap, olddelta)) { 426 atv.tv_sec = odelta / 1000000; 427 atv.tv_usec = odelta % 1000000; 428 (void) copyout(&atv, 429 (caddr_t)NETBSD32PTR64(SCARG(uap, olddelta)), sizeof(atv)); 430 } 431 } 432 #endif /* !__HAVE_TIMECOUNTER */ 433 return (0); 434 } 435 436 int 437 netbsd32_clock_gettime(l, v, retval) 438 struct lwp *l; 439 void *v; 440 register_t *retval; 441 { 442 struct netbsd32_clock_gettime_args /* { 443 syscallarg(netbsd32_clockid_t) clock_id; 444 syscallarg(netbsd32_timespecp_t) tp; 445 } */ *uap = v; 446 clockid_t clock_id; 447 struct timespec ats; 448 struct netbsd32_timespec ts32; 449 450 clock_id = SCARG(uap, clock_id); 451 if (clock_id != CLOCK_REALTIME) 452 return (EINVAL); 453 454 nanotime(&ats); 455 netbsd32_from_timespec(&ats, &ts32); 456 457 return copyout(&ts32, (caddr_t)NETBSD32PTR64(SCARG(uap, tp)), 458 sizeof(ts32)); 459 } 460 461 int 462 netbsd32_clock_settime(l, v, retval) 463 struct lwp *l; 464 void *v; 465 register_t *retval; 466 { 467 struct netbsd32_clock_settime_args /* { 468 syscallarg(netbsd32_clockid_t) clock_id; 469 syscallarg(const netbsd32_timespecp_t) tp; 470 } */ *uap = v; 471 struct netbsd32_timespec ts32; 472 clockid_t clock_id; 473 struct timespec ats; 474 int error; 475 476 if ((error = kauth_authorize_system(l->l_cred, 477 KAUTH_SYSTEM_TIME, KAUTH_REQ_SYSTEM_TIME_SYSTEM, NULL, NULL, 478 NULL)) != 0) 479 return (error); 480 481 clock_id = SCARG(uap, clock_id); 482 if (clock_id != CLOCK_REALTIME) 483 return (EINVAL); 484 485 if ((error = copyin((caddr_t)NETBSD32PTR64(SCARG(uap, tp)), &ts32, 486 sizeof(ts32))) != 0) 487 return (error); 488 489 netbsd32_to_timespec(&ts32, &ats); 490 return settime(l->l_proc, &ats); 491 } 492 493 int 494 netbsd32_clock_getres(l, v, retval) 495 struct lwp *l; 496 void *v; 497 register_t *retval; 498 { 499 struct netbsd32_clock_getres_args /* { 500 syscallarg(netbsd32_clockid_t) clock_id; 501 syscallarg(netbsd32_timespecp_t) tp; 502 } */ *uap = v; 503 struct netbsd32_timespec ts32; 504 clockid_t clock_id; 505 struct timespec ts; 506 int error = 0; 507 508 clock_id = SCARG(uap, clock_id); 509 if (clock_id != CLOCK_REALTIME) 510 return (EINVAL); 511 512 if (SCARG(uap, tp)) { 513 ts.tv_sec = 0; 514 ts.tv_nsec = 1000000000 / hz; 515 516 netbsd32_from_timespec(&ts, &ts32); 517 error = copyout(&ts, (caddr_t)NETBSD32PTR64(SCARG(uap, tp)), 518 sizeof(ts)); 519 } 520 521 return error; 522 } 523 524 int 525 netbsd32_nanosleep(l, v, retval) 526 struct lwp *l; 527 void *v; 528 register_t *retval; 529 { 530 struct netbsd32_nanosleep_args /* { 531 syscallarg(const netbsd32_timespecp_t) rqtp; 532 syscallarg(netbsd32_timespecp_t) rmtp; 533 } */ *uap = v; 534 static int nanowait; 535 struct netbsd32_timespec ts32; 536 struct timespec rqt; 537 struct timespec rmt; 538 struct timeval atv, utv, ctime; 539 int error, timo; 540 541 error = copyin((caddr_t)NETBSD32PTR64(SCARG(uap, rqtp)), (caddr_t)&ts32, 542 sizeof(ts32)); 543 if (error) 544 return (error); 545 546 netbsd32_to_timespec(&ts32, &rqt); 547 TIMESPEC_TO_TIMEVAL(&atv,&rqt); 548 if (itimerfix(&atv)) 549 return (EINVAL); 550 551 getmicrotime(&ctime); 552 timeradd(&atv,&ctime,&atv); 553 timo = hzto(&atv); 554 /* 555 * Avoid inadvertantly sleeping forever 556 */ 557 if (timo == 0) 558 timo = 1; 559 560 error = tsleep(&nanowait, PWAIT | PCATCH, "nanosleep", timo); 561 if (error == ERESTART) 562 error = EINTR; 563 if (error == EWOULDBLOCK) 564 error = 0; 565 566 if (SCARG(uap, rmtp)) { 567 int error1; 568 569 getmicrotime(&utv); 570 571 timersub(&atv, &utv, &utv); 572 if (utv.tv_sec < 0) 573 timerclear(&utv); 574 575 TIMEVAL_TO_TIMESPEC(&utv,&rmt); 576 netbsd32_from_timespec(&rmt, &ts32); 577 error1 = copyout(&ts32, 578 NETBSD32PTR64(SCARG(uap,rmtp)), sizeof(ts32)); 579 if (error1) 580 return (error1); 581 } 582 583 return error; 584 } 585 586 static int 587 netbsd32_timer_create_fetch(const void *src, void *dst, size_t size) 588 { 589 struct sigevent *evp = dst; 590 struct netbsd32_sigevent ev32; 591 int error; 592 593 error = copyin(src, &ev32, sizeof(ev32)); 594 if (error) 595 return error; 596 597 netbsd32_to_sigevent(&ev32, evp); 598 return 0; 599 } 600 601 int 602 netbsd32_timer_create(struct lwp *l, void *v, register_t *retval) 603 { 604 struct netbsd32_timer_create_args /* { 605 syscallarg(netbsd32_clockid_t) clock_id; 606 syscallarg(netbsd32_sigeventp_t) evp; 607 syscallarg(netbsd32_timerp_t) timerid; 608 } */ *uap = v; 609 610 return timer_create1(NETBSD32PTR64(SCARG(uap, timerid)), 611 SCARG(uap, clock_id), NETBSD32PTR64(SCARG(uap, evp)), 612 netbsd32_timer_create_fetch, l); 613 } 614 615 int 616 netbsd32_timer_delete(struct lwp *l, void *v, register_t *retval) 617 { 618 struct netbsd32_timer_delete_args /* { 619 syscallarg(netbsd32_timer_t) timerid; 620 } */ *uap = v; 621 struct sys_timer_delete_args ua; 622 623 NETBSD32TO64_UAP(timerid); 624 return sys_timer_delete(l, (void *)&ua, retval); 625 } 626 627 int 628 netbsd32_timer_settime(struct lwp *l, void *v, register_t *retval) 629 { 630 struct netbsd32_timer_settime_args /* { 631 syscallarg(netbsd32_timer_t) timerid; 632 syscallarg(int) flags; 633 syscallarg(const netbsd32_itimerspecp_t) value; 634 syscallarg(netbsd32_itimerspecp_t) ovalue; 635 } */ *uap = v; 636 int error; 637 struct itimerspec value, ovalue, *ovp = NULL; 638 struct netbsd32_itimerspec its32; 639 640 if ((error = copyin(NETBSD32PTR64(SCARG(uap, value)), &its32, 641 sizeof(its32))) != 0) 642 return (error); 643 netbsd32_to_timespec(&its32.it_interval, &value.it_interval); 644 netbsd32_to_timespec(&its32.it_value, &value.it_value); 645 646 if (SCARG(uap, ovalue)) 647 ovp = &ovalue; 648 649 if ((error = dotimer_settime(SCARG(uap, timerid), &value, ovp, 650 SCARG(uap, flags), l->l_proc)) != 0) 651 return error; 652 653 if (ovp) { 654 netbsd32_from_timespec(&ovp->it_interval, &its32.it_interval); 655 netbsd32_from_timespec(&ovp->it_value, &its32.it_value); 656 return copyout(&its32, NETBSD32PTR64(SCARG(uap, ovalue)), 657 sizeof(its32)); 658 } 659 return 0; 660 } 661 662 int 663 netbsd32_timer_gettime(struct lwp *l, void *v, register_t *retval) 664 { 665 struct netbsd32_timer_gettime_args /* { 666 syscallarg(netbsd32_timer_t) timerid; 667 syscallarg(netbsd32_itimerspecp_t) value; 668 } */ *uap = v; 669 int error; 670 struct itimerspec its; 671 struct netbsd32_itimerspec its32; 672 673 if ((error = dotimer_gettime(SCARG(uap, timerid), l->l_proc, 674 &its)) != 0) 675 return error; 676 677 netbsd32_from_timespec(&its.it_interval, &its32.it_interval); 678 netbsd32_from_timespec(&its.it_value, &its32.it_value); 679 680 return copyout(&its32, (caddr_t)NETBSD32PTR64(SCARG(uap, value)), 681 sizeof(its32)); 682 } 683 684 int 685 netbsd32_timer_getoverrun(struct lwp *l, void *v, register_t *retval) 686 { 687 struct netbsd32_timer_getoverrun_args /* { 688 syscallarg(netbsd32_timer_t) timerid; 689 } */ *uap = v; 690 struct sys_timer_getoverrun_args ua; 691 692 NETBSD32TO64_UAP(timerid); 693 return sys_timer_getoverrun(l, (void *)&ua, retval); 694 } 695