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
next prev 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