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