linux_time.c revision 283463
1/* $NetBSD: linux_time.c,v 1.14 2006/05/14 03:40:54 christos Exp $ */ 2 3/*- 4 * Copyright (c) 2001 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Emmanuel Dreyfus. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 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 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 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 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 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32#include <sys/cdefs.h> 33__FBSDID("$FreeBSD: head/sys/compat/linux/linux_time.c 283463 2015-05-24 17:29:18Z dchagin $"); 34#if 0 35__KERNEL_RCSID(0, "$NetBSD: linux_time.c,v 1.14 2006/05/14 03:40:54 christos Exp $"); 36#endif 37 38#include "opt_compat.h" 39 40#include <sys/param.h> 41#include <sys/kernel.h> 42#include <sys/lock.h> 43#include <sys/ucred.h> 44#include <sys/mount.h> 45#include <sys/mutex.h> 46#include <sys/resourcevar.h> 47#include <sys/sdt.h> 48#include <sys/signal.h> 49#include <sys/stdint.h> 50#include <sys/syscallsubr.h> 51#include <sys/sysproto.h> 52#include <sys/time.h> 53#include <sys/systm.h> 54#include <sys/proc.h> 55 56#ifdef COMPAT_LINUX32 57#include <machine/../linux32/linux.h> 58#include <machine/../linux32/linux32_proto.h> 59#else 60#include <machine/../linux/linux.h> 61#include <machine/../linux/linux_proto.h> 62#endif 63 64#include <compat/linux/linux_dtrace.h> 65#include <compat/linux/linux_timer.h> 66 67/* DTrace init */ 68LIN_SDT_PROVIDER_DECLARE(LINUX_DTRACE); 69 70/** 71 * DTrace probes in this module. 72 */ 73LIN_SDT_PROBE_DEFINE2(time, native_to_linux_timespec, entry, 74 "struct l_timespec *", "struct timespec *"); 75LIN_SDT_PROBE_DEFINE0(time, native_to_linux_timespec, return); 76LIN_SDT_PROBE_DEFINE2(time, linux_to_native_timespec, entry, 77 "struct timespec *", "struct l_timespec *"); 78LIN_SDT_PROBE_DEFINE1(time, linux_to_native_timespec, return, "int"); 79LIN_SDT_PROBE_DEFINE2(time, linux_to_native_clockid, entry, "clockid_t *", 80 "clockid_t"); 81LIN_SDT_PROBE_DEFINE1(time, linux_to_native_clockid, unsupported_clockid, 82 "clockid_t"); 83LIN_SDT_PROBE_DEFINE1(time, linux_to_native_clockid, unknown_clockid, 84 "clockid_t"); 85LIN_SDT_PROBE_DEFINE1(time, linux_to_native_clockid, return, "int"); 86LIN_SDT_PROBE_DEFINE2(time, linux_clock_gettime, entry, "clockid_t", 87 "struct l_timespec *"); 88LIN_SDT_PROBE_DEFINE1(time, linux_clock_gettime, conversion_error, "int"); 89LIN_SDT_PROBE_DEFINE1(time, linux_clock_gettime, gettime_error, "int"); 90LIN_SDT_PROBE_DEFINE1(time, linux_clock_gettime, copyout_error, "int"); 91LIN_SDT_PROBE_DEFINE1(time, linux_clock_gettime, return, "int"); 92LIN_SDT_PROBE_DEFINE2(time, linux_clock_settime, entry, "clockid_t", 93 "struct l_timespec *"); 94LIN_SDT_PROBE_DEFINE1(time, linux_clock_settime, conversion_error, "int"); 95LIN_SDT_PROBE_DEFINE1(time, linux_clock_settime, settime_error, "int"); 96LIN_SDT_PROBE_DEFINE1(time, linux_clock_settime, copyin_error, "int"); 97LIN_SDT_PROBE_DEFINE1(time, linux_clock_settime, return, "int"); 98LIN_SDT_PROBE_DEFINE2(time, linux_clock_getres, entry, "clockid_t", 99 "struct l_timespec *"); 100LIN_SDT_PROBE_DEFINE0(time, linux_clock_getres, nullcall); 101LIN_SDT_PROBE_DEFINE1(time, linux_clock_getres, conversion_error, "int"); 102LIN_SDT_PROBE_DEFINE1(time, linux_clock_getres, getres_error, "int"); 103LIN_SDT_PROBE_DEFINE1(time, linux_clock_getres, copyout_error, "int"); 104LIN_SDT_PROBE_DEFINE1(time, linux_clock_getres, return, "int"); 105LIN_SDT_PROBE_DEFINE2(time, linux_nanosleep, entry, "const struct l_timespec *", 106 "struct l_timespec *"); 107LIN_SDT_PROBE_DEFINE1(time, linux_nanosleep, conversion_error, "int"); 108LIN_SDT_PROBE_DEFINE1(time, linux_nanosleep, nanosleep_error, "int"); 109LIN_SDT_PROBE_DEFINE1(time, linux_nanosleep, copyout_error, "int"); 110LIN_SDT_PROBE_DEFINE1(time, linux_nanosleep, copyin_error, "int"); 111LIN_SDT_PROBE_DEFINE1(time, linux_nanosleep, return, "int"); 112LIN_SDT_PROBE_DEFINE4(time, linux_clock_nanosleep, entry, "clockid_t", "int", 113 "struct l_timespec *", "struct l_timespec *"); 114LIN_SDT_PROBE_DEFINE1(time, linux_clock_nanosleep, conversion_error, "int"); 115LIN_SDT_PROBE_DEFINE1(time, linux_clock_nanosleep, nanosleep_error, "int"); 116LIN_SDT_PROBE_DEFINE1(time, linux_clock_nanosleep, copyout_error, "int"); 117LIN_SDT_PROBE_DEFINE1(time, linux_clock_nanosleep, copyin_error, "int"); 118LIN_SDT_PROBE_DEFINE1(time, linux_clock_nanosleep, unsupported_flags, "int"); 119LIN_SDT_PROBE_DEFINE1(time, linux_clock_nanosleep, unsupported_clockid, "int"); 120LIN_SDT_PROBE_DEFINE1(time, linux_clock_nanosleep, return, "int"); 121 122static int linux_to_native_clockid(clockid_t *, clockid_t); 123 124 125void 126native_to_linux_timespec(struct l_timespec *ltp, struct timespec *ntp) 127{ 128 129 LIN_SDT_PROBE2(time, native_to_linux_timespec, entry, ltp, ntp); 130 131 ltp->tv_sec = ntp->tv_sec; 132 ltp->tv_nsec = ntp->tv_nsec; 133 134 LIN_SDT_PROBE0(time, native_to_linux_timespec, return); 135} 136 137int 138linux_to_native_timespec(struct timespec *ntp, struct l_timespec *ltp) 139{ 140 141 LIN_SDT_PROBE2(time, linux_to_native_timespec, entry, ntp, ltp); 142 143 if (ltp->tv_sec < 0 || ltp->tv_nsec > (l_long)999999999L) { 144 LIN_SDT_PROBE1(time, linux_to_native_timespec, return, EINVAL); 145 return (EINVAL); 146 } 147 ntp->tv_sec = ltp->tv_sec; 148 ntp->tv_nsec = ltp->tv_nsec; 149 150 LIN_SDT_PROBE1(time, linux_to_native_timespec, return, 0); 151 return (0); 152} 153 154static int 155linux_to_native_clockid(clockid_t *n, clockid_t l) 156{ 157 158 LIN_SDT_PROBE2(time, linux_to_native_clockid, entry, n, l); 159 160 if (l < 0) { 161 /* cpu-clock */ 162 if ((l & LINUX_CLOCKFD_MASK) == LINUX_CLOCKFD) 163 return (EINVAL); 164 if (LINUX_CPUCLOCK_WHICH(l) >= LINUX_CPUCLOCK_MAX) 165 return (EINVAL); 166 167 if (LINUX_CPUCLOCK_PERTHREAD(l)) 168 *n = CLOCK_THREAD_CPUTIME_ID; 169 else 170 *n = CLOCK_PROCESS_CPUTIME_ID; 171 return (0); 172 } 173 174 switch (l) { 175 case LINUX_CLOCK_REALTIME: 176 *n = CLOCK_REALTIME; 177 break; 178 case LINUX_CLOCK_MONOTONIC: 179 *n = CLOCK_MONOTONIC; 180 break; 181 case LINUX_CLOCK_REALTIME_COARSE: 182 *n = CLOCK_REALTIME_FAST; 183 break; 184 case LINUX_CLOCK_MONOTONIC_COARSE: 185 *n = CLOCK_MONOTONIC_FAST; 186 break; 187 case LINUX_CLOCK_MONOTONIC_RAW: 188 case LINUX_CLOCK_BOOTTIME: 189 case LINUX_CLOCK_REALTIME_ALARM: 190 case LINUX_CLOCK_BOOTTIME_ALARM: 191 case LINUX_CLOCK_SGI_CYCLE: 192 case LINUX_CLOCK_TAI: 193 LIN_SDT_PROBE1(time, linux_to_native_clockid, 194 unsupported_clockid, l); 195 LIN_SDT_PROBE1(time, linux_to_native_clockid, return, EINVAL); 196 return (EINVAL); 197 default: 198 LIN_SDT_PROBE1(time, linux_to_native_clockid, 199 unknown_clockid, l); 200 LIN_SDT_PROBE1(time, linux_to_native_clockid, return, EINVAL); 201 return (EINVAL); 202 } 203 204 LIN_SDT_PROBE1(time, linux_to_native_clockid, return, 0); 205 return (0); 206} 207 208int 209linux_clock_gettime(struct thread *td, struct linux_clock_gettime_args *args) 210{ 211 struct l_timespec lts; 212 struct timespec tp; 213 struct rusage ru; 214 struct thread *targettd; 215 struct proc *p; 216 int error, clockwhich; 217 clockid_t nwhich = 0; /* XXX: GCC */ 218 pid_t pid; 219 lwpid_t tid; 220 221 LIN_SDT_PROBE2(time, linux_clock_gettime, entry, args->which, args->tp); 222 223 error = linux_to_native_clockid(&nwhich, args->which); 224 if (error != 0) { 225 LIN_SDT_PROBE1(time, linux_clock_gettime, conversion_error, 226 error); 227 LIN_SDT_PROBE1(time, linux_clock_gettime, return, error); 228 return (error); 229 } 230 231 switch (nwhich) { 232 case CLOCK_PROCESS_CPUTIME_ID: 233 clockwhich = LINUX_CPUCLOCK_WHICH(args->which); 234 pid = LINUX_CPUCLOCK_ID(args->which); 235 if (pid == 0) { 236 p = td->td_proc; 237 PROC_LOCK(p); 238 } else { 239 error = pget(pid, PGET_CANSEE, &p); 240 if (error != 0) 241 return (EINVAL); 242 } 243 switch (clockwhich) { 244 case LINUX_CPUCLOCK_PROF: 245 PROC_STATLOCK(p); 246 calcru(p, &ru.ru_utime, &ru.ru_stime); 247 PROC_STATUNLOCK(p); 248 PROC_UNLOCK(p); 249 timevaladd(&ru.ru_utime, &ru.ru_stime); 250 TIMEVAL_TO_TIMESPEC(&ru.ru_utime, &tp); 251 break; 252 case LINUX_CPUCLOCK_VIRT: 253 PROC_STATLOCK(p); 254 calcru(p, &ru.ru_utime, &ru.ru_stime); 255 PROC_STATUNLOCK(p); 256 PROC_UNLOCK(p); 257 TIMEVAL_TO_TIMESPEC(&ru.ru_utime, &tp); 258 break; 259 case LINUX_CPUCLOCK_SCHED: 260 PROC_UNLOCK(p); 261 error = kern_clock_getcpuclockid2(td, pid, 262 CPUCLOCK_WHICH_PID, &nwhich); 263 if (error != 0) 264 return (EINVAL); 265 error = kern_clock_gettime(td, nwhich, &tp); 266 break; 267 default: 268 PROC_UNLOCK(p); 269 return (EINVAL); 270 } 271 272 break; 273 274 case CLOCK_THREAD_CPUTIME_ID: 275 clockwhich = LINUX_CPUCLOCK_WHICH(args->which); 276 p = td->td_proc; 277 tid = LINUX_CPUCLOCK_ID(args->which); 278 if (tid == 0) { 279 targettd = td; 280 PROC_LOCK(p); 281 } else { 282 targettd = tdfind(tid, p->p_pid); 283 if (targettd == NULL) 284 return (EINVAL); 285 } 286 switch (clockwhich) { 287 case LINUX_CPUCLOCK_PROF: 288 PROC_STATLOCK(p); 289 thread_lock(targettd); 290 rufetchtd(targettd, &ru); 291 thread_unlock(targettd); 292 PROC_STATUNLOCK(p); 293 PROC_UNLOCK(p); 294 timevaladd(&ru.ru_utime, &ru.ru_stime); 295 TIMEVAL_TO_TIMESPEC(&ru.ru_utime, &tp); 296 break; 297 case LINUX_CPUCLOCK_VIRT: 298 PROC_STATLOCK(p); 299 thread_lock(targettd); 300 rufetchtd(targettd, &ru); 301 thread_unlock(targettd); 302 PROC_STATUNLOCK(p); 303 PROC_UNLOCK(p); 304 TIMEVAL_TO_TIMESPEC(&ru.ru_utime, &tp); 305 break; 306 case LINUX_CPUCLOCK_SCHED: 307 error = kern_clock_getcpuclockid2(td, tid, 308 CPUCLOCK_WHICH_TID, &nwhich); 309 PROC_UNLOCK(p); 310 if (error != 0) 311 return (EINVAL); 312 error = kern_clock_gettime(td, nwhich, &tp); 313 break; 314 default: 315 PROC_UNLOCK(p); 316 return (EINVAL); 317 } 318 break; 319 320 default: 321 error = kern_clock_gettime(td, nwhich, &tp); 322 break; 323 } 324 if (error != 0) { 325 LIN_SDT_PROBE1(time, linux_clock_gettime, gettime_error, error); 326 LIN_SDT_PROBE1(time, linux_clock_gettime, return, error); 327 return (error); 328 } 329 native_to_linux_timespec(<s, &tp); 330 331 error = copyout(<s, args->tp, sizeof lts); 332 if (error != 0) 333 LIN_SDT_PROBE1(time, linux_clock_gettime, copyout_error, error); 334 335 LIN_SDT_PROBE1(time, linux_clock_gettime, return, error); 336 return (error); 337} 338 339int 340linux_clock_settime(struct thread *td, struct linux_clock_settime_args *args) 341{ 342 struct timespec ts; 343 struct l_timespec lts; 344 int error; 345 clockid_t nwhich = 0; /* XXX: GCC */ 346 347 LIN_SDT_PROBE2(time, linux_clock_settime, entry, args->which, args->tp); 348 349 error = linux_to_native_clockid(&nwhich, args->which); 350 if (error != 0) { 351 LIN_SDT_PROBE1(time, linux_clock_settime, conversion_error, 352 error); 353 LIN_SDT_PROBE1(time, linux_clock_settime, return, error); 354 return (error); 355 } 356 error = copyin(args->tp, <s, sizeof lts); 357 if (error != 0) { 358 LIN_SDT_PROBE1(time, linux_clock_settime, copyin_error, error); 359 LIN_SDT_PROBE1(time, linux_clock_settime, return, error); 360 return (error); 361 } 362 error = linux_to_native_timespec(&ts, <s); 363 if (error != 0) { 364 LIN_SDT_PROBE1(time, linux_clock_settime, conversion_error, 365 error); 366 LIN_SDT_PROBE1(time, linux_clock_settime, return, error); 367 return (error); 368 } 369 370 error = kern_clock_settime(td, nwhich, &ts); 371 if (error != 0) 372 LIN_SDT_PROBE1(time, linux_clock_settime, settime_error, error); 373 374 LIN_SDT_PROBE1(time, linux_clock_settime, return, error); 375 return (error); 376} 377 378int 379linux_clock_getres(struct thread *td, struct linux_clock_getres_args *args) 380{ 381 struct proc *p; 382 struct timespec ts; 383 struct l_timespec lts; 384 int error, clockwhich; 385 clockid_t nwhich = 0; /* XXX: GCC */ 386 pid_t pid; 387 lwpid_t tid; 388 389 LIN_SDT_PROBE2(time, linux_clock_getres, entry, args->which, args->tp); 390 391 error = linux_to_native_clockid(&nwhich, args->which); 392 if (error != 0) { 393 LIN_SDT_PROBE1(time, linux_clock_getres, conversion_error, 394 error); 395 LIN_SDT_PROBE1(time, linux_clock_getres, return, error); 396 return (error); 397 } 398 399 /* 400 * Check user supplied clock id in case of per-process 401 * or thread-specific cpu-time clock. 402 */ 403 switch (nwhich) { 404 case CLOCK_THREAD_CPUTIME_ID: 405 tid = LINUX_CPUCLOCK_ID(args->which); 406 if (tid != 0) { 407 p = td->td_proc; 408 if (tdfind(tid, p->p_pid) == NULL) 409 return (ESRCH); 410 PROC_UNLOCK(p); 411 } 412 break; 413 case CLOCK_PROCESS_CPUTIME_ID: 414 pid = LINUX_CPUCLOCK_ID(args->which); 415 if (pid != 0) { 416 error = pget(pid, PGET_CANSEE, &p); 417 if (error != 0) 418 return (EINVAL); 419 PROC_UNLOCK(p); 420 } 421 break; 422 } 423 424 if (args->tp == NULL) { 425 LIN_SDT_PROBE0(time, linux_clock_getres, nullcall); 426 LIN_SDT_PROBE1(time, linux_clock_getres, return, 0); 427 return (0); 428 } 429 430 switch (nwhich) { 431 case CLOCK_THREAD_CPUTIME_ID: 432 case CLOCK_PROCESS_CPUTIME_ID: 433 clockwhich = LINUX_CPUCLOCK_WHICH(args->which); 434 switch (clockwhich) { 435 case LINUX_CPUCLOCK_PROF: 436 nwhich = CLOCK_PROF; 437 break; 438 case LINUX_CPUCLOCK_VIRT: 439 nwhich = CLOCK_VIRTUAL; 440 break; 441 case LINUX_CPUCLOCK_SCHED: 442 break; 443 default: 444 return (EINVAL); 445 } 446 break; 447 448 default: 449 break; 450 } 451 error = kern_clock_getres(td, nwhich, &ts); 452 if (error != 0) { 453 LIN_SDT_PROBE1(time, linux_clock_getres, getres_error, error); 454 LIN_SDT_PROBE1(time, linux_clock_getres, return, error); 455 return (error); 456 } 457 native_to_linux_timespec(<s, &ts); 458 459 error = copyout(<s, args->tp, sizeof lts); 460 if (error != 0) 461 LIN_SDT_PROBE1(time, linux_clock_getres, copyout_error, error); 462 463 LIN_SDT_PROBE1(time, linux_clock_getres, return, error); 464 return (error); 465} 466 467int 468linux_nanosleep(struct thread *td, struct linux_nanosleep_args *args) 469{ 470 struct timespec *rmtp; 471 struct l_timespec lrqts, lrmts; 472 struct timespec rqts, rmts; 473 int error; 474 475 LIN_SDT_PROBE2(time, linux_nanosleep, entry, args->rqtp, args->rmtp); 476 477 error = copyin(args->rqtp, &lrqts, sizeof lrqts); 478 if (error != 0) { 479 LIN_SDT_PROBE1(time, linux_nanosleep, copyin_error, error); 480 LIN_SDT_PROBE1(time, linux_nanosleep, return, error); 481 return (error); 482 } 483 484 if (args->rmtp != NULL) 485 rmtp = &rmts; 486 else 487 rmtp = NULL; 488 489 error = linux_to_native_timespec(&rqts, &lrqts); 490 if (error != 0) { 491 LIN_SDT_PROBE1(time, linux_nanosleep, conversion_error, error); 492 LIN_SDT_PROBE1(time, linux_nanosleep, return, error); 493 return (error); 494 } 495 error = kern_nanosleep(td, &rqts, rmtp); 496 if (error != 0) { 497 LIN_SDT_PROBE1(time, linux_nanosleep, nanosleep_error, error); 498 LIN_SDT_PROBE1(time, linux_nanosleep, return, error); 499 return (error); 500 } 501 502 if (args->rmtp != NULL) { 503 native_to_linux_timespec(&lrmts, rmtp); 504 error = copyout(&lrmts, args->rmtp, sizeof(lrmts)); 505 if (error != 0) { 506 LIN_SDT_PROBE1(time, linux_nanosleep, copyout_error, 507 error); 508 LIN_SDT_PROBE1(time, linux_nanosleep, return, error); 509 return (error); 510 } 511 } 512 513 LIN_SDT_PROBE1(time, linux_nanosleep, return, 0); 514 return (0); 515} 516 517int 518linux_clock_nanosleep(struct thread *td, struct linux_clock_nanosleep_args *args) 519{ 520 struct timespec *rmtp; 521 struct l_timespec lrqts, lrmts; 522 struct timespec rqts, rmts; 523 int error; 524 525 LIN_SDT_PROBE4(time, linux_clock_nanosleep, entry, args->which, 526 args->flags, args->rqtp, args->rmtp); 527 528 if (args->flags != 0) { 529 /* XXX deal with TIMER_ABSTIME */ 530 LIN_SDT_PROBE1(time, linux_clock_nanosleep, unsupported_flags, 531 args->flags); 532 LIN_SDT_PROBE1(time, linux_clock_nanosleep, return, EINVAL); 533 return (EINVAL); /* XXX deal with TIMER_ABSTIME */ 534 } 535 536 if (args->which != LINUX_CLOCK_REALTIME) { 537 LIN_SDT_PROBE1(time, linux_clock_nanosleep, unsupported_clockid, 538 args->which); 539 LIN_SDT_PROBE1(time, linux_clock_nanosleep, return, EINVAL); 540 return (EINVAL); 541 } 542 543 error = copyin(args->rqtp, &lrqts, sizeof lrqts); 544 if (error != 0) { 545 LIN_SDT_PROBE1(time, linux_clock_nanosleep, copyin_error, 546 error); 547 LIN_SDT_PROBE1(time, linux_clock_nanosleep, return, error); 548 return (error); 549 } 550 551 if (args->rmtp != NULL) 552 rmtp = &rmts; 553 else 554 rmtp = NULL; 555 556 error = linux_to_native_timespec(&rqts, &lrqts); 557 if (error != 0) { 558 LIN_SDT_PROBE1(time, linux_clock_nanosleep, conversion_error, 559 error); 560 LIN_SDT_PROBE1(time, linux_clock_nanosleep, return, error); 561 return (error); 562 } 563 error = kern_nanosleep(td, &rqts, rmtp); 564 if (error != 0) { 565 LIN_SDT_PROBE1(time, linux_clock_nanosleep, nanosleep_error, 566 error); 567 LIN_SDT_PROBE1(time, linux_clock_nanosleep, return, error); 568 return (error); 569 } 570 571 if (args->rmtp != NULL) { 572 native_to_linux_timespec(&lrmts, rmtp); 573 error = copyout(&lrmts, args->rmtp, sizeof lrmts ); 574 if (error != 0) { 575 LIN_SDT_PROBE1(time, linux_clock_nanosleep, 576 copyout_error, error); 577 LIN_SDT_PROBE1(time, linux_nanosleep, return, error); 578 return (error); 579 } 580 } 581 582 LIN_SDT_PROBE1(time, linux_clock_nanosleep, return, 0); 583 return (0); 584} 585