aboutsummaryrefslogtreecommitdiffstats
path: root/xen/arch/x86/hvm/pmtimer.c
diff options
context:
space:
mode:
authorKeir Fraser <keir@xensource.com>2007-06-15 09:42:39 +0100
committerKeir Fraser <keir@xensource.com>2007-06-15 09:42:39 +0100
commitdd8e0a08e0823f193744290ebe1c16fe19642c91 (patch)
tree60b3778f44deb5fdf393dcbba287015d1f84bde6 /xen/arch/x86/hvm/pmtimer.c
parent1e542e2a4d0e777d343e217466fb91ec16ebefc1 (diff)
downloadxen-dd8e0a08e0823f193744290ebe1c16fe19642c91.tar.gz
xen-dd8e0a08e0823f193744290ebe1c16fe19642c91.tar.bz2
xen-dd8e0a08e0823f193744290ebe1c16fe19642c91.zip
hvm: Fix multiplication overflow in hvm/pmtimer.c
Too many ACPI events (SCI) are raised on hvm because of multiplication overflow. FREQUENCE_PMTIMER=3579545 (1000000000ULL << 32) / FREQUENCE_PMTIMER = 0xae9a7b1663a pmt_cycles_until_flip =~ 0x80000000 0xae9a7b1663a*0x80000000 = overflow!!! Signed-off-by: Kouya Shimura <kouya@jp.fujitsu.com>
Diffstat (limited to 'xen/arch/x86/hvm/pmtimer.c')
-rw-r--r--xen/arch/x86/hvm/pmtimer.c15
1 files changed, 7 insertions, 8 deletions
diff --git a/xen/arch/x86/hvm/pmtimer.c b/xen/arch/x86/hvm/pmtimer.c
index e0c803910f..7d848b4245 100644
--- a/xen/arch/x86/hvm/pmtimer.c
+++ b/xen/arch/x86/hvm/pmtimer.c
@@ -50,7 +50,6 @@
#define TMR_VAL_MASK (0xffffffff)
#define TMR_VAL_MSB (0x80000000)
-
/* Dispatch SCIs based on the PM1a_STS and PM1a_EN registers */
static void pmt_update_sci(PMTState *s)
{
@@ -89,19 +88,19 @@ static void pmt_timer_callback(void *opaque)
PMTState *s = opaque;
uint32_t pmt_cycles_until_flip;
uint64_t time_until_flip;
-
+
/* Recalculate the timer and make sure we get an SCI if we need one */
pmt_update_time(s);
-
+
/* How close are we to the next MSB flip? */
pmt_cycles_until_flip = TMR_VAL_MSB - (s->pm.tmr_val & (TMR_VAL_MSB - 1));
-
+
/* Overall time between MSB flips */
- time_until_flip = (1000000000ULL << 31) / FREQUENCE_PMTIMER;
-
+ time_until_flip = (1000000000ULL << 23) / FREQUENCE_PMTIMER;
+
/* Reduced appropriately */
- time_until_flip = (time_until_flip * pmt_cycles_until_flip) / (1ULL<<31);
-
+ time_until_flip = (time_until_flip * pmt_cycles_until_flip) >> 23;
+
/* Wake up again near the next bit-flip */
set_timer(&s->timer, NOW() + time_until_flip + MILLISECS(1));
}