aboutsummaryrefslogtreecommitdiffstats
path: root/xen/arch/x86/hvm/hpet.c
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2008-01-08 16:20:04 +0000
committerKeir Fraser <keir.fraser@citrix.com>2008-01-08 16:20:04 +0000
commit73ee2f2e11fcdc27aae4f8caa72d240c4c9ed5ac (patch)
tree8be74b360d3f5911344a42da2fef88e34126ae3b /xen/arch/x86/hvm/hpet.c
parent10e3974b14613c687ce84decc019f4e016063caa (diff)
downloadxen-73ee2f2e11fcdc27aae4f8caa72d240c4c9ed5ac.tar.gz
xen-73ee2f2e11fcdc27aae4f8caa72d240c4c9ed5ac.tar.bz2
xen-73ee2f2e11fcdc27aae4f8caa72d240c4c9ed5ac.zip
hvm: hpet: Fix overflow when converting to nanoseconds.
Currently in hpet_tick_to_ns, the approach is multiplying first, which easily causes overflow when tick is quite large. The patch cannot handle arbitratry large ticks duo to the precision requirement and 64bit's value range. But by optimize the equation, a larger ticks than current code can be supported. Also an overflow check is added before the calculation. From: Haitao Shan <haitao.shan@intel.com> Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
Diffstat (limited to 'xen/arch/x86/hvm/hpet.c')
-rw-r--r--xen/arch/x86/hvm/hpet.c8
1 files changed, 6 insertions, 2 deletions
diff --git a/xen/arch/x86/hvm/hpet.c b/xen/arch/x86/hvm/hpet.c
index 603ffe8915..14f525893f 100644
--- a/xen/arch/x86/hvm/hpet.c
+++ b/xen/arch/x86/hvm/hpet.c
@@ -71,8 +71,9 @@
#define HPET_TN_INT_ROUTE_CAP_MASK (0xffffffffULL \
<< HPET_TN_INT_ROUTE_CAP_SHIFT)
-#define hpet_tick_to_ns(h, tick) ((s_time_t)(tick)* \
- (S_TO_NS*TSC_PER_HPET_TICK)/h->tsc_freq)
+#define hpet_tick_to_ns(h, tick) \
+ ((s_time_t)((((tick) > (h)->hpet_to_ns_limit) ? \
+ ~0ULL : (tick) * (h)->hpet_to_ns_scale) >> 10))
#define timer_config(h, n) (h->hpet.timers[n].config)
#define timer_is_periodic(h, n) (timer_config(h, n) & HPET_TN_PERIODIC)
@@ -537,6 +538,9 @@ void hpet_init(struct vcpu *v)
h->vcpu = v;
h->tsc_freq = ticks_per_sec(v);
+ h->hpet_to_ns_scale = ((S_TO_NS * TSC_PER_HPET_TICK) << 10) / h->tsc_freq;
+ h->hpet_to_ns_limit = (~0ULL >> 1) / h->hpet_to_ns_scale;
+
/* 64-bit main counter; 3 timers supported; LegacyReplacementRoute. */
h->hpet.capability = 0x8086A201ULL;