]> xenbits.xensource.com Git - people/vhanquez/xen.git/commitdiff
hvm: hpet: Fix overflow when converting to nanoseconds.
authorKeir Fraser <keir.fraser@citrix.com>
Thu, 10 Jan 2008 11:39:23 +0000 (11:39 +0000)
committerKeir Fraser <keir.fraser@citrix.com>
Thu, 10 Jan 2008 11:39:23 +0000 (11:39 +0000)
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>
xen-unstable changeset:   16693:9ff64d045e61e7db6844b3db473e660e8c7e0551
xen-unstable date:        Tue Jan 08 16:20:04 2008 +0000

xen/arch/x86/hvm/hpet.c
xen/include/asm-x86/hvm/vpt.h

index a4a2cd0d33444f6b43490dd1e6db1367b7c233f0..9e2527090bd9dfea6000e3da4cccc8dccea7e59a 100644 (file)
@@ -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)
@@ -465,6 +466,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;
 
index 38d4aae9eb4f91a7946824c7536a744b575a51d1..1991f3f7bf730f4f4eed8c21916d31a4d2dc43ac 100644 (file)
@@ -41,6 +41,8 @@ typedef struct HPETState {
     struct hvm_hw_hpet hpet;
     struct vcpu *vcpu;
     uint64_t tsc_freq;
+    uint64_t hpet_to_ns_scale; /* hpet ticks to ns (multiplied by 2^10) */
+    uint64_t hpet_to_ns_limit; /* max hpet ticks convertable to ns      */
     uint64_t mc_offset;
     struct timer timers[HPET_TIMER_NUM];
     struct HPET_timer_fn_info timer_fn_info[HPET_TIMER_NUM];