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 default: 87 return -EINVAL; 88 } 89 90 return 0; 91 } 92 SYSCALL_DEFINE2(clock_gettime, const clockid_t, which_clock, 93 struct timespec __user *, tp) 94 { 95 int ret; 96 struct timespec64 kernel_tp; 97 98 ret = do_clock_gettime(which_clock, &kernel_tp); 99 if (ret) 100 return ret; 101 102 if (put_timespec64(&kernel_tp, tp)) 103 return -EFAULT; 104 return 0; 105 } 106 107 SYSCALL_DEFINE2(clock_getres, const clockid_t, which_clock, struct timespec __user *, tp) 108 { 109 struct timespec64 rtn_tp = { 110 .tv_sec = 0, 111 .tv_nsec = hrtimer_resolution, 112 }; 113 114 switch (which_clock) { 115 case CLOCK_REALTIME: 116 case CLOCK_MONOTONIC: 117 case CLOCK_BOOTTIME: 118 if (put_timespec64(&rtn_tp, tp)) 119 return -EFAULT; 120 return 0; 121 default: 122 return -EINVAL; 123 } 124 } 125 126 SYSCALL_DEFINE4(clock_nanosleep, const clockid_t, which_clock, int, flags, 127 const struct timespec __user *, rqtp, 128 struct timespec __user *, rmtp) 129 { 130 struct timespec64 t; 131 132 switch (which_clock) { 133 case CLOCK_REALTIME: 134 case CLOCK_MONOTONIC: 135 case CLOCK_BOOTTIME: 136 break; 137 default: 138 return -EINVAL; 139 } 140 141 if (get_timespec64(&t, rqtp)) 142 return -EFAULT; 143 if (!timespec64_valid(&t)) 144 return -EINVAL; 145 if (flags & TIMER_ABSTIME) 146 rmtp = NULL; 147 current->restart_block.nanosleep.type = rmtp ? TT_NATIVE : TT_NONE; 148 current->restart_block.nanosleep.rmtp = rmtp; 149 return hrtimer_nanosleep(&t, flags & TIMER_ABSTIME ? 150 HRTIMER_MODE_ABS : HRTIMER_MODE_REL, 151 which_clock); 152 } 153 154 #ifdef CONFIG_COMPAT 155 COMPAT_SYS_NI(timer_create); 156 COMPAT_SYS_NI(clock_adjtime); 157 COMPAT_SYS_NI(timer_settime); 158 COMPAT_SYS_NI(timer_gettime); 159 COMPAT_SYS_NI(getitimer); 160 COMPAT_SYS_NI(setitimer); 161 162 COMPAT_SYSCALL_DEFINE2(clock_settime, const clockid_t, which_clock, 163 struct compat_timespec __user *, tp) 164 { 165 struct timespec64 new_tp; 166 167 if (which_clock != CLOCK_REALTIME) 168 return -EINVAL; 169 if (compat_get_timespec64(&new_tp, tp)) 170 return -EFAULT; 171 172 return do_sys_settimeofday64(&new_tp, NULL); 173 } 174 175 COMPAT_SYSCALL_DEFINE2(clock_gettime, clockid_t, which_clock, 176 struct compat_timespec __user *, tp) 177 { 178 int ret; 179 struct timespec64 kernel_tp; 180 181 ret = do_clock_gettime(which_clock, &kernel_tp); 182 if (ret) 183 return ret; 184 185 if (compat_put_timespec64(&kernel_tp, tp)) 186 return -EFAULT; 187 return 0; 188 } 189 190 COMPAT_SYSCALL_DEFINE2(clock_getres, clockid_t, which_clock, 191 struct compat_timespec __user *, tp) 192 { 193 struct timespec64 rtn_tp = { 194 .tv_sec = 0, 195 .tv_nsec = hrtimer_resolution, 196 }; 197 198 switch (which_clock) { 199 case CLOCK_REALTIME: 200 case CLOCK_MONOTONIC: 201 case CLOCK_BOOTTIME: 202 if (compat_put_timespec64(&rtn_tp, tp)) 203 return -EFAULT; 204 return 0; 205 default: 206 return -EINVAL; 207 } 208 } 209 210 COMPAT_SYSCALL_DEFINE4(clock_nanosleep, clockid_t, which_clock, int, flags, 211 struct compat_timespec __user *, rqtp, 212 struct compat_timespec __user *, rmtp) 213 { 214 struct timespec64 t; 215 216 switch (which_clock) { 217 case CLOCK_REALTIME: 218 case CLOCK_MONOTONIC: 219 case CLOCK_BOOTTIME: 220 break; 221 default: 222 return -EINVAL; 223 } 224 225 if (compat_get_timespec64(&t, rqtp)) 226 return -EFAULT; 227 if (!timespec64_valid(&t)) 228 return -EINVAL; 229 if (flags & TIMER_ABSTIME) 230 rmtp = NULL; 231 current->restart_block.nanosleep.type = rmtp ? TT_COMPAT : TT_NONE; 232 current->restart_block.nanosleep.compat_rmtp = rmtp; 233 return hrtimer_nanosleep(&t, flags & TIMER_ABSTIME ? 234 HRTIMER_MODE_ABS : HRTIMER_MODE_REL, 235 which_clock); 236 } 237 #endif 238