Kernel KVM virtualization development
 help / color / mirror / Atom feed
* [PATCH v4 00/17] KVM: nVMX: Adjust VMPTRLD/VMPTRST behavior with active eVMCS
@ 2026-09-04  0:24 Sean Christopherson
  2026-09-04  0:24 ` [PATCH v4 01/17] KVM: nVMX: Make VMPTRLD result in #UD when eVMCS is used Sean Christopherson
                   ` (16 more replies)
  0 siblings, 17 replies; 21+ messages in thread
From: Sean Christopherson @ 2026-09-04  0:24 UTC (permalink / raw)
  To: Sean Christopherson, Paolo Bonzini
  Cc: kvm, linux-kernel, f734222792, Vitaly Kuznetsov, Sashiko Bot,
	Yosry Ahmed

The first four patches are Vitaly's series to adjust KVM's emulation of
VMPTRLD/VMPTRST when the vCPU has an active eVMCS to match Hyper-V, and more
importantly to not put the vCPU into an infinite loop.

The churn piled on top came from wanting to use KVM_ASM_SAFE() for more VMX
instructions to verify the RFLAGS bug+fix Sashiko pointed out, lack impulse
control when it comes to cleanups, and Yosry being a bad/good influence.

v4:
 - Redo the VMLAUNCH/VMRESUME handling, dedup eVMCS as well. [Yosry]
 - Give vmread() and vmwrite() the same treatment. [Yosry]
 - Drop pointless returns from eVMCS setup.

v3:
 - https://lore.kernel.org/all/20260826233919.998904-1-seanjc@google.com
 - MOAR PATCHES.

v2:
 - https://lore.kernel.org/all/20260818165258.2613603-1-vkuznets@redhat.com
 - Fix build when !CONFIG_KVM_HYPERV [Sashiko]
 - Drop now-unneeded evmcs_vmptrst() [Sashiko]
 - Avoid hardcoding VMPTRLD insn length in hyperv_evmcs [Sashiko], use
   KVM_ASM_SAFE framework instead [Sean]

v1: https://lore.kernel.org/all/20260814162221.2144473-1-vkuznets@redhat.com

Sean Christopherson (13):
  KVM: selftests: Don't clobber RFLAGS in happy path of __KVM_ASM_SAFE()
  KVM: selftests: Assert success in vmptrst(), kill off vmptrstz()
  KVM: selftests: Always assert that vmxon() and
    prepare_for_vmx_operation() succeed
  KVM: selftests: Always assert that vmclear() succeeds
  KVM: selftests: Always assert that vmptrld() succeeds
  KVM: selftests: Drop useless return code from load_vmcs()
  KVM: selftests: Add macros to handle simple VMX instructions
  KVM: selftests: Drop dead return code from evmcs_vmptrld() and
    load_evmcs()
  KVM: selftests: Dedup assembly code for VMLAUNCH and VMRESUME
  KVM: selftests: Assert success in vmlaunch() and vmresume()
  KVM: selftests: Add __vmwrite() and use it when initializing optional
    fields.
  KVM: selftests: Always assert that vmwrite() succeeds
  KVM: selftests: Always assert that vmreadz() succeeds

Vitaly Kuznetsov (4):
  KVM: nVMX: Make VMPTRLD result in #UD when eVMCS is used
  KVM: nVMX: Make VMPTRST return eVMCS GPA when it is used
  KVM: selftests: Adapt to the updated VMPTRST behavior when eVMCS is
    used
  KVM: selftests: Check VMPTRLD with active eVMCS

 arch/x86/kvm/vmx/nested.c                     |  24 ++-
 .../testing/selftests/kvm/include/x86/evmcs.h |  78 +--------
 .../selftests/kvm/include/x86/processor.h     |   2 +-
 tools/testing/selftests/kvm/include/x86/vmx.h | 165 ++++++------------
 .../testing/selftests/kvm/lib/x86/memstress.c |   8 +-
 tools/testing/selftests/kvm/lib/x86/vmx.c     | 143 ++++++++++-----
 .../selftests/kvm/x86/aperfmperf_test.c       |  10 +-
 .../kvm/x86/evmcs_smm_controls_test.c         |   6 +-
 .../testing/selftests/kvm/x86/hyperv_evmcs.c  |  83 +++++----
 .../selftests/kvm/x86/kvm_buslock_test.c      |   8 +-
 .../selftests/kvm/x86/nested_close_kvm_test.c |   6 +-
 .../selftests/kvm/x86/nested_dirty_log_test.c |   8 +-
 .../selftests/kvm/x86/nested_emulation_test.c |  23 +--
 .../kvm/x86/nested_exceptions_test.c          |  29 +--
 .../kvm/x86/nested_invalid_cr3_test.c         |  14 +-
 .../selftests/kvm/x86/nested_tdp_fault_test.c |  16 +-
 .../kvm/x86/nested_tsc_adjust_test.c          |  10 +-
 .../kvm/x86/nested_tsc_scaling_test.c         |  12 +-
 .../kvm/x86/save_restore_pf_stress_test.c     |  14 +-
 tools/testing/selftests/kvm/x86/smm_test.c    |   4 +-
 tools/testing/selftests/kvm/x86/state_test.c  |  70 ++++----
 .../kvm/x86/triple_fault_event_test.c         |   8 +-
 .../selftests/kvm/x86/vmx_apic_access_test.c  |  20 +--
 .../kvm/x86/vmx_apicv_updates_test.c          |  16 +-
 .../kvm/x86/vmx_invalid_nested_guest_state.c  |  12 +-
 .../kvm/x86/vmx_nested_la57_state_test.c      |  10 +-
 .../kvm/x86/vmx_preemption_timer_test.c       |  24 ++-
 27 files changed, 387 insertions(+), 436 deletions(-)


base-commit: 76671054f9a1ff6abb976583cd8da37650acdc97
-- 
2.55.0.979.g7e5102b832-goog


^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH v4 01/17] KVM: nVMX: Make VMPTRLD result in #UD when eVMCS is used
  2026-09-04  0:24 [PATCH v4 00/17] KVM: nVMX: Adjust VMPTRLD/VMPTRST behavior with active eVMCS Sean Christopherson
@ 2026-09-04  0:24 ` Sean Christopherson
  2026-09-04  0:24 ` [PATCH v4 02/17] KVM: nVMX: Make VMPTRST return eVMCS GPA when it " Sean Christopherson
                   ` (15 subsequent siblings)
  16 siblings, 0 replies; 21+ messages in thread
From: Sean Christopherson @ 2026-09-04  0:24 UTC (permalink / raw)
  To: Sean Christopherson, Paolo Bonzini
  Cc: kvm, linux-kernel, f734222792, Vitaly Kuznetsov, Sashiko Bot,
	Yosry Ahmed

From: Vitaly Kuznetsov <vkuznets@redhat.com>

VMPTRLD with active eVMCS is already forbidden, however, returning 1
without skipping the instruction or queuing an exception will likely
result in L1 getting stuck. Genuine Hyper-V seems to inject #UD under
similar circumstances, mimic the behavior in KVM.

Reported-by: f734222792@gmail.com
Link: https://bugzilla.kernel.org/show_bug.cgi?id=221841
Suggested-by: Sean Christopherson <seanjc@google.com>
Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
 arch/x86/kvm/vmx/nested.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c
index 151873407abd..ad3726fd4fda 100644
--- a/arch/x86/kvm/vmx/nested.c
+++ b/arch/x86/kvm/vmx/nested.c
@@ -5897,6 +5897,12 @@ static int handle_vmptrld(struct kvm_vcpu *vcpu)
 	if (!nested_vmx_check_permission(vcpu))
 		return 1;
 
+	/* Forbid normal VMPTRLD if Enlightened version was used */
+	if (nested_vmx_is_evmptr12_valid(vmx)) {
+		kvm_queue_exception(vcpu, UD_VECTOR);
+		return 1;
+	}
+
 	if (nested_vmx_get_vmptr(vcpu, &vmptr, &r))
 		return r;
 
@@ -5906,10 +5912,6 @@ static int handle_vmptrld(struct kvm_vcpu *vcpu)
 	if (vmptr == vmx->nested.vmxon_ptr)
 		return nested_vmx_fail(vcpu, VMXERR_VMPTRLD_VMXON_POINTER);
 
-	/* Forbid normal VMPTRLD if Enlightened version was used */
-	if (nested_vmx_is_evmptr12_valid(vmx))
-		return 1;
-
 	if (vmx->nested.current_vmptr != vmptr) {
 		struct gfn_to_hva_cache *ghc = &vmx->nested.vmcs12_cache;
 		struct vmcs_hdr hdr;
-- 
2.55.0.979.g7e5102b832-goog


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v4 02/17] KVM: nVMX: Make VMPTRST return eVMCS GPA when it is used
  2026-09-04  0:24 [PATCH v4 00/17] KVM: nVMX: Adjust VMPTRLD/VMPTRST behavior with active eVMCS Sean Christopherson
  2026-09-04  0:24 ` [PATCH v4 01/17] KVM: nVMX: Make VMPTRLD result in #UD when eVMCS is used Sean Christopherson
@ 2026-09-04  0:24 ` Sean Christopherson
  2026-09-04  0:24 ` [PATCH v4 03/17] KVM: selftests: Don't clobber RFLAGS in happy path of __KVM_ASM_SAFE() Sean Christopherson
                   ` (14 subsequent siblings)
  16 siblings, 0 replies; 21+ messages in thread
From: Sean Christopherson @ 2026-09-04  0:24 UTC (permalink / raw)
  To: Sean Christopherson, Paolo Bonzini
  Cc: kvm, linux-kernel, f734222792, Vitaly Kuznetsov, Sashiko Bot,
	Yosry Ahmed

From: Vitaly Kuznetsov <vkuznets@redhat.com>

VMPTRST with active eVMCS is currently forbidden, however, returning 1
without skipping the instruction will likely result in L1 getting
stuck. While TLFS does not specify the expected behavior, genuine Hyper-V
seems to be returning eVMCS GPA. Implement the same behavior in KVM.

Reported-by: f734222792@gmail.com
Link: https://bugzilla.kernel.org/show_bug.cgi?id=221841
Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
 arch/x86/kvm/vmx/nested.c | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c
index ad3726fd4fda..3058efa65c82 100644
--- a/arch/x86/kvm/vmx/nested.c
+++ b/arch/x86/kvm/vmx/nested.c
@@ -5964,7 +5964,7 @@ static int handle_vmptrst(struct kvm_vcpu *vcpu)
 {
 	unsigned long exit_qual = vmx_get_exit_qual(vcpu);
 	u32 instr_info = vmcs_read32(VMX_INSTRUCTION_INFO);
-	gpa_t current_vmptr = to_vmx(vcpu)->nested.current_vmptr;
+	gpa_t current_vmptr;
 	struct x86_exception e;
 	gva_t gva;
 	int r;
@@ -5972,8 +5972,16 @@ static int handle_vmptrst(struct kvm_vcpu *vcpu)
 	if (!nested_vmx_check_permission(vcpu))
 		return 1;
 
-	if (unlikely(nested_vmx_is_evmptr12_valid(to_vmx(vcpu))))
-		return 1;
+	/*
+	 * Hyper-V TLFS does not specify the behavior of VMPTRST when eVMCS is used
+	 * but genuine Hyper-V seems to be returning eVMCS GPA.
+	 */
+#ifdef CONFIG_KVM_HYPERV
+	if (nested_vmx_is_evmptr12_valid(to_vmx(vcpu)))
+		current_vmptr = to_vmx(vcpu)->nested.hv_evmcs_vmptr;
+	else
+#endif
+		current_vmptr = to_vmx(vcpu)->nested.current_vmptr;
 
 	if (get_vmx_mem_address(vcpu, exit_qual, instr_info,
 				true, sizeof(gpa_t), &gva))
-- 
2.55.0.979.g7e5102b832-goog


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v4 03/17] KVM: selftests: Don't clobber RFLAGS in happy path of __KVM_ASM_SAFE()
  2026-09-04  0:24 [PATCH v4 00/17] KVM: nVMX: Adjust VMPTRLD/VMPTRST behavior with active eVMCS Sean Christopherson
  2026-09-04  0:24 ` [PATCH v4 01/17] KVM: nVMX: Make VMPTRLD result in #UD when eVMCS is used Sean Christopherson
  2026-09-04  0:24 ` [PATCH v4 02/17] KVM: nVMX: Make VMPTRST return eVMCS GPA when it " Sean Christopherson
@ 2026-09-04  0:24 ` Sean Christopherson
  2026-09-04  0:24 ` [PATCH v4 04/17] KVM: selftests: Adapt to the updated VMPTRST behavior when eVMCS is used Sean Christopherson
                   ` (13 subsequent siblings)
  16 siblings, 0 replies; 21+ messages in thread
From: Sean Christopherson @ 2026-09-04  0:24 UTC (permalink / raw)
  To: Sean Christopherson, Paolo Bonzini
  Cc: kvm, linux-kernel, f734222792, Vitaly Kuznetsov, Sashiko Bot,
	Yosry Ahmed

Use a straight MOV instead of an XOR to zero R9 in the non-faulting path of
__KVM_ASM_SAFE() so as not to clobber RFLAGS.  XOR generates smaller code,
but optimizing performance by minimizing the code footprint is just about
the last thing that KVM selftests care about.

The bug is relatively benign in the current code base, e.g. it marginally
degrades the coverage in the fastops test, but otherwise does no harm.  But
the bug will become actively problematic if/when the "safe assembly" macros
are used for instructions that communicate results via RFLAGS, e.g. for VMX
instructions, which signal failure via RFLAGS.CF and RFLAGS.ZF.

Opportunistically use R9D instead of the full R9, as bits 63:32 of GPRs are
zeroed on writes to bit 31:0.

Reported-by: Sashiko Bot <sashiko-bot@kernel.org>
Closes: https://lore.kernel.org/all/20260818165258.2613603-5-vkuznets@redhat.com
Cc: Vitaly Kuznetsov <vkuznets@redhat.com>
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
 tools/testing/selftests/kvm/include/x86/processor.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/testing/selftests/kvm/include/x86/processor.h b/tools/testing/selftests/kvm/include/x86/processor.h
index 6e6f70035508..282b8aaff799 100644
--- a/tools/testing/selftests/kvm/include/x86/processor.h
+++ b/tools/testing/selftests/kvm/include/x86/processor.h
@@ -1318,7 +1318,7 @@ gva_t vm_alloc_stack(struct kvm_vm *vm, int nr_pages);
 	"lea 1f(%%rip), %%r10\n\t"				\
 	"lea 2f(%%rip), %%r11\n\t"				\
 	fep "1: " insn "\n\t"					\
-	"xor %%r9, %%r9\n\t"					\
+	"mov $0, %%r9d\n\t"					\
 	"2:\n\t"						\
 	"mov  %%r9b, %[vector]\n\t"				\
 	"mov  %%r10, %[error_code]\n\t"
-- 
2.55.0.979.g7e5102b832-goog


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v4 04/17] KVM: selftests: Adapt to the updated VMPTRST behavior when eVMCS is used
  2026-09-04  0:24 [PATCH v4 00/17] KVM: nVMX: Adjust VMPTRLD/VMPTRST behavior with active eVMCS Sean Christopherson
                   ` (2 preceding siblings ...)
  2026-09-04  0:24 ` [PATCH v4 03/17] KVM: selftests: Don't clobber RFLAGS in happy path of __KVM_ASM_SAFE() Sean Christopherson
@ 2026-09-04  0:24 ` Sean Christopherson
  2026-09-04  0:24 ` [PATCH v4 05/17] KVM: selftests: Check VMPTRLD with active eVMCS Sean Christopherson
                   ` (12 subsequent siblings)
  16 siblings, 0 replies; 21+ messages in thread
From: Sean Christopherson @ 2026-09-04  0:24 UTC (permalink / raw)
  To: Sean Christopherson, Paolo Bonzini
  Cc: kvm, linux-kernel, f734222792, Vitaly Kuznetsov, Sashiko Bot,
	Yosry Ahmed

From: Vitaly Kuznetsov <vkuznets@redhat.com>

Previously, VMPTRST was forbidden with eVMCS and selftests were mocking the
correct behavior in vmptrst() by returning enlightened vmptr directly.
Since KVM's behavior has changed to match genuine Hyper-V, adjust evmcs
test accordingly.

Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
 tools/testing/selftests/kvm/include/x86/evmcs.h | 8 --------
 tools/testing/selftests/kvm/include/x86/vmx.h   | 3 ---
 tools/testing/selftests/kvm/x86/hyperv_evmcs.c  | 5 ++---
 3 files changed, 2 insertions(+), 14 deletions(-)

diff --git a/tools/testing/selftests/kvm/include/x86/evmcs.h b/tools/testing/selftests/kvm/include/x86/evmcs.h
index 82a8ea6b661f..c5b9d26f6cdb 100644
--- a/tools/testing/selftests/kvm/include/x86/evmcs.h
+++ b/tools/testing/selftests/kvm/include/x86/evmcs.h
@@ -265,14 +265,6 @@ static inline bool load_evmcs(struct hyperv_test_pages *hv)
 	return true;
 }
 
-static inline int evmcs_vmptrst(u64 *value)
-{
-	*value = current_vp_assist->current_nested_vmcs &
-		~HV_X64_MSR_VP_ASSIST_PAGE_ENABLE;
-
-	return 0;
-}
-
 static inline int evmcs_vmread(u64 encoding, u64 *value)
 {
 	switch (encoding) {
diff --git a/tools/testing/selftests/kvm/include/x86/vmx.h b/tools/testing/selftests/kvm/include/x86/vmx.h
index 04f5e34dea3a..ac7d48d1387e 100644
--- a/tools/testing/selftests/kvm/include/x86/vmx.h
+++ b/tools/testing/selftests/kvm/include/x86/vmx.h
@@ -358,9 +358,6 @@ static inline int vmptrst(u64 *value)
 	u64 tmp;
 	u8 ret;
 
-	if (enable_evmcs)
-		return evmcs_vmptrst(value);
-
 	__asm__ __volatile__("vmptrst %[value]; setna %[ret]"
 		: [value]"=m"(tmp), [ret]"=rm"(ret)
 		: : "cc", "memory");
diff --git a/tools/testing/selftests/kvm/x86/hyperv_evmcs.c b/tools/testing/selftests/kvm/x86/hyperv_evmcs.c
index 63ea1533e4ea..6224d859d7bb 100644
--- a/tools/testing/selftests/kvm/x86/hyperv_evmcs.c
+++ b/tools/testing/selftests/kvm/x86/hyperv_evmcs.c
@@ -92,15 +92,14 @@ void guest_code(struct vmx_pages *vmx_pages, struct hyperv_test_pages *hv_pages,
 	GUEST_ASSERT(prepare_for_vmx_operation(vmx_pages));
 	GUEST_SYNC(3);
 	GUEST_ASSERT(load_evmcs(hv_pages));
-	GUEST_ASSERT(vmptrstz() == hv_pages->enlightened_vmcs_gpa);
+	/* VMPTRST returns -1 until VMLAUNCH with eVMCS ptr set */
+	GUEST_ASSERT(vmptrstz() == -1);
 
 	GUEST_SYNC(4);
-	GUEST_ASSERT(vmptrstz() == hv_pages->enlightened_vmcs_gpa);
 
 	prepare_vmcs(vmx_pages, l2_guest_code);
 
 	GUEST_SYNC(5);
-	GUEST_ASSERT(vmptrstz() == hv_pages->enlightened_vmcs_gpa);
 	current_evmcs->revision_id = -1u;
 	GUEST_ASSERT(vmlaunch());
 	current_evmcs->revision_id = EVMCS_VERSION;
-- 
2.55.0.979.g7e5102b832-goog


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v4 05/17] KVM: selftests: Check VMPTRLD with active eVMCS
  2026-09-04  0:24 [PATCH v4 00/17] KVM: nVMX: Adjust VMPTRLD/VMPTRST behavior with active eVMCS Sean Christopherson
                   ` (3 preceding siblings ...)
  2026-09-04  0:24 ` [PATCH v4 04/17] KVM: selftests: Adapt to the updated VMPTRST behavior when eVMCS is used Sean Christopherson
@ 2026-09-04  0:24 ` Sean Christopherson
  2026-09-04  0:24 ` [PATCH v4 06/17] KVM: selftests: Assert success in vmptrst(), kill off vmptrstz() Sean Christopherson
                   ` (11 subsequent siblings)
  16 siblings, 0 replies; 21+ messages in thread
From: Sean Christopherson @ 2026-09-04  0:24 UTC (permalink / raw)
  To: Sean Christopherson, Paolo Bonzini
  Cc: kvm, linux-kernel, f734222792, Vitaly Kuznetsov, Sashiko Bot,
	Yosry Ahmed

From: Vitaly Kuznetsov <vkuznets@redhat.com>

Check that VMPTRLD when eVMCS is active results in #UD. This matches
genuine Hyper-V's behavior.

Use KVM_ASM_SAFE framework to handle #UD from VMPTRLD.  Unfortunately, the
same trick cannot be applied to the existing #UD check on VMLAUNCH as
VMLAUNCH clobbers all registers which KVM_ASM_SAFE depends on.  Keep
VMLAUNCH handling separately.  Deliberately use a double-underscores
prefix instead of a "safe" postfix for the helper, to communicate that the
inner/outer helpers handle more than just exceptions, they also handle
VM-Fail conditions.

Assisted-by: Claude:claude-sonnet-4-6
Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
[sean: use __ instead of _safe]
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
 tools/testing/selftests/kvm/include/x86/vmx.h | 19 +++++++++++---
 .../testing/selftests/kvm/x86/hyperv_evmcs.c  | 26 +++++++++++++++----
 2 files changed, 37 insertions(+), 8 deletions(-)

diff --git a/tools/testing/selftests/kvm/include/x86/vmx.h b/tools/testing/selftests/kvm/include/x86/vmx.h
index ac7d48d1387e..a161dbee7e04 100644
--- a/tools/testing/selftests/kvm/include/x86/vmx.h
+++ b/tools/testing/selftests/kvm/include/x86/vmx.h
@@ -342,9 +342,6 @@ static inline int vmptrld(u64 vmcs_pa)
 {
 	u8 ret;
 
-	if (enable_evmcs)
-		return -1;
-
 	__asm__ __volatile__ ("vmptrld %[pa]; setna %[ret]"
 		: [ret]"=rm"(ret)
 		: [pa]"m"(vmcs_pa)
@@ -353,6 +350,22 @@ static inline int vmptrld(u64 vmcs_pa)
 	return ret;
 }
 
+static inline int __vmptrld(u64 vmcs_pa)
+{
+	u64 error_code;
+	u8 vector;
+	u8 failed;
+
+	asm volatile(KVM_ASM_SAFE("vmptrld %[pa]")
+		     "\n\tsetna %[failed]"
+		     : KVM_ASM_SAFE_OUTPUTS(vector, error_code),
+		       [failed]"=qm"(failed)
+		     : [pa]"m"(vmcs_pa)
+		     : "cc", "memory", KVM_ASM_SAFE_CLOBBERS);
+
+	return vector ? vector : failed ? -EINVAL : 0;
+}
+
 static inline int vmptrst(u64 *value)
 {
 	u64 tmp;
diff --git a/tools/testing/selftests/kvm/x86/hyperv_evmcs.c b/tools/testing/selftests/kvm/x86/hyperv_evmcs.c
index 6224d859d7bb..f953a9755a76 100644
--- a/tools/testing/selftests/kvm/x86/hyperv_evmcs.c
+++ b/tools/testing/selftests/kvm/x86/hyperv_evmcs.c
@@ -23,7 +23,11 @@ static int ud_count;
 static void guest_ud_handler(struct ex_regs *regs)
 {
 	ud_count++;
-	regs->rip += 3; /* VMLAUNCH */
+	/*
+	 * VMLAUNCH insn can't be easily covered by KVM_ASM_SAFE framework but
+	 * luckily the instruction is always three bytes.
+	 */
+	regs->rip += 3;
 }
 
 static void guest_nmi_handler(struct ex_regs *regs)
@@ -178,7 +182,15 @@ void guest_code(struct vmx_pages *vmx_pages, struct hyperv_test_pages *hv_pages,
 	GUEST_ASSERT(vmreadz(VM_EXIT_REASON) == EXIT_REASON_VMCALL);
 	GUEST_SYNC(11);
 
-	/* Try enlightened vmptrld with an incorrect GPA */
+	/* VMPTRLD instruction causes #UD after enlightened VMLAUNCH */
+	GUEST_ASSERT(__vmptrld(hv_pages->enlightened_vmcs_gpa) == UD_VECTOR);
+
+	/*
+	 * Try enlightened vmptrld with an incorrect GPA. GUEST_SYNC(12) signals
+	 * the host to enable guest_ud_handler() which cannot be enabled beforehand
+	 * to not override the default fixup handler from KVM_ASM_SAFE().
+	 */
+	GUEST_SYNC(12);
 	evmcs_vmptrld(0xdeadbeef, hv_pages->enlightened_vmcs);
 	GUEST_ASSERT(vmlaunch());
 	GUEST_ASSERT(ud_count == 1);
@@ -252,7 +264,6 @@ int main(int argc, char *argv[])
 	vcpu_args_set(vcpu, 3, vmx_pages_gva, hv_pages_gva, addr_gva2gpa(vm, hcall_page));
 	vcpu_set_msr(vcpu, HV_X64_MSR_VP_INDEX, vcpu->id);
 
-	vm_install_exception_handler(vm, UD_VECTOR, guest_ud_handler);
 	vm_install_exception_handler(vm, NMI_VECTOR, guest_nmi_handler);
 
 	pr_info("Running L1 which uses EVMCS to run L2\n");
@@ -282,7 +293,7 @@ int main(int argc, char *argv[])
 
 		/* Force immediate L2->L1 exit before resuming */
 		if (stage == 8) {
-			pr_info("Injecting NMI into L1 before L2 had a chance to run after restore\n");
+			pr_debug("Injecting NMI into L1 before L2 had a chance to run after restore\n");
 			inject_nmi(vcpu);
 		}
 
@@ -292,9 +303,14 @@ int main(int argc, char *argv[])
 		 * KVM_STATE_NESTED_EVMCS is not lost.
 		 */
 		if (stage == 9) {
-			pr_info("Trying extra KVM_GET_NESTED_STATE/KVM_SET_NESTED_STATE cycle\n");
+			pr_debug("Trying extra KVM_GET_NESTED_STATE/KVM_SET_NESTED_STATE cycle\n");
 			vcpu = save_restore_vm(vm, vcpu);
 		}
+
+		if (stage == 12) {
+			pr_debug("Trying enlightened VMLAUNCH with an invalid PTR\n");
+			vm_install_exception_handler(vm, UD_VECTOR, guest_ud_handler);
+		}
 	}
 
 done:
-- 
2.55.0.979.g7e5102b832-goog


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v4 06/17] KVM: selftests: Assert success in vmptrst(), kill off vmptrstz()
  2026-09-04  0:24 [PATCH v4 00/17] KVM: nVMX: Adjust VMPTRLD/VMPTRST behavior with active eVMCS Sean Christopherson
                   ` (4 preceding siblings ...)
  2026-09-04  0:24 ` [PATCH v4 05/17] KVM: selftests: Check VMPTRLD with active eVMCS Sean Christopherson
@ 2026-09-04  0:24 ` Sean Christopherson
  2026-09-04  0:24 ` [PATCH v4 07/17] KVM: selftests: Always assert that vmxon() and prepare_for_vmx_operation() succeed Sean Christopherson
                   ` (10 subsequent siblings)
  16 siblings, 0 replies; 21+ messages in thread
From: Sean Christopherson @ 2026-09-04  0:24 UTC (permalink / raw)
  To: Sean Christopherson, Paolo Bonzini
  Cc: kvm, linux-kernel, f734222792, Vitaly Kuznetsov, Sashiko Bot,
	Yosry Ahmed

Assert success in vmptrst() instead of punting to the caller, as literally
every user expects VMPTRST to succeed (and because '0' is a valid physical
address).

Signed-off-by: Sean Christopherson <seanjc@google.com>
---
 tools/testing/selftests/kvm/include/x86/vmx.h | 19 ++++---------------
 .../testing/selftests/kvm/x86/hyperv_evmcs.c  |  4 ++--
 tools/testing/selftests/kvm/x86/state_test.c  |  8 ++++----
 .../kvm/x86/vmx_preemption_timer_test.c       |  2 +-
 4 files changed, 11 insertions(+), 22 deletions(-)

diff --git a/tools/testing/selftests/kvm/include/x86/vmx.h b/tools/testing/selftests/kvm/include/x86/vmx.h
index a161dbee7e04..04f638fcd3ba 100644
--- a/tools/testing/selftests/kvm/include/x86/vmx.h
+++ b/tools/testing/selftests/kvm/include/x86/vmx.h
@@ -366,27 +366,16 @@ static inline int __vmptrld(u64 vmcs_pa)
 	return vector ? vector : failed ? -EINVAL : 0;
 }
 
-static inline int vmptrst(u64 *value)
+static inline u64 vmptrst(void)
 {
-	u64 tmp;
+	u64 value = 0;
 	u8 ret;
 
 	__asm__ __volatile__("vmptrst %[value]; setna %[ret]"
-		: [value]"=m"(tmp), [ret]"=rm"(ret)
+		: [value]"=m"(value), [ret]"=rm"(ret)
 		: : "cc", "memory");
 
-	*value = tmp;
-	return ret;
-}
-
-/*
- * A wrapper around vmptrst that ignores errors and returns zero if the
- * vmptrst instruction fails.
- */
-static inline u64 vmptrstz(void)
-{
-	u64 value = 0;
-	vmptrst(&value);
+	__GUEST_ASSERT(!ret, "vmptrst failed");
 	return value;
 }
 
diff --git a/tools/testing/selftests/kvm/x86/hyperv_evmcs.c b/tools/testing/selftests/kvm/x86/hyperv_evmcs.c
index f953a9755a76..0c9cf620c87d 100644
--- a/tools/testing/selftests/kvm/x86/hyperv_evmcs.c
+++ b/tools/testing/selftests/kvm/x86/hyperv_evmcs.c
@@ -97,7 +97,7 @@ void guest_code(struct vmx_pages *vmx_pages, struct hyperv_test_pages *hv_pages,
 	GUEST_SYNC(3);
 	GUEST_ASSERT(load_evmcs(hv_pages));
 	/* VMPTRST returns -1 until VMLAUNCH with eVMCS ptr set */
-	GUEST_ASSERT(vmptrstz() == -1);
+	GUEST_ASSERT(vmptrst() == -1);
 
 	GUEST_SYNC(4);
 
@@ -123,7 +123,7 @@ void guest_code(struct vmx_pages *vmx_pages, struct hyperv_test_pages *hv_pages,
 	GUEST_ASSERT(!vmlaunch());
 	GUEST_ASSERT_EQ(vmreadz(VM_EXIT_REASON), EXIT_REASON_EXCEPTION_NMI);
 	GUEST_ASSERT_EQ((vmreadz(VM_EXIT_INTR_INFO) & 0xff), NMI_VECTOR);
-	GUEST_ASSERT(vmptrstz() == hv_pages->enlightened_vmcs_gpa);
+	GUEST_ASSERT(vmptrst() == hv_pages->enlightened_vmcs_gpa);
 
 	/*
 	 * NMI forces L2->L1 exit, resuming L2 and hope that EVMCS is
diff --git a/tools/testing/selftests/kvm/x86/state_test.c b/tools/testing/selftests/kvm/x86/state_test.c
index 4a1056a6cb8d..9d4e0c1f7c18 100644
--- a/tools/testing/selftests/kvm/x86/state_test.c
+++ b/tools/testing/selftests/kvm/x86/state_test.c
@@ -78,17 +78,17 @@ static void vmx_l1_guest_code(struct vmx_pages *vmx_pages)
 	GUEST_ASSERT(prepare_for_vmx_operation(vmx_pages));
 	GUEST_SYNC(3);
 	GUEST_ASSERT(load_vmcs(vmx_pages));
-	GUEST_ASSERT(vmptrstz() == vmx_pages->vmcs_gpa);
+	GUEST_ASSERT(vmptrst() == vmx_pages->vmcs_gpa);
 
 	GUEST_SYNC(4);
-	GUEST_ASSERT(vmptrstz() == vmx_pages->vmcs_gpa);
+	GUEST_ASSERT(vmptrst() == vmx_pages->vmcs_gpa);
 
 	prepare_vmcs(vmx_pages, vmx_l2_guest_code);
 
 	GUEST_SYNC(5);
-	GUEST_ASSERT(vmptrstz() == vmx_pages->vmcs_gpa);
+	GUEST_ASSERT(vmptrst() == vmx_pages->vmcs_gpa);
 	GUEST_ASSERT(!vmlaunch());
-	GUEST_ASSERT(vmptrstz() == vmx_pages->vmcs_gpa);
+	GUEST_ASSERT(vmptrst() == vmx_pages->vmcs_gpa);
 	GUEST_ASSERT(vmreadz(VM_EXIT_REASON) == EXIT_REASON_VMCALL);
 
 	/* Check that the launched state is preserved.  */
diff --git a/tools/testing/selftests/kvm/x86/vmx_preemption_timer_test.c b/tools/testing/selftests/kvm/x86/vmx_preemption_timer_test.c
index eb8021c33cd4..523aab667d85 100644
--- a/tools/testing/selftests/kvm/x86/vmx_preemption_timer_test.c
+++ b/tools/testing/selftests/kvm/x86/vmx_preemption_timer_test.c
@@ -73,7 +73,7 @@ void l1_guest_code(struct vmx_pages *vmx_pages)
 	GUEST_ASSERT(vmx_pages->vmcs_gpa);
 	GUEST_ASSERT(prepare_for_vmx_operation(vmx_pages));
 	GUEST_ASSERT(load_vmcs(vmx_pages));
-	GUEST_ASSERT(vmptrstz() == vmx_pages->vmcs_gpa);
+	GUEST_ASSERT(vmptrst() == vmx_pages->vmcs_gpa);
 
 	prepare_vmcs(vmx_pages, l2_guest_code);
 
-- 
2.55.0.979.g7e5102b832-goog


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v4 07/17] KVM: selftests: Always assert that vmxon() and prepare_for_vmx_operation() succeed
  2026-09-04  0:24 [PATCH v4 00/17] KVM: nVMX: Adjust VMPTRLD/VMPTRST behavior with active eVMCS Sean Christopherson
                   ` (5 preceding siblings ...)
  2026-09-04  0:24 ` [PATCH v4 06/17] KVM: selftests: Assert success in vmptrst(), kill off vmptrstz() Sean Christopherson
@ 2026-09-04  0:24 ` Sean Christopherson
  2026-09-04  0:24 ` [PATCH v4 08/17] KVM: selftests: Always assert that vmclear() succeeds Sean Christopherson
                   ` (9 subsequent siblings)
  16 siblings, 0 replies; 21+ messages in thread
From: Sean Christopherson @ 2026-09-04  0:24 UTC (permalink / raw)
  To: Sean Christopherson, Paolo Bonzini
  Cc: kvm, linux-kernel, f734222792, Vitaly Kuznetsov, Sashiko Bot,
	Yosry Ahmed

Assert that vmxon() succeeds, and by extension prepare_for_vmx_operation().
Forcing every caller to assert that a core preparation helper succeeds is
absurd and generates hard-to-read code.

For all intents and purposes, no functional change intended.

Signed-off-by: Sean Christopherson <seanjc@google.com>
---
 tools/testing/selftests/kvm/include/x86/vmx.h              | 6 +++---
 tools/testing/selftests/kvm/lib/x86/memstress.c            | 2 +-
 tools/testing/selftests/kvm/lib/x86/vmx.c                  | 7 ++-----
 tools/testing/selftests/kvm/x86/aperfmperf_test.c          | 2 +-
 tools/testing/selftests/kvm/x86/evmcs_smm_controls_test.c  | 2 +-
 tools/testing/selftests/kvm/x86/hyperv_evmcs.c             | 2 +-
 tools/testing/selftests/kvm/x86/kvm_buslock_test.c         | 2 +-
 tools/testing/selftests/kvm/x86/nested_close_kvm_test.c    | 2 +-
 tools/testing/selftests/kvm/x86/nested_dirty_log_test.c    | 2 +-
 tools/testing/selftests/kvm/x86/nested_emulation_test.c    | 2 +-
 tools/testing/selftests/kvm/x86/nested_exceptions_test.c   | 2 +-
 tools/testing/selftests/kvm/x86/nested_invalid_cr3_test.c  | 2 +-
 tools/testing/selftests/kvm/x86/nested_tdp_fault_test.c    | 2 +-
 tools/testing/selftests/kvm/x86/nested_tsc_adjust_test.c   | 2 +-
 tools/testing/selftests/kvm/x86/nested_tsc_scaling_test.c  | 2 +-
 .../selftests/kvm/x86/save_restore_pf_stress_test.c        | 2 +-
 tools/testing/selftests/kvm/x86/smm_test.c                 | 2 +-
 tools/testing/selftests/kvm/x86/state_test.c               | 2 +-
 tools/testing/selftests/kvm/x86/triple_fault_event_test.c  | 2 +-
 tools/testing/selftests/kvm/x86/vmx_apic_access_test.c     | 2 +-
 tools/testing/selftests/kvm/x86/vmx_apicv_updates_test.c   | 2 +-
 .../selftests/kvm/x86/vmx_invalid_nested_guest_state.c     | 2 +-
 .../testing/selftests/kvm/x86/vmx_nested_la57_state_test.c | 2 +-
 .../testing/selftests/kvm/x86/vmx_preemption_timer_test.c  | 2 +-
 24 files changed, 27 insertions(+), 30 deletions(-)

diff --git a/tools/testing/selftests/kvm/include/x86/vmx.h b/tools/testing/selftests/kvm/include/x86/vmx.h
index 04f638fcd3ba..f7ca6646dfbe 100644
--- a/tools/testing/selftests/kvm/include/x86/vmx.h
+++ b/tools/testing/selftests/kvm/include/x86/vmx.h
@@ -309,7 +309,7 @@ struct vmx_msr_entry {
 
 #include "evmcs.h"
 
-static inline int vmxon(u64 phys)
+static inline void vmxon(u64 phys)
 {
 	u8 ret;
 
@@ -318,7 +318,7 @@ static inline int vmxon(u64 phys)
 		: [pa]"m"(phys)
 		: "cc", "memory");
 
-	return ret;
+	__GUEST_ASSERT(!ret, "vmxon [0x%lx] failed", phys);
 }
 
 static inline void vmxoff(void)
@@ -549,7 +549,7 @@ union vmx_ctrl_msr {
 };
 
 struct vmx_pages *vcpu_alloc_vmx(struct kvm_vm *vm, gva_t *p_vmx_gva);
-bool prepare_for_vmx_operation(struct vmx_pages *vmx);
+void prepare_for_vmx_operation(struct vmx_pages *vmx);
 void prepare_vmcs(struct vmx_pages *vmx, void *guest_rip);
 bool load_vmcs(struct vmx_pages *vmx);
 
diff --git a/tools/testing/selftests/kvm/lib/x86/memstress.c b/tools/testing/selftests/kvm/lib/x86/memstress.c
index e19e8b5a09c5..2fa39470c1b3 100644
--- a/tools/testing/selftests/kvm/lib/x86/memstress.c
+++ b/tools/testing/selftests/kvm/lib/x86/memstress.c
@@ -33,7 +33,7 @@ __asm__(
 static void l1_vmx_code(struct vmx_pages *vmx, u64 vcpu_id)
 {
 	GUEST_ASSERT(vmx->vmcs_gpa);
-	GUEST_ASSERT(prepare_for_vmx_operation(vmx));
+	prepare_for_vmx_operation(vmx);
 	GUEST_ASSERT(load_vmcs(vmx));
 	GUEST_ASSERT(ept_1g_pages_supported());
 
diff --git a/tools/testing/selftests/kvm/lib/x86/vmx.c b/tools/testing/selftests/kvm/lib/x86/vmx.c
index 089e1a8af53f..03d61b1159f8 100644
--- a/tools/testing/selftests/kvm/lib/x86/vmx.c
+++ b/tools/testing/selftests/kvm/lib/x86/vmx.c
@@ -125,7 +125,7 @@ vcpu_alloc_vmx(struct kvm_vm *vm, gva_t *p_vmx_gva)
 	return vmx;
 }
 
-bool prepare_for_vmx_operation(struct vmx_pages *vmx)
+void prepare_for_vmx_operation(struct vmx_pages *vmx)
 {
 	u64 feature_control;
 	u64 required;
@@ -163,10 +163,7 @@ bool prepare_for_vmx_operation(struct vmx_pages *vmx)
 
 	/* Enter VMX root operation. */
 	*(u32 *)(vmx->vmxon) = vmcs_revision();
-	if (vmxon(vmx->vmxon_gpa))
-		return false;
-
-	return true;
+	vmxon(vmx->vmxon_gpa);
 }
 
 bool load_vmcs(struct vmx_pages *vmx)
diff --git a/tools/testing/selftests/kvm/x86/aperfmperf_test.c b/tools/testing/selftests/kvm/x86/aperfmperf_test.c
index 845cb685f174..e32131cd6ed1 100644
--- a/tools/testing/selftests/kvm/x86/aperfmperf_test.c
+++ b/tools/testing/selftests/kvm/x86/aperfmperf_test.c
@@ -70,7 +70,7 @@ static void l1_svm_code(struct svm_test_data *svm)
 
 static void l1_vmx_code(struct vmx_pages *vmx)
 {
-	GUEST_ASSERT_EQ(prepare_for_vmx_operation(vmx), true);
+	prepare_for_vmx_operation(vmx);
 	GUEST_ASSERT_EQ(load_vmcs(vmx), true);
 
 	prepare_vmcs(vmx, NULL);
diff --git a/tools/testing/selftests/kvm/x86/evmcs_smm_controls_test.c b/tools/testing/selftests/kvm/x86/evmcs_smm_controls_test.c
index aa7f3b405fd3..cafb58a37023 100644
--- a/tools/testing/selftests/kvm/x86/evmcs_smm_controls_test.c
+++ b/tools/testing/selftests/kvm/x86/evmcs_smm_controls_test.c
@@ -55,7 +55,7 @@ static void guest_code(struct vmx_pages *vmx_pages,
 	enable_vp_assist(hv_pages->vp_assist_gpa, hv_pages->vp_assist);
 	evmcs_enable();
 
-	GUEST_ASSERT(prepare_for_vmx_operation(vmx_pages));
+	prepare_for_vmx_operation(vmx_pages);
 	GUEST_ASSERT(load_evmcs(hv_pages));
 	prepare_vmcs(vmx_pages, l2_guest_code);
 
diff --git a/tools/testing/selftests/kvm/x86/hyperv_evmcs.c b/tools/testing/selftests/kvm/x86/hyperv_evmcs.c
index 0c9cf620c87d..d0e857b75a47 100644
--- a/tools/testing/selftests/kvm/x86/hyperv_evmcs.c
+++ b/tools/testing/selftests/kvm/x86/hyperv_evmcs.c
@@ -93,7 +93,7 @@ void guest_code(struct vmx_pages *vmx_pages, struct hyperv_test_pages *hv_pages,
 	enable_vp_assist(hv_pages->vp_assist_gpa, hv_pages->vp_assist);
 	evmcs_enable();
 
-	GUEST_ASSERT(prepare_for_vmx_operation(vmx_pages));
+	prepare_for_vmx_operation(vmx_pages);
 	GUEST_SYNC(3);
 	GUEST_ASSERT(load_evmcs(hv_pages));
 	/* VMPTRST returns -1 until VMLAUNCH with eVMCS ptr set */
diff --git a/tools/testing/selftests/kvm/x86/kvm_buslock_test.c b/tools/testing/selftests/kvm/x86/kvm_buslock_test.c
index 25a182be00a9..2e006ce95896 100644
--- a/tools/testing/selftests/kvm/x86/kvm_buslock_test.c
+++ b/tools/testing/selftests/kvm/x86/kvm_buslock_test.c
@@ -42,7 +42,7 @@ static void l1_svm_code(struct svm_test_data *svm)
 
 static void l1_vmx_code(struct vmx_pages *vmx)
 {
-	GUEST_ASSERT_EQ(prepare_for_vmx_operation(vmx), true);
+	prepare_for_vmx_operation(vmx);
 	GUEST_ASSERT_EQ(load_vmcs(vmx), true);
 
 	prepare_vmcs(vmx, NULL);
diff --git a/tools/testing/selftests/kvm/x86/nested_close_kvm_test.c b/tools/testing/selftests/kvm/x86/nested_close_kvm_test.c
index b974cfb347d6..479e9adcc20b 100644
--- a/tools/testing/selftests/kvm/x86/nested_close_kvm_test.c
+++ b/tools/testing/selftests/kvm/x86/nested_close_kvm_test.c
@@ -30,7 +30,7 @@ static void l2_guest_code(void)
 
 static void l1_vmx_code(struct vmx_pages *vmx_pages)
 {
-	GUEST_ASSERT(prepare_for_vmx_operation(vmx_pages));
+	prepare_for_vmx_operation(vmx_pages);
 	GUEST_ASSERT(load_vmcs(vmx_pages));
 
 	/* Prepare the VMCS for L2 execution. */
diff --git a/tools/testing/selftests/kvm/x86/nested_dirty_log_test.c b/tools/testing/selftests/kvm/x86/nested_dirty_log_test.c
index 26b474bf1353..57f49471f4aa 100644
--- a/tools/testing/selftests/kvm/x86/nested_dirty_log_test.c
+++ b/tools/testing/selftests/kvm/x86/nested_dirty_log_test.c
@@ -93,7 +93,7 @@ void l1_vmx_code(struct vmx_pages *vmx)
 	void *l2_rip;
 
 	GUEST_ASSERT(vmx->vmcs_gpa);
-	GUEST_ASSERT(prepare_for_vmx_operation(vmx));
+	prepare_for_vmx_operation(vmx);
 	GUEST_ASSERT(load_vmcs(vmx));
 
 	if (vmx->eptp_gpa)
diff --git a/tools/testing/selftests/kvm/x86/nested_emulation_test.c b/tools/testing/selftests/kvm/x86/nested_emulation_test.c
index e08c6b0697e5..6f27930bb6b5 100644
--- a/tools/testing/selftests/kvm/x86/nested_emulation_test.c
+++ b/tools/testing/selftests/kvm/x86/nested_emulation_test.c
@@ -66,7 +66,7 @@ static void guest_code(void *test_data)
 					   BIT_ULL(INTERCEPT_HLT);
 		vmcb->control.intercept_exceptions = 0;
 	} else {
-		GUEST_ASSERT(prepare_for_vmx_operation(test_data));
+		prepare_for_vmx_operation(test_data);
 		GUEST_ASSERT(load_vmcs(test_data));
 
 		prepare_vmcs(test_data, NULL);
diff --git a/tools/testing/selftests/kvm/x86/nested_exceptions_test.c b/tools/testing/selftests/kvm/x86/nested_exceptions_test.c
index aeec3121c8e8..6a36cf4d1eab 100644
--- a/tools/testing/selftests/kvm/x86/nested_exceptions_test.c
+++ b/tools/testing/selftests/kvm/x86/nested_exceptions_test.c
@@ -125,7 +125,7 @@ static void vmx_run_l2(void *l2_code, int vector, u32 error_code)
 
 static void l1_vmx_code(struct vmx_pages *vmx)
 {
-	GUEST_ASSERT_EQ(prepare_for_vmx_operation(vmx), true);
+	prepare_for_vmx_operation(vmx);
 
 	GUEST_ASSERT_EQ(load_vmcs(vmx), true);
 
diff --git a/tools/testing/selftests/kvm/x86/nested_invalid_cr3_test.c b/tools/testing/selftests/kvm/x86/nested_invalid_cr3_test.c
index 8c2ba9674558..749a93c318fe 100644
--- a/tools/testing/selftests/kvm/x86/nested_invalid_cr3_test.c
+++ b/tools/testing/selftests/kvm/x86/nested_invalid_cr3_test.c
@@ -40,7 +40,7 @@ static void l1_vmx_code(struct vmx_pages *vmx_pages)
 {
 	uintptr_t save_cr3;
 
-	GUEST_ASSERT(prepare_for_vmx_operation(vmx_pages));
+	prepare_for_vmx_operation(vmx_pages);
 	GUEST_ASSERT(load_vmcs(vmx_pages));
 
 	prepare_vmcs(vmx_pages, l2_guest_code);
diff --git a/tools/testing/selftests/kvm/x86/nested_tdp_fault_test.c b/tools/testing/selftests/kvm/x86/nested_tdp_fault_test.c
index 2e04563790ff..b143ebe710e7 100644
--- a/tools/testing/selftests/kvm/x86/nested_tdp_fault_test.c
+++ b/tools/testing/selftests/kvm/x86/nested_tdp_fault_test.c
@@ -55,7 +55,7 @@ static void l1_vmx_code(struct vmx_pages *vmx, u64 expected_fault_gpa,
 	u64 exit_qual;
 
 	GUEST_ASSERT(vmx->vmcs_gpa);
-	GUEST_ASSERT(prepare_for_vmx_operation(vmx));
+	prepare_for_vmx_operation(vmx);
 	GUEST_ASSERT(load_vmcs(vmx));
 
 	prepare_vmcs(vmx, l2_entry);
diff --git a/tools/testing/selftests/kvm/x86/nested_tsc_adjust_test.c b/tools/testing/selftests/kvm/x86/nested_tsc_adjust_test.c
index cb79d7b9619c..3d2eae848ba6 100644
--- a/tools/testing/selftests/kvm/x86/nested_tsc_adjust_test.c
+++ b/tools/testing/selftests/kvm/x86/nested_tsc_adjust_test.c
@@ -86,7 +86,7 @@ static void l1_guest_code(void *data)
 		struct vmx_pages *vmx_pages = data;
 		u32 control;
 
-		GUEST_ASSERT(prepare_for_vmx_operation(vmx_pages));
+		prepare_for_vmx_operation(vmx_pages);
 		GUEST_ASSERT(load_vmcs(vmx_pages));
 
 		prepare_vmcs(vmx_pages, l2_guest_code);
diff --git a/tools/testing/selftests/kvm/x86/nested_tsc_scaling_test.c b/tools/testing/selftests/kvm/x86/nested_tsc_scaling_test.c
index 18f765835bf4..584071146b69 100644
--- a/tools/testing/selftests/kvm/x86/nested_tsc_scaling_test.c
+++ b/tools/testing/selftests/kvm/x86/nested_tsc_scaling_test.c
@@ -105,7 +105,7 @@ static void l1_vmx_code(struct vmx_pages *vmx_pages)
 	/* check that L1's frequency looks alright before launching L2 */
 	check_tsc_freq(UCHECK_L1);
 
-	GUEST_ASSERT(prepare_for_vmx_operation(vmx_pages));
+	prepare_for_vmx_operation(vmx_pages);
 	GUEST_ASSERT(load_vmcs(vmx_pages));
 
 	/* prepare the VMCS for L2 execution */
diff --git a/tools/testing/selftests/kvm/x86/save_restore_pf_stress_test.c b/tools/testing/selftests/kvm/x86/save_restore_pf_stress_test.c
index 507391ab2c93..6ab73a0bd34a 100644
--- a/tools/testing/selftests/kvm/x86/save_restore_pf_stress_test.c
+++ b/tools/testing/selftests/kvm/x86/save_restore_pf_stress_test.c
@@ -98,7 +98,7 @@ static void l1_svm_code(struct svm_test_data *svm)
 
 static void l1_vmx_code(struct vmx_pages *vmx)
 {
-	GUEST_ASSERT(prepare_for_vmx_operation(vmx));
+	prepare_for_vmx_operation(vmx);
 	GUEST_ASSERT(load_vmcs(vmx));
 	prepare_vmcs(vmx, guest_access_memory);
 
diff --git a/tools/testing/selftests/kvm/x86/smm_test.c b/tools/testing/selftests/kvm/x86/smm_test.c
index d1edafd5af75..be5662792ec8 100644
--- a/tools/testing/selftests/kvm/x86/smm_test.c
+++ b/tools/testing/selftests/kvm/x86/smm_test.c
@@ -78,7 +78,7 @@ static void guest_code(void *arg)
 		if (this_cpu_has(X86_FEATURE_SVM)) {
 			generic_svm_setup(svm, l2_guest_code);
 		} else {
-			GUEST_ASSERT(prepare_for_vmx_operation(vmx_pages));
+			prepare_for_vmx_operation(vmx_pages);
 			GUEST_ASSERT(load_vmcs(vmx_pages));
 			prepare_vmcs(vmx_pages, l2_guest_code);
 		}
diff --git a/tools/testing/selftests/kvm/x86/state_test.c b/tools/testing/selftests/kvm/x86/state_test.c
index 9d4e0c1f7c18..203584fcaf62 100644
--- a/tools/testing/selftests/kvm/x86/state_test.c
+++ b/tools/testing/selftests/kvm/x86/state_test.c
@@ -75,7 +75,7 @@ void vmx_l2_guest_code(void)
 static void vmx_l1_guest_code(struct vmx_pages *vmx_pages)
 {
 	GUEST_ASSERT(vmx_pages->vmcs_gpa);
-	GUEST_ASSERT(prepare_for_vmx_operation(vmx_pages));
+	prepare_for_vmx_operation(vmx_pages);
 	GUEST_SYNC(3);
 	GUEST_ASSERT(load_vmcs(vmx_pages));
 	GUEST_ASSERT(vmptrst() == vmx_pages->vmcs_gpa);
diff --git a/tools/testing/selftests/kvm/x86/triple_fault_event_test.c b/tools/testing/selftests/kvm/x86/triple_fault_event_test.c
index 0d83516f4bd0..57e79922b16b 100644
--- a/tools/testing/selftests/kvm/x86/triple_fault_event_test.c
+++ b/tools/testing/selftests/kvm/x86/triple_fault_event_test.c
@@ -25,7 +25,7 @@ void l1_guest_code_vmx(struct vmx_pages *vmx)
 {
 
 	GUEST_ASSERT(vmx->vmcs_gpa);
-	GUEST_ASSERT(prepare_for_vmx_operation(vmx));
+	prepare_for_vmx_operation(vmx);
 	GUEST_ASSERT(load_vmcs(vmx));
 
 	prepare_vmcs(vmx, l2_guest_code);
diff --git a/tools/testing/selftests/kvm/x86/vmx_apic_access_test.c b/tools/testing/selftests/kvm/x86/vmx_apic_access_test.c
index 463f73aa9159..7df9ab833cb2 100644
--- a/tools/testing/selftests/kvm/x86/vmx_apic_access_test.c
+++ b/tools/testing/selftests/kvm/x86/vmx_apic_access_test.c
@@ -38,7 +38,7 @@ static void l1_guest_code(struct vmx_pages *vmx_pages, unsigned long high_gpa)
 {
 	u32 control;
 
-	GUEST_ASSERT(prepare_for_vmx_operation(vmx_pages));
+	prepare_for_vmx_operation(vmx_pages);
 	GUEST_ASSERT(load_vmcs(vmx_pages));
 
 	/* Prepare the VMCS for L2 execution. */
diff --git a/tools/testing/selftests/kvm/x86/vmx_apicv_updates_test.c b/tools/testing/selftests/kvm/x86/vmx_apicv_updates_test.c
index f9b88a6f6113..8e4dc304533a 100644
--- a/tools/testing/selftests/kvm/x86/vmx_apicv_updates_test.c
+++ b/tools/testing/selftests/kvm/x86/vmx_apicv_updates_test.c
@@ -33,7 +33,7 @@ static void l1_guest_code(struct vmx_pages *vmx_pages)
 {
 	u32 control;
 
-	GUEST_ASSERT(prepare_for_vmx_operation(vmx_pages));
+	prepare_for_vmx_operation(vmx_pages);
 	GUEST_ASSERT(load_vmcs(vmx_pages));
 
 	/* Prepare the VMCS for L2 execution. */
diff --git a/tools/testing/selftests/kvm/x86/vmx_invalid_nested_guest_state.c b/tools/testing/selftests/kvm/x86/vmx_invalid_nested_guest_state.c
index c8379124b317..8999f0458aa1 100644
--- a/tools/testing/selftests/kvm/x86/vmx_invalid_nested_guest_state.c
+++ b/tools/testing/selftests/kvm/x86/vmx_invalid_nested_guest_state.c
@@ -41,7 +41,7 @@ static void l2_guest_code(void)
 
 static void l1_guest_code(struct vmx_pages *vmx_pages)
 {
-	GUEST_ASSERT(prepare_for_vmx_operation(vmx_pages));
+	prepare_for_vmx_operation(vmx_pages);
 	GUEST_ASSERT(load_vmcs(vmx_pages));
 
 	/* Prepare the VMCS for L2 execution. */
diff --git a/tools/testing/selftests/kvm/x86/vmx_nested_la57_state_test.c b/tools/testing/selftests/kvm/x86/vmx_nested_la57_state_test.c
index 75073efa926d..444596ab1592 100644
--- a/tools/testing/selftests/kvm/x86/vmx_nested_la57_state_test.c
+++ b/tools/testing/selftests/kvm/x86/vmx_nested_la57_state_test.c
@@ -37,7 +37,7 @@ static void l1_guest_code(struct vmx_pages *vmx_pages)
 	GUEST_ASSERT(rdmsr(MSR_GS_BASE) == LA57_GS_BASE);
 
 	GUEST_ASSERT(vmx_pages->vmcs_gpa);
-	GUEST_ASSERT(prepare_for_vmx_operation(vmx_pages));
+	prepare_for_vmx_operation(vmx_pages);
 	GUEST_ASSERT(load_vmcs(vmx_pages));
 
 	prepare_vmcs(vmx_pages, l2_guest_code);
diff --git a/tools/testing/selftests/kvm/x86/vmx_preemption_timer_test.c b/tools/testing/selftests/kvm/x86/vmx_preemption_timer_test.c
index 523aab667d85..09f9686657ad 100644
--- a/tools/testing/selftests/kvm/x86/vmx_preemption_timer_test.c
+++ b/tools/testing/selftests/kvm/x86/vmx_preemption_timer_test.c
@@ -71,7 +71,7 @@ void l1_guest_code(struct vmx_pages *vmx_pages)
 	u64 l1_tsc_deadline, l2_tsc_deadline;
 
 	GUEST_ASSERT(vmx_pages->vmcs_gpa);
-	GUEST_ASSERT(prepare_for_vmx_operation(vmx_pages));
+	prepare_for_vmx_operation(vmx_pages);
 	GUEST_ASSERT(load_vmcs(vmx_pages));
 	GUEST_ASSERT(vmptrst() == vmx_pages->vmcs_gpa);
 
-- 
2.55.0.979.g7e5102b832-goog


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v4 08/17] KVM: selftests: Always assert that vmclear() succeeds
  2026-09-04  0:24 [PATCH v4 00/17] KVM: nVMX: Adjust VMPTRLD/VMPTRST behavior with active eVMCS Sean Christopherson
                   ` (6 preceding siblings ...)
  2026-09-04  0:24 ` [PATCH v4 07/17] KVM: selftests: Always assert that vmxon() and prepare_for_vmx_operation() succeed Sean Christopherson
@ 2026-09-04  0:24 ` Sean Christopherson
  2026-09-04  0:24 ` [PATCH v4 09/17] KVM: selftests: Always assert that vmptrld() succeeds Sean Christopherson
                   ` (8 subsequent siblings)
  16 siblings, 0 replies; 21+ messages in thread
From: Sean Christopherson @ 2026-09-04  0:24 UTC (permalink / raw)
  To: Sean Christopherson, Paolo Bonzini
  Cc: kvm, linux-kernel, f734222792, Vitaly Kuznetsov, Sashiko Bot,
	Yosry Ahmed

Continue removing dead error "handling", and assert that VMCLEAR
succeeds instead of forcing callers of load_vmcs() to assert success.

For all intents and purposes, no functional change intended.

Signed-off-by: Sean Christopherson <seanjc@google.com>
---
 tools/testing/selftests/kvm/include/x86/vmx.h | 4 ++--
 tools/testing/selftests/kvm/lib/x86/vmx.c     | 6 ++----
 2 files changed, 4 insertions(+), 6 deletions(-)

diff --git a/tools/testing/selftests/kvm/include/x86/vmx.h b/tools/testing/selftests/kvm/include/x86/vmx.h
index f7ca6646dfbe..cf37a03a93b9 100644
--- a/tools/testing/selftests/kvm/include/x86/vmx.h
+++ b/tools/testing/selftests/kvm/include/x86/vmx.h
@@ -326,7 +326,7 @@ static inline void vmxoff(void)
 	__asm__ __volatile__("vmxoff");
 }
 
-static inline int vmclear(u64 vmcs_pa)
+static inline void vmclear(u64 vmcs_pa)
 {
 	u8 ret;
 
@@ -335,7 +335,7 @@ static inline int vmclear(u64 vmcs_pa)
 		: [pa]"m"(vmcs_pa)
 		: "cc", "memory");
 
-	return ret;
+	__GUEST_ASSERT(!ret, "vmclear [0x%lx] failed\n", vmcs_pa);
 }
 
 static inline int vmptrld(u64 vmcs_pa)
diff --git a/tools/testing/selftests/kvm/lib/x86/vmx.c b/tools/testing/selftests/kvm/lib/x86/vmx.c
index 03d61b1159f8..57a8287de0d2 100644
--- a/tools/testing/selftests/kvm/lib/x86/vmx.c
+++ b/tools/testing/selftests/kvm/lib/x86/vmx.c
@@ -170,16 +170,14 @@ bool load_vmcs(struct vmx_pages *vmx)
 {
 	/* Load a VMCS. */
 	*(u32 *)(vmx->vmcs) = vmcs_revision();
-	if (vmclear(vmx->vmcs_gpa))
-		return false;
+	vmclear(vmx->vmcs_gpa);
 
 	if (vmptrld(vmx->vmcs_gpa))
 		return false;
 
 	/* Setup shadow VMCS, do not load it yet. */
 	*(u32 *)(vmx->shadow_vmcs) = vmcs_revision() | 0x80000000ul;
-	if (vmclear(vmx->shadow_vmcs_gpa))
-		return false;
+	vmclear(vmx->shadow_vmcs_gpa);
 
 	return true;
 }
-- 
2.55.0.979.g7e5102b832-goog


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v4 09/17] KVM: selftests: Always assert that vmptrld() succeeds
  2026-09-04  0:24 [PATCH v4 00/17] KVM: nVMX: Adjust VMPTRLD/VMPTRST behavior with active eVMCS Sean Christopherson
                   ` (7 preceding siblings ...)
  2026-09-04  0:24 ` [PATCH v4 08/17] KVM: selftests: Always assert that vmclear() succeeds Sean Christopherson
@ 2026-09-04  0:24 ` Sean Christopherson
  2026-09-04  0:24 ` [PATCH v4 10/17] KVM: selftests: Drop useless return code from load_vmcs() Sean Christopherson
                   ` (7 subsequent siblings)
  16 siblings, 0 replies; 21+ messages in thread
From: Sean Christopherson @ 2026-09-04  0:24 UTC (permalink / raw)
  To: Sean Christopherson, Paolo Bonzini
  Cc: kvm, linux-kernel, f734222792, Vitaly Kuznetsov, Sashiko Bot,
	Yosry Ahmed

Assert that vmptrld() succeeds instead of forcing all callers to do the
same, and opportunistically provide a macro to print (hopefully) useful
information on VMX instruction failures.

Leave load_vmcs() as-is for the moment to minimize the amount of churn
since the vmptrld() changes aren't completely trivial.

Signed-off-by: Sean Christopherson <seanjc@google.com>
---
 tools/testing/selftests/kvm/include/x86/vmx.h | 23 +++++++++----------
 tools/testing/selftests/kvm/lib/x86/vmx.c     |  3 +--
 tools/testing/selftests/kvm/x86/state_test.c  |  6 ++---
 3 files changed, 15 insertions(+), 17 deletions(-)

diff --git a/tools/testing/selftests/kvm/include/x86/vmx.h b/tools/testing/selftests/kvm/include/x86/vmx.h
index cf37a03a93b9..8f004b946826 100644
--- a/tools/testing/selftests/kvm/include/x86/vmx.h
+++ b/tools/testing/selftests/kvm/include/x86/vmx.h
@@ -309,6 +309,10 @@ struct vmx_msr_entry {
 
 #include "evmcs.h"
 
+#define GUEST_ASSERT_VMX_INSN_SUCCEEDED(insn, __r, __pa)		\
+	__GUEST_ASSERT(!__r, __stringify(insn) "[0x%lx] hit %s",	\
+		       __pa, __r < 0 ? "VM-Fail" : ex_str(__r))
+
 static inline void vmxon(u64 phys)
 {
 	u8 ret;
@@ -338,18 +342,6 @@ static inline void vmclear(u64 vmcs_pa)
 	__GUEST_ASSERT(!ret, "vmclear [0x%lx] failed\n", vmcs_pa);
 }
 
-static inline int vmptrld(u64 vmcs_pa)
-{
-	u8 ret;
-
-	__asm__ __volatile__ ("vmptrld %[pa]; setna %[ret]"
-		: [ret]"=rm"(ret)
-		: [pa]"m"(vmcs_pa)
-		: "cc", "memory");
-
-	return ret;
-}
-
 static inline int __vmptrld(u64 vmcs_pa)
 {
 	u64 error_code;
@@ -366,6 +358,13 @@ static inline int __vmptrld(u64 vmcs_pa)
 	return vector ? vector : failed ? -EINVAL : 0;
 }
 
+static inline void vmptrld(u64 vmcs_pa)
+{
+	int ret = __vmptrld(vmcs_pa);
+
+	GUEST_ASSERT_VMX_INSN_SUCCEEDED(vmptrld, ret, vmcs_pa);
+}
+
 static inline u64 vmptrst(void)
 {
 	u64 value = 0;
diff --git a/tools/testing/selftests/kvm/lib/x86/vmx.c b/tools/testing/selftests/kvm/lib/x86/vmx.c
index 57a8287de0d2..e65024b9ea0d 100644
--- a/tools/testing/selftests/kvm/lib/x86/vmx.c
+++ b/tools/testing/selftests/kvm/lib/x86/vmx.c
@@ -172,8 +172,7 @@ bool load_vmcs(struct vmx_pages *vmx)
 	*(u32 *)(vmx->vmcs) = vmcs_revision();
 	vmclear(vmx->vmcs_gpa);
 
-	if (vmptrld(vmx->vmcs_gpa))
-		return false;
+	vmptrld(vmx->vmcs_gpa);
 
 	/* Setup shadow VMCS, do not load it yet. */
 	*(u32 *)(vmx->shadow_vmcs) = vmcs_revision() | 0x80000000ul;
diff --git a/tools/testing/selftests/kvm/x86/state_test.c b/tools/testing/selftests/kvm/x86/state_test.c
index 203584fcaf62..a7786f478be0 100644
--- a/tools/testing/selftests/kvm/x86/state_test.c
+++ b/tools/testing/selftests/kvm/x86/state_test.c
@@ -108,7 +108,7 @@ static void vmx_l1_guest_code(struct vmx_pages *vmx_pages)
 	vmwrite(SECONDARY_VM_EXEC_CONTROL, SECONDARY_EXEC_SHADOW_VMCS);
 	vmwrite(VMCS_LINK_POINTER, vmx_pages->shadow_vmcs_gpa);
 
-	GUEST_ASSERT(!vmptrld(vmx_pages->shadow_vmcs_gpa));
+	vmptrld(vmx_pages->shadow_vmcs_gpa);
 	GUEST_ASSERT(vmlaunch());
 	GUEST_SYNC(8);
 	GUEST_ASSERT(vmlaunch());
@@ -118,11 +118,11 @@ static void vmx_l1_guest_code(struct vmx_pages *vmx_pages)
 	GUEST_SYNC(9);
 	GUEST_ASSERT(vmreadz(GUEST_RIP) == 0xc0ffee);
 
-	GUEST_ASSERT(!vmptrld(vmx_pages->vmcs_gpa));
+	vmptrld(vmx_pages->vmcs_gpa);
 	GUEST_ASSERT(!vmresume());
 	GUEST_ASSERT(vmreadz(VM_EXIT_REASON) == EXIT_REASON_VMCALL);
 
-	GUEST_ASSERT(!vmptrld(vmx_pages->shadow_vmcs_gpa));
+	vmptrld(vmx_pages->shadow_vmcs_gpa);
 	GUEST_ASSERT(vmreadz(GUEST_RIP) == 0xc0ffffee);
 	GUEST_ASSERT(vmlaunch());
 	GUEST_ASSERT(vmresume());
-- 
2.55.0.979.g7e5102b832-goog


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v4 10/17] KVM: selftests: Drop useless return code from load_vmcs()
  2026-09-04  0:24 [PATCH v4 00/17] KVM: nVMX: Adjust VMPTRLD/VMPTRST behavior with active eVMCS Sean Christopherson
                   ` (8 preceding siblings ...)
  2026-09-04  0:24 ` [PATCH v4 09/17] KVM: selftests: Always assert that vmptrld() succeeds Sean Christopherson
@ 2026-09-04  0:24 ` Sean Christopherson
  2026-09-04  0:24 ` [PATCH v4 11/17] KVM: selftests: Add macros to handle simple VMX instructions Sean Christopherson
                   ` (6 subsequent siblings)
  16 siblings, 0 replies; 21+ messages in thread
From: Sean Christopherson @ 2026-09-04  0:24 UTC (permalink / raw)
  To: Sean Christopherson, Paolo Bonzini
  Cc: kvm, linux-kernel, f734222792, Vitaly Kuznetsov, Sashiko Bot,
	Yosry Ahmed

Now that load_vmcs() either asserts or returns success, drop the return
code and the many asserts in its callers.

Signed-off-by: Sean Christopherson <seanjc@google.com>
---
 tools/testing/selftests/kvm/include/x86/vmx.h                 | 2 +-
 tools/testing/selftests/kvm/lib/x86/memstress.c               | 2 +-
 tools/testing/selftests/kvm/lib/x86/vmx.c                     | 4 +---
 tools/testing/selftests/kvm/x86/aperfmperf_test.c             | 2 +-
 tools/testing/selftests/kvm/x86/kvm_buslock_test.c            | 2 +-
 tools/testing/selftests/kvm/x86/nested_close_kvm_test.c       | 2 +-
 tools/testing/selftests/kvm/x86/nested_dirty_log_test.c       | 2 +-
 tools/testing/selftests/kvm/x86/nested_emulation_test.c       | 2 +-
 tools/testing/selftests/kvm/x86/nested_exceptions_test.c      | 2 +-
 tools/testing/selftests/kvm/x86/nested_invalid_cr3_test.c     | 2 +-
 tools/testing/selftests/kvm/x86/nested_tdp_fault_test.c       | 2 +-
 tools/testing/selftests/kvm/x86/nested_tsc_adjust_test.c      | 2 +-
 tools/testing/selftests/kvm/x86/nested_tsc_scaling_test.c     | 2 +-
 tools/testing/selftests/kvm/x86/save_restore_pf_stress_test.c | 2 +-
 tools/testing/selftests/kvm/x86/smm_test.c                    | 2 +-
 tools/testing/selftests/kvm/x86/state_test.c                  | 2 +-
 tools/testing/selftests/kvm/x86/triple_fault_event_test.c     | 2 +-
 tools/testing/selftests/kvm/x86/vmx_apic_access_test.c        | 2 +-
 tools/testing/selftests/kvm/x86/vmx_apicv_updates_test.c      | 2 +-
 .../selftests/kvm/x86/vmx_invalid_nested_guest_state.c        | 2 +-
 tools/testing/selftests/kvm/x86/vmx_nested_la57_state_test.c  | 2 +-
 tools/testing/selftests/kvm/x86/vmx_preemption_timer_test.c   | 2 +-
 22 files changed, 22 insertions(+), 24 deletions(-)

diff --git a/tools/testing/selftests/kvm/include/x86/vmx.h b/tools/testing/selftests/kvm/include/x86/vmx.h
index 8f004b946826..5c46ae95c4c3 100644
--- a/tools/testing/selftests/kvm/include/x86/vmx.h
+++ b/tools/testing/selftests/kvm/include/x86/vmx.h
@@ -550,7 +550,7 @@ union vmx_ctrl_msr {
 struct vmx_pages *vcpu_alloc_vmx(struct kvm_vm *vm, gva_t *p_vmx_gva);
 void prepare_for_vmx_operation(struct vmx_pages *vmx);
 void prepare_vmcs(struct vmx_pages *vmx, void *guest_rip);
-bool load_vmcs(struct vmx_pages *vmx);
+void load_vmcs(struct vmx_pages *vmx);
 
 bool ept_1g_pages_supported(void);
 
diff --git a/tools/testing/selftests/kvm/lib/x86/memstress.c b/tools/testing/selftests/kvm/lib/x86/memstress.c
index 2fa39470c1b3..207350ab6114 100644
--- a/tools/testing/selftests/kvm/lib/x86/memstress.c
+++ b/tools/testing/selftests/kvm/lib/x86/memstress.c
@@ -34,7 +34,7 @@ static void l1_vmx_code(struct vmx_pages *vmx, u64 vcpu_id)
 {
 	GUEST_ASSERT(vmx->vmcs_gpa);
 	prepare_for_vmx_operation(vmx);
-	GUEST_ASSERT(load_vmcs(vmx));
+	load_vmcs(vmx);
 	GUEST_ASSERT(ept_1g_pages_supported());
 
 	*(u64 *)vmx->stack = vcpu_id;
diff --git a/tools/testing/selftests/kvm/lib/x86/vmx.c b/tools/testing/selftests/kvm/lib/x86/vmx.c
index e65024b9ea0d..5c6cadc08405 100644
--- a/tools/testing/selftests/kvm/lib/x86/vmx.c
+++ b/tools/testing/selftests/kvm/lib/x86/vmx.c
@@ -166,7 +166,7 @@ void prepare_for_vmx_operation(struct vmx_pages *vmx)
 	vmxon(vmx->vmxon_gpa);
 }
 
-bool load_vmcs(struct vmx_pages *vmx)
+void load_vmcs(struct vmx_pages *vmx)
 {
 	/* Load a VMCS. */
 	*(u32 *)(vmx->vmcs) = vmcs_revision();
@@ -177,8 +177,6 @@ bool load_vmcs(struct vmx_pages *vmx)
 	/* Setup shadow VMCS, do not load it yet. */
 	*(u32 *)(vmx->shadow_vmcs) = vmcs_revision() | 0x80000000ul;
 	vmclear(vmx->shadow_vmcs_gpa);
-
-	return true;
 }
 
 static bool ept_vpid_cap_supported(u64 mask)
diff --git a/tools/testing/selftests/kvm/x86/aperfmperf_test.c b/tools/testing/selftests/kvm/x86/aperfmperf_test.c
index e32131cd6ed1..11f5894d8ac7 100644
--- a/tools/testing/selftests/kvm/x86/aperfmperf_test.c
+++ b/tools/testing/selftests/kvm/x86/aperfmperf_test.c
@@ -71,7 +71,7 @@ static void l1_svm_code(struct svm_test_data *svm)
 static void l1_vmx_code(struct vmx_pages *vmx)
 {
 	prepare_for_vmx_operation(vmx);
-	GUEST_ASSERT_EQ(load_vmcs(vmx), true);
+	load_vmcs(vmx);
 
 	prepare_vmcs(vmx, NULL);
 
diff --git a/tools/testing/selftests/kvm/x86/kvm_buslock_test.c b/tools/testing/selftests/kvm/x86/kvm_buslock_test.c
index 2e006ce95896..22993ec697fa 100644
--- a/tools/testing/selftests/kvm/x86/kvm_buslock_test.c
+++ b/tools/testing/selftests/kvm/x86/kvm_buslock_test.c
@@ -43,7 +43,7 @@ static void l1_svm_code(struct svm_test_data *svm)
 static void l1_vmx_code(struct vmx_pages *vmx)
 {
 	prepare_for_vmx_operation(vmx);
-	GUEST_ASSERT_EQ(load_vmcs(vmx), true);
+	load_vmcs(vmx);
 
 	prepare_vmcs(vmx, NULL);
 
diff --git a/tools/testing/selftests/kvm/x86/nested_close_kvm_test.c b/tools/testing/selftests/kvm/x86/nested_close_kvm_test.c
index 479e9adcc20b..309cab009929 100644
--- a/tools/testing/selftests/kvm/x86/nested_close_kvm_test.c
+++ b/tools/testing/selftests/kvm/x86/nested_close_kvm_test.c
@@ -31,7 +31,7 @@ static void l2_guest_code(void)
 static void l1_vmx_code(struct vmx_pages *vmx_pages)
 {
 	prepare_for_vmx_operation(vmx_pages);
-	GUEST_ASSERT(load_vmcs(vmx_pages));
+	load_vmcs(vmx_pages);
 
 	/* Prepare the VMCS for L2 execution. */
 	prepare_vmcs(vmx_pages, l2_guest_code);
diff --git a/tools/testing/selftests/kvm/x86/nested_dirty_log_test.c b/tools/testing/selftests/kvm/x86/nested_dirty_log_test.c
index 57f49471f4aa..dca2bfc8b158 100644
--- a/tools/testing/selftests/kvm/x86/nested_dirty_log_test.c
+++ b/tools/testing/selftests/kvm/x86/nested_dirty_log_test.c
@@ -94,7 +94,7 @@ void l1_vmx_code(struct vmx_pages *vmx)
 
 	GUEST_ASSERT(vmx->vmcs_gpa);
 	prepare_for_vmx_operation(vmx);
-	GUEST_ASSERT(load_vmcs(vmx));
+	load_vmcs(vmx);
 
 	if (vmx->eptp_gpa)
 		l2_rip = l2_guest_code_tdp_enabled;
diff --git a/tools/testing/selftests/kvm/x86/nested_emulation_test.c b/tools/testing/selftests/kvm/x86/nested_emulation_test.c
index 6f27930bb6b5..2b38eff4f516 100644
--- a/tools/testing/selftests/kvm/x86/nested_emulation_test.c
+++ b/tools/testing/selftests/kvm/x86/nested_emulation_test.c
@@ -67,7 +67,7 @@ static void guest_code(void *test_data)
 		vmcb->control.intercept_exceptions = 0;
 	} else {
 		prepare_for_vmx_operation(test_data);
-		GUEST_ASSERT(load_vmcs(test_data));
+		load_vmcs(test_data);
 
 		prepare_vmcs(test_data, NULL);
 		GUEST_ASSERT(!vmwrite(GUEST_IDTR_LIMIT, 0));
diff --git a/tools/testing/selftests/kvm/x86/nested_exceptions_test.c b/tools/testing/selftests/kvm/x86/nested_exceptions_test.c
index 6a36cf4d1eab..50c271a03692 100644
--- a/tools/testing/selftests/kvm/x86/nested_exceptions_test.c
+++ b/tools/testing/selftests/kvm/x86/nested_exceptions_test.c
@@ -127,7 +127,7 @@ static void l1_vmx_code(struct vmx_pages *vmx)
 {
 	prepare_for_vmx_operation(vmx);
 
-	GUEST_ASSERT_EQ(load_vmcs(vmx), true);
+	load_vmcs(vmx);
 
 	prepare_vmcs(vmx, NULL);
 	GUEST_ASSERT_EQ(vmwrite(GUEST_IDTR_LIMIT, 0), 0);
diff --git a/tools/testing/selftests/kvm/x86/nested_invalid_cr3_test.c b/tools/testing/selftests/kvm/x86/nested_invalid_cr3_test.c
index 749a93c318fe..43deb3b358ea 100644
--- a/tools/testing/selftests/kvm/x86/nested_invalid_cr3_test.c
+++ b/tools/testing/selftests/kvm/x86/nested_invalid_cr3_test.c
@@ -41,7 +41,7 @@ static void l1_vmx_code(struct vmx_pages *vmx_pages)
 	uintptr_t save_cr3;
 
 	prepare_for_vmx_operation(vmx_pages);
-	GUEST_ASSERT(load_vmcs(vmx_pages));
+	load_vmcs(vmx_pages);
 
 	prepare_vmcs(vmx_pages, l2_guest_code);
 
diff --git a/tools/testing/selftests/kvm/x86/nested_tdp_fault_test.c b/tools/testing/selftests/kvm/x86/nested_tdp_fault_test.c
index b143ebe710e7..52df467e9c44 100644
--- a/tools/testing/selftests/kvm/x86/nested_tdp_fault_test.c
+++ b/tools/testing/selftests/kvm/x86/nested_tdp_fault_test.c
@@ -56,7 +56,7 @@ static void l1_vmx_code(struct vmx_pages *vmx, u64 expected_fault_gpa,
 
 	GUEST_ASSERT(vmx->vmcs_gpa);
 	prepare_for_vmx_operation(vmx);
-	GUEST_ASSERT(load_vmcs(vmx));
+	load_vmcs(vmx);
 
 	prepare_vmcs(vmx, l2_entry);
 
diff --git a/tools/testing/selftests/kvm/x86/nested_tsc_adjust_test.c b/tools/testing/selftests/kvm/x86/nested_tsc_adjust_test.c
index 3d2eae848ba6..05194762ed33 100644
--- a/tools/testing/selftests/kvm/x86/nested_tsc_adjust_test.c
+++ b/tools/testing/selftests/kvm/x86/nested_tsc_adjust_test.c
@@ -87,7 +87,7 @@ static void l1_guest_code(void *data)
 		u32 control;
 
 		prepare_for_vmx_operation(vmx_pages);
-		GUEST_ASSERT(load_vmcs(vmx_pages));
+		load_vmcs(vmx_pages);
 
 		prepare_vmcs(vmx_pages, l2_guest_code);
 		control = vmreadz(CPU_BASED_VM_EXEC_CONTROL);
diff --git a/tools/testing/selftests/kvm/x86/nested_tsc_scaling_test.c b/tools/testing/selftests/kvm/x86/nested_tsc_scaling_test.c
index 584071146b69..b9fae268a9ec 100644
--- a/tools/testing/selftests/kvm/x86/nested_tsc_scaling_test.c
+++ b/tools/testing/selftests/kvm/x86/nested_tsc_scaling_test.c
@@ -106,7 +106,7 @@ static void l1_vmx_code(struct vmx_pages *vmx_pages)
 	check_tsc_freq(UCHECK_L1);
 
 	prepare_for_vmx_operation(vmx_pages);
-	GUEST_ASSERT(load_vmcs(vmx_pages));
+	load_vmcs(vmx_pages);
 
 	/* prepare the VMCS for L2 execution */
 	prepare_vmcs(vmx_pages, l2_guest_code);
diff --git a/tools/testing/selftests/kvm/x86/save_restore_pf_stress_test.c b/tools/testing/selftests/kvm/x86/save_restore_pf_stress_test.c
index 6ab73a0bd34a..c0e4d6e156ad 100644
--- a/tools/testing/selftests/kvm/x86/save_restore_pf_stress_test.c
+++ b/tools/testing/selftests/kvm/x86/save_restore_pf_stress_test.c
@@ -99,7 +99,7 @@ static void l1_svm_code(struct svm_test_data *svm)
 static void l1_vmx_code(struct vmx_pages *vmx)
 {
 	prepare_for_vmx_operation(vmx);
-	GUEST_ASSERT(load_vmcs(vmx));
+	load_vmcs(vmx);
 	prepare_vmcs(vmx, guest_access_memory);
 
 	GUEST_ASSERT(!vmwrite(EXCEPTION_BITMAP, BIT(UD_VECTOR)));
diff --git a/tools/testing/selftests/kvm/x86/smm_test.c b/tools/testing/selftests/kvm/x86/smm_test.c
index be5662792ec8..377df09e582a 100644
--- a/tools/testing/selftests/kvm/x86/smm_test.c
+++ b/tools/testing/selftests/kvm/x86/smm_test.c
@@ -79,7 +79,7 @@ static void guest_code(void *arg)
 			generic_svm_setup(svm, l2_guest_code);
 		} else {
 			prepare_for_vmx_operation(vmx_pages);
-			GUEST_ASSERT(load_vmcs(vmx_pages));
+			load_vmcs(vmx_pages);
 			prepare_vmcs(vmx_pages, l2_guest_code);
 		}
 
diff --git a/tools/testing/selftests/kvm/x86/state_test.c b/tools/testing/selftests/kvm/x86/state_test.c
index a7786f478be0..bd5e9e36b2c9 100644
--- a/tools/testing/selftests/kvm/x86/state_test.c
+++ b/tools/testing/selftests/kvm/x86/state_test.c
@@ -77,7 +77,7 @@ static void vmx_l1_guest_code(struct vmx_pages *vmx_pages)
 	GUEST_ASSERT(vmx_pages->vmcs_gpa);
 	prepare_for_vmx_operation(vmx_pages);
 	GUEST_SYNC(3);
-	GUEST_ASSERT(load_vmcs(vmx_pages));
+	load_vmcs(vmx_pages);
 	GUEST_ASSERT(vmptrst() == vmx_pages->vmcs_gpa);
 
 	GUEST_SYNC(4);
diff --git a/tools/testing/selftests/kvm/x86/triple_fault_event_test.c b/tools/testing/selftests/kvm/x86/triple_fault_event_test.c
index 57e79922b16b..a9fb7046ea4f 100644
--- a/tools/testing/selftests/kvm/x86/triple_fault_event_test.c
+++ b/tools/testing/selftests/kvm/x86/triple_fault_event_test.c
@@ -26,7 +26,7 @@ void l1_guest_code_vmx(struct vmx_pages *vmx)
 
 	GUEST_ASSERT(vmx->vmcs_gpa);
 	prepare_for_vmx_operation(vmx);
-	GUEST_ASSERT(load_vmcs(vmx));
+	load_vmcs(vmx);
 
 	prepare_vmcs(vmx, l2_guest_code);
 
diff --git a/tools/testing/selftests/kvm/x86/vmx_apic_access_test.c b/tools/testing/selftests/kvm/x86/vmx_apic_access_test.c
index 7df9ab833cb2..1793f7b02219 100644
--- a/tools/testing/selftests/kvm/x86/vmx_apic_access_test.c
+++ b/tools/testing/selftests/kvm/x86/vmx_apic_access_test.c
@@ -39,7 +39,7 @@ static void l1_guest_code(struct vmx_pages *vmx_pages, unsigned long high_gpa)
 	u32 control;
 
 	prepare_for_vmx_operation(vmx_pages);
-	GUEST_ASSERT(load_vmcs(vmx_pages));
+	load_vmcs(vmx_pages);
 
 	/* Prepare the VMCS for L2 execution. */
 	prepare_vmcs(vmx_pages, l2_guest_code);
diff --git a/tools/testing/selftests/kvm/x86/vmx_apicv_updates_test.c b/tools/testing/selftests/kvm/x86/vmx_apicv_updates_test.c
index 8e4dc304533a..f7ebc9b15629 100644
--- a/tools/testing/selftests/kvm/x86/vmx_apicv_updates_test.c
+++ b/tools/testing/selftests/kvm/x86/vmx_apicv_updates_test.c
@@ -34,7 +34,7 @@ static void l1_guest_code(struct vmx_pages *vmx_pages)
 	u32 control;
 
 	prepare_for_vmx_operation(vmx_pages);
-	GUEST_ASSERT(load_vmcs(vmx_pages));
+	load_vmcs(vmx_pages);
 
 	/* Prepare the VMCS for L2 execution. */
 	prepare_vmcs(vmx_pages, l2_guest_code);
diff --git a/tools/testing/selftests/kvm/x86/vmx_invalid_nested_guest_state.c b/tools/testing/selftests/kvm/x86/vmx_invalid_nested_guest_state.c
index 8999f0458aa1..4a6445958cf4 100644
--- a/tools/testing/selftests/kvm/x86/vmx_invalid_nested_guest_state.c
+++ b/tools/testing/selftests/kvm/x86/vmx_invalid_nested_guest_state.c
@@ -42,7 +42,7 @@ static void l2_guest_code(void)
 static void l1_guest_code(struct vmx_pages *vmx_pages)
 {
 	prepare_for_vmx_operation(vmx_pages);
-	GUEST_ASSERT(load_vmcs(vmx_pages));
+	load_vmcs(vmx_pages);
 
 	/* Prepare the VMCS for L2 execution. */
 	prepare_vmcs(vmx_pages, l2_guest_code);
diff --git a/tools/testing/selftests/kvm/x86/vmx_nested_la57_state_test.c b/tools/testing/selftests/kvm/x86/vmx_nested_la57_state_test.c
index 444596ab1592..04c2d5113e84 100644
--- a/tools/testing/selftests/kvm/x86/vmx_nested_la57_state_test.c
+++ b/tools/testing/selftests/kvm/x86/vmx_nested_la57_state_test.c
@@ -38,7 +38,7 @@ static void l1_guest_code(struct vmx_pages *vmx_pages)
 
 	GUEST_ASSERT(vmx_pages->vmcs_gpa);
 	prepare_for_vmx_operation(vmx_pages);
-	GUEST_ASSERT(load_vmcs(vmx_pages));
+	load_vmcs(vmx_pages);
 
 	prepare_vmcs(vmx_pages, l2_guest_code);
 
diff --git a/tools/testing/selftests/kvm/x86/vmx_preemption_timer_test.c b/tools/testing/selftests/kvm/x86/vmx_preemption_timer_test.c
index 09f9686657ad..50fc9309158f 100644
--- a/tools/testing/selftests/kvm/x86/vmx_preemption_timer_test.c
+++ b/tools/testing/selftests/kvm/x86/vmx_preemption_timer_test.c
@@ -72,7 +72,7 @@ void l1_guest_code(struct vmx_pages *vmx_pages)
 
 	GUEST_ASSERT(vmx_pages->vmcs_gpa);
 	prepare_for_vmx_operation(vmx_pages);
-	GUEST_ASSERT(load_vmcs(vmx_pages));
+	load_vmcs(vmx_pages);
 	GUEST_ASSERT(vmptrst() == vmx_pages->vmcs_gpa);
 
 	prepare_vmcs(vmx_pages, l2_guest_code);
-- 
2.55.0.979.g7e5102b832-goog


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v4 11/17] KVM: selftests: Add macros to handle simple VMX instructions
  2026-09-04  0:24 [PATCH v4 00/17] KVM: nVMX: Adjust VMPTRLD/VMPTRST behavior with active eVMCS Sean Christopherson
                   ` (9 preceding siblings ...)
  2026-09-04  0:24 ` [PATCH v4 10/17] KVM: selftests: Drop useless return code from load_vmcs() Sean Christopherson
@ 2026-09-04  0:24 ` Sean Christopherson
  2026-09-04  0:24 ` [PATCH v4 12/17] KVM: selftests: Drop dead return code from evmcs_vmptrld() and load_evmcs() Sean Christopherson
                   ` (5 subsequent siblings)
  16 siblings, 0 replies; 21+ messages in thread
From: Sean Christopherson @ 2026-09-04  0:24 UTC (permalink / raw)
  To: Sean Christopherson, Paolo Bonzini
  Cc: kvm, linux-kernel, f734222792, Vitaly Kuznetsov, Sashiko Bot,
	Yosry Ahmed

Add macros to build helpers for VMXON, VMPTRLD, and VMCLEAR, i.e. the VMX
instructions that take a VMCS address as input, and don't have outputs.
Getting the params right is annoying, especially when using KVM_ASM_SAFE().

As a bonus, this adds non-asserting double-underscores versions of VMXON
and VMCLEAR for "free".

Signed-off-by: Sean Christopherson <seanjc@google.com>
---
 tools/testing/selftests/kvm/include/x86/vmx.h | 71 +++++++------------
 1 file changed, 26 insertions(+), 45 deletions(-)

diff --git a/tools/testing/selftests/kvm/include/x86/vmx.h b/tools/testing/selftests/kvm/include/x86/vmx.h
index 5c46ae95c4c3..3def8df902a2 100644
--- a/tools/testing/selftests/kvm/include/x86/vmx.h
+++ b/tools/testing/selftests/kvm/include/x86/vmx.h
@@ -313,58 +313,39 @@ struct vmx_msr_entry {
 	__GUEST_ASSERT(!__r, __stringify(insn) "[0x%lx] hit %s",	\
 		       __pa, __r < 0 ? "VM-Fail" : ex_str(__r))
 
-static inline void vmxon(u64 phys)
-{
-	u8 ret;
-
-	__asm__ __volatile__ ("vmxon %[pa]; setna %[ret]"
-		: [ret]"=rm"(ret)
-		: [pa]"m"(phys)
-		: "cc", "memory");
-
-	__GUEST_ASSERT(!ret, "vmxon [0x%lx] failed", phys);
+#define BUILD_VMCS_ASM_HELPERS(insn)					\
+static inline int __##insn(u64 vmcs_pa)					\
+{									\
+	u64 error_code;							\
+	u8 vector;							\
+	u8 failed;							\
+									\
+	asm volatile(KVM_ASM_SAFE(__stringify(insn) " %[pa]")		\
+		     "\n\tsetna %[failed]"				\
+		     : KVM_ASM_SAFE_OUTPUTS(vector, error_code),	\
+		       [failed]"=qm"(failed)				\
+		     : [pa]"m"(vmcs_pa)					\
+		     : "cc", "memory", KVM_ASM_SAFE_CLOBBERS);		\
+									\
+	return vector ? vector : failed ? -EINVAL : 0;			\
+}									\
+									\
+static inline void insn(u64 vmcs_pa)					\
+{									\
+	int ret = __##insn(vmcs_pa);					\
+									\
+	GUEST_ASSERT_VMX_INSN_SUCCEEDED(insn, ret, vmcs_pa);		\
 }
 
+BUILD_VMCS_ASM_HELPERS(vmxon)
+BUILD_VMCS_ASM_HELPERS(vmptrld)
+BUILD_VMCS_ASM_HELPERS(vmclear)
+
 static inline void vmxoff(void)
 {
 	__asm__ __volatile__("vmxoff");
 }
 
-static inline void vmclear(u64 vmcs_pa)
-{
-	u8 ret;
-
-	__asm__ __volatile__ ("vmclear %[pa]; setna %[ret]"
-		: [ret]"=rm"(ret)
-		: [pa]"m"(vmcs_pa)
-		: "cc", "memory");
-
-	__GUEST_ASSERT(!ret, "vmclear [0x%lx] failed\n", vmcs_pa);
-}
-
-static inline int __vmptrld(u64 vmcs_pa)
-{
-	u64 error_code;
-	u8 vector;
-	u8 failed;
-
-	asm volatile(KVM_ASM_SAFE("vmptrld %[pa]")
-		     "\n\tsetna %[failed]"
-		     : KVM_ASM_SAFE_OUTPUTS(vector, error_code),
-		       [failed]"=qm"(failed)
-		     : [pa]"m"(vmcs_pa)
-		     : "cc", "memory", KVM_ASM_SAFE_CLOBBERS);
-
-	return vector ? vector : failed ? -EINVAL : 0;
-}
-
-static inline void vmptrld(u64 vmcs_pa)
-{
-	int ret = __vmptrld(vmcs_pa);
-
-	GUEST_ASSERT_VMX_INSN_SUCCEEDED(vmptrld, ret, vmcs_pa);
-}
-
 static inline u64 vmptrst(void)
 {
 	u64 value = 0;
-- 
2.55.0.979.g7e5102b832-goog


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v4 12/17] KVM: selftests: Drop dead return code from evmcs_vmptrld() and load_evmcs()
  2026-09-04  0:24 [PATCH v4 00/17] KVM: nVMX: Adjust VMPTRLD/VMPTRST behavior with active eVMCS Sean Christopherson
                   ` (10 preceding siblings ...)
  2026-09-04  0:24 ` [PATCH v4 11/17] KVM: selftests: Add macros to handle simple VMX instructions Sean Christopherson
@ 2026-09-04  0:24 ` Sean Christopherson
  2026-09-04  0:24 ` [PATCH v4 13/17] KVM: selftests: Dedup assembly code for VMLAUNCH and VMRESUME Sean Christopherson
                   ` (4 subsequent siblings)
  16 siblings, 0 replies; 21+ messages in thread
From: Sean Christopherson @ 2026-09-04  0:24 UTC (permalink / raw)
  To: Sean Christopherson, Paolo Bonzini
  Cc: kvm, linux-kernel, f734222792, Vitaly Kuznetsov, Sashiko Bot,
	Yosry Ahmed

Drop the return codes from evmcs_vmptrld() and load_evmcs() as they are
hardcoded to return '0' and "true" respectively.

No functional change intended.

Signed-off-by: Sean Christopherson <seanjc@google.com>
---
 tools/testing/selftests/kvm/include/x86/evmcs.h      | 12 +++---------
 .../selftests/kvm/x86/evmcs_smm_controls_test.c      |  2 +-
 tools/testing/selftests/kvm/x86/hyperv_evmcs.c       |  2 +-
 3 files changed, 5 insertions(+), 11 deletions(-)

diff --git a/tools/testing/selftests/kvm/include/x86/evmcs.h b/tools/testing/selftests/kvm/include/x86/evmcs.h
index c5b9d26f6cdb..f18ebfb10ee0 100644
--- a/tools/testing/selftests/kvm/include/x86/evmcs.h
+++ b/tools/testing/selftests/kvm/include/x86/evmcs.h
@@ -245,24 +245,18 @@ static inline void evmcs_enable(void)
 	enable_evmcs = true;
 }
 
-static inline int evmcs_vmptrld(u64 vmcs_pa, void *vmcs)
+static inline void evmcs_vmptrld(u64 vmcs_pa, void *vmcs)
 {
 	current_vp_assist->current_nested_vmcs = vmcs_pa;
 	current_vp_assist->enlighten_vmentry = 1;
 
 	current_evmcs = vmcs;
-
-	return 0;
 }
 
-static inline bool load_evmcs(struct hyperv_test_pages *hv)
+static inline void load_evmcs(struct hyperv_test_pages *hv)
 {
-	if (evmcs_vmptrld(hv->enlightened_vmcs_gpa, hv->enlightened_vmcs))
-		return false;
-
+	evmcs_vmptrld(hv->enlightened_vmcs_gpa, hv->enlightened_vmcs);
 	current_evmcs->revision_id = EVMCS_VERSION;
-
-	return true;
 }
 
 static inline int evmcs_vmread(u64 encoding, u64 *value)
diff --git a/tools/testing/selftests/kvm/x86/evmcs_smm_controls_test.c b/tools/testing/selftests/kvm/x86/evmcs_smm_controls_test.c
index cafb58a37023..5c0391f8a38d 100644
--- a/tools/testing/selftests/kvm/x86/evmcs_smm_controls_test.c
+++ b/tools/testing/selftests/kvm/x86/evmcs_smm_controls_test.c
@@ -56,7 +56,7 @@ static void guest_code(struct vmx_pages *vmx_pages,
 	evmcs_enable();
 
 	prepare_for_vmx_operation(vmx_pages);
-	GUEST_ASSERT(load_evmcs(hv_pages));
+	load_evmcs(hv_pages);
 	prepare_vmcs(vmx_pages, l2_guest_code);
 
 	GUEST_ASSERT(!vmlaunch());
diff --git a/tools/testing/selftests/kvm/x86/hyperv_evmcs.c b/tools/testing/selftests/kvm/x86/hyperv_evmcs.c
index d0e857b75a47..854b86c4be8a 100644
--- a/tools/testing/selftests/kvm/x86/hyperv_evmcs.c
+++ b/tools/testing/selftests/kvm/x86/hyperv_evmcs.c
@@ -95,7 +95,7 @@ void guest_code(struct vmx_pages *vmx_pages, struct hyperv_test_pages *hv_pages,
 
 	prepare_for_vmx_operation(vmx_pages);
 	GUEST_SYNC(3);
-	GUEST_ASSERT(load_evmcs(hv_pages));
+	load_evmcs(hv_pages);
 	/* VMPTRST returns -1 until VMLAUNCH with eVMCS ptr set */
 	GUEST_ASSERT(vmptrst() == -1);
 
-- 
2.55.0.979.g7e5102b832-goog


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v4 13/17] KVM: selftests: Dedup assembly code for VMLAUNCH and VMRESUME
  2026-09-04  0:24 [PATCH v4 00/17] KVM: nVMX: Adjust VMPTRLD/VMPTRST behavior with active eVMCS Sean Christopherson
                   ` (11 preceding siblings ...)
  2026-09-04  0:24 ` [PATCH v4 12/17] KVM: selftests: Drop dead return code from evmcs_vmptrld() and load_evmcs() Sean Christopherson
@ 2026-09-04  0:24 ` Sean Christopherson
  2026-09-04  0:24 ` [PATCH v4 14/17] KVM: selftests: Assert success in vmlaunch() and vmresume() Sean Christopherson
                   ` (3 subsequent siblings)
  16 siblings, 0 replies; 21+ messages in thread
From: Sean Christopherson @ 2026-09-04  0:24 UTC (permalink / raw)
  To: Sean Christopherson, Paolo Bonzini
  Cc: kvm, linux-kernel, f734222792, Vitaly Kuznetsov, Sashiko Bot,
	Yosry Ahmed

Dedup the assembly code for VMLAUNCH vs. VMRESUME, for both architectural
VMCS and eVMCS, as the difference is literally only the actual VM-Enter
instruction for VMLAUNCH vs. VMRESUME, and VMWRITE vs. MOV for VMCS vs.
eVMCS.

Opportunistically place the implementations in vmx.c so that the lengthy
sequence (~580 bytes of code) aren't inlined for every single VM-Enter.

000000000041b910 <__vmlaunch>:
  41b910:       80 3d 61 5e 10 00 00                            cmpb   $0x0,0x105e61(%rip)        # 521778 <enable_evmcs>
  41b917:       0f 85 13 01 00 00                               jne    41ba30 <__vmlaunch+0x120>
  41b91d:       ba 14 6c 00 00                                  mov    $0x6c14,%edx
  41b922:       b9 16 6c 00 00                                  mov    $0x6c16,%ecx
  41b927:       6a 00                                           push   $0x0
  41b929:       0f 79 d4                                        vmwrite %rsp,%rdx
  41b92c:       48 8d 05 82 00 00 00                            lea    0x82(%rip),%rax        # 41b9b5 <__vmlaunch+0xa5>
  41b933:       0f 79 c8                                        vmwrite %rax,%rcx
  <xchg GPRs>
  41b9ae:       0f 01 c2                                        vmlaunch
  41b9b1:       48 ff 04 24                                     incq   (%rsp)
  <xchg GPRs>
  41ba2d:       58                                              pop    %rax
  41ba2e:       c3                                              ret
  41ba2f:       90                                              nop
  41ba30:       48 8b 35 39 5d 10 00                            mov    0x105d39(%rip),%rsi        # 521770 <current_evmcs>
  41ba37:       c7 86 38 03 00 00 00 00 00 00                   movl   $0x0,0x338(%rsi)
  41ba41:       6a 00                                           push   $0x0
  41ba43:       48 89 a6 68 02 00 00                            mov    %rsp,0x268(%rsi)
  41ba4a:       48 8d 05 83 00 00 00                            lea    0x83(%rip),%rax        # 41bad4 <__vmlaunch+0x1c4>
  41ba51:       48 89 46 50                                     mov    %rax,0x50(%rsi)
  <xchg GPRs>
  41bacd:       0f 01 c2                                        vmlaunch
  41bad0:       48 ff 04 24                                     incq   (%rsp)
  <xchg GPRs>
  41bb4c:       58                                              pop    %rax
  41bb4d:       c3                                              ret

No functional change intended (though the code generation will be quite
different).

Cc: Yosry Ahmed <yosry@kernel.org>
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
 .../testing/selftests/kvm/include/x86/evmcs.h | 58 -------------------
 tools/testing/selftests/kvm/include/x86/vmx.h | 47 ++-------------
 tools/testing/selftests/kvm/lib/x86/vmx.c     | 55 ++++++++++++++++++
 3 files changed, 60 insertions(+), 100 deletions(-)

diff --git a/tools/testing/selftests/kvm/include/x86/evmcs.h b/tools/testing/selftests/kvm/include/x86/evmcs.h
index f18ebfb10ee0..491fb8107473 100644
--- a/tools/testing/selftests/kvm/include/x86/evmcs.h
+++ b/tools/testing/selftests/kvm/include/x86/evmcs.h
@@ -1187,62 +1187,4 @@ static inline int evmcs_vmwrite(u64 encoding, u64 value)
 	return 0;
 }
 
-static inline int evmcs_vmlaunch(void)
-{
-	int ret;
-
-	current_evmcs->hv_clean_fields = 0;
-
-	__asm__ __volatile__("push $0;"
-			     "mov %%rsp, (%[host_rsp]);"
-			     "lea 1f(%%rip), %%rax;"
-			     "mov %%rax, (%[host_rip]);"
-			     VMX_SWITCH_GPRS_ASM
-			     "vmlaunch;"
-			     "incq (%%rsp);"
-			     "1: ;"
-			     VMX_SWITCH_GPRS_ASM
-			     "pop %%rax;"
-			     : [ret]"=&a"(ret)
-			     : [host_rsp]"r"
-			       ((u64)&current_evmcs->host_rsp),
-			       [host_rip]"r"
-			       ((u64)&current_evmcs->host_rip),
-			       GUEST_REGS_OFFSETS
-			     : "memory", "cc");
-	return ret;
-}
-
-/*
- * No guest state (e.g. GPRs) is established by this vmresume.
- */
-static inline int evmcs_vmresume(void)
-{
-	int ret;
-
-	/* HOST_RIP */
-	current_evmcs->hv_clean_fields &= ~HV_VMX_ENLIGHTENED_CLEAN_FIELD_HOST_GRP1;
-	/* HOST_RSP */
-	current_evmcs->hv_clean_fields &= ~HV_VMX_ENLIGHTENED_CLEAN_FIELD_HOST_POINTER;
-
-	__asm__ __volatile__("push $0;"
-			     "mov %%rsp, (%[host_rsp]);"
-			     "lea 1f(%%rip), %%rax;"
-			     "mov %%rax, (%[host_rip]);"
-			     VMX_SWITCH_GPRS_ASM
-			     "vmresume;"
-			     "incq (%%rsp);"
-			     "1: ;"
-			     VMX_SWITCH_GPRS_ASM
-			     "pop %%rax;"
-			     : [ret]"=&a"(ret)
-			     : [host_rsp]"r"
-			       ((u64)&current_evmcs->host_rsp),
-			       [host_rip]"r"
-			       ((u64)&current_evmcs->host_rip),
-			       GUEST_REGS_OFFSETS
-			     : "memory", "cc");
-	return ret;
-}
-
 #endif /* !SELFTEST_KVM_EVMCS_H */
diff --git a/tools/testing/selftests/kvm/include/x86/vmx.h b/tools/testing/selftests/kvm/include/x86/vmx.h
index 3def8df902a2..d0ac8e128d98 100644
--- a/tools/testing/selftests/kvm/include/x86/vmx.h
+++ b/tools/testing/selftests/kvm/include/x86/vmx.h
@@ -359,54 +359,17 @@ static inline u64 vmptrst(void)
 	return value;
 }
 
+int __vmlaunch(void);
+int __vmresume(void);
+
 static inline int vmlaunch(void)
 {
-	int ret;
-
-	if (enable_evmcs)
-		return evmcs_vmlaunch();
-
-	__asm__ __volatile__("push $0;"
-			     "vmwrite %%rsp, %[host_rsp];"
-			     "lea 1f(%%rip), %%rax;"
-			     "vmwrite %%rax, %[host_rip];"
-			     VMX_SWITCH_GPRS_ASM
-			     "vmlaunch;"
-			     "incq (%%rsp);"
-			     "1: ;"
-			     VMX_SWITCH_GPRS_ASM
-			     "pop %%rax;"
-			     : [ret]"=&a"(ret)
-			     : [host_rsp]"r"((u64)HOST_RSP),
-			       [host_rip]"r"((u64)HOST_RIP),
-			       GUEST_REGS_OFFSETS
-			     : "memory", "cc");
-	return ret;
+	return __vmlaunch();
 }
 
 static inline int vmresume(void)
 {
-	int ret;
-
-	if (enable_evmcs)
-		return evmcs_vmresume();
-
-	__asm__ __volatile__("push $0;"
-			     "vmwrite %%rsp, %[host_rsp];"
-			     "lea 1f(%%rip), %%rax;"
-			     "vmwrite %%rax, %[host_rip];"
-			     VMX_SWITCH_GPRS_ASM
-			     "vmresume;"
-			     "incq (%%rsp);"
-			     "1: ;"
-			     VMX_SWITCH_GPRS_ASM
-			     "pop %%rax;"
-			     : [ret]"=&a"(ret)
-			     : [host_rsp]"r"((u64)HOST_RSP),
-			       [host_rip]"r"((u64)HOST_RIP),
-			       GUEST_REGS_OFFSETS
-			     : "memory", "cc");
-	return ret;
+	return __vmresume();
 }
 
 static inline void vmcall(void)
diff --git a/tools/testing/selftests/kvm/lib/x86/vmx.c b/tools/testing/selftests/kvm/lib/x86/vmx.c
index 5c6cadc08405..1a8515de42b0 100644
--- a/tools/testing/selftests/kvm/lib/x86/vmx.c
+++ b/tools/testing/selftests/kvm/lib/x86/vmx.c
@@ -179,6 +179,61 @@ void load_vmcs(struct vmx_pages *vmx)
 	vmclear(vmx->shadow_vmcs_gpa);
 }
 
+#define __BUILD_VMX_VM_ENTRY_HELPER(insn, prefix, vmwrite_insn, vmwrite_operand,	\
+				    __host_rsp, __host_rip)				\
+static int __##prefix##_##insn(void)							\
+{											\
+	int ret;									\
+											\
+	__asm__ __volatile__("push $0;"							\
+			     __stringify(vmwrite_insn) " %%rsp, %[host_rsp];"		\
+			     "lea 1f(%%rip), %%rax;"					\
+			     __stringify(vmwrite_insn) " %%rax, %[host_rip];"		\
+			     VMX_SWITCH_GPRS_ASM					\
+			     __stringify(insn)";"					\
+			     "incq (%%rsp);"						\
+			     "1: ;"							\
+			     VMX_SWITCH_GPRS_ASM					\
+			     "pop %%rax;"						\
+			     : [ret]"=&a"(ret)						\
+			     : [host_rsp]__stringify(vmwrite_operand)(__host_rsp),	\
+			       [host_rip]__stringify(vmwrite_operand)(__host_rip),	\
+			       GUEST_REGS_OFFSETS					\
+			     : "memory", "cc");						\
+	return ret;									\
+}
+
+#define BUILD_VMX_VM_ENTRY_HELPER(insn) \
+	__BUILD_VMX_VM_ENTRY_HELPER(insn, _, vmwrite, r, (u64)HOST_RSP, (u64)HOST_RIP)	\
+	__BUILD_VMX_VM_ENTRY_HELPER(insn, __evmcs, mov, m,				\
+				    current_evmcs->host_rsp, current_evmcs->host_rip)
+
+BUILD_VMX_VM_ENTRY_HELPER(vmlaunch)
+BUILD_VMX_VM_ENTRY_HELPER(vmresume)
+
+int __vmlaunch(void)
+{
+	if (enable_evmcs) {
+		current_evmcs->hv_clean_fields = 0;
+		return ____evmcs_vmlaunch();
+	}
+
+	return ____vmlaunch();
+}
+
+int __vmresume(void)
+{
+	if (enable_evmcs) {
+		/* HOST_RIP */
+		current_evmcs->hv_clean_fields &= ~HV_VMX_ENLIGHTENED_CLEAN_FIELD_HOST_GRP1;
+		/* HOST_RSP */
+		current_evmcs->hv_clean_fields &= ~HV_VMX_ENLIGHTENED_CLEAN_FIELD_HOST_POINTER;
+		return ____evmcs_vmresume();
+	}
+
+	return ____vmresume();
+}
+
 static bool ept_vpid_cap_supported(u64 mask)
 {
 	return rdmsr(MSR_IA32_VMX_EPT_VPID_CAP) & mask;
-- 
2.55.0.979.g7e5102b832-goog


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v4 14/17] KVM: selftests: Assert success in vmlaunch() and vmresume()
  2026-09-04  0:24 [PATCH v4 00/17] KVM: nVMX: Adjust VMPTRLD/VMPTRST behavior with active eVMCS Sean Christopherson
                   ` (12 preceding siblings ...)
  2026-09-04  0:24 ` [PATCH v4 13/17] KVM: selftests: Dedup assembly code for VMLAUNCH and VMRESUME Sean Christopherson
@ 2026-09-04  0:24 ` Sean Christopherson
  2026-09-04  0:35   ` sashiko-bot
  2026-09-04  0:24 ` [PATCH v4 15/17] KVM: selftests: Add __vmwrite() and use it when initializing optional fields Sean Christopherson
                   ` (2 subsequent siblings)
  16 siblings, 1 reply; 21+ messages in thread
From: Sean Christopherson @ 2026-09-04  0:24 UTC (permalink / raw)
  To: Sean Christopherson, Paolo Bonzini
  Cc: kvm, linux-kernel, f734222792, Vitaly Kuznetsov, Sashiko Bot,
	Yosry Ahmed

Assert success in the "outer" APIs for VMLAUNCH and VMRESUME to dedup a
pile of code, and switch to the double-underscores versions as necessary,
to make it more obvious which paths expect VM-Enter *failure*.

Signed-off-by: Sean Christopherson <seanjc@google.com>
---
 tools/testing/selftests/kvm/include/x86/vmx.h |  8 +++----
 .../testing/selftests/kvm/lib/x86/memstress.c |  2 +-
 .../selftests/kvm/x86/aperfmperf_test.c       |  2 +-
 .../kvm/x86/evmcs_smm_controls_test.c         |  2 +-
 .../testing/selftests/kvm/x86/hyperv_evmcs.c  | 22 ++++++++---------
 .../selftests/kvm/x86/kvm_buslock_test.c      |  2 +-
 .../selftests/kvm/x86/nested_close_kvm_test.c |  2 +-
 .../selftests/kvm/x86/nested_dirty_log_test.c |  2 +-
 .../selftests/kvm/x86/nested_emulation_test.c |  5 +++-
 .../kvm/x86/nested_exceptions_test.c          |  5 +++-
 .../kvm/x86/nested_invalid_cr3_test.c         |  4 ++--
 .../selftests/kvm/x86/nested_tdp_fault_test.c |  2 +-
 .../kvm/x86/nested_tsc_adjust_test.c          |  2 +-
 .../kvm/x86/nested_tsc_scaling_test.c         |  2 +-
 .../kvm/x86/save_restore_pf_stress_test.c     |  4 ++--
 tools/testing/selftests/kvm/x86/state_test.c  | 24 +++++++++----------
 .../kvm/x86/triple_fault_event_test.c         |  2 +-
 .../selftests/kvm/x86/vmx_apic_access_test.c  |  4 ++--
 .../kvm/x86/vmx_apicv_updates_test.c          |  4 ++--
 .../kvm/x86/vmx_invalid_nested_guest_state.c  |  2 +-
 .../kvm/x86/vmx_nested_la57_state_test.c      |  2 +-
 .../kvm/x86/vmx_preemption_timer_test.c       |  4 ++--
 22 files changed, 57 insertions(+), 51 deletions(-)

diff --git a/tools/testing/selftests/kvm/include/x86/vmx.h b/tools/testing/selftests/kvm/include/x86/vmx.h
index d0ac8e128d98..1419043b41dd 100644
--- a/tools/testing/selftests/kvm/include/x86/vmx.h
+++ b/tools/testing/selftests/kvm/include/x86/vmx.h
@@ -362,14 +362,14 @@ static inline u64 vmptrst(void)
 int __vmlaunch(void);
 int __vmresume(void);
 
-static inline int vmlaunch(void)
+static inline void vmlaunch(void)
 {
-	return __vmlaunch();
+	__GUEST_ASSERT(!__vmlaunch(), "vmlaunch hit VM-Fail");
 }
 
-static inline int vmresume(void)
+static inline void vmresume(void)
 {
-	return __vmresume();
+	__GUEST_ASSERT(!__vmresume(), "vmresume hit VM-Fail");
 }
 
 static inline void vmcall(void)
diff --git a/tools/testing/selftests/kvm/lib/x86/memstress.c b/tools/testing/selftests/kvm/lib/x86/memstress.c
index 207350ab6114..6a1815fb97e9 100644
--- a/tools/testing/selftests/kvm/lib/x86/memstress.c
+++ b/tools/testing/selftests/kvm/lib/x86/memstress.c
@@ -40,7 +40,7 @@ static void l1_vmx_code(struct vmx_pages *vmx, u64 vcpu_id)
 	*(u64 *)vmx->stack = vcpu_id;
 	prepare_vmcs(vmx, memstress_l2_guest_entry);
 
-	GUEST_ASSERT(!vmlaunch());
+	vmlaunch();
 	GUEST_ASSERT_EQ(vmreadz(VM_EXIT_REASON), EXIT_REASON_VMCALL);
 	GUEST_DONE();
 }
diff --git a/tools/testing/selftests/kvm/x86/aperfmperf_test.c b/tools/testing/selftests/kvm/x86/aperfmperf_test.c
index 11f5894d8ac7..a082658c1e48 100644
--- a/tools/testing/selftests/kvm/x86/aperfmperf_test.c
+++ b/tools/testing/selftests/kvm/x86/aperfmperf_test.c
@@ -83,7 +83,7 @@ static void l1_vmx_code(struct vmx_pages *vmx)
 		vmreadz(CPU_BASED_VM_EXEC_CONTROL) | CPU_BASED_USE_MSR_BITMAPS);
 
 	GUEST_ASSERT(!vmwrite(GUEST_RIP, (u64)l2_guest_code));
-	GUEST_ASSERT(!vmlaunch());
+	vmlaunch();
 }
 
 static void guest_code(void *nested_test_data)
diff --git a/tools/testing/selftests/kvm/x86/evmcs_smm_controls_test.c b/tools/testing/selftests/kvm/x86/evmcs_smm_controls_test.c
index 5c0391f8a38d..4a65eb02349c 100644
--- a/tools/testing/selftests/kvm/x86/evmcs_smm_controls_test.c
+++ b/tools/testing/selftests/kvm/x86/evmcs_smm_controls_test.c
@@ -59,7 +59,7 @@ static void guest_code(struct vmx_pages *vmx_pages,
 	load_evmcs(hv_pages);
 	prepare_vmcs(vmx_pages, l2_guest_code);
 
-	GUEST_ASSERT(!vmlaunch());
+	vmlaunch();
 
 	/* L2 exits via vmcall if test fails */
 	sync_with_host(2);
diff --git a/tools/testing/selftests/kvm/x86/hyperv_evmcs.c b/tools/testing/selftests/kvm/x86/hyperv_evmcs.c
index 854b86c4be8a..bb31c1aa51bf 100644
--- a/tools/testing/selftests/kvm/x86/hyperv_evmcs.c
+++ b/tools/testing/selftests/kvm/x86/hyperv_evmcs.c
@@ -105,7 +105,7 @@ void guest_code(struct vmx_pages *vmx_pages, struct hyperv_test_pages *hv_pages,
 
 	GUEST_SYNC(5);
 	current_evmcs->revision_id = -1u;
-	GUEST_ASSERT(vmlaunch());
+	GUEST_ASSERT(__vmlaunch());
 	current_evmcs->revision_id = EVMCS_VERSION;
 	GUEST_SYNC(6);
 
@@ -120,7 +120,7 @@ void guest_code(struct vmx_pages *vmx_pages, struct hyperv_test_pages *hv_pages,
 	current_vp_assist->nested_control.features.directhypercall = 1;
 	*(u32 *)(hv_pages->partition_assist) = 0;
 
-	GUEST_ASSERT(!vmlaunch());
+	vmlaunch();
 	GUEST_ASSERT_EQ(vmreadz(VM_EXIT_REASON), EXIT_REASON_EXCEPTION_NMI);
 	GUEST_ASSERT_EQ((vmreadz(VM_EXIT_INTR_INFO) & 0xff), NMI_VECTOR);
 	GUEST_ASSERT(vmptrst() == hv_pages->enlightened_vmcs_gpa);
@@ -130,7 +130,7 @@ void guest_code(struct vmx_pages *vmx_pages, struct hyperv_test_pages *hv_pages,
 	 * up-to-date (RIP points where it should and not at the beginning
 	 * of l2_guest_code(). GUEST_SYNC(9) checks that.
 	 */
-	GUEST_ASSERT(!vmresume());
+	vmresume();
 
 	GUEST_SYNC(10);
 
@@ -141,13 +141,13 @@ void guest_code(struct vmx_pages *vmx_pages, struct hyperv_test_pages *hv_pages,
 	vmwrite(CPU_BASED_VM_EXEC_CONTROL, vmreadz(CPU_BASED_VM_EXEC_CONTROL) |
 		CPU_BASED_USE_MSR_BITMAPS);
 	__set_bit(MSR_FS_BASE & 0x1fff, vmx_pages->msr + 0x400);
-	GUEST_ASSERT(!vmresume());
+	vmresume();
 	GUEST_ASSERT(vmreadz(VM_EXIT_REASON) == EXIT_REASON_MSR_READ);
 	current_evmcs->guest_rip += 2; /* rdmsr */
 
 	/* Enable enlightened MSR bitmap */
 	current_evmcs->hv_enlightenments_control.msr_bitmap = 1;
-	GUEST_ASSERT(!vmresume());
+	vmresume();
 	GUEST_ASSERT(vmreadz(VM_EXIT_REASON) == EXIT_REASON_MSR_READ);
 	current_evmcs->guest_rip += 2; /* rdmsr */
 
@@ -155,14 +155,14 @@ void guest_code(struct vmx_pages *vmx_pages, struct hyperv_test_pages *hv_pages,
 	__set_bit(MSR_GS_BASE & 0x1fff, vmx_pages->msr + 0x400);
 	/* Make sure HV_VMX_ENLIGHTENED_CLEAN_FIELD_MSR_BITMAP is set */
 	current_evmcs->hv_clean_fields |= HV_VMX_ENLIGHTENED_CLEAN_FIELD_MSR_BITMAP;
-	GUEST_ASSERT(!vmresume());
+	vmresume();
 	/* Make sure we don't see EXIT_REASON_MSR_READ here so eMSR bitmap works */
 	GUEST_ASSERT(vmreadz(VM_EXIT_REASON) == EXIT_REASON_VMCALL);
 	current_evmcs->guest_rip += 3; /* vmcall */
 
 	/* Now tell KVM we've changed MSR-Bitmap */
 	current_evmcs->hv_clean_fields &= ~HV_VMX_ENLIGHTENED_CLEAN_FIELD_MSR_BITMAP;
-	GUEST_ASSERT(!vmresume());
+	vmresume();
 	GUEST_ASSERT(vmreadz(VM_EXIT_REASON) == EXIT_REASON_MSR_READ);
 	current_evmcs->guest_rip += 2; /* rdmsr */
 
@@ -170,15 +170,15 @@ void guest_code(struct vmx_pages *vmx_pages, struct hyperv_test_pages *hv_pages,
 	 * L2 TLB flush test. First VMCALL should be handled directly by L0,
 	 * no VMCALL exit expected.
 	 */
-	GUEST_ASSERT(!vmresume());
+	vmresume();
 	GUEST_ASSERT(vmreadz(VM_EXIT_REASON) == EXIT_REASON_MSR_READ);
 	current_evmcs->guest_rip += 2; /* rdmsr */
 	/* Enable synthetic vmexit */
 	*(u32 *)(hv_pages->partition_assist) = 1;
-	GUEST_ASSERT(!vmresume());
+	vmresume();
 	GUEST_ASSERT(vmreadz(VM_EXIT_REASON) == HV_VMX_SYNTHETIC_EXIT_REASON_TRAP_AFTER_FLUSH);
 
-	GUEST_ASSERT(!vmresume());
+	vmresume();
 	GUEST_ASSERT(vmreadz(VM_EXIT_REASON) == EXIT_REASON_VMCALL);
 	GUEST_SYNC(11);
 
@@ -192,7 +192,7 @@ void guest_code(struct vmx_pages *vmx_pages, struct hyperv_test_pages *hv_pages,
 	 */
 	GUEST_SYNC(12);
 	evmcs_vmptrld(0xdeadbeef, hv_pages->enlightened_vmcs);
-	GUEST_ASSERT(vmlaunch());
+	GUEST_ASSERT(__vmlaunch());
 	GUEST_ASSERT(ud_count == 1);
 	GUEST_DONE();
 }
diff --git a/tools/testing/selftests/kvm/x86/kvm_buslock_test.c b/tools/testing/selftests/kvm/x86/kvm_buslock_test.c
index 22993ec697fa..337d3c28bc6d 100644
--- a/tools/testing/selftests/kvm/x86/kvm_buslock_test.c
+++ b/tools/testing/selftests/kvm/x86/kvm_buslock_test.c
@@ -48,7 +48,7 @@ static void l1_vmx_code(struct vmx_pages *vmx)
 	prepare_vmcs(vmx, NULL);
 
 	GUEST_ASSERT(!vmwrite(GUEST_RIP, (u64)l2_guest_code));
-	GUEST_ASSERT(!vmlaunch());
+	vmlaunch();
 }
 
 static void guest_code(void *test_data)
diff --git a/tools/testing/selftests/kvm/x86/nested_close_kvm_test.c b/tools/testing/selftests/kvm/x86/nested_close_kvm_test.c
index 309cab009929..1f4a5e44a6ef 100644
--- a/tools/testing/selftests/kvm/x86/nested_close_kvm_test.c
+++ b/tools/testing/selftests/kvm/x86/nested_close_kvm_test.c
@@ -36,7 +36,7 @@ static void l1_vmx_code(struct vmx_pages *vmx_pages)
 	/* Prepare the VMCS for L2 execution. */
 	prepare_vmcs(vmx_pages, l2_guest_code);
 
-	GUEST_ASSERT(!vmlaunch());
+	vmlaunch();
 	GUEST_ASSERT(0);
 }
 
diff --git a/tools/testing/selftests/kvm/x86/nested_dirty_log_test.c b/tools/testing/selftests/kvm/x86/nested_dirty_log_test.c
index dca2bfc8b158..7987ce50c382 100644
--- a/tools/testing/selftests/kvm/x86/nested_dirty_log_test.c
+++ b/tools/testing/selftests/kvm/x86/nested_dirty_log_test.c
@@ -104,7 +104,7 @@ void l1_vmx_code(struct vmx_pages *vmx)
 	prepare_vmcs(vmx, l2_rip);
 
 	GUEST_SYNC(TEST_SYNC_NO_FAULT);
-	GUEST_ASSERT(!vmlaunch());
+	vmlaunch();
 	GUEST_SYNC(TEST_SYNC_NO_FAULT);
 	GUEST_ASSERT_EQ(vmreadz(VM_EXIT_REASON), EXIT_REASON_VMCALL);
 	GUEST_DONE();
diff --git a/tools/testing/selftests/kvm/x86/nested_emulation_test.c b/tools/testing/selftests/kvm/x86/nested_emulation_test.c
index 2b38eff4f516..51e2f7e386c1 100644
--- a/tools/testing/selftests/kvm/x86/nested_emulation_test.c
+++ b/tools/testing/selftests/kvm/x86/nested_emulation_test.c
@@ -102,7 +102,10 @@ static void guest_code(void *test_data)
 			exit_insn_len = vmcb->control.next_rip - vmcb->save.rip;
 			GUEST_ASSERT_EQ(vmcb->save.rip, (u64)l2_instruction);
 		} else {
-			GUEST_ASSERT_EQ(i ? vmresume() : vmlaunch(), 0);
+			if (!i)
+				vmlaunch();
+			else
+				vmresume();
 			exit_reason = vmreadz(VM_EXIT_REASON);
 			exit_insn_len = vmreadz(VM_EXIT_INSTRUCTION_LEN);
 			GUEST_ASSERT_EQ(vmreadz(GUEST_RIP), (u64)l2_instruction);
diff --git a/tools/testing/selftests/kvm/x86/nested_exceptions_test.c b/tools/testing/selftests/kvm/x86/nested_exceptions_test.c
index 50c271a03692..031eb84229dc 100644
--- a/tools/testing/selftests/kvm/x86/nested_exceptions_test.c
+++ b/tools/testing/selftests/kvm/x86/nested_exceptions_test.c
@@ -112,7 +112,10 @@ static void vmx_run_l2(void *l2_code, int vector, u32 error_code)
 {
 	GUEST_ASSERT(!vmwrite(GUEST_RIP, (u64)l2_code));
 
-	GUEST_ASSERT_EQ(vector == SS_VECTOR ? vmlaunch() : vmresume(), 0);
+	if (vector == SS_VECTOR)
+		vmlaunch();
+	else
+		vmresume();
 
 	if (vector == FAKE_TRIPLE_FAULT_VECTOR)
 		return;
diff --git a/tools/testing/selftests/kvm/x86/nested_invalid_cr3_test.c b/tools/testing/selftests/kvm/x86/nested_invalid_cr3_test.c
index 43deb3b358ea..101c1fe79eeb 100644
--- a/tools/testing/selftests/kvm/x86/nested_invalid_cr3_test.c
+++ b/tools/testing/selftests/kvm/x86/nested_invalid_cr3_test.c
@@ -48,13 +48,13 @@ static void l1_vmx_code(struct vmx_pages *vmx_pages)
 	/* Try to run L2 with invalid CR3 and make sure it fails */
 	save_cr3 = vmreadz(GUEST_CR3);
 	vmwrite(GUEST_CR3, -1ull);
-	GUEST_ASSERT(!vmlaunch());
+	vmlaunch();
 	GUEST_ASSERT(vmreadz(VM_EXIT_REASON) ==
 		     (EXIT_REASON_FAILED_VMENTRY | EXIT_REASON_INVALID_STATE));
 
 	/* Now restore CR3 and make sure L2 runs successfully */
 	vmwrite(GUEST_CR3, save_cr3);
-	GUEST_ASSERT(!vmlaunch());
+	vmlaunch();
 	GUEST_ASSERT(vmreadz(VM_EXIT_REASON) == EXIT_REASON_VMCALL);
 
 	GUEST_DONE();
diff --git a/tools/testing/selftests/kvm/x86/nested_tdp_fault_test.c b/tools/testing/selftests/kvm/x86/nested_tdp_fault_test.c
index 52df467e9c44..d6c443e3d147 100644
--- a/tools/testing/selftests/kvm/x86/nested_tdp_fault_test.c
+++ b/tools/testing/selftests/kvm/x86/nested_tdp_fault_test.c
@@ -60,7 +60,7 @@ static void l1_vmx_code(struct vmx_pages *vmx, u64 expected_fault_gpa,
 
 	prepare_vmcs(vmx, l2_entry);
 
-	GUEST_ASSERT(!vmlaunch());
+	vmlaunch();
 
 	/* Verify we got an EPT violation exit */
 	__GUEST_ASSERT(vmreadz(VM_EXIT_REASON) == EXIT_REASON_EPT_VIOLATION,
diff --git a/tools/testing/selftests/kvm/x86/nested_tsc_adjust_test.c b/tools/testing/selftests/kvm/x86/nested_tsc_adjust_test.c
index 05194762ed33..c60dea899624 100644
--- a/tools/testing/selftests/kvm/x86/nested_tsc_adjust_test.c
+++ b/tools/testing/selftests/kvm/x86/nested_tsc_adjust_test.c
@@ -95,7 +95,7 @@ static void l1_guest_code(void *data)
 		vmwrite(CPU_BASED_VM_EXEC_CONTROL, control);
 		vmwrite(TSC_OFFSET, TSC_OFFSET_VALUE);
 
-		GUEST_ASSERT(!vmlaunch());
+		vmlaunch();
 		GUEST_ASSERT(vmreadz(VM_EXIT_REASON) == EXIT_REASON_VMCALL);
 	} else {
 		struct svm_test_data *svm = data;
diff --git a/tools/testing/selftests/kvm/x86/nested_tsc_scaling_test.c b/tools/testing/selftests/kvm/x86/nested_tsc_scaling_test.c
index b9fae268a9ec..b2fc7f0b5b3c 100644
--- a/tools/testing/selftests/kvm/x86/nested_tsc_scaling_test.c
+++ b/tools/testing/selftests/kvm/x86/nested_tsc_scaling_test.c
@@ -125,7 +125,7 @@ static void l1_vmx_code(struct vmx_pages *vmx_pages)
 	vmwrite(TSC_MULTIPLIER_HIGH, TSC_MULTIPLIER_L2 >> 32);
 
 	/* launch L2 */
-	GUEST_ASSERT(!vmlaunch());
+	vmlaunch();
 	GUEST_ASSERT(vmreadz(VM_EXIT_REASON) == EXIT_REASON_VMCALL);
 
 	/* check that L1's frequency still looks good */
diff --git a/tools/testing/selftests/kvm/x86/save_restore_pf_stress_test.c b/tools/testing/selftests/kvm/x86/save_restore_pf_stress_test.c
index c0e4d6e156ad..f88427e925fc 100644
--- a/tools/testing/selftests/kvm/x86/save_restore_pf_stress_test.c
+++ b/tools/testing/selftests/kvm/x86/save_restore_pf_stress_test.c
@@ -104,11 +104,11 @@ static void l1_vmx_code(struct vmx_pages *vmx)
 
 	GUEST_ASSERT(!vmwrite(EXCEPTION_BITMAP, BIT(UD_VECTOR)));
 
-	GUEST_ASSERT(!vmlaunch());
+	vmlaunch();
 	while (1) {
 		GUEST_ASSERT_EQ(vmreadz(VM_EXIT_REASON), EXIT_REASON_EXCEPTION_NMI);
 		GUEST_ASSERT_EQ(vmreadz(VM_EXIT_INTR_INFO) & 0xff, UD_VECTOR);
-		GUEST_ASSERT(!vmresume());
+		vmresume();
 	}
 }
 
diff --git a/tools/testing/selftests/kvm/x86/state_test.c b/tools/testing/selftests/kvm/x86/state_test.c
index bd5e9e36b2c9..38c9689ac601 100644
--- a/tools/testing/selftests/kvm/x86/state_test.c
+++ b/tools/testing/selftests/kvm/x86/state_test.c
@@ -87,20 +87,20 @@ static void vmx_l1_guest_code(struct vmx_pages *vmx_pages)
 
 	GUEST_SYNC(5);
 	GUEST_ASSERT(vmptrst() == vmx_pages->vmcs_gpa);
-	GUEST_ASSERT(!vmlaunch());
+	vmlaunch();
 	GUEST_ASSERT(vmptrst() == vmx_pages->vmcs_gpa);
 	GUEST_ASSERT(vmreadz(VM_EXIT_REASON) == EXIT_REASON_VMCALL);
 
 	/* Check that the launched state is preserved.  */
-	GUEST_ASSERT(vmlaunch());
+	GUEST_ASSERT(__vmlaunch());
 
-	GUEST_ASSERT(!vmresume());
+	vmresume();
 	GUEST_ASSERT(vmreadz(VM_EXIT_REASON) == EXIT_REASON_VMCALL);
 
 	GUEST_SYNC(7);
 	GUEST_ASSERT(vmreadz(VM_EXIT_REASON) == EXIT_REASON_VMCALL);
 
-	GUEST_ASSERT(!vmresume());
+	vmresume();
 	GUEST_ASSERT(vmreadz(VM_EXIT_REASON) == EXIT_REASON_VMCALL);
 
 	vmwrite(GUEST_RIP, vmreadz(GUEST_RIP) + 3);
@@ -109,27 +109,27 @@ static void vmx_l1_guest_code(struct vmx_pages *vmx_pages)
 	vmwrite(VMCS_LINK_POINTER, vmx_pages->shadow_vmcs_gpa);
 
 	vmptrld(vmx_pages->shadow_vmcs_gpa);
-	GUEST_ASSERT(vmlaunch());
+	GUEST_ASSERT(__vmlaunch());
 	GUEST_SYNC(8);
-	GUEST_ASSERT(vmlaunch());
-	GUEST_ASSERT(vmresume());
+	GUEST_ASSERT(__vmlaunch());
+	GUEST_ASSERT(__vmresume());
 
 	vmwrite(GUEST_RIP, 0xc0ffee);
 	GUEST_SYNC(9);
 	GUEST_ASSERT(vmreadz(GUEST_RIP) == 0xc0ffee);
 
 	vmptrld(vmx_pages->vmcs_gpa);
-	GUEST_ASSERT(!vmresume());
+	vmresume();
 	GUEST_ASSERT(vmreadz(VM_EXIT_REASON) == EXIT_REASON_VMCALL);
 
 	vmptrld(vmx_pages->shadow_vmcs_gpa);
 	GUEST_ASSERT(vmreadz(GUEST_RIP) == 0xc0ffffee);
-	GUEST_ASSERT(vmlaunch());
-	GUEST_ASSERT(vmresume());
+	GUEST_ASSERT(__vmlaunch());
+	GUEST_ASSERT(__vmresume());
 	GUEST_SYNC(13);
 	GUEST_ASSERT(vmreadz(GUEST_RIP) == 0xc0ffffee);
-	GUEST_ASSERT(vmlaunch());
-	GUEST_ASSERT(vmresume());
+	GUEST_ASSERT(__vmlaunch());
+	GUEST_ASSERT(__vmresume());
 }
 
 static void __attribute__((__flatten__)) guest_code(void *arg)
diff --git a/tools/testing/selftests/kvm/x86/triple_fault_event_test.c b/tools/testing/selftests/kvm/x86/triple_fault_event_test.c
index a9fb7046ea4f..bb31a1ba8932 100644
--- a/tools/testing/selftests/kvm/x86/triple_fault_event_test.c
+++ b/tools/testing/selftests/kvm/x86/triple_fault_event_test.c
@@ -30,7 +30,7 @@ void l1_guest_code_vmx(struct vmx_pages *vmx)
 
 	prepare_vmcs(vmx, l2_guest_code);
 
-	GUEST_ASSERT(!vmlaunch());
+	vmlaunch();
 	/* L2 should triple fault after a triple fault event injected. */
 	GUEST_ASSERT(vmreadz(VM_EXIT_REASON) == EXIT_REASON_TRIPLE_FAULT);
 	GUEST_DONE();
diff --git a/tools/testing/selftests/kvm/x86/vmx_apic_access_test.c b/tools/testing/selftests/kvm/x86/vmx_apic_access_test.c
index 1793f7b02219..fe29c869a235 100644
--- a/tools/testing/selftests/kvm/x86/vmx_apic_access_test.c
+++ b/tools/testing/selftests/kvm/x86/vmx_apic_access_test.c
@@ -53,14 +53,14 @@ static void l1_guest_code(struct vmx_pages *vmx_pages, unsigned long high_gpa)
 
 	/* Try to launch L2 with the memory-backed APIC-access address. */
 	GUEST_SYNC(vmreadz(APIC_ACCESS_ADDR));
-	GUEST_ASSERT(!vmlaunch());
+	vmlaunch();
 	GUEST_ASSERT(vmreadz(VM_EXIT_REASON) == EXIT_REASON_VMCALL);
 
 	vmwrite(APIC_ACCESS_ADDR, high_gpa);
 
 	/* Try to resume L2 with the unbacked APIC-access address. */
 	GUEST_SYNC(vmreadz(APIC_ACCESS_ADDR));
-	GUEST_ASSERT(!vmresume());
+	vmresume();
 	GUEST_ASSERT(vmreadz(VM_EXIT_REASON) == EXIT_REASON_VMCALL);
 
 	GUEST_DONE();
diff --git a/tools/testing/selftests/kvm/x86/vmx_apicv_updates_test.c b/tools/testing/selftests/kvm/x86/vmx_apicv_updates_test.c
index f7ebc9b15629..e578221da247 100644
--- a/tools/testing/selftests/kvm/x86/vmx_apicv_updates_test.c
+++ b/tools/testing/selftests/kvm/x86/vmx_apicv_updates_test.c
@@ -62,7 +62,7 @@ static void l1_guest_code(struct vmx_pages *vmx_pages)
 	 * Run L2 to switch to x2APIC mode, which in turn will uninhibit APICv,
 	 * as KVM should force the APIC ID back to its default.
 	 */
-	GUEST_ASSERT(!vmlaunch());
+	vmlaunch();
 	GUEST_ASSERT(vmreadz(VM_EXIT_REASON) == EXIT_REASON_VMCALL);
 	vmwrite(GUEST_RIP, vmreadz(GUEST_RIP) + vmreadz(VM_EXIT_INSTRUCTION_LEN));
 	GUEST_ASSERT(rdmsr(MSR_IA32_APICBASE) & MSR_IA32_APICBASE_EXTD);
@@ -90,7 +90,7 @@ static void l1_guest_code(struct vmx_pages *vmx_pages)
 	 * handles the x2APIC => xAPIC transition and inhibits APICv while L2
 	 * is active.
 	 */
-	GUEST_ASSERT(!vmresume());
+	vmresume();
 	GUEST_ASSERT(vmreadz(VM_EXIT_REASON) == EXIT_REASON_VMCALL);
 	GUEST_ASSERT(!(rdmsr(MSR_IA32_APICBASE) & MSR_IA32_APICBASE_EXTD));
 
diff --git a/tools/testing/selftests/kvm/x86/vmx_invalid_nested_guest_state.c b/tools/testing/selftests/kvm/x86/vmx_invalid_nested_guest_state.c
index 4a6445958cf4..3017938fa993 100644
--- a/tools/testing/selftests/kvm/x86/vmx_invalid_nested_guest_state.c
+++ b/tools/testing/selftests/kvm/x86/vmx_invalid_nested_guest_state.c
@@ -55,7 +55,7 @@ static void l1_guest_code(struct vmx_pages *vmx_pages)
 	GUEST_ASSERT(!(vmreadz(CPU_BASED_VM_EXEC_CONTROL) & CPU_BASED_ACTIVATE_SECONDARY_CONTROLS) ||
 		     !(vmreadz(SECONDARY_VM_EXEC_CONTROL) & SECONDARY_EXEC_UNRESTRICTED_GUEST));
 
-	GUEST_ASSERT(!vmlaunch());
+	vmlaunch();
 
 	/* L2 should triple fault after main() stuffs invalid guest state. */
 	GUEST_ASSERT(vmreadz(VM_EXIT_REASON) == EXIT_REASON_TRIPLE_FAULT);
diff --git a/tools/testing/selftests/kvm/x86/vmx_nested_la57_state_test.c b/tools/testing/selftests/kvm/x86/vmx_nested_la57_state_test.c
index 04c2d5113e84..b3651c5ab138 100644
--- a/tools/testing/selftests/kvm/x86/vmx_nested_la57_state_test.c
+++ b/tools/testing/selftests/kvm/x86/vmx_nested_la57_state_test.c
@@ -56,7 +56,7 @@ static void l1_guest_code(struct vmx_pages *vmx_pages)
 	guest_cr4 &= ~X86_CR4_LA57;
 	vmwrite(GUEST_CR4, guest_cr4);
 
-	GUEST_ASSERT(!vmlaunch());
+	vmlaunch();
 
 	exit_reason = vmreadz(VM_EXIT_REASON);
 	GUEST_ASSERT(exit_reason == EXIT_REASON_VMCALL);
diff --git a/tools/testing/selftests/kvm/x86/vmx_preemption_timer_test.c b/tools/testing/selftests/kvm/x86/vmx_preemption_timer_test.c
index 50fc9309158f..cda53df33888 100644
--- a/tools/testing/selftests/kvm/x86/vmx_preemption_timer_test.c
+++ b/tools/testing/selftests/kvm/x86/vmx_preemption_timer_test.c
@@ -90,7 +90,7 @@ void l1_guest_code(struct vmx_pages *vmx_pages)
 	    !(ctrl_exit_rev.clr & VM_EXIT_SAVE_VMX_PREEMPTION_TIMER))
 		return;
 
-	GUEST_ASSERT(!vmlaunch());
+	vmlaunch();
 	GUEST_ASSERT(vmreadz(VM_EXIT_REASON) == EXIT_REASON_VMCALL);
 	vmwrite(GUEST_RIP, vmreadz(GUEST_RIP) + vmreadz(VM_EXIT_INSTRUCTION_LEN));
 
@@ -110,7 +110,7 @@ void l1_guest_code(struct vmx_pages *vmx_pages)
 
 	l1_vmx_pt_start = (rdtsc() >> vmx_pt_rate) << vmx_pt_rate;
 
-	GUEST_ASSERT(!vmresume());
+	vmresume();
 
 	l1_vmx_pt_finish = rdtsc();
 
-- 
2.55.0.979.g7e5102b832-goog


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v4 15/17] KVM: selftests: Add __vmwrite() and use it when initializing optional fields.
  2026-09-04  0:24 [PATCH v4 00/17] KVM: nVMX: Adjust VMPTRLD/VMPTRST behavior with active eVMCS Sean Christopherson
                   ` (13 preceding siblings ...)
  2026-09-04  0:24 ` [PATCH v4 14/17] KVM: selftests: Assert success in vmlaunch() and vmresume() Sean Christopherson
@ 2026-09-04  0:24 ` Sean Christopherson
  2026-09-04  0:35   ` sashiko-bot
  2026-09-04  0:24 ` [PATCH v4 16/17] KVM: selftests: Always assert that vmwrite() succeeds Sean Christopherson
  2026-09-04  0:24 ` [PATCH v4 17/17] KVM: selftests: Always assert that vmreadz() succeeds Sean Christopherson
  16 siblings, 1 reply; 21+ messages in thread
From: Sean Christopherson @ 2026-09-04  0:24 UTC (permalink / raw)
  To: Sean Christopherson, Paolo Bonzini
  Cc: kvm, linux-kernel, f734222792, Vitaly Kuznetsov, Sashiko Bot,
	Yosry Ahmed

Add __vmwrite() in anticipation of having vmwrite() assert success, and use
the "failure allowed" version in the common VMCS setup code, which is the
only code that wants to write fields that may or may not exist (although
arguably the code should check if the field exists instead of blindly
writing).

E.g. When doing initial configuration of a VMCS, the core library doesn't
want to assume secondary controls are supported, and so blindly does a
VMWRITE and pivots on success/failure.

All usage of vmwrite() outside of common setup already asserts success, or
100% relies on VMWRITE succeeding in order for the test to function
correctly.

No functional change intended.

Signed-off-by: Sean Christopherson <seanjc@google.com>
---
 tools/testing/selftests/kvm/include/x86/vmx.h |  7 ++++++-
 tools/testing/selftests/kvm/lib/x86/vmx.c     | 18 +++++++++---------
 2 files changed, 15 insertions(+), 10 deletions(-)

diff --git a/tools/testing/selftests/kvm/include/x86/vmx.h b/tools/testing/selftests/kvm/include/x86/vmx.h
index 1419043b41dd..40111db580a8 100644
--- a/tools/testing/selftests/kvm/include/x86/vmx.h
+++ b/tools/testing/selftests/kvm/include/x86/vmx.h
@@ -414,7 +414,7 @@ static inline u64 vmreadz(u64 encoding)
 	return value;
 }
 
-static inline int vmwrite(u64 encoding, u64 value)
+static __always_inline int __vmwrite(u64 encoding, u64 value)
 {
 	u8 ret;
 
@@ -429,6 +429,11 @@ static inline int vmwrite(u64 encoding, u64 value)
 	return ret;
 }
 
+static inline int vmwrite(u64 encoding, u64 value)
+{
+	return __vmwrite(encoding, value);
+}
+
 static inline u32 vmcs_revision(void)
 {
 	return rdmsr(MSR_IA32_VMX_BASIC);
diff --git a/tools/testing/selftests/kvm/lib/x86/vmx.c b/tools/testing/selftests/kvm/lib/x86/vmx.c
index 1a8515de42b0..b6bd9423e676 100644
--- a/tools/testing/selftests/kvm/lib/x86/vmx.c
+++ b/tools/testing/selftests/kvm/lib/x86/vmx.c
@@ -252,7 +252,7 @@ static inline void init_vmcs_control_fields(struct vmx_pages *vmx)
 	u32 sec_exec_ctl = 0;
 
 	vmwrite(VIRTUAL_PROCESSOR_ID, 0);
-	vmwrite(POSTED_INTR_NV, 0);
+	__vmwrite(POSTED_INTR_NV, 0);
 
 	vmwrite(PIN_BASED_VM_EXEC_CONTROL, rdmsr(MSR_IA32_VMX_TRUE_PINBASED_CTLS));
 
@@ -269,7 +269,7 @@ static inline void init_vmcs_control_fields(struct vmx_pages *vmx)
 		sec_exec_ctl |= SECONDARY_EXEC_ENABLE_EPT;
 	}
 
-	if (!vmwrite(SECONDARY_VM_EXEC_CONTROL, sec_exec_ctl))
+	if (!__vmwrite(SECONDARY_VM_EXEC_CONTROL, sec_exec_ctl))
 		vmwrite(CPU_BASED_VM_EXEC_CONTROL,
 			rdmsr(MSR_IA32_VMX_TRUE_PROCBASED_CTLS) | CPU_BASED_ACTIVATE_SECONDARY_CONTROLS);
 	else {
@@ -289,16 +289,16 @@ static inline void init_vmcs_control_fields(struct vmx_pages *vmx)
 		VM_ENTRY_IA32E_MODE);		  /* 64-bit guest */
 	vmwrite(VM_ENTRY_MSR_LOAD_COUNT, 0);
 	vmwrite(VM_ENTRY_INTR_INFO_FIELD, 0);
-	vmwrite(TPR_THRESHOLD, 0);
+	__vmwrite(TPR_THRESHOLD, 0);
 
 	vmwrite(CR0_GUEST_HOST_MASK, 0);
 	vmwrite(CR4_GUEST_HOST_MASK, 0);
 	vmwrite(CR0_READ_SHADOW, get_cr0());
 	vmwrite(CR4_READ_SHADOW, get_cr4());
 
-	vmwrite(MSR_BITMAP, vmx->msr_gpa);
-	vmwrite(VMREAD_BITMAP, vmx->vmread_gpa);
-	vmwrite(VMWRITE_BITMAP, vmx->vmwrite_gpa);
+	__vmwrite(MSR_BITMAP, vmx->msr_gpa);
+	__vmwrite(VMREAD_BITMAP, vmx->vmread_gpa);
+	__vmwrite(VMWRITE_BITMAP, vmx->vmwrite_gpa);
 }
 
 /*
@@ -356,8 +356,8 @@ static inline void init_vmcs_guest_state(void *rip, void *rsp)
 	vmwrite(GUEST_GS_SELECTOR, vmreadz(HOST_GS_SELECTOR));
 	vmwrite(GUEST_LDTR_SELECTOR, 0);
 	vmwrite(GUEST_TR_SELECTOR, vmreadz(HOST_TR_SELECTOR));
-	vmwrite(GUEST_INTR_STATUS, 0);
-	vmwrite(GUEST_PML_INDEX, 0);
+	__vmwrite(GUEST_INTR_STATUS, 0);
+	__vmwrite(GUEST_PML_INDEX, 0);
 
 	vmwrite(VMCS_LINK_POINTER, -1ll);
 	vmwrite(GUEST_IA32_DEBUGCTL, 0);
@@ -391,7 +391,7 @@ static inline void init_vmcs_guest_state(void *rip, void *rsp)
 	vmwrite(GUEST_INTERRUPTIBILITY_INFO, 0);
 	vmwrite(GUEST_ACTIVITY_STATE, 0);
 	vmwrite(GUEST_SYSENTER_CS, vmreadz(HOST_IA32_SYSENTER_CS));
-	vmwrite(VMX_PREEMPTION_TIMER_VALUE, 0);
+	__vmwrite(VMX_PREEMPTION_TIMER_VALUE, 0);
 
 	vmwrite(GUEST_CR0, vmreadz(HOST_CR0));
 	vmwrite(GUEST_CR3, vmreadz(HOST_CR3));
-- 
2.55.0.979.g7e5102b832-goog


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v4 16/17] KVM: selftests: Always assert that vmwrite() succeeds
  2026-09-04  0:24 [PATCH v4 00/17] KVM: nVMX: Adjust VMPTRLD/VMPTRST behavior with active eVMCS Sean Christopherson
                   ` (14 preceding siblings ...)
  2026-09-04  0:24 ` [PATCH v4 15/17] KVM: selftests: Add __vmwrite() and use it when initializing optional fields Sean Christopherson
@ 2026-09-04  0:24 ` Sean Christopherson
  2026-09-04  0:24 ` [PATCH v4 17/17] KVM: selftests: Always assert that vmreadz() succeeds Sean Christopherson
  16 siblings, 0 replies; 21+ messages in thread
From: Sean Christopherson @ 2026-09-04  0:24 UTC (permalink / raw)
  To: Sean Christopherson, Paolo Bonzini
  Cc: kvm, linux-kernel, f734222792, Vitaly Kuznetsov, Sashiko Bot,
	Yosry Ahmed

Assert that vmwrite() succeeds instead of forcing all callers to do the
same (or as is much more common, ignoring VM-Fail and likely letting the
test fail in weird ways), opportunistically provide a more verbose error
message on failure.

All usage of vmwrite() "guarantees" success, either because the field in
question is unconditionally emulated by KVM, by virtue of earlier support
checks, or by falling over (later in the test) if the VMWRITE fails.

Cc: Yosry Ahmed <yosry@kernel.org>
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
 tools/testing/selftests/kvm/include/x86/vmx.h          |  5 +++--
 tools/testing/selftests/kvm/x86/aperfmperf_test.c      |  2 +-
 tools/testing/selftests/kvm/x86/kvm_buslock_test.c     |  2 +-
 .../testing/selftests/kvm/x86/nested_emulation_test.c  |  6 +++---
 .../testing/selftests/kvm/x86/nested_exceptions_test.c | 10 +++++-----
 .../selftests/kvm/x86/save_restore_pf_stress_test.c    |  2 +-
 tools/testing/selftests/kvm/x86/state_test.c           |  4 ++--
 .../selftests/kvm/x86/vmx_preemption_timer_test.c      |  8 +++-----
 8 files changed, 19 insertions(+), 20 deletions(-)

diff --git a/tools/testing/selftests/kvm/include/x86/vmx.h b/tools/testing/selftests/kvm/include/x86/vmx.h
index 40111db580a8..be10028c51b9 100644
--- a/tools/testing/selftests/kvm/include/x86/vmx.h
+++ b/tools/testing/selftests/kvm/include/x86/vmx.h
@@ -429,9 +429,10 @@ static __always_inline int __vmwrite(u64 encoding, u64 value)
 	return ret;
 }
 
-static inline int vmwrite(u64 encoding, u64 value)
+static inline void vmwrite(u64 encoding, u64 value)
 {
-	return __vmwrite(encoding, value);
+	__GUEST_ASSERT(!__vmwrite(encoding, value),
+		       "vmwrite[0x%lx] = 0x%lx hit VM-Fail", encoding, value);
 }
 
 static inline u32 vmcs_revision(void)
diff --git a/tools/testing/selftests/kvm/x86/aperfmperf_test.c b/tools/testing/selftests/kvm/x86/aperfmperf_test.c
index a082658c1e48..7761a8bdf5f6 100644
--- a/tools/testing/selftests/kvm/x86/aperfmperf_test.c
+++ b/tools/testing/selftests/kvm/x86/aperfmperf_test.c
@@ -82,7 +82,7 @@ static void l1_vmx_code(struct vmx_pages *vmx)
 	vmwrite(CPU_BASED_VM_EXEC_CONTROL,
 		vmreadz(CPU_BASED_VM_EXEC_CONTROL) | CPU_BASED_USE_MSR_BITMAPS);
 
-	GUEST_ASSERT(!vmwrite(GUEST_RIP, (u64)l2_guest_code));
+	vmwrite(GUEST_RIP, (u64)l2_guest_code);
 	vmlaunch();
 }
 
diff --git a/tools/testing/selftests/kvm/x86/kvm_buslock_test.c b/tools/testing/selftests/kvm/x86/kvm_buslock_test.c
index 337d3c28bc6d..e1d2730b16ba 100644
--- a/tools/testing/selftests/kvm/x86/kvm_buslock_test.c
+++ b/tools/testing/selftests/kvm/x86/kvm_buslock_test.c
@@ -47,7 +47,7 @@ static void l1_vmx_code(struct vmx_pages *vmx)
 
 	prepare_vmcs(vmx, NULL);
 
-	GUEST_ASSERT(!vmwrite(GUEST_RIP, (u64)l2_guest_code));
+	vmwrite(GUEST_RIP, (u64)l2_guest_code);
 	vmlaunch();
 }
 
diff --git a/tools/testing/selftests/kvm/x86/nested_emulation_test.c b/tools/testing/selftests/kvm/x86/nested_emulation_test.c
index 51e2f7e386c1..009932b1604e 100644
--- a/tools/testing/selftests/kvm/x86/nested_emulation_test.c
+++ b/tools/testing/selftests/kvm/x86/nested_emulation_test.c
@@ -70,9 +70,9 @@ static void guest_code(void *test_data)
 		load_vmcs(test_data);
 
 		prepare_vmcs(test_data, NULL);
-		GUEST_ASSERT(!vmwrite(GUEST_IDTR_LIMIT, 0));
-		GUEST_ASSERT(!vmwrite(GUEST_RIP, (u64)l2_guest_code));
-		GUEST_ASSERT(!vmwrite(EXCEPTION_BITMAP, 0));
+		vmwrite(GUEST_IDTR_LIMIT, 0);
+		vmwrite(GUEST_RIP, (u64)l2_guest_code);
+		vmwrite(EXCEPTION_BITMAP, 0);
 
 		vmwrite(CPU_BASED_VM_EXEC_CONTROL, vmreadz(CPU_BASED_VM_EXEC_CONTROL) |
 						   CPU_BASED_PAUSE_EXITING |
diff --git a/tools/testing/selftests/kvm/x86/nested_exceptions_test.c b/tools/testing/selftests/kvm/x86/nested_exceptions_test.c
index 031eb84229dc..d0beaa7b280b 100644
--- a/tools/testing/selftests/kvm/x86/nested_exceptions_test.c
+++ b/tools/testing/selftests/kvm/x86/nested_exceptions_test.c
@@ -110,7 +110,7 @@ static void l1_svm_code(struct svm_test_data *svm)
 
 static void vmx_run_l2(void *l2_code, int vector, u32 error_code)
 {
-	GUEST_ASSERT(!vmwrite(GUEST_RIP, (u64)l2_code));
+	vmwrite(GUEST_RIP, (u64)l2_code);
 
 	if (vector == SS_VECTOR)
 		vmlaunch();
@@ -133,21 +133,21 @@ static void l1_vmx_code(struct vmx_pages *vmx)
 	load_vmcs(vmx);
 
 	prepare_vmcs(vmx, NULL);
-	GUEST_ASSERT_EQ(vmwrite(GUEST_IDTR_LIMIT, 0), 0);
+	vmwrite(GUEST_IDTR_LIMIT, 0);
 
 	/*
 	 * VMX disallows injecting an exception with error_code[31:16] != 0,
 	 * and hardware will never generate a VM-Exit with bits 31:16 set.
 	 * KVM should likewise truncate the "bad" userspace value.
 	 */
-	GUEST_ASSERT_EQ(vmwrite(EXCEPTION_BITMAP, INTERCEPT_SS_GP_DF), 0);
+	vmwrite(EXCEPTION_BITMAP, INTERCEPT_SS_GP_DF);
 	vmx_run_l2(l2_ss_pending_test, SS_VECTOR, (u16)SS_ERROR_CODE);
 	vmx_run_l2(l2_ss_injected_gp_test, GP_VECTOR, GP_ERROR_CODE_INTEL);
 
-	GUEST_ASSERT_EQ(vmwrite(EXCEPTION_BITMAP, INTERCEPT_SS_DF), 0);
+	vmwrite(EXCEPTION_BITMAP, INTERCEPT_SS_DF);
 	vmx_run_l2(l2_ss_injected_df_test, DF_VECTOR, DF_ERROR_CODE);
 
-	GUEST_ASSERT_EQ(vmwrite(EXCEPTION_BITMAP, INTERCEPT_SS), 0);
+	vmwrite(EXCEPTION_BITMAP, INTERCEPT_SS);
 	vmx_run_l2(l2_ss_injected_tf_test, FAKE_TRIPLE_FAULT_VECTOR, 0);
 	GUEST_ASSERT_EQ(vmreadz(VM_EXIT_REASON), EXIT_REASON_TRIPLE_FAULT);
 
diff --git a/tools/testing/selftests/kvm/x86/save_restore_pf_stress_test.c b/tools/testing/selftests/kvm/x86/save_restore_pf_stress_test.c
index f88427e925fc..e728f040916f 100644
--- a/tools/testing/selftests/kvm/x86/save_restore_pf_stress_test.c
+++ b/tools/testing/selftests/kvm/x86/save_restore_pf_stress_test.c
@@ -102,7 +102,7 @@ static void l1_vmx_code(struct vmx_pages *vmx)
 	load_vmcs(vmx);
 	prepare_vmcs(vmx, guest_access_memory);
 
-	GUEST_ASSERT(!vmwrite(EXCEPTION_BITMAP, BIT(UD_VECTOR)));
+	vmwrite(EXCEPTION_BITMAP, BIT(UD_VECTOR));
 
 	vmlaunch();
 	while (1) {
diff --git a/tools/testing/selftests/kvm/x86/state_test.c b/tools/testing/selftests/kvm/x86/state_test.c
index 38c9689ac601..7cb1d160e2d9 100644
--- a/tools/testing/selftests/kvm/x86/state_test.c
+++ b/tools/testing/selftests/kvm/x86/state_test.c
@@ -62,10 +62,10 @@ void vmx_l2_guest_code(void)
 	GUEST_ASSERT(vmreadz(GUEST_RIP) == 0xc0ffee);
 	GUEST_SYNC(10);
 	GUEST_ASSERT(vmreadz(GUEST_RIP) == 0xc0ffee);
-	GUEST_ASSERT(!vmwrite(GUEST_RIP, 0xc0fffee));
+	vmwrite(GUEST_RIP, 0xc0fffee);
 	GUEST_SYNC(11);
 	GUEST_ASSERT(vmreadz(GUEST_RIP) == 0xc0fffee);
-	GUEST_ASSERT(!vmwrite(GUEST_RIP, 0xc0ffffee));
+	vmwrite(GUEST_RIP, 0xc0ffffee);
 	GUEST_SYNC(12);
 
 	/* Done, exit to L1 and never come back.  */
diff --git a/tools/testing/selftests/kvm/x86/vmx_preemption_timer_test.c b/tools/testing/selftests/kvm/x86/vmx_preemption_timer_test.c
index cda53df33888..c5f9d9879f61 100644
--- a/tools/testing/selftests/kvm/x86/vmx_preemption_timer_test.c
+++ b/tools/testing/selftests/kvm/x86/vmx_preemption_timer_test.c
@@ -97,12 +97,10 @@ void l1_guest_code(struct vmx_pages *vmx_pages)
 	/*
 	 * Turn on PIN control and resume the guest
 	 */
-	GUEST_ASSERT(!vmwrite(PIN_BASED_VM_EXEC_CONTROL,
-			      vmreadz(PIN_BASED_VM_EXEC_CONTROL) |
-			      PIN_BASED_VMX_PREEMPTION_TIMER));
+	vmwrite(PIN_BASED_VM_EXEC_CONTROL,
+		vmreadz(PIN_BASED_VM_EXEC_CONTROL) | PIN_BASED_VMX_PREEMPTION_TIMER);
 
-	GUEST_ASSERT(!vmwrite(VMX_PREEMPTION_TIMER_VALUE,
-			      PREEMPTION_TIMER_VALUE));
+	vmwrite(VMX_PREEMPTION_TIMER_VALUE, PREEMPTION_TIMER_VALUE);
 
 	vmx_pt_rate = rdmsr(MSR_IA32_VMX_MISC) & 0x1F;
 
-- 
2.55.0.979.g7e5102b832-goog


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v4 17/17] KVM: selftests: Always assert that vmreadz() succeeds
  2026-09-04  0:24 [PATCH v4 00/17] KVM: nVMX: Adjust VMPTRLD/VMPTRST behavior with active eVMCS Sean Christopherson
                   ` (15 preceding siblings ...)
  2026-09-04  0:24 ` [PATCH v4 16/17] KVM: selftests: Always assert that vmwrite() succeeds Sean Christopherson
@ 2026-09-04  0:24 ` Sean Christopherson
  2026-09-04  0:36   ` sashiko-bot
  16 siblings, 1 reply; 21+ messages in thread
From: Sean Christopherson @ 2026-09-04  0:24 UTC (permalink / raw)
  To: Sean Christopherson, Paolo Bonzini
  Cc: kvm, linux-kernel, f734222792, Vitaly Kuznetsov, Sashiko Bot,
	Yosry Ahmed

Rename vmreadz() => vmread() (and vmread() => __vmread()) and have it
assert success instead of returning garbage on failure.  While the eVMCS
path avoids clobbering *value on failure, the VMREAD path unconditionally
stores tmp to *value, without ever zeroing tmp.  I.e. if VMREAD did fail,
*value would be loaded with random stack data, not '0'.

An audit of the code confirms that nothing is actually relying on vmreadz()
to zero the result on failure, as all paths either check for a non-zero
value, propagate the result into vmwrite(), or guard the vmread() with a
pre-check that the field exists.

Opportunistically fix the bug in what is now __vmread(), so that the code
isn't consuming uninitialized stack data.  Begrudgingly keep zeroing
value in vmread(), as gcc-15 at least isn't smart enough to figure out
that value won't be used uninitialized (though to be fair, strictly
speaking it isn't actually unreachable code).

Signed-off-by: Sean Christopherson <seanjc@google.com>
---
 tools/testing/selftests/kvm/include/x86/vmx.h | 15 +++---
 .../testing/selftests/kvm/lib/x86/memstress.c |  2 +-
 tools/testing/selftests/kvm/lib/x86/vmx.c     | 52 +++++++++----------
 .../selftests/kvm/x86/aperfmperf_test.c       |  2 +-
 .../testing/selftests/kvm/x86/hyperv_evmcs.c  | 24 ++++-----
 .../selftests/kvm/x86/nested_dirty_log_test.c |  2 +-
 .../selftests/kvm/x86/nested_emulation_test.c |  8 +--
 .../kvm/x86/nested_exceptions_test.c          | 10 ++--
 .../kvm/x86/nested_invalid_cr3_test.c         |  6 +--
 .../selftests/kvm/x86/nested_tdp_fault_test.c | 10 ++--
 .../kvm/x86/nested_tsc_adjust_test.c          |  4 +-
 .../kvm/x86/nested_tsc_scaling_test.c         |  6 +--
 .../kvm/x86/save_restore_pf_stress_test.c     |  4 +-
 tools/testing/selftests/kvm/x86/state_test.c  | 24 ++++-----
 .../kvm/x86/triple_fault_event_test.c         |  2 +-
 .../selftests/kvm/x86/vmx_apic_access_test.c  | 12 ++---
 .../kvm/x86/vmx_apicv_updates_test.c          |  8 +--
 .../kvm/x86/vmx_invalid_nested_guest_state.c  |  6 +--
 .../kvm/x86/vmx_nested_la57_state_test.c      |  4 +-
 .../kvm/x86/vmx_preemption_timer_test.c       |  8 +--
 20 files changed, 104 insertions(+), 105 deletions(-)

diff --git a/tools/testing/selftests/kvm/include/x86/vmx.h b/tools/testing/selftests/kvm/include/x86/vmx.h
index be10028c51b9..a4807e41fe69 100644
--- a/tools/testing/selftests/kvm/include/x86/vmx.h
+++ b/tools/testing/selftests/kvm/include/x86/vmx.h
@@ -386,7 +386,7 @@ static inline void vmcall(void)
 			       "r10", "r11", "r12", "r13", "r14", "r15");
 }
 
-static inline int vmread(u64 encoding, u64 *value)
+static inline int __vmread(u64 encoding, u64 *value)
 {
 	u64 tmp;
 	u8 ret;
@@ -399,18 +399,17 @@ static inline int vmread(u64 encoding, u64 *value)
 		: [encoding]"r"(encoding)
 		: "cc", "memory");
 
-	*value = tmp;
+	if (!ret)
+		*value = tmp;
 	return ret;
 }
 
-/*
- * A wrapper around vmread that ignores errors and returns zero if the
- * vmread instruction fails.
- */
-static inline u64 vmreadz(u64 encoding)
+static inline u64 vmread(u64 encoding)
 {
 	u64 value = 0;
-	vmread(encoding, &value);
+
+	__GUEST_ASSERT(!__vmread(encoding, &value),
+		       "vmwread[0x%lx] hit VM-Fail", encoding);
 	return value;
 }
 
diff --git a/tools/testing/selftests/kvm/lib/x86/memstress.c b/tools/testing/selftests/kvm/lib/x86/memstress.c
index 6a1815fb97e9..9bfea36144a7 100644
--- a/tools/testing/selftests/kvm/lib/x86/memstress.c
+++ b/tools/testing/selftests/kvm/lib/x86/memstress.c
@@ -41,7 +41,7 @@ static void l1_vmx_code(struct vmx_pages *vmx, u64 vcpu_id)
 	prepare_vmcs(vmx, memstress_l2_guest_entry);
 
 	vmlaunch();
-	GUEST_ASSERT_EQ(vmreadz(VM_EXIT_REASON), EXIT_REASON_VMCALL);
+	GUEST_ASSERT_EQ(vmread(VM_EXIT_REASON), EXIT_REASON_VMCALL);
 	GUEST_DONE();
 }
 
diff --git a/tools/testing/selftests/kvm/lib/x86/vmx.c b/tools/testing/selftests/kvm/lib/x86/vmx.c
index b6bd9423e676..9c752739c6c7 100644
--- a/tools/testing/selftests/kvm/lib/x86/vmx.c
+++ b/tools/testing/selftests/kvm/lib/x86/vmx.c
@@ -308,7 +308,7 @@ static inline void init_vmcs_control_fields(struct vmx_pages *vmx)
  */
 static inline void init_vmcs_host_state(void)
 {
-	u32 exit_controls = vmreadz(VM_EXIT_CONTROLS);
+	u32 exit_controls = vmread(VM_EXIT_CONTROLS);
 
 	vmwrite(HOST_ES_SELECTOR, get_es());
 	vmwrite(HOST_CS_SELECTOR, get_cs());
@@ -348,23 +348,23 @@ static inline void init_vmcs_host_state(void)
  */
 static inline void init_vmcs_guest_state(void *rip, void *rsp)
 {
-	vmwrite(GUEST_ES_SELECTOR, vmreadz(HOST_ES_SELECTOR));
-	vmwrite(GUEST_CS_SELECTOR, vmreadz(HOST_CS_SELECTOR));
-	vmwrite(GUEST_SS_SELECTOR, vmreadz(HOST_SS_SELECTOR));
-	vmwrite(GUEST_DS_SELECTOR, vmreadz(HOST_DS_SELECTOR));
-	vmwrite(GUEST_FS_SELECTOR, vmreadz(HOST_FS_SELECTOR));
-	vmwrite(GUEST_GS_SELECTOR, vmreadz(HOST_GS_SELECTOR));
+	vmwrite(GUEST_ES_SELECTOR, vmread(HOST_ES_SELECTOR));
+	vmwrite(GUEST_CS_SELECTOR, vmread(HOST_CS_SELECTOR));
+	vmwrite(GUEST_SS_SELECTOR, vmread(HOST_SS_SELECTOR));
+	vmwrite(GUEST_DS_SELECTOR, vmread(HOST_DS_SELECTOR));
+	vmwrite(GUEST_FS_SELECTOR, vmread(HOST_FS_SELECTOR));
+	vmwrite(GUEST_GS_SELECTOR, vmread(HOST_GS_SELECTOR));
 	vmwrite(GUEST_LDTR_SELECTOR, 0);
-	vmwrite(GUEST_TR_SELECTOR, vmreadz(HOST_TR_SELECTOR));
+	vmwrite(GUEST_TR_SELECTOR, vmread(HOST_TR_SELECTOR));
 	__vmwrite(GUEST_INTR_STATUS, 0);
 	__vmwrite(GUEST_PML_INDEX, 0);
 
 	vmwrite(VMCS_LINK_POINTER, -1ll);
 	vmwrite(GUEST_IA32_DEBUGCTL, 0);
-	vmwrite(GUEST_IA32_PAT, vmreadz(HOST_IA32_PAT));
-	vmwrite(GUEST_IA32_EFER, vmreadz(HOST_IA32_EFER));
+	vmwrite(GUEST_IA32_PAT, vmread(HOST_IA32_PAT));
+	vmwrite(GUEST_IA32_EFER, vmread(HOST_IA32_EFER));
 	vmwrite(GUEST_IA32_PERF_GLOBAL_CTRL,
-		vmreadz(HOST_IA32_PERF_GLOBAL_CTRL));
+		vmread(HOST_IA32_PERF_GLOBAL_CTRL));
 
 	vmwrite(GUEST_ES_LIMIT, -1);
 	vmwrite(GUEST_CS_LIMIT, -1);
@@ -377,42 +377,42 @@ static inline void init_vmcs_guest_state(void *rip, void *rsp)
 	vmwrite(GUEST_GDTR_LIMIT, 0xffff);
 	vmwrite(GUEST_IDTR_LIMIT, 0xffff);
 	vmwrite(GUEST_ES_AR_BYTES,
-		vmreadz(GUEST_ES_SELECTOR) == 0 ? 0x10000 : 0xc093);
+		vmread(GUEST_ES_SELECTOR) == 0 ? 0x10000 : 0xc093);
 	vmwrite(GUEST_CS_AR_BYTES, 0xa09b);
 	vmwrite(GUEST_SS_AR_BYTES, 0xc093);
 	vmwrite(GUEST_DS_AR_BYTES,
-		vmreadz(GUEST_DS_SELECTOR) == 0 ? 0x10000 : 0xc093);
+		vmread(GUEST_DS_SELECTOR) == 0 ? 0x10000 : 0xc093);
 	vmwrite(GUEST_FS_AR_BYTES,
-		vmreadz(GUEST_FS_SELECTOR) == 0 ? 0x10000 : 0xc093);
+		vmread(GUEST_FS_SELECTOR) == 0 ? 0x10000 : 0xc093);
 	vmwrite(GUEST_GS_AR_BYTES,
-		vmreadz(GUEST_GS_SELECTOR) == 0 ? 0x10000 : 0xc093);
+		vmread(GUEST_GS_SELECTOR) == 0 ? 0x10000 : 0xc093);
 	vmwrite(GUEST_LDTR_AR_BYTES, 0x10000);
 	vmwrite(GUEST_TR_AR_BYTES, 0x8b);
 	vmwrite(GUEST_INTERRUPTIBILITY_INFO, 0);
 	vmwrite(GUEST_ACTIVITY_STATE, 0);
-	vmwrite(GUEST_SYSENTER_CS, vmreadz(HOST_IA32_SYSENTER_CS));
+	vmwrite(GUEST_SYSENTER_CS, vmread(HOST_IA32_SYSENTER_CS));
 	__vmwrite(VMX_PREEMPTION_TIMER_VALUE, 0);
 
-	vmwrite(GUEST_CR0, vmreadz(HOST_CR0));
-	vmwrite(GUEST_CR3, vmreadz(HOST_CR3));
-	vmwrite(GUEST_CR4, vmreadz(HOST_CR4));
+	vmwrite(GUEST_CR0, vmread(HOST_CR0));
+	vmwrite(GUEST_CR3, vmread(HOST_CR3));
+	vmwrite(GUEST_CR4, vmread(HOST_CR4));
 	vmwrite(GUEST_ES_BASE, 0);
 	vmwrite(GUEST_CS_BASE, 0);
 	vmwrite(GUEST_SS_BASE, 0);
 	vmwrite(GUEST_DS_BASE, 0);
-	vmwrite(GUEST_FS_BASE, vmreadz(HOST_FS_BASE));
-	vmwrite(GUEST_GS_BASE, vmreadz(HOST_GS_BASE));
+	vmwrite(GUEST_FS_BASE, vmread(HOST_FS_BASE));
+	vmwrite(GUEST_GS_BASE, vmread(HOST_GS_BASE));
 	vmwrite(GUEST_LDTR_BASE, 0);
-	vmwrite(GUEST_TR_BASE, vmreadz(HOST_TR_BASE));
-	vmwrite(GUEST_GDTR_BASE, vmreadz(HOST_GDTR_BASE));
-	vmwrite(GUEST_IDTR_BASE, vmreadz(HOST_IDTR_BASE));
+	vmwrite(GUEST_TR_BASE, vmread(HOST_TR_BASE));
+	vmwrite(GUEST_GDTR_BASE, vmread(HOST_GDTR_BASE));
+	vmwrite(GUEST_IDTR_BASE, vmread(HOST_IDTR_BASE));
 	vmwrite(GUEST_DR7, 0x400);
 	vmwrite(GUEST_RSP, (u64)rsp);
 	vmwrite(GUEST_RIP, (u64)rip);
 	vmwrite(GUEST_RFLAGS, X86_EFLAGS_FIXED);
 	vmwrite(GUEST_PENDING_DBG_EXCEPTIONS, 0);
-	vmwrite(GUEST_SYSENTER_ESP, vmreadz(HOST_IA32_SYSENTER_ESP));
-	vmwrite(GUEST_SYSENTER_EIP, vmreadz(HOST_IA32_SYSENTER_EIP));
+	vmwrite(GUEST_SYSENTER_ESP, vmread(HOST_IA32_SYSENTER_ESP));
+	vmwrite(GUEST_SYSENTER_EIP, vmread(HOST_IA32_SYSENTER_EIP));
 }
 
 void prepare_vmcs(struct vmx_pages *vmx, void *guest_rip)
diff --git a/tools/testing/selftests/kvm/x86/aperfmperf_test.c b/tools/testing/selftests/kvm/x86/aperfmperf_test.c
index 7761a8bdf5f6..1ca6495a446f 100644
--- a/tools/testing/selftests/kvm/x86/aperfmperf_test.c
+++ b/tools/testing/selftests/kvm/x86/aperfmperf_test.c
@@ -80,7 +80,7 @@ static void l1_vmx_code(struct vmx_pages *vmx)
 	 * in the VMCS by prepare_vmcs()), as MSR exiting mandatory on Intel.
 	 */
 	vmwrite(CPU_BASED_VM_EXEC_CONTROL,
-		vmreadz(CPU_BASED_VM_EXEC_CONTROL) | CPU_BASED_USE_MSR_BITMAPS);
+		vmread(CPU_BASED_VM_EXEC_CONTROL) | CPU_BASED_USE_MSR_BITMAPS);
 
 	vmwrite(GUEST_RIP, (u64)l2_guest_code);
 	vmlaunch();
diff --git a/tools/testing/selftests/kvm/x86/hyperv_evmcs.c b/tools/testing/selftests/kvm/x86/hyperv_evmcs.c
index bb31c1aa51bf..32c5de890ba7 100644
--- a/tools/testing/selftests/kvm/x86/hyperv_evmcs.c
+++ b/tools/testing/selftests/kvm/x86/hyperv_evmcs.c
@@ -109,7 +109,7 @@ void guest_code(struct vmx_pages *vmx_pages, struct hyperv_test_pages *hv_pages,
 	current_evmcs->revision_id = EVMCS_VERSION;
 	GUEST_SYNC(6);
 
-	vmwrite(PIN_BASED_VM_EXEC_CONTROL, vmreadz(PIN_BASED_VM_EXEC_CONTROL) |
+	vmwrite(PIN_BASED_VM_EXEC_CONTROL, vmread(PIN_BASED_VM_EXEC_CONTROL) |
 		PIN_BASED_NMI_EXITING);
 
 	/* L2 TLB flush setup */
@@ -121,8 +121,8 @@ void guest_code(struct vmx_pages *vmx_pages, struct hyperv_test_pages *hv_pages,
 	*(u32 *)(hv_pages->partition_assist) = 0;
 
 	vmlaunch();
-	GUEST_ASSERT_EQ(vmreadz(VM_EXIT_REASON), EXIT_REASON_EXCEPTION_NMI);
-	GUEST_ASSERT_EQ((vmreadz(VM_EXIT_INTR_INFO) & 0xff), NMI_VECTOR);
+	GUEST_ASSERT_EQ(vmread(VM_EXIT_REASON), EXIT_REASON_EXCEPTION_NMI);
+	GUEST_ASSERT_EQ((vmread(VM_EXIT_INTR_INFO) & 0xff), NMI_VECTOR);
 	GUEST_ASSERT(vmptrst() == hv_pages->enlightened_vmcs_gpa);
 
 	/*
@@ -134,21 +134,21 @@ void guest_code(struct vmx_pages *vmx_pages, struct hyperv_test_pages *hv_pages,
 
 	GUEST_SYNC(10);
 
-	GUEST_ASSERT(vmreadz(VM_EXIT_REASON) == EXIT_REASON_VMCALL);
+	GUEST_ASSERT(vmread(VM_EXIT_REASON) == EXIT_REASON_VMCALL);
 	current_evmcs->guest_rip += 3; /* vmcall */
 
 	/* Intercept RDMSR 0xc0000100 */
-	vmwrite(CPU_BASED_VM_EXEC_CONTROL, vmreadz(CPU_BASED_VM_EXEC_CONTROL) |
+	vmwrite(CPU_BASED_VM_EXEC_CONTROL, vmread(CPU_BASED_VM_EXEC_CONTROL) |
 		CPU_BASED_USE_MSR_BITMAPS);
 	__set_bit(MSR_FS_BASE & 0x1fff, vmx_pages->msr + 0x400);
 	vmresume();
-	GUEST_ASSERT(vmreadz(VM_EXIT_REASON) == EXIT_REASON_MSR_READ);
+	GUEST_ASSERT(vmread(VM_EXIT_REASON) == EXIT_REASON_MSR_READ);
 	current_evmcs->guest_rip += 2; /* rdmsr */
 
 	/* Enable enlightened MSR bitmap */
 	current_evmcs->hv_enlightenments_control.msr_bitmap = 1;
 	vmresume();
-	GUEST_ASSERT(vmreadz(VM_EXIT_REASON) == EXIT_REASON_MSR_READ);
+	GUEST_ASSERT(vmread(VM_EXIT_REASON) == EXIT_REASON_MSR_READ);
 	current_evmcs->guest_rip += 2; /* rdmsr */
 
 	/* Intercept RDMSR 0xc0000101 without telling KVM about it */
@@ -157,13 +157,13 @@ void guest_code(struct vmx_pages *vmx_pages, struct hyperv_test_pages *hv_pages,
 	current_evmcs->hv_clean_fields |= HV_VMX_ENLIGHTENED_CLEAN_FIELD_MSR_BITMAP;
 	vmresume();
 	/* Make sure we don't see EXIT_REASON_MSR_READ here so eMSR bitmap works */
-	GUEST_ASSERT(vmreadz(VM_EXIT_REASON) == EXIT_REASON_VMCALL);
+	GUEST_ASSERT(vmread(VM_EXIT_REASON) == EXIT_REASON_VMCALL);
 	current_evmcs->guest_rip += 3; /* vmcall */
 
 	/* Now tell KVM we've changed MSR-Bitmap */
 	current_evmcs->hv_clean_fields &= ~HV_VMX_ENLIGHTENED_CLEAN_FIELD_MSR_BITMAP;
 	vmresume();
-	GUEST_ASSERT(vmreadz(VM_EXIT_REASON) == EXIT_REASON_MSR_READ);
+	GUEST_ASSERT(vmread(VM_EXIT_REASON) == EXIT_REASON_MSR_READ);
 	current_evmcs->guest_rip += 2; /* rdmsr */
 
 	/*
@@ -171,15 +171,15 @@ void guest_code(struct vmx_pages *vmx_pages, struct hyperv_test_pages *hv_pages,
 	 * no VMCALL exit expected.
 	 */
 	vmresume();
-	GUEST_ASSERT(vmreadz(VM_EXIT_REASON) == EXIT_REASON_MSR_READ);
+	GUEST_ASSERT(vmread(VM_EXIT_REASON) == EXIT_REASON_MSR_READ);
 	current_evmcs->guest_rip += 2; /* rdmsr */
 	/* Enable synthetic vmexit */
 	*(u32 *)(hv_pages->partition_assist) = 1;
 	vmresume();
-	GUEST_ASSERT(vmreadz(VM_EXIT_REASON) == HV_VMX_SYNTHETIC_EXIT_REASON_TRAP_AFTER_FLUSH);
+	GUEST_ASSERT(vmread(VM_EXIT_REASON) == HV_VMX_SYNTHETIC_EXIT_REASON_TRAP_AFTER_FLUSH);
 
 	vmresume();
-	GUEST_ASSERT(vmreadz(VM_EXIT_REASON) == EXIT_REASON_VMCALL);
+	GUEST_ASSERT(vmread(VM_EXIT_REASON) == EXIT_REASON_VMCALL);
 	GUEST_SYNC(11);
 
 	/* VMPTRLD instruction causes #UD after enlightened VMLAUNCH */
diff --git a/tools/testing/selftests/kvm/x86/nested_dirty_log_test.c b/tools/testing/selftests/kvm/x86/nested_dirty_log_test.c
index 7987ce50c382..7e5f9ae1cb00 100644
--- a/tools/testing/selftests/kvm/x86/nested_dirty_log_test.c
+++ b/tools/testing/selftests/kvm/x86/nested_dirty_log_test.c
@@ -106,7 +106,7 @@ void l1_vmx_code(struct vmx_pages *vmx)
 	GUEST_SYNC(TEST_SYNC_NO_FAULT);
 	vmlaunch();
 	GUEST_SYNC(TEST_SYNC_NO_FAULT);
-	GUEST_ASSERT_EQ(vmreadz(VM_EXIT_REASON), EXIT_REASON_VMCALL);
+	GUEST_ASSERT_EQ(vmread(VM_EXIT_REASON), EXIT_REASON_VMCALL);
 	GUEST_DONE();
 }
 
diff --git a/tools/testing/selftests/kvm/x86/nested_emulation_test.c b/tools/testing/selftests/kvm/x86/nested_emulation_test.c
index 009932b1604e..68d9ce9dc6ba 100644
--- a/tools/testing/selftests/kvm/x86/nested_emulation_test.c
+++ b/tools/testing/selftests/kvm/x86/nested_emulation_test.c
@@ -74,7 +74,7 @@ static void guest_code(void *test_data)
 		vmwrite(GUEST_RIP, (u64)l2_guest_code);
 		vmwrite(EXCEPTION_BITMAP, 0);
 
-		vmwrite(CPU_BASED_VM_EXEC_CONTROL, vmreadz(CPU_BASED_VM_EXEC_CONTROL) |
+		vmwrite(CPU_BASED_VM_EXEC_CONTROL, vmread(CPU_BASED_VM_EXEC_CONTROL) |
 						   CPU_BASED_PAUSE_EXITING |
 						   CPU_BASED_HLT_EXITING);
 	}
@@ -106,9 +106,9 @@ static void guest_code(void *test_data)
 				vmlaunch();
 			else
 				vmresume();
-			exit_reason = vmreadz(VM_EXIT_REASON);
-			exit_insn_len = vmreadz(VM_EXIT_INSTRUCTION_LEN);
-			GUEST_ASSERT_EQ(vmreadz(GUEST_RIP), (u64)l2_instruction);
+			exit_reason = vmread(VM_EXIT_REASON);
+			exit_insn_len = vmread(VM_EXIT_INSTRUCTION_LEN);
+			GUEST_ASSERT_EQ(vmread(GUEST_RIP), (u64)l2_instruction);
 		}
 
 		__GUEST_ASSERT(exit_reason == insn->exit_reason[f],
diff --git a/tools/testing/selftests/kvm/x86/nested_exceptions_test.c b/tools/testing/selftests/kvm/x86/nested_exceptions_test.c
index d0beaa7b280b..d23e24f35790 100644
--- a/tools/testing/selftests/kvm/x86/nested_exceptions_test.c
+++ b/tools/testing/selftests/kvm/x86/nested_exceptions_test.c
@@ -120,10 +120,10 @@ static void vmx_run_l2(void *l2_code, int vector, u32 error_code)
 	if (vector == FAKE_TRIPLE_FAULT_VECTOR)
 		return;
 
-	GUEST_ASSERT_EQ(vmreadz(VM_EXIT_REASON), EXIT_REASON_EXCEPTION_NMI);
-	GUEST_ASSERT_EQ((vmreadz(VM_EXIT_INTR_INFO) & 0xff), vector);
-	GUEST_ASSERT_EQ(vmreadz(VM_EXIT_INTR_ERROR_CODE), error_code);
-	GUEST_ASSERT(!vmreadz(GUEST_INTERRUPTIBILITY_INFO));
+	GUEST_ASSERT_EQ(vmread(VM_EXIT_REASON), EXIT_REASON_EXCEPTION_NMI);
+	GUEST_ASSERT_EQ((vmread(VM_EXIT_INTR_INFO) & 0xff), vector);
+	GUEST_ASSERT_EQ(vmread(VM_EXIT_INTR_ERROR_CODE), error_code);
+	GUEST_ASSERT(!vmread(GUEST_INTERRUPTIBILITY_INFO));
 }
 
 static void l1_vmx_code(struct vmx_pages *vmx)
@@ -149,7 +149,7 @@ static void l1_vmx_code(struct vmx_pages *vmx)
 
 	vmwrite(EXCEPTION_BITMAP, INTERCEPT_SS);
 	vmx_run_l2(l2_ss_injected_tf_test, FAKE_TRIPLE_FAULT_VECTOR, 0);
-	GUEST_ASSERT_EQ(vmreadz(VM_EXIT_REASON), EXIT_REASON_TRIPLE_FAULT);
+	GUEST_ASSERT_EQ(vmread(VM_EXIT_REASON), EXIT_REASON_TRIPLE_FAULT);
 
 	GUEST_DONE();
 }
diff --git a/tools/testing/selftests/kvm/x86/nested_invalid_cr3_test.c b/tools/testing/selftests/kvm/x86/nested_invalid_cr3_test.c
index 101c1fe79eeb..6e147826bc90 100644
--- a/tools/testing/selftests/kvm/x86/nested_invalid_cr3_test.c
+++ b/tools/testing/selftests/kvm/x86/nested_invalid_cr3_test.c
@@ -46,16 +46,16 @@ static void l1_vmx_code(struct vmx_pages *vmx_pages)
 	prepare_vmcs(vmx_pages, l2_guest_code);
 
 	/* Try to run L2 with invalid CR3 and make sure it fails */
-	save_cr3 = vmreadz(GUEST_CR3);
+	save_cr3 = vmread(GUEST_CR3);
 	vmwrite(GUEST_CR3, -1ull);
 	vmlaunch();
-	GUEST_ASSERT(vmreadz(VM_EXIT_REASON) ==
+	GUEST_ASSERT(vmread(VM_EXIT_REASON) ==
 		     (EXIT_REASON_FAILED_VMENTRY | EXIT_REASON_INVALID_STATE));
 
 	/* Now restore CR3 and make sure L2 runs successfully */
 	vmwrite(GUEST_CR3, save_cr3);
 	vmlaunch();
-	GUEST_ASSERT(vmreadz(VM_EXIT_REASON) == EXIT_REASON_VMCALL);
+	GUEST_ASSERT(vmread(VM_EXIT_REASON) == EXIT_REASON_VMCALL);
 
 	GUEST_DONE();
 }
diff --git a/tools/testing/selftests/kvm/x86/nested_tdp_fault_test.c b/tools/testing/selftests/kvm/x86/nested_tdp_fault_test.c
index d6c443e3d147..fae77d843b13 100644
--- a/tools/testing/selftests/kvm/x86/nested_tdp_fault_test.c
+++ b/tools/testing/selftests/kvm/x86/nested_tdp_fault_test.c
@@ -63,17 +63,17 @@ static void l1_vmx_code(struct vmx_pages *vmx, u64 expected_fault_gpa,
 	vmlaunch();
 
 	/* Verify we got an EPT violation exit */
-	__GUEST_ASSERT(vmreadz(VM_EXIT_REASON) == EXIT_REASON_EPT_VIOLATION,
+	__GUEST_ASSERT(vmread(VM_EXIT_REASON) == EXIT_REASON_EPT_VIOLATION,
 		       "Expected EPT violation (0x%x), got 0x%lx",
 		       EXIT_REASON_EPT_VIOLATION,
-		       vmreadz(VM_EXIT_REASON));
+		       vmread(VM_EXIT_REASON));
 
-	__GUEST_ASSERT(vmreadz(GUEST_PHYSICAL_ADDRESS) == expected_fault_gpa,
+	__GUEST_ASSERT(vmread(GUEST_PHYSICAL_ADDRESS) == expected_fault_gpa,
 		       "Expected guest_physical_address = 0x%lx, got 0x%lx",
 		       expected_fault_gpa,
-		       vmreadz(GUEST_PHYSICAL_ADDRESS));
+		       vmread(GUEST_PHYSICAL_ADDRESS));
 
-	exit_qual = vmreadz(EXIT_QUALIFICATION);
+	exit_qual = vmread(EXIT_QUALIFICATION);
 
 	/*
 	 * Note, EPT page table accesses are always read+write, e.g. so that
diff --git a/tools/testing/selftests/kvm/x86/nested_tsc_adjust_test.c b/tools/testing/selftests/kvm/x86/nested_tsc_adjust_test.c
index c60dea899624..6a1a88e926f8 100644
--- a/tools/testing/selftests/kvm/x86/nested_tsc_adjust_test.c
+++ b/tools/testing/selftests/kvm/x86/nested_tsc_adjust_test.c
@@ -90,13 +90,13 @@ static void l1_guest_code(void *data)
 		load_vmcs(vmx_pages);
 
 		prepare_vmcs(vmx_pages, l2_guest_code);
-		control = vmreadz(CPU_BASED_VM_EXEC_CONTROL);
+		control = vmread(CPU_BASED_VM_EXEC_CONTROL);
 		control |= CPU_BASED_USE_MSR_BITMAPS | CPU_BASED_USE_TSC_OFFSETTING;
 		vmwrite(CPU_BASED_VM_EXEC_CONTROL, control);
 		vmwrite(TSC_OFFSET, TSC_OFFSET_VALUE);
 
 		vmlaunch();
-		GUEST_ASSERT(vmreadz(VM_EXIT_REASON) == EXIT_REASON_VMCALL);
+		GUEST_ASSERT(vmread(VM_EXIT_REASON) == EXIT_REASON_VMCALL);
 	} else {
 		struct svm_test_data *svm = data;
 
diff --git a/tools/testing/selftests/kvm/x86/nested_tsc_scaling_test.c b/tools/testing/selftests/kvm/x86/nested_tsc_scaling_test.c
index b2fc7f0b5b3c..c763f4cf0f62 100644
--- a/tools/testing/selftests/kvm/x86/nested_tsc_scaling_test.c
+++ b/tools/testing/selftests/kvm/x86/nested_tsc_scaling_test.c
@@ -112,11 +112,11 @@ static void l1_vmx_code(struct vmx_pages *vmx_pages)
 	prepare_vmcs(vmx_pages, l2_guest_code);
 
 	/* enable TSC offsetting and TSC scaling for L2 */
-	control = vmreadz(CPU_BASED_VM_EXEC_CONTROL);
+	control = vmread(CPU_BASED_VM_EXEC_CONTROL);
 	control |= CPU_BASED_USE_MSR_BITMAPS | CPU_BASED_USE_TSC_OFFSETTING;
 	vmwrite(CPU_BASED_VM_EXEC_CONTROL, control);
 
-	control = vmreadz(SECONDARY_VM_EXEC_CONTROL);
+	control = vmread(SECONDARY_VM_EXEC_CONTROL);
 	control |= SECONDARY_EXEC_TSC_SCALING;
 	vmwrite(SECONDARY_VM_EXEC_CONTROL, control);
 
@@ -126,7 +126,7 @@ static void l1_vmx_code(struct vmx_pages *vmx_pages)
 
 	/* launch L2 */
 	vmlaunch();
-	GUEST_ASSERT(vmreadz(VM_EXIT_REASON) == EXIT_REASON_VMCALL);
+	GUEST_ASSERT(vmread(VM_EXIT_REASON) == EXIT_REASON_VMCALL);
 
 	/* check that L1's frequency still looks good */
 	check_tsc_freq(UCHECK_L1);
diff --git a/tools/testing/selftests/kvm/x86/save_restore_pf_stress_test.c b/tools/testing/selftests/kvm/x86/save_restore_pf_stress_test.c
index e728f040916f..24056921110c 100644
--- a/tools/testing/selftests/kvm/x86/save_restore_pf_stress_test.c
+++ b/tools/testing/selftests/kvm/x86/save_restore_pf_stress_test.c
@@ -106,8 +106,8 @@ static void l1_vmx_code(struct vmx_pages *vmx)
 
 	vmlaunch();
 	while (1) {
-		GUEST_ASSERT_EQ(vmreadz(VM_EXIT_REASON), EXIT_REASON_EXCEPTION_NMI);
-		GUEST_ASSERT_EQ(vmreadz(VM_EXIT_INTR_INFO) & 0xff, UD_VECTOR);
+		GUEST_ASSERT_EQ(vmread(VM_EXIT_REASON), EXIT_REASON_EXCEPTION_NMI);
+		GUEST_ASSERT_EQ(vmread(VM_EXIT_INTR_INFO) & 0xff, UD_VECTOR);
 		vmresume();
 	}
 }
diff --git a/tools/testing/selftests/kvm/x86/state_test.c b/tools/testing/selftests/kvm/x86/state_test.c
index 7cb1d160e2d9..75e09d5e03eb 100644
--- a/tools/testing/selftests/kvm/x86/state_test.c
+++ b/tools/testing/selftests/kvm/x86/state_test.c
@@ -59,12 +59,12 @@ void vmx_l2_guest_code(void)
 	vmcall();
 
 	/* L1 has now set up a shadow VMCS for us.  */
-	GUEST_ASSERT(vmreadz(GUEST_RIP) == 0xc0ffee);
+	GUEST_ASSERT(vmread(GUEST_RIP) == 0xc0ffee);
 	GUEST_SYNC(10);
-	GUEST_ASSERT(vmreadz(GUEST_RIP) == 0xc0ffee);
+	GUEST_ASSERT(vmread(GUEST_RIP) == 0xc0ffee);
 	vmwrite(GUEST_RIP, 0xc0fffee);
 	GUEST_SYNC(11);
-	GUEST_ASSERT(vmreadz(GUEST_RIP) == 0xc0fffee);
+	GUEST_ASSERT(vmread(GUEST_RIP) == 0xc0fffee);
 	vmwrite(GUEST_RIP, 0xc0ffffee);
 	GUEST_SYNC(12);
 
@@ -89,21 +89,21 @@ static void vmx_l1_guest_code(struct vmx_pages *vmx_pages)
 	GUEST_ASSERT(vmptrst() == vmx_pages->vmcs_gpa);
 	vmlaunch();
 	GUEST_ASSERT(vmptrst() == vmx_pages->vmcs_gpa);
-	GUEST_ASSERT(vmreadz(VM_EXIT_REASON) == EXIT_REASON_VMCALL);
+	GUEST_ASSERT(vmread(VM_EXIT_REASON) == EXIT_REASON_VMCALL);
 
 	/* Check that the launched state is preserved.  */
 	GUEST_ASSERT(__vmlaunch());
 
 	vmresume();
-	GUEST_ASSERT(vmreadz(VM_EXIT_REASON) == EXIT_REASON_VMCALL);
+	GUEST_ASSERT(vmread(VM_EXIT_REASON) == EXIT_REASON_VMCALL);
 
 	GUEST_SYNC(7);
-	GUEST_ASSERT(vmreadz(VM_EXIT_REASON) == EXIT_REASON_VMCALL);
+	GUEST_ASSERT(vmread(VM_EXIT_REASON) == EXIT_REASON_VMCALL);
 
 	vmresume();
-	GUEST_ASSERT(vmreadz(VM_EXIT_REASON) == EXIT_REASON_VMCALL);
+	GUEST_ASSERT(vmread(VM_EXIT_REASON) == EXIT_REASON_VMCALL);
 
-	vmwrite(GUEST_RIP, vmreadz(GUEST_RIP) + 3);
+	vmwrite(GUEST_RIP, vmread(GUEST_RIP) + 3);
 
 	vmwrite(SECONDARY_VM_EXEC_CONTROL, SECONDARY_EXEC_SHADOW_VMCS);
 	vmwrite(VMCS_LINK_POINTER, vmx_pages->shadow_vmcs_gpa);
@@ -116,18 +116,18 @@ static void vmx_l1_guest_code(struct vmx_pages *vmx_pages)
 
 	vmwrite(GUEST_RIP, 0xc0ffee);
 	GUEST_SYNC(9);
-	GUEST_ASSERT(vmreadz(GUEST_RIP) == 0xc0ffee);
+	GUEST_ASSERT(vmread(GUEST_RIP) == 0xc0ffee);
 
 	vmptrld(vmx_pages->vmcs_gpa);
 	vmresume();
-	GUEST_ASSERT(vmreadz(VM_EXIT_REASON) == EXIT_REASON_VMCALL);
+	GUEST_ASSERT(vmread(VM_EXIT_REASON) == EXIT_REASON_VMCALL);
 
 	vmptrld(vmx_pages->shadow_vmcs_gpa);
-	GUEST_ASSERT(vmreadz(GUEST_RIP) == 0xc0ffffee);
+	GUEST_ASSERT(vmread(GUEST_RIP) == 0xc0ffffee);
 	GUEST_ASSERT(__vmlaunch());
 	GUEST_ASSERT(__vmresume());
 	GUEST_SYNC(13);
-	GUEST_ASSERT(vmreadz(GUEST_RIP) == 0xc0ffffee);
+	GUEST_ASSERT(vmread(GUEST_RIP) == 0xc0ffffee);
 	GUEST_ASSERT(__vmlaunch());
 	GUEST_ASSERT(__vmresume());
 }
diff --git a/tools/testing/selftests/kvm/x86/triple_fault_event_test.c b/tools/testing/selftests/kvm/x86/triple_fault_event_test.c
index bb31a1ba8932..b2b796fd9ffb 100644
--- a/tools/testing/selftests/kvm/x86/triple_fault_event_test.c
+++ b/tools/testing/selftests/kvm/x86/triple_fault_event_test.c
@@ -32,7 +32,7 @@ void l1_guest_code_vmx(struct vmx_pages *vmx)
 
 	vmlaunch();
 	/* L2 should triple fault after a triple fault event injected. */
-	GUEST_ASSERT(vmreadz(VM_EXIT_REASON) == EXIT_REASON_TRIPLE_FAULT);
+	GUEST_ASSERT(vmread(VM_EXIT_REASON) == EXIT_REASON_TRIPLE_FAULT);
 	GUEST_DONE();
 }
 
diff --git a/tools/testing/selftests/kvm/x86/vmx_apic_access_test.c b/tools/testing/selftests/kvm/x86/vmx_apic_access_test.c
index fe29c869a235..d6373c414d18 100644
--- a/tools/testing/selftests/kvm/x86/vmx_apic_access_test.c
+++ b/tools/testing/selftests/kvm/x86/vmx_apic_access_test.c
@@ -43,25 +43,25 @@ static void l1_guest_code(struct vmx_pages *vmx_pages, unsigned long high_gpa)
 
 	/* Prepare the VMCS for L2 execution. */
 	prepare_vmcs(vmx_pages, l2_guest_code);
-	control = vmreadz(CPU_BASED_VM_EXEC_CONTROL);
+	control = vmread(CPU_BASED_VM_EXEC_CONTROL);
 	control |= CPU_BASED_ACTIVATE_SECONDARY_CONTROLS;
 	vmwrite(CPU_BASED_VM_EXEC_CONTROL, control);
-	control = vmreadz(SECONDARY_VM_EXEC_CONTROL);
+	control = vmread(SECONDARY_VM_EXEC_CONTROL);
 	control |= SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES;
 	vmwrite(SECONDARY_VM_EXEC_CONTROL, control);
 	vmwrite(APIC_ACCESS_ADDR, vmx_pages->apic_access_gpa);
 
 	/* Try to launch L2 with the memory-backed APIC-access address. */
-	GUEST_SYNC(vmreadz(APIC_ACCESS_ADDR));
+	GUEST_SYNC(vmread(APIC_ACCESS_ADDR));
 	vmlaunch();
-	GUEST_ASSERT(vmreadz(VM_EXIT_REASON) == EXIT_REASON_VMCALL);
+	GUEST_ASSERT(vmread(VM_EXIT_REASON) == EXIT_REASON_VMCALL);
 
 	vmwrite(APIC_ACCESS_ADDR, high_gpa);
 
 	/* Try to resume L2 with the unbacked APIC-access address. */
-	GUEST_SYNC(vmreadz(APIC_ACCESS_ADDR));
+	GUEST_SYNC(vmread(APIC_ACCESS_ADDR));
 	vmresume();
-	GUEST_ASSERT(vmreadz(VM_EXIT_REASON) == EXIT_REASON_VMCALL);
+	GUEST_ASSERT(vmread(VM_EXIT_REASON) == EXIT_REASON_VMCALL);
 
 	GUEST_DONE();
 }
diff --git a/tools/testing/selftests/kvm/x86/vmx_apicv_updates_test.c b/tools/testing/selftests/kvm/x86/vmx_apicv_updates_test.c
index e578221da247..cda9e43e8599 100644
--- a/tools/testing/selftests/kvm/x86/vmx_apicv_updates_test.c
+++ b/tools/testing/selftests/kvm/x86/vmx_apicv_updates_test.c
@@ -38,7 +38,7 @@ static void l1_guest_code(struct vmx_pages *vmx_pages)
 
 	/* Prepare the VMCS for L2 execution. */
 	prepare_vmcs(vmx_pages, l2_guest_code);
-	control = vmreadz(CPU_BASED_VM_EXEC_CONTROL);
+	control = vmread(CPU_BASED_VM_EXEC_CONTROL);
 	control |= CPU_BASED_USE_MSR_BITMAPS;
 	vmwrite(CPU_BASED_VM_EXEC_CONTROL, control);
 
@@ -63,8 +63,8 @@ static void l1_guest_code(struct vmx_pages *vmx_pages)
 	 * as KVM should force the APIC ID back to its default.
 	 */
 	vmlaunch();
-	GUEST_ASSERT(vmreadz(VM_EXIT_REASON) == EXIT_REASON_VMCALL);
-	vmwrite(GUEST_RIP, vmreadz(GUEST_RIP) + vmreadz(VM_EXIT_INSTRUCTION_LEN));
+	GUEST_ASSERT(vmread(VM_EXIT_REASON) == EXIT_REASON_VMCALL);
+	vmwrite(GUEST_RIP, vmread(GUEST_RIP) + vmread(VM_EXIT_INSTRUCTION_LEN));
 	GUEST_ASSERT(rdmsr(MSR_IA32_APICBASE) & MSR_IA32_APICBASE_EXTD);
 
 	/*
@@ -91,7 +91,7 @@ static void l1_guest_code(struct vmx_pages *vmx_pages)
 	 * is active.
 	 */
 	vmresume();
-	GUEST_ASSERT(vmreadz(VM_EXIT_REASON) == EXIT_REASON_VMCALL);
+	GUEST_ASSERT(vmread(VM_EXIT_REASON) == EXIT_REASON_VMCALL);
 	GUEST_ASSERT(!(rdmsr(MSR_IA32_APICBASE) & MSR_IA32_APICBASE_EXTD));
 
 	xapic_write_reg(APIC_ICR, APIC_DEST_SELF | APIC_DM_FIXED | GOOD_IPI_VECTOR);
diff --git a/tools/testing/selftests/kvm/x86/vmx_invalid_nested_guest_state.c b/tools/testing/selftests/kvm/x86/vmx_invalid_nested_guest_state.c
index 3017938fa993..bbd188949412 100644
--- a/tools/testing/selftests/kvm/x86/vmx_invalid_nested_guest_state.c
+++ b/tools/testing/selftests/kvm/x86/vmx_invalid_nested_guest_state.c
@@ -52,13 +52,13 @@ static void l1_guest_code(struct vmx_pages *vmx_pages)
 	 * library hasn't enabled it.  Because KVM selftests jump directly to
 	 * 64-bit mode, unrestricted guest support isn't required.
 	 */
-	GUEST_ASSERT(!(vmreadz(CPU_BASED_VM_EXEC_CONTROL) & CPU_BASED_ACTIVATE_SECONDARY_CONTROLS) ||
-		     !(vmreadz(SECONDARY_VM_EXEC_CONTROL) & SECONDARY_EXEC_UNRESTRICTED_GUEST));
+	GUEST_ASSERT(!(vmread(CPU_BASED_VM_EXEC_CONTROL) & CPU_BASED_ACTIVATE_SECONDARY_CONTROLS) ||
+		     !(vmread(SECONDARY_VM_EXEC_CONTROL) & SECONDARY_EXEC_UNRESTRICTED_GUEST));
 
 	vmlaunch();
 
 	/* L2 should triple fault after main() stuffs invalid guest state. */
-	GUEST_ASSERT(vmreadz(VM_EXIT_REASON) == EXIT_REASON_TRIPLE_FAULT);
+	GUEST_ASSERT(vmread(VM_EXIT_REASON) == EXIT_REASON_TRIPLE_FAULT);
 	GUEST_DONE();
 }
 
diff --git a/tools/testing/selftests/kvm/x86/vmx_nested_la57_state_test.c b/tools/testing/selftests/kvm/x86/vmx_nested_la57_state_test.c
index b3651c5ab138..16f57af5a8e1 100644
--- a/tools/testing/selftests/kvm/x86/vmx_nested_la57_state_test.c
+++ b/tools/testing/selftests/kvm/x86/vmx_nested_la57_state_test.c
@@ -52,13 +52,13 @@ static void l1_guest_code(struct vmx_pages *vmx_pages)
 	pml4_pa = pml5[0] & PHYSICAL_PAGE_MASK;
 	vmwrite(GUEST_CR3, pml4_pa);
 
-	guest_cr4 = vmreadz(GUEST_CR4);
+	guest_cr4 = vmread(GUEST_CR4);
 	guest_cr4 &= ~X86_CR4_LA57;
 	vmwrite(GUEST_CR4, guest_cr4);
 
 	vmlaunch();
 
-	exit_reason = vmreadz(VM_EXIT_REASON);
+	exit_reason = vmread(VM_EXIT_REASON);
 	GUEST_ASSERT(exit_reason == EXIT_REASON_VMCALL);
 }
 
diff --git a/tools/testing/selftests/kvm/x86/vmx_preemption_timer_test.c b/tools/testing/selftests/kvm/x86/vmx_preemption_timer_test.c
index c5f9d9879f61..376c96e68341 100644
--- a/tools/testing/selftests/kvm/x86/vmx_preemption_timer_test.c
+++ b/tools/testing/selftests/kvm/x86/vmx_preemption_timer_test.c
@@ -91,14 +91,14 @@ void l1_guest_code(struct vmx_pages *vmx_pages)
 		return;
 
 	vmlaunch();
-	GUEST_ASSERT(vmreadz(VM_EXIT_REASON) == EXIT_REASON_VMCALL);
-	vmwrite(GUEST_RIP, vmreadz(GUEST_RIP) + vmreadz(VM_EXIT_INSTRUCTION_LEN));
+	GUEST_ASSERT(vmread(VM_EXIT_REASON) == EXIT_REASON_VMCALL);
+	vmwrite(GUEST_RIP, vmread(GUEST_RIP) + vmread(VM_EXIT_INSTRUCTION_LEN));
 
 	/*
 	 * Turn on PIN control and resume the guest
 	 */
 	vmwrite(PIN_BASED_VM_EXEC_CONTROL,
-		vmreadz(PIN_BASED_VM_EXEC_CONTROL) | PIN_BASED_VMX_PREEMPTION_TIMER);
+		vmread(PIN_BASED_VM_EXEC_CONTROL) | PIN_BASED_VMX_PREEMPTION_TIMER);
 
 	vmwrite(VMX_PREEMPTION_TIMER_VALUE, PREEMPTION_TIMER_VALUE);
 
@@ -121,7 +121,7 @@ void l1_guest_code(struct vmx_pages *vmx_pages)
 	/*
 	 * Ensure the exit from L2 is due to preemption timer expiry
 	 */
-	GUEST_ASSERT(vmreadz(VM_EXIT_REASON) == EXIT_REASON_PREEMPTION_TIMER);
+	GUEST_ASSERT(vmread(VM_EXIT_REASON) == EXIT_REASON_PREEMPTION_TIMER);
 
 	l1_tsc_deadline = l1_vmx_pt_start +
 		(PREEMPTION_TIMER_VALUE << vmx_pt_rate);
-- 
2.55.0.979.g7e5102b832-goog


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* Re: [PATCH v4 14/17] KVM: selftests: Assert success in vmlaunch() and vmresume()
  2026-09-04  0:24 ` [PATCH v4 14/17] KVM: selftests: Assert success in vmlaunch() and vmresume() Sean Christopherson
@ 2026-09-04  0:35   ` sashiko-bot
  0 siblings, 0 replies; 21+ messages in thread
From: sashiko-bot @ 2026-09-04  0:35 UTC (permalink / raw)
  To: Sean Christopherson; +Cc: kvm

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] The vmlaunch() and vmresume() wrappers are defined as static inline functions instead of macros. Because __GUEST_ASSERT captures __FILE__ and __LINE__ at the point of its invocation, assertion failures in these wrappers will report the file and line number inside vmx.h rather than the actual caller's location in the test file.
--

commit 00cde4aa7e9af50759c8cee7b3f7fecea0caf3ed
Author: Sean Christopherson <seanjc@google.com>

KVM: selftests: Assert success in vmlaunch() and vmresume()

This patch updates the outer vmlaunch and vmresume selftests APIs to assert
success directly, deduplicating error checking across tests. Tests expecting
VM-Enter failures now explicitly use the double-underscore versions.

> diff --git a/tools/testing/selftests/kvm/include/x86/vmx.h b/tools/testing/selftests/kvm/include/x86/vmx.h
> index d0ac8e128d985..1419043b41dd3 100644
> --- a/tools/testing/selftests/kvm/include/x86/vmx.h
> +++ b/tools/testing/selftests/kvm/include/x86/vmx.h
> @@ -362,14 +362,14 @@ static inline u64 vmptrst(void)
>  int __vmlaunch(void);
>  int __vmresume(void);
>  
> -static inline int vmlaunch(void)
> +static inline void vmlaunch(void)
>  {
> -	return __vmlaunch();
> +	__GUEST_ASSERT(!__vmlaunch(), "vmlaunch hit VM-Fail");
>  }

[Severity: Medium]
Because __GUEST_ASSERT captures the __FILE__ and __LINE__ macros at the point
of its invocation, placing it inside a static inline function will cause
assertion failures to always report the location inside vmx.h instead of the
actual caller's location in the test file (for example, inside state_test.c
or nested_emulation_test.c).

Does this cause a loss of debugging context when a VM-Fail assertion triggers
in tests with multiple vmlaunch invocations? Could vmlaunch be defined as a
macro instead to preserve the caller's location?

>  
> -static inline int vmresume(void)
> +static inline void vmresume(void)
>  {
> -	return __vmresume();
> +	__GUEST_ASSERT(!__vmresume(), "vmresume hit VM-Fail");
>  }

[Severity: Medium]
Similarly for vmresume, using __GUEST_ASSERT in an inline function will mask
the file and line number of the actual test invocation. Would a macro be more
appropriate here as well to retain the debugging context?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260904002423.3154436-1-seanjc@google.com?part=14

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH v4 15/17] KVM: selftests: Add __vmwrite() and use it when initializing optional fields.
  2026-09-04  0:24 ` [PATCH v4 15/17] KVM: selftests: Add __vmwrite() and use it when initializing optional fields Sean Christopherson
@ 2026-09-04  0:35   ` sashiko-bot
  0 siblings, 0 replies; 21+ messages in thread
From: sashiko-bot @ 2026-09-04  0:35 UTC (permalink / raw)
  To: Sean Christopherson; +Cc: kvm

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] The patch fails to convert all blind writes of optional VMCS fields to the non-asserting `__vmwrite()` in the common setup code, contradicting its stated intent and setting up a test crash.
--

commit 2bdd2a9b67ebe18b99a514555581198b78d1fab6
Author: Sean Christopherson <seanjc@google.com>

KVM: selftests: Add __vmwrite() and use it when initializing optional fields.

This commit introduces __vmwrite(), a non-asserting version of vmwrite(), to
allow writing optional VMCS fields in common setup code where success is not
guaranteed. It prepares for vmwrite() to unconditionally assert success in
subsequent patches.

> diff --git a/tools/testing/selftests/kvm/lib/x86/vmx.c b/tools/testing/selftests/kvm/lib/x86/vmx.c
> index 1a8515de42b06..b6bd9423e6768 100644
> --- a/tools/testing/selftests/kvm/lib/x86/vmx.c
> +++ b/tools/testing/selftests/kvm/lib/x86/vmx.c
> @@ -252,7 +252,7 @@ static inline void init_vmcs_control_fields(struct vmx_pages *vmx)
>  	u32 sec_exec_ctl = 0;
>  
>  	vmwrite(VIRTUAL_PROCESSOR_ID, 0);

[Severity: Medium]
Will this blindly write to the VIRTUAL_PROCESSOR_ID field using the asserting
vmwrite()?

Since VPID is an optional secondary control that may not exist on all
hardware, this could crash selftests with a VM-Fail assertion on unsupported
hardware once vmwrite() is modified to assert success. Could this be converted
to __vmwrite() similar to POSTED_INTR_NV?

> -	vmwrite(POSTED_INTR_NV, 0);
> +	__vmwrite(POSTED_INTR_NV, 0);
>  
>  	vmwrite(PIN_BASED_VM_EXEC_CONTROL, rdmsr(MSR_IA32_VMX_TRUE_PINBASED_CTLS));

[ ... ]

> @@ -356,8 +356,8 @@ static inline void init_vmcs_guest_state(void *rip, void *rsp)
>  	vmwrite(GUEST_GS_SELECTOR, vmreadz(HOST_GS_SELECTOR));
>  	vmwrite(GUEST_LDTR_SELECTOR, 0);
>  	vmwrite(GUEST_TR_SELECTOR, vmreadz(HOST_TR_SELECTOR));
> -	vmwrite(GUEST_INTR_STATUS, 0);
> -	vmwrite(GUEST_PML_INDEX, 0);
> +	__vmwrite(GUEST_INTR_STATUS, 0);
> +	__vmwrite(GUEST_PML_INDEX, 0);
>  
>  	vmwrite(VMCS_LINK_POINTER, -1ll);
>  	vmwrite(GUEST_IA32_DEBUGCTL, 0);

[Severity: Medium]
Will these writes to optional guest state fields cause test failures on CPUs
or nested hypervisors that lack these features?

Fields like GUEST_IA32_DEBUGCTL, GUEST_IA32_PAT, GUEST_IA32_EFER, and
GUEST_IA32_PERF_GLOBAL_CTRL are written unconditionally using vmwrite() here
in init_vmcs_guest_state(). It seems they will assert failure on unsupported
hardware. Should these also be switched to use __vmwrite() to avoid crashing?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260904002423.3154436-1-seanjc@google.com?part=15

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH v4 17/17] KVM: selftests: Always assert that vmreadz() succeeds
  2026-09-04  0:24 ` [PATCH v4 17/17] KVM: selftests: Always assert that vmreadz() succeeds Sean Christopherson
@ 2026-09-04  0:36   ` sashiko-bot
  0 siblings, 0 replies; 21+ messages in thread
From: sashiko-bot @ 2026-09-04  0:36 UTC (permalink / raw)
  To: Sean Christopherson; +Cc: kvm

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Low] Typo in assertion message: 'vmwread' instead of 'vmread'.
--

commit b99bd290de04e34e69f57ca551e7c07af56c2b56
Author: Sean Christopherson <seanjc@google.com>

    KVM: selftests: Always assert that vmreadz() succeeds
    
    Rename vmreadz() => vmread() (and vmread() => __vmread()) and have it
    assert success instead of returning garbage on failure.  While the eVMCS
    path avoids clobbering *value on failure, the VMREAD path unconditionally
    stores tmp to *value, without ever zeroing tmp.

> diff --git a/tools/testing/selftests/kvm/include/x86/vmx.h b/tools/testing/selftests/kvm/include/x86/vmx.h
> index be10028c51b96..a4807e41fe69c 100644
> --- a/tools/testing/selftests/kvm/include/x86/vmx.h
> +++ b/tools/testing/selftests/kvm/include/x86/vmx.h
[ ... ]
> @@ -399,18 +399,17 @@ static inline int vmread(u64 encoding, u64 *value)
>  		: [encoding]"r"(encoding)
>  		: "cc", "memory");
>  
> -	*value = tmp;
> +	if (!ret)
> +		*value = tmp;
>  	return ret;
>  }
>  
> -/*
> - * A wrapper around vmread that ignores errors and returns zero if the
> - * vmread instruction fails.
> - */
> -static inline u64 vmreadz(u64 encoding)
> +static inline u64 vmread(u64 encoding)
>  {
>  	u64 value = 0;
> -	vmread(encoding, &value);
> +
> +	__GUEST_ASSERT(!__vmread(encoding, &value),
> +		       "vmwread[0x%lx] hit VM-Fail", encoding);

[Severity: Low]
Is there a typo in the assert message here? It says 'vmwread' instead of
'vmread'.

>  	return value;
>  }
>

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260904002423.3154436-1-seanjc@google.com?part=17

^ permalink raw reply	[flat|nested] 21+ messages in thread

end of thread, other threads:[~2026-09-04  0:36 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-04  0:24 [PATCH v4 00/17] KVM: nVMX: Adjust VMPTRLD/VMPTRST behavior with active eVMCS Sean Christopherson
2026-09-04  0:24 ` [PATCH v4 01/17] KVM: nVMX: Make VMPTRLD result in #UD when eVMCS is used Sean Christopherson
2026-09-04  0:24 ` [PATCH v4 02/17] KVM: nVMX: Make VMPTRST return eVMCS GPA when it " Sean Christopherson
2026-09-04  0:24 ` [PATCH v4 03/17] KVM: selftests: Don't clobber RFLAGS in happy path of __KVM_ASM_SAFE() Sean Christopherson
2026-09-04  0:24 ` [PATCH v4 04/17] KVM: selftests: Adapt to the updated VMPTRST behavior when eVMCS is used Sean Christopherson
2026-09-04  0:24 ` [PATCH v4 05/17] KVM: selftests: Check VMPTRLD with active eVMCS Sean Christopherson
2026-09-04  0:24 ` [PATCH v4 06/17] KVM: selftests: Assert success in vmptrst(), kill off vmptrstz() Sean Christopherson
2026-09-04  0:24 ` [PATCH v4 07/17] KVM: selftests: Always assert that vmxon() and prepare_for_vmx_operation() succeed Sean Christopherson
2026-09-04  0:24 ` [PATCH v4 08/17] KVM: selftests: Always assert that vmclear() succeeds Sean Christopherson
2026-09-04  0:24 ` [PATCH v4 09/17] KVM: selftests: Always assert that vmptrld() succeeds Sean Christopherson
2026-09-04  0:24 ` [PATCH v4 10/17] KVM: selftests: Drop useless return code from load_vmcs() Sean Christopherson
2026-09-04  0:24 ` [PATCH v4 11/17] KVM: selftests: Add macros to handle simple VMX instructions Sean Christopherson
2026-09-04  0:24 ` [PATCH v4 12/17] KVM: selftests: Drop dead return code from evmcs_vmptrld() and load_evmcs() Sean Christopherson
2026-09-04  0:24 ` [PATCH v4 13/17] KVM: selftests: Dedup assembly code for VMLAUNCH and VMRESUME Sean Christopherson
2026-09-04  0:24 ` [PATCH v4 14/17] KVM: selftests: Assert success in vmlaunch() and vmresume() Sean Christopherson
2026-09-04  0:35   ` sashiko-bot
2026-09-04  0:24 ` [PATCH v4 15/17] KVM: selftests: Add __vmwrite() and use it when initializing optional fields Sean Christopherson
2026-09-04  0:35   ` sashiko-bot
2026-09-04  0:24 ` [PATCH v4 16/17] KVM: selftests: Always assert that vmwrite() succeeds Sean Christopherson
2026-09-04  0:24 ` [PATCH v4 17/17] KVM: selftests: Always assert that vmreadz() succeeds Sean Christopherson
2026-09-04  0:36   ` sashiko-bot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox