|
@@ -353,6 +353,7 @@ static inline int apic_find_highest_irr(struct kvm_lapic *apic)
|
|
|
if (!apic->irr_pending)
|
|
|
return -1;
|
|
|
|
|
|
+ kvm_x86_ops->sync_pir_to_irr(apic->vcpu);
|
|
|
result = apic_search_irr(apic);
|
|
|
ASSERT(result == -1 || result >= 16);
|
|
|
|
|
@@ -683,18 +684,25 @@ static int __apic_accept_irq(struct kvm_lapic *apic, int delivery_mode,
|
|
|
if (dest_map)
|
|
|
__set_bit(vcpu->vcpu_id, dest_map);
|
|
|
|
|
|
- result = !apic_test_and_set_irr(vector, apic);
|
|
|
- trace_kvm_apic_accept_irq(vcpu->vcpu_id, delivery_mode,
|
|
|
- trig_mode, vector, !result);
|
|
|
- if (!result) {
|
|
|
- if (trig_mode)
|
|
|
- apic_debug("level trig mode repeatedly for "
|
|
|
- "vector %d", vector);
|
|
|
- break;
|
|
|
- }
|
|
|
+ if (kvm_x86_ops->deliver_posted_interrupt) {
|
|
|
+ result = 1;
|
|
|
+ kvm_x86_ops->deliver_posted_interrupt(vcpu, vector);
|
|
|
+ } else {
|
|
|
+ result = !apic_test_and_set_irr(vector, apic);
|
|
|
|
|
|
- kvm_make_request(KVM_REQ_EVENT, vcpu);
|
|
|
- kvm_vcpu_kick(vcpu);
|
|
|
+ if (!result) {
|
|
|
+ if (trig_mode)
|
|
|
+ apic_debug("level trig mode repeatedly "
|
|
|
+ "for vector %d", vector);
|
|
|
+ goto out;
|
|
|
+ }
|
|
|
+
|
|
|
+ kvm_make_request(KVM_REQ_EVENT, vcpu);
|
|
|
+ kvm_vcpu_kick(vcpu);
|
|
|
+ }
|
|
|
+out:
|
|
|
+ trace_kvm_apic_accept_irq(vcpu->vcpu_id, delivery_mode,
|
|
|
+ trig_mode, vector, !result);
|
|
|
break;
|
|
|
|
|
|
case APIC_DM_REMRD:
|