aboutsummaryrefslogtreecommitdiffstats
path: root/xen/arch/x86/hvm/vlapic.c
diff options
context:
space:
mode:
authorKeir Fraser <keir@xen.org>2010-12-07 18:10:46 +0000
committerKeir Fraser <keir@xen.org>2010-12-07 18:10:46 +0000
commit91ddbc059f3f563cd38e82095f19facf6e2257af (patch)
tree802da780de2fa8a27245c371dff4267c136cd8f1 /xen/arch/x86/hvm/vlapic.c
parentd5c277ab26f7fbb64b8b1d09b9dc328212cd2988 (diff)
downloadxen-91ddbc059f3f563cd38e82095f19facf6e2257af.tar.gz
xen-91ddbc059f3f563cd38e82095f19facf6e2257af.tar.bz2
xen-91ddbc059f3f563cd38e82095f19facf6e2257af.zip
x86 hvm: Fix VLAPIC TMCCT register when timer is one-shot
Signed-off-by: Keir Fraser <keir@xen.org>
Diffstat (limited to 'xen/arch/x86/hvm/vlapic.c')
-rw-r--r--xen/arch/x86/hvm/vlapic.c8
1 files changed, 5 insertions, 3 deletions
diff --git a/xen/arch/x86/hvm/vlapic.c b/xen/arch/x86/hvm/vlapic.c
index 3b94ca96a8..f394518caf 100644
--- a/xen/arch/x86/hvm/vlapic.c
+++ b/xen/arch/x86/hvm/vlapic.c
@@ -430,7 +430,7 @@ static uint32_t vlapic_get_tmcct(struct vlapic *vlapic)
counter_passed = ((hvm_get_guest_time(v) - vlapic->timer_last_update)
/ APIC_BUS_CYCLE_NS / vlapic->hw.timer_divisor);
- tmcct = tmict - counter_passed;
+ tmcct = (counter_passed < tmict) ? tmict - counter_passed : 0;
HVM_DBG_LOG(DBG_LEVEL_VLAPIC_TIMER,
"timer initial count %d, timer current count %d, "
@@ -677,7 +677,8 @@ static int vlapic_write(struct vcpu *v, unsigned long address,
(uint32_t)val * vlapic->hw.timer_divisor);
create_periodic_time(current, &vlapic->pt, period,
vlapic_lvtt_period(vlapic) ? period : 0,
- vlapic->pt.irq, vlapic_pt_cb,
+ vlapic->pt.irq,
+ vlapic_lvtt_period(vlapic) ? vlapic_pt_cb : NULL,
&vlapic->timer_last_update);
vlapic->timer_last_update = vlapic->pt.last_plt_gtime;
@@ -874,7 +875,8 @@ static void lapic_rearm(struct vlapic *s)
s->pt.irq = vlapic_get_reg(s, APIC_LVTT) & APIC_VECTOR_MASK;
create_periodic_time(vlapic_vcpu(s), &s->pt, period,
vlapic_lvtt_period(s) ? period : 0,
- s->pt.irq, vlapic_pt_cb,
+ s->pt.irq,
+ vlapic_lvtt_period(s) ? vlapic_pt_cb : NULL,
&s->timer_last_update);
s->timer_last_update = s->pt.last_plt_gtime;
}