diff --git a/sys/arch/xen/conf/GENERIC b/sys/arch/xen/conf/GENERIC index f67e9125ef2c..07e67fc2c8d9 100644 --- a/sys/arch/xen/conf/GENERIC +++ b/sys/arch/xen/conf/GENERIC @@ -1,4 +1,4 @@ -# $NetBSD: GENERIC,v 1.15 2004/09/04 23:29:57 manu Exp $ +# $NetBSD: GENERIC,v 1.16 2004/09/23 02:24:22 tls Exp $ # NetBSD: GENERIC,v 1.596 2004/04/07 13:13:59 augustss Exp # # GENERIC machine description file @@ -23,14 +23,13 @@ include "arch/xen/conf/std.xen" options INCLUDE_CONFIG_FILE # embed config file in kernel binary -#ident "GENERIC-$Revision: 1.15 $" +#ident "GENERIC-$Revision: 1.16 $" maxusers 32 # estimated number of users # options XEN options DOM0OPS -options HZ=50 # CPU support. At least one is REQUIRED. options I686_CPU @@ -55,7 +54,7 @@ options I686_CPU options INSECURE # disable kernel security levels - X needs this options RTC_OFFSET=0 # hardware clock is this many mins. west of GMT -#options NTP # NTP phase/frequency locked loop +options NTP # NTP phase/frequency locked loop #options NO_TSC_TIME # Don't use TSC microtime, even if available. # Improves time behavior under VMware. diff --git a/sys/arch/xen/conf/XEN b/sys/arch/xen/conf/XEN index b1a996309f50..2405bdc78be3 100644 --- a/sys/arch/xen/conf/XEN +++ b/sys/arch/xen/conf/XEN @@ -1,4 +1,4 @@ -# $NetBSD: XEN,v 1.12 2004/09/04 23:29:57 manu Exp $ +# $NetBSD: XEN,v 1.13 2004/09/23 02:24:22 tls Exp $ include "arch/xen/conf/std.xen" @@ -13,7 +13,6 @@ maxusers 32 # estimated number of users # options XEN options DOM0OPS -options HZ=50 #options I586_CPU options I686_CPU @@ -29,7 +28,7 @@ options I686_CPU options INSECURE # disable kernel security levels - X needs this options RTC_OFFSET=0 # hardware clock is this many mins. west of GMT -#options NTP # NTP phase/frequency locked loop +options NTP # NTP phase/frequency locked loop options KTRACE # system call tracing via ktrace(1) #options SYSTRACE # system call vetting via systrace(1) diff --git a/sys/arch/xen/i386/locore.S b/sys/arch/xen/i386/locore.S index 78153d76eb3b..a3bb95182c5e 100644 --- a/sys/arch/xen/i386/locore.S +++ b/sys/arch/xen/i386/locore.S @@ -1,4 +1,4 @@ -/* $NetBSD: locore.S,v 1.5 2004/04/26 22:05:04 cl Exp $ */ +/* $NetBSD: locore.S,v 1.6 2004/09/23 02:24:22 tls Exp $ */ /* NetBSD: locore.S,v 1.26 2004/04/12 13:17:46 yamt Exp */ /*- @@ -1588,6 +1588,7 @@ idle_zero: pushl $IPL_NONE call _C_LABEL(Xspllower) addl $4,%esp + jmp idle_start 4: call _C_LABEL(uvm_pageidlezero) CLI(%eax) diff --git a/sys/arch/xen/xen/clock.c b/sys/arch/xen/xen/clock.c index 72c90af2bdfc..ca762e9d4469 100644 --- a/sys/arch/xen/xen/clock.c +++ b/sys/arch/xen/xen/clock.c @@ -1,4 +1,4 @@ -/* $NetBSD: clock.c,v 1.6 2004/07/16 22:36:33 tls Exp $ */ +/* $NetBSD: clock.c,v 1.7 2004/09/23 02:24:22 tls Exp $ */ /* * @@ -34,7 +34,7 @@ #include "opt_xen.h" #include -__KERNEL_RCSID(0, "$NetBSD: clock.c,v 1.6 2004/07/16 22:36:33 tls Exp $"); +__KERNEL_RCSID(0, "$NetBSD: clock.c,v 1.7 2004/09/23 02:24:22 tls Exp $"); #include #include @@ -54,13 +54,17 @@ __KERNEL_RCSID(0, "$NetBSD: clock.c,v 1.6 2004/07/16 22:36:33 tls Exp $"); static int xen_timer_handler(void *, struct trapframe *); /* These are peridically updated in shared_info, and then copied here. */ -static unsigned long shadow_tsc_stamp; -static u_int64_t shadow_system_time; +static uint64_t shadow_tsc_stamp; +static uint64_t shadow_system_time; static unsigned long shadow_time_version; static struct timeval shadow_tv; static int timeset; +static uint64_t processed_system_time; + +#define NS_PER_TICK (1000000000ULL/hz) + /* * Reads a consistent set of time-base values from Xen, into a shadow data * area. Must be called at splclock. @@ -73,12 +77,23 @@ get_time_values_from_xen(void) __insn_barrier(); shadow_tv.tv_sec = HYPERVISOR_shared_info->wc_sec; shadow_tv.tv_usec = HYPERVISOR_shared_info->wc_usec; - shadow_tsc_stamp = HYPERVISOR_shared_info->tsc_timestamp; + shadow_tsc_stamp = HYPERVISOR_shared_info->tsc_timestamp << + HYPERVISOR_shared_info->rdtsc_bitshift; shadow_system_time = HYPERVISOR_shared_info->system_time; __insn_barrier(); } while (shadow_time_version != HYPERVISOR_shared_info->time_version1); } +static uint64_t +get_tsc_offset_ns(void) +{ + uint32_t tsc_delta; + struct cpu_info *ci = curcpu(); + + tsc_delta = cpu_counter32() - shadow_tsc_stamp; + return tsc_delta * 1000000000 / cpu_frequency(ci); +} + void inittodr(time_t base) { @@ -189,6 +204,9 @@ void xen_initclocks() { + get_time_values_from_xen(); + processed_system_time = shadow_system_time; + event_set_handler(_EVENT_TIMER, (int (*)(void *))xen_timer_handler, NULL, IPL_CLOCK); hypervisor_enable_event(_EVENT_TIMER); @@ -197,6 +215,8 @@ xen_initclocks() static int xen_timer_handler(void *arg, struct trapframe *regs) { + int64_t delta; + #if defined(I586_CPU) || defined(I686_CPU) static int microset_iter; /* call cc_microset once/sec */ struct cpu_info *ci = curcpu(); @@ -222,7 +242,13 @@ xen_timer_handler(void *arg, struct trapframe *regs) get_time_values_from_xen(); - hardclock((struct clockframe *)regs); + delta = (int64_t)(shadow_system_time + get_tsc_offset_ns() - + processed_system_time); + while (delta >= NS_PER_TICK) { + hardclock((struct clockframe *)regs); + delta -= NS_PER_TICK; + processed_system_time += NS_PER_TICK; + } return 0; }