KVM: Route irq 0 to vcpu 0 exclusively
authorAvi Kivity <avi@qumranet.com>
Mon, 25 Feb 2008 08:28:31 +0000 (10:28 +0200)
committerAvi Kivity <avi@qumranet.com>
Tue, 4 Mar 2008 13:19:48 +0000 (15:19 +0200)
Some Linux versions allow the timer interrupt to be processed by more than
one cpu, leading to hangs due to tsc instability.  Work around the issue
by only disaptching the interrupt to vcpu 0.

Problem analyzed (and patch tested) by Sheng Yang.

Signed-off-by: Avi Kivity <avi@qumranet.com>
virt/kvm/ioapic.c

index 317f8e211cd2a136f6a07c8333731dadd0389cbe..4232fd75dd20b710a4ca16c857b80a83948f2fe9 100644 (file)
@@ -211,6 +211,10 @@ static void ioapic_deliver(struct kvm_ioapic *ioapic, int irq)
        case IOAPIC_LOWEST_PRIORITY:
                vcpu = kvm_get_lowest_prio_vcpu(ioapic->kvm, vector,
                                deliver_bitmask);
+#ifdef CONFIG_X86
+               if (irq == 0)
+                       vcpu = ioapic->kvm->vcpus[0];
+#endif
                if (vcpu != NULL)
                        ioapic_inj_irq(ioapic, vcpu, vector,
                                       trig_mode, delivery_mode);
@@ -220,6 +224,10 @@ static void ioapic_deliver(struct kvm_ioapic *ioapic, int irq)
                                     deliver_bitmask, vector, IOAPIC_LOWEST_PRIORITY);
                break;
        case IOAPIC_FIXED:
+#ifdef CONFIG_X86
+               if (irq == 0)
+                       deliver_bitmask = 1;
+#endif
                for (vcpu_id = 0; deliver_bitmask != 0; vcpu_id++) {
                        if (!(deliver_bitmask & (1 << vcpu_id)))
                                continue;