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