All of lore.kernel.org
 help / color / mirror / Atom feed
From: Sean Christopherson <seanjc@google.com>
To: Jim Mattson <jmattson@google.com>
Cc: James Houghton <jthoughton@google.com>,
	Paolo Bonzini <pbonzini@redhat.com>,
	kvm@vger.kernel.org,  Yosry Ahmed <yosry@kernel.org>
Subject: Re: [PATCH] KVM: selftests: Add test for shadow VMCS flush during vCPU teardown
Date: Thu, 1 Oct 2026 13:13:59 -0700	[thread overview]
Message-ID: <ar6_B0Cj831UB-wh@google.com> (raw)
In-Reply-To: <20260911191011.528460-1-jmattson@google.com>

On Fri, Sep 11, 2026, Jim Mattson wrote:
> As requested, a half-baked selftest. :)
> 
> I dropped stable from the cc list.
> 
> When a vCPU is destroyed while L2 is active and VMCS shadowing is
> enabled, KVM synthesizes a nested VM-Exit. This flushes the cached
> shadow VMCS12 back to guest memory. However, on process exit, do_exit()
> calls exit_mm() before closing file descriptors. KVM teardown runs
> with current->mm == NULL on a borrowed lazy TLB active_mm.
> Consequently, nested_flush_cached_shadow_vmcs12() writes the shadow
> VMCS12 into whatever address space is active on that CPU.
> 
> Add a selftest to verify this behavior. The test runs a victim process
> and a nested VMM process on the same physical CPU. The victim process
> maps a page and fills it with canary bytes. The VMM sets up an L2 guest
> with VMCS shadowing mapped at the identical host virtual address using
> MAP_FIXED_NOREPLACE. When the VMM exits with open file descriptors, the
> victim yields the CPU while the VMM terminates. This scheduling
> heuristic attempts to hit the race window where VMM teardown runs under
> the victim's active_mm and flushes the shadow VMCS into the victim's
> address space.
> 
> ---

FWIW, diff to get this working on the current kvm-x86/next.  I hacked it to use
VA=0x1000 for the "bad" mapping as the address picked by the kernel for the victim
was colliding with an existing allocation in the VMM (I didn't bother trying to
figure out where the allocation came from, didn't seem interesting).

diff --git a/tools/testing/selftests/kvm/x86/vmx_shadow_vmcs_teardown_test.c b/tools/testing/selftests/kvm/x86/vmx_shadow_vmcs_teardown_test.c
index e0863ef20d3e..fbaba40ceefa 100644
--- a/tools/testing/selftests/kvm/x86/vmx_shadow_vmcs_teardown_test.c
+++ b/tools/testing/selftests/kvm/x86/vmx_shadow_vmcs_teardown_test.c
@@ -45,18 +45,15 @@ static void l2_guest_code(void)
 
 static void l1_guest_code(struct vmx_pages *vmx_pages)
 {
-	unsigned long l2_guest_stack[L2_GUEST_STACK_SIZE];
-
-	GUEST_ASSERT(prepare_for_vmx_operation(vmx_pages));
-	GUEST_ASSERT(load_vmcs(vmx_pages));
+	prepare_for_vmx_operation(vmx_pages);
+	load_vmcs(vmx_pages);
 
 	/* Prepare the VMCS for L2 execution. */
-	prepare_vmcs(vmx_pages, l2_guest_code,
-		     &l2_guest_stack[L2_GUEST_STACK_SIZE]);
+	prepare_vmcs(vmx_pages, l2_guest_code);
 
 	/* Enable VMCS shadowing and set the shadow VMCS link pointer. */
 	vmwrite(SECONDARY_VM_EXEC_CONTROL,
-		vmreadz(SECONDARY_VM_EXEC_CONTROL) | SECONDARY_EXEC_SHADOW_VMCS);
+		vmread(SECONDARY_VM_EXEC_CONTROL) | SECONDARY_EXEC_SHADOW_VMCS);
 	vmwrite(VMCS_LINK_POINTER, vmx_pages->shadow_vmcs_gpa);
 
 	vmlaunch();
@@ -77,10 +74,10 @@ static bool kvm_cpu_has_shadow_vmcs(void)
 
 static void run_vmm(int pcpu, void *target_hva, int c2_to_c1_fd)
 {
-	vm_vaddr_t vmx_pages_gva;
 	struct kvm_vcpu *vcpu;
 	struct kvm_vm *vm;
 	struct vmx_pages *vmx;
+	gva_t vmx_pages_gva;
 	void *shadow_hva;
 
 	pin_self_to_cpu(pcpu);
@@ -97,12 +94,11 @@ static void run_vmm(int pcpu, void *target_hva, int c2_to_c1_fd)
 	 */
 	shadow_hva = mmap(target_hva, PAGE_SIZE, PROT_READ | PROT_WRITE,
 			  MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED_NOREPLACE, -1, 0);
-	TEST_ASSERT(shadow_hva == target_hva, "mmap target_hva failed in VMM");
+	TEST_ASSERT_EQ(shadow_hva, target_hva);
 	memset(shadow_hva, 0, PAGE_SIZE);
 
 	/* Add a caller-managed memslot for the shadow VMCS backing page. */
-	vm_userspace_mem_region_add_caller_managed(vm, shadow_hva,
-						   SHADOW_VMCS_GPA, 10, 1, 0);
+	vm_set_user_memory_region2(vm, 10, 0, SHADOW_VMCS_GPA, PAGE_SIZE, shadow_hva, -1, 0);
 	virt_pg_map(vm, SHADOW_VMCS_GVA, SHADOW_VMCS_GPA);
 
 	/* Override the shadow VMCS pointers in vmx_pages. */
@@ -156,7 +152,7 @@ static void run_victim(int pcpu, int ready_fd, int c2_to_c1_fd,
 
 	pin_self_to_cpu(pcpu);
 
-	victim_hva = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE,
+	victim_hva = mmap((void *)0x1000ul, PAGE_SIZE, PROT_READ | PROT_WRITE,
 			  MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
 	TEST_ASSERT(victim_hva != MAP_FAILED, "mmap failed in victim");
 	memset(victim_hva, CANARY_BYTE, PAGE_SIZE);

      parent reply	other threads:[~2026-10-01 20:14 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-08 13:28 [PATCH] KVM: nVMX: Don't flush shadow VMCS12 to guest memory during vCPU teardown Jim Mattson
2026-09-08 13:57 ` sashiko-bot
2026-09-08 17:34 ` James Houghton
2026-09-08 19:12   ` Jim Mattson
2026-09-09 15:41     ` James Houghton
2026-09-09 19:00     ` Sean Christopherson
2026-09-10 18:58       ` James Houghton
2026-09-10 19:14         ` Sean Christopherson
2026-09-10 19:32           ` Sean Christopherson
2026-09-10 19:40           ` Sean Christopherson
2026-09-11 17:39       ` Jim Mattson
2026-09-11 18:10         ` Sean Christopherson
2026-09-11 19:10           ` [PATCH] KVM: selftests: Add test for shadow VMCS flush " Jim Mattson
2026-09-11 19:25             ` sashiko-bot
2026-10-01 20:13             ` Sean Christopherson [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=ar6_B0Cj831UB-wh@google.com \
    --to=seanjc@google.com \
    --cc=jmattson@google.com \
    --cc=jthoughton@google.com \
    --cc=kvm@vger.kernel.org \
    --cc=pbonzini@redhat.com \
    --cc=yosry@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.