summaryrefslogtreecommitdiff
path: root/sys/kern
diff options
context:
space:
mode:
authorChris Kuethe <ckuethe@cvs.openbsd.org>2009-06-05 15:17:03 +0000
committerChris Kuethe <ckuethe@cvs.openbsd.org>2009-06-05 15:17:03 +0000
commit6c3ef1a2ea4a552a93af9adde4436df8dc99b12b (patch)
tree2d6a0d3822f9813576d0239d1f0ea36b14396d9b /sys/kern
parent469bd0bed7e9bdffe5d255ac77d319b97ec9c7b7 (diff)
abort any time adjustment in progress if the clock is set with settimeofday
ok millert
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/kern_time.c40
1 files changed, 27 insertions, 13 deletions
diff --git a/sys/kern/kern_time.c b/sys/kern/kern_time.c
index 2f407187375..cbf0c4e27f5 100644
--- a/sys/kern/kern_time.c
+++ b/sys/kern/kern_time.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_time.c,v 1.65 2008/09/19 23:36:24 djm Exp $ */
+/* $OpenBSD: kern_time.c,v 1.66 2009/06/05 15:17:02 ckuethe Exp $ */
/* $NetBSD: kern_time.c,v 1.20 1996/02/18 11:57:06 fvdl Exp $ */
/*
@@ -66,7 +66,7 @@ int
settime(struct timespec *ts)
{
struct timespec now;
-
+
/*
* Don't allow the time to be set forward so far it will wrap
@@ -319,6 +319,16 @@ sys_gettimeofday(struct proc *p, void *v, register_t *retval)
return (error);
}
+#ifdef __HAVE_TIMECOUNTER
+struct timeval adjtimedelta; /* unapplied time correction */
+#else
+int tickdelta; /* current clock skew, us. per tick */
+long timedelta; /* unapplied time correction, us. */
+long bigadj = 1000000; /* use 10x skew above bigadj us. */
+int64_t ntp_tick_permanent;
+int64_t ntp_tick_acc;
+#endif
+
/* ARGSUSED */
int
sys_settimeofday(struct proc *p, void *v, register_t *retval)
@@ -343,6 +353,20 @@ sys_settimeofday(struct proc *p, void *v, register_t *retval)
if (SCARG(uap, tv)) {
struct timespec ts;
+ /*
+ * Adjtime in progress is meaningless or harmful after
+ * setting the clock. Cancel adjtime and then set new time.
+ */
+#ifdef __HAVE_TIMECOUNTER
+ adjtimedelta.tv_usec = 0;
+ adjtimedelta.tv_sec = 0;
+#else
+ int s = splclock();
+ tickdelta = 0;
+ timedelta = 0;
+ splx(s);
+#endif
+
TIMEVAL_TO_TIMESPEC(&atv, &ts);
if ((error = settime(&ts)) != 0)
return (error);
@@ -352,16 +376,6 @@ sys_settimeofday(struct proc *p, void *v, register_t *retval)
return (0);
}
-#ifdef __HAVE_TIMECOUNTER
-struct timeval adjtimedelta; /* unapplied time correction */
-#else
-int tickdelta; /* current clock skew, us. per tick */
-long timedelta; /* unapplied time correction, us. */
-long bigadj = 1000000; /* use 10x skew above bigadj us. */
-int64_t ntp_tick_permanent;
-int64_t ntp_tick_acc;
-#endif
-
/* ARGSUSED */
int
sys_adjfreq(struct proc *p, void *v, register_t *retval)
@@ -478,7 +492,7 @@ sys_adjtime(struct proc *p, void *v, register_t *retval)
odelta = ndelta;
ndelta += atv.tv_usec;
if (atv.tv_usec > 0 && ndelta <= odelta)
- ndelta = LONG_MAX;
+ ndelta = LONG_MAX;
else if (atv.tv_usec < 0 && ndelta >= odelta)
ndelta = LONG_MIN;
}