Commit | Line | Data |
---|---|---|
35728b82 | 1 | // SPDX-License-Identifier: GPL-2.0 |
baa73d9e NP |
2 | /* |
3 | * Dummy stubs used when CONFIG_POSIX_TIMERS=n | |
4 | * | |
5 | * Created by: Nicolas Pitre, July 2016 | |
6 | * Copyright: (C) 2016 Linaro Limited | |
baa73d9e NP |
7 | */ |
8 | ||
9 | #include <linux/linkage.h> | |
10 | #include <linux/kernel.h> | |
11 | #include <linux/sched.h> | |
12 | #include <linux/errno.h> | |
13 | #include <linux/syscalls.h> | |
14 | #include <linux/ktime.h> | |
15 | #include <linux/timekeeping.h> | |
16 | #include <linux/posix-timers.h> | |
edbeda46 | 17 | #include <linux/compat.h> |
baa73d9e | 18 | |
7303e30e DB |
19 | #ifdef CONFIG_ARCH_HAS_SYSCALL_WRAPPER |
20 | /* Architectures may override SYS_NI and COMPAT_SYS_NI */ | |
21 | #include <asm/syscall_wrapper.h> | |
22 | #endif | |
23 | ||
baa73d9e NP |
24 | asmlinkage long sys_ni_posix_timers(void) |
25 | { | |
26 | pr_err_once("process %d (%s) attempted a POSIX timer syscall " | |
27 | "while CONFIG_POSIX_TIMERS is not set\n", | |
28 | current->pid, current->comm); | |
29 | return -ENOSYS; | |
30 | } | |
31 | ||
7303e30e | 32 | #ifndef SYS_NI |
baa73d9e | 33 | #define SYS_NI(name) SYSCALL_ALIAS(sys_##name, sys_ni_posix_timers) |
7303e30e DB |
34 | #endif |
35 | ||
36 | #ifndef COMPAT_SYS_NI | |
3a4d44b6 | 37 | #define COMPAT_SYS_NI(name) SYSCALL_ALIAS(compat_sys_##name, sys_ni_posix_timers) |
7303e30e | 38 | #endif |
baa73d9e NP |
39 | |
40 | SYS_NI(timer_create); | |
41 | SYS_NI(timer_gettime); | |
42 | SYS_NI(timer_getoverrun); | |
43 | SYS_NI(timer_settime); | |
44 | SYS_NI(timer_delete); | |
45 | SYS_NI(clock_adjtime); | |
46 | SYS_NI(getitimer); | |
47 | SYS_NI(setitimer); | |
8dabe724 | 48 | SYS_NI(clock_adjtime32); |
baa73d9e NP |
49 | #ifdef __ARCH_WANT_SYS_ALARM |
50 | SYS_NI(alarm); | |
51 | #endif | |
52 | ||
53 | /* | |
54 | * We preserve minimal support for CLOCK_REALTIME and CLOCK_MONOTONIC | |
55 | * as it is easy to remain compatible with little code. CLOCK_BOOTTIME | |
56 | * is also included for convenience as at least systemd uses it. | |
57 | */ | |
58 | ||
59 | SYSCALL_DEFINE2(clock_settime, const clockid_t, which_clock, | |
6d5b8413 | 60 | const struct __kernel_timespec __user *, tp) |
baa73d9e | 61 | { |
5c499410 | 62 | struct timespec64 new_tp; |
baa73d9e NP |
63 | |
64 | if (which_clock != CLOCK_REALTIME) | |
65 | return -EINVAL; | |
5c499410 | 66 | if (get_timespec64(&new_tp, tp)) |
baa73d9e | 67 | return -EFAULT; |
2ac00f17 | 68 | |
5c499410 | 69 | return do_sys_settimeofday64(&new_tp, NULL); |
baa73d9e NP |
70 | } |
71 | ||
5c499410 | 72 | int do_clock_gettime(clockid_t which_clock, struct timespec64 *tp) |
baa73d9e | 73 | { |
baa73d9e | 74 | switch (which_clock) { |
5c499410 DD |
75 | case CLOCK_REALTIME: |
76 | ktime_get_real_ts64(tp); | |
77 | break; | |
78 | case CLOCK_MONOTONIC: | |
79 | ktime_get_ts64(tp); | |
80 | break; | |
81 | case CLOCK_BOOTTIME: | |
58a10456 | 82 | ktime_get_boottime_ts64(tp); |
5c499410 DD |
83 | break; |
84 | default: | |
85 | return -EINVAL; | |
baa73d9e | 86 | } |
3c9c12f4 | 87 | |
5c499410 DD |
88 | return 0; |
89 | } | |
90 | SYSCALL_DEFINE2(clock_gettime, const clockid_t, which_clock, | |
6d5b8413 | 91 | struct __kernel_timespec __user *, tp) |
5c499410 DD |
92 | { |
93 | int ret; | |
94 | struct timespec64 kernel_tp; | |
95 | ||
96 | ret = do_clock_gettime(which_clock, &kernel_tp); | |
97 | if (ret) | |
98 | return ret; | |
99 | ||
100 | if (put_timespec64(&kernel_tp, tp)) | |
baa73d9e NP |
101 | return -EFAULT; |
102 | return 0; | |
103 | } | |
104 | ||
6d5b8413 | 105 | SYSCALL_DEFINE2(clock_getres, const clockid_t, which_clock, struct __kernel_timespec __user *, tp) |
baa73d9e | 106 | { |
5c499410 | 107 | struct timespec64 rtn_tp = { |
baa73d9e NP |
108 | .tv_sec = 0, |
109 | .tv_nsec = hrtimer_resolution, | |
110 | }; | |
111 | ||
112 | switch (which_clock) { | |
113 | case CLOCK_REALTIME: | |
114 | case CLOCK_MONOTONIC: | |
115 | case CLOCK_BOOTTIME: | |
5c499410 | 116 | if (put_timespec64(&rtn_tp, tp)) |
baa73d9e NP |
117 | return -EFAULT; |
118 | return 0; | |
119 | default: | |
120 | return -EINVAL; | |
121 | } | |
122 | } | |
123 | ||
124 | SYSCALL_DEFINE4(clock_nanosleep, const clockid_t, which_clock, int, flags, | |
01909974 DD |
125 | const struct __kernel_timespec __user *, rqtp, |
126 | struct __kernel_timespec __user *, rmtp) | |
baa73d9e | 127 | { |
fe460423 | 128 | struct timespec64 t; |
baa73d9e NP |
129 | |
130 | switch (which_clock) { | |
131 | case CLOCK_REALTIME: | |
132 | case CLOCK_MONOTONIC: | |
133 | case CLOCK_BOOTTIME: | |
edbeda46 | 134 | break; |
baa73d9e NP |
135 | default: |
136 | return -EINVAL; | |
137 | } | |
edbeda46 | 138 | |
fe460423 | 139 | if (get_timespec64(&t, rqtp)) |
edbeda46 | 140 | return -EFAULT; |
fe460423 | 141 | if (!timespec64_valid(&t)) |
edbeda46 AV |
142 | return -EINVAL; |
143 | if (flags & TIMER_ABSTIME) | |
144 | rmtp = NULL; | |
145 | current->restart_block.nanosleep.type = rmtp ? TT_NATIVE : TT_NONE; | |
146 | current->restart_block.nanosleep.rmtp = rmtp; | |
fe460423 | 147 | return hrtimer_nanosleep(&t, flags & TIMER_ABSTIME ? |
edbeda46 AV |
148 | HRTIMER_MODE_ABS : HRTIMER_MODE_REL, |
149 | which_clock); | |
baa73d9e NP |
150 | } |
151 | ||
152 | #ifdef CONFIG_COMPAT | |
63a766a1 | 153 | COMPAT_SYS_NI(timer_create); |
63a766a1 DD |
154 | COMPAT_SYS_NI(getitimer); |
155 | COMPAT_SYS_NI(setitimer); | |
b5793b0d | 156 | #endif |
63a766a1 | 157 | |
b5793b0d | 158 | #ifdef CONFIG_COMPAT_32BIT_TIME |
8dabe724 AB |
159 | SYS_NI(timer_settime32); |
160 | SYS_NI(timer_gettime32); | |
161 | ||
162 | SYSCALL_DEFINE2(clock_settime32, const clockid_t, which_clock, | |
163 | struct old_timespec32 __user *, tp) | |
d822cdcc | 164 | { |
5c499410 | 165 | struct timespec64 new_tp; |
d822cdcc AV |
166 | |
167 | if (which_clock != CLOCK_REALTIME) | |
168 | return -EINVAL; | |
9afc5eee | 169 | if (get_old_timespec32(&new_tp, tp)) |
d822cdcc AV |
170 | return -EFAULT; |
171 | ||
5c499410 | 172 | return do_sys_settimeofday64(&new_tp, NULL); |
d822cdcc AV |
173 | } |
174 | ||
8dabe724 AB |
175 | SYSCALL_DEFINE2(clock_gettime32, clockid_t, which_clock, |
176 | struct old_timespec32 __user *, tp) | |
d822cdcc | 177 | { |
5c499410 DD |
178 | int ret; |
179 | struct timespec64 kernel_tp; | |
d822cdcc | 180 | |
5c499410 DD |
181 | ret = do_clock_gettime(which_clock, &kernel_tp); |
182 | if (ret) | |
183 | return ret; | |
d822cdcc | 184 | |
9afc5eee | 185 | if (put_old_timespec32(&kernel_tp, tp)) |
d822cdcc AV |
186 | return -EFAULT; |
187 | return 0; | |
188 | } | |
189 | ||
8dabe724 AB |
190 | SYSCALL_DEFINE2(clock_getres_time32, clockid_t, which_clock, |
191 | struct old_timespec32 __user *, tp) | |
d822cdcc | 192 | { |
5c499410 | 193 | struct timespec64 rtn_tp = { |
d822cdcc AV |
194 | .tv_sec = 0, |
195 | .tv_nsec = hrtimer_resolution, | |
196 | }; | |
197 | ||
198 | switch (which_clock) { | |
199 | case CLOCK_REALTIME: | |
200 | case CLOCK_MONOTONIC: | |
201 | case CLOCK_BOOTTIME: | |
9afc5eee | 202 | if (put_old_timespec32(&rtn_tp, tp)) |
d822cdcc AV |
203 | return -EFAULT; |
204 | return 0; | |
205 | default: | |
206 | return -EINVAL; | |
207 | } | |
208 | } | |
5c499410 | 209 | |
8dabe724 AB |
210 | SYSCALL_DEFINE4(clock_nanosleep_time32, clockid_t, which_clock, int, flags, |
211 | struct old_timespec32 __user *, rqtp, | |
212 | struct old_timespec32 __user *, rmtp) | |
baa73d9e | 213 | { |
fe460423 | 214 | struct timespec64 t; |
edbeda46 AV |
215 | |
216 | switch (which_clock) { | |
217 | case CLOCK_REALTIME: | |
218 | case CLOCK_MONOTONIC: | |
219 | case CLOCK_BOOTTIME: | |
220 | break; | |
221 | default: | |
222 | return -EINVAL; | |
223 | } | |
224 | ||
9afc5eee | 225 | if (get_old_timespec32(&t, rqtp)) |
edbeda46 | 226 | return -EFAULT; |
fe460423 | 227 | if (!timespec64_valid(&t)) |
edbeda46 AV |
228 | return -EINVAL; |
229 | if (flags & TIMER_ABSTIME) | |
230 | rmtp = NULL; | |
231 | current->restart_block.nanosleep.type = rmtp ? TT_COMPAT : TT_NONE; | |
232 | current->restart_block.nanosleep.compat_rmtp = rmtp; | |
fe460423 | 233 | return hrtimer_nanosleep(&t, flags & TIMER_ABSTIME ? |
edbeda46 AV |
234 | HRTIMER_MODE_ABS : HRTIMER_MODE_REL, |
235 | which_clock); | |
baa73d9e NP |
236 | } |
237 | #endif |