diff options
author | kfraser@localhost.localdomain <kfraser@localhost.localdomain> | 2007-01-12 10:08:38 +0000 |
---|---|---|
committer | kfraser@localhost.localdomain <kfraser@localhost.localdomain> | 2007-01-12 10:08:38 +0000 |
commit | 4c8688811f74e58a04bf5f10e0240e7c0c11b510 (patch) | |
tree | 9c2f8cb4504b45490311fe3bb524e7ca6f607a9e /xen/arch/x86/hvm/vioapic.c | |
parent | bfdf10eac543f670c7347ea738bf08f6a9e02934 (diff) | |
download | xen-4c8688811f74e58a04bf5f10e0240e7c0c11b510.tar.gz xen-4c8688811f74e58a04bf5f10e0240e7c0c11b510.tar.bz2 xen-4c8688811f74e58a04bf5f10e0240e7c0c11b510.zip |
[HVM] Fix timer interrupt delivery on x64 Vista.
x64 SMP Vista HVM guest uses HPET as the main system timer, and it
uses physical destination mode with broadcast to deliver the interrupts
generated by HPET. In current code, timer interrupts are injected only
to VCPU0 in vioapic.c, but this doesn't satisfy x64 SMP Vista -- when
it boots, it complains "a clock interrupt was not received on a
secondary processor within the allocated time interval" with Bug Check
0x101.
Signed-off-by: Dexuan Cui <dexuan.cui@intel.com>
Diffstat (limited to 'xen/arch/x86/hvm/vioapic.c')
-rw-r--r-- | xen/arch/x86/hvm/vioapic.c | 11 |
1 files changed, 9 insertions, 2 deletions
diff --git a/xen/arch/x86/hvm/vioapic.c b/xen/arch/x86/hvm/vioapic.c index 843c76a6dd..6f68a85b77 100644 --- a/xen/arch/x86/hvm/vioapic.c +++ b/xen/arch/x86/hvm/vioapic.c @@ -309,6 +309,13 @@ static uint32_t ioapic_get_delivery_bitmask( return mask; } +static inline int pit_channel0_enabled(void) +{ + PITState *pit = ¤t->domain->arch.hvm_domain.pl_time.vpit; + struct periodic_time *pt = &pit->channels[0].pt; + return pt->enabled; +} + static void vioapic_deliver(struct vioapic *vioapic, int irq) { uint16_t dest = vioapic->redirtbl[irq].fields.dest_id; @@ -341,7 +348,7 @@ static void vioapic_deliver(struct vioapic *vioapic, int irq) { #ifdef IRQ0_SPECIAL_ROUTING /* Force round-robin to pick VCPU 0 */ - if ( irq == hvm_isa_irq_to_gsi(0) ) + if ( (irq == hvm_isa_irq_to_gsi(0)) && pit_channel0_enabled() ) { v = vioapic_domain(vioapic)->vcpu[0]; target = v ? vcpu_vlapic(v) : NULL; @@ -374,7 +381,7 @@ static void vioapic_deliver(struct vioapic *vioapic, int irq) deliver_bitmask &= ~(1 << bit); #ifdef IRQ0_SPECIAL_ROUTING /* Do not deliver timer interrupts to VCPU != 0 */ - if ( irq == hvm_isa_irq_to_gsi(0) ) + if ( (irq == hvm_isa_irq_to_gsi(0)) && pit_channel0_enabled() ) v = vioapic_domain(vioapic)->vcpu[0]; else #endif |