aboutsummaryrefslogtreecommitdiffstats
path: root/xen/arch/x86/hvm/vioapic.c
diff options
context:
space:
mode:
authorkfraser@localhost.localdomain <kfraser@localhost.localdomain>2007-01-12 10:08:38 +0000
committerkfraser@localhost.localdomain <kfraser@localhost.localdomain>2007-01-12 10:08:38 +0000
commit4c8688811f74e58a04bf5f10e0240e7c0c11b510 (patch)
tree9c2f8cb4504b45490311fe3bb524e7ca6f607a9e /xen/arch/x86/hvm/vioapic.c
parentbfdf10eac543f670c7347ea738bf08f6a9e02934 (diff)
downloadxen-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.c11
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 = &current->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