diff options
Diffstat (limited to 'kernel/time.c')
-rw-r--r-- | kernel/time.c | 106 |
1 files changed, 57 insertions, 49 deletions
diff --git a/kernel/time.c b/kernel/time.c index 7927c2aa1..e16a7a150 100644 --- a/kernel/time.c +++ b/kernel/time.c @@ -216,32 +216,24 @@ void (*hardpps_ptr)(struct timeval *) = (void (*)(struct timeval *))0; /* adjtimex mainly allows reading (and writing, if superuser) of * kernel time-keeping variables. used by xntpd. */ -asmlinkage int sys_adjtimex(struct timex *txc_p) +int do_adjtimex(struct timex *txc) { long ltemp, mtemp, save_adjust; - struct timex txc; /* Local copy of parameter */ - - /* Copy the user data space into the kernel copy - * structure. But bear in mind that the structures - * may change - */ - if(copy_from_user(&txc, txc_p, sizeof(struct timex))) - return -EFAULT; /* In order to modify anything, you gotta be super-user! */ - if (txc.modes && !suser()) + if (txc->modes && !suser()) return -EPERM; /* Now we validate the data before disabling interrupts */ - if (txc.modes != ADJ_OFFSET_SINGLESHOT && (txc.modes & ADJ_OFFSET)) + if (txc->modes != ADJ_OFFSET_SINGLESHOT && (txc->modes & ADJ_OFFSET)) /* adjustment Offset limited to +- .512 seconds */ - if (txc.offset <= - MAXPHASE || txc.offset >= MAXPHASE ) + if (txc->offset <= - MAXPHASE || txc->offset >= MAXPHASE ) return -EINVAL; /* if the quartz is off by more than 10% something is VERY wrong ! */ - if (txc.modes & ADJ_TICK) - if (txc.tick < 900000/HZ || txc.tick > 1100000/HZ) + if (txc->modes & ADJ_TICK) + if (txc->tick < 900000/HZ || txc->tick > 1100000/HZ) return -EINVAL; cli(); /* SMP: global cli() is enough protection. */ @@ -250,37 +242,37 @@ asmlinkage int sys_adjtimex(struct timex *txc_p) save_adjust = time_adjust; /* If there are input parameters, then process them */ - if (txc.modes) + if (txc->modes) { if (time_state == TIME_BAD) time_state = TIME_OK; - if (txc.modes & ADJ_STATUS) - time_status = txc.status; + if (txc->modes & ADJ_STATUS) + time_status = txc->status; - if (txc.modes & ADJ_FREQUENCY) - time_freq = txc.freq; + if (txc->modes & ADJ_FREQUENCY) + time_freq = txc->freq; - if (txc.modes & ADJ_MAXERROR) - time_maxerror = txc.maxerror; + if (txc->modes & ADJ_MAXERROR) + time_maxerror = txc->maxerror; - if (txc.modes & ADJ_ESTERROR) - time_esterror = txc.esterror; + if (txc->modes & ADJ_ESTERROR) + time_esterror = txc->esterror; - if (txc.modes & ADJ_TIMECONST) - time_constant = txc.constant; + if (txc->modes & ADJ_TIMECONST) + time_constant = txc->constant; - if (txc.modes & ADJ_OFFSET) - if ((txc.modes == ADJ_OFFSET_SINGLESHOT) + if (txc->modes & ADJ_OFFSET) + if ((txc->modes == ADJ_OFFSET_SINGLESHOT) || !(time_status & STA_PLL)) { - time_adjust = txc.offset; + time_adjust = txc->offset; } else if ((time_status & STA_PLL)||(time_status & STA_PPSTIME)) { ltemp = (time_status & STA_PPSTIME && time_status & STA_PPSSIGNAL) ? - pps_offset : txc.offset; + pps_offset : txc->offset; /* * Scale the phase adjustment and @@ -335,30 +327,46 @@ asmlinkage int sys_adjtimex(struct timex *txc_p) else if (time_freq < -time_tolerance) time_freq = -time_tolerance; } /* STA_PLL || STA_PPSTIME */ - if (txc.modes & ADJ_TICK) - tick = txc.tick; + if (txc->modes & ADJ_TICK) + tick = txc->tick; } - txc.offset = save_adjust; - txc.freq = time_freq; - txc.maxerror = time_maxerror; - txc.esterror = time_esterror; - txc.status = time_status; - txc.constant = time_constant; - txc.precision = time_precision; - txc.tolerance = time_tolerance; - txc.time = xtime; - txc.tick = tick; - txc.ppsfreq = pps_freq; - txc.jitter = pps_jitter; - txc.shift = pps_shift; - txc.stabil = pps_stabil; - txc.jitcnt = pps_jitcnt; - txc.calcnt = pps_calcnt; - txc.errcnt = pps_errcnt; - txc.stbcnt = pps_stbcnt; + txc->offset = save_adjust; + txc->freq = time_freq; + txc->maxerror = time_maxerror; + txc->esterror = time_esterror; + txc->status = time_status; + txc->constant = time_constant; + txc->precision = time_precision; + txc->tolerance = time_tolerance; + txc->time = xtime; + txc->tick = tick; + txc->ppsfreq = pps_freq; + txc->jitter = pps_jitter; + txc->shift = pps_shift; + txc->stabil = pps_stabil; + txc->jitcnt = pps_jitcnt; + txc->calcnt = pps_calcnt; + txc->errcnt = pps_errcnt; + txc->stbcnt = pps_stbcnt; sti(); + return 0; +} + +asmlinkage int sys_adjtimex(struct timex *txc_p) +{ + struct timex txc; /* Local copy of parameter */ + int ret; + + /* Copy the user data space into the kernel copy + * structure. But bear in mind that the structures + * may change + */ + if(copy_from_user(&txc, txc_p, sizeof(struct timex))) + return -EFAULT; + if ((ret = do_adjtimex(&txc))) + return ret; return copy_to_user(txc_p, &txc, sizeof(struct timex)) ? -EFAULT : time_state; } |