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 default: 77 return -EINVAL; 78 } 79 80 return 0; 81 } 82 SYSCALL_DEFINE2(clock_gettime, const clockid_t, which_clock, 83 struct timespec __user *, tp) 84 { 85 int ret; 86 struct timespec64 kernel_tp; 87 88 ret = do_clock_gettime(which_clock, &kernel_tp); 89 if (ret) 90 return ret; 91 92 if (put_timespec64(&kernel_tp, tp)) 93 return -EFAULT; 94 return 0; 95 } 96 97 SYSCALL_DEFINE2(clock_getres, const clockid_t, which_clock, struct timespec __user *, tp) 98 { 99 struct timespec64 rtn_tp = { 100 .tv_sec = 0, 101 .tv_nsec = hrtimer_resolution, 102 }; 103 104 switch (which_clock) { 105 case CLOCK_REALTIME: 106 case CLOCK_MONOTONIC: 107 case CLOCK_BOOTTIME: 108 if (put_timespec64(&rtn_tp, tp)) 109 return -EFAULT; 110 return 0; 111 default: 112 return -EINVAL; 113 } 114 } 115 116 SYSCALL_DEFINE4(clock_nanosleep, const clockid_t, which_clock, int, flags, 117 const struct timespec __user *, rqtp, 118 struct timespec __user *, rmtp) 119 { 120 struct timespec64 t64; 121 struct timespec t; 122 123 switch (which_clock) { 124 case CLOCK_REALTIME: 125 case CLOCK_MONOTONIC: 126 case CLOCK_BOOTTIME: 127 break; 128 default: 129 return -EINVAL; 130 } 131 132 if (copy_from_user(&t, rqtp, sizeof (struct timespec))) 133 return -EFAULT; 134 t64 = timespec_to_timespec64(t); 135 if (!timespec64_valid(&t64)) 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(&t64, 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 t64; 207 struct timespec t; 208 209 switch (which_clock) { 210 case CLOCK_REALTIME: 211 case CLOCK_MONOTONIC: 212 case CLOCK_BOOTTIME: 213 break; 214 default: 215 return -EINVAL; 216 } 217 218 if (compat_get_timespec(&t, rqtp)) 219 return -EFAULT; 220 t64 = timespec_to_timespec64(t); 221 if (!timespec64_valid(&t64)) 222 return -EINVAL; 223 if (flags & TIMER_ABSTIME) 224 rmtp = NULL; 225 current->restart_block.nanosleep.type = rmtp ? TT_COMPAT : TT_NONE; 226 current->restart_block.nanosleep.compat_rmtp = rmtp; 227 return hrtimer_nanosleep(&t64, flags & TIMER_ABSTIME ? 228 HRTIMER_MODE_ABS : HRTIMER_MODE_REL, 229 which_clock); 230 } 231 #endif 232