[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] [HVM] Fix assumptions that ISA IRQ 0 connects to GSI 0.



# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxxx
# Date 1167323595 0
# Node ID ce83c1896accbdc3e073d7d2363d32c5d254945d
# Parent  766eec31afabc566a54749a8b5795160c8687de5
[HVM] Fix assumptions that ISA IRQ 0 connects to GSI 0.
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
---
 xen/arch/x86/hvm/irq.c        |   40 +++++++++++++++++++++-------------------
 xen/arch/x86/hvm/vioapic.c    |    4 ++--
 xen/arch/x86/hvm/vpt.c        |   35 +++++++++++++++++++----------------
 xen/include/asm-x86/hvm/irq.h |    9 ++++++---
 4 files changed, 48 insertions(+), 40 deletions(-)

diff -r 766eec31afab -r ce83c1896acc xen/arch/x86/hvm/irq.c
--- a/xen/arch/x86/hvm/irq.c    Thu Dec 28 15:28:45 2006 +0000
+++ b/xen/arch/x86/hvm/irq.c    Thu Dec 28 16:33:15 2006 +0000
@@ -85,7 +85,7 @@ void hvm_isa_irq_assert(
     struct domain *d, unsigned int isa_irq)
 {
     struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq;
-    unsigned int gsi = (isa_irq == 0) ? 2 : isa_irq;
+    unsigned int gsi = hvm_isa_irq_to_gsi(isa_irq);
 
     ASSERT(isa_irq <= 15);
 
@@ -105,7 +105,7 @@ void hvm_isa_irq_deassert(
     struct domain *d, unsigned int isa_irq)
 {
     struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq;
-    unsigned int gsi = (isa_irq == 0) ? 2 : isa_irq;
+    unsigned int gsi = hvm_isa_irq_to_gsi(isa_irq);
 
     ASSERT(isa_irq <= 15);
 
@@ -257,23 +257,25 @@ int cpu_get_interrupt(struct vcpu *v, in
     return -1;
 }
 
-int get_intr_vector(struct vcpu* v, int irq, int type)
-{
+int get_isa_irq_vector(struct vcpu *v, int isa_irq, int type)
+{
+    unsigned int gsi = hvm_isa_irq_to_gsi(isa_irq);
+
     if ( type == APIC_DM_EXTINT )
-        return v->domain->arch.hvm_domain.irq.vpic[irq >> 3].irq_base
-                + (irq & 0x7);
-
-    return domain_vioapic(v->domain)->redirtbl[irq].fields.vector;
-}
-
-int is_irq_masked(struct vcpu *v, int irq)
-{
-    if ( is_lvtt(v, irq) )
+        return (v->domain->arch.hvm_domain.irq.vpic[isa_irq >> 3].irq_base
+                + (isa_irq & 7));
+
+    return domain_vioapic(v->domain)->redirtbl[gsi].fields.vector;
+}
+
+int is_isa_irq_masked(struct vcpu *v, int isa_irq)
+{
+    unsigned int gsi = hvm_isa_irq_to_gsi(isa_irq);
+
+    if ( is_lvtt(v, isa_irq) )
         return !is_lvtt_enabled(v);
 
-    if ( v->domain->arch.hvm_domain.irq.vpic[irq >> 3].imr & (1 << (irq & 7))
-            && domain_vioapic(v->domain)->redirtbl[irq].fields.mask )
-        return 1;
-
-    return 0;
-}
+    return ((v->domain->arch.hvm_domain.irq.vpic[isa_irq >> 3].imr &
+             (1 << (isa_irq & 7))) &&
+            domain_vioapic(v->domain)->redirtbl[gsi].fields.mask);
+}
diff -r 766eec31afab -r ce83c1896acc xen/arch/x86/hvm/vioapic.c
--- a/xen/arch/x86/hvm/vioapic.c        Thu Dec 28 15:28:45 2006 +0000
+++ b/xen/arch/x86/hvm/vioapic.c        Thu Dec 28 16:33:15 2006 +0000
@@ -341,7 +341,7 @@ static void vioapic_deliver(struct vioap
     {
 #ifdef IRQ0_SPECIAL_ROUTING
         /* Force round-robin to pick VCPU 0 */
-        if ( irq == 0 )
+        if ( irq == hvm_isa_irq_to_gsi(0) )
         {
             v = vioapic_domain(vioapic)->vcpu[0];
             target = v ? vcpu_vlapic(v) : NULL;
@@ -374,7 +374,7 @@ static void vioapic_deliver(struct vioap
             deliver_bitmask &= ~(1 << bit);
 #ifdef IRQ0_SPECIAL_ROUTING
             /* Do not deliver timer interrupts to VCPU != 0 */
-            if ( (irq == 0) && (bit != 0) )
+            if ( irq == hvm_isa_irq_to_gsi(0) )
                 v = vioapic_domain(vioapic)->vcpu[0];
             else
 #endif
diff -r 766eec31afab -r ce83c1896acc xen/arch/x86/hvm/vpt.c
--- a/xen/arch/x86/hvm/vpt.c    Thu Dec 28 15:28:45 2006 +0000
+++ b/xen/arch/x86/hvm/vpt.c    Thu Dec 28 16:33:15 2006 +0000
@@ -108,16 +108,18 @@ void pt_update_irq(struct vcpu *v)
     list_for_each( list, head )
     {
         pt = list_entry(list, struct periodic_time, list);
-        if ( !is_irq_masked(v, pt->irq) && pt->pending_intr_nr 
-                && pt->last_plt_gtime + pt->period < max_lag )
-        {
-            max_lag = pt->last_plt_gtime + pt->period;
+        if ( !is_isa_irq_masked(v, pt->irq) && pt->pending_intr_nr &&
+             ((pt->last_plt_gtime + pt->period_cycles) < max_lag) )
+        {
+            max_lag = pt->last_plt_gtime + pt->period_cycles;
             irq = pt->irq;
         }
     }
 
     if ( is_lvtt(v, irq) )
+    {
         vlapic_set_irq(vcpu_vlapic(v), irq, 0);
+    }
     else if ( irq >= 0 )
     {
         hvm_isa_irq_deassert(v->domain, irq);
@@ -141,16 +143,15 @@ struct periodic_time *is_pt_irq(struct v
 
         if ( is_lvtt(v, pt->irq) )
         {
-            if (pt->irq == vector)
-                return pt;
-            else
+            if ( pt->irq != vector )
                 continue;
-        }
-
-        vec = get_intr_vector(v, pt->irq, type);
+            return pt;
+        }
+
+        vec = get_isa_irq_vector(v, pt->irq, type);
 
         /* RTC irq need special care */
-        if ( vector != vec || (pt->irq == 8 && !is_rtc_periodic_irq(rtc)) )
+        if ( (vector != vec) || (pt->irq == 8 && !is_rtc_periodic_irq(rtc)) )
             continue;
 
         return pt;
@@ -163,14 +164,14 @@ void pt_intr_post(struct vcpu *v, int ve
 {
     struct periodic_time *pt = is_pt_irq(v, vector, type);
 
-    if (pt == NULL)
+    if ( pt == NULL )
         return;
 
     pt->pending_intr_nr--;
     pt->last_plt_gtime += pt->period_cycles;
     hvm_set_guest_time(pt->vcpu, pt->last_plt_gtime);
 
-    if (pt->cb)
+    if ( pt->cb != NULL )
         pt->cb(pt->vcpu, pt->priv);
 }
 
@@ -200,9 +201,11 @@ void create_periodic_time(struct periodi
     destroy_periodic_time(pt);
 
     pt->enabled = 1;
-    if (period < 900000) /* < 0.9 ms */
-    {
-        printk("HVM_PlatformTime: program too small period %"PRIu64"\n", 
period);
+    if ( period < 900000 ) /* < 0.9 ms */
+    {
+        gdprintk(XENLOG_WARNING,
+                 "HVM_PlatformTime: program too small period %"PRIu64"\n",
+                 period);
         period = 900000; /* force to 0.9ms */
     }
     pt->period = period;
diff -r 766eec31afab -r ce83c1896acc xen/include/asm-x86/hvm/irq.h
--- a/xen/include/asm-x86/hvm/irq.h     Thu Dec 28 15:28:45 2006 +0000
+++ b/xen/include/asm-x86/hvm/irq.h     Thu Dec 28 16:33:15 2006 +0000
@@ -61,7 +61,8 @@ struct hvm_irq {
     /*
      * Number of wires asserting each GSI.
      * 
-     * GSIs 0-15 are the ISA IRQs. ISA devices map directly into this space.
+     * GSIs 0-15 are the ISA IRQs. ISA devices map directly into this space
+     * except ISA IRQ 0, which is connected to GSI 2.
      * PCI links map into this space via the PCI-ISA bridge.
      * 
      * GSIs 16+ are used only be PCI devices. The mapping from PCI device to
@@ -87,6 +88,8 @@ struct hvm_irq {
 #define hvm_pci_intx_link(dev, intx) \
     (((dev) + (intx)) & 3)
 
+#define hvm_isa_irq_to_gsi(isa_irq) ((isa_irq) ? : 2)
+
 /* Modify state of a PCI INTx wire. */
 void hvm_pci_intx_assert(
     struct domain *d, unsigned int device, unsigned int intx);
@@ -106,7 +109,7 @@ void hvm_set_callback_gsi(struct domain 
 
 int cpu_get_interrupt(struct vcpu *v, int *type);
 int cpu_has_pending_irq(struct vcpu *v);
-int get_intr_vector(struct vcpu* vcpu, int irq, int type);
-int is_irq_masked(struct vcpu *v, int irq);
+int get_isa_irq_vector(struct vcpu *vcpu, int irq, int type);
+int is_isa_irq_masked(struct vcpu *v, int isa_irq);
 
 #endif /* __ASM_X86_HVM_IRQ_H__ */

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.