public inbox for kvm@vger.kernel.org
 help / color / mirror / Atom feed
From: Jon Kohler <jon@nutanix.com>
To: seanjc@google.com, pbonzini@redhat.com, kvm@vger.kernel.org
Cc: Jon Kohler <jon@nutanix.com>
Subject: [kvm-unit-tests PATCH 06/17] x86/vmx: switch to new vmx.h EPT violation defs
Date: Tue, 16 Sep 2025 10:22:35 -0700	[thread overview]
Message-ID: <20250916172247.610021-7-jon@nutanix.com> (raw)
In-Reply-To: <20250916172247.610021-1-jon@nutanix.com>

Migrate to new vmx.h's EPT violation defs, which makes it easier
to grok from one code base to another.

Fix a few small formatting issues along the way.

No functional change intended.

Signed-off-by: Jon Kohler <jon@nutanix.com>

---
 x86/vmx.h       |  11 -----
 x86/vmx_tests.c | 127 +++++++++++++++++++++++++++++-------------------
 2 files changed, 77 insertions(+), 61 deletions(-)

diff --git a/x86/vmx.h b/x86/vmx.h
index 41346252..9b076b0c 100644
--- a/x86/vmx.h
+++ b/x86/vmx.h
@@ -618,17 +618,6 @@ enum Intr_type {
 #define EPT_ADDR_MASK		GENMASK_ULL(51, 12)
 #define PAGE_MASK_2M		(~(PAGE_SIZE_2M-1))
 
-#define EPT_VLT_RD		(1ull << 0)
-#define EPT_VLT_WR		(1ull << 1)
-#define EPT_VLT_FETCH		(1ull << 2)
-#define EPT_VLT_PERM_RD		(1ull << 3)
-#define EPT_VLT_PERM_WR		(1ull << 4)
-#define EPT_VLT_PERM_EX		(1ull << 5)
-#define EPT_VLT_PERM_USER_EX	(1ull << 6)
-#define EPT_VLT_PERMS		(EPT_VLT_PERM_RD | EPT_VLT_PERM_WR | \
-				 EPT_VLT_PERM_EX)
-#define EPT_VLT_LADDR_VLD	(1ull << 7)
-#define EPT_VLT_PADDR		(1ull << 8)
 #define EPT_VLT_GUEST_USER	(1ull << 9)
 #define EPT_VLT_GUEST_RW	(1ull << 10)
 #define EPT_VLT_GUEST_EX	(1ull << 11)
diff --git a/x86/vmx_tests.c b/x86/vmx_tests.c
index dbcb6cae..a09b687f 100644
--- a/x86/vmx_tests.c
+++ b/x86/vmx_tests.c
@@ -1443,8 +1443,9 @@ static int ept_exit_handler_common(union exit_reason exit_reason, bool have_ad)
 			check_ept_ad(pml4, guest_cr3, (unsigned long)data_page1, 0,
 				     have_ad ? EPT_ACCESS_FLAG | EPT_DIRTY_FLAG : 0);
 			clear_ept_ad(pml4, guest_cr3, (unsigned long)data_page1);
-			if (exit_qual == (EPT_VLT_WR | EPT_VLT_LADDR_VLD |
-					EPT_VLT_PADDR))
+			if (exit_qual == (EPT_VIOLATION_ACC_WRITE |
+					  EPT_VIOLATION_GVA_IS_VALID |
+					  EPT_VIOLATION_GVA_TRANSLATED))
 				vmx_inc_test_stage();
 			set_ept_pte(pml4, (unsigned long)data_page1,
 				1, data_page1_pte | (EPT_PRESENT));
@@ -1454,16 +1455,16 @@ static int ept_exit_handler_common(union exit_reason exit_reason, bool have_ad)
 			check_ept_ad(pml4, guest_cr3, (unsigned long)data_page1, 0,
 				     have_ad ? EPT_ACCESS_FLAG | EPT_DIRTY_FLAG : 0);
 			clear_ept_ad(pml4, guest_cr3, (unsigned long)data_page1);
-			if (exit_qual == (EPT_VLT_RD |
-					  (have_ad ? EPT_VLT_WR : 0) |
-					  EPT_VLT_LADDR_VLD))
+			if (exit_qual == (EPT_VIOLATION_ACC_READ |
+					  (have_ad ? EPT_VIOLATION_ACC_WRITE : 0) |
+					   EPT_VIOLATION_GVA_IS_VALID))
 				vmx_inc_test_stage();
 			set_ept_pte(pml4, guest_pte_addr, 2,
 				data_page1_pte_pte | (EPT_PRESENT));
 			invept(INVEPT_SINGLE, eptp);
 			break;
 		case 5:
-			if (exit_qual & EPT_VLT_RD)
+			if (exit_qual & EPT_VIOLATION_ACC_READ)
 				vmx_inc_test_stage();
 			TEST_ASSERT(get_ept_pte(pml4, (unsigned long)pci_physaddr,
 						1, &memaddr_pte));
@@ -1471,7 +1472,7 @@ static int ept_exit_handler_common(union exit_reason exit_reason, bool have_ad)
 			invept(INVEPT_SINGLE, eptp);
 			break;
 		case 6:
-			if (exit_qual & EPT_VLT_WR)
+			if (exit_qual & EPT_VIOLATION_ACC_WRITE)
 				vmx_inc_test_stage();
 			TEST_ASSERT(get_ept_pte(pml4, (unsigned long)pci_physaddr,
 						1, &memaddr_pte));
@@ -2283,14 +2284,14 @@ do {									\
 		       (expected & flag) ? "" : "un");			\
 } while (0)
 
-	DIAGNOSE(EPT_VLT_RD);
-	DIAGNOSE(EPT_VLT_WR);
-	DIAGNOSE(EPT_VLT_FETCH);
-	DIAGNOSE(EPT_VLT_PERM_RD);
-	DIAGNOSE(EPT_VLT_PERM_WR);
-	DIAGNOSE(EPT_VLT_PERM_EX);
-	DIAGNOSE(EPT_VLT_LADDR_VLD);
-	DIAGNOSE(EPT_VLT_PADDR);
+	DIAGNOSE(EPT_VIOLATION_ACC_READ);
+	DIAGNOSE(EPT_VIOLATION_ACC_WRITE);
+	DIAGNOSE(EPT_VIOLATION_ACC_INSTR);
+	DIAGNOSE(EPT_VIOLATION_PROT_READ);
+	DIAGNOSE(EPT_VIOLATION_PROT_WRITE);
+	DIAGNOSE(EPT_VIOLATION_PROT_EXEC);
+	DIAGNOSE(EPT_VIOLATION_GVA_IS_VALID);
+	DIAGNOSE(EPT_VIOLATION_GVA_TRANSLATED);
 
 #undef DIAGNOSE
 }
@@ -2357,7 +2358,7 @@ static void do_ept_violation(bool leaf, enum ept_access_op op,
 
 	/* Mask undefined bits (which may later be defined in certain cases). */
 	qual &= ~(EPT_VLT_GUEST_USER | EPT_VLT_GUEST_RW | EPT_VLT_GUEST_EX |
-		 EPT_VLT_PERM_USER_EX);
+		  EPT_VIOLATION_EXEC_FOR_RING3_LIN);
 
 	diagnose_ept_violation_qual(expected_qual, qual);
 	TEST_EXPECT_EQ(expected_qual, qual);
@@ -2419,18 +2420,20 @@ static void ept_access_violation(unsigned long access, enum ept_access_op op,
 				       u64 expected_qual)
 {
 	ept_violation(EPT_PRESENT, access, op,
-		      expected_qual | EPT_VLT_LADDR_VLD | EPT_VLT_PADDR);
+		      expected_qual | EPT_VIOLATION_GVA_IS_VALID |
+		      EPT_VIOLATION_GVA_TRANSLATED);
 }
 
 /*
  * For translations that don't involve a GVA, that is physical address (paddr)
- * accesses, EPT violations don't set the flag EPT_VLT_PADDR.  For a typical
- * guest memory access, the hardware does GVA -> GPA -> HPA.  However, certain
- * translations don't involve GVAs, such as when the hardware does the guest
- * page table walk. For example, in translating GVA_1 -> GPA_1, the guest MMU
- * might try to set an A bit on a guest PTE. If the GPA_2 that the PTE resides
- * on isn't present in the EPT, then the EPT violation will be for GPA_2 and
- * the EPT_VLT_PADDR bit will be clear in the exit qualification.
+ * accesses, EPT violations don't set the flag EPT_VIOLATION_GVA_TRANSLATED.
+ * For a typical guest memory access, the hardware does GVA -> GPA -> HPA.
+ * However, certain translations don't involve GVAs, such as when the hardware
+ * does the guest page table walk. For example, in translating GVA_1 -> GPA_1,
+ * the guest MMU might try to set an A bit on a guest PTE. If the GPA_2 that
+ * the PTE resides on isn't present in the EPT, then the EPT violation will be
+ * for GPA_2 and the EPT_VIOLATION_GVA_TRANSLATED bit will be clear in the exit
+ * qualification.
  *
  * Note that paddr violations can also be triggered by loading PAE page tables
  * with wonky addresses. We don't test that yet.
@@ -2449,7 +2452,7 @@ static void ept_access_violation(unsigned long access, enum ept_access_op op,
  *			Is a violation expected during the paddr access?
  *
  *	@expected_qual	Expected qualification for the EPT violation.
- *			EPT_VLT_PADDR should be clear.
+ *			EPT_VIOLATION_GVA_TRANSLATED should be clear.
  */
 static void ept_access_paddr(unsigned long ept_access, unsigned long pte_ad,
 			     enum ept_access_op op, bool expect_violation,
@@ -2492,7 +2495,7 @@ static void ept_access_paddr(unsigned long ept_access, unsigned long pte_ad,
 
 	if (expect_violation) {
 		do_ept_violation(/*leaf=*/true, op,
-				 expected_qual | EPT_VLT_LADDR_VLD, gpa);
+				 expected_qual | EPT_VIOLATION_GVA_IS_VALID, gpa);
 		ept_untwiddle(gpa, /*level=*/1, orig_epte);
 		do_ept_access_op(op);
 	} else {
@@ -2611,9 +2614,10 @@ static void ept_misconfig_at_level_mkhuge_op(bool mkhuge, int level,
 	/*
 	 * broken:
 	 * According to description of exit qual for EPT violation,
-	 * EPT_VLT_LADDR_VLD indicates if GUEST_LINEAR_ADDRESS is valid.
+	 * EPT_VIOLATION_GVA_IS_VALID indicates if GUEST_LINEAR_ADDRESS is
+	 * valid.
 	 * However, I can't find anything that says GUEST_LINEAR_ADDRESS ought
-	 * to be set for msiconfig.
+	 * to be set for misconfig.
 	 */
 	TEST_EXPECT_EQ(vmcs_read(GUEST_LINEAR_ADDRESS),
 		       (unsigned long) (
@@ -2664,7 +2668,9 @@ static void ept_reserved_bit_at_level_nohuge(int level, int bit)
 
 	/* Making the entry non-present turns reserved bits into ignored. */
 	ept_violation_at_level(level, EPT_PRESENT, 1ul << bit, OP_READ,
-			       EPT_VLT_RD | EPT_VLT_LADDR_VLD | EPT_VLT_PADDR);
+			       EPT_VIOLATION_ACC_READ |
+			       EPT_VIOLATION_GVA_IS_VALID |
+			       EPT_VIOLATION_GVA_TRANSLATED);
 }
 
 static void ept_reserved_bit_at_level_huge(int level, int bit)
@@ -2674,7 +2680,9 @@ static void ept_reserved_bit_at_level_huge(int level, int bit)
 
 	/* Making the entry non-present turns reserved bits into ignored. */
 	ept_violation_at_level(level, EPT_PRESENT, 1ul << bit, OP_READ,
-			       EPT_VLT_RD | EPT_VLT_LADDR_VLD | EPT_VLT_PADDR);
+			       EPT_VIOLATION_ACC_READ |
+			       EPT_VIOLATION_GVA_IS_VALID |
+			       EPT_VIOLATION_GVA_TRANSLATED);
 }
 
 static void ept_reserved_bit_at_level(int level, int bit)
@@ -2684,7 +2692,9 @@ static void ept_reserved_bit_at_level(int level, int bit)
 
 	/* Making the entry non-present turns reserved bits into ignored. */
 	ept_violation_at_level(level, EPT_PRESENT, 1ul << bit, OP_READ,
-			       EPT_VLT_RD | EPT_VLT_LADDR_VLD | EPT_VLT_PADDR);
+			       EPT_VIOLATION_ACC_READ |
+			       EPT_VIOLATION_GVA_IS_VALID |
+			       EPT_VIOLATION_GVA_TRANSLATED);
 }
 
 static void ept_reserved_bit(int bit)
@@ -2787,9 +2797,9 @@ static void ept_access_test_not_present(void)
 {
 	ept_access_test_setup();
 	/* --- */
-	ept_access_violation(0, OP_READ, EPT_VLT_RD);
-	ept_access_violation(0, OP_WRITE, EPT_VLT_WR);
-	ept_access_violation(0, OP_EXEC, EPT_VLT_FETCH);
+	ept_access_violation(0, OP_READ, EPT_VIOLATION_ACC_READ);
+	ept_access_violation(0, OP_WRITE, EPT_VIOLATION_ACC_WRITE);
+	ept_access_violation(0, OP_EXEC, EPT_VIOLATION_ACC_INSTR);
 }
 
 static void ept_access_test_read_only(void)
@@ -2798,8 +2808,10 @@ static void ept_access_test_read_only(void)
 
 	/* r-- */
 	ept_access_allowed(EPT_RA, OP_READ);
-	ept_access_violation(EPT_RA, OP_WRITE, EPT_VLT_WR | EPT_VLT_PERM_RD);
-	ept_access_violation(EPT_RA, OP_EXEC, EPT_VLT_FETCH | EPT_VLT_PERM_RD);
+	ept_access_violation(EPT_RA, OP_WRITE, EPT_VIOLATION_ACC_WRITE |
+			     EPT_VIOLATION_PROT_READ);
+	ept_access_violation(EPT_RA, OP_EXEC, EPT_VIOLATION_ACC_INSTR |
+			     EPT_VIOLATION_PROT_READ);
 }
 
 static void ept_access_test_write_only(void)
@@ -2816,7 +2828,9 @@ static void ept_access_test_read_write(void)
 	ept_access_allowed(EPT_RA | EPT_WA, OP_READ);
 	ept_access_allowed(EPT_RA | EPT_WA, OP_WRITE);
 	ept_access_violation(EPT_RA | EPT_WA, OP_EXEC,
-			   EPT_VLT_FETCH | EPT_VLT_PERM_RD | EPT_VLT_PERM_WR);
+			     EPT_VIOLATION_ACC_INSTR |
+			     EPT_VIOLATION_PROT_READ |
+			     EPT_VIOLATION_PROT_WRITE);
 }
 
 
@@ -2826,9 +2840,11 @@ static void ept_access_test_execute_only(void)
 	/* --x */
 	if (ept_execute_only_supported()) {
 		ept_access_violation(EPT_EA, OP_READ,
-				     EPT_VLT_RD | EPT_VLT_PERM_EX);
+				     EPT_VIOLATION_ACC_READ |
+				     EPT_VIOLATION_PROT_EXEC);
 		ept_access_violation(EPT_EA, OP_WRITE,
-				     EPT_VLT_WR | EPT_VLT_PERM_EX);
+				     EPT_VIOLATION_ACC_WRITE |
+				     EPT_VIOLATION_PROT_EXEC);
 		ept_access_allowed(EPT_EA, OP_EXEC);
 	} else {
 		ept_access_misconfig(EPT_EA);
@@ -2841,7 +2857,9 @@ static void ept_access_test_read_execute(void)
 	/* r-x */
 	ept_access_allowed(EPT_RA | EPT_EA, OP_READ);
 	ept_access_violation(EPT_RA | EPT_EA, OP_WRITE,
-			   EPT_VLT_WR | EPT_VLT_PERM_RD | EPT_VLT_PERM_EX);
+			     EPT_VIOLATION_ACC_WRITE |
+			     EPT_VIOLATION_PROT_READ |
+			     EPT_VIOLATION_PROT_EXEC);
 	ept_access_allowed(EPT_RA | EPT_EA, OP_EXEC);
 }
 
@@ -2936,14 +2954,17 @@ static void ept_access_test_paddr_not_present_ad_disabled(void)
 	ept_access_test_setup();
 	ept_disable_ad_bits();
 
-	ept_access_violation_paddr(0, PT_AD_MASK, OP_READ, EPT_VLT_RD);
-	ept_access_violation_paddr(0, PT_AD_MASK, OP_WRITE, EPT_VLT_RD);
-	ept_access_violation_paddr(0, PT_AD_MASK, OP_EXEC, EPT_VLT_RD);
+	ept_access_violation_paddr(0, PT_AD_MASK, OP_READ,
+				   EPT_VIOLATION_ACC_READ);
+	ept_access_violation_paddr(0, PT_AD_MASK, OP_WRITE,
+				   EPT_VIOLATION_ACC_READ);
+	ept_access_violation_paddr(0, PT_AD_MASK, OP_EXEC,
+				   EPT_VIOLATION_ACC_READ);
 }
 
 static void ept_access_test_paddr_not_present_ad_enabled(void)
 {
-	u64 qual = EPT_VLT_RD | EPT_VLT_WR;
+	u64 qual = EPT_VIOLATION_ACC_READ | EPT_VIOLATION_ACC_WRITE;
 
 	ept_access_test_setup();
 	ept_enable_ad_bits_or_skip_test();
@@ -2961,7 +2982,8 @@ static void ept_access_test_paddr_read_only_ad_disabled(void)
 	 * translation of the GPA to host physical address) a read+write
 	 * if the A/D bits have to be set.
 	 */
-	u64 qual = EPT_VLT_WR | EPT_VLT_RD | EPT_VLT_PERM_RD;
+	u64 qual = EPT_VIOLATION_ACC_WRITE | EPT_VIOLATION_ACC_READ |
+		   EPT_VIOLATION_PROT_READ;
 
 	ept_access_test_setup();
 	ept_disable_ad_bits();
@@ -2987,7 +3009,8 @@ static void ept_access_test_paddr_read_only_ad_enabled(void)
 	 * structures are considered writes as far as EPT translation
 	 * is concerned.
 	 */
-	u64 qual = EPT_VLT_WR | EPT_VLT_RD | EPT_VLT_PERM_RD;
+	u64 qual = EPT_VIOLATION_ACC_WRITE | EPT_VIOLATION_ACC_READ |
+		   EPT_VIOLATION_PROT_READ;
 
 	ept_access_test_setup();
 	ept_enable_ad_bits_or_skip_test();
@@ -3029,7 +3052,8 @@ static void ept_access_test_paddr_read_execute_ad_disabled(void)
 	 * translation of the GPA to host physical address) a read+write
 	 * if the A/D bits have to be set.
 	 */
-	u64 qual = EPT_VLT_WR | EPT_VLT_RD | EPT_VLT_PERM_RD | EPT_VLT_PERM_EX;
+	u64 qual = EPT_VIOLATION_ACC_WRITE | EPT_VIOLATION_ACC_READ |
+		   EPT_VIOLATION_PROT_READ | EPT_VIOLATION_PROT_EXEC;
 
 	ept_access_test_setup();
 	ept_disable_ad_bits();
@@ -3055,7 +3079,8 @@ static void ept_access_test_paddr_read_execute_ad_enabled(void)
 	 * structures are considered writes as far as EPT translation
 	 * is concerned.
 	 */
-	u64 qual = EPT_VLT_WR | EPT_VLT_RD | EPT_VLT_PERM_RD | EPT_VLT_PERM_EX;
+	u64 qual = EPT_VIOLATION_ACC_WRITE | EPT_VIOLATION_ACC_READ |
+		   EPT_VIOLATION_PROT_READ | EPT_VIOLATION_PROT_EXEC;
 
 	ept_access_test_setup();
 	ept_enable_ad_bits_or_skip_test();
@@ -3089,8 +3114,10 @@ static void ept_access_test_force_2m_page(void)
 	TEST_ASSERT_EQ(ept_2m_supported(), true);
 	ept_allowed_at_level_mkhuge(true, 2, 0, 0, OP_READ);
 	ept_violation_at_level_mkhuge(true, 2, EPT_PRESENT, EPT_RA, OP_WRITE,
-				      EPT_VLT_WR | EPT_VLT_PERM_RD |
-				      EPT_VLT_LADDR_VLD | EPT_VLT_PADDR);
+				      EPT_VIOLATION_ACC_WRITE |
+				      EPT_VIOLATION_PROT_READ |
+				      EPT_VIOLATION_GVA_IS_VALID |
+				      EPT_VIOLATION_GVA_TRANSLATED);
 	ept_misconfig_at_level_mkhuge(true, 2, EPT_PRESENT, EPT_WA);
 }
 
-- 
2.43.0


  parent reply	other threads:[~2025-09-16 16:44 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-09-16 17:22 [kvm-unit-tests PATCH 00/17] x86/vmx: align with Linux kernel VMX definitions Jon Kohler
2025-09-16 17:22 ` [kvm-unit-tests PATCH 01/17] lib: add linux vmx.h clone from 6.16 Jon Kohler
2025-09-16 17:22 ` [kvm-unit-tests PATCH 02/17] lib: add linux trapnr.h " Jon Kohler
2025-09-16 17:22 ` [kvm-unit-tests PATCH 03/17] lib: add vmxfeatures.h " Jon Kohler
2025-09-16 17:22 ` [kvm-unit-tests PATCH 04/17] lib: define __aligned() in compiler.h Jon Kohler
2025-09-16 17:22 ` [kvm-unit-tests PATCH 05/17] x86/vmx: basic integration for new vmx.h Jon Kohler
2025-09-16 17:22 ` Jon Kohler [this message]
2025-09-16 17:22 ` [kvm-unit-tests PATCH 07/17] x86/vmx: switch to new vmx.h EPT RWX defs Jon Kohler
2025-09-16 17:22 ` [kvm-unit-tests PATCH 08/17] x86/vmx: switch to new vmx.h EPT access and dirty defs Jon Kohler
2025-09-16 17:22 ` [kvm-unit-tests PATCH 09/17] x86/vmx: switch to new vmx.h EPT capability and memory type defs Jon Kohler
2025-09-16 17:22 ` [kvm-unit-tests PATCH 10/17] x86/vmx: switch to new vmx.h primary processor-based VM-execution controls Jon Kohler
2025-09-16 17:22 ` [kvm-unit-tests PATCH 11/17] x86/vmx: switch to new vmx.h secondary execution control bit Jon Kohler
2025-09-16 17:22 ` [kvm-unit-tests PATCH 12/17] x86/vmx: switch to new vmx.h secondary execution controls Jon Kohler
2025-09-16 17:22 ` [kvm-unit-tests PATCH 13/17] x86/vmx: switch to new vmx.h pin based VM-execution controls Jon Kohler
2025-09-16 17:22 ` [kvm-unit-tests PATCH 14/17] x86/vmx: switch to new vmx.h exit controls Jon Kohler
2025-09-16 17:22 ` [kvm-unit-tests PATCH 15/17] x86/vmx: switch to new vmx.h entry controls Jon Kohler
2025-09-16 17:22 ` [kvm-unit-tests PATCH 16/17] x86/vmx: switch to new vmx.h interrupt defs Jon Kohler
2025-09-16 17:22 ` [kvm-unit-tests PATCH 17/17] x86/vmx: align exit reasons with Linux uapi Jon Kohler
2025-11-12 19:02 ` [kvm-unit-tests PATCH 00/17] x86/vmx: align with Linux kernel VMX definitions Sean Christopherson
2025-11-14 14:52   ` Jon Kohler
2025-11-17 17:41     ` Sean Christopherson

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=20250916172247.610021-7-jon@nutanix.com \
    --to=jon@nutanix.com \
    --cc=kvm@vger.kernel.org \
    --cc=pbonzini@redhat.com \
    --cc=seanjc@google.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