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 asmlinkage long sys_ni_posix_timers(void) 23 { 24 pr_err_once("process %d (%s) attempted a POSIX timer syscall " 25 "while CONFIG_POSIX_TIMERS is not set\n", 26 current->pid, current->comm); 27 return -ENOSYS; 28 } 29 30 #define SYS_NI(name) SYSCALL_ALIAS(sys_##name, sys_ni_posix_timers) 31 #define COMPAT_SYS_NI(name) SYSCALL_ALIAS(compat_sys_##name, sys_ni_posix_timers) 32 33 SYS_NI(timer_create); 34 SYS_NI(timer_gettime); 35 SYS_NI(timer_getoverrun); 36 SYS_NI(timer_settime); 37 SYS_NI(timer_delete); 38 SYS_NI(clock_adjtime); 39 SYS_NI(getitimer); 40 SYS_NI(setitimer); 41 #ifdef __ARCH_WANT_SYS_ALARM 42 SYS_NI(alarm); 43 #endif 44 45 /* 46 * We preserve minimal support for CLOCK_REALTIME and CLOCK_MONOTONIC 47 * as it is easy to remain compatible with little code. CLOCK_BOOTTIME 48 * is also included for convenience as at least systemd uses it. 49 */ 50 51 SYSCALL_DEFINE2(clock_settime, const clockid_t, which_clock, 52 const struct timespec __user *, tp) 53 { 54 struct timespec64 new_tp; 55 56 if (which_clock != CLOCK_REALTIME) 57 return -EINVAL; 58 if (get_timespec64(&new_tp, tp)) 59 return -EFAULT; 60 61 return do_sys_settimeofday64(&new_tp, NULL); 62 } 63 64 int do_clock_gettime(clockid_t which_clock, struct timespec64 *tp) 65 { 66 switch (which_clock) { 67 case CLOCK_REALTIME: 68 ktime_get_real_ts64(tp); 69 break; 70 case CLOCK_MONOTONIC: 71 ktime_get_ts64(tp); 72 break; 73 case CLOCK_BOOTTIME: 74 get_monotonic_boottime64(tp); 75 break; 76 case CLOCK_MONOTONIC_ACTIVE: 77 ktime_get_active_ts64(tp); 78 default: 79 return -EINVAL; 80 } 81 82 return 0; 83 } 84 SYSCALL_DEFINE2(clock_gettime, const clockid_t, which_clock, 85 struct timespec __user *, tp) 86 { 87 int ret; 88 struct timespec64 kernel_tp; 89 90 ret = do_clock_gettime(which_clock, &kernel_tp); 91 if (ret) 92 return ret; 93 94 if (put_timespec64(&kernel_tp, tp)) 95 return -EFAULT; 96 return 0; 97 } 98 99 SYSCALL_DEFINE2(clock_getres, const clockid_t, which_clock, struct timespec __user *, tp) 100 { 101 struct timespec64 rtn_tp = { 102 .tv_sec = 0, 103 .tv_nsec = hrtimer_resolution, 104 }; 105 106 switch (which_clock) { 107 case CLOCK_REALTIME: 108 case CLOCK_MONOTONIC: 109 case CLOCK_BOOTTIME: 110 if (put_timespec64(&rtn_tp, tp)) 111 return -EFAULT; 112 return 0; 113 default: 114 return -EINVAL; 115 } 116 } 117 118 SYSCALL_DEFINE4(clock_nanosleep, const clockid_t, which_clock, int, flags, 119 const struct timespec __user *, rqtp, 120 struct timespec __user *, rmtp) 121 { 122 struct timespec64 t; 123 124 switch (which_clock) { 125 case CLOCK_REALTIME: 126 case CLOCK_MONOTONIC: 127 case CLOCK_BOOTTIME: 128 break; 129 default: 130 return -EINVAL; 131 } 132 133 if (get_timespec64(&t, rqtp)) 134 return -EFAULT; 135 if (!timespec64_valid(&t)) 136 return -EINVAL; 137 if (flags & TIMER_ABSTIME) 138 rmtp = NULL; 139 current->restart_block.nanosleep.type = rmtp ? TT_NATIVE : TT_NONE; 140 current->restart_block.nanosleep.rmtp = rmtp; 141 return hrtimer_nanosleep(&t, flags & TIMER_ABSTIME ? 142 HRTIMER_MODE_ABS : HRTIMER_MODE_REL, 143 which_clock); 144 } 145 146 #ifdef CONFIG_COMPAT 147 COMPAT_SYS_NI(timer_create); 148 COMPAT_SYS_NI(clock_adjtime); 149 COMPAT_SYS_NI(timer_settime); 150 COMPAT_SYS_NI(timer_gettime); 151 COMPAT_SYS_NI(getitimer); 152 COMPAT_SYS_NI(setitimer); 153 154 COMPAT_SYSCALL_DEFINE2(clock_settime, const clockid_t, which_clock, 155 struct compat_timespec __user *, tp) 156 { 157 struct timespec64 new_tp; 158 159 if (which_clock != CLOCK_REALTIME) 160 return -EINVAL; 161 if (compat_get_timespec64(&new_tp, tp)) 162 return -EFAULT; 163 164 return do_sys_settimeofday64(&new_tp, NULL); 165 } 166 167 COMPAT_SYSCALL_DEFINE2(clock_gettime, clockid_t, which_clock, 168 struct compat_timespec __user *, tp) 169 { 170 int ret; 171 struct timespec64 kernel_tp; 172 173 ret = do_clock_gettime(which_clock, &kernel_tp); 174 if (ret) 175 return ret; 176 177 if (compat_put_timespec64(&kernel_tp, tp)) 178 return -EFAULT; 179 return 0; 180 } 181 182 COMPAT_SYSCALL_DEFINE2(clock_getres, clockid_t, which_clock, 183 struct compat_timespec __user *, tp) 184 { 185 struct timespec64 rtn_tp = { 186 .tv_sec = 0, 187 .tv_nsec = hrtimer_resolution, 188 }; 189 190 switch (which_clock) { 191 case CLOCK_REALTIME: 192 case CLOCK_MONOTONIC: 193 case CLOCK_BOOTTIME: 194 if (compat_put_timespec64(&rtn_tp, tp)) 195 return -EFAULT; 196 return 0; 197 default: 198 return -EINVAL; 199 } 200 } 201 202 COMPAT_SYSCALL_DEFINE4(clock_nanosleep, clockid_t, which_clock, int, flags, 203 struct compat_timespec __user *, rqtp, 204 struct compat_timespec __user *, rmtp) 205 { 206 struct timespec64 t; 207 208 switch (which_clock) { 209 case CLOCK_REALTIME: 210 case CLOCK_MONOTONIC: 211 case CLOCK_BOOTTIME: 212 break; 213 default: 214 return -EINVAL; 215 } 216 217 if (compat_get_timespec64(&t, rqtp)) 218 return -EFAULT; 219 if (!timespec64_valid(&t)) 220 return -EINVAL; 221 if (flags & TIMER_ABSTIME) 222 rmtp = NULL; 223 current->restart_block.nanosleep.type = rmtp ? TT_COMPAT : TT_NONE; 224 current->restart_block.nanosleep.compat_rmtp = rmtp; 225 return hrtimer_nanosleep(&t, flags & TIMER_ABSTIME ? 226 HRTIMER_MODE_ABS : HRTIMER_MODE_REL, 227 which_clock); 228 } 229 #endif 230