@@ -26,6 +26,7 @@ TEST_GEN_PROGS_x86_64 += x86_64/vmx_dirty_log_test
TEST_GEN_PROGS_x86_64 += x86_64/vmx_set_nested_state_test
TEST_GEN_PROGS_x86_64 += x86_64/vmx_tsc_adjust_test
TEST_GEN_PROGS_x86_64 += x86_64/xss_msr_test
+TEST_GEN_PROGS_x86_64 += x86_64/xsave_cpuid_test
TEST_GEN_PROGS_x86_64 += clear_dirty_log_test
TEST_GEN_PROGS_x86_64 += dirty_log_test
TEST_GEN_PROGS_x86_64 += kvm_create_max_vcpus
new file mode 100644
@@ -0,0 +1,81 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * This selftest is based on xss_msr_test.c, but the test approach conflicts
+ * with that of the original test app, so make it a seperate test app.
+ *
+ * It tests for XSAVE(S) based CPUID leaves enumeration and supported bits
+ * in MSR_IA32_XSS.
+ *
+ * Since currently MSR_IA32_XSS isn't supported in kernel and KVM, need to
+ * inject the sample data and mask via KVM before kick off this app, otherwise,
+ * no supervisor XSAVE leaves and bits will be enumerated.
+ */
+
+#include <sys/ioctl.h>
+
+#include "test_util.h"
+#include "kvm_util.h"
+#include "vmx.h"
+
+#define VCPU_ID 1
+#define MSR_BITS 64
+
+#define X86_FEATURE_XSAVES (1<<3)
+
+int enum_xsave_cpuid(struct kvm_vm *vm)
+{
+ struct kvm_cpuid2 *cpuid;
+ struct kvm_cpuid_entry2 *entry2 = NULL;
+ int i;
+
+ cpuid = kvm_get_supported_cpuid();
+ if (cpuid)
+ vcpu_set_cpuid(vm, VCPU_ID, cpuid);
+ for (i = 0; i < cpuid->nent; i++) {
+ entry2 = &cpuid->entries[i];
+ if (entry2->function == 0xd) {
+ printf("cpuid.[d.%d]: eax = 0x%08x, ebx = 0x%08x, ecx = 0x%08x, edx = 0x%08x\n", entry2->index ,entry2->eax, entry2->ebx, entry2->ecx, entry2->edx);
+ }
+ }
+ return 0;
+}
+
+int main(int argc, char *argv[])
+{
+ struct kvm_cpuid_entry2 *entry;
+ bool xss_supported = false;
+ struct kvm_vm *vm;
+ uint64_t enabled_bits = 0;
+ int i, r;
+
+ /* Create VM */
+ vm = vm_create_default(VCPU_ID, 0, 0);
+
+ if (kvm_get_cpuid_max_basic() >= 0xd) {
+ entry = kvm_get_supported_cpuid_index(0xd, 1);
+ xss_supported = entry && !!(entry->eax & X86_FEATURE_XSAVES);
+ }
+ if (!xss_supported) {
+ printf("IA32_XSS is not supported by the vCPU.\n");
+ return -1;
+ }
+
+ enum_xsave_cpuid(vm);
+
+ /*
+ * Below loop is to test which bit is supported on current system.
+ * Before run this selftest, host MSR_IA32_XSS is set to 0x3900 and KVM
+ * XSS mask is set to the same value, otherwise, it cannot enumerate
+ * valid bit in MSR_IA32_XSS.
+ */
+ for (i = 0; i < MSR_BITS; ++i) {
+ r = _vcpu_set_msr(vm, VCPU_ID, MSR_IA32_XSS, 1ull << i);
+ if (r == 1) {
+ enabled_bits |= 1ull << i;
+ printf("bit[%d] in MSR_IA32_XSS is supported\n", i);
+ }
+ }
+ printf("Supported bit mask in MSR_IA32_XSS is : 0x%lx\n", enabled_bits);
+ kvm_vm_free(vm);
+ return 0;
+}
Test CPUID(EAX=DH, ECX=i, i>=0) enumeration and supervisor XSAVE bits support in MSR IA32_XSS. Signed-off-by: Yang Weijiang <weijiang.yang@intel.com> --- tools/testing/selftests/kvm/Makefile | 1 + .../selftests/kvm/x86_64/xsave_cpuid_test.c | 81 +++++++++++++++++++ 2 files changed, 82 insertions(+) create mode 100644 tools/testing/selftests/kvm/x86_64/xsave_cpuid_test.c