]>
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); | |
48 | #ifdef __ARCH_WANT_SYS_ALARM | |
49 | SYS_NI(alarm); | |
50 | #endif | |
51 | ||
52 | /* | |
53 | * We preserve minimal support for CLOCK_REALTIME and CLOCK_MONOTONIC | |
54 | * as it is easy to remain compatible with little code. CLOCK_BOOTTIME | |
55 | * is also included for convenience as at least systemd uses it. | |
56 | */ | |
57 | ||
58 | SYSCALL_DEFINE2(clock_settime, const clockid_t, which_clock, | |
6d5b8413 | 59 | const struct __kernel_timespec __user *, tp) |
baa73d9e | 60 | { |
5c499410 | 61 | struct timespec64 new_tp; |
baa73d9e NP |
62 | |
63 | if (which_clock != CLOCK_REALTIME) | |
64 | return -EINVAL; | |
5c499410 | 65 | if (get_timespec64(&new_tp, tp)) |
baa73d9e | 66 | return -EFAULT; |
2ac00f17 | 67 | |
5c499410 | 68 | return do_sys_settimeofday64(&new_tp, NULL); |
baa73d9e NP |
69 | } |
70 | ||
5c499410 | 71 | int do_clock_gettime(clockid_t which_clock, struct timespec64 *tp) |
baa73d9e | 72 | { |
baa73d9e | 73 | switch (which_clock) { |
5c499410 DD |
74 | case CLOCK_REALTIME: |
75 | ktime_get_real_ts64(tp); | |
76 | break; | |
77 | case CLOCK_MONOTONIC: | |
78 | ktime_get_ts64(tp); | |
79 | break; | |
80 | case CLOCK_BOOTTIME: | |
58a10456 | 81 | ktime_get_boottime_ts64(tp); |
5c499410 DD |
82 | break; |
83 | default: | |
84 | return -EINVAL; | |
baa73d9e | 85 | } |
3c9c12f4 | 86 | |
5c499410 DD |
87 | return 0; |
88 | } | |
89 | SYSCALL_DEFINE2(clock_gettime, const clockid_t, which_clock, | |
6d5b8413 | 90 | struct __kernel_timespec __user *, tp) |
5c499410 DD |
91 | { |
92 | int ret; | |
93 | struct timespec64 kernel_tp; | |
94 | ||
95 | ret = do_clock_gettime(which_clock, &kernel_tp); | |
96 | if (ret) | |
97 | return ret; | |
98 | ||
99 | if (put_timespec64(&kernel_tp, tp)) | |
baa73d9e NP |
100 | return -EFAULT; |
101 | return 0; | |
102 | } | |
103 | ||
6d5b8413 | 104 | SYSCALL_DEFINE2(clock_getres, const clockid_t, which_clock, struct __kernel_timespec __user *, tp) |
baa73d9e | 105 | { |
5c499410 | 106 | struct timespec64 rtn_tp = { |
baa73d9e NP |
107 | .tv_sec = 0, |
108 | .tv_nsec = hrtimer_resolution, | |
109 | }; | |
110 | ||
111 | switch (which_clock) { | |
112 | case CLOCK_REALTIME: | |
113 | case CLOCK_MONOTONIC: | |
114 | case CLOCK_BOOTTIME: | |
5c499410 | 115 | if (put_timespec64(&rtn_tp, tp)) |
baa73d9e NP |
116 | return -EFAULT; |
117 | return 0; | |
118 | default: | |
119 | return -EINVAL; | |
120 | } | |
121 | } | |
122 | ||
123 | SYSCALL_DEFINE4(clock_nanosleep, const clockid_t, which_clock, int, flags, | |
01909974 DD |
124 | const struct __kernel_timespec __user *, rqtp, |
125 | struct __kernel_timespec __user *, rmtp) | |
baa73d9e | 126 | { |
fe460423 | 127 | struct timespec64 t; |
baa73d9e NP |
128 | |
129 | switch (which_clock) { | |
130 | case CLOCK_REALTIME: | |
131 | case CLOCK_MONOTONIC: | |
132 | case CLOCK_BOOTTIME: | |
edbeda46 | 133 | break; |
baa73d9e NP |
134 | default: |
135 | return -EINVAL; | |
136 | } | |
edbeda46 | 137 | |
fe460423 | 138 | if (get_timespec64(&t, rqtp)) |
edbeda46 | 139 | return -EFAULT; |
fe460423 | 140 | if (!timespec64_valid(&t)) |
edbeda46 AV |
141 | return -EINVAL; |
142 | if (flags & TIMER_ABSTIME) | |
143 | rmtp = NULL; | |
144 | current->restart_block.nanosleep.type = rmtp ? TT_NATIVE : TT_NONE; | |
145 | current->restart_block.nanosleep.rmtp = rmtp; | |
fe460423 | 146 | return hrtimer_nanosleep(&t, flags & TIMER_ABSTIME ? |
edbeda46 AV |
147 | HRTIMER_MODE_ABS : HRTIMER_MODE_REL, |
148 | which_clock); | |
baa73d9e NP |
149 | } |
150 | ||
151 | #ifdef CONFIG_COMPAT | |
63a766a1 DD |
152 | COMPAT_SYS_NI(timer_create); |
153 | COMPAT_SYS_NI(clock_adjtime); | |
154 | COMPAT_SYS_NI(timer_settime); | |
155 | COMPAT_SYS_NI(timer_gettime); | |
156 | COMPAT_SYS_NI(getitimer); | |
157 | COMPAT_SYS_NI(setitimer); | |
b5793b0d | 158 | #endif |
63a766a1 | 159 | |
b5793b0d | 160 | #ifdef CONFIG_COMPAT_32BIT_TIME |
d822cdcc | 161 | COMPAT_SYSCALL_DEFINE2(clock_settime, const clockid_t, which_clock, |
9afc5eee | 162 | struct old_timespec32 __user *, tp) |
d822cdcc | 163 | { |
5c499410 | 164 | struct timespec64 new_tp; |
d822cdcc AV |
165 | |
166 | if (which_clock != CLOCK_REALTIME) | |
167 | return -EINVAL; | |
9afc5eee | 168 | if (get_old_timespec32(&new_tp, tp)) |
d822cdcc AV |
169 | return -EFAULT; |
170 | ||
5c499410 | 171 | return do_sys_settimeofday64(&new_tp, NULL); |
d822cdcc AV |
172 | } |
173 | ||
5c499410 | 174 | COMPAT_SYSCALL_DEFINE2(clock_gettime, clockid_t, which_clock, |
9afc5eee | 175 | struct old_timespec32 __user *, tp) |
d822cdcc | 176 | { |
5c499410 DD |
177 | int ret; |
178 | struct timespec64 kernel_tp; | |
d822cdcc | 179 | |
5c499410 DD |
180 | ret = do_clock_gettime(which_clock, &kernel_tp); |
181 | if (ret) | |
182 | return ret; | |
d822cdcc | 183 | |
9afc5eee | 184 | if (put_old_timespec32(&kernel_tp, tp)) |
d822cdcc AV |
185 | return -EFAULT; |
186 | return 0; | |
187 | } | |
188 | ||
5c499410 | 189 | COMPAT_SYSCALL_DEFINE2(clock_getres, clockid_t, which_clock, |
9afc5eee | 190 | struct old_timespec32 __user *, tp) |
d822cdcc | 191 | { |
5c499410 | 192 | struct timespec64 rtn_tp = { |
d822cdcc AV |
193 | .tv_sec = 0, |
194 | .tv_nsec = hrtimer_resolution, | |
195 | }; | |
196 | ||
197 | switch (which_clock) { | |
198 | case CLOCK_REALTIME: | |
199 | case CLOCK_MONOTONIC: | |
200 | case CLOCK_BOOTTIME: | |
9afc5eee | 201 | if (put_old_timespec32(&rtn_tp, tp)) |
d822cdcc AV |
202 | return -EFAULT; |
203 | return 0; | |
204 | default: | |
205 | return -EINVAL; | |
206 | } | |
207 | } | |
5c499410 | 208 | |
edbeda46 | 209 | COMPAT_SYSCALL_DEFINE4(clock_nanosleep, clockid_t, which_clock, int, flags, |
9afc5eee AB |
210 | struct old_timespec32 __user *, rqtp, |
211 | struct old_timespec32 __user *, rmtp) | |
baa73d9e | 212 | { |
fe460423 | 213 | struct timespec64 t; |
edbeda46 AV |
214 | |
215 | switch (which_clock) { | |
216 | case CLOCK_REALTIME: | |
217 | case CLOCK_MONOTONIC: | |
218 | case CLOCK_BOOTTIME: | |
219 | break; | |
220 | default: | |
221 | return -EINVAL; | |
222 | } | |
223 | ||
9afc5eee | 224 | if (get_old_timespec32(&t, rqtp)) |
edbeda46 | 225 | return -EFAULT; |
fe460423 | 226 | if (!timespec64_valid(&t)) |
edbeda46 AV |
227 | return -EINVAL; |
228 | if (flags & TIMER_ABSTIME) | |
229 | rmtp = NULL; | |
230 | current->restart_block.nanosleep.type = rmtp ? TT_COMPAT : TT_NONE; | |
231 | current->restart_block.nanosleep.compat_rmtp = rmtp; | |
fe460423 | 232 | return hrtimer_nanosleep(&t, flags & TIMER_ABSTIME ? |
edbeda46 AV |
233 | HRTIMER_MODE_ABS : HRTIMER_MODE_REL, |
234 | which_clock); | |
baa73d9e NP |
235 | } |
236 | #endif |