#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)
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;
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];