aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAvi Kivity <avi@qumranet.com>2008-02-25 03:28:31 -0500
committerAvi Kivity <avi@qumranet.com>2008-03-04 08:19:48 -0500
commit8c35f237fb5664d30aa90448c3d6cea0cbb43f35 (patch)
tree1de7e021aff7ac0593ed9307045f6dd4fa771995
parent0b975a3c2d53829fa978e18fabae7d99031f588f (diff)
KVM: Route irq 0 to vcpu 0 exclusively
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>
-rw-r--r--virt/kvm/ioapic.c8
1 files changed, 8 insertions, 0 deletions
diff --git a/virt/kvm/ioapic.c b/virt/kvm/ioapic.c
index 317f8e211cd2..4232fd75dd20 100644
--- a/virt/kvm/ioapic.c
+++ b/virt/kvm/ioapic.c
@@ -211,6 +211,10 @@ static void ioapic_deliver(struct kvm_ioapic *ioapic, int irq)
211 case IOAPIC_LOWEST_PRIORITY: 211 case IOAPIC_LOWEST_PRIORITY:
212 vcpu = kvm_get_lowest_prio_vcpu(ioapic->kvm, vector, 212 vcpu = kvm_get_lowest_prio_vcpu(ioapic->kvm, vector,
213 deliver_bitmask); 213 deliver_bitmask);
214#ifdef CONFIG_X86
215 if (irq == 0)
216 vcpu = ioapic->kvm->vcpus[0];
217#endif
214 if (vcpu != NULL) 218 if (vcpu != NULL)
215 ioapic_inj_irq(ioapic, vcpu, vector, 219 ioapic_inj_irq(ioapic, vcpu, vector,
216 trig_mode, delivery_mode); 220 trig_mode, delivery_mode);
@@ -220,6 +224,10 @@ static void ioapic_deliver(struct kvm_ioapic *ioapic, int irq)
220 deliver_bitmask, vector, IOAPIC_LOWEST_PRIORITY); 224 deliver_bitmask, vector, IOAPIC_LOWEST_PRIORITY);
221 break; 225 break;
222 case IOAPIC_FIXED: 226 case IOAPIC_FIXED:
227#ifdef CONFIG_X86
228 if (irq == 0)
229 deliver_bitmask = 1;
230#endif
223 for (vcpu_id = 0; deliver_bitmask != 0; vcpu_id++) { 231 for (vcpu_id = 0; deliver_bitmask != 0; vcpu_id++) {
224 if (!(deliver_bitmask & (1 << vcpu_id))) 232 if (!(deliver_bitmask & (1 << vcpu_id)))
225 continue; 233 continue;