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

[Xen-changelog] [xen-unstable] Workaround for bigsmp APIC mode SMP linux guests - we cannot correctly deal



# HG changeset patch
# User Steven Hand <steven@xxxxxxxxxxxxx>
# Node ID 8e8128077259ec2f042cd69059d9b38b4fd8d433
# Parent  59b41031641d80f9fa1e5b8af0e7d399c346e484
Workaround for bigsmp APIC mode SMP linux guests - we cannot correctly deal
with timer interrupts being delivered to VCPUs other than 0, so spit a
warning and then subsequently ignore the target. This fixes the recent
issues Intel reported when booting SMP FC5 and FC6 kernels.

Needs a better fix at some point.

Signed-off-by: Steven Hand <steven@xxxxxxxxxxxxx>
---
 xen/arch/x86/hvm/vioapic.c |   53 +++++++++++++++++++++++++++++----------------
 1 files changed, 35 insertions(+), 18 deletions(-)

diff -r 59b41031641d -r 8e8128077259 xen/arch/x86/hvm/vioapic.c
--- a/xen/arch/x86/hvm/vioapic.c        Fri Oct 20 11:00:08 2006 +0100
+++ b/xen/arch/x86/hvm/vioapic.c        Fri Oct 20 11:43:14 2006 +0100
@@ -42,6 +42,9 @@
 
 /* HACK: Route IRQ0 only to VCPU0 to prevent time jumps. */
 #define IRQ0_SPECIAL_ROUTING 1
+#ifdef IRQ0_SPECIAL_ROUTING
+static int redir_warning_done = 0; 
+#endif
 
 #if defined(__ia64__)
 #define opt_hvm_debug_level opt_vmx_debug_level
@@ -155,6 +158,7 @@ static void hvm_vioapic_update_imr(struc
        clear_bit(index, &s->imr);
 }
 
+
 static void hvm_vioapic_write_indirect(struct hvm_vioapic *s,
                                       unsigned long addr,
                                       unsigned long length,
@@ -179,21 +183,35 @@ static void hvm_vioapic_write_indirect(s
         {
             uint32_t redir_index = 0;
 
+            redir_index = (s->ioregsel - 0x10) >> 1;
+
             HVM_DBG_LOG(DBG_LEVEL_IOAPIC, "hvm_vioapic_write_indirect "
               "change redir index %x val %lx\n",
               redir_index, val);
 
-            redir_index = (s->ioregsel - 0x10) >> 1;
-
             if (redir_index >= 0 && redir_index < IOAPIC_NUM_PINS) {
                 uint64_t redir_content;
 
                 redir_content = s->redirtbl[redir_index].value;
 
-                if (s->ioregsel & 0x1)
+                if (s->ioregsel & 0x1) {
+#ifdef IRQ0_SPECIAL_ROUTING
+                    if ( !redir_warning_done && (redir_index == 0) &&
+                         ((val >> 24) != 0) ) {
+                        /*
+                         * Cannot yet handle delivering PIT interrupts to
+                         * any VCPU != 0. Needs proper fixing, but for now
+                         * simply spit a warning that we're going to ignore
+                         * the target in practice & always deliver to VCPU 0
+                         */
+                        printk("IO-APIC: PIT (IRQ0) redirect to VCPU %lx "
+                               "will be ignored.\n", val >> 24); 
+                        redir_warning_done = 1;
+                    }
+#endif
                     redir_content = (((uint64_t)val & 0xffffffff) << 32) |
                                     (redir_content & 0xffffffff);
-                else
+                } else
                     redir_content = ((redir_content >> 32) << 32) |
                                     (val & 0xffffffff);
                 s->redirtbl[redir_index].value = redir_content;
@@ -409,6 +427,8 @@ static void ioapic_deliver(hvm_vioapic_t
     uint8_t vector = s->redirtbl[irqno].RedirForm.vector;
     uint8_t trig_mode = s->redirtbl[irqno].RedirForm.trigmod;
     uint32_t deliver_bitmask;
+    struct vlapic *target;
+
 
     HVM_DBG_LOG(DBG_LEVEL_IOAPIC,
       "dest %x dest_mode %x delivery_mode %x vector %x trig_mode %x\n",
@@ -427,9 +447,8 @@ static void ioapic_deliver(hvm_vioapic_t
     switch (delivery_mode) {
     case dest_LowestPrio:
     {
-        struct vlapic* target;
-
 #ifdef IRQ0_SPECIAL_ROUTING
+        /* Force round-robin to pick VCPU 0 */
         if (irqno == 0)
             target = s->lapic_info[0];
         else
@@ -450,19 +469,17 @@ static void ioapic_deliver(hvm_vioapic_t
     {
         uint8_t bit;
         for (bit = 0; bit < s->lapic_count; bit++) {
-            if (deliver_bitmask & (1 << bit)) {
+            if ( !(deliver_bitmask & (1 << bit)) )
+                continue;
 #ifdef IRQ0_SPECIAL_ROUTING
-                if ( (irqno == 0) && (bit !=0) )
-                {
-                    printk("PIT irq to bit %x\n", bit);
-                    domain_crash_synchronous();
-                }
-#endif
-                if (s->lapic_info[bit]) {
-                    ioapic_inj_irq(s, s->lapic_info[bit],
-                                vector, trig_mode, delivery_mode);
-                }
-            }
+            /* Do not deliver timer interrupts to VCPU != 0 */
+            if ( (irqno == 0) && (bit !=0 ) )
+                target = s->lapic_info[0];
+            else
+#endif
+                target = s->lapic_info[bit];
+            if (target)
+                ioapic_inj_irq(s, target, vector, trig_mode, delivery_mode);
         }
         break;
     }

_______________________________________________
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®.