diff -r 3157b54eb465 xen/arch/x86/hvm/hpet.c --- a/xen/arch/x86/hvm/hpet.c Thu Jan 04 16:34:19 2007 +0000 +++ b/xen/arch/x86/hvm/hpet.c Wed Jan 10 16:50:52 2007 +0800 @@ -144,7 +144,7 @@ static void hpet_stop_timer(HPETState *h static void hpet_set_timer(HPETState *h, unsigned int tn) { - uint64_t tn_cmp, cur_tick; + uint64_t tn_cmp, cur_tick, scheduled, passed; ASSERT(tn < HPET_TIMER_NUM); @@ -167,11 +167,25 @@ static void hpet_set_timer(HPETState *h, cur_tick = (uint32_t)cur_tick; } - if ( (int64_t)(tn_cmp - cur_tick) > 0 ) - set_timer(&h->timers[tn], NOW() + - hpet_tick_to_ns(h, tn_cmp-cur_tick)); - else - set_timer(&h->timers[tn], NOW()); + scheduled = tn_cmp - cur_tick; + if ( (int64_t)scheduled < 0 ) + { + passed = cur_tick - tn_cmp; + + /* the number of HPET tick that stands for + * 1/(2^10) second, namely, 0.9765625 millisecond */ + #define hpet_tiny_time_span (h->tsc_freq >> 10) + if ( passed < hpet_tiny_time_span ) + scheduled = 0; + else + { + if ( timer_is_32bit(h, tn) ) + scheduled = (uint32_t)scheduled; + else + scheduled = (uint64_t)scheduled; + } + } + set_timer(&h->timers[tn], NOW() + hpet_tick_to_ns(h, scheduled)); } static inline uint64_t hpet_fixup_reg(