Commit c2207bbc authored by Sean Christopherson's avatar Sean Christopherson
Browse files

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: default avatarKai Huang <kai.huang@intel.com>
Link: https://lore.kernel.org/r/20250304013335.4155703-3-seanjc@google.com


Signed-off-by: default avatarSean Christopherson <seanjc@google.com>
parent b1f7723a
Loading
Loading
Loading
Loading
+2 −5
Original line number Diff line number Diff line
@@ -296,11 +296,8 @@ void kvm_ioapic_scan_entry(struct kvm_vcpu *vcpu, ulong *ioapic_handled_vectors)
		    index == RTC_GSI) {
			u16 dm = kvm_lapic_irq_dest_mode(!!e->fields.dest_mode);

			if (kvm_apic_match_dest(vcpu, NULL, APIC_DEST_NOSHORT,
						e->fields.dest_id, dm) ||
			    kvm_apic_pending_eoi(vcpu, e->fields.vector))
				__set_bit(e->fields.vector,
					  ioapic_handled_vectors);
			kvm_scan_ioapic_irq(vcpu, e->fields.dest_id, dm,
					    e->fields.vector, ioapic_handled_vectors);
		}
	}
	spin_unlock(&ioapic->lock);
+2 −0
Original line number Diff line number Diff line
@@ -120,4 +120,6 @@ void kvm_ioapic_scan_entry(struct kvm_vcpu *vcpu,
			   ulong *ioapic_handled_vectors);
void kvm_scan_ioapic_routes(struct kvm_vcpu *vcpu,
			    ulong *ioapic_handled_vectors);
void kvm_scan_ioapic_irq(struct kvm_vcpu *vcpu, u32 dest_id, u16 dest_mode,
			 u8 vector, unsigned long *ioapic_handled_vectors);
#endif
+17 −4
Original line number Diff line number Diff line
@@ -402,6 +402,21 @@ void kvm_arch_post_irq_routing_update(struct kvm *kvm)
	kvm_make_scan_ioapic_request(kvm);
}

void kvm_scan_ioapic_irq(struct kvm_vcpu *vcpu, u32 dest_id, u16 dest_mode,
			 u8 vector, unsigned long *ioapic_handled_vectors)
{
	/*
	 * Intercept EOI if the vCPU is the target of the new IRQ routing, or
	 * the vCPU has a pending IRQ from the old routing, i.e. if the vCPU
	 * may receive a level-triggered IRQ in the future, or already received
	 * level-triggered IRQ.  The EOI needs to be intercepted and forwarded
	 * to I/O APIC emulation so that the IRQ can be de-asserted.
	 */
	if (kvm_apic_match_dest(vcpu, NULL, APIC_DEST_NOSHORT, dest_id, dest_mode) ||
	    kvm_apic_pending_eoi(vcpu, vector))
		__set_bit(vector, ioapic_handled_vectors);
}

void kvm_scan_ioapic_routes(struct kvm_vcpu *vcpu,
			    ulong *ioapic_handled_vectors)
{
@@ -427,10 +442,8 @@ void kvm_scan_ioapic_routes(struct kvm_vcpu *vcpu,
			if (!irq.trig_mode)
				continue;

			if (kvm_apic_match_dest(vcpu, NULL, APIC_DEST_NOSHORT,
						irq.dest_id, irq.dest_mode) ||
			     kvm_apic_pending_eoi(vcpu, irq.vector))
				__set_bit(irq.vector, ioapic_handled_vectors);
			kvm_scan_ioapic_irq(vcpu, irq.dest_id, irq.dest_mode,
					    irq.vector, ioapic_handled_vectors);
		}
	}
	srcu_read_unlock(&kvm->irq_srcu, idx);