GNU Linux-libre 4.14.324-gnu1
[releases.git] / kernel / time / posix-stubs.c
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 #include <linux/compat.h>
21
22 asmlinkage long sys_ni_posix_timers(void)
23 {
24         pr_err_once("process %d (%s) attempted a POSIX timer syscall "
25                     "while CONFIG_POSIX_TIMERS is not set\n",
26                     current->pid, current->comm);
27         return -ENOSYS;
28 }
29
30 #define SYS_NI(name)  SYSCALL_ALIAS(sys_##name, sys_ni_posix_timers)
31 #define COMPAT_SYS_NI(name)  SYSCALL_ALIAS(compat_sys_##name, sys_ni_posix_timers)
32
33 SYS_NI(timer_create);
34 SYS_NI(timer_gettime);
35 SYS_NI(timer_getoverrun);
36 SYS_NI(timer_settime);
37 SYS_NI(timer_delete);
38 SYS_NI(clock_adjtime);
39 SYS_NI(getitimer);
40 SYS_NI(setitimer);
41 #ifdef __ARCH_WANT_SYS_ALARM
42 SYS_NI(alarm);
43 #endif
44
45 /*
46  * We preserve minimal support for CLOCK_REALTIME and CLOCK_MONOTONIC
47  * as it is easy to remain compatible with little code. CLOCK_BOOTTIME
48  * is also included for convenience as at least systemd uses it.
49  */
50
51 SYSCALL_DEFINE2(clock_settime, const clockid_t, which_clock,
52                 const struct timespec __user *, tp)
53 {
54         struct timespec64 new_tp;
55
56         if (which_clock != CLOCK_REALTIME)
57                 return -EINVAL;
58         if (get_timespec64(&new_tp, tp))
59                 return -EFAULT;
60
61         return do_sys_settimeofday64(&new_tp, NULL);
62 }
63
64 int do_clock_gettime(clockid_t which_clock, struct timespec64 *tp)
65 {
66         switch (which_clock) {
67         case CLOCK_REALTIME:
68                 ktime_get_real_ts64(tp);
69                 break;
70         case CLOCK_MONOTONIC:
71                 ktime_get_ts64(tp);
72                 break;
73         case CLOCK_BOOTTIME:
74                 get_monotonic_boottime64(tp);
75                 break;
76         default:
77                 return -EINVAL;
78         }
79
80         return 0;
81 }
82 SYSCALL_DEFINE2(clock_gettime, const clockid_t, which_clock,
83                 struct timespec __user *, tp)
84 {
85         int ret;
86         struct timespec64 kernel_tp;
87
88         ret = do_clock_gettime(which_clock, &kernel_tp);
89         if (ret)
90                 return ret;
91
92         if (put_timespec64(&kernel_tp, tp))
93                 return -EFAULT;
94         return 0;
95 }
96
97 SYSCALL_DEFINE2(clock_getres, const clockid_t, which_clock, struct timespec __user *, tp)
98 {
99         struct timespec64 rtn_tp = {
100                 .tv_sec = 0,
101                 .tv_nsec = hrtimer_resolution,
102         };
103
104         switch (which_clock) {
105         case CLOCK_REALTIME:
106         case CLOCK_MONOTONIC:
107         case CLOCK_BOOTTIME:
108                 if (put_timespec64(&rtn_tp, tp))
109                         return -EFAULT;
110                 return 0;
111         default:
112                 return -EINVAL;
113         }
114 }
115
116 SYSCALL_DEFINE4(clock_nanosleep, const clockid_t, which_clock, int, flags,
117                 const struct timespec __user *, rqtp,
118                 struct timespec __user *, rmtp)
119 {
120         struct timespec64 t64;
121         struct timespec t;
122
123         switch (which_clock) {
124         case CLOCK_REALTIME:
125         case CLOCK_MONOTONIC:
126         case CLOCK_BOOTTIME:
127                 break;
128         default:
129                 return -EINVAL;
130         }
131
132         if (copy_from_user(&t, rqtp, sizeof (struct timespec)))
133                 return -EFAULT;
134         t64 = timespec_to_timespec64(t);
135         if (!timespec64_valid(&t64))
136                 return -EINVAL;
137         if (flags & TIMER_ABSTIME)
138                 rmtp = NULL;
139         current->restart_block.fn = do_no_restart_syscall;
140         current->restart_block.nanosleep.type = rmtp ? TT_NATIVE : TT_NONE;
141         current->restart_block.nanosleep.rmtp = rmtp;
142         return hrtimer_nanosleep(&t64, flags & TIMER_ABSTIME ?
143                                  HRTIMER_MODE_ABS : HRTIMER_MODE_REL,
144                                  which_clock);
145 }
146
147 #ifdef CONFIG_COMPAT
148 COMPAT_SYS_NI(timer_create);
149 COMPAT_SYS_NI(clock_adjtime);
150 COMPAT_SYS_NI(timer_settime);
151 COMPAT_SYS_NI(timer_gettime);
152 COMPAT_SYS_NI(getitimer);
153 COMPAT_SYS_NI(setitimer);
154
155 COMPAT_SYSCALL_DEFINE2(clock_settime, const clockid_t, which_clock,
156                        struct compat_timespec __user *, tp)
157 {
158         struct timespec64 new_tp;
159
160         if (which_clock != CLOCK_REALTIME)
161                 return -EINVAL;
162         if (compat_get_timespec64(&new_tp, tp))
163                 return -EFAULT;
164
165         return do_sys_settimeofday64(&new_tp, NULL);
166 }
167
168 COMPAT_SYSCALL_DEFINE2(clock_gettime, clockid_t, which_clock,
169                        struct compat_timespec __user *, tp)
170 {
171         int ret;
172         struct timespec64 kernel_tp;
173
174         ret = do_clock_gettime(which_clock, &kernel_tp);
175         if (ret)
176                 return ret;
177
178         if (compat_put_timespec64(&kernel_tp, tp))
179                 return -EFAULT;
180         return 0;
181 }
182
183 COMPAT_SYSCALL_DEFINE2(clock_getres, clockid_t, which_clock,
184                        struct compat_timespec __user *, tp)
185 {
186         struct timespec64 rtn_tp = {
187                 .tv_sec = 0,
188                 .tv_nsec = hrtimer_resolution,
189         };
190
191         switch (which_clock) {
192         case CLOCK_REALTIME:
193         case CLOCK_MONOTONIC:
194         case CLOCK_BOOTTIME:
195                 if (compat_put_timespec64(&rtn_tp, tp))
196                         return -EFAULT;
197                 return 0;
198         default:
199                 return -EINVAL;
200         }
201 }
202
203 COMPAT_SYSCALL_DEFINE4(clock_nanosleep, clockid_t, which_clock, int, flags,
204                        struct compat_timespec __user *, rqtp,
205                        struct compat_timespec __user *, rmtp)
206 {
207         struct timespec64 t64;
208         struct timespec t;
209
210         switch (which_clock) {
211         case CLOCK_REALTIME:
212         case CLOCK_MONOTONIC:
213         case CLOCK_BOOTTIME:
214                 break;
215         default:
216                 return -EINVAL;
217         }
218
219         if (compat_get_timespec(&t, rqtp))
220                 return -EFAULT;
221         t64 = timespec_to_timespec64(t);
222         if (!timespec64_valid(&t64))
223                 return -EINVAL;
224         if (flags & TIMER_ABSTIME)
225                 rmtp = NULL;
226         current->restart_block.fn = do_no_restart_syscall;
227         current->restart_block.nanosleep.type = rmtp ? TT_COMPAT : TT_NONE;
228         current->restart_block.nanosleep.compat_rmtp = rmtp;
229         return hrtimer_nanosleep(&t64, flags & TIMER_ABSTIME ?
230                                  HRTIMER_MODE_ABS : HRTIMER_MODE_REL,
231                                  which_clock);
232 }
233 #endif