ia64/xen-unstable

changeset 13394:162d9d9eaf4a

[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>
author kfraser@localhost.localdomain
date Fri Jan 12 10:08:38 2007 +0000 (2007-01-12)
parents ecf6a0a05350
children 95a0b456255a
files xen/arch/x86/domain.c xen/arch/x86/hvm/vioapic.c
line diff
     1.1 --- a/xen/arch/x86/domain.c	Thu Jan 11 19:01:28 2007 +0000
     1.2 +++ b/xen/arch/x86/domain.c	Fri Jan 12 10:08:38 2007 +0000
     1.3 @@ -1047,7 +1047,7 @@ void context_switch(struct vcpu *prev, s
     1.4  
     1.5      local_irq_disable();
     1.6  
     1.7 -    if ( is_hvm_vcpu(prev) )
     1.8 +    if ( is_hvm_vcpu(prev) && !list_empty(&prev->arch.hvm_vcpu.tm_list) )
     1.9          pt_freeze_time(prev);
    1.10  
    1.11      set_current(next);
     2.1 --- a/xen/arch/x86/hvm/vioapic.c	Thu Jan 11 19:01:28 2007 +0000
     2.2 +++ b/xen/arch/x86/hvm/vioapic.c	Fri Jan 12 10:08:38 2007 +0000
     2.3 @@ -309,6 +309,13 @@ static uint32_t ioapic_get_delivery_bitm
     2.4      return mask;
     2.5  }
     2.6  
     2.7 +static inline int pit_channel0_enabled(void)
     2.8 +{
     2.9 +    PITState *pit = &current->domain->arch.hvm_domain.pl_time.vpit;
    2.10 +    struct periodic_time *pt = &pit->channels[0].pt;
    2.11 +    return pt->enabled;
    2.12 +}
    2.13 +
    2.14  static void vioapic_deliver(struct vioapic *vioapic, int irq)
    2.15  {
    2.16      uint16_t dest = vioapic->redirtbl[irq].fields.dest_id;
    2.17 @@ -341,7 +348,7 @@ static void vioapic_deliver(struct vioap
    2.18      {
    2.19  #ifdef IRQ0_SPECIAL_ROUTING
    2.20          /* Force round-robin to pick VCPU 0 */
    2.21 -        if ( irq == hvm_isa_irq_to_gsi(0) )
    2.22 +        if ( (irq == hvm_isa_irq_to_gsi(0)) && pit_channel0_enabled() )
    2.23          {
    2.24              v = vioapic_domain(vioapic)->vcpu[0];
    2.25              target = v ? vcpu_vlapic(v) : NULL;
    2.26 @@ -374,7 +381,7 @@ static void vioapic_deliver(struct vioap
    2.27              deliver_bitmask &= ~(1 << bit);
    2.28  #ifdef IRQ0_SPECIAL_ROUTING
    2.29              /* Do not deliver timer interrupts to VCPU != 0 */
    2.30 -            if ( irq == hvm_isa_irq_to_gsi(0) )
    2.31 +            if ( (irq == hvm_isa_irq_to_gsi(0)) && pit_channel0_enabled() )
    2.32                  v = vioapic_domain(vioapic)->vcpu[0];
    2.33              else
    2.34  #endif