diff options
author | Keir Fraser <keir.fraser@citrix.com> | 2009-11-03 09:33:22 +0000 |
---|---|---|
committer | Keir Fraser <keir.fraser@citrix.com> | 2009-11-03 09:33:22 +0000 |
commit | b95beb185810484d5afe91b994d2c2d1670af74c (patch) | |
tree | df43239616fdab10f7593af4deb1509b397f50e8 /xen/arch/x86/hvm/vlapic.c | |
parent | ad1f74192ab40866396316cd86bec3f98b6ef56b (diff) | |
download | xen-b95beb185810484d5afe91b994d2c2d1670af74c.tar.gz xen-b95beb185810484d5afe91b994d2c2d1670af74c.tar.bz2 xen-b95beb185810484d5afe91b994d2c2d1670af74c.zip |
x86: Clean up APIC local timer handling.
1. Writing TMICT=0 disables the timer. Use this fact to simplify and
improve reprogram_timer(). In particular, we always write TMICT, and
write zero when we do not need a timer interrupt.
2. In HPET broadcast timer handler, set TMICT=0 when we mask the APIC
local timer. May as well do this early, before entering deep sleep.
3. In HVM-guest APIC emulation, disable the emulated local timer when
the guest sets TMICT=0. Previously we would issue an immediate
one-shot interrupt.
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
Diffstat (limited to 'xen/arch/x86/hvm/vlapic.c')
-rw-r--r-- | xen/arch/x86/hvm/vlapic.c | 11 |
1 files changed, 9 insertions, 2 deletions
diff --git a/xen/arch/x86/hvm/vlapic.c b/xen/arch/x86/hvm/vlapic.c index 6d1d7b9e71..83057f91f5 100644 --- a/xen/arch/x86/hvm/vlapic.c +++ b/xen/arch/x86/hvm/vlapic.c @@ -667,10 +667,17 @@ static int vlapic_write(struct vcpu *v, unsigned long address, case APIC_TMICT: { - uint64_t period = (uint64_t)APIC_BUS_CYCLE_NS * - (uint32_t)val * vlapic->hw.timer_divisor; + uint64_t period; vlapic_set_reg(vlapic, APIC_TMICT, val); + if ( val == 0 ) + { + destroy_periodic_time(&vlapic->pt); + break; + } + + period = ((uint64_t)APIC_BUS_CYCLE_NS * + (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, |