[PATCH v2 9/9] KVM: selftests: vmx_apic_access_test: Check APIC virtualization support
From: Ewan Hai-oc
Date: Thu Sep 10 2026 - 08:08:57 EST
From: Frank Zhu <frankzhu@xxxxxxxxxxx>
Not all CPUs that support VMX necessarily support the "virtualize APIC
accesses" secondary processor-based VM-execution control. For example,
some Zhaoxin CPUs lack this feature. Add a capability check before
running the test to properly skip on unsupported hardware instead of
failing.
Add kvm_cpu_has_vmx_apic_access_virt() helper to vmx.c, following the
same pattern as kvm_cpu_has_ept().
Signed-off-by: Frank Zhu <frankzhu@xxxxxxxxxxx>
---
tools/testing/selftests/kvm/include/x86/vmx.h | 1 +
tools/testing/selftests/kvm/lib/x86/vmx.c | 15 +++++++++++++++
.../selftests/kvm/x86/vmx_apic_access_test.c | 1 +
3 files changed, 17 insertions(+)
diff --git a/tools/testing/selftests/kvm/include/x86/vmx.h b/tools/testing/selftests/kvm/include/x86/vmx.h
index 04f5e34de..b196651bd 100644
--- a/tools/testing/selftests/kvm/include/x86/vmx.h
+++ b/tools/testing/selftests/kvm/include/x86/vmx.h
@@ -557,6 +557,7 @@ bool load_vmcs(struct vmx_pages *vmx);
bool ept_1g_pages_supported(void);
bool kvm_cpu_has_ept(void);
+bool kvm_cpu_has_vmx_apic_access_virt(void);
void vm_enable_ept(struct kvm_vm *vm);
void prepare_virtualize_apic_accesses(struct vmx_pages *vmx, struct kvm_vm *vm);
diff --git a/tools/testing/selftests/kvm/lib/x86/vmx.c b/tools/testing/selftests/kvm/lib/x86/vmx.c
index 089e1a8af..e512191f1 100644
--- a/tools/testing/selftests/kvm/lib/x86/vmx.c
+++ b/tools/testing/selftests/kvm/lib/x86/vmx.c
@@ -390,6 +390,21 @@ bool kvm_cpu_has_ept(void)
return ctrl & SECONDARY_EXEC_ENABLE_EPT;
}
+bool kvm_cpu_has_vmx_apic_access_virt(void)
+{
+ u64 ctrl;
+
+ if (!kvm_cpu_has(X86_FEATURE_VMX))
+ return false;
+
+ ctrl = kvm_get_feature_msr(MSR_IA32_VMX_TRUE_PROCBASED_CTLS) >> 32;
+ if (!(ctrl & CPU_BASED_ACTIVATE_SECONDARY_CONTROLS))
+ return false;
+
+ ctrl = kvm_get_feature_msr(MSR_IA32_VMX_PROCBASED_CTLS2) >> 32;
+ return ctrl & SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES;
+}
+
void prepare_virtualize_apic_accesses(struct vmx_pages *vmx, struct kvm_vm *vm)
{
vmx->apic_access = (void *)vm_alloc_page(vm);
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 463f73aa9..a1b6da4c0 100644
--- a/tools/testing/selftests/kvm/x86/vmx_apic_access_test.c
+++ b/tools/testing/selftests/kvm/x86/vmx_apic_access_test.c
@@ -78,6 +78,7 @@ int main(int argc, char *argv[])
struct kvm_vm *vm;
TEST_REQUIRE(kvm_cpu_has(X86_FEATURE_VMX));
+ TEST_REQUIRE(kvm_cpu_has_vmx_apic_access_virt());
vm = vm_create_with_one_vcpu(&vcpu, l1_guest_code);
--
2.34.1