1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Copyright (C) 2019, Google LLC.
4 *
5 * Tests for the IA32_XSS MSR.
6 */
7
8 #define _GNU_SOURCE /* for program_invocation_short_name */
9 #include <sys/ioctl.h>
10
11 #include "test_util.h"
12 #include "kvm_util.h"
13 #include "vmx.h"
14
15 #define VCPU_ID 1
16 #define MSR_BITS 64
17
18 #define X86_FEATURE_XSAVES (1<<3)
19
is_supported_msr(u32 msr_index)20 bool is_supported_msr(u32 msr_index)
21 {
22 struct kvm_msr_list *list;
23 bool found = false;
24 int i;
25
26 list = kvm_get_msr_index_list();
27 for (i = 0; i < list->nmsrs; ++i) {
28 if (list->indices[i] == msr_index) {
29 found = true;
30 break;
31 }
32 }
33
34 free(list);
35 return found;
36 }
37
main(int argc,char * argv[])38 int main(int argc, char *argv[])
39 {
40 struct kvm_cpuid_entry2 *entry;
41 bool xss_supported = false;
42 struct kvm_vm *vm;
43 uint64_t xss_val;
44 int i, r;
45
46 /* Create VM */
47 vm = vm_create_default(VCPU_ID, 0, 0);
48
49 if (kvm_get_cpuid_max_basic() >= 0xd) {
50 entry = kvm_get_supported_cpuid_index(0xd, 1);
51 xss_supported = entry && !!(entry->eax & X86_FEATURE_XSAVES);
52 }
53 if (!xss_supported) {
54 printf("IA32_XSS is not supported by the vCPU.\n");
55 exit(KSFT_SKIP);
56 }
57
58 xss_val = vcpu_get_msr(vm, VCPU_ID, MSR_IA32_XSS);
59 TEST_ASSERT(xss_val == 0,
60 "MSR_IA32_XSS should be initialized to zero\n");
61
62 vcpu_set_msr(vm, VCPU_ID, MSR_IA32_XSS, xss_val);
63 /*
64 * At present, KVM only supports a guest IA32_XSS value of 0. Verify
65 * that trying to set the guest IA32_XSS to an unsupported value fails.
66 * Also, in the future when a non-zero value succeeds check that
67 * IA32_XSS is in the KVM_GET_MSR_INDEX_LIST.
68 */
69 for (i = 0; i < MSR_BITS; ++i) {
70 r = _vcpu_set_msr(vm, VCPU_ID, MSR_IA32_XSS, 1ull << i);
71 TEST_ASSERT(r == 0 || is_supported_msr(MSR_IA32_XSS),
72 "IA32_XSS was able to be set, but was not found in KVM_GET_MSR_INDEX_LIST.\n");
73 }
74
75 kvm_vm_free(vm);
76 }
77