All of lore.kernel.org
 help / color / mirror / Atom feed
From: Yosry Ahmed <yosry@kernel.org>
To: Sean Christopherson <seanjc@google.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>,
	Jim Mattson <jmattson@google.com>,
	 kvm@vger.kernel.org, linux-kernel@vger.kernel.org,
	stable@vger.kernel.org,  Sashiko <sashiko-bot@kernel.org>
Subject: Re: [PATCH v2] KVM: nVMX: Service local TLB flushes on failed nested VM-Enter
Date: Tue, 28 Jul 2026 00:43:46 +0000	[thread overview]
Message-ID: <amf7CA4q33qoIx25@google.com> (raw)
In-Reply-To: <20260722230128.1587363-1-yosry@kernel.org>

On Wed, Jul 22, 2026 at 11:01:28PM +0000, Yosry Ahmed wrote:
> KVM services local TLB flushes on "full" nested VM-Exits (through
> __nested_vmx_vmexit()), but not if a nested VM-Enter fails (e.g. due to
> failed VMCS checks in nested_vmx_enter_non_root_mode()).
> 
> However, it is possible that KVM had queued TLB flushes that need to be
> performed, even if the nested VM-Enter was not successful. For example,
> if VPID is disabled for L2 (via nested_vmx_transition_tlb_flush(), or if
> via the MSR load lists, as the SDM says:
> 
>   If any MSR is being loaded in such a way that would architecturally
>   require a TLB flush, the TLBs are updated so that, after VM entry, the
>   logical processor will not use any translations that were cached before
>   the transition.
> 
> The SDM is unclear about when the TLB flush should occur, and whether or
> not a failed VM entry would flush the TLB, so it is safer to always
> do the TLB flush in this case.
> 
> More concretely, KVM also updates the last VPID L1 used for L2 in
> nested_vmx_transition_tlb_flush() (i.e. last_vpid), even if the VM entry
> ultimately fails. With the current code, KVM could miss a TLB flush if
> L1 changes L2's VPID, then does a failed VM entry followed by a
> successful one, as the failed VM entry would update last_vpid but not
> actually flush the TLB. Servicing local TLB flushes on failed VM entries
> makes sure that the TLB is always flushed when last_vpid is updated.
> 
> Fixes: 5c614b3583e7 ("KVM: nVMX: nested VPID emulation")
> Cc: stable@vger.kernel.org
> Reported-by: Sashiko <sashiko-bot@kernel.org> # Internal review
> Suggested-by: Sean Christopherson <seanjc@google.com>
> Signed-off-by: Yosry Ahmed <yosry@kernel.org>
> ---

For the record, my reproducer was basically the nested TLB flushes
selftest introduced here:
https://lore.kernel.org/kvm/20260728003557.1136583-29-yosry@kernel.org/

With this diff on top:

diff --git a/tools/testing/selftests/kvm/x86/nested_tlb_flush_test.c b/tools/testing/selftests/kvm/x86/nested_tlb_flush_test.c
index 55c9909bb085f..1659dd9c0044a 100644
--- a/tools/testing/selftests/kvm/x86/nested_tlb_flush_test.c
+++ b/tools/testing/selftests/kvm/x86/nested_tlb_flush_test.c
@@ -123,8 +123,26 @@ static void run_l2(void *nested_state, bool launch)
                vmx_tlb_flush(nested_state);
                if (launch)
                        GUEST_ASSERT(!vmlaunch());
-               else
-                       GUEST_ASSERT(!vmresume());
+               else {
+                       struct vmx_pages *vmx = nested_state;
+                       struct vmx_msr_entry *entry = vmx->msr;
+
+                       /* Inject VM-Entry failure via invalid MSR load */
+                       entry->index = 0xc0000100; /* MSR_FS_BASE, disallowed for loading */
+                       entry->reserved = 0;
+                       entry->value = 0;
+                       vmwrite(VM_ENTRY_MSR_LOAD_ADDR, vmx->msr_gpa);
+                       vmwrite(VM_ENTRY_MSR_LOAD_COUNT, 1);
+
+                       GUEST_ASSERT_EQ(vmresume(), 0);
+                       GUEST_ASSERT_EQ(vmreadz(VM_EXIT_REASON), (EXIT_REASON_FAILED_VMENTRY | EXIT_REASON_MSR_LOAD_FAIL));
+
+                       /* Fix failure and retry */
+                       vmwrite(VM_ENTRY_MSR_LOAD_COUNT, 0);
+                       memset(vmx->msr, 0, 4096);
+
+                       GUEST_ASSERT_EQ(vmresume(), 0);
+               }
                GUEST_ASSERT_EQ(vmreadz(VM_EXIT_REASON), EXIT_REASON_VMCALL);
                vmwrite(GUEST_RIP, vmreadz(GUEST_RIP) + 3); /* skip over VMCALL */
        } else {

      reply	other threads:[~2026-07-28  0:43 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-22 23:01 [PATCH v2] KVM: nVMX: Service local TLB flushes on failed nested VM-Enter Yosry Ahmed
2026-07-28  0:43 ` Yosry Ahmed [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=amf7CA4q33qoIx25@google.com \
    --to=yosry@kernel.org \
    --cc=jmattson@google.com \
    --cc=kvm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=pbonzini@redhat.com \
    --cc=sashiko-bot@kernel.org \
    --cc=seanjc@google.com \
    --cc=stable@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.