kernel/time.c
31331 /*
31332 * linux/kernel/time.c
31333 *
31334 * Copyright (C) 1991, 1992 Linus Torvalds
31335 *
31336 * This file contains the interface functions for the
31337 * various time related system calls: time, stime,
31338 * gettimeofday, settimeofday, adjtime */
31339 /*
31340 * Modification history kernel/time.c
31341 *
31342 * 1993-09-02 Philip Gladstone
31343 * Created file with time related functions from
31344 * sched.c and adjtimex()
31345 * 1993-10-08 Torsten Duwe
31346 * adjtime interface update and CMOS clock write
31347 * code
31348 * 1995-08-13 Torsten Duwe
31349 * kernel PLL updated to 1994-12-13 specs (rfc-1589)
31350 * 1999-01-16 Ulrich Windl
31351 * Introduced error checking for many cases in
31352 * adjtimex(). Updated NTP code according to
31353 * technical memorandum Jan '96 "A Kernel Model for
31354 * Precision Timekeeping" by Dave Mills Allow
31355 * time_constant larger than MAXTC(6) for NTP v4
31356 * (MAXTC == 10) (Even though the technical
31357 * memorandum forbids it) */
31358
31359 #include <linux/mm.h>
31360 #include <linux/timex.h>
31361 #include <linux/smp_lock.h>
31362
31363 #include <asm/uaccess.h>
31364
31365 /* The timezone where the local system is located. Used
31366 * as a default by some programs who obtain this value by
31367 * using gettimeofday. */
31368 struct timezone sys_tz = { 0, 0};
31369
31370 static void do_normal_gettime(struct timeval * tm)
31371 {
31372 *tm=xtime;
31373 }
31374
31375 void (*do_get_fast_time)(struct timeval *) =
31376 do_normal_gettime;
31377
31378 /* Generic way to access 'xtime' (the current time of
31379 * day). This can be changed if the platform provides a
31380 * more accurate (and fast!) version. */
31381
31382 void get_fast_time(struct timeval * t)
31383 {
31384 do_get_fast_time(t);
31385 }
31386
31387 #ifndef __alpha__
31388
31389 /* sys_time() can be implemented in user-level using
31390 * sys_gettimeofday(). Is this for backwards
31391 * compatibility? If so, why not move it into the
31392 * appropriate arch directory (for those architectures
31393 * that need it). */
31394 asmlinkage int sys_time(int * tloc)
31395 {
31396 int i;
31397
31398 /* SMP: This is fairly trivial. We grab CURRENT_TIME
31399 * and stuff it to user space. No side effects */
31400 i = CURRENT_TIME;
31401 if (tloc) {
31402 if (put_user(i,tloc))
31403 i = -EFAULT;
31404 }
31405 return i;
31406 }
31407
31408 /* sys_stime() can be implemented in user-level using
31409 * sys_settimeofday(). Is this for backwards
31410 * compatibility? If so, why not move it into the
31411 * appropriate arch directory (for those architectures
31412 * that need it). */
31413 asmlinkage int sys_stime(int * tptr)
31414 {
31415 int value;
31416
31417 if (!capable(CAP_SYS_TIME))
31418 return -EPERM;
31419 if (get_user(value, tptr))
31420 return -EFAULT;
31421 cli();
31422 xtime.tv_sec = value;
31423 xtime.tv_usec = 0;
31424 time_adjust = 0; /* stop active adjtime() */
31425 time_status |= STA_UNSYNC;
31426 time_maxerror = NTP_PHASE_LIMIT;
31427 time_esterror = NTP_PHASE_LIMIT;
31428 sti();
31429 return 0;
31430 }
31431
31432 #endif
31433
31434 asmlinkage int sys_gettimeofday(struct timeval *tv,
31435 struct timezone *tz)
31436 {
31437 if (tv) {
31438 struct timeval ktv;
31439 do_gettimeofday(&ktv);
31440 if (copy_to_user(tv, &ktv, sizeof(ktv)))
31441 return -EFAULT;
31442 }
31443 if (tz) {
31444 if (copy_to_user(tz, &sys_tz, sizeof(sys_tz)))
31445 return -EFAULT;
31446 }
31447 return 0;
31448 }
31449
31450 /* Adjust the time obtained from the CMOS to be UTC time
31451 * instead of local time.
31452 *
31453 * This is ugly, but preferable to the alternatives.
31454 * Otherwise we would either need to write a program to
31455 * do it in /etc/rc (and risk confusion if the program
31456 * gets run more than once; it would also be hard to make
31457 * the program warp the clock precisely n hours) or
31458 * compile in the timezone information into the kernel.
31459 * Bad, bad....
31460 *
31461 * - TYT, 1992-01-01
31462 *
31463 * The best thing to do is to keep the CMOS clock in
31464 * universal time (UTC) as real UNIX machines always do
31465 * it. This avoids all headaches about daylight saving
31466 * times and warping kernel clocks. */
31467 inline static void warp_clock(void)
31468 {
31469 cli();
31470 xtime.tv_sec += sys_tz.tz_minuteswest * 60;
31471 sti();
31472 }
31473
31474 /* In case for some reason the CMOS clock has not already
31475 * been running in UTC, but in some local time: The first
31476 * time we set the timezone, we will warp the clock so
31477 * that it is ticking UTC time instead of local
31478 * time. Presumably, if someone is setting the timezone
31479 * then we are running in an environment where the
31480 * programs understand about timezones. This should be
31481 * done at boot time in the /etc/rc script, as soon as
31482 * possible, so that the clock can be set
31483 * right. Otherwise, various programs will get confused
31484 * when the clock gets warped. */
31485 int do_sys_settimeofday(struct timeval *tv,
31486 struct timezone *tz)
31487 {
31488 static int firsttime = 1;
31489
31490 if (!capable(CAP_SYS_TIME))
31491 return -EPERM;
31492
31493 if (tz) {
31494 /* SMP safe, global irq locking makes it work. */
31495 sys_tz = *tz;
31496 if (firsttime) {
31497 firsttime = 0;
31498 if (!tv)
31499 warp_clock();
31500 }
31501 }
31502 if (tv)
31503 {
31504 /* SMP safe, again the code in arch/foo/time.c should
31505 * globally block out interrupts when it runs.
31506 */
31507 do_settimeofday(tv);
31508 }
31509 return 0;
31510 }
31511
31512 asmlinkage int sys_settimeofday(struct timeval *tv,
31513 struct timezone *tz)
31514 {
31515 struct timeval new_tv;
31516 struct timezone new_tz;
31517
31518 if (tv) {
31519 if (copy_from_user(&new_tv, tv, sizeof(*tv)))
31520 return -EFAULT;
31521 }
31522 if (tz) {
31523 if (copy_from_user(&new_tz, tz, sizeof(*tz)))
31524 return -EFAULT;
31525 }
31526
31527 return do_sys_settimeofday(tv ? &new_tv : NULL,
31528 tz ? &new_tz : NULL);
31529 }
31530
31531 long pps_offset = 0; /* pps time offset (us) */
31532 long pps_jitter = MAXTIME; /* time dispersion (jitter)
31533 (us) */
31534 long pps_freq = 0; /* frequency offset (scaled
31535 ppm) */
31536 long pps_stabil = MAXFREQ; /* frequency dispersion
31537 (scaled ppm) */
31538 long pps_valid = PPS_VALID; /* pps signal watchdog
31539 counter */
31540 int pps_shift = PPS_SHIFT; /* interval duration (s)
31541 (shift) */
31542 long pps_jitcnt = 0; /* jitter limit exceeded */
31543 long pps_calcnt = 0; /* calibration intervals */
31544 long pps_errcnt = 0; /* calibration errors */
31545 long pps_stbcnt = 0; /* stability limit exceeded*/
31546
31547 /* hook for a loadable hardpps kernel module */
31548 void (*hardpps_ptr)(struct timeval *) =
31549 (void (*)(struct timeval *))0;
31550
31551 /* adjtimex mainly allows reading (and writing, if
31552 * superuser) of kernel time-keeping variables. used by
31553 * xntpd. */
31554 int do_adjtimex(struct timex *txc)
31555 {
31556 long ltemp, mtemp, save_adjust;
31557 int result = time_state; /* mostly `TIME_OK' */
31558
31559 /* In order to modify anything, you gotta be
31560 * super-user! */
31561 if (txc->modes && !capable(CAP_SYS_TIME))
31562 return -EPERM;
31563
31564 /* Now we validate the data before disabling interrupts
31565 */
31566 if (txc->modes != ADJ_OFFSET_SINGLESHOT &&
31567 (txc->modes & ADJ_OFFSET))
31568 /* adjustment Offset limited to +- .512 seconds */
31569 if (txc->offset <= - MAXPHASE ||
31570 txc->offset >= MAXPHASE)
31571 return -EINVAL;
31572
31573 /* if the quartz is off by more than 10% something is
31574 * VERY wrong ! */
31575 if (txc->modes & ADJ_TICK)
31576 if (txc->tick < 900000/HZ || txc->tick > 1100000/HZ)
31577 return -EINVAL;
31578
31579 cli(); /* SMP: global cli() is enough protection. */
31580
31581 /* Save for later - semantics of adjtime is to return
31582 * old value */
31583 save_adjust = time_adjust;
31584
31585 #if 0 /* STA_CLOCKERR is never set yet */
31586 time_status &= ~STA_CLOCKERR; /* reset STA_CLOCKERR */
31587 #endif
31588 /* If there are input parameters, then process them */
31589 if (txc->modes)
31590 {
31591 if (txc->modes & ADJ_STATUS)
31592 /* only set allowed bits */
31593 time_status = (txc->status & ~STA_RONLY) |
31594 (time_status & STA_RONLY);
31595
31596 if (txc->modes & ADJ_FREQUENCY) { /* p. 22 */
31597 if (txc->freq > MAXFREQ || txc->freq < -MAXFREQ){
31598 result = -EINVAL;
31599 goto leave;
31600 }
31601 time_freq = txc->freq - pps_freq;
31602 }
31603
31604 if (txc->modes & ADJ_MAXERROR) {
31605 if (txc->maxerror < 0 ||
31606 txc->maxerror >= NTP_PHASE_LIMIT) {
31607 result = -EINVAL;
31608 goto leave;
31609 }
31610 time_maxerror = txc->maxerror;
31611 }
31612
31613 if (txc->modes & ADJ_ESTERROR) {
31614 if (txc->esterror < 0 ||
31615 txc->esterror >= NTP_PHASE_LIMIT) {
31616 result = -EINVAL;
31617 goto leave;
31618 }
31619 time_esterror = txc->esterror;
31620 }
31621
31622 if (txc->modes & ADJ_TIMECONST) { /* p. 24 */
31623 if (txc->constant < 0) { /*NTP v4 uses values > 6*/
31624 result = -EINVAL;
31625 goto leave;
31626 }
31627 time_constant = txc->constant;
31628 }
31629
31630 /* values checked earlier */
31631 if (txc->modes & ADJ_OFFSET) {
31632 if (txc->modes == ADJ_OFFSET_SINGLESHOT) {
31633 /* adjtime() is independent from ntp_adjtime() */
31634 time_adjust = txc->offset;
31635 }
31636 else if ( time_status & (STA_PLL | STA_PPSTIME) ) {
31637 ltemp =
31638 (time_status & (STA_PPSTIME | STA_PPSSIGNAL))
31639 == (STA_PPSTIME | STA_PPSSIGNAL)
31640 ? pps_offset : txc->offset;
31641
31642 /* Scale the phase adjustment and clamp to the
31643 * operating range. */
31644 if (ltemp > MAXPHASE)
31645 time_offset = MAXPHASE << SHIFT_UPDATE;
31646 else if (ltemp < -MAXPHASE)
31647 time_offset = -(MAXPHASE << SHIFT_UPDATE);
31648 else
31649 time_offset = ltemp << SHIFT_UPDATE;
31650
31651 /* Select whether the frequency is to be
31652 * controlled and in which mode (PLL or
31653 * FLL). Clamp to the operating range. Ugly
31654 * multiply/divide should be replaced someday.
31655 */
31656
31657 if (time_status & STA_FREQHOLD ||
31658 time_reftime == 0)
31659 time_reftime = xtime.tv_sec;
31660 mtemp = xtime.tv_sec - time_reftime;
31661 time_reftime = xtime.tv_sec;
31662 if (time_status & STA_FLL) {
31663 if (mtemp >= MINSEC) {
31664 ltemp = (time_offset / mtemp) <<
31665 (SHIFT_USEC - SHIFT_UPDATE);
31666 if (ltemp < 0)
31667 time_freq -= -ltemp >> SHIFT_KH;
31668 else
31669 time_freq += ltemp >> SHIFT_KH;
31670 } else
31671 /* calibration interval too short (p. 12) */
31672 result = TIME_ERROR;
31673 } else { /* PLL mode */
31674 if (mtemp < MAXSEC) {
31675 ltemp *= mtemp;
31676 if (ltemp < 0)
31677 time_freq -= -ltemp >>
31678 (time_constant +
31679 time_constant +
31680 SHIFT_KF - SHIFT_USEC);
31681 else
31682 time_freq += ltemp >>
31683 (time_constant +
31684 time_constant +
31685 SHIFT_KF - SHIFT_USEC);
31686 } else
31687 /* calibration interval too long (p. 12) */
31688 result = TIME_ERROR;
31689 }
31690 if (time_freq > time_tolerance)
31691 time_freq = time_tolerance;
31692 else if (time_freq < -time_tolerance)
31693 time_freq = -time_tolerance;
31694 } /* STA_PLL || STA_PPSTIME */
31695 } /* txc->modes & ADJ_OFFSET */
31696 if (txc->modes & ADJ_TICK) {
31697 /* if the quartz is off by more than 10% something
31698 is VERY wrong ! */
31699 if (txc->tick < 900000/HZ ||
31700 txc->tick > 1100000/HZ) {
31701 result = -EINVAL;
31702 goto leave;
31703 }
31704 tick = txc->tick;
31705 }
31706 } /* txc->modes */
31707 leave:
31708 if ((time_status & (STA_UNSYNC|STA_CLOCKERR)) != 0
31709 || ((time_status & (STA_PPSFREQ|STA_PPSTIME)) != 0
31710 && (time_status & STA_PPSSIGNAL) == 0)
31711 /* p. 24, (b) */
31712 || ((time_status & (STA_PPSTIME|STA_PPSJITTER))
31713 == (STA_PPSTIME|STA_PPSJITTER))
31714 /* p. 24, (c) */
31715 || ((time_status & STA_PPSFREQ) != 0
31716 && (time_status &
31717 (STA_PPSWANDER|STA_PPSERROR)) != 0))
31718 /* p. 24, (d) */
31719 result = TIME_ERROR;
31720
31721 if ((txc->modes & ADJ_OFFSET_SINGLESHOT) ==
31722 ADJ_OFFSET_SINGLESHOT)
31723 txc->offset = save_adjust;
31724 else {
31725 if (time_offset < 0)
31726 txc->offset = -(-time_offset >> SHIFT_UPDATE);
31727 else
31728 txc->offset = time_offset >> SHIFT_UPDATE;
31729 }
31730 txc->freq = time_freq + pps_freq;
31731 txc->maxerror = time_maxerror;
31732 txc->esterror = time_esterror;
31733 txc->status = time_status;
31734 txc->constant = time_constant;
31735 txc->precision = time_precision;
31736 txc->tolerance = time_tolerance;
31737 do_gettimeofday(&txc->time);
31738 txc->tick = tick;
31739 txc->ppsfreq = pps_freq;
31740 txc->jitter = pps_jitter >> PPS_AVG;
31741 txc->shift = pps_shift;
31742 txc->stabil = pps_stabil;
31743 txc->jitcnt = pps_jitcnt;
31744 txc->calcnt = pps_calcnt;
31745 txc->errcnt = pps_errcnt;
31746 txc->stbcnt = pps_stbcnt;
31747
31748 sti();
31749 return(result);
31750 }
31751
31752 asmlinkage int sys_adjtimex(struct timex *txc_p)
31753 {
31754 struct timex txc; /* Local copy of parameter */
31755 int ret;
31756
31757 /* Copy the user data space into the kernel copy
31758 * structure. But bear in mind that the structures may
31759 * change */
31760 if(copy_from_user(&txc, txc_p, sizeof(struct timex)))
31761 return -EFAULT;
31762 ret = do_adjtimex(&txc);
31763 return copy_to_user(txc_p, &txc, sizeof(struct timex))
31764 ? -EFAULT : ret;
31765 }
Сайт управляется системой
uCoz