blob: 4e76021cea7f3c543283f0e9d58f4ca54808ef9c [file] [log] [blame]
Nicolas Pitrebaa73d92016-11-11 00:10:10 -05001/*
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>
Al Viroedbeda42017-06-07 09:42:31 +010020#include <linux/compat.h>
Nicolas Pitrebaa73d92016-11-11 00:10:10 -050021
Dominik Brodowski7303e302018-04-05 11:53:03 +020022#ifdef CONFIG_ARCH_HAS_SYSCALL_WRAPPER
23/* Architectures may override SYS_NI and COMPAT_SYS_NI */
24#include <asm/syscall_wrapper.h>
25#endif
26
Nicolas Pitrebaa73d92016-11-11 00:10:10 -050027asmlinkage long sys_ni_posix_timers(void)
28{
29 pr_err_once("process %d (%s) attempted a POSIX timer syscall "
30 "while CONFIG_POSIX_TIMERS is not set\n",
31 current->pid, current->comm);
32 return -ENOSYS;
33}
34
Dominik Brodowski7303e302018-04-05 11:53:03 +020035#ifndef SYS_NI
Nicolas Pitrebaa73d92016-11-11 00:10:10 -050036#define SYS_NI(name) SYSCALL_ALIAS(sys_##name, sys_ni_posix_timers)
Dominik Brodowski7303e302018-04-05 11:53:03 +020037#endif
38
39#ifndef COMPAT_SYS_NI
Al Viro3a4d44b2017-06-07 09:42:34 +010040#define COMPAT_SYS_NI(name) SYSCALL_ALIAS(compat_sys_##name, sys_ni_posix_timers)
Dominik Brodowski7303e302018-04-05 11:53:03 +020041#endif
Nicolas Pitrebaa73d92016-11-11 00:10:10 -050042
43SYS_NI(timer_create);
44SYS_NI(timer_gettime);
45SYS_NI(timer_getoverrun);
46SYS_NI(timer_settime);
47SYS_NI(timer_delete);
48SYS_NI(clock_adjtime);
49SYS_NI(getitimer);
50SYS_NI(setitimer);
51#ifdef __ARCH_WANT_SYS_ALARM
52SYS_NI(alarm);
53#endif
54
55/*
56 * We preserve minimal support for CLOCK_REALTIME and CLOCK_MONOTONIC
57 * as it is easy to remain compatible with little code. CLOCK_BOOTTIME
58 * is also included for convenience as at least systemd uses it.
59 */
60
61SYSCALL_DEFINE2(clock_settime, const clockid_t, which_clock,
Deepa Dinamani6d5b8412018-03-13 21:03:32 -070062 const struct __kernel_timespec __user *, tp)
Nicolas Pitrebaa73d92016-11-11 00:10:10 -050063{
Deepa Dinamani5c499412017-06-24 11:45:05 -070064 struct timespec64 new_tp;
Nicolas Pitrebaa73d92016-11-11 00:10:10 -050065
66 if (which_clock != CLOCK_REALTIME)
67 return -EINVAL;
Deepa Dinamani5c499412017-06-24 11:45:05 -070068 if (get_timespec64(&new_tp, tp))
Nicolas Pitrebaa73d92016-11-11 00:10:10 -050069 return -EFAULT;
Deepa Dinamani2ac00f12017-03-26 12:04:12 -070070
Deepa Dinamani5c499412017-06-24 11:45:05 -070071 return do_sys_settimeofday64(&new_tp, NULL);
Nicolas Pitrebaa73d92016-11-11 00:10:10 -050072}
73
Deepa Dinamani5c499412017-06-24 11:45:05 -070074int do_clock_gettime(clockid_t which_clock, struct timespec64 *tp)
Nicolas Pitrebaa73d92016-11-11 00:10:10 -050075{
Nicolas Pitrebaa73d92016-11-11 00:10:10 -050076 switch (which_clock) {
Deepa Dinamani5c499412017-06-24 11:45:05 -070077 case CLOCK_REALTIME:
78 ktime_get_real_ts64(tp);
79 break;
80 case CLOCK_MONOTONIC:
81 ktime_get_ts64(tp);
82 break;
83 case CLOCK_BOOTTIME:
84 get_monotonic_boottime64(tp);
85 break;
Thomas Gleixner72199322018-03-01 17:33:32 +010086 case CLOCK_MONOTONIC_ACTIVE:
87 ktime_get_active_ts64(tp);
Deepa Dinamani5c499412017-06-24 11:45:05 -070088 default:
89 return -EINVAL;
Nicolas Pitrebaa73d92016-11-11 00:10:10 -050090 }
Deepa Dinamani3c9c12f2017-03-26 12:04:14 -070091
Deepa Dinamani5c499412017-06-24 11:45:05 -070092 return 0;
93}
94SYSCALL_DEFINE2(clock_gettime, const clockid_t, which_clock,
Deepa Dinamani6d5b8412018-03-13 21:03:32 -070095 struct __kernel_timespec __user *, tp)
Deepa Dinamani5c499412017-06-24 11:45:05 -070096{
97 int ret;
98 struct timespec64 kernel_tp;
99
100 ret = do_clock_gettime(which_clock, &kernel_tp);
101 if (ret)
102 return ret;
103
104 if (put_timespec64(&kernel_tp, tp))
Nicolas Pitrebaa73d92016-11-11 00:10:10 -0500105 return -EFAULT;
106 return 0;
107}
108
Deepa Dinamani6d5b8412018-03-13 21:03:32 -0700109SYSCALL_DEFINE2(clock_getres, const clockid_t, which_clock, struct __kernel_timespec __user *, tp)
Nicolas Pitrebaa73d92016-11-11 00:10:10 -0500110{
Deepa Dinamani5c499412017-06-24 11:45:05 -0700111 struct timespec64 rtn_tp = {
Nicolas Pitrebaa73d92016-11-11 00:10:10 -0500112 .tv_sec = 0,
113 .tv_nsec = hrtimer_resolution,
114 };
115
116 switch (which_clock) {
117 case CLOCK_REALTIME:
118 case CLOCK_MONOTONIC:
119 case CLOCK_BOOTTIME:
Deepa Dinamani5c499412017-06-24 11:45:05 -0700120 if (put_timespec64(&rtn_tp, tp))
Nicolas Pitrebaa73d92016-11-11 00:10:10 -0500121 return -EFAULT;
122 return 0;
123 default:
124 return -EINVAL;
125 }
126}
127
128SYSCALL_DEFINE4(clock_nanosleep, const clockid_t, which_clock, int, flags,
129 const struct timespec __user *, rqtp,
130 struct timespec __user *, rmtp)
131{
Arnd Bergmannfe460422017-10-13 20:29:38 +0200132 struct timespec64 t;
Nicolas Pitrebaa73d92016-11-11 00:10:10 -0500133
134 switch (which_clock) {
135 case CLOCK_REALTIME:
136 case CLOCK_MONOTONIC:
137 case CLOCK_BOOTTIME:
Al Viroedbeda42017-06-07 09:42:31 +0100138 break;
Nicolas Pitrebaa73d92016-11-11 00:10:10 -0500139 default:
140 return -EINVAL;
141 }
Al Viroedbeda42017-06-07 09:42:31 +0100142
Arnd Bergmannfe460422017-10-13 20:29:38 +0200143 if (get_timespec64(&t, rqtp))
Al Viroedbeda42017-06-07 09:42:31 +0100144 return -EFAULT;
Arnd Bergmannfe460422017-10-13 20:29:38 +0200145 if (!timespec64_valid(&t))
Al Viroedbeda42017-06-07 09:42:31 +0100146 return -EINVAL;
147 if (flags & TIMER_ABSTIME)
148 rmtp = NULL;
149 current->restart_block.nanosleep.type = rmtp ? TT_NATIVE : TT_NONE;
150 current->restart_block.nanosleep.rmtp = rmtp;
Arnd Bergmannfe460422017-10-13 20:29:38 +0200151 return hrtimer_nanosleep(&t, flags & TIMER_ABSTIME ?
Al Viroedbeda42017-06-07 09:42:31 +0100152 HRTIMER_MODE_ABS : HRTIMER_MODE_REL,
153 which_clock);
Nicolas Pitrebaa73d92016-11-11 00:10:10 -0500154}
155
156#ifdef CONFIG_COMPAT
Deepa Dinamani63a766a2017-06-24 11:45:04 -0700157COMPAT_SYS_NI(timer_create);
158COMPAT_SYS_NI(clock_adjtime);
159COMPAT_SYS_NI(timer_settime);
160COMPAT_SYS_NI(timer_gettime);
161COMPAT_SYS_NI(getitimer);
162COMPAT_SYS_NI(setitimer);
Deepa Dinamanib5793b02018-03-13 21:03:29 -0700163#endif
Deepa Dinamani63a766a2017-06-24 11:45:04 -0700164
Deepa Dinamanib5793b02018-03-13 21:03:29 -0700165#ifdef CONFIG_COMPAT_32BIT_TIME
Al Virod822cdc2017-06-07 09:42:38 +0100166COMPAT_SYSCALL_DEFINE2(clock_settime, const clockid_t, which_clock,
167 struct compat_timespec __user *, tp)
168{
Deepa Dinamani5c499412017-06-24 11:45:05 -0700169 struct timespec64 new_tp;
Al Virod822cdc2017-06-07 09:42:38 +0100170
171 if (which_clock != CLOCK_REALTIME)
172 return -EINVAL;
Deepa Dinamani5c499412017-06-24 11:45:05 -0700173 if (compat_get_timespec64(&new_tp, tp))
Al Virod822cdc2017-06-07 09:42:38 +0100174 return -EFAULT;
175
Deepa Dinamani5c499412017-06-24 11:45:05 -0700176 return do_sys_settimeofday64(&new_tp, NULL);
Al Virod822cdc2017-06-07 09:42:38 +0100177}
178
Deepa Dinamani5c499412017-06-24 11:45:05 -0700179COMPAT_SYSCALL_DEFINE2(clock_gettime, clockid_t, which_clock,
180 struct compat_timespec __user *, tp)
Al Virod822cdc2017-06-07 09:42:38 +0100181{
Deepa Dinamani5c499412017-06-24 11:45:05 -0700182 int ret;
183 struct timespec64 kernel_tp;
Al Virod822cdc2017-06-07 09:42:38 +0100184
Deepa Dinamani5c499412017-06-24 11:45:05 -0700185 ret = do_clock_gettime(which_clock, &kernel_tp);
186 if (ret)
187 return ret;
Al Virod822cdc2017-06-07 09:42:38 +0100188
Deepa Dinamani5c499412017-06-24 11:45:05 -0700189 if (compat_put_timespec64(&kernel_tp, tp))
Al Virod822cdc2017-06-07 09:42:38 +0100190 return -EFAULT;
191 return 0;
192}
193
Deepa Dinamani5c499412017-06-24 11:45:05 -0700194COMPAT_SYSCALL_DEFINE2(clock_getres, clockid_t, which_clock,
Al Virod822cdc2017-06-07 09:42:38 +0100195 struct compat_timespec __user *, tp)
196{
Deepa Dinamani5c499412017-06-24 11:45:05 -0700197 struct timespec64 rtn_tp = {
Al Virod822cdc2017-06-07 09:42:38 +0100198 .tv_sec = 0,
199 .tv_nsec = hrtimer_resolution,
200 };
201
202 switch (which_clock) {
203 case CLOCK_REALTIME:
204 case CLOCK_MONOTONIC:
205 case CLOCK_BOOTTIME:
Deepa Dinamani5c499412017-06-24 11:45:05 -0700206 if (compat_put_timespec64(&rtn_tp, tp))
Al Virod822cdc2017-06-07 09:42:38 +0100207 return -EFAULT;
208 return 0;
209 default:
210 return -EINVAL;
211 }
212}
Deepa Dinamani5c499412017-06-24 11:45:05 -0700213
Al Viroedbeda42017-06-07 09:42:31 +0100214COMPAT_SYSCALL_DEFINE4(clock_nanosleep, clockid_t, which_clock, int, flags,
215 struct compat_timespec __user *, rqtp,
216 struct compat_timespec __user *, rmtp)
Nicolas Pitrebaa73d92016-11-11 00:10:10 -0500217{
Arnd Bergmannfe460422017-10-13 20:29:38 +0200218 struct timespec64 t;
Al Viroedbeda42017-06-07 09:42:31 +0100219
220 switch (which_clock) {
221 case CLOCK_REALTIME:
222 case CLOCK_MONOTONIC:
223 case CLOCK_BOOTTIME:
224 break;
225 default:
226 return -EINVAL;
227 }
228
Arnd Bergmannfe460422017-10-13 20:29:38 +0200229 if (compat_get_timespec64(&t, rqtp))
Al Viroedbeda42017-06-07 09:42:31 +0100230 return -EFAULT;
Arnd Bergmannfe460422017-10-13 20:29:38 +0200231 if (!timespec64_valid(&t))
Al Viroedbeda42017-06-07 09:42:31 +0100232 return -EINVAL;
233 if (flags & TIMER_ABSTIME)
234 rmtp = NULL;
235 current->restart_block.nanosleep.type = rmtp ? TT_COMPAT : TT_NONE;
236 current->restart_block.nanosleep.compat_rmtp = rmtp;
Arnd Bergmannfe460422017-10-13 20:29:38 +0200237 return hrtimer_nanosleep(&t, flags & TIMER_ABSTIME ?
Al Viroedbeda42017-06-07 09:42:31 +0100238 HRTIMER_MODE_ABS : HRTIMER_MODE_REL,
239 which_clock);
Nicolas Pitrebaa73d92016-11-11 00:10:10 -0500240}
241#endif