[PATCH v4 15/17] KVM: selftests: Add __vmwrite() and use it when initializing optional fields.

From: Sean Christopherson

Date: Thu Sep 03 2026 - 20:27:34 EST


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@xxxxxxxxxx>
---
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