public inbox for kvm@vger.kernel.org
 help / color / mirror / Atom feed
From: Takahiro Itazuri <itazur@amazon.com>
To: <kvm@vger.kernel.org>, Sean Christopherson <seanjc@google.com>,
	"Paolo Bonzini" <pbonzini@redhat.com>
Cc: Vitaly Kuznetsov <vkuznets@redhat.com>,
	Fuad Tabba <tabba@google.com>,
	Brendan Jackman <jackmanb@google.com>,
	David Hildenbrand <david@kernel.org>,
	David Woodhouse <dwmw2@infradead.org>,
	Paul Durrant <pdurrant@amazon.com>,
	Nikita Kalyazin <nikita.kalyazin@linux.dev>,
	Patrick Roy <patrick.roy@campus.lmu.de>,
	Patrick Roy <patrick.roy@linux.dev>,
	"Derek Manwaring" <derekmn@amazon.com>,
	Alina Cernea <acernea@amazon.com>,
	"Michael Zoumboulakis" <zoumboul@amazon.com>,
	Takahiro Itazuri <zulinx86@gmail.com>,
	Takahiro Itazuri <itazur@amazon.com>
Subject: [RFC PATCH v4 7/7] KVM: selftests: Test pfncache invalidation for gmem-backed memory
Date: Mon, 20 Apr 2026 15:46:08 +0000	[thread overview]
Message-ID: <20260420154720.29012-8-itazur@amazon.com> (raw)
In-Reply-To: <20260420154720.29012-1-itazur@amazon.com>

Extend pfncache_gmem_test to verify pfncache invalidation paths:

 - punch_hole: fallocate(PUNCH_HOLE) on the pvclock page's guest_memfd
   frees the backing page and invalidates the pfncache.  The next
   vcpu_run re-resolves the PFN with a freshly allocated page.

 - file release: kvm_vm_free() closes the guest_memfd fd, triggering a
   full-range pfncache invalidation.

 - private-to-shared conversion: KVM_SET_MEMORY_ATTRIBUTES changes the
   pvclock page from private to shared, invalidating the pfncache.  The
   PFN is re-resolved via GUP instead of kvm_gmem_get_pfn().

Signed-off-by: Takahiro Itazuri <itazur@amazon.com>
---
 .../selftests/kvm/x86/pfncache_gmem_test.c    | 39 ++++++++++++++++---
 1 file changed, 34 insertions(+), 5 deletions(-)

diff --git a/tools/testing/selftests/kvm/x86/pfncache_gmem_test.c b/tools/testing/selftests/kvm/x86/pfncache_gmem_test.c
index c61b161f3e0c..a63940c36b15 100644
--- a/tools/testing/selftests/kvm/x86/pfncache_gmem_test.c
+++ b/tools/testing/selftests/kvm/x86/pfncache_gmem_test.c
@@ -36,11 +36,10 @@ static void guest_main(vm_paddr_t pvti_pa, struct pvclock_vcpu_time_info *pvti)
 {
 	int stage = 0;
 
-	wrmsr(MSR_KVM_SYSTEM_TIME_NEW, pvti_pa | KVM_MSR_ENABLED);
-
 	for (;;) {
 		uint64_t clock;
 
+		wrmsr(MSR_KVM_SYSTEM_TIME_NEW, pvti_pa | KVM_MSR_ENABLED);
 		GUEST_ASSERT(pvti->system_time != 0);
 		clock = __pvclock_read_cycles(pvti, rdtsc());
 		GUEST_SYNC_CLOCK(stage++, clock);
@@ -97,7 +96,8 @@ static uint64_t run_and_verify_kvm_clock(struct kvm_vcpu *vcpu,
 #define PVCLOCK_GPA		(1ULL << 32)
 
 static struct kvm_vm *setup_vm(struct vm_shape shape,
-			       struct kvm_vcpu **vcpu_out)
+			       struct kvm_vcpu **vcpu_out,
+			       vm_paddr_t *pvti_gpa_out)
 {
 	struct kvm_vm *vm;
 
@@ -118,6 +118,9 @@ static struct kvm_vm *setup_vm(struct vm_shape shape,
 		vcpu_args_set(*vcpu_out, 2, (vm_paddr_t)PVCLOCK_GPA,
 			      (struct pvclock_vcpu_time_info *)PVCLOCK_GPA);
 		vm_mem_set_private(vm, PVCLOCK_GPA, getpagesize());
+
+		if (pvti_gpa_out)
+			*pvti_gpa_out = PVCLOCK_GPA;
 	} else {
 		vm_vaddr_t pvti_gva;
 		vm_paddr_t pvti_gpa;
@@ -125,6 +128,9 @@ static struct kvm_vm *setup_vm(struct vm_shape shape,
 		pvti_gva = vm_vaddr_alloc(vm, getpagesize(), 0x10000);
 		pvti_gpa = addr_gva2gpa(vm, pvti_gva);
 		vcpu_args_set(*vcpu_out, 2, pvti_gpa, pvti_gva);
+
+		if (pvti_gpa_out)
+			*pvti_gpa_out = pvti_gpa;
 	}
 
 	return vm;
@@ -139,16 +145,27 @@ static void test_no_direct_map(void)
 	};
 	struct kvm_vcpu *vcpu;
 	struct kvm_vm *vm;
+	vm_paddr_t pvti_gpa;
 	uint64_t clock = 0;
 
 	pr_info("Testing pfncache with NO_DIRECT_MAP guest_memfd\n");
 
-	vm = setup_vm(shape, &vcpu);
+	vm = setup_vm(shape, &vcpu, &pvti_gpa);
 
 	/* Verify kvm-clock works with gmem-backed pfncache (vmap KHVA) */
 	clock = run_and_verify_kvm_clock(vcpu, clock);
 	clock = run_and_verify_kvm_clock(vcpu, clock);
 
+	/*
+	 * Punch a hole in the pvclock page's guest_memfd backing.  This
+	 * invalidates the pfncache; the next vcpu_run re-resolves the PFN
+	 * with a freshly allocated page.
+	 */
+	pr_info("  punch_hole on pvclock page\n");
+	vm_guest_mem_punch_hole(vm, pvti_gpa, getpagesize());
+	clock = run_and_verify_kvm_clock(vcpu, clock);
+
+	/* Smoke test: VM teardown (closing guest_memfd) doesn't crash. */
 	kvm_vm_free(vm);
 }
 
@@ -160,16 +177,28 @@ static void test_sw_protected_vm(void)
 	};
 	struct kvm_vcpu *vcpu;
 	struct kvm_vm *vm;
+	vm_paddr_t pvti_gpa;
 	uint64_t clock = 0;
 
 	pr_info("Testing pfncache with SW_PROTECTED_VM (guest_memfd-backed private memory)\n");
 
-	vm = setup_vm(shape, &vcpu);
+	vm = setup_vm(shape, &vcpu, &pvti_gpa);
 
 	/* Verify kvm-clock works with gmem-backed private memory */
 	clock = run_and_verify_kvm_clock(vcpu, clock);
 	clock = run_and_verify_kvm_clock(vcpu, clock);
 
+	/* Convert pvclock page from private to shared */
+	pr_info("  converting pvclock page: private -> shared\n");
+	vm_mem_set_shared(vm, pvti_gpa, getpagesize());
+	clock = run_and_verify_kvm_clock(vcpu, 0);
+
+	/* Convert back to private */
+	pr_info("  converting pvclock page: shared -> private\n");
+	vm_mem_set_private(vm, pvti_gpa, getpagesize());
+	clock = run_and_verify_kvm_clock(vcpu, 0);
+
+	/* Smoke test: VM teardown (closing guest_memfd) doesn't crash. */
 	kvm_vm_free(vm);
 }
 
-- 
2.50.1


      parent reply	other threads:[~2026-04-20 15:48 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-04-20 15:46 [RFC PATCH v4 0/7] KVM: pfncache: Add guest_memfd support to pfncache Takahiro Itazuri
2026-04-20 15:46 ` [RFC PATCH v4 1/7] KVM: pfncache: Resolve PFNs via kvm_gmem_get_pfn() for gmem-backed GPAs Takahiro Itazuri
2026-04-20 15:46 ` [RFC PATCH v4 2/7] KVM: pfncache: Obtain KHVA via vmap() for gmem with NO_DIRECT_MAP Takahiro Itazuri
2026-04-20 15:46 ` [RFC PATCH v4 3/7] KVM: Rename invalidate_begin to invalidate_start for consistency Takahiro Itazuri
2026-04-20 15:46 ` [RFC PATCH v4 4/7] KVM: pfncache: Rename invalidate_start() helper Takahiro Itazuri
2026-04-20 15:46 ` [RFC PATCH v4 5/7] KVM: pfncache: Invalidate on gmem invalidation and memattr updates Takahiro Itazuri
2026-04-20 15:46 ` [RFC PATCH v4 6/7] KVM: selftests: Test pfncache with gmem-backed memory Takahiro Itazuri
2026-04-20 15:46 ` Takahiro Itazuri [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=20260420154720.29012-8-itazur@amazon.com \
    --to=itazur@amazon.com \
    --cc=acernea@amazon.com \
    --cc=david@kernel.org \
    --cc=derekmn@amazon.com \
    --cc=dwmw2@infradead.org \
    --cc=jackmanb@google.com \
    --cc=kvm@vger.kernel.org \
    --cc=nikita.kalyazin@linux.dev \
    --cc=patrick.roy@campus.lmu.de \
    --cc=patrick.roy@linux.dev \
    --cc=pbonzini@redhat.com \
    --cc=pdurrant@amazon.com \
    --cc=seanjc@google.com \
    --cc=tabba@google.com \
    --cc=vkuznets@redhat.com \
    --cc=zoumboul@amazon.com \
    --cc=zulinx86@gmail.com \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox