1
2
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#include <linux/module.h>
31#include <linux/timex.h>
32#include <linux/capability.h>
33#include <linux/clocksource.h>
34#include <linux/errno.h>
35#include <linux/syscalls.h>
36#include <linux/security.h>
37#include <linux/fs.h>
38#include <linux/slab.h>
39#include <linux/math64.h>
40
41#include <asm/uaccess.h>
42#include <asm/unistd.h>
43
44#include "timeconst.h"
45
46
47
48
49
50struct timezone sys_tz;
51
52EXPORT_SYMBOL(sys_tz);
53
54#ifdef __ARCH_WANT_SYS_TIME
55
56
57
58
59
60
61
62SYSCALL_DEFINE1(time, time_t __user *, tloc)
63{
64 time_t i = get_seconds();
65
66 if (tloc) {
67 if (put_user(i,tloc))
68 i = -EFAULT;
69 }
70 return i;
71}
72
73
74
75
76
77
78
79
80SYSCALL_DEFINE1(stime, time_t __user *, tptr)
81{
82 struct timespec tv;
83 int err;
84
85 if (get_user(tv.tv_sec, tptr))
86 return -EFAULT;
87
88 tv.tv_nsec = 0;
89
90 err = security_settime(&tv, NULL);
91 if (err)
92 return err;
93
94 do_settimeofday(&tv);
95 return 0;
96}
97
98#endif
99
100SYSCALL_DEFINE2(gettimeofday, struct timeval __user *, tv,
101 struct timezone __user *, tz)
102{
103 if (likely(tv != NULL)) {
104 struct timeval ktv;
105 do_gettimeofday(&ktv);
106 if (copy_to_user(tv, &ktv, sizeof(ktv)))
107 return -EFAULT;
108 }
109 if (unlikely(tz != NULL)) {
110 if (copy_to_user(tz, &sys_tz, sizeof(sys_tz)))
111 return -EFAULT;
112 }
113 return 0;
114}
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132static inline void warp_clock(void)
133{
134 write_seqlock_irq(&xtime_lock);
135 wall_to_monotonic.tv_sec -= sys_tz.tz_minuteswest * 60;
136 xtime.tv_sec += sys_tz.tz_minuteswest * 60;
137 update_xtime_cache(0);
138 write_sequnlock_irq(&xtime_lock);
139 clock_was_set();
140}
141
142
143
144
145
146
147
148
149
150
151
152
153int do_sys_settimeofday(struct timespec *tv, struct timezone *tz)
154{
155 static int firsttime = 1;
156 int error = 0;
157
158 if (tv && !timespec_valid(tv))
159 return -EINVAL;
160
161 error = security_settime(tv, tz);
162 if (error)
163 return error;
164
165 if (tz) {
166
167 sys_tz = *tz;
168 update_vsyscall_tz();
169 if (firsttime) {
170 firsttime = 0;
171 if (!tv)
172 warp_clock();
173 }
174 }
175 if (tv)
176 {
177
178
179
180 return do_settimeofday(tv);
181 }
182 return 0;
183}
184
185SYSCALL_DEFINE2(settimeofday, struct timeval __user *, tv,
186 struct timezone __user *, tz)
187{
188 struct timeval user_tv;
189 struct timespec new_ts;
190 struct timezone new_tz;
191
192 if (tv) {
193 if (copy_from_user(&user_tv, tv, sizeof(*tv)))
194 return -EFAULT;
195 new_ts.tv_sec = user_tv.tv_sec;
196 new_ts.tv_nsec = user_tv.tv_usec * NSEC_PER_USEC;
197 }
198 if (tz) {
199 if (copy_from_user(&new_tz, tz, sizeof(*tz)))
200 return -EFAULT;
201 }
202
203 return do_sys_settimeofday(tv ? &new_ts : NULL, tz ? &new_tz : NULL);
204}
205
206SYSCALL_DEFINE1(adjtimex, struct timex __user *, txc_p)
207{
208 struct timex txc;
209 int ret;
210
211
212
213
214
215 if(copy_from_user(&txc, txc_p, sizeof(struct timex)))
216 return -EFAULT;
217 ret = do_adjtimex(&txc);
218 return copy_to_user(txc_p, &txc, sizeof(struct timex)) ? -EFAULT : ret;
219}
220
221
222
223
224
225
226
227
228struct timespec current_fs_time(struct super_block *sb)
229{
230 struct timespec now = current_kernel_time();
231 return timespec_trunc(now, sb->s_time_gran);
232}
233EXPORT_SYMBOL(current_fs_time);
234
235
236
237
238
239
240
241unsigned int inline jiffies_to_msecs(const unsigned long j)
242{
243#if HZ <= MSEC_PER_SEC && !(MSEC_PER_SEC % HZ)
244 return (MSEC_PER_SEC / HZ) * j;
245#elif HZ > MSEC_PER_SEC && !(HZ % MSEC_PER_SEC)
246 return (j + (HZ / MSEC_PER_SEC) - 1)/(HZ / MSEC_PER_SEC);
247#else
248# if BITS_PER_LONG == 32
249 return (HZ_TO_MSEC_MUL32 * j) >> HZ_TO_MSEC_SHR32;
250# else
251 return (j * HZ_TO_MSEC_NUM) / HZ_TO_MSEC_DEN;
252# endif
253#endif
254}
255EXPORT_SYMBOL(jiffies_to_msecs);
256
257unsigned int inline jiffies_to_usecs(const unsigned long j)
258{
259#if HZ <= USEC_PER_SEC && !(USEC_PER_SEC % HZ)
260 return (USEC_PER_SEC / HZ) * j;
261#elif HZ > USEC_PER_SEC && !(HZ % USEC_PER_SEC)
262 return (j + (HZ / USEC_PER_SEC) - 1)/(HZ / USEC_PER_SEC);
263#else
264# if BITS_PER_LONG == 32
265 return (HZ_TO_USEC_MUL32 * j) >> HZ_TO_USEC_SHR32;
266# else
267 return (j * HZ_TO_USEC_NUM) / HZ_TO_USEC_DEN;
268# endif
269#endif
270}
271EXPORT_SYMBOL(jiffies_to_usecs);
272
273
274
275
276
277
278
279
280
281
282
283
284
285struct timespec timespec_trunc(struct timespec t, unsigned gran)
286{
287
288
289
290
291
292 if (gran <= jiffies_to_usecs(1) * 1000) {
293
294 } else if (gran == 1000000000) {
295 t.tv_nsec = 0;
296 } else {
297 t.tv_nsec -= t.tv_nsec % gran;
298 }
299 return t;
300}
301EXPORT_SYMBOL(timespec_trunc);
302
303#ifndef CONFIG_GENERIC_TIME
304
305
306
307
308void getnstimeofday(struct timespec *tv)
309{
310 struct timeval x;
311
312 do_gettimeofday(&x);
313 tv->tv_sec = x.tv_sec;
314 tv->tv_nsec = x.tv_usec * NSEC_PER_USEC;
315}
316EXPORT_SYMBOL_GPL(getnstimeofday);
317#endif
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334unsigned long
335mktime(const unsigned int year0, const unsigned int mon0,
336 const unsigned int day, const unsigned int hour,
337 const unsigned int min, const unsigned int sec)
338{
339 unsigned int mon = mon0, year = year0;
340
341
342 if (0 >= (int) (mon -= 2)) {
343 mon += 12;
344 year -= 1;
345 }
346
347 return ((((unsigned long)
348 (year/4 - year/100 + year/400 + 367*mon/12 + day) +
349 year*365 - 719499
350 )*24 + hour
351 )*60 + min
352 )*60 + sec;
353}
354
355EXPORT_SYMBOL(mktime);
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371void set_normalized_timespec(struct timespec *ts, time_t sec, long nsec)
372{
373 while (nsec >= NSEC_PER_SEC) {
374 nsec -= NSEC_PER_SEC;
375 ++sec;
376 }
377 while (nsec < 0) {
378 nsec += NSEC_PER_SEC;
379 --sec;
380 }
381 ts->tv_sec = sec;
382 ts->tv_nsec = nsec;
383}
384EXPORT_SYMBOL(set_normalized_timespec);
385
386
387
388
389
390
391
392struct timespec ns_to_timespec(const s64 nsec)
393{
394 struct timespec ts;
395 s32 rem;
396
397 if (!nsec)
398 return (struct timespec) {0, 0};
399
400 ts.tv_sec = div_s64_rem(nsec, NSEC_PER_SEC, &rem);
401 if (unlikely(rem < 0)) {
402 ts.tv_sec--;
403 rem += NSEC_PER_SEC;
404 }
405 ts.tv_nsec = rem;
406
407 return ts;
408}
409EXPORT_SYMBOL(ns_to_timespec);
410
411
412
413
414
415
416
417struct timeval ns_to_timeval(const s64 nsec)
418{
419 struct timespec ts = ns_to_timespec(nsec);
420 struct timeval tv;
421
422 tv.tv_sec = ts.tv_sec;
423 tv.tv_usec = (suseconds_t) ts.tv_nsec / 1000;
424
425 return tv;
426}
427EXPORT_SYMBOL(ns_to_timeval);
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443unsigned long msecs_to_jiffies(const unsigned int m)
444{
445
446
447
448 if ((int)m < 0)
449 return MAX_JIFFY_OFFSET;
450
451#if HZ <= MSEC_PER_SEC && !(MSEC_PER_SEC % HZ)
452
453
454
455
456
457 return (m + (MSEC_PER_SEC / HZ) - 1) / (MSEC_PER_SEC / HZ);
458#elif HZ > MSEC_PER_SEC && !(HZ % MSEC_PER_SEC)
459
460
461
462
463
464
465
466 if (m > jiffies_to_msecs(MAX_JIFFY_OFFSET))
467 return MAX_JIFFY_OFFSET;
468
469 return m * (HZ / MSEC_PER_SEC);
470#else
471
472
473
474
475
476 if (HZ > MSEC_PER_SEC && m > jiffies_to_msecs(MAX_JIFFY_OFFSET))
477 return MAX_JIFFY_OFFSET;
478
479 return (MSEC_TO_HZ_MUL32 * m + MSEC_TO_HZ_ADJ32)
480 >> MSEC_TO_HZ_SHR32;
481#endif
482}
483EXPORT_SYMBOL(msecs_to_jiffies);
484
485unsigned long usecs_to_jiffies(const unsigned int u)
486{
487 if (u > jiffies_to_usecs(MAX_JIFFY_OFFSET))
488 return MAX_JIFFY_OFFSET;
489#if HZ <= USEC_PER_SEC && !(USEC_PER_SEC % HZ)
490 return (u + (USEC_PER_SEC / HZ) - 1) / (USEC_PER_SEC / HZ);
491#elif HZ > USEC_PER_SEC && !(HZ % USEC_PER_SEC)
492 return u * (HZ / USEC_PER_SEC);
493#else
494 return (USEC_TO_HZ_MUL32 * u + USEC_TO_HZ_ADJ32)
495 >> USEC_TO_HZ_SHR32;
496#endif
497}
498EXPORT_SYMBOL(usecs_to_jiffies);
499
500
501
502
503
504
505
506
507
508
509
510
511unsigned long
512timespec_to_jiffies(const struct timespec *value)
513{
514 unsigned long sec = value->tv_sec;
515 long nsec = value->tv_nsec + TICK_NSEC - 1;
516
517 if (sec >= MAX_SEC_IN_JIFFIES){
518 sec = MAX_SEC_IN_JIFFIES;
519 nsec = 0;
520 }
521 return (((u64)sec * SEC_CONVERSION) +
522 (((u64)nsec * NSEC_CONVERSION) >>
523 (NSEC_JIFFIE_SC - SEC_JIFFIE_SC))) >> SEC_JIFFIE_SC;
524
525}
526EXPORT_SYMBOL(timespec_to_jiffies);
527
528void
529jiffies_to_timespec(const unsigned long jiffies, struct timespec *value)
530{
531
532
533
534
535 u32 rem;
536 value->tv_sec = div_u64_rem((u64)jiffies * TICK_NSEC,
537 NSEC_PER_SEC, &rem);
538 value->tv_nsec = rem;
539}
540EXPORT_SYMBOL(jiffies_to_timespec);
541
542
543
544
545
546
547
548
549
550
551
552
553
554unsigned long
555timeval_to_jiffies(const struct timeval *value)
556{
557 unsigned long sec = value->tv_sec;
558 long usec = value->tv_usec;
559
560 if (sec >= MAX_SEC_IN_JIFFIES){
561 sec = MAX_SEC_IN_JIFFIES;
562 usec = 0;
563 }
564 return (((u64)sec * SEC_CONVERSION) +
565 (((u64)usec * USEC_CONVERSION + USEC_ROUND) >>
566 (USEC_JIFFIE_SC - SEC_JIFFIE_SC))) >> SEC_JIFFIE_SC;
567}
568EXPORT_SYMBOL(timeval_to_jiffies);
569
570void jiffies_to_timeval(const unsigned long jiffies, struct timeval *value)
571{
572
573
574
575
576 u32 rem;
577
578 value->tv_sec = div_u64_rem((u64)jiffies * TICK_NSEC,
579 NSEC_PER_SEC, &rem);
580 value->tv_usec = rem / NSEC_PER_USEC;
581}
582EXPORT_SYMBOL(jiffies_to_timeval);
583
584
585
586
587clock_t jiffies_to_clock_t(long x)
588{
589#if (TICK_NSEC % (NSEC_PER_SEC / USER_HZ)) == 0
590# if HZ < USER_HZ
591 return x * (USER_HZ / HZ);
592# else
593 return x / (HZ / USER_HZ);
594# endif
595#else
596 return div_u64((u64)x * TICK_NSEC, NSEC_PER_SEC / USER_HZ);
597#endif
598}
599EXPORT_SYMBOL(jiffies_to_clock_t);
600
601unsigned long clock_t_to_jiffies(unsigned long x)
602{
603#if (HZ % USER_HZ)==0
604 if (x >= ~0UL / (HZ / USER_HZ))
605 return ~0UL;
606 return x * (HZ / USER_HZ);
607#else
608
609 if (x >= ~0UL / HZ * USER_HZ)
610 return ~0UL;
611
612
613 return div_u64((u64)x * HZ, USER_HZ);
614#endif
615}
616EXPORT_SYMBOL(clock_t_to_jiffies);
617
618u64 jiffies_64_to_clock_t(u64 x)
619{
620#if (TICK_NSEC % (NSEC_PER_SEC / USER_HZ)) == 0
621# if HZ < USER_HZ
622 x = div_u64(x * USER_HZ, HZ);
623# elif HZ > USER_HZ
624 x = div_u64(x, HZ / USER_HZ);
625# else
626
627# endif
628#else
629
630
631
632
633
634 x = div_u64(x * TICK_NSEC, (NSEC_PER_SEC / USER_HZ));
635#endif
636 return x;
637}
638EXPORT_SYMBOL(jiffies_64_to_clock_t);
639
640u64 nsec_to_clock_t(u64 x)
641{
642#if (NSEC_PER_SEC % USER_HZ) == 0
643 return div_u64(x, NSEC_PER_SEC / USER_HZ);
644#elif (USER_HZ % 512) == 0
645 return div_u64(x * USER_HZ / 512, NSEC_PER_SEC / 512);
646#else
647
648
649
650
651
652 return div_u64(x * 9, (9ull * NSEC_PER_SEC + (USER_HZ / 2)) / USER_HZ);
653#endif
654}
655
656#if (BITS_PER_LONG < 64)
657u64 get_jiffies_64(void)
658{
659 unsigned long seq;
660 u64 ret;
661
662 do {
663 seq = read_seqbegin(&xtime_lock);
664 ret = jiffies_64;
665 } while (read_seqretry(&xtime_lock, seq));
666 return ret;
667}
668EXPORT_SYMBOL(get_jiffies_64);
669#endif
670
671EXPORT_SYMBOL(jiffies);
672