Merge tag 'vfio-v4.17-rc1' of git://github.com/awilliam/linux-vfio
[linux-2.6-microblaze.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         case CLOCK_MONOTONIC_ACTIVE:
77                 ktime_get_active_ts64(tp);
78         default:
79                 return -EINVAL;
80         }
81
82         return 0;
83 }
84 SYSCALL_DEFINE2(clock_gettime, const clockid_t, which_clock,
85                 struct timespec __user *, tp)
86 {
87         int ret;
88         struct timespec64 kernel_tp;
89
90         ret = do_clock_gettime(which_clock, &kernel_tp);
91         if (ret)
92                 return ret;
93
94         if (put_timespec64(&kernel_tp, tp))
95                 return -EFAULT;
96         return 0;
97 }
98
99 SYSCALL_DEFINE2(clock_getres, const clockid_t, which_clock, struct timespec __user *, tp)
100 {
101         struct timespec64 rtn_tp = {
102                 .tv_sec = 0,
103                 .tv_nsec = hrtimer_resolution,
104         };
105
106         switch (which_clock) {
107         case CLOCK_REALTIME:
108         case CLOCK_MONOTONIC:
109         case CLOCK_BOOTTIME:
110                 if (put_timespec64(&rtn_tp, tp))
111                         return -EFAULT;
112                 return 0;
113         default:
114                 return -EINVAL;
115         }
116 }
117
118 SYSCALL_DEFINE4(clock_nanosleep, const clockid_t, which_clock, int, flags,
119                 const struct timespec __user *, rqtp,
120                 struct timespec __user *, rmtp)
121 {
122         struct timespec64 t;
123
124         switch (which_clock) {
125         case CLOCK_REALTIME:
126         case CLOCK_MONOTONIC:
127         case CLOCK_BOOTTIME:
128                 break;
129         default:
130                 return -EINVAL;
131         }
132
133         if (get_timespec64(&t, rqtp))
134                 return -EFAULT;
135         if (!timespec64_valid(&t))
136                 return -EINVAL;
137         if (flags & TIMER_ABSTIME)
138                 rmtp = NULL;
139         current->restart_block.nanosleep.type = rmtp ? TT_NATIVE : TT_NONE;
140         current->restart_block.nanosleep.rmtp = rmtp;
141         return hrtimer_nanosleep(&t, flags & TIMER_ABSTIME ?
142                                  HRTIMER_MODE_ABS : HRTIMER_MODE_REL,
143                                  which_clock);
144 }
145
146 #ifdef CONFIG_COMPAT
147 COMPAT_SYS_NI(timer_create);
148 COMPAT_SYS_NI(clock_adjtime);
149 COMPAT_SYS_NI(timer_settime);
150 COMPAT_SYS_NI(timer_gettime);
151 COMPAT_SYS_NI(getitimer);
152 COMPAT_SYS_NI(setitimer);
153
154 COMPAT_SYSCALL_DEFINE2(clock_settime, const clockid_t, which_clock,
155                        struct compat_timespec __user *, tp)
156 {
157         struct timespec64 new_tp;
158
159         if (which_clock != CLOCK_REALTIME)
160                 return -EINVAL;
161         if (compat_get_timespec64(&new_tp, tp))
162                 return -EFAULT;
163
164         return do_sys_settimeofday64(&new_tp, NULL);
165 }
166
167 COMPAT_SYSCALL_DEFINE2(clock_gettime, clockid_t, which_clock,
168                        struct compat_timespec __user *, tp)
169 {
170         int ret;
171         struct timespec64 kernel_tp;
172
173         ret = do_clock_gettime(which_clock, &kernel_tp);
174         if (ret)
175                 return ret;
176
177         if (compat_put_timespec64(&kernel_tp, tp))
178                 return -EFAULT;
179         return 0;
180 }
181
182 COMPAT_SYSCALL_DEFINE2(clock_getres, clockid_t, which_clock,
183                        struct compat_timespec __user *, tp)
184 {
185         struct timespec64 rtn_tp = {
186                 .tv_sec = 0,
187                 .tv_nsec = hrtimer_resolution,
188         };
189
190         switch (which_clock) {
191         case CLOCK_REALTIME:
192         case CLOCK_MONOTONIC:
193         case CLOCK_BOOTTIME:
194                 if (compat_put_timespec64(&rtn_tp, tp))
195                         return -EFAULT;
196                 return 0;
197         default:
198                 return -EINVAL;
199         }
200 }
201
202 COMPAT_SYSCALL_DEFINE4(clock_nanosleep, clockid_t, which_clock, int, flags,
203                        struct compat_timespec __user *, rqtp,
204                        struct compat_timespec __user *, rmtp)
205 {
206         struct timespec64 t;
207
208         switch (which_clock) {
209         case CLOCK_REALTIME:
210         case CLOCK_MONOTONIC:
211         case CLOCK_BOOTTIME:
212                 break;
213         default:
214                 return -EINVAL;
215         }
216
217         if (compat_get_timespec64(&t, rqtp))
218                 return -EFAULT;
219         if (!timespec64_valid(&t))
220                 return -EINVAL;
221         if (flags & TIMER_ABSTIME)
222                 rmtp = NULL;
223         current->restart_block.nanosleep.type = rmtp ? TT_COMPAT : TT_NONE;
224         current->restart_block.nanosleep.compat_rmtp = rmtp;
225         return hrtimer_nanosleep(&t, flags & TIMER_ABSTIME ?
226                                  HRTIMER_MODE_ABS : HRTIMER_MODE_REL,
227                                  which_clock);
228 }
229 #endif