linux/kernel/time/posix-stubs.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Dummy stubs used when CONFIG_POSIX_TIMERS=n
   4 *
   5 * Created by:  Nicolas Pitre, July 2016
   6 * Copyright:   (C) 2016 Linaro Limited
   7 */
   8
   9#include <linux/linkage.h>
  10#include <linux/kernel.h>
  11#include <linux/sched.h>
  12#include <linux/errno.h>
  13#include <linux/syscalls.h>
  14#include <linux/ktime.h>
  15#include <linux/timekeeping.h>
  16#include <linux/posix-timers.h>
  17#include <linux/time_namespace.h>
  18#include <linux/compat.h>
  19
  20#ifdef CONFIG_ARCH_HAS_SYSCALL_WRAPPER
  21/* Architectures may override SYS_NI and COMPAT_SYS_NI */
  22#include <asm/syscall_wrapper.h>
  23#endif
  24
  25asmlinkage long sys_ni_posix_timers(void)
  26{
  27        pr_err_once("process %d (%s) attempted a POSIX timer syscall "
  28                    "while CONFIG_POSIX_TIMERS is not set\n",
  29                    current->pid, current->comm);
  30        return -ENOSYS;
  31}
  32
  33#ifndef SYS_NI
  34#define SYS_NI(name)  SYSCALL_ALIAS(sys_##name, sys_ni_posix_timers)
  35#endif
  36
  37#ifndef COMPAT_SYS_NI
  38#define COMPAT_SYS_NI(name)  SYSCALL_ALIAS(compat_sys_##name, sys_ni_posix_timers)
  39#endif
  40
  41SYS_NI(timer_create);
  42SYS_NI(timer_gettime);
  43SYS_NI(timer_getoverrun);
  44SYS_NI(timer_settime);
  45SYS_NI(timer_delete);
  46SYS_NI(clock_adjtime);
  47SYS_NI(getitimer);
  48SYS_NI(setitimer);
  49SYS_NI(clock_adjtime32);
  50#ifdef __ARCH_WANT_SYS_ALARM
  51SYS_NI(alarm);
  52#endif
  53
  54/*
  55 * We preserve minimal support for CLOCK_REALTIME and CLOCK_MONOTONIC
  56 * as it is easy to remain compatible with little code. CLOCK_BOOTTIME
  57 * is also included for convenience as at least systemd uses it.
  58 */
  59
  60SYSCALL_DEFINE2(clock_settime, const clockid_t, which_clock,
  61                const struct __kernel_timespec __user *, tp)
  62{
  63        struct timespec64 new_tp;
  64
  65        if (which_clock != CLOCK_REALTIME)
  66                return -EINVAL;
  67        if (get_timespec64(&new_tp, tp))
  68                return -EFAULT;
  69
  70        return do_sys_settimeofday64(&new_tp, NULL);
  71}
  72
  73int do_clock_gettime(clockid_t which_clock, struct timespec64 *tp)
  74{
  75        switch (which_clock) {
  76        case CLOCK_REALTIME:
  77                ktime_get_real_ts64(tp);
  78                break;
  79        case CLOCK_MONOTONIC:
  80                ktime_get_ts64(tp);
  81                timens_add_monotonic(tp);
  82                break;
  83        case CLOCK_BOOTTIME:
  84                ktime_get_boottime_ts64(tp);
  85                timens_add_boottime(tp);
  86                break;
  87        default:
  88                return -EINVAL;
  89        }
  90
  91        return 0;
  92}
  93SYSCALL_DEFINE2(clock_gettime, const clockid_t, which_clock,
  94                struct __kernel_timespec __user *, tp)
  95{
  96        int ret;
  97        struct timespec64 kernel_tp;
  98
  99        ret = do_clock_gettime(which_clock, &kernel_tp);
 100        if (ret)
 101                return ret;
 102
 103        if (put_timespec64(&kernel_tp, tp))
 104                return -EFAULT;
 105        return 0;
 106}
 107
 108SYSCALL_DEFINE2(clock_getres, const clockid_t, which_clock, struct __kernel_timespec __user *, tp)
 109{
 110        struct timespec64 rtn_tp = {
 111                .tv_sec = 0,
 112                .tv_nsec = hrtimer_resolution,
 113        };
 114
 115        switch (which_clock) {
 116        case CLOCK_REALTIME:
 117        case CLOCK_MONOTONIC:
 118        case CLOCK_BOOTTIME:
 119                if (put_timespec64(&rtn_tp, tp))
 120                        return -EFAULT;
 121                return 0;
 122        default:
 123                return -EINVAL;
 124        }
 125}
 126
 127SYSCALL_DEFINE4(clock_nanosleep, const clockid_t, which_clock, int, flags,
 128                const struct __kernel_timespec __user *, rqtp,
 129                struct __kernel_timespec __user *, rmtp)
 130{
 131        struct timespec64 t;
 132        ktime_t texp;
 133
 134        switch (which_clock) {
 135        case CLOCK_REALTIME:
 136        case CLOCK_MONOTONIC:
 137        case CLOCK_BOOTTIME:
 138                break;
 139        default:
 140                return -EINVAL;
 141        }
 142
 143        if (get_timespec64(&t, rqtp))
 144                return -EFAULT;
 145        if (!timespec64_valid(&t))
 146                return -EINVAL;
 147        if (flags & TIMER_ABSTIME)
 148                rmtp = NULL;
 149        current->restart_block.nanosleep.type = rmtp ? TT_NATIVE : TT_NONE;
 150        current->restart_block.nanosleep.rmtp = rmtp;
 151        texp = timespec64_to_ktime(t);
 152        if (flags & TIMER_ABSTIME)
 153                texp = timens_ktime_to_host(which_clock, texp);
 154        return hrtimer_nanosleep(texp, flags & TIMER_ABSTIME ?
 155                                 HRTIMER_MODE_ABS : HRTIMER_MODE_REL,
 156                                 which_clock);
 157}
 158
 159#ifdef CONFIG_COMPAT
 160COMPAT_SYS_NI(timer_create);
 161#endif
 162
 163#if defined(CONFIG_COMPAT) || defined(CONFIG_ALPHA)
 164COMPAT_SYS_NI(getitimer);
 165COMPAT_SYS_NI(setitimer);
 166#endif
 167
 168#ifdef CONFIG_COMPAT_32BIT_TIME
 169SYS_NI(timer_settime32);
 170SYS_NI(timer_gettime32);
 171
 172SYSCALL_DEFINE2(clock_settime32, const clockid_t, which_clock,
 173                struct old_timespec32 __user *, tp)
 174{
 175        struct timespec64 new_tp;
 176
 177        if (which_clock != CLOCK_REALTIME)
 178                return -EINVAL;
 179        if (get_old_timespec32(&new_tp, tp))
 180                return -EFAULT;
 181
 182        return do_sys_settimeofday64(&new_tp, NULL);
 183}
 184
 185SYSCALL_DEFINE2(clock_gettime32, clockid_t, which_clock,
 186                struct old_timespec32 __user *, tp)
 187{
 188        int ret;
 189        struct timespec64 kernel_tp;
 190
 191        ret = do_clock_gettime(which_clock, &kernel_tp);
 192        if (ret)
 193                return ret;
 194
 195        if (put_old_timespec32(&kernel_tp, tp))
 196                return -EFAULT;
 197        return 0;
 198}
 199
 200SYSCALL_DEFINE2(clock_getres_time32, clockid_t, which_clock,
 201                struct old_timespec32 __user *, tp)
 202{
 203        struct timespec64 rtn_tp = {
 204                .tv_sec = 0,
 205                .tv_nsec = hrtimer_resolution,
 206        };
 207
 208        switch (which_clock) {
 209        case CLOCK_REALTIME:
 210        case CLOCK_MONOTONIC:
 211        case CLOCK_BOOTTIME:
 212                if (put_old_timespec32(&rtn_tp, tp))
 213                        return -EFAULT;
 214                return 0;
 215        default:
 216                return -EINVAL;
 217        }
 218}
 219
 220SYSCALL_DEFINE4(clock_nanosleep_time32, clockid_t, which_clock, int, flags,
 221                struct old_timespec32 __user *, rqtp,
 222                struct old_timespec32 __user *, rmtp)
 223{
 224        struct timespec64 t;
 225        ktime_t texp;
 226
 227        switch (which_clock) {
 228        case CLOCK_REALTIME:
 229        case CLOCK_MONOTONIC:
 230        case CLOCK_BOOTTIME:
 231                break;
 232        default:
 233                return -EINVAL;
 234        }
 235
 236        if (get_old_timespec32(&t, rqtp))
 237                return -EFAULT;
 238        if (!timespec64_valid(&t))
 239                return -EINVAL;
 240        if (flags & TIMER_ABSTIME)
 241                rmtp = NULL;
 242        current->restart_block.nanosleep.type = rmtp ? TT_COMPAT : TT_NONE;
 243        current->restart_block.nanosleep.compat_rmtp = rmtp;
 244        texp = timespec64_to_ktime(t);
 245        if (flags & TIMER_ABSTIME)
 246                texp = timens_ktime_to_host(which_clock, texp);
 247        return hrtimer_nanosleep(texp, flags & TIMER_ABSTIME ?
 248                                 HRTIMER_MODE_ABS : HRTIMER_MODE_REL,
 249                                 which_clock);
 250}
 251#endif
 252