aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2016-12-18 15:43:41 -0500
committerRadim Krčmář <rkrcmar@redhat.com>2017-01-09 08:48:03 -0500
commit4d82d12b39132e820b9ac4aa058ccc733db98917 (patch)
tree1b45c6b38d4a934131b77c62f964c36a4676b18f
parent26fbbee5815e9352187ac18f0aa53534f62567ff (diff)
KVM: lapic: do not scan IRR when delivering an interrupt
On interrupt delivery the PPR can only grow (except for auto-EOI), so it is impossible that non-auto-EOI interrupt delivery results in KVM_REQ_EVENT. We can therefore use __apic_update_ppr. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-rw-r--r--arch/x86/kvm/lapic.c19
1 files changed, 15 insertions, 4 deletions
diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
index 457fb206647d..10a745faa659 100644
--- a/arch/x86/kvm/lapic.c
+++ b/arch/x86/kvm/lapic.c
@@ -2115,6 +2115,7 @@ int kvm_get_apic_interrupt(struct kvm_vcpu *vcpu)
2115{ 2115{
2116 int vector = kvm_apic_has_interrupt(vcpu); 2116 int vector = kvm_apic_has_interrupt(vcpu);
2117 struct kvm_lapic *apic = vcpu->arch.apic; 2117 struct kvm_lapic *apic = vcpu->arch.apic;
2118 u32 ppr;
2118 2119
2119 if (vector == -1) 2120 if (vector == -1)
2120 return -1; 2121 return -1;
@@ -2126,13 +2127,23 @@ int kvm_get_apic_interrupt(struct kvm_vcpu *vcpu)
2126 * because the process would deliver it through the IDT. 2127 * because the process would deliver it through the IDT.
2127 */ 2128 */
2128 2129
2129 apic_set_isr(vector, apic);
2130 apic_update_ppr(apic);
2131 apic_clear_irr(vector, apic); 2130 apic_clear_irr(vector, apic);
2132
2133 if (test_bit(vector, vcpu_to_synic(vcpu)->auto_eoi_bitmap)) { 2131 if (test_bit(vector, vcpu_to_synic(vcpu)->auto_eoi_bitmap)) {
2134 apic_clear_isr(vector, apic); 2132 /*
2133 * For auto-EOI interrupts, there might be another pending
2134 * interrupt above PPR, so check whether to raise another
2135 * KVM_REQ_EVENT.
2136 */
2135 apic_update_ppr(apic); 2137 apic_update_ppr(apic);
2138 } else {
2139 /*
2140 * For normal interrupts, PPR has been raised and there cannot
2141 * be a higher-priority pending interrupt---except if there was
2142 * a concurrent interrupt injection, but that would have
2143 * triggered KVM_REQ_EVENT already.
2144 */
2145 apic_set_isr(vector, apic);
2146 __apic_update_ppr(apic, &ppr);
2136 } 2147 }
2137 2148
2138 return vector; 2149 return vector;