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 timespec64 new_tp64; 53 struct timespec new_tp; 54 55 if (which_clock != CLOCK_REALTIME) 56 return -EINVAL; 57 if (copy_from_user(&new_tp, tp, sizeof (*tp))) 58 return -EFAULT; 59 60 new_tp64 = timespec_to_timespec64(new_tp); 61 return do_sys_settimeofday64(&new_tp64, NULL); 62 } 63 64 SYSCALL_DEFINE2(clock_gettime, const clockid_t, which_clock, 65 struct timespec __user *,tp) 66 { 67 struct timespec64 kernel_tp64; 68 struct timespec kernel_tp; 69 70 switch (which_clock) { 71 case CLOCK_REALTIME: ktime_get_real_ts64(&kernel_tp64); break; 72 case CLOCK_MONOTONIC: ktime_get_ts64(&kernel_tp64); break; 73 case CLOCK_BOOTTIME: get_monotonic_boottime64(&kernel_tp64); break; 74 default: return -EINVAL; 75 } 76 77 kernel_tp = timespec64_to_timespec(kernel_tp64); 78 if (copy_to_user(tp, &kernel_tp, sizeof (kernel_tp))) 79 return -EFAULT; 80 return 0; 81 } 82 83 SYSCALL_DEFINE2(clock_getres, const clockid_t, which_clock, struct timespec __user *, tp) 84 { 85 struct timespec rtn_tp = { 86 .tv_sec = 0, 87 .tv_nsec = hrtimer_resolution, 88 }; 89 90 switch (which_clock) { 91 case CLOCK_REALTIME: 92 case CLOCK_MONOTONIC: 93 case CLOCK_BOOTTIME: 94 if (copy_to_user(tp, &rtn_tp, sizeof(rtn_tp))) 95 return -EFAULT; 96 return 0; 97 default: 98 return -EINVAL; 99 } 100 } 101 102 SYSCALL_DEFINE4(clock_nanosleep, const clockid_t, which_clock, int, flags, 103 const struct timespec __user *, rqtp, 104 struct timespec __user *, rmtp) 105 { 106 struct timespec64 t64; 107 struct timespec t; 108 109 switch (which_clock) { 110 case CLOCK_REALTIME: 111 case CLOCK_MONOTONIC: 112 case CLOCK_BOOTTIME: 113 if (copy_from_user(&t, rqtp, sizeof (struct timespec))) 114 return -EFAULT; 115 t64 = timespec_to_timespec64(t); 116 if (!timespec64_valid(&t64)) 117 return -EINVAL; 118 return hrtimer_nanosleep(&t64, rmtp, flags & TIMER_ABSTIME ? 119 HRTIMER_MODE_ABS : HRTIMER_MODE_REL, 120 which_clock); 121 default: 122 return -EINVAL; 123 } 124 } 125 126 #ifdef CONFIG_COMPAT 127 long clock_nanosleep_restart(struct restart_block *restart_block) 128 { 129 return hrtimer_nanosleep_restart(restart_block); 130 } 131 #endif 132