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 __kernel_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 ktime_get_boottime_ts64(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 __kernel_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 __kernel_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 __kernel_timespec __user *, rqtp, 128 struct __kernel_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 #endif 162 163 #ifdef CONFIG_COMPAT_32BIT_TIME 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