Linux Audio

Check our new training course

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