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 21 asmlinkage long sys_ni_posix_timers(void) 22 { 23 pr_err_once("process %d (%s) attempted a POSIX timer syscall " 24 "while CONFIG_POSIX_TIMERS is not set\n", 25 current->pid, current->comm); 26 return -ENOSYS; 27 } 28 29 #define SYS_NI(name) SYSCALL_ALIAS(sys_##name, sys_ni_posix_timers) 30 31 SYS_NI(timer_create); 32 SYS_NI(timer_gettime); 33 SYS_NI(timer_getoverrun); 34 SYS_NI(timer_settime); 35 SYS_NI(timer_delete); 36 SYS_NI(clock_adjtime); 37 SYS_NI(getitimer); 38 SYS_NI(setitimer); 39 #ifdef __ARCH_WANT_SYS_ALARM 40 SYS_NI(alarm); 41 #endif 42 43 /* 44 * We preserve minimal support for CLOCK_REALTIME and CLOCK_MONOTONIC 45 * as it is easy to remain compatible with little code. CLOCK_BOOTTIME 46 * is also included for convenience as at least systemd uses it. 47 */ 48 49 SYSCALL_DEFINE2(clock_settime, const clockid_t, which_clock, 50 const struct timespec __user *, tp) 51 { 52 struct timespec new_tp; 53 54 if (which_clock != CLOCK_REALTIME) 55 return -EINVAL; 56 if (copy_from_user(&new_tp, tp, sizeof (*tp))) 57 return -EFAULT; 58 return do_sys_settimeofday(&new_tp, NULL); 59 } 60 61 SYSCALL_DEFINE2(clock_gettime, const clockid_t, which_clock, 62 struct timespec __user *,tp) 63 { 64 struct timespec kernel_tp; 65 66 switch (which_clock) { 67 case CLOCK_REALTIME: ktime_get_real_ts(&kernel_tp); break; 68 case CLOCK_MONOTONIC: ktime_get_ts(&kernel_tp); break; 69 case CLOCK_BOOTTIME: get_monotonic_boottime(&kernel_tp); break; 70 default: return -EINVAL; 71 } 72 if (copy_to_user(tp, &kernel_tp, sizeof (kernel_tp))) 73 return -EFAULT; 74 return 0; 75 } 76 77 SYSCALL_DEFINE2(clock_getres, const clockid_t, which_clock, struct timespec __user *, tp) 78 { 79 struct timespec rtn_tp = { 80 .tv_sec = 0, 81 .tv_nsec = hrtimer_resolution, 82 }; 83 84 switch (which_clock) { 85 case CLOCK_REALTIME: 86 case CLOCK_MONOTONIC: 87 case CLOCK_BOOTTIME: 88 if (copy_to_user(tp, &rtn_tp, sizeof(rtn_tp))) 89 return -EFAULT; 90 return 0; 91 default: 92 return -EINVAL; 93 } 94 } 95 96 SYSCALL_DEFINE4(clock_nanosleep, const clockid_t, which_clock, int, flags, 97 const struct timespec __user *, rqtp, 98 struct timespec __user *, rmtp) 99 { 100 struct timespec t; 101 102 switch (which_clock) { 103 case CLOCK_REALTIME: 104 case CLOCK_MONOTONIC: 105 case CLOCK_BOOTTIME: 106 if (copy_from_user(&t, rqtp, sizeof (struct timespec))) 107 return -EFAULT; 108 if (!timespec_valid(&t)) 109 return -EINVAL; 110 return hrtimer_nanosleep(&t, rmtp, flags & TIMER_ABSTIME ? 111 HRTIMER_MODE_ABS : HRTIMER_MODE_REL, 112 which_clock); 113 default: 114 return -EINVAL; 115 } 116 } 117 118 #ifdef CONFIG_COMPAT 119 long clock_nanosleep_restart(struct restart_block *restart_block) 120 { 121 return hrtimer_nanosleep_restart(restart_block); 122 } 123 #endif 124