diff options
author | Paolo Bonzini <pbonzini@redhat.com> | 2016-12-18 15:43:41 -0500 |
---|---|---|
committer | Radim Krčmář <rkrcmar@redhat.com> | 2017-01-09 08:48:03 -0500 |
commit | 4d82d12b39132e820b9ac4aa058ccc733db98917 (patch) | |
tree | 1b45c6b38d4a934131b77c62f964c36a4676b18f | |
parent | 26fbbee5815e9352187ac18f0aa53534f62567ff (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.c | 19 |
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; |