Commit f3200d00 authored by Gleb Natapov's avatar Gleb Natapov Committed by Marcelo Tosatti

KVM: inject ExtINT interrupt before APIC interrupts

According to Intel SDM Volume 3 Section 10.8.1 "Interrupt Handling with
the Pentium 4 and Intel Xeon Processors" and Section 10.8.2 "Interrupt
Handling with the P6 Family and Pentium Processors" ExtINT interrupts are
sent directly to the processor core for handling. Currently KVM checks
APIC before it considers ExtINT interrupts for injection which is
backwards from the spec. Make code behave according to the SDM.
Signed-off-by: default avatarGleb Natapov <gleb@redhat.com>
Acked-by: default avatar"Zhang, Yang Z" <yang.z.zhang@intel.com>
Signed-off-by: default avatarMarcelo Tosatti <mtosatti@redhat.com>
parent 5e2c6883
...@@ -241,6 +241,8 @@ int kvm_pic_read_irq(struct kvm *kvm) ...@@ -241,6 +241,8 @@ int kvm_pic_read_irq(struct kvm *kvm)
int irq, irq2, intno; int irq, irq2, intno;
struct kvm_pic *s = pic_irqchip(kvm); struct kvm_pic *s = pic_irqchip(kvm);
s->output = 0;
pic_lock(s); pic_lock(s);
irq = pic_get_irq(&s->pics[0]); irq = pic_get_irq(&s->pics[0]);
if (irq >= 0) { if (irq >= 0) {
......
...@@ -48,14 +48,10 @@ int kvm_cpu_has_interrupt(struct kvm_vcpu *v) ...@@ -48,14 +48,10 @@ int kvm_cpu_has_interrupt(struct kvm_vcpu *v)
if (!irqchip_in_kernel(v->kvm)) if (!irqchip_in_kernel(v->kvm))
return v->arch.interrupt.pending; return v->arch.interrupt.pending;
if (kvm_apic_has_interrupt(v) == -1) { /* LAPIC */ if (kvm_apic_accept_pic_intr(v) && pic_irqchip(v->kvm)->output)
if (kvm_apic_accept_pic_intr(v)) { return pic_irqchip(v->kvm)->output; /* PIC */
s = pic_irqchip(v->kvm); /* PIC */
return s->output; return kvm_apic_has_interrupt(v) != -1; /* LAPIC */
} else
return 0;
}
return 1;
} }
EXPORT_SYMBOL_GPL(kvm_cpu_has_interrupt); EXPORT_SYMBOL_GPL(kvm_cpu_has_interrupt);
...@@ -65,20 +61,14 @@ EXPORT_SYMBOL_GPL(kvm_cpu_has_interrupt); ...@@ -65,20 +61,14 @@ EXPORT_SYMBOL_GPL(kvm_cpu_has_interrupt);
int kvm_cpu_get_interrupt(struct kvm_vcpu *v) int kvm_cpu_get_interrupt(struct kvm_vcpu *v)
{ {
struct kvm_pic *s; struct kvm_pic *s;
int vector;
if (!irqchip_in_kernel(v->kvm)) if (!irqchip_in_kernel(v->kvm))
return v->arch.interrupt.nr; return v->arch.interrupt.nr;
vector = kvm_get_apic_interrupt(v); /* APIC */ if (kvm_apic_accept_pic_intr(v) && pic_irqchip(v->kvm)->output)
if (vector == -1) { return kvm_pic_read_irq(v->kvm); /* PIC */
if (kvm_apic_accept_pic_intr(v)) {
s = pic_irqchip(v->kvm); return kvm_get_apic_interrupt(v); /* APIC */
s->output = 0; /* PIC */
vector = kvm_pic_read_irq(v->kvm);
}
}
return vector;
} }
EXPORT_SYMBOL_GPL(kvm_cpu_get_interrupt); EXPORT_SYMBOL_GPL(kvm_cpu_get_interrupt);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment