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 t; 121 122 switch (which_clock) { 123 case CLOCK_REALTIME: 124 case CLOCK_MONOTONIC: 125 case CLOCK_BOOTTIME: 126 break; 127 default: 128 return -EINVAL; 129 } 130 131 if (get_timespec64(&t, rqtp)) 132 return -EFAULT; 133 if (!timespec64_valid(&t)) 134 return -EINVAL; 135 if (flags & TIMER_ABSTIME) 136 rmtp = NULL; 137 current->restart_block.nanosleep.type = rmtp ? TT_NATIVE : TT_NONE; 138 current->restart_block.nanosleep.rmtp = rmtp; 139 return hrtimer_nanosleep(&t, flags & TIMER_ABSTIME ? 140 HRTIMER_MODE_ABS : HRTIMER_MODE_REL, 141 which_clock); 142 } 143 144 #ifdef CONFIG_COMPAT 145 COMPAT_SYS_NI(timer_create); 146 COMPAT_SYS_NI(clock_adjtime); 147 COMPAT_SYS_NI(timer_settime); 148 COMPAT_SYS_NI(timer_gettime); 149 COMPAT_SYS_NI(getitimer); 150 COMPAT_SYS_NI(setitimer); 151 152 COMPAT_SYSCALL_DEFINE2(clock_settime, const clockid_t, which_clock, 153 struct compat_timespec __user *, tp) 154 { 155 struct timespec64 new_tp; 156 157 if (which_clock != CLOCK_REALTIME) 158 return -EINVAL; 159 if (compat_get_timespec64(&new_tp, tp)) 160 return -EFAULT; 161 162 return do_sys_settimeofday64(&new_tp, NULL); 163 } 164 165 COMPAT_SYSCALL_DEFINE2(clock_gettime, clockid_t, which_clock, 166 struct compat_timespec __user *, tp) 167 { 168 int ret; 169 struct timespec64 kernel_tp; 170 171 ret = do_clock_gettime(which_clock, &kernel_tp); 172 if (ret) 173 return ret; 174 175 if (compat_put_timespec64(&kernel_tp, tp)) 176 return -EFAULT; 177 return 0; 178 } 179 180 COMPAT_SYSCALL_DEFINE2(clock_getres, clockid_t, which_clock, 181 struct compat_timespec __user *, tp) 182 { 183 struct timespec64 rtn_tp = { 184 .tv_sec = 0, 185 .tv_nsec = hrtimer_resolution, 186 }; 187 188 switch (which_clock) { 189 case CLOCK_REALTIME: 190 case CLOCK_MONOTONIC: 191 case CLOCK_BOOTTIME: 192 if (compat_put_timespec64(&rtn_tp, tp)) 193 return -EFAULT; 194 return 0; 195 default: 196 return -EINVAL; 197 } 198 } 199 200 COMPAT_SYSCALL_DEFINE4(clock_nanosleep, clockid_t, which_clock, int, flags, 201 struct compat_timespec __user *, rqtp, 202 struct compat_timespec __user *, rmtp) 203 { 204 struct timespec64 t; 205 206 switch (which_clock) { 207 case CLOCK_REALTIME: 208 case CLOCK_MONOTONIC: 209 case CLOCK_BOOTTIME: 210 break; 211 default: 212 return -EINVAL; 213 } 214 215 if (compat_get_timespec64(&t, rqtp)) 216 return -EFAULT; 217 if (!timespec64_valid(&t)) 218 return -EINVAL; 219 if (flags & TIMER_ABSTIME) 220 rmtp = NULL; 221 current->restart_block.nanosleep.type = rmtp ? TT_COMPAT : TT_NONE; 222 current->restart_block.nanosleep.compat_rmtp = rmtp; 223 return hrtimer_nanosleep(&t, flags & TIMER_ABSTIME ? 224 HRTIMER_MODE_ABS : HRTIMER_MODE_REL, 225 which_clock); 226 } 227 #endif 228