diff --git a/sys/kern/kern_time.c b/sys/kern/kern_time.c
index 8383eae..2f8979b 100644
--- a/sys/kern/kern_time.c
+++ b/sys/kern/kern_time.c
@@ -67,10 +67,9 @@ struct timezone tz;
  * timers when they expire.
  */
 
-static int	nanosleep1 (struct timespec *rqt,
-		    struct timespec *rmt);
-static int	settime (struct timeval *);
-static void	timevalfix (struct timeval *);
+static int	nanosleep1(struct timespec *rqt, struct timespec *rmt);
+static int	settime(struct timeval *);
+static void	timevalfix(struct timeval *);
 
 static int     sleep_hard_us = 100;
 SYSCTL_INT(_kern, OID_AUTO, sleep_hard_us, CTLFLAG_RW, &sleep_hard_us, 0, "")
@@ -140,56 +139,71 @@ settime(struct timeval *tv)
 	return (0);
 }
 
-/* ARGSUSED */
 int
-sys_clock_gettime(struct clock_gettime_args *uap)
+kern_clock_gettime(clockid_t clock_id, struct timespec *ats)
 {
-	struct timespec ats;
-
-	switch(uap->clock_id) {
+	switch(clock_id) {
 	case CLOCK_REALTIME:
-		nanotime(&ats);
-		return (copyout(&ats, uap->tp, sizeof(ats)));
+		nanotime(ats);
 	case CLOCK_MONOTONIC:
-		nanouptime(&ats);
-		return (copyout(&ats, uap->tp, sizeof(ats)));
+		nanouptime(ats);
 	default:
 		return (EINVAL);
 	}
+
+	return (0);
 }
 
 /* ARGSUSED */
 int
-sys_clock_settime(struct clock_settime_args *uap)
+sys_clock_gettime(struct clock_gettime_args *uap)
+{
+	struct timespec ats;
+	int error;
+
+	error = kern_clock_gettime(uap->clock_id, &ats);
+	if (error == 0)
+		error = copyout(&ats, uap->tp, sizeof(ats))
+	
+	return (error);
+}
+
+int
+kern_clock_settime(clockid_t clock_id, struct timespec *ats)
 {
 	struct thread *td = curthread;
 	struct timeval atv;
-	struct timespec ats;
 	int error;
 
 	if ((error = priv_check(td, PRIV_ROOT)) != 0)
 		return (error);
-	switch(uap->clock_id) {
-	case CLOCK_REALTIME:
-		if ((error = copyin(uap->tp, &ats, sizeof(ats))) != 0)
-			return (error);
-		if (ats.tv_nsec < 0 || ats.tv_nsec >= 1000000000)
-			return (EINVAL);
-		/* XXX Don't convert nsec->usec and back */
-		TIMESPEC_TO_TIMEVAL(&atv, &ats);
-		error = settime(&atv);
-		return (error);
-	default:
+	if (clock_id != CLOCK_REALTIME)
 		return (EINVAL);
-	}
+	if (ats->tv_nsec < 0 || ats->tv_nsec >= 1000000000)
+		return (EINVAL);
+
+	TIMESPEC_TO_TIMEVAL(&atv, ats);
+	error = settime(&atv);
+	return (error);
 }
 
+/* ARGSUSED */
 int
-sys_clock_getres(struct clock_getres_args *uap)
+sys_clock_settime(struct clock_settime_args *uap)
 {
-	struct timespec ts;
+	struct timespec ats;
+	int error;
+
+	if ((error = copyin(uap->tp, &ats, sizeof(ats))) != 0)
+		return (error);
+	
+	return (kern_clock_settime(uap->clock_id, &ats));
+}
 
-	switch(uap->clock_id) {
+int
+kern_clock_getres(clockid_t clock_id, struct timespec *ts)
+{
+	switch(clock_id) {
 	case CLOCK_REALTIME:
 	case CLOCK_MONOTONIC:
 		/*
@@ -198,12 +212,26 @@ sys_clock_getres(struct clock_getres_args *uap)
 		 * if rounding down would give 0.  Perfect rounding
 		 * is unimportant.
 		 */
-		ts.tv_sec = 0;
-		ts.tv_nsec = 1000000000 / sys_cputimer->freq + 1;
-		return(copyout(&ts, uap->tp, sizeof(ts)));
+		ts->tv_sec = 0;
+		ts->tv_nsec = 1000000000 / sys_cputimer->freq + 1;
 	default:
 		return(EINVAL);
 	}
+
+	return (0);
+}
+
+int
+sys_clock_getres(struct clock_getres_args *uap)
+{
+	int error;
+	struct timespec ts;
+
+	error = kern_clock_getres(uap->clock_id, &ts);
+	if (error == 0)
+		error = copyout(&ts, uap->tp, sizeof(ts));
+	
+	return (error);
 }
 
 /*
diff --git a/sys/sys/time.h b/sys/sys/time.h
index 8531295..88e6ae9 100644
--- a/sys/sys/time.h
+++ b/sys/sys/time.h
@@ -226,6 +226,9 @@ time_t	get_approximate_time_t(void);
 void	set_timeofday(struct timespec *ts);
 void	kern_adjtime(int64_t, int64_t *);
 void	kern_reladjtime(int64_t);
+int	kern_clock_gettime(clockid_t, struct timespec *);
+int	kern_clock_settime(clockid_t, struct timespec *);
+int	kern_clock_getres(clockid_t, struct timespec *);
 void	timevaladd (struct timeval *, const struct timeval *);
 void	timevalsub (struct timeval *, const struct timeval *);
 int	tvtohz_high (struct timeval *);
