]>
Commit | Line | Data |
---|---|---|
baa73d9e NP |
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 | { | |
2ac00f17 | 52 | struct timespec64 new_tp64; |
baa73d9e NP |
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; | |
2ac00f17 DD |
59 | |
60 | new_tp64 = timespec_to_timespec64(new_tp); | |
61 | return do_sys_settimeofday64(&new_tp64, NULL); | |
baa73d9e NP |
62 | } |
63 | ||
64 | SYSCALL_DEFINE2(clock_gettime, const clockid_t, which_clock, | |
65 | struct timespec __user *,tp) | |
66 | { | |
3c9c12f4 | 67 | struct timespec64 kernel_tp64; |
baa73d9e NP |
68 | struct timespec kernel_tp; |
69 | ||
70 | switch (which_clock) { | |
3c9c12f4 DD |
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; | |
baa73d9e NP |
74 | default: return -EINVAL; |
75 | } | |
3c9c12f4 DD |
76 | |
77 | kernel_tp = timespec64_to_timespec(kernel_tp64); | |
baa73d9e NP |
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 | { | |
ad196384 | 106 | struct timespec64 t64; |
baa73d9e NP |
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; | |
ad196384 DD |
115 | t64 = timespec_to_timespec64(t); |
116 | if (!timespec64_valid(&t64)) | |
baa73d9e | 117 | return -EINVAL; |
ad196384 | 118 | return hrtimer_nanosleep(&t64, rmtp, flags & TIMER_ABSTIME ? |
baa73d9e NP |
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 |