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