1*35728b82SThomas Gleixner // SPDX-License-Identifier: GPL-2.0 2baa73d9eSNicolas Pitre /* 3baa73d9eSNicolas Pitre * Dummy stubs used when CONFIG_POSIX_TIMERS=n 4baa73d9eSNicolas Pitre * 5baa73d9eSNicolas Pitre * Created by: Nicolas Pitre, July 2016 6baa73d9eSNicolas Pitre * Copyright: (C) 2016 Linaro Limited 7baa73d9eSNicolas Pitre * 8baa73d9eSNicolas Pitre * This program is free software; you can redistribute it and/or modify 9baa73d9eSNicolas Pitre * it under the terms of the GNU General Public License version 2 as 10baa73d9eSNicolas Pitre * published by the Free Software Foundation. 11baa73d9eSNicolas Pitre */ 12baa73d9eSNicolas Pitre 13baa73d9eSNicolas Pitre #include <linux/linkage.h> 14baa73d9eSNicolas Pitre #include <linux/kernel.h> 15baa73d9eSNicolas Pitre #include <linux/sched.h> 16baa73d9eSNicolas Pitre #include <linux/errno.h> 17baa73d9eSNicolas Pitre #include <linux/syscalls.h> 18baa73d9eSNicolas Pitre #include <linux/ktime.h> 19baa73d9eSNicolas Pitre #include <linux/timekeeping.h> 20baa73d9eSNicolas Pitre #include <linux/posix-timers.h> 21edbeda46SAl Viro #include <linux/compat.h> 22baa73d9eSNicolas Pitre 237303e30eSDominik Brodowski #ifdef CONFIG_ARCH_HAS_SYSCALL_WRAPPER 247303e30eSDominik Brodowski /* Architectures may override SYS_NI and COMPAT_SYS_NI */ 257303e30eSDominik Brodowski #include <asm/syscall_wrapper.h> 267303e30eSDominik Brodowski #endif 277303e30eSDominik Brodowski 28baa73d9eSNicolas Pitre asmlinkage long sys_ni_posix_timers(void) 29baa73d9eSNicolas Pitre { 30baa73d9eSNicolas Pitre pr_err_once("process %d (%s) attempted a POSIX timer syscall " 31baa73d9eSNicolas Pitre "while CONFIG_POSIX_TIMERS is not set\n", 32baa73d9eSNicolas Pitre current->pid, current->comm); 33baa73d9eSNicolas Pitre return -ENOSYS; 34baa73d9eSNicolas Pitre } 35baa73d9eSNicolas Pitre 367303e30eSDominik Brodowski #ifndef SYS_NI 37baa73d9eSNicolas Pitre #define SYS_NI(name) SYSCALL_ALIAS(sys_##name, sys_ni_posix_timers) 387303e30eSDominik Brodowski #endif 397303e30eSDominik Brodowski 407303e30eSDominik Brodowski #ifndef COMPAT_SYS_NI 413a4d44b6SAl Viro #define COMPAT_SYS_NI(name) SYSCALL_ALIAS(compat_sys_##name, sys_ni_posix_timers) 427303e30eSDominik Brodowski #endif 43baa73d9eSNicolas Pitre 44baa73d9eSNicolas Pitre SYS_NI(timer_create); 45baa73d9eSNicolas Pitre SYS_NI(timer_gettime); 46baa73d9eSNicolas Pitre SYS_NI(timer_getoverrun); 47baa73d9eSNicolas Pitre SYS_NI(timer_settime); 48baa73d9eSNicolas Pitre SYS_NI(timer_delete); 49baa73d9eSNicolas Pitre SYS_NI(clock_adjtime); 50baa73d9eSNicolas Pitre SYS_NI(getitimer); 51baa73d9eSNicolas Pitre SYS_NI(setitimer); 52baa73d9eSNicolas Pitre #ifdef __ARCH_WANT_SYS_ALARM 53baa73d9eSNicolas Pitre SYS_NI(alarm); 54baa73d9eSNicolas Pitre #endif 55baa73d9eSNicolas Pitre 56baa73d9eSNicolas Pitre /* 57baa73d9eSNicolas Pitre * We preserve minimal support for CLOCK_REALTIME and CLOCK_MONOTONIC 58baa73d9eSNicolas Pitre * as it is easy to remain compatible with little code. CLOCK_BOOTTIME 59baa73d9eSNicolas Pitre * is also included for convenience as at least systemd uses it. 60baa73d9eSNicolas Pitre */ 61baa73d9eSNicolas Pitre 62baa73d9eSNicolas Pitre SYSCALL_DEFINE2(clock_settime, const clockid_t, which_clock, 636d5b8413SDeepa Dinamani const struct __kernel_timespec __user *, tp) 64baa73d9eSNicolas Pitre { 655c499410SDeepa Dinamani struct timespec64 new_tp; 66baa73d9eSNicolas Pitre 67baa73d9eSNicolas Pitre if (which_clock != CLOCK_REALTIME) 68baa73d9eSNicolas Pitre return -EINVAL; 695c499410SDeepa Dinamani if (get_timespec64(&new_tp, tp)) 70baa73d9eSNicolas Pitre return -EFAULT; 712ac00f17SDeepa Dinamani 725c499410SDeepa Dinamani return do_sys_settimeofday64(&new_tp, NULL); 73baa73d9eSNicolas Pitre } 74baa73d9eSNicolas Pitre 755c499410SDeepa Dinamani int do_clock_gettime(clockid_t which_clock, struct timespec64 *tp) 765c499410SDeepa Dinamani { 775c499410SDeepa Dinamani switch (which_clock) { 785c499410SDeepa Dinamani case CLOCK_REALTIME: 795c499410SDeepa Dinamani ktime_get_real_ts64(tp); 805c499410SDeepa Dinamani break; 815c499410SDeepa Dinamani case CLOCK_MONOTONIC: 825c499410SDeepa Dinamani ktime_get_ts64(tp); 835c499410SDeepa Dinamani break; 845c499410SDeepa Dinamani case CLOCK_BOOTTIME: 8558a10456SArnd Bergmann ktime_get_boottime_ts64(tp); 865c499410SDeepa Dinamani break; 875c499410SDeepa Dinamani default: 885c499410SDeepa Dinamani return -EINVAL; 895c499410SDeepa Dinamani } 905c499410SDeepa Dinamani 915c499410SDeepa Dinamani return 0; 925c499410SDeepa Dinamani } 93baa73d9eSNicolas Pitre SYSCALL_DEFINE2(clock_gettime, const clockid_t, which_clock, 946d5b8413SDeepa Dinamani struct __kernel_timespec __user *, tp) 95baa73d9eSNicolas Pitre { 965c499410SDeepa Dinamani int ret; 975c499410SDeepa Dinamani struct timespec64 kernel_tp; 98baa73d9eSNicolas Pitre 995c499410SDeepa Dinamani ret = do_clock_gettime(which_clock, &kernel_tp); 1005c499410SDeepa Dinamani if (ret) 1015c499410SDeepa Dinamani return ret; 1023c9c12f4SDeepa Dinamani 1035c499410SDeepa Dinamani if (put_timespec64(&kernel_tp, tp)) 104baa73d9eSNicolas Pitre return -EFAULT; 105baa73d9eSNicolas Pitre return 0; 106baa73d9eSNicolas Pitre } 107baa73d9eSNicolas Pitre 1086d5b8413SDeepa Dinamani SYSCALL_DEFINE2(clock_getres, const clockid_t, which_clock, struct __kernel_timespec __user *, tp) 109baa73d9eSNicolas Pitre { 1105c499410SDeepa Dinamani struct timespec64 rtn_tp = { 111baa73d9eSNicolas Pitre .tv_sec = 0, 112baa73d9eSNicolas Pitre .tv_nsec = hrtimer_resolution, 113baa73d9eSNicolas Pitre }; 114baa73d9eSNicolas Pitre 115baa73d9eSNicolas Pitre switch (which_clock) { 116baa73d9eSNicolas Pitre case CLOCK_REALTIME: 117baa73d9eSNicolas Pitre case CLOCK_MONOTONIC: 118baa73d9eSNicolas Pitre case CLOCK_BOOTTIME: 1195c499410SDeepa Dinamani if (put_timespec64(&rtn_tp, tp)) 120baa73d9eSNicolas Pitre return -EFAULT; 121baa73d9eSNicolas Pitre return 0; 122baa73d9eSNicolas Pitre default: 123baa73d9eSNicolas Pitre return -EINVAL; 124baa73d9eSNicolas Pitre } 125baa73d9eSNicolas Pitre } 126baa73d9eSNicolas Pitre 127baa73d9eSNicolas Pitre SYSCALL_DEFINE4(clock_nanosleep, const clockid_t, which_clock, int, flags, 12801909974SDeepa Dinamani const struct __kernel_timespec __user *, rqtp, 12901909974SDeepa Dinamani struct __kernel_timespec __user *, rmtp) 130baa73d9eSNicolas Pitre { 131fe460423SArnd Bergmann struct timespec64 t; 132baa73d9eSNicolas Pitre 133baa73d9eSNicolas Pitre switch (which_clock) { 134baa73d9eSNicolas Pitre case CLOCK_REALTIME: 135baa73d9eSNicolas Pitre case CLOCK_MONOTONIC: 136baa73d9eSNicolas Pitre case CLOCK_BOOTTIME: 137edbeda46SAl Viro break; 138edbeda46SAl Viro default: 139edbeda46SAl Viro return -EINVAL; 140edbeda46SAl Viro } 141edbeda46SAl Viro 142fe460423SArnd Bergmann if (get_timespec64(&t, rqtp)) 143baa73d9eSNicolas Pitre return -EFAULT; 144fe460423SArnd Bergmann if (!timespec64_valid(&t)) 145baa73d9eSNicolas Pitre return -EINVAL; 146192a82f9SAl Viro if (flags & TIMER_ABSTIME) 147192a82f9SAl Viro rmtp = NULL; 148edbeda46SAl Viro current->restart_block.nanosleep.type = rmtp ? TT_NATIVE : TT_NONE; 149192a82f9SAl Viro current->restart_block.nanosleep.rmtp = rmtp; 150fe460423SArnd Bergmann return hrtimer_nanosleep(&t, flags & TIMER_ABSTIME ? 151baa73d9eSNicolas Pitre HRTIMER_MODE_ABS : HRTIMER_MODE_REL, 152baa73d9eSNicolas Pitre which_clock); 153baa73d9eSNicolas Pitre } 154baa73d9eSNicolas Pitre 155baa73d9eSNicolas Pitre #ifdef CONFIG_COMPAT 15663a766a1SDeepa Dinamani COMPAT_SYS_NI(timer_create); 15763a766a1SDeepa Dinamani COMPAT_SYS_NI(clock_adjtime); 15863a766a1SDeepa Dinamani COMPAT_SYS_NI(timer_settime); 15963a766a1SDeepa Dinamani COMPAT_SYS_NI(timer_gettime); 16063a766a1SDeepa Dinamani COMPAT_SYS_NI(getitimer); 16163a766a1SDeepa Dinamani COMPAT_SYS_NI(setitimer); 162b5793b0dSDeepa Dinamani #endif 16363a766a1SDeepa Dinamani 164b5793b0dSDeepa Dinamani #ifdef CONFIG_COMPAT_32BIT_TIME 165d822cdccSAl Viro COMPAT_SYSCALL_DEFINE2(clock_settime, const clockid_t, which_clock, 1669afc5eeeSArnd Bergmann struct old_timespec32 __user *, tp) 167d822cdccSAl Viro { 1685c499410SDeepa Dinamani struct timespec64 new_tp; 169d822cdccSAl Viro 170d822cdccSAl Viro if (which_clock != CLOCK_REALTIME) 171d822cdccSAl Viro return -EINVAL; 1729afc5eeeSArnd Bergmann if (get_old_timespec32(&new_tp, tp)) 173d822cdccSAl Viro return -EFAULT; 174d822cdccSAl Viro 1755c499410SDeepa Dinamani return do_sys_settimeofday64(&new_tp, NULL); 176d822cdccSAl Viro } 177d822cdccSAl Viro 1785c499410SDeepa Dinamani COMPAT_SYSCALL_DEFINE2(clock_gettime, clockid_t, which_clock, 1799afc5eeeSArnd Bergmann struct old_timespec32 __user *, tp) 180d822cdccSAl Viro { 1815c499410SDeepa Dinamani int ret; 1825c499410SDeepa Dinamani struct timespec64 kernel_tp; 183d822cdccSAl Viro 1845c499410SDeepa Dinamani ret = do_clock_gettime(which_clock, &kernel_tp); 1855c499410SDeepa Dinamani if (ret) 1865c499410SDeepa Dinamani return ret; 187d822cdccSAl Viro 1889afc5eeeSArnd Bergmann if (put_old_timespec32(&kernel_tp, tp)) 189d822cdccSAl Viro return -EFAULT; 190d822cdccSAl Viro return 0; 191d822cdccSAl Viro } 192d822cdccSAl Viro 1935c499410SDeepa Dinamani COMPAT_SYSCALL_DEFINE2(clock_getres, clockid_t, which_clock, 1949afc5eeeSArnd Bergmann struct old_timespec32 __user *, tp) 195d822cdccSAl Viro { 1965c499410SDeepa Dinamani struct timespec64 rtn_tp = { 197d822cdccSAl Viro .tv_sec = 0, 198d822cdccSAl Viro .tv_nsec = hrtimer_resolution, 199d822cdccSAl Viro }; 200d822cdccSAl Viro 201d822cdccSAl Viro switch (which_clock) { 202d822cdccSAl Viro case CLOCK_REALTIME: 203d822cdccSAl Viro case CLOCK_MONOTONIC: 204d822cdccSAl Viro case CLOCK_BOOTTIME: 2059afc5eeeSArnd Bergmann if (put_old_timespec32(&rtn_tp, tp)) 206d822cdccSAl Viro return -EFAULT; 207d822cdccSAl Viro return 0; 208d822cdccSAl Viro default: 209d822cdccSAl Viro return -EINVAL; 210d822cdccSAl Viro } 211d822cdccSAl Viro } 2125c499410SDeepa Dinamani 213edbeda46SAl Viro COMPAT_SYSCALL_DEFINE4(clock_nanosleep, clockid_t, which_clock, int, flags, 2149afc5eeeSArnd Bergmann struct old_timespec32 __user *, rqtp, 2159afc5eeeSArnd Bergmann struct old_timespec32 __user *, rmtp) 216baa73d9eSNicolas Pitre { 217fe460423SArnd Bergmann struct timespec64 t; 218edbeda46SAl Viro 219edbeda46SAl Viro switch (which_clock) { 220edbeda46SAl Viro case CLOCK_REALTIME: 221edbeda46SAl Viro case CLOCK_MONOTONIC: 222edbeda46SAl Viro case CLOCK_BOOTTIME: 223edbeda46SAl Viro break; 224edbeda46SAl Viro default: 225edbeda46SAl Viro return -EINVAL; 226edbeda46SAl Viro } 227edbeda46SAl Viro 2289afc5eeeSArnd Bergmann if (get_old_timespec32(&t, rqtp)) 229edbeda46SAl Viro return -EFAULT; 230fe460423SArnd Bergmann if (!timespec64_valid(&t)) 231edbeda46SAl Viro return -EINVAL; 232edbeda46SAl Viro if (flags & TIMER_ABSTIME) 233edbeda46SAl Viro rmtp = NULL; 234edbeda46SAl Viro current->restart_block.nanosleep.type = rmtp ? TT_COMPAT : TT_NONE; 235edbeda46SAl Viro current->restart_block.nanosleep.compat_rmtp = rmtp; 236fe460423SArnd Bergmann return hrtimer_nanosleep(&t, flags & TIMER_ABSTIME ? 237edbeda46SAl Viro HRTIMER_MODE_ABS : HRTIMER_MODE_REL, 238edbeda46SAl Viro which_clock); 239baa73d9eSNicolas Pitre } 240baa73d9eSNicolas Pitre #endif 241