This is a note to let you know that I've just added the patch titled KVM: VMX: prepare sync_pir_to_irr for running with APICv disabled to the 5.15-stable tree which can be found at: http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary The filename of the patch is: kvm-vmx-prepare-sync_pir_to_irr-for-running-with-apicv-disabled.patch and it can be found in the queue-5.15 subdirectory. If you, or anyone else, feels it should not be added to the stable tree, please let <stable@xxxxxxxxxxxxxxx> know about it. >From 7e1901f6c86c896acff6609e0176f93f756d8b2a Mon Sep 17 00:00:00 2001 From: Paolo Bonzini <pbonzini@xxxxxxxxxx> Date: Mon, 22 Nov 2021 19:43:09 -0500 Subject: KVM: VMX: prepare sync_pir_to_irr for running with APICv disabled From: Paolo Bonzini <pbonzini@xxxxxxxxxx> commit 7e1901f6c86c896acff6609e0176f93f756d8b2a upstream. If APICv is disabled for this vCPU, assigned devices may still attempt to post interrupts. In that case, we need to cancel the vmentry and deliver the interrupt with KVM_REQ_EVENT. Extend the existing code that handles injection of L1 interrupts into L2 to cover this case as well. vmx_hwapic_irr_update is only called when APICv is active so it would be confusing to add a check for vcpu->arch.apicv_active in there. Instead, just use vmx_set_rvi directly in vmx_sync_pir_to_irr. Cc: stable@xxxxxxxxxxxxxxx Reviewed-by: Maxim Levitsky <mlevitsk@xxxxxxxxxx> Reviewed-by: David Matlack <dmatlack@xxxxxxxxxx> Reviewed-by: Sean Christopherson <seanjc@xxxxxxxxxx> Message-Id: <20211123004311.2954158-3-pbonzini@xxxxxxxxxx> Signed-off-by: Paolo Bonzini <pbonzini@xxxxxxxxxx> Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx> --- arch/x86/kvm/vmx/vmx.c | 39 +++++++++++++++++++++++++-------------- 1 file changed, 25 insertions(+), 14 deletions(-) --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -6242,9 +6242,9 @@ static int vmx_sync_pir_to_irr(struct kv { struct vcpu_vmx *vmx = to_vmx(vcpu); int max_irr; - bool max_irr_updated; + bool got_posted_interrupt; - if (KVM_BUG_ON(!vcpu->arch.apicv_active, vcpu->kvm)) + if (KVM_BUG_ON(!enable_apicv, vcpu->kvm)) return -EIO; if (pi_test_on(&vmx->pi_desc)) { @@ -6254,22 +6254,33 @@ static int vmx_sync_pir_to_irr(struct kv * But on x86 this is just a compiler barrier anyway. */ smp_mb__after_atomic(); - max_irr_updated = + got_posted_interrupt = kvm_apic_update_irr(vcpu, vmx->pi_desc.pir, &max_irr); - - /* - * If we are running L2 and L1 has a new pending interrupt - * which can be injected, this may cause a vmexit or it may - * be injected into L2. Either way, this interrupt will be - * processed via KVM_REQ_EVENT, not RVI, because we do not use - * virtual interrupt delivery to inject L1 interrupts into L2. - */ - if (is_guest_mode(vcpu) && max_irr_updated) - kvm_make_request(KVM_REQ_EVENT, vcpu); } else { max_irr = kvm_lapic_find_highest_irr(vcpu); + got_posted_interrupt = false; } - vmx_hwapic_irr_update(vcpu, max_irr); + + /* + * Newly recognized interrupts are injected via either virtual interrupt + * delivery (RVI) or KVM_REQ_EVENT. Virtual interrupt delivery is + * disabled in two cases: + * + * 1) If L2 is running and the vCPU has a new pending interrupt. If L1 + * wants to exit on interrupts, KVM_REQ_EVENT is needed to synthesize a + * VM-Exit to L1. If L1 doesn't want to exit, the interrupt is injected + * into L2, but KVM doesn't use virtual interrupt delivery to inject + * interrupts into L2, and so KVM_REQ_EVENT is again needed. + * + * 2) If APICv is disabled for this vCPU, assigned devices may still + * attempt to post interrupts. The posted interrupt vector will cause + * a VM-Exit and the subsequent entry will call sync_pir_to_irr. + */ + if (!is_guest_mode(vcpu) && kvm_vcpu_apicv_active(vcpu)) + vmx_set_rvi(max_irr); + else if (got_posted_interrupt) + kvm_make_request(KVM_REQ_EVENT, vcpu); + return max_irr; } Patches currently in stable-queue which might be from pbonzini@xxxxxxxxxx are queue-5.15/kvm-nvmx-abide-to-kvm_req_tlb_flush_guest-request-on-nested-vmentry-vmexit.patch queue-5.15/kvm-x86-mmu-fix-tlb-flush-range-when-handling-disconnected-pt.patch queue-5.15/kvm-nvmx-flush-current-vpid-l1-vs.-l2-for-kvm_req_tlb_flush_guest.patch queue-5.15/kvm-x86-use-vcpu-arch.walk_mmu-for-kvm_mmu_invlpg.patch queue-5.15/kvm-disallow-user-memslot-with-size-that-exceeds-unsigned-long.patch queue-5.15/kvm-nvmx-emulate-guest-tlb-flush-on-nested-vm-enter-with-new-vpid12.patch queue-5.15/kvm-x86-ignore-apicv-if-lapic-is-not-enabled.patch queue-5.15/kvm-fix-avic_set_running-for-preemptable-kernels.patch queue-5.15/kvm-x86-check-pir-even-for-vcpus-with-disabled-apicv.patch queue-5.15/kvm-x86-use-a-stable-condition-around-all-vt-d-pi-paths.patch queue-5.15/kvm-mmu-shadow-nested-paging-does-not-have-pku.patch queue-5.15/kvm-ensure-local-memslot-copies-operate-on-up-to-date-arch-specific-data.patch queue-5.15/kvm-vmx-prepare-sync_pir_to_irr-for-running-with-apicv-disabled.patch