diff options
Diffstat (limited to 'kernel/time/posix-stubs.c')
-rw-r--r-- | kernel/time/posix-stubs.c | 112 |
1 files changed, 102 insertions, 10 deletions
diff --git a/kernel/time/posix-stubs.c b/kernel/time/posix-stubs.c index c0cd53eb018a..38f3b20efa29 100644 --- a/kernel/time/posix-stubs.c +++ b/kernel/time/posix-stubs.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/ktime.h> | 17 | #include <linux/ktime.h> |
18 | #include <linux/timekeeping.h> | 18 | #include <linux/timekeeping.h> |
19 | #include <linux/posix-timers.h> | 19 | #include <linux/posix-timers.h> |
20 | #include <linux/compat.h> | ||
20 | 21 | ||
21 | asmlinkage long sys_ni_posix_timers(void) | 22 | asmlinkage long sys_ni_posix_timers(void) |
22 | { | 23 | { |
@@ -27,6 +28,7 @@ asmlinkage long sys_ni_posix_timers(void) | |||
27 | } | 28 | } |
28 | 29 | ||
29 | #define SYS_NI(name) SYSCALL_ALIAS(sys_##name, sys_ni_posix_timers) | 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) | ||
30 | 32 | ||
31 | SYS_NI(timer_create); | 33 | SYS_NI(timer_create); |
32 | SYS_NI(timer_gettime); | 34 | SYS_NI(timer_gettime); |
@@ -39,6 +41,12 @@ SYS_NI(setitimer); | |||
39 | #ifdef __ARCH_WANT_SYS_ALARM | 41 | #ifdef __ARCH_WANT_SYS_ALARM |
40 | SYS_NI(alarm); | 42 | SYS_NI(alarm); |
41 | #endif | 43 | #endif |
44 | COMPAT_SYS_NI(timer_create); | ||
45 | COMPAT_SYS_NI(clock_adjtime); | ||
46 | COMPAT_SYS_NI(timer_settime); | ||
47 | COMPAT_SYS_NI(timer_gettime); | ||
48 | COMPAT_SYS_NI(getitimer); | ||
49 | COMPAT_SYS_NI(setitimer); | ||
42 | 50 | ||
43 | /* | 51 | /* |
44 | * We preserve minimal support for CLOCK_REALTIME and CLOCK_MONOTONIC | 52 | * We preserve minimal support for CLOCK_REALTIME and CLOCK_MONOTONIC |
@@ -110,22 +118,106 @@ SYSCALL_DEFINE4(clock_nanosleep, const clockid_t, which_clock, int, flags, | |||
110 | case CLOCK_REALTIME: | 118 | case CLOCK_REALTIME: |
111 | case CLOCK_MONOTONIC: | 119 | case CLOCK_MONOTONIC: |
112 | case CLOCK_BOOTTIME: | 120 | case CLOCK_BOOTTIME: |
113 | if (copy_from_user(&t, rqtp, sizeof (struct timespec))) | 121 | break; |
114 | return -EFAULT; | ||
115 | t64 = timespec_to_timespec64(t); | ||
116 | if (!timespec64_valid(&t64)) | ||
117 | return -EINVAL; | ||
118 | return hrtimer_nanosleep(&t64, rmtp, flags & TIMER_ABSTIME ? | ||
119 | HRTIMER_MODE_ABS : HRTIMER_MODE_REL, | ||
120 | which_clock); | ||
121 | default: | 122 | default: |
122 | return -EINVAL; | 123 | return -EINVAL; |
123 | } | 124 | } |
125 | |||
126 | if (copy_from_user(&t, rqtp, sizeof (struct timespec))) | ||
127 | return -EFAULT; | ||
128 | t64 = timespec_to_timespec64(t); | ||
129 | if (!timespec64_valid(&t64)) | ||
130 | return -EINVAL; | ||
131 | if (flags & TIMER_ABSTIME) | ||
132 | rmtp = NULL; | ||
133 | current->restart_block.nanosleep.type = rmtp ? TT_NATIVE : TT_NONE; | ||
134 | current->restart_block.nanosleep.rmtp = rmtp; | ||
135 | return hrtimer_nanosleep(&t64, flags & TIMER_ABSTIME ? | ||
136 | HRTIMER_MODE_ABS : HRTIMER_MODE_REL, | ||
137 | which_clock); | ||
124 | } | 138 | } |
125 | 139 | ||
126 | #ifdef CONFIG_COMPAT | 140 | #ifdef CONFIG_COMPAT |
127 | long clock_nanosleep_restart(struct restart_block *restart_block) | 141 | COMPAT_SYSCALL_DEFINE2(clock_settime, const clockid_t, which_clock, |
142 | struct compat_timespec __user *, tp) | ||
143 | { | ||
144 | struct timespec64 new_tp64; | ||
145 | struct timespec new_tp; | ||
146 | |||
147 | if (which_clock != CLOCK_REALTIME) | ||
148 | return -EINVAL; | ||
149 | if (compat_get_timespec(&new_tp, tp)) | ||
150 | return -EFAULT; | ||
151 | |||
152 | new_tp64 = timespec_to_timespec64(new_tp); | ||
153 | return do_sys_settimeofday64(&new_tp64, NULL); | ||
154 | } | ||
155 | |||
156 | COMPAT_SYSCALL_DEFINE2(clock_gettime, const clockid_t, which_clock, | ||
157 | struct compat_timespec __user *,tp) | ||
128 | { | 158 | { |
129 | return hrtimer_nanosleep_restart(restart_block); | 159 | struct timespec64 kernel_tp64; |
160 | struct timespec kernel_tp; | ||
161 | |||
162 | switch (which_clock) { | ||
163 | case CLOCK_REALTIME: ktime_get_real_ts64(&kernel_tp64); break; | ||
164 | case CLOCK_MONOTONIC: ktime_get_ts64(&kernel_tp64); break; | ||
165 | case CLOCK_BOOTTIME: get_monotonic_boottime64(&kernel_tp64); break; | ||
166 | default: return -EINVAL; | ||
167 | } | ||
168 | |||
169 | kernel_tp = timespec64_to_timespec(kernel_tp64); | ||
170 | if (compat_put_timespec(&kernel_tp, tp)) | ||
171 | return -EFAULT; | ||
172 | return 0; | ||
173 | } | ||
174 | |||
175 | COMPAT_SYSCALL_DEFINE2(clock_getres, const clockid_t, which_clock, | ||
176 | struct compat_timespec __user *, tp) | ||
177 | { | ||
178 | struct timespec rtn_tp = { | ||
179 | .tv_sec = 0, | ||
180 | .tv_nsec = hrtimer_resolution, | ||
181 | }; | ||
182 | |||
183 | switch (which_clock) { | ||
184 | case CLOCK_REALTIME: | ||
185 | case CLOCK_MONOTONIC: | ||
186 | case CLOCK_BOOTTIME: | ||
187 | if (compat_put_timespec(&rtn_tp, tp)) | ||
188 | return -EFAULT; | ||
189 | return 0; | ||
190 | default: | ||
191 | return -EINVAL; | ||
192 | } | ||
193 | } | ||
194 | COMPAT_SYSCALL_DEFINE4(clock_nanosleep, clockid_t, which_clock, int, flags, | ||
195 | struct compat_timespec __user *, rqtp, | ||
196 | struct compat_timespec __user *, rmtp) | ||
197 | { | ||
198 | struct timespec64 t64; | ||
199 | struct timespec t; | ||
200 | |||
201 | switch (which_clock) { | ||
202 | case CLOCK_REALTIME: | ||
203 | case CLOCK_MONOTONIC: | ||
204 | case CLOCK_BOOTTIME: | ||
205 | break; | ||
206 | default: | ||
207 | return -EINVAL; | ||
208 | } | ||
209 | |||
210 | if (compat_get_timespec(&t, rqtp)) | ||
211 | return -EFAULT; | ||
212 | t64 = timespec_to_timespec64(t); | ||
213 | if (!timespec64_valid(&t64)) | ||
214 | return -EINVAL; | ||
215 | if (flags & TIMER_ABSTIME) | ||
216 | rmtp = NULL; | ||
217 | current->restart_block.nanosleep.type = rmtp ? TT_COMPAT : TT_NONE; | ||
218 | current->restart_block.nanosleep.compat_rmtp = rmtp; | ||
219 | return hrtimer_nanosleep(&t64, flags & TIMER_ABSTIME ? | ||
220 | HRTIMER_MODE_ABS : HRTIMER_MODE_REL, | ||
221 | which_clock); | ||
130 | } | 222 | } |
131 | #endif | 223 | #endif |