RHEL4/kernel/time.c
<<
>>
Prefs
   1/*
   2 *  linux/kernel/time.c
   3 *
   4 *  Copyright (C) 1991, 1992  Linus Torvalds
   5 *
   6 *  This file contains the interface functions for the various
   7 *  time related system calls: time, stime, gettimeofday, settimeofday,
   8 *                             adjtime
   9 */
  10/*
  11 * Modification history kernel/time.c
  12 * 
  13 * 1993-09-02    Philip Gladstone
  14 *      Created file with time related functions from sched.c and adjtimex() 
  15 * 1993-10-08    Torsten Duwe
  16 *      adjtime interface update and CMOS clock write code
  17 * 1995-08-13    Torsten Duwe
  18 *      kernel PLL updated to 1994-12-13 specs (rfc-1589)
  19 * 1999-01-16    Ulrich Windl
  20 *      Introduced error checking for many cases in adjtimex().
  21 *      Updated NTP code according to technical memorandum Jan '96
  22 *      "A Kernel Model for Precision Timekeeping" by Dave Mills
  23 *      Allow time_constant larger than MAXTC(6) for NTP v4 (MAXTC == 10)
  24 *      (Even though the technical memorandum forbids it)
  25 * 2004-07-14    Christoph Lameter
  26 *      Added getnstimeofday to allow the posix timer functions to return
  27 *      with nanosecond accuracy
  28 */
  29
  30#include <linux/module.h>
  31#include <linux/timex.h>
  32#include <linux/errno.h>
  33#include <linux/smp_lock.h>
  34#include <asm/uaccess.h>
  35#include <asm/unistd.h>
  36#include <linux/fs.h>
  37
  38/* 
  39 * The timezone where the local system is located.  Used as a default by some
  40 * programs who obtain this value by using gettimeofday.
  41 */
  42struct timezone sys_tz;
  43
  44EXPORT_SYMBOL(sys_tz);
  45
  46#ifdef __ARCH_WANT_SYS_TIME
  47
  48/*
  49 * sys_time() can be implemented in user-level using
  50 * sys_gettimeofday().  Is this for backwards compatibility?  If so,
  51 * why not move it into the appropriate arch directory (for those
  52 * architectures that need it).
  53 *
  54 * XXX This function is NOT 64-bit clean!
  55 */
  56asmlinkage long sys_time(int __user * tloc)
  57{
  58        int i;
  59        struct timeval tv;
  60
  61        do_gettimeofday(&tv);
  62        i = tv.tv_sec;
  63
  64        if (tloc) {
  65                if (put_user(i,tloc))
  66                        i = -EFAULT;
  67        }
  68        return i;
  69}
  70
  71/*
  72 * sys_stime() can be implemented in user-level using
  73 * sys_settimeofday().  Is this for backwards compatibility?  If so,
  74 * why not move it into the appropriate arch directory (for those
  75 * architectures that need it).
  76 */
  77 
  78asmlinkage long sys_stime(time_t __user *tptr)
  79{
  80        struct timespec tv;
  81
  82        if (!capable(CAP_SYS_TIME))
  83                return -EPERM;
  84        if (get_user(tv.tv_sec, tptr))
  85                return -EFAULT;
  86
  87        tv.tv_nsec = 0;
  88        do_settimeofday(&tv);
  89        return 0;
  90}
  91
  92#endif /* __ARCH_WANT_SYS_TIME */
  93
  94asmlinkage long sys_gettimeofday(struct timeval __user *tv, struct timezone __user *tz)
  95{
  96        if (likely(tv != NULL)) {
  97                struct timeval ktv;
  98                do_gettimeofday(&ktv);
  99                if (copy_to_user(tv, &ktv, sizeof(ktv)))
 100                        return -EFAULT;
 101        }
 102        if (unlikely(tz != NULL)) {
 103                if (copy_to_user(tz, &sys_tz, sizeof(sys_tz)))
 104                        return -EFAULT;
 105        }
 106        return 0;
 107}
 108
 109/*
 110 * Adjust the time obtained from the CMOS to be UTC time instead of
 111 * local time.
 112 * 
 113 * This is ugly, but preferable to the alternatives.  Otherwise we
 114 * would either need to write a program to do it in /etc/rc (and risk
 115 * confusion if the program gets run more than once; it would also be 
 116 * hard to make the program warp the clock precisely n hours)  or
 117 * compile in the timezone information into the kernel.  Bad, bad....
 118 *
 119 *                                              - TYT, 1992-01-01
 120 *
 121 * The best thing to do is to keep the CMOS clock in universal time (UTC)
 122 * as real UNIX machines always do it. This avoids all headaches about
 123 * daylight saving times and warping kernel clocks.
 124 */
 125inline static void warp_clock(void)
 126{
 127        write_seqlock_irq(&xtime_lock);
 128        wall_to_monotonic.tv_sec -= sys_tz.tz_minuteswest * 60;
 129        xtime.tv_sec += sys_tz.tz_minuteswest * 60;
 130        time_interpolator_reset();
 131        write_sequnlock_irq(&xtime_lock);
 132        clock_was_set();
 133}
 134
 135/*
 136 * In case for some reason the CMOS clock has not already been running
 137 * in UTC, but in some local time: The first time we set the timezone,
 138 * we will warp the clock so that it is ticking UTC time instead of
 139 * local time. Presumably, if someone is setting the timezone then we
 140 * are running in an environment where the programs understand about
 141 * timezones. This should be done at boot time in the /etc/rc script,
 142 * as soon as possible, so that the clock can be set right. Otherwise,
 143 * various programs will get confused when the clock gets warped.
 144 */
 145
 146int do_sys_settimeofday(struct timespec *tv, struct timezone *tz)
 147{
 148        static int firsttime = 1;
 149
 150        if (!capable(CAP_SYS_TIME))
 151                return -EPERM;
 152                
 153        if (tz) {
 154                /* SMP safe, global irq locking makes it work. */
 155                sys_tz = *tz;
 156                if (firsttime) {
 157                        firsttime = 0;
 158                        if (!tv)
 159                                warp_clock();
 160                }
 161        }
 162        if (tv)
 163        {
 164                /* SMP safe, again the code in arch/foo/time.c should
 165                 * globally block out interrupts when it runs.
 166                 */
 167                return do_settimeofday(tv);
 168        }
 169        return 0;
 170}
 171
 172asmlinkage long sys_settimeofday(struct timeval __user *tv,
 173                                struct timezone __user *tz)
 174{
 175        struct timeval user_tv;
 176        struct timespec new_ts;
 177        struct timezone new_tz;
 178
 179        if (tv) {
 180                if (copy_from_user(&user_tv, tv, sizeof(*tv)))
 181                        return -EFAULT;
 182                new_ts.tv_sec = user_tv.tv_sec;
 183                new_ts.tv_nsec = user_tv.tv_usec * NSEC_PER_USEC;
 184        }
 185        if (tz) {
 186                if (copy_from_user(&new_tz, tz, sizeof(*tz)))
 187                        return -EFAULT;
 188        }
 189
 190        return do_sys_settimeofday(tv ? &new_ts : NULL, tz ? &new_tz : NULL);
 191}
 192
 193long pps_offset;                /* pps time offset (us) */
 194long pps_jitter = MAXTIME;      /* time dispersion (jitter) (us) */
 195
 196long pps_freq;                  /* frequency offset (scaled ppm) */
 197long pps_stabil = MAXFREQ;      /* frequency dispersion (scaled ppm) */
 198
 199long pps_valid = PPS_VALID;     /* pps signal watchdog counter */
 200
 201int pps_shift = PPS_SHIFT;      /* interval duration (s) (shift) */
 202
 203long pps_jitcnt;                /* jitter limit exceeded */
 204long pps_calcnt;                /* calibration intervals */
 205long pps_errcnt;                /* calibration errors */
 206long pps_stbcnt;                /* stability limit exceeded */
 207
 208/* hook for a loadable hardpps kernel module */
 209void (*hardpps_ptr)(struct timeval *);
 210
 211/* adjtimex mainly allows reading (and writing, if superuser) of
 212 * kernel time-keeping variables. used by xntpd.
 213 */
 214int do_adjtimex(struct timex *txc)
 215{
 216        long ltemp, mtemp, save_adjust;
 217        int result;
 218
 219        /* In order to modify anything, you gotta be super-user! */
 220        if (txc->modes && !capable(CAP_SYS_TIME))
 221                return -EPERM;
 222                
 223        /* Now we validate the data before disabling interrupts */
 224
 225        if ((txc->modes & ADJ_OFFSET_SINGLESHOT) == ADJ_OFFSET_SINGLESHOT)
 226          /* singleshot must not be used with any other mode bits */
 227                if (txc->modes != ADJ_OFFSET_SINGLESHOT)
 228                        return -EINVAL;
 229
 230        if (txc->modes != ADJ_OFFSET_SINGLESHOT && (txc->modes & ADJ_OFFSET))
 231          /* adjustment Offset limited to +- .512 seconds */
 232                if (txc->offset <= - MAXPHASE || txc->offset >= MAXPHASE )
 233                        return -EINVAL; 
 234
 235        /* if the quartz is off by more than 10% something is VERY wrong ! */
 236        if (txc->modes & ADJ_TICK)
 237                if (txc->tick <  900000/USER_HZ ||
 238                    txc->tick > 1100000/USER_HZ)
 239                        return -EINVAL;
 240
 241        write_seqlock_irq(&xtime_lock);
 242        result = time_state;    /* mostly `TIME_OK' */
 243
 244        /* Save for later - semantics of adjtime is to return old value */
 245        save_adjust = time_next_adjust ? time_next_adjust : time_adjust;
 246
 247#if 0   /* STA_CLOCKERR is never set yet */
 248        time_status &= ~STA_CLOCKERR;           /* reset STA_CLOCKERR */
 249#endif
 250        /* If there are input parameters, then process them */
 251        if (txc->modes)
 252        {
 253            if (txc->modes & ADJ_STATUS)        /* only set allowed bits */
 254                time_status =  (txc->status & ~STA_RONLY) |
 255                              (time_status & STA_RONLY);
 256
 257            if (txc->modes & ADJ_FREQUENCY) {   /* p. 22 */
 258                if (txc->freq > MAXFREQ || txc->freq < -MAXFREQ) {
 259                    result = -EINVAL;
 260                    goto leave;
 261                }
 262                time_freq = txc->freq - pps_freq;
 263            }
 264
 265            if (txc->modes & ADJ_MAXERROR) {
 266                if (txc->maxerror < 0 || txc->maxerror >= NTP_PHASE_LIMIT) {
 267                    result = -EINVAL;
 268                    goto leave;
 269                }
 270                time_maxerror = txc->maxerror;
 271            }
 272
 273            if (txc->modes & ADJ_ESTERROR) {
 274                if (txc->esterror < 0 || txc->esterror >= NTP_PHASE_LIMIT) {
 275                    result = -EINVAL;
 276                    goto leave;
 277                }
 278                time_esterror = txc->esterror;
 279            }
 280
 281            if (txc->modes & ADJ_TIMECONST) {   /* p. 24 */
 282                if (txc->constant < 0) {        /* NTP v4 uses values > 6 */
 283                    result = -EINVAL;
 284                    goto leave;
 285                }
 286                time_constant = txc->constant;
 287            }
 288
 289            if (txc->modes & ADJ_OFFSET) {      /* values checked earlier */
 290                if (txc->modes == ADJ_OFFSET_SINGLESHOT) {
 291                    /* adjtime() is independent from ntp_adjtime() */
 292                    if ((time_next_adjust = txc->offset) == 0)
 293                         time_adjust = 0;
 294                }
 295                else if ( time_status & (STA_PLL | STA_PPSTIME) ) {
 296                    ltemp = (time_status & (STA_PPSTIME | STA_PPSSIGNAL)) ==
 297                            (STA_PPSTIME | STA_PPSSIGNAL) ?
 298                            pps_offset : txc->offset;
 299
 300                    /*
 301                     * Scale the phase adjustment and
 302                     * clamp to the operating range.
 303                     */
 304                    if (ltemp > MAXPHASE)
 305                        time_offset = MAXPHASE << SHIFT_UPDATE;
 306                    else if (ltemp < -MAXPHASE)
 307                        time_offset = -(MAXPHASE << SHIFT_UPDATE);
 308                    else
 309                        time_offset = ltemp << SHIFT_UPDATE;
 310
 311                    /*
 312                     * Select whether the frequency is to be controlled
 313                     * and in which mode (PLL or FLL). Clamp to the operating
 314                     * range. Ugly multiply/divide should be replaced someday.
 315                     */
 316
 317                    if (time_status & STA_FREQHOLD || time_reftime == 0)
 318                        time_reftime = xtime.tv_sec;
 319                    mtemp = xtime.tv_sec - time_reftime;
 320                    time_reftime = xtime.tv_sec;
 321                    if (time_status & STA_FLL) {
 322                        if (mtemp >= MINSEC) {
 323                            ltemp = (time_offset / mtemp) << (SHIFT_USEC -
 324                                                              SHIFT_UPDATE);
 325                            if (ltemp < 0)
 326                                time_freq -= -ltemp >> SHIFT_KH;
 327                            else
 328                                time_freq += ltemp >> SHIFT_KH;
 329                        } else /* calibration interval too short (p. 12) */
 330                                result = TIME_ERROR;
 331                    } else {    /* PLL mode */
 332                        if (mtemp < MAXSEC) {
 333                            ltemp *= mtemp;
 334                            if (ltemp < 0)
 335                                time_freq -= -ltemp >> (time_constant +
 336                                                        time_constant +
 337                                                        SHIFT_KF - SHIFT_USEC);
 338                            else
 339                                time_freq += ltemp >> (time_constant +
 340                                                       time_constant +
 341                                                       SHIFT_KF - SHIFT_USEC);
 342                        } else /* calibration interval too long (p. 12) */
 343                                result = TIME_ERROR;
 344                    }
 345                    if (time_freq > time_tolerance)
 346                        time_freq = time_tolerance;
 347                    else if (time_freq < -time_tolerance)
 348                        time_freq = -time_tolerance;
 349                } /* STA_PLL || STA_PPSTIME */
 350            } /* txc->modes & ADJ_OFFSET */
 351            if (txc->modes & ADJ_TICK) {
 352                tick_usec = txc->tick;
 353                tick_nsec = TICK_USEC_TO_NSEC(tick_usec);
 354            }
 355        } /* txc->modes */
 356leave:  if ((time_status & (STA_UNSYNC|STA_CLOCKERR)) != 0
 357            || ((time_status & (STA_PPSFREQ|STA_PPSTIME)) != 0
 358                && (time_status & STA_PPSSIGNAL) == 0)
 359            /* p. 24, (b) */
 360            || ((time_status & (STA_PPSTIME|STA_PPSJITTER))
 361                == (STA_PPSTIME|STA_PPSJITTER))
 362            /* p. 24, (c) */
 363            || ((time_status & STA_PPSFREQ) != 0
 364                && (time_status & (STA_PPSWANDER|STA_PPSERROR)) != 0))
 365            /* p. 24, (d) */
 366                result = TIME_ERROR;
 367        
 368        if ((txc->modes & ADJ_OFFSET_SINGLESHOT) == ADJ_OFFSET_SINGLESHOT)
 369            txc->offset    = save_adjust;
 370        else {
 371            if (time_offset < 0)
 372                txc->offset = -(-time_offset >> SHIFT_UPDATE);
 373            else
 374                txc->offset = time_offset >> SHIFT_UPDATE;
 375        }
 376        txc->freq          = time_freq + pps_freq;
 377        txc->maxerror      = time_maxerror;
 378        txc->esterror      = time_esterror;
 379        txc->status        = time_status;
 380        txc->constant      = time_constant;
 381        txc->precision     = time_precision;
 382        txc->tolerance     = time_tolerance;
 383        txc->tick          = tick_usec;
 384        txc->ppsfreq       = pps_freq;
 385        txc->jitter        = pps_jitter >> PPS_AVG;
 386        txc->shift         = pps_shift;
 387        txc->stabil        = pps_stabil;
 388        txc->jitcnt        = pps_jitcnt;
 389        txc->calcnt        = pps_calcnt;
 390        txc->errcnt        = pps_errcnt;
 391        txc->stbcnt        = pps_stbcnt;
 392        write_sequnlock_irq(&xtime_lock);
 393        do_gettimeofday(&txc->time);
 394        return(result);
 395}
 396
 397asmlinkage long sys_adjtimex(struct timex __user *txc_p)
 398{
 399        struct timex txc;               /* Local copy of parameter */
 400        int ret;
 401
 402        /* Copy the user data space into the kernel copy
 403         * structure. But bear in mind that the structures
 404         * may change
 405         */
 406        if(copy_from_user(&txc, txc_p, sizeof(struct timex)))
 407                return -EFAULT;
 408        ret = do_adjtimex(&txc);
 409        return copy_to_user(txc_p, &txc, sizeof(struct timex)) ? -EFAULT : ret;
 410}
 411
 412struct timespec current_kernel_time(void)
 413{
 414        struct timespec now;
 415        unsigned long seq;
 416
 417        do {
 418                seq = read_seqbegin(&xtime_lock);
 419                
 420                now = xtime;
 421        } while (read_seqretry(&xtime_lock, seq));
 422
 423        return now; 
 424}
 425
 426EXPORT_SYMBOL(current_kernel_time);
 427
 428/**
 429 * current_fs_time - Return FS time
 430 * @sb: Superblock.
 431 *
 432 * Return the current time truncated to the time granuality supported by
 433 * the fs.
 434 */
 435struct timespec current_fs_time(struct super_block *sb)
 436{
 437        struct timespec now = current_kernel_time();
 438        return timespec_trunc(now, get_sb_time_gran(sb));
 439}
 440EXPORT_SYMBOL(current_fs_time);
 441
 442/**
 443 * timespec_trunc - Truncate timespec to a granuality
 444 * @t: Timespec
 445 * @gran: Granuality in ns.
 446 *
 447 * Truncate a timespec to a granuality. gran must be smaller than a second.
 448 * Always rounds down.
 449 *
 450 * This function should be only used for timestamps returned by
 451 * current_kernel_time() or CURRENT_TIME, not with do_gettimeofday() because
 452 * it doesn't handle the better resolution of the later.
 453 */
 454struct timespec timespec_trunc(struct timespec t, unsigned gran)
 455{
 456        /*
 457         * Division is pretty slow so avoid it for common cases.
 458         * Currently current_kernel_time() never returns better than
 459         * jiffies resolution. Exploit that.
 460         */
 461        if (gran <= jiffies_to_usecs(1) * 1000) {
 462                /* nothing */
 463        } else if (gran == 1000000000) {
 464                t.tv_nsec = 0;
 465        } else {
 466                t.tv_nsec -= t.tv_nsec % gran;
 467        }
 468        return t;
 469}
 470EXPORT_SYMBOL(timespec_trunc);
 471
 472#ifdef CONFIG_TIME_INTERPOLATION
 473void getnstimeofday (struct timespec *tv)
 474{
 475        unsigned long seq,sec,nsec;
 476
 477        do {
 478                seq = read_seqbegin(&xtime_lock);
 479                sec = xtime.tv_sec;
 480                nsec = xtime.tv_nsec+time_interpolator_get_offset();
 481        } while (unlikely(read_seqretry(&xtime_lock, seq)));
 482
 483        while (unlikely(nsec >= NSEC_PER_SEC)) {
 484                nsec -= NSEC_PER_SEC;
 485                ++sec;
 486        }
 487        tv->tv_sec = sec;
 488        tv->tv_nsec = nsec;
 489}
 490
 491int do_settimeofday (struct timespec *tv)
 492{
 493        time_t wtm_sec, sec = tv->tv_sec;
 494        long wtm_nsec, nsec = tv->tv_nsec;
 495
 496        if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
 497                return -EINVAL;
 498
 499        write_seqlock_irq(&xtime_lock);
 500        {
 501                /*
 502                 * This is revolting. We need to set "xtime" correctly. However, the value
 503                 * in this location is the value at the most recent update of wall time.
 504                 * Discover what correction gettimeofday would have done, and then undo
 505                 * it!
 506                 */
 507                nsec -= time_interpolator_get_offset();
 508
 509                wtm_sec  = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec);
 510                wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec);
 511
 512                set_normalized_timespec(&xtime, sec, nsec);
 513                set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec);
 514
 515                time_adjust = 0;                /* stop active adjtime() */
 516                time_status |= STA_UNSYNC;
 517                time_maxerror = NTP_PHASE_LIMIT;
 518                time_esterror = NTP_PHASE_LIMIT;
 519                time_interpolator_reset();
 520        }
 521        write_sequnlock_irq(&xtime_lock);
 522        clock_was_set();
 523        return 0;
 524}
 525
 526EXPORT_SYMBOL(do_settimeofday);
 527
 528void do_gettimeofday (struct timeval *tv)
 529{
 530        unsigned long seq, nsec, usec, sec, offset;
 531        do {
 532                seq = read_seqbegin(&xtime_lock);
 533                offset = time_interpolator_get_offset();
 534                sec = xtime.tv_sec;
 535                nsec = xtime.tv_nsec;
 536        } while (unlikely(read_seqretry(&xtime_lock, seq)));
 537
 538        usec = (nsec + offset) / 1000;
 539
 540        while (unlikely(usec >= USEC_PER_SEC)) {
 541                usec -= USEC_PER_SEC;
 542                ++sec;
 543        }
 544
 545        tv->tv_sec = sec;
 546        tv->tv_usec = usec;
 547}
 548
 549EXPORT_SYMBOL(do_gettimeofday);
 550
 551
 552#else
 553/*
 554 * Simulate gettimeofday using do_gettimeofday which only allows a timeval
 555 * and therefore only yields usec accuracy
 556 */
 557void getnstimeofday(struct timespec *tv)
 558{
 559        struct timeval x;
 560
 561        do_gettimeofday(&x);
 562        tv->tv_sec = x.tv_sec;
 563        tv->tv_nsec = x.tv_usec * NSEC_PER_USEC;
 564}
 565#endif
 566
 567#if (BITS_PER_LONG < 64)
 568u64 get_jiffies_64(void)
 569{
 570        unsigned long seq;
 571        u64 ret;
 572
 573        do {
 574                seq = read_seqbegin(&xtime_lock);
 575                ret = jiffies_64;
 576        } while (read_seqretry(&xtime_lock, seq));
 577        return ret;
 578}
 579
 580EXPORT_SYMBOL(get_jiffies_64);
 581#endif
 582
 583EXPORT_SYMBOL(jiffies);
 584