Blame view

kernel/posix-timers.c 29.2 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
  /*
f30c22695   Uwe Zeisberger   fix file specific...
2
   * linux/kernel/posix-timers.c
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
   *
   *
   * 2002-10-15  Posix Clocks & timers
   *                           by George Anzinger george@mvista.com
   *
   *			     Copyright (C) 2002 2003 by MontaVista Software.
   *
   * 2004-06-01  Fix CLOCK_REALTIME clock/timer TIMER_ABSTIME bug.
   *			     Copyright (C) 2004 Boris Hu
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License as published by
   * the Free Software Foundation; either version 2 of the License, or (at
   * your option) any later version.
   *
   * This program is distributed in the hope that it will be useful, but
   * WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
   * General Public License for more details.
  
   * You should have received a copy of the GNU General Public License
   * along with this program; if not, write to the Free Software
   * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
   *
   * MontaVista Software | 1237 East Arques Avenue | Sunnyvale | CA 94085 | USA
   */
  
  /* These are all the functions necessary to implement
   * POSIX clocks & timers
   */
  #include <linux/mm.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
34
35
36
  #include <linux/interrupt.h>
  #include <linux/slab.h>
  #include <linux/time.h>
97d1f15b7   Arjan van de Ven   [PATCH] sem2mutex...
37
  #include <linux/mutex.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
38
39
  
  #include <asm/uaccess.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
40
41
42
43
44
45
46
47
48
  #include <linux/list.h>
  #include <linux/init.h>
  #include <linux/compiler.h>
  #include <linux/idr.h>
  #include <linux/posix-timers.h>
  #include <linux/syscalls.h>
  #include <linux/wait.h>
  #include <linux/workqueue.h>
  #include <linux/module.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
  /*
   * Management arrays for POSIX timers.	 Timers are kept in slab memory
   * Timer ids are allocated by an external routine that keeps track of the
   * id and the timer.  The external interface is:
   *
   * void *idr_find(struct idr *idp, int id);           to find timer_id <id>
   * int idr_get_new(struct idr *idp, void *ptr);       to get a new id and
   *                                                    related it to <ptr>
   * void idr_remove(struct idr *idp, int id);          to release <id>
   * void idr_init(struct idr *idp);                    to initialize <idp>
   *                                                    which we supply.
   * The idr_get_new *may* call slab for more memory so it must not be
   * called under a spin lock.  Likewise idr_remore may release memory
   * (but it may be ok to do this under a lock...).
   * idr_find is just a memory look up and is quite fast.  A -1 return
   * indicates that the requested id does not exist.
   */
  
  /*
   * Lets keep our timers in a slab cache :-)
   */
e18b890bb   Christoph Lameter   [PATCH] slab: rem...
70
  static struct kmem_cache *posix_timers_cache;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
71
72
73
74
  static struct idr posix_timers_id;
  static DEFINE_SPINLOCK(idr_lock);
  
  /*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
   * we assume that the new SIGEV_THREAD_ID shares no bits with the other
   * SIGEV values.  Here we put out an error if this assumption fails.
   */
  #if SIGEV_THREAD_ID != (SIGEV_THREAD_ID & \
                         ~(SIGEV_SIGNAL | SIGEV_NONE | SIGEV_THREAD))
  #error "SIGEV_THREAD_ID must not share bit with other SIGEV values!"
  #endif
  
  
  /*
   * The timer ID is turned into a timer address by idr_find().
   * Verifying a valid ID consists of:
   *
   * a) checking that idr_find() returns other than -1.
   * b) checking that the timer id matches the one in the timer itself.
   * c) that the timer owner is in the callers thread group.
   */
  
  /*
   * CLOCKs: The POSIX standard calls for a couple of clocks and allows us
   *	    to implement others.  This structure defines the various
   *	    clocks and allows the possibility of adding others.	 We
   *	    provide an interface to add clocks to the table and expect
   *	    the "arch" code to add at least one clock that is high
   *	    resolution.	 Here we define the standard CLOCK_REALTIME as a
   *	    1/HZ resolution clock.
   *
   * RESOLUTION: Clock resolution is used to round up timer and interval
   *	    times, NOT to report clock times, which are reported with as
   *	    much resolution as the system can muster.  In some cases this
   *	    resolution may depend on the underlying clock hardware and
   *	    may not be quantifiable until run time, and only then is the
   *	    necessary code is written.	The standard says we should say
   *	    something about this issue in the documentation...
   *
   * FUNCTIONS: The CLOCKs structure defines possible functions to handle
   *	    various clock functions.  For clocks that use the standard
   *	    system timer code these entries should be NULL.  This will
   *	    allow dispatch without the overhead of indirect function
   *	    calls.  CLOCKS that depend on other sources (e.g. WWV or GPS)
   *	    must supply functions here, even if the function just returns
   *	    ENOSYS.  The standard POSIX timer management code assumes the
   *	    following: 1.) The k_itimer struct (sched.h) is used for the
27af4245b   Oleg Nesterov   posix-timers: use...
118
   *	    timer.  2.) The list, it_lock, it_clock, it_id and it_pid
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
   *	    fields are not modified by timer code.
   *
   *          At this time all functions EXCEPT clock_nanosleep can be
   *          redirected by the CLOCKS structure.  Clock_nanosleep is in
   *          there, but the code ignores it.
   *
   * Permissions: It is assumed that the clock_settime() function defined
   *	    for each clock will take care of permission checks.	 Some
   *	    clocks may be set able by any user (i.e. local process
   *	    clocks) others not.	 Currently the only set able clock we
   *	    have is CLOCK_REALTIME and its high res counter part, both of
   *	    which we beg off on and pass to do_sys_settimeofday().
   */
  
  static struct k_clock posix_clocks[MAX_CLOCKS];
becf8b5d0   Thomas Gleixner   [PATCH] hrtimer: ...
134

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
135
  /*
becf8b5d0   Thomas Gleixner   [PATCH] hrtimer: ...
136
   * These ones are defined below.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
137
   */
becf8b5d0   Thomas Gleixner   [PATCH] hrtimer: ...
138
139
140
141
142
143
  static int common_nsleep(const clockid_t, int flags, struct timespec *t,
  			 struct timespec __user *rmtp);
  static void common_timer_get(struct k_itimer *, struct itimerspec *);
  static int common_timer_set(struct k_itimer *, int,
  			    struct itimerspec *, struct itimerspec *);
  static int common_timer_del(struct k_itimer *timer);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
144

c9cb2e3d7   Thomas Gleixner   [PATCH] hrtimers:...
145
  static enum hrtimer_restart posix_timer_fn(struct hrtimer *data);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
  
  static struct k_itimer *lock_timer(timer_t timer_id, unsigned long *flags);
  
  static inline void unlock_timer(struct k_itimer *timr, unsigned long flags)
  {
  	spin_unlock_irqrestore(&timr->it_lock, flags);
  }
  
  /*
   * Call the k_clock hook function if non-null, or the default function.
   */
  #define CLOCK_DISPATCH(clock, call, arglist) \
   	((clock) < 0 ? posix_cpu_##call arglist : \
   	 (posix_clocks[clock].call != NULL \
   	  ? (*posix_clocks[clock].call) arglist : common_##call arglist))
  
  /*
   * Default clock hook functions when the struct k_clock passed
   * to register_posix_clock leaves a function pointer null.
   *
   * The function common_CALL is the default implementation for
   * the function pointer CALL in struct k_clock.
   */
a924b04dd   Thomas Gleixner   [PATCH] hrtimer: ...
169
  static inline int common_clock_getres(const clockid_t which_clock,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
170
171
172
173
174
175
  				      struct timespec *tp)
  {
  	tp->tv_sec = 0;
  	tp->tv_nsec = posix_clocks[which_clock].res;
  	return 0;
  }
becf8b5d0   Thomas Gleixner   [PATCH] hrtimer: ...
176
177
178
179
  /*
   * Get real time for posix timers
   */
  static int common_clock_get(clockid_t which_clock, struct timespec *tp)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
180
  {
becf8b5d0   Thomas Gleixner   [PATCH] hrtimer: ...
181
  	ktime_get_real_ts(tp);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
182
183
  	return 0;
  }
a924b04dd   Thomas Gleixner   [PATCH] hrtimer: ...
184
185
  static inline int common_clock_set(const clockid_t which_clock,
  				   struct timespec *tp)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
186
187
188
  {
  	return do_sys_settimeofday(tp, NULL);
  }
858119e15   Arjan van de Ven   [PATCH] Unlinline...
189
  static int common_timer_create(struct k_itimer *new_timer)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
190
  {
7978672c4   George Anzinger   [PATCH] hrtimers:...
191
  	hrtimer_init(&new_timer->it.real.timer, new_timer->it_clock, 0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
192
193
  	return 0;
  }
3d44cc3e0   Thomas Gleixner   Null pointer dere...
194
195
196
197
  static int no_timer_create(struct k_itimer *new_timer)
  {
  	return -EOPNOTSUPP;
  }
70d715fd0   Hiroshi Shimamoto   posix-timers: Fix...
198
199
200
201
202
  static int no_nsleep(const clockid_t which_clock, int flags,
  		     struct timespec *tsave, struct timespec __user *rmtp)
  {
  	return -EOPNOTSUPP;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
203
  /*
becf8b5d0   Thomas Gleixner   [PATCH] hrtimer: ...
204
   * Return nonzero if we know a priori this clockid_t value is bogus.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
205
   */
a924b04dd   Thomas Gleixner   [PATCH] hrtimer: ...
206
  static inline int invalid_clockid(const clockid_t which_clock)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
207
208
209
210
211
212
213
  {
  	if (which_clock < 0)	/* CPU clock, posix_cpu_* will check it */
  		return 0;
  	if ((unsigned) which_clock >= MAX_CLOCKS)
  		return 1;
  	if (posix_clocks[which_clock].clock_getres != NULL)
  		return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
214
215
  	if (posix_clocks[which_clock].res != 0)
  		return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
216
217
  	return 1;
  }
becf8b5d0   Thomas Gleixner   [PATCH] hrtimer: ...
218
219
220
221
222
223
224
225
  /*
   * Get monotonic time for posix timers
   */
  static int posix_ktime_get_ts(clockid_t which_clock, struct timespec *tp)
  {
  	ktime_get_ts(tp);
  	return 0;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
226
227
  
  /*
2d42244ae   John Stultz   clocksource: intr...
228
229
230
231
232
233
234
   * Get monotonic time for posix timers
   */
  static int posix_get_monotonic_raw(clockid_t which_clock, struct timespec *tp)
  {
  	getrawmonotonic(tp);
  	return 0;
  }
da15cfdae   John Stultz   time: Introduce C...
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
  
  static int posix_get_realtime_coarse(clockid_t which_clock, struct timespec *tp)
  {
  	*tp = current_kernel_time();
  	return 0;
  }
  
  static int posix_get_monotonic_coarse(clockid_t which_clock,
  						struct timespec *tp)
  {
  	*tp = get_monotonic_coarse();
  	return 0;
  }
  
  int posix_get_coarse_res(const clockid_t which_clock, struct timespec *tp)
  {
  	*tp = ktime_to_timespec(KTIME_LOW_RES);
  	return 0;
  }
2d42244ae   John Stultz   clocksource: intr...
254
  /*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
255
256
257
258
   * Initialize everything, well, just everything in Posix clocks/timers ;)
   */
  static __init int init_posix_timers(void)
  {
becf8b5d0   Thomas Gleixner   [PATCH] hrtimer: ...
259
260
  	struct k_clock clock_realtime = {
  		.clock_getres = hrtimer_get_res,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
261
  	};
becf8b5d0   Thomas Gleixner   [PATCH] hrtimer: ...
262
263
264
265
  	struct k_clock clock_monotonic = {
  		.clock_getres = hrtimer_get_res,
  		.clock_get = posix_ktime_get_ts,
  		.clock_set = do_posix_clock_nosettime,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
266
  	};
2d42244ae   John Stultz   clocksource: intr...
267
268
269
270
  	struct k_clock clock_monotonic_raw = {
  		.clock_getres = hrtimer_get_res,
  		.clock_get = posix_get_monotonic_raw,
  		.clock_set = do_posix_clock_nosettime,
3d44cc3e0   Thomas Gleixner   Null pointer dere...
271
  		.timer_create = no_timer_create,
70d715fd0   Hiroshi Shimamoto   posix-timers: Fix...
272
  		.nsleep = no_nsleep,
2d42244ae   John Stultz   clocksource: intr...
273
  	};
da15cfdae   John Stultz   time: Introduce C...
274
275
276
277
278
279
280
281
282
283
284
285
286
287
  	struct k_clock clock_realtime_coarse = {
  		.clock_getres = posix_get_coarse_res,
  		.clock_get = posix_get_realtime_coarse,
  		.clock_set = do_posix_clock_nosettime,
  		.timer_create = no_timer_create,
  		.nsleep = no_nsleep,
  	};
  	struct k_clock clock_monotonic_coarse = {
  		.clock_getres = posix_get_coarse_res,
  		.clock_get = posix_get_monotonic_coarse,
  		.clock_set = do_posix_clock_nosettime,
  		.timer_create = no_timer_create,
  		.nsleep = no_nsleep,
  	};
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
288
289
290
  
  	register_posix_clock(CLOCK_REALTIME, &clock_realtime);
  	register_posix_clock(CLOCK_MONOTONIC, &clock_monotonic);
2d42244ae   John Stultz   clocksource: intr...
291
  	register_posix_clock(CLOCK_MONOTONIC_RAW, &clock_monotonic_raw);
da15cfdae   John Stultz   time: Introduce C...
292
293
  	register_posix_clock(CLOCK_REALTIME_COARSE, &clock_realtime_coarse);
  	register_posix_clock(CLOCK_MONOTONIC_COARSE, &clock_monotonic_coarse);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
294
295
  
  	posix_timers_cache = kmem_cache_create("posix_timers_cache",
040b5c6f9   Alexey Dobriyan   SLAB_PANIC more (...
296
297
  					sizeof (struct k_itimer), 0, SLAB_PANIC,
  					NULL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
298
299
300
301
302
  	idr_init(&posix_timers_id);
  	return 0;
  }
  
  __initcall(init_posix_timers);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
303
304
  static void schedule_next_timer(struct k_itimer *timr)
  {
44f214755   Roman Zippel   [PATCH] hrtimers:...
305
  	struct hrtimer *timer = &timr->it.real.timer;
becf8b5d0   Thomas Gleixner   [PATCH] hrtimer: ...
306
  	if (timr->it.real.interval.tv64 == 0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
307
  		return;
4d672e7ac   Davide Libenzi   timerfd: new time...
308
309
310
  	timr->it_overrun += (unsigned int) hrtimer_forward(timer,
  						timer->base->get_time(),
  						timr->it.real.interval);
44f214755   Roman Zippel   [PATCH] hrtimers:...
311

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
312
313
314
  	timr->it_overrun_last = timr->it_overrun;
  	timr->it_overrun = -1;
  	++timr->it_requeue_pending;
44f214755   Roman Zippel   [PATCH] hrtimers:...
315
  	hrtimer_restart(timer);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
  }
  
  /*
   * This function is exported for use by the signal deliver code.  It is
   * called just prior to the info block being released and passes that
   * block to us.  It's function is to update the overrun entry AND to
   * restart the timer.  It should only be called if the timer is to be
   * restarted (i.e. we have flagged this in the sys_private entry of the
   * info block).
   *
   * To protect aginst the timer going away while the interrupt is queued,
   * we require that the it_requeue_pending flag be set.
   */
  void do_schedule_next_timer(struct siginfo *info)
  {
  	struct k_itimer *timr;
  	unsigned long flags;
  
  	timr = lock_timer(info->si_tid, &flags);
becf8b5d0   Thomas Gleixner   [PATCH] hrtimer: ...
335
336
337
338
339
  	if (timr && timr->it_requeue_pending == info->si_sys_private) {
  		if (timr->it_clock < 0)
  			posix_cpu_timer_schedule(timr);
  		else
  			schedule_next_timer(timr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
340

54da11749   Oleg Nesterov   posix-timers: do_...
341
  		info->si_overrun += timr->it_overrun_last;
becf8b5d0   Thomas Gleixner   [PATCH] hrtimer: ...
342
  	}
b6557fbca   Thomas Gleixner   [PATCH] hrtimers:...
343
344
  	if (timr)
  		unlock_timer(timr, flags);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
345
  }
ba661292a   Oleg Nesterov   posix-timers: fix...
346
  int posix_timer_event(struct k_itimer *timr, int si_private)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
347
  {
27af4245b   Oleg Nesterov   posix-timers: use...
348
349
  	struct task_struct *task;
  	int shared, ret = -1;
ba661292a   Oleg Nesterov   posix-timers: fix...
350
351
352
353
354
355
356
357
358
359
360
  	/*
  	 * FIXME: if ->sigq is queued we can race with
  	 * dequeue_signal()->do_schedule_next_timer().
  	 *
  	 * If dequeue_signal() sees the "right" value of
  	 * si_sys_private it calls do_schedule_next_timer().
  	 * We re-queue ->sigq and drop ->it_lock().
  	 * do_schedule_next_timer() locks the timer
  	 * and re-schedules it while ->sigq is pending.
  	 * Not really bad, but not that we want.
  	 */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
361
  	timr->sigq->info.si_sys_private = si_private;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
362

27af4245b   Oleg Nesterov   posix-timers: use...
363
364
365
366
367
368
369
  	rcu_read_lock();
  	task = pid_task(timr->it_pid, PIDTYPE_PID);
  	if (task) {
  		shared = !(timr->it_sigev_notify & SIGEV_THREAD_ID);
  		ret = send_sigqueue(timr->sigq, task, shared);
  	}
  	rcu_read_unlock();
4aa736117   Oleg Nesterov   posix-timers: don...
370
371
  	/* If we failed to send the signal the timer stops. */
  	return ret > 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
372
373
374
375
376
377
378
379
380
381
  }
  EXPORT_SYMBOL_GPL(posix_timer_event);
  
  /*
   * This function gets called when a POSIX.1b interval timer expires.  It
   * is used as a callback from the kernel internal timer.  The
   * run_timer_list code ALWAYS calls with interrupts on.
  
   * This code is for CLOCK_REALTIME* and CLOCK_MONOTONIC* timers.
   */
c9cb2e3d7   Thomas Gleixner   [PATCH] hrtimers:...
382
  static enum hrtimer_restart posix_timer_fn(struct hrtimer *timer)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
383
  {
05cfb614d   Roman Zippel   [PATCH] hrtimers:...
384
  	struct k_itimer *timr;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
385
  	unsigned long flags;
becf8b5d0   Thomas Gleixner   [PATCH] hrtimer: ...
386
  	int si_private = 0;
c9cb2e3d7   Thomas Gleixner   [PATCH] hrtimers:...
387
  	enum hrtimer_restart ret = HRTIMER_NORESTART;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
388

05cfb614d   Roman Zippel   [PATCH] hrtimers:...
389
  	timr = container_of(timer, struct k_itimer, it.real.timer);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
390
  	spin_lock_irqsave(&timr->it_lock, flags);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
391

becf8b5d0   Thomas Gleixner   [PATCH] hrtimer: ...
392
393
  	if (timr->it.real.interval.tv64 != 0)
  		si_private = ++timr->it_requeue_pending;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
394

becf8b5d0   Thomas Gleixner   [PATCH] hrtimer: ...
395
396
397
398
399
400
401
  	if (posix_timer_event(timr, si_private)) {
  		/*
  		 * signal was not sent because of sig_ignor
  		 * we will not get a call back to restart it AND
  		 * it should be restarted.
  		 */
  		if (timr->it.real.interval.tv64 != 0) {
58229a189   Thomas Gleixner   posix-timers: Pre...
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
  			ktime_t now = hrtimer_cb_get_time(timer);
  
  			/*
  			 * FIXME: What we really want, is to stop this
  			 * timer completely and restart it in case the
  			 * SIG_IGN is removed. This is a non trivial
  			 * change which involves sighand locking
  			 * (sigh !), which we don't want to do late in
  			 * the release cycle.
  			 *
  			 * For now we just let timers with an interval
  			 * less than a jiffie expire every jiffie to
  			 * avoid softirq starvation in case of SIG_IGN
  			 * and a very small interval, which would put
  			 * the timer right back on the softirq pending
  			 * list. By moving now ahead of time we trick
  			 * hrtimer_forward() to expire the timer
  			 * later, while we still maintain the overrun
  			 * accuracy, but have some inconsistency in
  			 * the timer_gettime() case. This is at least
  			 * better than a starved softirq. A more
  			 * complex fix which solves also another related
  			 * inconsistency is already in the pipeline.
  			 */
  #ifdef CONFIG_HIGH_RES_TIMERS
  			{
  				ktime_t kj = ktime_set(0, NSEC_PER_SEC / HZ);
  
  				if (timr->it.real.interval.tv64 < kj.tv64)
  					now = ktime_add(now, kj);
  			}
  #endif
4d672e7ac   Davide Libenzi   timerfd: new time...
434
  			timr->it_overrun += (unsigned int)
58229a189   Thomas Gleixner   posix-timers: Pre...
435
  				hrtimer_forward(timer, now,
becf8b5d0   Thomas Gleixner   [PATCH] hrtimer: ...
436
437
  						timr->it.real.interval);
  			ret = HRTIMER_RESTART;
a0a0c28c1   Roman Zippel   [PATCH] posix-tim...
438
  			++timr->it_requeue_pending;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
439
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
440
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
441

becf8b5d0   Thomas Gleixner   [PATCH] hrtimer: ...
442
443
444
  	unlock_timer(timr, flags);
  	return ret;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
445

27af4245b   Oleg Nesterov   posix-timers: use...
446
  static struct pid *good_sigevent(sigevent_t * event)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
447
448
449
450
  {
  	struct task_struct *rtn = current->group_leader;
  
  	if ((event->sigev_notify & SIGEV_THREAD_ID ) &&
8dc86af00   Pavel Emelyanov   Use find_task_by_...
451
  		(!(rtn = find_task_by_vpid(event->sigev_notify_thread_id)) ||
bac0abd61   Pavel Emelyanov   Isolate some expl...
452
  		 !same_thread_group(rtn, current) ||
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
453
454
455
456
457
458
  		 (event->sigev_notify & ~SIGEV_THREAD_ID) != SIGEV_SIGNAL))
  		return NULL;
  
  	if (((event->sigev_notify & ~SIGEV_THREAD_ID) != SIGEV_NONE) &&
  	    ((event->sigev_signo <= 0) || (event->sigev_signo > SIGRTMAX)))
  		return NULL;
27af4245b   Oleg Nesterov   posix-timers: use...
459
  	return task_pid(rtn);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
460
  }
a924b04dd   Thomas Gleixner   [PATCH] hrtimer: ...
461
  void register_posix_clock(const clockid_t clock_id, struct k_clock *new_clock)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
  {
  	if ((unsigned) clock_id >= MAX_CLOCKS) {
  		printk("POSIX clock register failed for clock_id %d
  ",
  		       clock_id);
  		return;
  	}
  
  	posix_clocks[clock_id] = *new_clock;
  }
  EXPORT_SYMBOL_GPL(register_posix_clock);
  
  static struct k_itimer * alloc_posix_timer(void)
  {
  	struct k_itimer *tmr;
c37622296   Robert P. J. Day   [PATCH] Transform...
477
  	tmr = kmem_cache_zalloc(posix_timers_cache, GFP_KERNEL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
478
479
  	if (!tmr)
  		return tmr;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
480
481
  	if (unlikely(!(tmr->sigq = sigqueue_alloc()))) {
  		kmem_cache_free(posix_timers_cache, tmr);
aa94fbd5c   Dan Carpenter   fix error-path NU...
482
  		return NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
483
  	}
ba661292a   Oleg Nesterov   posix-timers: fix...
484
  	memset(&tmr->sigq->info, 0, sizeof(siginfo_t));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
485
486
487
488
489
490
491
492
493
494
495
496
497
  	return tmr;
  }
  
  #define IT_ID_SET	1
  #define IT_ID_NOT_SET	0
  static void release_posix_timer(struct k_itimer *tmr, int it_id_set)
  {
  	if (it_id_set) {
  		unsigned long flags;
  		spin_lock_irqsave(&idr_lock, flags);
  		idr_remove(&posix_timers_id, tmr->it_id);
  		spin_unlock_irqrestore(&idr_lock, flags);
  	}
899921025   Oleg Nesterov   posix-timers: che...
498
  	put_pid(tmr->it_pid);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
499
  	sigqueue_free(tmr->sigq);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
500
501
502
503
  	kmem_cache_free(posix_timers_cache, tmr);
  }
  
  /* Create a POSIX.1b interval timer. */
362e9c07c   Heiko Carstens   [CVE-2009-0029] S...
504
505
506
  SYSCALL_DEFINE3(timer_create, const clockid_t, which_clock,
  		struct sigevent __user *, timer_event_spec,
  		timer_t __user *, created_timer_id)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
507
  {
2cd499e38   Oleg Nesterov   posix-timers: sys...
508
  	struct k_itimer *new_timer;
ef864c958   Oleg Nesterov   posix-timers: sys...
509
  	int error, new_timer_id;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
  	sigevent_t event;
  	int it_id_set = IT_ID_NOT_SET;
  
  	if (invalid_clockid(which_clock))
  		return -EINVAL;
  
  	new_timer = alloc_posix_timer();
  	if (unlikely(!new_timer))
  		return -EAGAIN;
  
  	spin_lock_init(&new_timer->it_lock);
   retry:
  	if (unlikely(!idr_pre_get(&posix_timers_id, GFP_KERNEL))) {
  		error = -EAGAIN;
  		goto out;
  	}
  	spin_lock_irq(&idr_lock);
5a51b713c   Oleg Nesterov   posix-timers: loc...
527
  	error = idr_get_new(&posix_timers_id, new_timer, &new_timer_id);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
528
  	spin_unlock_irq(&idr_lock);
ef864c958   Oleg Nesterov   posix-timers: sys...
529
530
531
  	if (error) {
  		if (error == -EAGAIN)
  			goto retry;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
532
  		/*
0b0a3e7b1   Joe Perches   kernel/: Spelling...
533
  		 * Weird looking, but we return EAGAIN if the IDR is
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
  		 * full (proper POSIX return value for this)
  		 */
  		error = -EAGAIN;
  		goto out;
  	}
  
  	it_id_set = IT_ID_SET;
  	new_timer->it_id = (timer_t) new_timer_id;
  	new_timer->it_clock = which_clock;
  	new_timer->it_overrun = -1;
  	error = CLOCK_DISPATCH(which_clock, timer_create, (new_timer));
  	if (error)
  		goto out;
  
  	/*
  	 * return the timer_id now.  The next step is hard to
  	 * back out if there is an error.
  	 */
  	if (copy_to_user(created_timer_id,
  			 &new_timer_id, sizeof (new_timer_id))) {
  		error = -EFAULT;
  		goto out;
  	}
  	if (timer_event_spec) {
  		if (copy_from_user(&event, timer_event_spec, sizeof (event))) {
  			error = -EFAULT;
  			goto out;
  		}
36b2f0460   Oleg Nesterov   posix-timers: sys...
562
  		rcu_read_lock();
899921025   Oleg Nesterov   posix-timers: che...
563
  		new_timer->it_pid = get_pid(good_sigevent(&event));
36b2f0460   Oleg Nesterov   posix-timers: sys...
564
  		rcu_read_unlock();
899921025   Oleg Nesterov   posix-timers: che...
565
  		if (!new_timer->it_pid) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
566
567
568
569
  			error = -EINVAL;
  			goto out;
  		}
  	} else {
5a9fa7307   Oleg Nesterov   posix-timers: kil...
570
571
572
  		event.sigev_notify = SIGEV_SIGNAL;
  		event.sigev_signo = SIGALRM;
  		event.sigev_value.sival_int = new_timer->it_id;
899921025   Oleg Nesterov   posix-timers: che...
573
  		new_timer->it_pid = get_pid(task_tgid(current));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
574
  	}
5a9fa7307   Oleg Nesterov   posix-timers: kil...
575
576
577
  	new_timer->it_sigev_notify     = event.sigev_notify;
  	new_timer->sigq->info.si_signo = event.sigev_signo;
  	new_timer->sigq->info.si_value = event.sigev_value;
717835d94   Oleg Nesterov   posix-timers: mov...
578
  	new_timer->sigq->info.si_tid   = new_timer->it_id;
5a9fa7307   Oleg Nesterov   posix-timers: kil...
579
  	new_timer->sigq->info.si_code  = SI_TIMER;
717835d94   Oleg Nesterov   posix-timers: mov...
580

36b2f0460   Oleg Nesterov   posix-timers: sys...
581
  	spin_lock_irq(&current->sighand->siglock);
27af4245b   Oleg Nesterov   posix-timers: use...
582
  	new_timer->it_signal = current->signal;
36b2f0460   Oleg Nesterov   posix-timers: sys...
583
584
  	list_add(&new_timer->list, &current->signal->posix_timers);
  	spin_unlock_irq(&current->sighand->siglock);
ef864c958   Oleg Nesterov   posix-timers: sys...
585
586
  
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
587
588
589
590
591
592
   	/*
  	 * In the case of the timer belonging to another task, after
  	 * the task is unlocked, the timer is owned by the other task
  	 * and may cease to exist at any time.  Don't use or modify
  	 * new_timer after the unlock call.
  	 */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
593
  out:
ef864c958   Oleg Nesterov   posix-timers: sys...
594
  	release_posix_timer(new_timer, it_id_set);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
595
596
597
598
  	return error;
  }
  
  /*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
599
600
601
602
603
604
   * Locking issues: We need to protect the result of the id look up until
   * we get the timer locked down so it is not deleted under us.  The
   * removal is done under the idr spinlock so we use that here to bridge
   * the find to the timer lock.  To avoid a dead lock, the timer id MUST
   * be release with out holding the timer lock.
   */
31d928456   Oleg Nesterov   posix-timers: loc...
605
  static struct k_itimer *lock_timer(timer_t timer_id, unsigned long *flags)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
606
607
608
609
610
611
612
  {
  	struct k_itimer *timr;
  	/*
  	 * Watch out here.  We do a irqsave on the idr_lock and pass the
  	 * flags part over to the timer lock.  Must not let interrupts in
  	 * while we are moving the lock.
  	 */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
613
  	spin_lock_irqsave(&idr_lock, *flags);
31d928456   Oleg Nesterov   posix-timers: loc...
614
  	timr = idr_find(&posix_timers_id, (int)timer_id);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
615
616
  	if (timr) {
  		spin_lock(&timr->it_lock);
899921025   Oleg Nesterov   posix-timers: che...
617
  		if (timr->it_signal == current->signal) {
179394af7   Thomas Gleixner   posix-timers: fix...
618
  			spin_unlock(&idr_lock);
31d928456   Oleg Nesterov   posix-timers: loc...
619
620
621
622
623
  			return timr;
  		}
  		spin_unlock(&timr->it_lock);
  	}
  	spin_unlock_irqrestore(&idr_lock, *flags);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
624

31d928456   Oleg Nesterov   posix-timers: loc...
625
  	return NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
  }
  
  /*
   * Get the time remaining on a POSIX.1b interval timer.  This function
   * is ALWAYS called with spin_lock_irq on the timer, thus it must not
   * mess with irq.
   *
   * We have a couple of messes to clean up here.  First there is the case
   * of a timer that has a requeue pending.  These timers should appear to
   * be in the timer list with an expiry as if we were to requeue them
   * now.
   *
   * The second issue is the SIGEV_NONE timer which may be active but is
   * not really ever put in the timer list (to save system resources).
   * This timer may be expired, and if so, we will do it here.  Otherwise
   * it is the same as a requeue pending timer WRT to what we should
   * report.
   */
  static void
  common_timer_get(struct k_itimer *timr, struct itimerspec *cur_setting)
  {
3b98a5328   Roman Zippel   [PATCH] hrtimers:...
647
  	ktime_t now, remaining, iv;
becf8b5d0   Thomas Gleixner   [PATCH] hrtimer: ...
648
  	struct hrtimer *timer = &timr->it.real.timer;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
649

becf8b5d0   Thomas Gleixner   [PATCH] hrtimer: ...
650
  	memset(cur_setting, 0, sizeof(struct itimerspec));
becf8b5d0   Thomas Gleixner   [PATCH] hrtimer: ...
651

3b98a5328   Roman Zippel   [PATCH] hrtimers:...
652
  	iv = timr->it.real.interval;
becf8b5d0   Thomas Gleixner   [PATCH] hrtimer: ...
653
  	/* interval timer ? */
3b98a5328   Roman Zippel   [PATCH] hrtimers:...
654
655
656
657
  	if (iv.tv64)
  		cur_setting->it_interval = ktime_to_timespec(iv);
  	else if (!hrtimer_active(timer) &&
  		 (timr->it_sigev_notify & ~SIGEV_THREAD_ID) != SIGEV_NONE)
becf8b5d0   Thomas Gleixner   [PATCH] hrtimer: ...
658
  		return;
3b98a5328   Roman Zippel   [PATCH] hrtimers:...
659
660
  
  	now = timer->base->get_time();
becf8b5d0   Thomas Gleixner   [PATCH] hrtimer: ...
661
  	/*
3b98a5328   Roman Zippel   [PATCH] hrtimers:...
662
663
664
  	 * When a requeue is pending or this is a SIGEV_NONE
  	 * timer move the expiry time forward by intervals, so
  	 * expiry is > now.
becf8b5d0   Thomas Gleixner   [PATCH] hrtimer: ...
665
  	 */
3b98a5328   Roman Zippel   [PATCH] hrtimers:...
666
667
  	if (iv.tv64 && (timr->it_requeue_pending & REQUEUE_PENDING ||
  	    (timr->it_sigev_notify & ~SIGEV_THREAD_ID) == SIGEV_NONE))
4d672e7ac   Davide Libenzi   timerfd: new time...
668
  		timr->it_overrun += (unsigned int) hrtimer_forward(timer, now, iv);
3b98a5328   Roman Zippel   [PATCH] hrtimers:...
669

cc584b213   Arjan van de Ven   hrtimer: convert ...
670
  	remaining = ktime_sub(hrtimer_get_expires(timer), now);
becf8b5d0   Thomas Gleixner   [PATCH] hrtimer: ...
671
  	/* Return 0 only, when the timer is expired and not pending */
3b98a5328   Roman Zippel   [PATCH] hrtimers:...
672
673
674
675
676
677
678
679
  	if (remaining.tv64 <= 0) {
  		/*
  		 * A single shot SIGEV_NONE timer must return 0, when
  		 * it is expired !
  		 */
  		if ((timr->it_sigev_notify & ~SIGEV_THREAD_ID) != SIGEV_NONE)
  			cur_setting->it_value.tv_nsec = 1;
  	} else
becf8b5d0   Thomas Gleixner   [PATCH] hrtimer: ...
680
  		cur_setting->it_value = ktime_to_timespec(remaining);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
681
682
683
  }
  
  /* Get the time remaining on a POSIX.1b interval timer. */
362e9c07c   Heiko Carstens   [CVE-2009-0029] S...
684
685
  SYSCALL_DEFINE2(timer_gettime, timer_t, timer_id,
  		struct itimerspec __user *, setting)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
  {
  	struct k_itimer *timr;
  	struct itimerspec cur_setting;
  	unsigned long flags;
  
  	timr = lock_timer(timer_id, &flags);
  	if (!timr)
  		return -EINVAL;
  
  	CLOCK_DISPATCH(timr->it_clock, timer_get, (timr, &cur_setting));
  
  	unlock_timer(timr, flags);
  
  	if (copy_to_user(setting, &cur_setting, sizeof (cur_setting)))
  		return -EFAULT;
  
  	return 0;
  }
becf8b5d0   Thomas Gleixner   [PATCH] hrtimer: ...
704

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
705
706
707
708
709
710
711
712
713
  /*
   * Get the number of overruns of a POSIX.1b interval timer.  This is to
   * be the overrun of the timer last delivered.  At the same time we are
   * accumulating overruns on the next timer.  The overrun is frozen when
   * the signal is delivered, either at the notify time (if the info block
   * is not queued) or at the actual delivery time (as we are informed by
   * the call back to do_schedule_next_timer().  So all we need to do is
   * to pick up the frozen overrun.
   */
362e9c07c   Heiko Carstens   [CVE-2009-0029] S...
714
  SYSCALL_DEFINE1(timer_getoverrun, timer_t, timer_id)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
715
716
717
  {
  	struct k_itimer *timr;
  	int overrun;
5ba253313   Al Viro   more low-hanging ...
718
  	unsigned long flags;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
719
720
721
722
723
724
725
726
727
728
  
  	timr = lock_timer(timer_id, &flags);
  	if (!timr)
  		return -EINVAL;
  
  	overrun = timr->it_overrun_last;
  	unlock_timer(timr, flags);
  
  	return overrun;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
729
730
731
  
  /* Set a POSIX.1b interval timer. */
  /* timr->it_lock is taken. */
858119e15   Arjan van de Ven   [PATCH] Unlinline...
732
  static int
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
733
734
735
  common_timer_set(struct k_itimer *timr, int flags,
  		 struct itimerspec *new_setting, struct itimerspec *old_setting)
  {
becf8b5d0   Thomas Gleixner   [PATCH] hrtimer: ...
736
  	struct hrtimer *timer = &timr->it.real.timer;
7978672c4   George Anzinger   [PATCH] hrtimers:...
737
  	enum hrtimer_mode mode;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
738
739
740
741
742
  
  	if (old_setting)
  		common_timer_get(timr, old_setting);
  
  	/* disable the timer */
becf8b5d0   Thomas Gleixner   [PATCH] hrtimer: ...
743
  	timr->it.real.interval.tv64 = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
744
745
746
747
  	/*
  	 * careful here.  If smp we could be in the "fire" routine which will
  	 * be spinning as we hold the lock.  But this is ONLY an SMP issue.
  	 */
becf8b5d0   Thomas Gleixner   [PATCH] hrtimer: ...
748
  	if (hrtimer_try_to_cancel(timer) < 0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
749
  		return TIMER_RETRY;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
750
751
752
753
  
  	timr->it_requeue_pending = (timr->it_requeue_pending + 2) & 
  		~REQUEUE_PENDING;
  	timr->it_overrun_last = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
754

becf8b5d0   Thomas Gleixner   [PATCH] hrtimer: ...
755
756
757
  	/* switch off the timer when it_value is zero */
  	if (!new_setting->it_value.tv_sec && !new_setting->it_value.tv_nsec)
  		return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
758

c9cb2e3d7   Thomas Gleixner   [PATCH] hrtimers:...
759
  	mode = flags & TIMER_ABSTIME ? HRTIMER_MODE_ABS : HRTIMER_MODE_REL;
7978672c4   George Anzinger   [PATCH] hrtimers:...
760
  	hrtimer_init(&timr->it.real.timer, timr->it_clock, mode);
7978672c4   George Anzinger   [PATCH] hrtimers:...
761
  	timr->it.real.timer.function = posix_timer_fn;
becf8b5d0   Thomas Gleixner   [PATCH] hrtimer: ...
762

cc584b213   Arjan van de Ven   hrtimer: convert ...
763
  	hrtimer_set_expires(timer, timespec_to_ktime(new_setting->it_value));
becf8b5d0   Thomas Gleixner   [PATCH] hrtimer: ...
764
765
766
767
768
  
  	/* Convert interval */
  	timr->it.real.interval = timespec_to_ktime(new_setting->it_interval);
  
  	/* SIGEV_NONE timers are not queued ! See common_timer_get */
952bbc87f   Thomas Gleixner   [PATCH] hrtimers:...
769
770
  	if (((timr->it_sigev_notify & ~SIGEV_THREAD_ID) == SIGEV_NONE)) {
  		/* Setup correct expiry time for relative timers */
5a7780e72   Thomas Gleixner   hrtimer: check re...
771
  		if (mode == HRTIMER_MODE_REL) {
cc584b213   Arjan van de Ven   hrtimer: convert ...
772
  			hrtimer_add_expires(timer, timer->base->get_time());
5a7780e72   Thomas Gleixner   hrtimer: check re...
773
  		}
becf8b5d0   Thomas Gleixner   [PATCH] hrtimer: ...
774
  		return 0;
952bbc87f   Thomas Gleixner   [PATCH] hrtimers:...
775
  	}
becf8b5d0   Thomas Gleixner   [PATCH] hrtimer: ...
776

cc584b213   Arjan van de Ven   hrtimer: convert ...
777
  	hrtimer_start_expires(timer, mode);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
778
779
780
781
  	return 0;
  }
  
  /* Set a POSIX.1b interval timer */
362e9c07c   Heiko Carstens   [CVE-2009-0029] S...
782
783
784
  SYSCALL_DEFINE4(timer_settime, timer_t, timer_id, int, flags,
  		const struct itimerspec __user *, new_setting,
  		struct itimerspec __user *, old_setting)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
785
786
787
788
  {
  	struct k_itimer *timr;
  	struct itimerspec new_spec, old_spec;
  	int error = 0;
5ba253313   Al Viro   more low-hanging ...
789
  	unsigned long flag;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
790
791
792
793
794
795
796
  	struct itimerspec *rtn = old_setting ? &old_spec : NULL;
  
  	if (!new_setting)
  		return -EINVAL;
  
  	if (copy_from_user(&new_spec, new_setting, sizeof (new_spec)))
  		return -EFAULT;
becf8b5d0   Thomas Gleixner   [PATCH] hrtimer: ...
797
798
  	if (!timespec_valid(&new_spec.it_interval) ||
  	    !timespec_valid(&new_spec.it_value))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
799
800
801
802
803
804
805
806
807
808
809
810
811
812
  		return -EINVAL;
  retry:
  	timr = lock_timer(timer_id, &flag);
  	if (!timr)
  		return -EINVAL;
  
  	error = CLOCK_DISPATCH(timr->it_clock, timer_set,
  			       (timr, flags, &new_spec, rtn));
  
  	unlock_timer(timr, flag);
  	if (error == TIMER_RETRY) {
  		rtn = NULL;	// We already got the old time...
  		goto retry;
  	}
becf8b5d0   Thomas Gleixner   [PATCH] hrtimer: ...
813
814
  	if (old_setting && !error &&
  	    copy_to_user(old_setting, &old_spec, sizeof (old_spec)))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
815
816
817
818
819
820
821
  		error = -EFAULT;
  
  	return error;
  }
  
  static inline int common_timer_del(struct k_itimer *timer)
  {
becf8b5d0   Thomas Gleixner   [PATCH] hrtimer: ...
822
  	timer->it.real.interval.tv64 = 0;
f972be33c   Oleg Nesterov   [PATCH] posix-tim...
823

becf8b5d0   Thomas Gleixner   [PATCH] hrtimer: ...
824
  	if (hrtimer_try_to_cancel(&timer->it.real.timer) < 0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
825
  		return TIMER_RETRY;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
826
827
828
829
830
831
832
833
834
  	return 0;
  }
  
  static inline int timer_delete_hook(struct k_itimer *timer)
  {
  	return CLOCK_DISPATCH(timer->it_clock, timer_del, (timer));
  }
  
  /* Delete a POSIX.1b interval timer. */
362e9c07c   Heiko Carstens   [CVE-2009-0029] S...
835
  SYSCALL_DEFINE1(timer_delete, timer_t, timer_id)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
836
837
  {
  	struct k_itimer *timer;
5ba253313   Al Viro   more low-hanging ...
838
  	unsigned long flags;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
839

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
840
  retry_delete:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
841
842
843
  	timer = lock_timer(timer_id, &flags);
  	if (!timer)
  		return -EINVAL;
becf8b5d0   Thomas Gleixner   [PATCH] hrtimer: ...
844
  	if (timer_delete_hook(timer) == TIMER_RETRY) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
845
846
847
  		unlock_timer(timer, flags);
  		goto retry_delete;
  	}
becf8b5d0   Thomas Gleixner   [PATCH] hrtimer: ...
848

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
849
850
851
852
853
854
855
  	spin_lock(&current->sighand->siglock);
  	list_del(&timer->list);
  	spin_unlock(&current->sighand->siglock);
  	/*
  	 * This keeps any tasks waiting on the spin lock from thinking
  	 * they got something (see the lock code above).
  	 */
899921025   Oleg Nesterov   posix-timers: che...
856
  	timer->it_signal = NULL;
4b7a13042   Oleg Nesterov   posix timers: tim...
857

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
858
859
860
861
  	unlock_timer(timer, flags);
  	release_posix_timer(timer, IT_ID_SET);
  	return 0;
  }
becf8b5d0   Thomas Gleixner   [PATCH] hrtimer: ...
862

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
863
864
865
  /*
   * return timer owned by the process, used by exit_itimers
   */
858119e15   Arjan van de Ven   [PATCH] Unlinline...
866
  static void itimer_delete(struct k_itimer *timer)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
867
868
  {
  	unsigned long flags;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
869
  retry_delete:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
870
  	spin_lock_irqsave(&timer->it_lock, flags);
becf8b5d0   Thomas Gleixner   [PATCH] hrtimer: ...
871
  	if (timer_delete_hook(timer) == TIMER_RETRY) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
872
873
874
  		unlock_timer(timer, flags);
  		goto retry_delete;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
875
876
877
878
879
  	list_del(&timer->list);
  	/*
  	 * This keeps any tasks waiting on the spin lock from thinking
  	 * they got something (see the lock code above).
  	 */
899921025   Oleg Nesterov   posix-timers: che...
880
  	timer->it_signal = NULL;
4b7a13042   Oleg Nesterov   posix timers: tim...
881

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
882
883
884
885
886
  	unlock_timer(timer, flags);
  	release_posix_timer(timer, IT_ID_SET);
  }
  
  /*
25f407f0b   Roland McGrath   [PATCH] Call exit...
887
   * This is called by do_exit or de_thread, only when there are no more
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
888
889
890
891
892
893
894
895
896
897
898
   * references to the shared signal_struct.
   */
  void exit_itimers(struct signal_struct *sig)
  {
  	struct k_itimer *tmr;
  
  	while (!list_empty(&sig->posix_timers)) {
  		tmr = list_entry(sig->posix_timers.next, struct k_itimer, list);
  		itimer_delete(tmr);
  	}
  }
becf8b5d0   Thomas Gleixner   [PATCH] hrtimer: ...
899
  /* Not available / possible... functions */
a924b04dd   Thomas Gleixner   [PATCH] hrtimer: ...
900
  int do_posix_clock_nosettime(const clockid_t clockid, struct timespec *tp)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
901
902
903
904
  {
  	return -EINVAL;
  }
  EXPORT_SYMBOL_GPL(do_posix_clock_nosettime);
a924b04dd   Thomas Gleixner   [PATCH] hrtimer: ...
905
  int do_posix_clock_nonanosleep(const clockid_t clock, int flags,
97735f25d   Thomas Gleixner   [PATCH] hrtimer: ...
906
  			       struct timespec *t, struct timespec __user *r)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
907
908
909
910
911
912
913
914
  {
  #ifndef ENOTSUP
  	return -EOPNOTSUPP;	/* aka ENOTSUP in userland for POSIX */
  #else  /*  parisc does define it separately.  */
  	return -ENOTSUP;
  #endif
  }
  EXPORT_SYMBOL_GPL(do_posix_clock_nonanosleep);
362e9c07c   Heiko Carstens   [CVE-2009-0029] S...
915
916
  SYSCALL_DEFINE2(clock_settime, const clockid_t, which_clock,
  		const struct timespec __user *, tp)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
917
918
919
920
921
922
923
924
925
926
  {
  	struct timespec new_tp;
  
  	if (invalid_clockid(which_clock))
  		return -EINVAL;
  	if (copy_from_user(&new_tp, tp, sizeof (*tp)))
  		return -EFAULT;
  
  	return CLOCK_DISPATCH(which_clock, clock_set, (which_clock, &new_tp));
  }
362e9c07c   Heiko Carstens   [CVE-2009-0029] S...
927
928
  SYSCALL_DEFINE2(clock_gettime, const clockid_t, which_clock,
  		struct timespec __user *,tp)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
929
930
931
932
933
934
935
936
937
938
939
940
941
942
  {
  	struct timespec kernel_tp;
  	int error;
  
  	if (invalid_clockid(which_clock))
  		return -EINVAL;
  	error = CLOCK_DISPATCH(which_clock, clock_get,
  			       (which_clock, &kernel_tp));
  	if (!error && copy_to_user(tp, &kernel_tp, sizeof (kernel_tp)))
  		error = -EFAULT;
  
  	return error;
  
  }
362e9c07c   Heiko Carstens   [CVE-2009-0029] S...
943
944
  SYSCALL_DEFINE2(clock_getres, const clockid_t, which_clock,
  		struct timespec __user *, tp)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
  {
  	struct timespec rtn_tp;
  	int error;
  
  	if (invalid_clockid(which_clock))
  		return -EINVAL;
  
  	error = CLOCK_DISPATCH(which_clock, clock_getres,
  			       (which_clock, &rtn_tp));
  
  	if (!error && tp && copy_to_user(tp, &rtn_tp, sizeof (rtn_tp))) {
  		error = -EFAULT;
  	}
  
  	return error;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
961
  /*
97735f25d   Thomas Gleixner   [PATCH] hrtimer: ...
962
963
964
965
966
   * nanosleep for monotonic and realtime clocks
   */
  static int common_nsleep(const clockid_t which_clock, int flags,
  			 struct timespec *tsave, struct timespec __user *rmtp)
  {
080344b98   Oleg Nesterov   hrtimer: fix *rmt...
967
968
969
  	return hrtimer_nanosleep(tsave, rmtp, flags & TIMER_ABSTIME ?
  				 HRTIMER_MODE_ABS : HRTIMER_MODE_REL,
  				 which_clock);
97735f25d   Thomas Gleixner   [PATCH] hrtimer: ...
970
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
971

362e9c07c   Heiko Carstens   [CVE-2009-0029] S...
972
973
974
  SYSCALL_DEFINE4(clock_nanosleep, const clockid_t, which_clock, int, flags,
  		const struct timespec __user *, rqtp,
  		struct timespec __user *, rmtp)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
975
976
  {
  	struct timespec t;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
977
978
979
980
981
982
  
  	if (invalid_clockid(which_clock))
  		return -EINVAL;
  
  	if (copy_from_user(&t, rqtp, sizeof (struct timespec)))
  		return -EFAULT;
5f82b2b77   Thomas Gleixner   [PATCH] hrtimer: ...
983
  	if (!timespec_valid(&t))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
984
  		return -EINVAL;
97735f25d   Thomas Gleixner   [PATCH] hrtimer: ...
985
986
  	return CLOCK_DISPATCH(which_clock, nsleep,
  			      (which_clock, flags, &t, rmtp));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
987
  }
1711ef386   Toyo Abe   [PATCH] posix-tim...
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
  
  /*
   * nanosleep_restart for monotonic and realtime clocks
   */
  static int common_nsleep_restart(struct restart_block *restart_block)
  {
  	return hrtimer_nanosleep_restart(restart_block);
  }
  
  /*
   * This will restart clock_nanosleep. This is required only by
   * compat_clock_nanosleep_restart for now.
   */
  long
  clock_nanosleep_restart(struct restart_block *restart_block)
  {
  	clockid_t which_clock = restart_block->arg0;
  
  	return CLOCK_DISPATCH(which_clock, nsleep_restart,
  			      (restart_block));
  }