diff mbox series

KVM: x86: Always sync PIR to IRR prior to scanning I/O APIC routes

Message ID 20240611014845.82795-1-seanjc@google.com (mailing list archive)
State New, archived
Headers show
Series KVM: x86: Always sync PIR to IRR prior to scanning I/O APIC routes | expand

Commit Message

Sean Christopherson June 11, 2024, 1:48 a.m. UTC
Sync pending posted interrupts to the IRR prior to re-scanning I/O APIC
routes, irrespective of whether the I/O APIC is emulated by userspace or
by KVM.  If a level-triggered interrupt routed through the I/O APIC is
pending or in-service for a vCPU, KVM needs to intercept EOIs on said
vCPU even if the vCPU isn't the destination for the new routing, e.g. if
servicing an interrupt using the old routing races with I/O APIC
reconfiguration.

Commit fceb3a36c29a ("KVM: x86: ioapic: Fix level-triggered EOI and
userspace I/OAPIC reconfigure race") fixed the common cases, but
kvm_apic_pending_eoi() only checks if an interrupt is in the local
APIC's IRR or ISR, i.e. misses the uncommon case where an interrupt is
pending in the PIR.

Failure to intercept EOI can manifest as guest hangs with Windows 11 if
the guest uses the RTC as its timekeeping source, e.g. if the VMM doesn't
expose a more modern form of time to the guest.

Cc: stable@vger.kernel.org
Cc: Adamos Ttofari <attofari@amazon.de>
Cc: Raghavendra Rao Ananta <rananta@google.com>
Cc: Jim Mattson <jmattson@google.com>
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
 arch/x86/kvm/x86.c | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)


base-commit: af0903ab52ee6d6f0f63af67fa73d5eb00f79b9a

Comments

Jim Mattson June 11, 2024, 3:47 a.m. UTC | #1
On Mon, Jun 10, 2024 at 6:48 PM Sean Christopherson <seanjc@google.com> wrote:
>
> Sync pending posted interrupts to the IRR prior to re-scanning I/O APIC
> routes, irrespective of whether the I/O APIC is emulated by userspace or
> by KVM.  If a level-triggered interrupt routed through the I/O APIC is
> pending or in-service for a vCPU, KVM needs to intercept EOIs on said
> vCPU even if the vCPU isn't the destination for the new routing, e.g. if
> servicing an interrupt using the old routing races with I/O APIC
> reconfiguration.
>
> Commit fceb3a36c29a ("KVM: x86: ioapic: Fix level-triggered EOI and
> userspace I/OAPIC reconfigure race") fixed the common cases, but
> kvm_apic_pending_eoi() only checks if an interrupt is in the local
> APIC's IRR or ISR, i.e. misses the uncommon case where an interrupt is
> pending in the PIR.
>
> Failure to intercept EOI can manifest as guest hangs with Windows 11 if
> the guest uses the RTC as its timekeeping source, e.g. if the VMM doesn't
> expose a more modern form of time to the guest.
>
> Cc: stable@vger.kernel.org
> Cc: Adamos Ttofari <attofari@amazon.de>
> Cc: Raghavendra Rao Ananta <rananta@google.com>
> Cc: Jim Mattson <jmattson@google.com>
> Signed-off-by: Sean Christopherson <seanjc@google.com>
Reviewed-by: Jim Mattson <jmattson@google.com>
Paolo Bonzini June 11, 2024, 7:54 a.m. UTC | #2
Queued, thanks.

Paolo
diff mbox series

Patch

diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 4157602c964e..f2322af38242 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -10736,13 +10736,12 @@  static void vcpu_scan_ioapic(struct kvm_vcpu *vcpu)
 
 	bitmap_zero(vcpu->arch.ioapic_handled_vectors, 256);
 
+	static_call_cond(kvm_x86_sync_pir_to_irr)(vcpu);
+
 	if (irqchip_split(vcpu->kvm))
 		kvm_scan_ioapic_routes(vcpu, vcpu->arch.ioapic_handled_vectors);
-	else {
-		static_call_cond(kvm_x86_sync_pir_to_irr)(vcpu);
-		if (ioapic_in_kernel(vcpu->kvm))
-			kvm_ioapic_scan_entry(vcpu, vcpu->arch.ioapic_handled_vectors);
-	}
+	else if (ioapic_in_kernel(vcpu->kvm))
+		kvm_ioapic_scan_entry(vcpu, vcpu->arch.ioapic_handled_vectors);
 
 	if (is_guest_mode(vcpu))
 		vcpu->arch.load_eoi_exitmap_pending = true;