Skip to content

Commit c2207bb

Browse files
committed
KVM: x86: Add a helper to deduplicate I/O APIC EOI interception logic
Extract the vCPU specific EOI interception logic for I/O APIC emulation into a common helper for userspace and in-kernel emulation in anticipation of optimizing the "pending EOI" case. No functional change intended. Reviewed-by: Kai Huang <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Sean Christopherson <[email protected]>
1 parent b1f7723 commit c2207bb

File tree

3 files changed

+21
-9
lines changed

3 files changed

+21
-9
lines changed

arch/x86/kvm/ioapic.c

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -296,11 +296,8 @@ void kvm_ioapic_scan_entry(struct kvm_vcpu *vcpu, ulong *ioapic_handled_vectors)
296296
index == RTC_GSI) {
297297
u16 dm = kvm_lapic_irq_dest_mode(!!e->fields.dest_mode);
298298

299-
if (kvm_apic_match_dest(vcpu, NULL, APIC_DEST_NOSHORT,
300-
e->fields.dest_id, dm) ||
301-
kvm_apic_pending_eoi(vcpu, e->fields.vector))
302-
__set_bit(e->fields.vector,
303-
ioapic_handled_vectors);
299+
kvm_scan_ioapic_irq(vcpu, e->fields.dest_id, dm,
300+
e->fields.vector, ioapic_handled_vectors);
304301
}
305302
}
306303
spin_unlock(&ioapic->lock);

arch/x86/kvm/ioapic.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,4 +120,6 @@ void kvm_ioapic_scan_entry(struct kvm_vcpu *vcpu,
120120
ulong *ioapic_handled_vectors);
121121
void kvm_scan_ioapic_routes(struct kvm_vcpu *vcpu,
122122
ulong *ioapic_handled_vectors);
123+
void kvm_scan_ioapic_irq(struct kvm_vcpu *vcpu, u32 dest_id, u16 dest_mode,
124+
u8 vector, unsigned long *ioapic_handled_vectors);
123125
#endif

arch/x86/kvm/irq_comm.c

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,21 @@ void kvm_arch_post_irq_routing_update(struct kvm *kvm)
402402
kvm_make_scan_ioapic_request(kvm);
403403
}
404404

405+
void kvm_scan_ioapic_irq(struct kvm_vcpu *vcpu, u32 dest_id, u16 dest_mode,
406+
u8 vector, unsigned long *ioapic_handled_vectors)
407+
{
408+
/*
409+
* Intercept EOI if the vCPU is the target of the new IRQ routing, or
410+
* the vCPU has a pending IRQ from the old routing, i.e. if the vCPU
411+
* may receive a level-triggered IRQ in the future, or already received
412+
* level-triggered IRQ. The EOI needs to be intercepted and forwarded
413+
* to I/O APIC emulation so that the IRQ can be de-asserted.
414+
*/
415+
if (kvm_apic_match_dest(vcpu, NULL, APIC_DEST_NOSHORT, dest_id, dest_mode) ||
416+
kvm_apic_pending_eoi(vcpu, vector))
417+
__set_bit(vector, ioapic_handled_vectors);
418+
}
419+
405420
void kvm_scan_ioapic_routes(struct kvm_vcpu *vcpu,
406421
ulong *ioapic_handled_vectors)
407422
{
@@ -427,10 +442,8 @@ void kvm_scan_ioapic_routes(struct kvm_vcpu *vcpu,
427442
if (!irq.trig_mode)
428443
continue;
429444

430-
if (kvm_apic_match_dest(vcpu, NULL, APIC_DEST_NOSHORT,
431-
irq.dest_id, irq.dest_mode) ||
432-
kvm_apic_pending_eoi(vcpu, irq.vector))
433-
__set_bit(irq.vector, ioapic_handled_vectors);
445+
kvm_scan_ioapic_irq(vcpu, irq.dest_id, irq.dest_mode,
446+
irq.vector, ioapic_handled_vectors);
434447
}
435448
}
436449
srcu_read_unlock(&kvm->irq_srcu, idx);

0 commit comments

Comments
 (0)