# HG changeset patch
# User kfraser@xxxxxxxxxxxxxxxxxxxxx
# Date 1169146468 0
# Node ID e2539ab3580a28a6bebfe7ea4756fb8c6f90a722
# Parent 16847428f8595359972985934cba843c903570ab
[HVM] Fix slow wallclock in x64 Vista. This is due to confusing a
timeout in the past vs. a timeout in the future when looking at a
32-bit HPET comparator.
Signed-off-by: Dexuan Cui <dexuan.cui@xxxxxxxxx>
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
---
xen/arch/x86/hvm/hpet.c | 24 ++++++++++++++++++------
1 files changed, 18 insertions(+), 6 deletions(-)
diff -r 16847428f859 -r e2539ab3580a xen/arch/x86/hvm/hpet.c
--- a/xen/arch/x86/hvm/hpet.c Thu Jan 18 18:40:30 2007 +0000
+++ b/xen/arch/x86/hvm/hpet.c Thu Jan 18 18:54:28 2007 +0000
@@ -142,9 +142,13 @@ static void hpet_stop_timer(HPETState *h
stop_timer(&h->timers[tn]);
}
+/* the number of HPET tick that stands for
+ * 1/(2^10) second, namely, 0.9765625 milliseconds */
+#define HPET_TINY_TIME_SPAN (h->tsc_freq >> 10)
+
static void hpet_set_timer(HPETState *h, unsigned int tn)
{
- uint64_t tn_cmp, cur_tick;
+ uint64_t tn_cmp, cur_tick, diff;
ASSERT(tn < HPET_TIMER_NUM);
@@ -167,11 +171,19 @@ 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());
+ diff = tn_cmp - cur_tick;
+
+ /*
+ * Detect time values set in the past. This is hard to do for 32-bit
+ * comparators as the timer does not have to be set that far in the future
+ * for the counter difference to wrap a 32-bit signed integer. We fudge
+ * by looking for a 'small' time value in the past.
+ */
+ if ( (int64_t)diff < 0 )
+ diff = (timer_is_32bit(h, tn) && (-diff > HPET_TINY_TIME_SPAN))
+ ? (uint32_t)diff : 0;
+
+ set_timer(&h->timers[tn], NOW() + hpet_tick_to_ns(h, diff));
}
static inline uint64_t hpet_fixup_reg(
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|