Home | History | Annotate | Line # | Download | only in common
      1  1.40   thorpej /*	$NetBSD: linux32_time.c,v 1.40 2021/09/19 23:51:37 thorpej Exp $ */
      2   1.1      manu 
      3   1.1      manu /*-
      4   1.1      manu  * Copyright (c) 2006 Emmanuel Dreyfus, all rights reserved.
      5   1.1      manu  *
      6   1.1      manu  * Redistribution and use in source and binary forms, with or without
      7   1.1      manu  * modification, are permitted provided that the following conditions
      8   1.1      manu  * are met:
      9   1.1      manu  * 1. Redistributions of source code must retain the above copyright
     10   1.1      manu  *    notice, this list of conditions and the following disclaimer.
     11   1.1      manu  * 2. Redistributions in binary form must reproduce the above copyright
     12   1.1      manu  *    notice, this list of conditions and the following disclaimer in the
     13   1.1      manu  *    documentation and/or other materials provided with the distribution.
     14   1.1      manu  * 3. All advertising materials mentioning features or use of this software
     15   1.1      manu  *    must display the following acknowledgement:
     16   1.1      manu  *	This product includes software developed by Emmanuel Dreyfus
     17   1.1      manu  * 4. The name of the author may not be used to endorse or promote
     18   1.1      manu  *    products derived from this software without specific prior written
     19   1.1      manu  *    permission.
     20   1.1      manu  *
     21   1.1      manu  * THIS SOFTWARE IS PROVIDED BY THE THE AUTHOR AND CONTRIBUTORS ``AS IS''
     22   1.1      manu  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     23   1.1      manu  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     24   1.1      manu  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS
     25   1.1      manu  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     26   1.1      manu  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     27   1.1      manu  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     28   1.1      manu  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     29   1.1      manu  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     30   1.1      manu  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     31   1.1      manu  * POSSIBILITY OF SUCH DAMAGE.
     32   1.1      manu  */
     33   1.1      manu 
     34   1.1      manu #include <sys/cdefs.h>
     35   1.1      manu 
     36  1.40   thorpej __KERNEL_RCSID(0, "$NetBSD: linux32_time.c,v 1.40 2021/09/19 23:51:37 thorpej Exp $");
     37   1.1      manu 
     38   1.1      manu #include <sys/types.h>
     39   1.1      manu #include <sys/param.h>
     40   1.1      manu #include <sys/fstypes.h>
     41   1.1      manu #include <sys/signal.h>
     42   1.1      manu #include <sys/dirent.h>
     43   1.4       skd #include <sys/kauth.h>
     44   1.1      manu #include <sys/kernel.h>
     45   1.1      manu #include <sys/fcntl.h>
     46  1.12       dsl #include <sys/namei.h>
     47   1.1      manu #include <sys/select.h>
     48  1.40   thorpej #include <sys/timerfd.h>
     49   1.1      manu #include <sys/proc.h>
     50  1.13       dsl #include <sys/resourcevar.h>
     51   1.1      manu #include <sys/ucred.h>
     52   1.1      manu #include <sys/swap.h>
     53  1.12       dsl #include <sys/vfs_syscalls.h>
     54   1.1      manu 
     55   1.1      manu #include <machine/types.h>
     56   1.1      manu 
     57   1.1      manu #include <sys/syscallargs.h>
     58   1.1      manu 
     59   1.1      manu #include <compat/netbsd32/netbsd32.h>
     60   1.1      manu #include <compat/netbsd32/netbsd32_conv.h>
     61   1.1      manu #include <compat/netbsd32/netbsd32_syscallargs.h>
     62   1.1      manu 
     63   1.1      manu #include <compat/linux/common/linux_types.h>
     64   1.1      manu #include <compat/linux/common/linux_signal.h>
     65   1.1      manu #include <compat/linux/common/linux_machdep.h>
     66   1.1      manu #include <compat/linux/common/linux_misc.h>
     67   1.1      manu #include <compat/linux/common/linux_oldolduname.h>
     68  1.18     njoly #include <compat/linux/common/linux_sched.h>
     69  1.23        ad #include <compat/linux/common/linux_ipc.h>
     70  1.23        ad #include <compat/linux/common/linux_sem.h>
     71   1.1      manu #include <compat/linux/linux_syscallargs.h>
     72   1.1      manu 
     73   1.1      manu #include <compat/linux32/common/linux32_types.h>
     74   1.1      manu #include <compat/linux32/common/linux32_signal.h>
     75   1.1      manu #include <compat/linux32/common/linux32_machdep.h>
     76   1.1      manu #include <compat/linux32/common/linux32_sysctl.h>
     77   1.1      manu #include <compat/linux32/common/linux32_socketcall.h>
     78  1.36  christos #include <compat/linux32/common/linux32_sched.h>
     79   1.1      manu #include <compat/linux32/linux32_syscallargs.h>
     80   1.1      manu 
     81  1.39   thorpej CTASSERT(LINUX_TIMER_ABSTIME == TIMER_ABSTIME);
     82  1.39   thorpej 
     83   1.1      manu extern struct timezone linux_sys_tz;
     84  1.18     njoly 
     85   1.1      manu int
     86  1.16       dsl linux32_sys_gettimeofday(struct lwp *l, const struct linux32_sys_gettimeofday_args *uap, register_t *retval)
     87   1.1      manu {
     88  1.16       dsl 	/* {
     89  1.28     njoly 		syscallarg(netbsd32_timeval50p_t) tp;
     90   1.1      manu 		syscallarg(netbsd32_timezonep_t) tzp;
     91  1.16       dsl 	} */
     92   1.1      manu 	struct timeval tv;
     93  1.28     njoly 	struct netbsd32_timeval50 tv32;
     94   1.1      manu 	int error;
     95   1.1      manu 
     96  1.10       dsl 	if (SCARG_P32(uap, tp) != NULL) {
     97   1.1      manu 		microtime(&tv);
     98  1.28     njoly 		netbsd32_from_timeval50(&tv, &tv32);
     99  1.10       dsl 		if ((error = copyout(&tv32, SCARG_P32(uap, tp),
    100   1.1      manu 		    sizeof(tv32))) != 0)
    101   1.1      manu 			return error;
    102   1.1      manu 	}
    103   1.1      manu 
    104   1.1      manu 	/* timezone size does not change */
    105  1.10       dsl 	if (SCARG_P32(uap, tzp) != NULL) {
    106  1.10       dsl 		if ((error = copyout(&linux_sys_tz, SCARG_P32(uap, tzp),
    107   1.1      manu 		    sizeof(linux_sys_tz))) != 0)
    108   1.1      manu 			return error;
    109   1.1      manu 	}
    110   1.1      manu 
    111   1.1      manu 	return 0;
    112   1.1      manu }
    113   1.1      manu 
    114   1.1      manu int
    115  1.16       dsl linux32_sys_settimeofday(struct lwp *l, const struct linux32_sys_settimeofday_args *uap, register_t *retval)
    116   1.1      manu {
    117  1.16       dsl 	/* {
    118  1.28     njoly 		syscallarg(netbsd32_timeval50p_t) tp;
    119   1.1      manu 		syscallarg(netbsd32_timezonep_t) tzp;
    120  1.16       dsl 	} */
    121   1.1      manu 	struct linux_sys_settimeofday_args ua;
    122   1.1      manu 
    123  1.28     njoly 	NETBSD32TOP_UAP(tp, struct timeval50);
    124   1.1      manu 	NETBSD32TOP_UAP(tzp, struct timezone);
    125   1.1      manu 
    126   1.1      manu 	return linux_sys_settimeofday(l, &ua, retval);
    127   1.1      manu }
    128   1.1      manu 
    129   1.1      manu int
    130  1.16       dsl linux32_sys_time(struct lwp *l, const struct linux32_sys_time_args *uap, register_t *retval)
    131   1.1      manu {
    132  1.16       dsl 	/* {
    133  1.26     njoly 		syscallarg(linux32_timep_t) t;
    134  1.16       dsl 	} */
    135   1.2      manu         struct timeval atv;
    136   1.2      manu         linux32_time_t tt;
    137   1.2      manu         int error;
    138   1.2      manu 
    139   1.2      manu         microtime(&atv);
    140   1.2      manu 
    141   1.2      manu         tt = (linux32_time_t)atv.tv_sec;
    142   1.2      manu 
    143  1.10       dsl         if (SCARG_P32(uap, t) && (error = copyout(&tt,
    144  1.10       dsl 	    SCARG_P32(uap, t), sizeof(tt))))
    145   1.2      manu                 return error;
    146   1.1      manu 
    147   1.2      manu         retval[0] = tt;
    148   1.1      manu 
    149   1.2      manu         return 0;
    150   1.1      manu }
    151   1.1      manu 
    152   1.1      manu 
    153  1.20  christos #define	CONVTCK(r)	(r.tv_sec * hz + r.tv_usec / (1000000 / hz))
    154  1.20  christos 
    155   1.1      manu int
    156  1.16       dsl linux32_sys_times(struct lwp *l, const struct linux32_sys_times_args *uap, register_t *retval)
    157   1.1      manu {
    158  1.16       dsl 	/* {
    159   1.1      manu 		syscallarg(linux32_tmsp_t) tms;
    160  1.16       dsl 	} */
    161  1.20  christos 	struct proc *p = l->l_proc;
    162  1.20  christos 	struct timeval t;
    163  1.20  christos 	int error;
    164   1.1      manu 
    165  1.20  christos 	if (SCARG_P32(uap, tms)) {
    166  1.20  christos 		struct linux32_tms ltms32;
    167  1.20  christos 		struct rusage ru;
    168  1.20  christos 
    169  1.38  riastrad 		memset(&ltms32, 0, sizeof(ltms32));
    170  1.38  riastrad 
    171  1.20  christos 		mutex_enter(p->p_lock);
    172  1.20  christos 		calcru(p, &ru.ru_utime, &ru.ru_stime, NULL, NULL);
    173  1.20  christos 		ltms32.ltms32_utime = CONVTCK(ru.ru_utime);
    174  1.20  christos 		ltms32.ltms32_stime = CONVTCK(ru.ru_stime);
    175  1.20  christos 		ltms32.ltms32_cutime = CONVTCK(p->p_stats->p_cru.ru_utime);
    176  1.20  christos 		ltms32.ltms32_cstime = CONVTCK(p->p_stats->p_cru.ru_stime);
    177  1.20  christos 		mutex_exit(p->p_lock);
    178  1.13       dsl 
    179  1.21  christos 		error = copyout(&ltms32, SCARG_P32(uap, tms), sizeof(ltms32));
    180  1.21  christos 		if (error)
    181  1.20  christos 			return error;
    182  1.20  christos 	}
    183  1.13       dsl 
    184  1.20  christos 	getmicrouptime(&t);
    185  1.13       dsl 
    186  1.20  christos 	retval[0] = ((linux32_clock_t)(CONVTCK(t)));
    187  1.20  christos 	return 0;
    188  1.20  christos }
    189   1.1      manu 
    190  1.20  christos #undef CONVTCK
    191   1.1      manu 
    192   1.1      manu int
    193  1.16       dsl linux32_sys_stime(struct lwp *l, const struct linux32_sys_stime_args *uap, register_t *retval)
    194   1.1      manu {
    195  1.16       dsl 	/* {
    196   1.1      manu 		syscallarg(linux32_timep_t) t;
    197  1.16       dsl 	} */
    198   1.1      manu 	struct timespec ts;
    199   1.1      manu 	linux32_time_t tt32;
    200   1.1      manu 	int error;
    201   1.1      manu 
    202  1.27     njoly 	if ((error = copyin(SCARG_P32(uap, t), &tt32, sizeof tt32)) != 0)
    203  1.10       dsl 		return error;
    204   1.1      manu 
    205   1.1      manu 	ts.tv_sec = (long)tt32;
    206   1.1      manu 	ts.tv_nsec = 0;
    207   1.1      manu 
    208   1.5        ad 	return settime(l->l_proc, &ts);
    209   1.1      manu }
    210   1.1      manu 
    211   1.1      manu int
    212  1.16       dsl linux32_sys_utime(struct lwp *l, const struct linux32_sys_utime_args *uap, register_t *retval)
    213   1.1      manu {
    214  1.16       dsl 	/* {
    215   1.1      manu 		syscallarg(const netbsd32_charp) path;
    216   1.1      manu 		syscallarg(linux32_utimbufp_t) times;
    217  1.16       dsl 	} */
    218   1.1      manu         struct timeval tv[2], *tvp;
    219   1.1      manu         struct linux32_utimbuf lut;
    220   1.1      manu         int error;
    221   1.1      manu 
    222  1.10       dsl         if (SCARG_P32(uap, times) != NULL) {
    223  1.10       dsl                 if ((error = copyin(SCARG_P32(uap, times), &lut, sizeof lut)))
    224   1.1      manu                         return error;
    225   1.1      manu 
    226   1.1      manu                 tv[0].tv_sec = (long)lut.l_actime;
    227   1.1      manu                 tv[0].tv_usec = 0;
    228   1.1      manu                 tv[1].tv_sec = (long)lut.l_modtime;
    229   1.1      manu 		tv[1].tv_usec = 0;
    230  1.12       dsl                 tvp = tv;
    231   1.1      manu         } else {
    232  1.12       dsl 		tvp = NULL;
    233   1.1      manu 	}
    234   1.1      manu 
    235  1.12       dsl         return do_sys_utimes(l, NULL, SCARG_P32(uap, path), FOLLOW,
    236  1.12       dsl 			    tvp, UIO_SYSSPACE);
    237  1.18     njoly }
    238  1.18     njoly 
    239  1.34       chs void
    240  1.39   thorpej native_to_linux32_timespec(struct linux32_timespec *ltp,
    241  1.39   thorpej     const struct timespec *ntp)
    242  1.18     njoly {
    243  1.38  riastrad 
    244  1.38  riastrad 	memset(ltp, 0, sizeof(*ltp));
    245  1.18     njoly 	ltp->tv_sec = ntp->tv_sec;
    246  1.18     njoly 	ltp->tv_nsec = ntp->tv_nsec;
    247  1.18     njoly }
    248  1.18     njoly 
    249  1.34       chs void
    250  1.39   thorpej linux32_to_native_timespec(struct timespec *ntp,
    251  1.39   thorpej     const struct linux32_timespec *ltp)
    252  1.18     njoly {
    253  1.38  riastrad 
    254  1.38  riastrad 	memset(ntp, 0, sizeof(*ntp));
    255  1.18     njoly 	ntp->tv_sec = ltp->tv_sec;
    256  1.18     njoly 	ntp->tv_nsec = ltp->tv_nsec;
    257  1.18     njoly }
    258  1.18     njoly 
    259  1.39   thorpej void
    260  1.39   thorpej native_to_linux32_itimerspec(struct linux32_itimerspec *litp,
    261  1.39   thorpej     const struct itimerspec *nitp)
    262  1.39   thorpej {
    263  1.39   thorpej 	memset(litp, 0, sizeof(*litp));
    264  1.39   thorpej 	native_to_linux32_timespec(&litp->it_interval, &nitp->it_interval);
    265  1.39   thorpej 	native_to_linux32_timespec(&litp->it_value, &nitp->it_value);
    266  1.39   thorpej }
    267  1.39   thorpej 
    268  1.39   thorpej void
    269  1.39   thorpej linux32_to_native_itimerspec(struct itimerspec *nitp,
    270  1.39   thorpej     const struct linux32_itimerspec *litp)
    271  1.39   thorpej {
    272  1.39   thorpej 	memset(nitp, 0, sizeof(*nitp));
    273  1.39   thorpej 	linux32_to_native_timespec(&nitp->it_interval, &litp->it_interval);
    274  1.39   thorpej 	linux32_to_native_timespec(&nitp->it_value, &litp->it_value);
    275  1.39   thorpej }
    276  1.39   thorpej 
    277  1.18     njoly int
    278  1.22     njoly linux32_sys_nanosleep(struct lwp *l,
    279  1.22     njoly     const struct linux32_sys_nanosleep_args *uap, register_t *retval)
    280  1.22     njoly {
    281  1.22     njoly 	/* {
    282  1.22     njoly 		syscallarg(linux32_timespecp_t) rqtp;
    283  1.22     njoly 		syscallarg(linux32_timespecp_t) rmtp;
    284  1.22     njoly 	} */
    285  1.22     njoly 	struct timespec rqts, rmts;
    286  1.22     njoly 	struct linux32_timespec lrqts, lrmts;
    287  1.22     njoly 	int error, error1;
    288  1.22     njoly 
    289  1.22     njoly 	error = copyin(SCARG_P32(uap, rqtp), &lrqts, sizeof(lrqts));
    290  1.22     njoly 	if (error != 0)
    291  1.22     njoly 		return error;
    292  1.22     njoly 	linux32_to_native_timespec(&rqts, &lrqts);
    293  1.22     njoly 
    294  1.37  christos 	error = nanosleep1(l, CLOCK_MONOTONIC, 0, &rqts,
    295  1.37  christos 	    SCARG_P32(uap, rmtp) ? &rmts : NULL);
    296  1.22     njoly 	if (SCARG_P32(uap, rmtp) == NULL || (error != 0 && error != EINTR))
    297  1.22     njoly 		return error;
    298  1.22     njoly 
    299  1.22     njoly 	native_to_linux32_timespec(&lrmts, &rmts);
    300  1.22     njoly 	error1 = copyout(&lrmts, SCARG_P32(uap, rmtp), sizeof(lrmts));
    301  1.22     njoly 	return error1 ? error1 : error;
    302  1.22     njoly }
    303  1.22     njoly 
    304  1.22     njoly int
    305  1.18     njoly linux32_sys_clock_settime(struct lwp *l,
    306  1.18     njoly     const struct linux32_sys_clock_settime_args *uap, register_t *retval)
    307  1.18     njoly {
    308  1.18     njoly 	/* {
    309  1.18     njoly 		syscallarg(clockid_t) which;
    310  1.18     njoly 		syscallarg(linux32_timespecp_t) tp;
    311  1.18     njoly 	} */
    312  1.18     njoly 	int error;
    313  1.18     njoly 	struct timespec ts;
    314  1.18     njoly 	struct linux32_timespec lts;
    315  1.30     njoly 	clockid_t id;
    316  1.18     njoly 
    317  1.30     njoly 	error = linux_to_native_clockid(&id, SCARG(uap, which));
    318  1.30     njoly 	if (error != 0)
    319  1.30     njoly 		return error;
    320  1.18     njoly 
    321  1.18     njoly 	if ((error = copyin(SCARG_P32(uap, tp), &lts, sizeof lts)))
    322  1.18     njoly 		return error;
    323  1.18     njoly 
    324  1.18     njoly 	linux32_to_native_timespec(&ts, &lts);
    325  1.30     njoly 	return clock_settime1(l->l_proc, id, &ts, true);
    326  1.18     njoly }
    327  1.18     njoly 
    328  1.18     njoly int
    329  1.18     njoly linux32_sys_clock_gettime(struct lwp *l,
    330  1.18     njoly     const struct linux32_sys_clock_gettime_args *uap, register_t *retval)
    331  1.18     njoly {
    332  1.18     njoly 	/* {
    333  1.18     njoly 		syscallarg(clockid_t) which;
    334  1.18     njoly 		syscallarg(linux32_timespecp_t) tp;
    335  1.18     njoly 	} */
    336  1.32     njoly 	int error;
    337  1.32     njoly 	clockid_t id;
    338  1.18     njoly 	struct timespec ts;
    339  1.18     njoly 	struct linux32_timespec lts;
    340  1.18     njoly 
    341  1.32     njoly 	error = linux_to_native_clockid(&id, SCARG(uap, which));
    342  1.32     njoly 	if (error != 0)
    343  1.32     njoly 		return error;
    344  1.32     njoly 
    345  1.32     njoly 	error = clock_gettime1(id, &ts);
    346  1.32     njoly 	if (error != 0)
    347  1.32     njoly 		return error;
    348  1.18     njoly 
    349  1.18     njoly 	native_to_linux32_timespec(&lts, &ts);
    350  1.18     njoly 	return copyout(&lts, SCARG_P32(uap, tp), sizeof lts);
    351  1.18     njoly }
    352  1.18     njoly 
    353  1.18     njoly int
    354  1.18     njoly linux32_sys_clock_getres(struct lwp *l,
    355  1.18     njoly     const struct linux32_sys_clock_getres_args *uap, register_t *retval)
    356  1.18     njoly {
    357  1.18     njoly 	/* {
    358  1.18     njoly 		syscallarg(clockid_t) which;
    359  1.18     njoly 		syscallarg(linux32_timespecp_t) tp;
    360  1.18     njoly 	} */
    361  1.18     njoly 	int error;
    362  1.18     njoly 	clockid_t id;
    363  1.18     njoly 	struct timespec ts;
    364  1.18     njoly 	struct linux32_timespec lts;
    365  1.18     njoly 
    366  1.18     njoly 	error = linux_to_native_clockid(&id, SCARG(uap, which));
    367  1.18     njoly 	if (error != 0 || SCARG_P32(uap, tp) == NULL)
    368  1.18     njoly 		return error;
    369  1.18     njoly 
    370  1.31     njoly 	error = clock_getres1(id, &ts);
    371  1.31     njoly 	if (error != 0)
    372  1.31     njoly 		return error;
    373  1.31     njoly 
    374  1.18     njoly 	native_to_linux32_timespec(&lts, &ts);
    375  1.18     njoly 	return copyout(&lts, SCARG_P32(uap, tp), sizeof lts);
    376  1.18     njoly }
    377  1.25     njoly 
    378  1.25     njoly int
    379  1.25     njoly linux32_sys_clock_nanosleep(struct lwp *l,
    380  1.25     njoly     const struct linux32_sys_clock_nanosleep_args *uap, register_t *retval)
    381  1.25     njoly {
    382  1.25     njoly 	/* {
    383  1.25     njoly 		syscallarg(clockid_t) which;
    384  1.25     njoly 		syscallarg(int) flags;
    385  1.25     njoly 		syscallarg(linux32_timespecp_t) rqtp;
    386  1.25     njoly 		syscallarg(linux32_timespecp_t) rmtp;
    387  1.25     njoly 	} */
    388  1.25     njoly 	struct linux32_timespec lrqts, lrmts;
    389  1.25     njoly 	struct timespec rqts, rmts;
    390  1.37  christos 	int error, error1, flags;
    391  1.35     njoly 	clockid_t id;
    392  1.25     njoly 
    393  1.37  christos 	flags = SCARG(uap, flags) != 0 ? TIMER_ABSTIME : 0;
    394  1.35     njoly 
    395  1.35     njoly 	error = linux_to_native_clockid(&id, SCARG(uap, which));
    396  1.35     njoly 	if (error != 0)
    397  1.35     njoly 		return error;
    398  1.25     njoly 
    399  1.25     njoly 	error = copyin(SCARG_P32(uap, rqtp), &lrqts, sizeof lrqts);
    400  1.25     njoly 	if (error != 0)
    401  1.25     njoly 		return error;
    402  1.25     njoly 	linux32_to_native_timespec(&rqts, &lrqts);
    403  1.25     njoly 
    404  1.37  christos 	error = nanosleep1(l, id, flags, &rqts,
    405  1.37  christos 	    SCARG_P32(uap, rmtp) ? &rmts : NULL);
    406  1.25     njoly 	if (SCARG_P32(uap, rmtp) == NULL || (error != 0 && error != EINTR))
    407  1.25     njoly 		return error;
    408  1.25     njoly 
    409  1.25     njoly 	native_to_linux32_timespec(&lrmts, &rmts);
    410  1.25     njoly 	error1 = copyout(&lrmts, SCARG_P32(uap, rmtp), sizeof lrmts);
    411  1.25     njoly 	return error1 ? error1 : error;
    412  1.25     njoly }
    413  1.39   thorpej 
    414  1.39   thorpej int
    415  1.39   thorpej linux32_sys_timer_create(struct lwp *l,
    416  1.39   thorpej     const struct linux32_sys_timer_create_args *uap, register_t *retval)
    417  1.39   thorpej {
    418  1.39   thorpej 	/* {
    419  1.39   thorpej 		syscallarg(clockid_t) clockid;
    420  1.39   thorpej 		syscallarg(struct linux32_sigevent *) evp;
    421  1.39   thorpej 		syscallarg(timer_t *) timerid;
    422  1.39   thorpej 	} */
    423  1.39   thorpej 	clockid_t id;
    424  1.39   thorpej 	int error;
    425  1.39   thorpej 
    426  1.39   thorpej 	error = linux_to_native_timer_create_clockid(&id, SCARG(uap, clockid));
    427  1.39   thorpej 	if (error == 0) {
    428  1.39   thorpej 		error = timer_create1(SCARG(uap, timerid), id,
    429  1.39   thorpej 		    (void *)SCARG(uap, evp), linux32_sigevent_copyin, l);
    430  1.39   thorpej 	}
    431  1.39   thorpej 
    432  1.39   thorpej 	return error;
    433  1.39   thorpej }
    434  1.39   thorpej 
    435  1.39   thorpej int
    436  1.39   thorpej linux32_sys_timer_settime(struct lwp *l,
    437  1.39   thorpej     const struct linux32_sys_timer_settime_args *uap, register_t *retval)
    438  1.39   thorpej {
    439  1.39   thorpej 	/* {
    440  1.39   thorpej 		syscallarg(timer_t) timerid;
    441  1.39   thorpej 		syscallarg(int) flags;
    442  1.39   thorpej 		syscallarg(const struct linux32_itimerspec *) tim;
    443  1.39   thorpej 		syscallarg(struct linux32_itimerspec *) otim;
    444  1.39   thorpej 	} */
    445  1.39   thorpej 	struct itimerspec value, ovalue, *ovp = NULL;
    446  1.39   thorpej 	struct linux32_itimerspec tim, otim;
    447  1.39   thorpej 	int error;
    448  1.39   thorpej 
    449  1.39   thorpej 	error = copyin(SCARG(uap, tim), &tim, sizeof(tim));
    450  1.39   thorpej 	if (error) {
    451  1.39   thorpej 		return error;
    452  1.39   thorpej 	}
    453  1.39   thorpej 	linux32_to_native_itimerspec(&value, &tim);
    454  1.39   thorpej 
    455  1.39   thorpej 	if (SCARG(uap, otim)) {
    456  1.39   thorpej 		ovp = &ovalue;
    457  1.39   thorpej 	}
    458  1.39   thorpej 
    459  1.39   thorpej 	if (SCARG(uap, flags) & ~TIMER_ABSTIME) {
    460  1.39   thorpej 		return EINVAL;
    461  1.39   thorpej 	}
    462  1.39   thorpej 
    463  1.39   thorpej 	error = dotimer_settime(SCARG(uap, timerid), &value, ovp,
    464  1.39   thorpej 	    SCARG(uap, flags), l->l_proc);
    465  1.39   thorpej 	if (error) {
    466  1.39   thorpej 		return error;
    467  1.39   thorpej 	}
    468  1.39   thorpej 
    469  1.39   thorpej 	if (ovp) {
    470  1.39   thorpej 		native_to_linux32_itimerspec(&otim, ovp);
    471  1.39   thorpej 		error = copyout(&otim, SCARG(uap, otim), sizeof(otim));
    472  1.39   thorpej 	}
    473  1.39   thorpej 
    474  1.39   thorpej 	return error;
    475  1.39   thorpej }
    476  1.39   thorpej 
    477  1.39   thorpej int
    478  1.39   thorpej linux32_sys_timer_gettime(struct lwp *l,
    479  1.39   thorpej     const struct linux32_sys_timer_gettime_args *uap, register_t *retval)
    480  1.39   thorpej {
    481  1.39   thorpej 	/* {
    482  1.39   thorpej 		syscallarg(timer_t) timerid;
    483  1.39   thorpej 		syscallarg(struct linux32_itimerspec *) tim;
    484  1.39   thorpej 	} */
    485  1.39   thorpej 	struct itimerspec its;
    486  1.39   thorpej 	struct linux32_itimerspec lits;
    487  1.39   thorpej 	int error;
    488  1.39   thorpej 
    489  1.39   thorpej 	error = dotimer_gettime(SCARG(uap, timerid), l->l_proc, &its);
    490  1.39   thorpej 	if (error == 0) {
    491  1.39   thorpej 		native_to_linux32_itimerspec(&lits, &its);
    492  1.39   thorpej 		error = copyout(&lits, SCARG(uap, tim), sizeof(lits));
    493  1.39   thorpej 	}
    494  1.39   thorpej 
    495  1.39   thorpej 	return error;
    496  1.39   thorpej }
    497  1.39   thorpej 
    498  1.39   thorpej /*
    499  1.39   thorpej  * timer_gettoverrun(2) and timer_delete(2) are handled directly
    500  1.39   thorpej  * by the native calls.
    501  1.39   thorpej  */
    502  1.40   thorpej 
    503  1.40   thorpej /*
    504  1.40   thorpej  * timerfd_create() is handled by the standard COMPAT_LINUX call.
    505  1.40   thorpej  */
    506  1.40   thorpej 
    507  1.40   thorpej int
    508  1.40   thorpej linux32_sys_timerfd_gettime(struct lwp *l,
    509  1.40   thorpej     const struct linux32_sys_timerfd_gettime_args *uap, register_t *retval)
    510  1.40   thorpej {
    511  1.40   thorpej 	/* {
    512  1.40   thorpej 		syscallarg(int) fd;
    513  1.40   thorpej 		syscallarg(struct linux32_itimerspec *) tim;
    514  1.40   thorpej 	} */
    515  1.40   thorpej 	struct itimerspec its;
    516  1.40   thorpej 	struct linux32_itimerspec lits;
    517  1.40   thorpej 	int error;
    518  1.40   thorpej 
    519  1.40   thorpej 	error = do_timerfd_gettime(l, SCARG(uap, fd), &its, retval);
    520  1.40   thorpej 	if (error == 0) {
    521  1.40   thorpej 		native_to_linux32_itimerspec(&lits, &its);
    522  1.40   thorpej 		error = copyout(&lits, SCARG(uap, tim), sizeof(lits));
    523  1.40   thorpej 	}
    524  1.40   thorpej 
    525  1.40   thorpej 	return error;
    526  1.40   thorpej }
    527  1.40   thorpej 
    528  1.40   thorpej int
    529  1.40   thorpej linux32_sys_timerfd_settime(struct lwp *l,
    530  1.40   thorpej     const struct linux32_sys_timerfd_settime_args *uap, register_t *retval)
    531  1.40   thorpej {
    532  1.40   thorpej 	/* {
    533  1.40   thorpej 		syscallarg(int) fd;
    534  1.40   thorpej 		syscallarg(int) flags;
    535  1.40   thorpej 		syscallarg(const struct linux32_itimerspec *) tim;
    536  1.40   thorpej 		syscallarg(struct linux32_itimerspec *) otim;
    537  1.40   thorpej 	} */
    538  1.40   thorpej 	struct itimerspec nits, oits, *oitsp = NULL;
    539  1.40   thorpej 	struct linux32_itimerspec lits;
    540  1.40   thorpej 	int nflags;
    541  1.40   thorpej 	int error;
    542  1.40   thorpej 
    543  1.40   thorpej 	error = copyin(SCARG(uap, tim), &lits, sizeof(lits));
    544  1.40   thorpej 	if (error) {
    545  1.40   thorpej 		return error;
    546  1.40   thorpej 	}
    547  1.40   thorpej 	linux32_to_native_itimerspec(&nits, &lits);
    548  1.40   thorpej 
    549  1.40   thorpej 	error = linux_to_native_timerfd_settime_flags(&nflags,
    550  1.40   thorpej 	    SCARG(uap, flags));
    551  1.40   thorpej 	if (error) {
    552  1.40   thorpej 		return error;
    553  1.40   thorpej 	}
    554  1.40   thorpej 
    555  1.40   thorpej 	if (SCARG(uap, otim)) {
    556  1.40   thorpej 		oitsp = &oits;
    557  1.40   thorpej 	}
    558  1.40   thorpej 
    559  1.40   thorpej 	error = do_timerfd_settime(l, SCARG(uap, fd), nflags,
    560  1.40   thorpej 	    &nits, oitsp, retval);
    561  1.40   thorpej 	if (error == 0 && oitsp != NULL) {
    562  1.40   thorpej 		native_to_linux32_itimerspec(&lits, oitsp);
    563  1.40   thorpej 		error = copyout(&lits, SCARG(uap, otim), sizeof(lits));
    564  1.40   thorpej 	}
    565  1.40   thorpej 
    566  1.40   thorpej 	return error;
    567  1.40   thorpej }
    568