[PATCH 10/12] KVM: selftests: Move EPT-specific init outside nested_create_pte()

Yosry Ahmed posted 12 patches 4 months, 1 week ago
There is a newer version of this series
[PATCH 10/12] KVM: selftests: Move EPT-specific init outside nested_create_pte()
Posted by Yosry Ahmed 4 months, 1 week ago
From: Yosry Ahmed <yosryahmed@google.com>

Refactor the EPT specific initialization into nested_ept_create_pte(),
in preparation for making nested_create_pte() NPT-friendly.

Signed-off-by: Yosry Ahmed <yosry.ahmed@linux.dev>
---
 tools/testing/selftests/kvm/lib/x86/vmx.c | 71 ++++++++++++++---------
 1 file changed, 43 insertions(+), 28 deletions(-)

diff --git a/tools/testing/selftests/kvm/lib/x86/vmx.c b/tools/testing/selftests/kvm/lib/x86/vmx.c
index b0e6267eac806..eeacf42bf30b1 100644
--- a/tools/testing/selftests/kvm/lib/x86/vmx.c
+++ b/tools/testing/selftests/kvm/lib/x86/vmx.c
@@ -365,46 +365,61 @@ void prepare_vmcs(struct vmx_pages *vmx, void *guest_rip, void *guest_rsp)
 	init_vmcs_guest_state(guest_rip, guest_rsp);
 }
 
+static bool nested_ept_create_pte(struct kvm_vm *vm,
+				  uint64_t *pte,
+				  uint64_t paddr,
+				  uint64_t *address,
+				  bool *leaf)
+{
+	struct eptPageTableEntry *epte = (struct eptPageTableEntry *)pte;
+
+	/* PTE already exists? */
+	if (epte->readable) {
+		*leaf = epte->page_size;
+		*address = epte->address;
+		return false;
+	}
+
+	epte->writable = true;
+	epte->readable = true;
+	epte->executable = true;
+	epte->page_size = *leaf;
+
+	if (*leaf)
+		epte->address = paddr >> vm->page_shift;
+	else
+		epte->address = vm_alloc_page_table(vm) >> vm->page_shift;
+
+	*address = epte->address;
+
+	/*
+	 * For now mark these as accessed and dirty because the only
+	 * testcase we have needs that.  Can be reconsidered later.
+	 */
+	epte->accessed = *leaf;
+	epte->dirty = *leaf;
+	return true;
+}
+
 static uint64_t nested_create_pte(struct kvm_vm *vm,
 				  uint64_t *pte,
 				  uint64_t nested_paddr,
 				  uint64_t paddr,
 				  int level,
-				  bool leaf)
+				  bool want_leaf)
 {
-	struct eptPageTableEntry *epte = (struct eptPageTableEntry *)pte;
-
-	if (!epte->readable) {
-		epte->writable = true;
-		epte->readable = true;
-		epte->executable = true;
-		epte->page_size = leaf;
+	bool leaf = want_leaf;
+	uint64_t address;
 
-		if (leaf)
-			epte->address = paddr >> vm->page_shift;
-		else
-			epte->address = vm_alloc_page_table(vm) >> vm->page_shift;
-
-		/*
-		 * For now mark these as accessed and dirty because the only
-		 * testcase we have needs that.  Can be reconsidered later.
-		 */
-		epte->accessed = leaf;
-		epte->dirty = leaf;
-	} else {
-		/*
-		 * Entry already present.  Assert that the caller doesn't want a
-		 * leaf entry at this level, and that there isn't a leaf entry
-		 * at this level.
-		 */
-		TEST_ASSERT(!leaf,
+	if (!nested_ept_create_pte(vm, pte, paddr, &address, &leaf)) {
+		TEST_ASSERT(!want_leaf,
 			    "Cannot create leaf entry at level: %u, nested_paddr: 0x%lx",
 			    level, nested_paddr);
-		TEST_ASSERT(!epte->page_size,
+		TEST_ASSERT(!leaf,
 			    "Leaf entry already exists at level: %u, nested_paddr: 0x%lx",
 			    level, nested_paddr);
 	}
-	return epte->address;
+	return address;
 }
 
 
-- 
2.51.0.618.g983fd99d29-goog
Re: [PATCH 10/12] KVM: selftests: Move EPT-specific init outside nested_create_pte()
Posted by Jim Mattson 3 months, 3 weeks ago
On Wed, Oct 1, 2025 at 8:06 AM Yosry Ahmed <yosry.ahmed@linux.dev> wrote:
>
> From: Yosry Ahmed <yosryahmed@google.com>
>
> Refactor the EPT specific initialization into nested_ept_create_pte(),
> in preparation for making nested_create_pte() NPT-friendly.
>
> Signed-off-by: Yosry Ahmed <yosry.ahmed@linux.dev>
> ---
>  tools/testing/selftests/kvm/lib/x86/vmx.c | 71 ++++++++++++++---------
>  1 file changed, 43 insertions(+), 28 deletions(-)
>
> ...
> +
> +       /*
> +        * For now mark these as accessed and dirty because the only
> +        * testcase we have needs that.  Can be reconsidered later.
> +        */
> +       epte->accessed = *leaf;
> +       epte->dirty = *leaf;

Not your change, but it seems strange to set the 'accessed' bit only
at the leaf. The CPU will set the 'accessed' bits from the PGD down as
it does the walk. So, to only have an accessed bit set on the leaf
requires the existence of some software agent to clear the higher
levels.

Reviewed-by: Jim Mattson <jmattson@google.com>