diff mbox series

[RFC,2/2] KVM: tests: Selftest for xsave CPUID enumeration

Message ID 20200211065706.3462-2-weijiang.yang@intel.com (mailing list archive)
State New, archived
Headers show
Series [RFC,1/2] KVM: CPUID: Enable supervisor XSAVE states in CPUID enumeration and XSS | expand

Commit Message

Yang, Weijiang Feb. 11, 2020, 6:57 a.m. UTC
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
diff mbox series

Patch

diff --git a/tools/testing/selftests/kvm/Makefile b/tools/testing/selftests/kvm/Makefile
index 3138a916574a..fc458dc949d2 100644
--- a/tools/testing/selftests/kvm/Makefile
+++ b/tools/testing/selftests/kvm/Makefile
@@ -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
diff --git a/tools/testing/selftests/kvm/x86_64/xsave_cpuid_test.c b/tools/testing/selftests/kvm/x86_64/xsave_cpuid_test.c
new file mode 100644
index 000000000000..262a624c8f51
--- /dev/null
+++ b/tools/testing/selftests/kvm/x86_64/xsave_cpuid_test.c
@@ -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;
+}