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 25 asmlinkage 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 41 SYS_NI(timer_create); 42 SYS_NI(timer_gettime); 43 SYS_NI(timer_getoverrun); 44 SYS_NI(timer_settime); 45 SYS_NI(timer_delete); 46 SYS_NI(clock_adjtime); 47 SYS_NI(getitimer); 48 SYS_NI(setitimer); 49 SYS_NI(clock_adjtime32); 50 #ifdef __ARCH_WANT_SYS_ALARM 51 SYS_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 60 SYSCALL_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 73 static int 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 } 93 94 SYSCALL_DEFINE2(clock_gettime, const clockid_t, which_clock, 95 struct __kernel_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 __kernel_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 __kernel_timespec __user *, rqtp, 130 struct __kernel_timespec __user *, rmtp) 131 { 132 struct timespec64 t; 133 ktime_t texp; 134 135 switch (which_clock) { 136 case CLOCK_REALTIME: 137 case CLOCK_MONOTONIC: 138 case CLOCK_BOOTTIME: 139 break; 140 default: 141 return -EINVAL; 142 } 143 144 if (get_timespec64(&t, rqtp)) 145 return -EFAULT; 146 if (!timespec64_valid(&t)) 147 return -EINVAL; 148 if (flags & TIMER_ABSTIME) 149 rmtp = NULL; 150 current->restart_block.nanosleep.type = rmtp ? TT_NATIVE : TT_NONE; 151 current->restart_block.nanosleep.rmtp = rmtp; 152 texp = timespec64_to_ktime(t); 153 if (flags & TIMER_ABSTIME) 154 texp = timens_ktime_to_host(which_clock, texp); 155 return hrtimer_nanosleep(texp, flags & TIMER_ABSTIME ? 156 HRTIMER_MODE_ABS : HRTIMER_MODE_REL, 157 which_clock); 158 } 159 160 #ifdef CONFIG_COMPAT 161 COMPAT_SYS_NI(timer_create); 162 #endif 163 164 #if defined(CONFIG_COMPAT) || defined(CONFIG_ALPHA) 165 COMPAT_SYS_NI(getitimer); 166 COMPAT_SYS_NI(setitimer); 167 #endif 168 169 #ifdef CONFIG_COMPAT_32BIT_TIME 170 SYS_NI(timer_settime32); 171 SYS_NI(timer_gettime32); 172 173 SYSCALL_DEFINE2(clock_settime32, const clockid_t, which_clock, 174 struct old_timespec32 __user *, tp) 175 { 176 struct timespec64 new_tp; 177 178 if (which_clock != CLOCK_REALTIME) 179 return -EINVAL; 180 if (get_old_timespec32(&new_tp, tp)) 181 return -EFAULT; 182 183 return do_sys_settimeofday64(&new_tp, NULL); 184 } 185 186 SYSCALL_DEFINE2(clock_gettime32, clockid_t, which_clock, 187 struct old_timespec32 __user *, tp) 188 { 189 int ret; 190 struct timespec64 kernel_tp; 191 192 ret = do_clock_gettime(which_clock, &kernel_tp); 193 if (ret) 194 return ret; 195 196 if (put_old_timespec32(&kernel_tp, tp)) 197 return -EFAULT; 198 return 0; 199 } 200 201 SYSCALL_DEFINE2(clock_getres_time32, clockid_t, which_clock, 202 struct old_timespec32 __user *, tp) 203 { 204 struct timespec64 rtn_tp = { 205 .tv_sec = 0, 206 .tv_nsec = hrtimer_resolution, 207 }; 208 209 switch (which_clock) { 210 case CLOCK_REALTIME: 211 case CLOCK_MONOTONIC: 212 case CLOCK_BOOTTIME: 213 if (put_old_timespec32(&rtn_tp, tp)) 214 return -EFAULT; 215 return 0; 216 default: 217 return -EINVAL; 218 } 219 } 220 221 SYSCALL_DEFINE4(clock_nanosleep_time32, clockid_t, which_clock, int, flags, 222 struct old_timespec32 __user *, rqtp, 223 struct old_timespec32 __user *, rmtp) 224 { 225 struct timespec64 t; 226 ktime_t texp; 227 228 switch (which_clock) { 229 case CLOCK_REALTIME: 230 case CLOCK_MONOTONIC: 231 case CLOCK_BOOTTIME: 232 break; 233 default: 234 return -EINVAL; 235 } 236 237 if (get_old_timespec32(&t, rqtp)) 238 return -EFAULT; 239 if (!timespec64_valid(&t)) 240 return -EINVAL; 241 if (flags & TIMER_ABSTIME) 242 rmtp = NULL; 243 current->restart_block.nanosleep.type = rmtp ? TT_COMPAT : TT_NONE; 244 current->restart_block.nanosleep.compat_rmtp = rmtp; 245 texp = timespec64_to_ktime(t); 246 if (flags & TIMER_ABSTIME) 247 texp = timens_ktime_to_host(which_clock, texp); 248 return hrtimer_nanosleep(texp, flags & TIMER_ABSTIME ? 249 HRTIMER_MODE_ABS : HRTIMER_MODE_REL, 250 which_clock); 251 } 252 #endif 253