ia64/xen-unstable

changeset 13211:ce83c1896acc

[HVM] Fix assumptions that ISA IRQ 0 connects to GSI 0.
Signed-off-by: Keir Fraser <keir@xensource.com>
author kaf24@localhost.localdomain
date Thu Dec 28 16:33:15 2006 +0000 (2006-12-28)
parents 766eec31afab
children 91130d1e6006
files xen/arch/x86/hvm/irq.c xen/arch/x86/hvm/vioapic.c xen/arch/x86/hvm/vpt.c xen/include/asm-x86/hvm/irq.h
line diff
     1.1 --- a/xen/arch/x86/hvm/irq.c	Thu Dec 28 15:28:45 2006 +0000
     1.2 +++ b/xen/arch/x86/hvm/irq.c	Thu Dec 28 16:33:15 2006 +0000
     1.3 @@ -85,7 +85,7 @@ void hvm_isa_irq_assert(
     1.4      struct domain *d, unsigned int isa_irq)
     1.5  {
     1.6      struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq;
     1.7 -    unsigned int gsi = (isa_irq == 0) ? 2 : isa_irq;
     1.8 +    unsigned int gsi = hvm_isa_irq_to_gsi(isa_irq);
     1.9  
    1.10      ASSERT(isa_irq <= 15);
    1.11  
    1.12 @@ -105,7 +105,7 @@ void hvm_isa_irq_deassert(
    1.13      struct domain *d, unsigned int isa_irq)
    1.14  {
    1.15      struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq;
    1.16 -    unsigned int gsi = (isa_irq == 0) ? 2 : isa_irq;
    1.17 +    unsigned int gsi = hvm_isa_irq_to_gsi(isa_irq);
    1.18  
    1.19      ASSERT(isa_irq <= 15);
    1.20  
    1.21 @@ -257,23 +257,25 @@ int cpu_get_interrupt(struct vcpu *v, in
    1.22      return -1;
    1.23  }
    1.24  
    1.25 -int get_intr_vector(struct vcpu* v, int irq, int type)
    1.26 +int get_isa_irq_vector(struct vcpu *v, int isa_irq, int type)
    1.27  {
    1.28 +    unsigned int gsi = hvm_isa_irq_to_gsi(isa_irq);
    1.29 +
    1.30      if ( type == APIC_DM_EXTINT )
    1.31 -        return v->domain->arch.hvm_domain.irq.vpic[irq >> 3].irq_base
    1.32 -                + (irq & 0x7);
    1.33 +        return (v->domain->arch.hvm_domain.irq.vpic[isa_irq >> 3].irq_base
    1.34 +                + (isa_irq & 7));
    1.35  
    1.36 -    return domain_vioapic(v->domain)->redirtbl[irq].fields.vector;
    1.37 +    return domain_vioapic(v->domain)->redirtbl[gsi].fields.vector;
    1.38  }
    1.39  
    1.40 -int is_irq_masked(struct vcpu *v, int irq)
    1.41 +int is_isa_irq_masked(struct vcpu *v, int isa_irq)
    1.42  {
    1.43 -    if ( is_lvtt(v, irq) )
    1.44 +    unsigned int gsi = hvm_isa_irq_to_gsi(isa_irq);
    1.45 +
    1.46 +    if ( is_lvtt(v, isa_irq) )
    1.47          return !is_lvtt_enabled(v);
    1.48  
    1.49 -    if ( v->domain->arch.hvm_domain.irq.vpic[irq >> 3].imr & (1 << (irq & 7))
    1.50 -            && domain_vioapic(v->domain)->redirtbl[irq].fields.mask )
    1.51 -        return 1;
    1.52 -
    1.53 -    return 0;
    1.54 +    return ((v->domain->arch.hvm_domain.irq.vpic[isa_irq >> 3].imr &
    1.55 +             (1 << (isa_irq & 7))) &&
    1.56 +            domain_vioapic(v->domain)->redirtbl[gsi].fields.mask);
    1.57  }
     2.1 --- a/xen/arch/x86/hvm/vioapic.c	Thu Dec 28 15:28:45 2006 +0000
     2.2 +++ b/xen/arch/x86/hvm/vioapic.c	Thu Dec 28 16:33:15 2006 +0000
     2.3 @@ -341,7 +341,7 @@ static void vioapic_deliver(struct vioap
     2.4      {
     2.5  #ifdef IRQ0_SPECIAL_ROUTING
     2.6          /* Force round-robin to pick VCPU 0 */
     2.7 -        if ( irq == 0 )
     2.8 +        if ( irq == hvm_isa_irq_to_gsi(0) )
     2.9          {
    2.10              v = vioapic_domain(vioapic)->vcpu[0];
    2.11              target = v ? vcpu_vlapic(v) : NULL;
    2.12 @@ -374,7 +374,7 @@ static void vioapic_deliver(struct vioap
    2.13              deliver_bitmask &= ~(1 << bit);
    2.14  #ifdef IRQ0_SPECIAL_ROUTING
    2.15              /* Do not deliver timer interrupts to VCPU != 0 */
    2.16 -            if ( (irq == 0) && (bit != 0) )
    2.17 +            if ( irq == hvm_isa_irq_to_gsi(0) )
    2.18                  v = vioapic_domain(vioapic)->vcpu[0];
    2.19              else
    2.20  #endif
     3.1 --- a/xen/arch/x86/hvm/vpt.c	Thu Dec 28 15:28:45 2006 +0000
     3.2 +++ b/xen/arch/x86/hvm/vpt.c	Thu Dec 28 16:33:15 2006 +0000
     3.3 @@ -108,16 +108,18 @@ void pt_update_irq(struct vcpu *v)
     3.4      list_for_each( list, head )
     3.5      {
     3.6          pt = list_entry(list, struct periodic_time, list);
     3.7 -        if ( !is_irq_masked(v, pt->irq) && pt->pending_intr_nr 
     3.8 -                && pt->last_plt_gtime + pt->period < max_lag )
     3.9 +        if ( !is_isa_irq_masked(v, pt->irq) && pt->pending_intr_nr &&
    3.10 +             ((pt->last_plt_gtime + pt->period_cycles) < max_lag) )
    3.11          {
    3.12 -            max_lag = pt->last_plt_gtime + pt->period;
    3.13 +            max_lag = pt->last_plt_gtime + pt->period_cycles;
    3.14              irq = pt->irq;
    3.15          }
    3.16      }
    3.17  
    3.18      if ( is_lvtt(v, irq) )
    3.19 +    {
    3.20          vlapic_set_irq(vcpu_vlapic(v), irq, 0);
    3.21 +    }
    3.22      else if ( irq >= 0 )
    3.23      {
    3.24          hvm_isa_irq_deassert(v->domain, irq);
    3.25 @@ -141,16 +143,15 @@ struct periodic_time *is_pt_irq(struct v
    3.26  
    3.27          if ( is_lvtt(v, pt->irq) )
    3.28          {
    3.29 -            if (pt->irq == vector)
    3.30 -                return pt;
    3.31 -            else
    3.32 +            if ( pt->irq != vector )
    3.33                  continue;
    3.34 +            return pt;
    3.35          }
    3.36  
    3.37 -        vec = get_intr_vector(v, pt->irq, type);
    3.38 +        vec = get_isa_irq_vector(v, pt->irq, type);
    3.39  
    3.40          /* RTC irq need special care */
    3.41 -        if ( vector != vec || (pt->irq == 8 && !is_rtc_periodic_irq(rtc)) )
    3.42 +        if ( (vector != vec) || (pt->irq == 8 && !is_rtc_periodic_irq(rtc)) )
    3.43              continue;
    3.44  
    3.45          return pt;
    3.46 @@ -163,14 +164,14 @@ void pt_intr_post(struct vcpu *v, int ve
    3.47  {
    3.48      struct periodic_time *pt = is_pt_irq(v, vector, type);
    3.49  
    3.50 -    if (pt == NULL)
    3.51 +    if ( pt == NULL )
    3.52          return;
    3.53  
    3.54      pt->pending_intr_nr--;
    3.55      pt->last_plt_gtime += pt->period_cycles;
    3.56      hvm_set_guest_time(pt->vcpu, pt->last_plt_gtime);
    3.57  
    3.58 -    if (pt->cb)
    3.59 +    if ( pt->cb != NULL )
    3.60          pt->cb(pt->vcpu, pt->priv);
    3.61  }
    3.62  
    3.63 @@ -200,9 +201,11 @@ void create_periodic_time(struct periodi
    3.64      destroy_periodic_time(pt);
    3.65  
    3.66      pt->enabled = 1;
    3.67 -    if (period < 900000) /* < 0.9 ms */
    3.68 +    if ( period < 900000 ) /* < 0.9 ms */
    3.69      {
    3.70 -        printk("HVM_PlatformTime: program too small period %"PRIu64"\n", period);
    3.71 +        gdprintk(XENLOG_WARNING,
    3.72 +                 "HVM_PlatformTime: program too small period %"PRIu64"\n",
    3.73 +                 period);
    3.74          period = 900000; /* force to 0.9ms */
    3.75      }
    3.76      pt->period = period;
     4.1 --- a/xen/include/asm-x86/hvm/irq.h	Thu Dec 28 15:28:45 2006 +0000
     4.2 +++ b/xen/include/asm-x86/hvm/irq.h	Thu Dec 28 16:33:15 2006 +0000
     4.3 @@ -61,7 +61,8 @@ struct hvm_irq {
     4.4      /*
     4.5       * Number of wires asserting each GSI.
     4.6       * 
     4.7 -     * GSIs 0-15 are the ISA IRQs. ISA devices map directly into this space.
     4.8 +     * GSIs 0-15 are the ISA IRQs. ISA devices map directly into this space
     4.9 +     * except ISA IRQ 0, which is connected to GSI 2.
    4.10       * PCI links map into this space via the PCI-ISA bridge.
    4.11       * 
    4.12       * GSIs 16+ are used only be PCI devices. The mapping from PCI device to
    4.13 @@ -87,6 +88,8 @@ struct hvm_irq {
    4.14  #define hvm_pci_intx_link(dev, intx) \
    4.15      (((dev) + (intx)) & 3)
    4.16  
    4.17 +#define hvm_isa_irq_to_gsi(isa_irq) ((isa_irq) ? : 2)
    4.18 +
    4.19  /* Modify state of a PCI INTx wire. */
    4.20  void hvm_pci_intx_assert(
    4.21      struct domain *d, unsigned int device, unsigned int intx);
    4.22 @@ -106,7 +109,7 @@ void hvm_set_callback_gsi(struct domain 
    4.23  
    4.24  int cpu_get_interrupt(struct vcpu *v, int *type);
    4.25  int cpu_has_pending_irq(struct vcpu *v);
    4.26 -int get_intr_vector(struct vcpu* vcpu, int irq, int type);
    4.27 -int is_irq_masked(struct vcpu *v, int irq);
    4.28 +int get_isa_irq_vector(struct vcpu *vcpu, int irq, int type);
    4.29 +int is_isa_irq_masked(struct vcpu *v, int isa_irq);
    4.30  
    4.31  #endif /* __ASM_X86_HVM_IRQ_H__ */