aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/kvm/lapic.c18
1 files changed, 12 insertions, 6 deletions
diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
index 6e8ce5a1a05d..e0e5642dae41 100644
--- a/arch/x86/kvm/lapic.c
+++ b/arch/x86/kvm/lapic.c
@@ -341,8 +341,12 @@ EXPORT_SYMBOL_GPL(kvm_apic_update_irr);
341 341
342static inline void apic_set_irr(int vec, struct kvm_lapic *apic) 342static inline void apic_set_irr(int vec, struct kvm_lapic *apic)
343{ 343{
344 apic->irr_pending = true;
345 apic_set_vector(vec, apic->regs + APIC_IRR); 344 apic_set_vector(vec, apic->regs + APIC_IRR);
345 /*
346 * irr_pending must be true if any interrupt is pending; set it after
347 * APIC_IRR to avoid race with apic_clear_irr
348 */
349 apic->irr_pending = true;
346} 350}
347 351
348static inline int apic_search_irr(struct kvm_lapic *apic) 352static inline int apic_search_irr(struct kvm_lapic *apic)
@@ -374,13 +378,15 @@ static inline void apic_clear_irr(int vec, struct kvm_lapic *apic)
374 378
375 vcpu = apic->vcpu; 379 vcpu = apic->vcpu;
376 380
377 apic_clear_vector(vec, apic->regs + APIC_IRR); 381 if (unlikely(kvm_apic_vid_enabled(vcpu->kvm))) {
378 if (unlikely(kvm_apic_vid_enabled(vcpu->kvm)))
379 /* try to update RVI */ 382 /* try to update RVI */
383 apic_clear_vector(vec, apic->regs + APIC_IRR);
380 kvm_make_request(KVM_REQ_EVENT, vcpu); 384 kvm_make_request(KVM_REQ_EVENT, vcpu);
381 else { 385 } else {
382 vec = apic_search_irr(apic); 386 apic->irr_pending = false;
383 apic->irr_pending = (vec != -1); 387 apic_clear_vector(vec, apic->regs + APIC_IRR);
388 if (apic_search_irr(apic) != -1)
389 apic->irr_pending = true;
384 } 390 }
385} 391}
386 392