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.fn = do_no_restart_syscall; 151 current->restart_block.nanosleep.type = rmtp ? TT_NATIVE : TT_NONE; 152 current->restart_block.nanosleep.rmtp = rmtp; 153 texp = timespec64_to_ktime(t); 154 if (flags & TIMER_ABSTIME) 155 texp = timens_ktime_to_host(which_clock, texp); 156 return hrtimer_nanosleep(texp, flags & TIMER_ABSTIME ? 157 HRTIMER_MODE_ABS : HRTIMER_MODE_REL, 158 which_clock); 159 } 160 161 #ifdef CONFIG_COMPAT 162 COMPAT_SYS_NI(timer_create); 163 #endif 164 165 #if defined(CONFIG_COMPAT) || defined(CONFIG_ALPHA) 166 COMPAT_SYS_NI(getitimer); 167 COMPAT_SYS_NI(setitimer); 168 #endif 169 170 #ifdef CONFIG_COMPAT_32BIT_TIME 171 SYS_NI(timer_settime32); 172 SYS_NI(timer_gettime32); 173 174 SYSCALL_DEFINE2(clock_settime32, const clockid_t, which_clock, 175 struct old_timespec32 __user *, tp) 176 { 177 struct timespec64 new_tp; 178 179 if (which_clock != CLOCK_REALTIME) 180 return -EINVAL; 181 if (get_old_timespec32(&new_tp, tp)) 182 return -EFAULT; 183 184 return do_sys_settimeofday64(&new_tp, NULL); 185 } 186 187 SYSCALL_DEFINE2(clock_gettime32, clockid_t, which_clock, 188 struct old_timespec32 __user *, tp) 189 { 190 int ret; 191 struct timespec64 kernel_tp; 192 193 ret = do_clock_gettime(which_clock, &kernel_tp); 194 if (ret) 195 return ret; 196 197 if (put_old_timespec32(&kernel_tp, tp)) 198 return -EFAULT; 199 return 0; 200 } 201 202 SYSCALL_DEFINE2(clock_getres_time32, clockid_t, which_clock, 203 struct old_timespec32 __user *, tp) 204 { 205 struct timespec64 rtn_tp = { 206 .tv_sec = 0, 207 .tv_nsec = hrtimer_resolution, 208 }; 209 210 switch (which_clock) { 211 case CLOCK_REALTIME: 212 case CLOCK_MONOTONIC: 213 case CLOCK_BOOTTIME: 214 if (put_old_timespec32(&rtn_tp, tp)) 215 return -EFAULT; 216 return 0; 217 default: 218 return -EINVAL; 219 } 220 } 221 222 SYSCALL_DEFINE4(clock_nanosleep_time32, clockid_t, which_clock, int, flags, 223 struct old_timespec32 __user *, rqtp, 224 struct old_timespec32 __user *, rmtp) 225 { 226 struct timespec64 t; 227 ktime_t texp; 228 229 switch (which_clock) { 230 case CLOCK_REALTIME: 231 case CLOCK_MONOTONIC: 232 case CLOCK_BOOTTIME: 233 break; 234 default: 235 return -EINVAL; 236 } 237 238 if (get_old_timespec32(&t, rqtp)) 239 return -EFAULT; 240 if (!timespec64_valid(&t)) 241 return -EINVAL; 242 if (flags & TIMER_ABSTIME) 243 rmtp = NULL; 244 current->restart_block.fn = do_no_restart_syscall; 245 current->restart_block.nanosleep.type = rmtp ? TT_COMPAT : TT_NONE; 246 current->restart_block.nanosleep.compat_rmtp = rmtp; 247 texp = timespec64_to_ktime(t); 248 if (flags & TIMER_ABSTIME) 249 texp = timens_ktime_to_host(which_clock, texp); 250 return hrtimer_nanosleep(texp, flags & TIMER_ABSTIME ? 251 HRTIMER_MODE_ABS : HRTIMER_MODE_REL, 252 which_clock); 253 } 254 #endif 255