1e2e1cc1fSVitaly Kuznetsov // SPDX-License-Identifier: GPL-2.0-only
2e2e1cc1fSVitaly Kuznetsov /*
3e2e1cc1fSVitaly Kuznetsov * Copyright (C) 2021, Red Hat, Inc.
4e2e1cc1fSVitaly Kuznetsov *
5e2e1cc1fSVitaly Kuznetsov * Tests for Hyper-V features enablement
6e2e1cc1fSVitaly Kuznetsov */
7e2e1cc1fSVitaly Kuznetsov #include <asm/kvm_para.h>
8e2e1cc1fSVitaly Kuznetsov #include <linux/kvm_para.h>
9e2e1cc1fSVitaly Kuznetsov #include <stdint.h>
10e2e1cc1fSVitaly Kuznetsov
11e2e1cc1fSVitaly Kuznetsov #include "test_util.h"
12e2e1cc1fSVitaly Kuznetsov #include "kvm_util.h"
13e2e1cc1fSVitaly Kuznetsov #include "processor.h"
14e2e1cc1fSVitaly Kuznetsov #include "hyperv.h"
15e2e1cc1fSVitaly Kuznetsov
162f10428aSVitaly Kuznetsov /*
172f10428aSVitaly Kuznetsov * HYPERV_CPUID_ENLIGHTMENT_INFO.EBX is not a 'feature' CPUID leaf
182f10428aSVitaly Kuznetsov * but to activate the feature it is sufficient to set it to a non-zero
192f10428aSVitaly Kuznetsov * value. Use BIT(0) for that.
202f10428aSVitaly Kuznetsov */
212f10428aSVitaly Kuznetsov #define HV_PV_SPINLOCKS_TEST \
222f10428aSVitaly Kuznetsov KVM_X86_CPU_FEATURE(HYPERV_CPUID_ENLIGHTMENT_INFO, 0, EBX, 0)
232f10428aSVitaly Kuznetsov
24e2e1cc1fSVitaly Kuznetsov struct msr_data {
25e2e1cc1fSVitaly Kuznetsov uint32_t idx;
2667b16f18SVitaly Kuznetsov bool fault_expected;
27e2e1cc1fSVitaly Kuznetsov bool write;
28e2e1cc1fSVitaly Kuznetsov u64 write_val;
29e2e1cc1fSVitaly Kuznetsov };
30e2e1cc1fSVitaly Kuznetsov
31e2e1cc1fSVitaly Kuznetsov struct hcall_data {
32e2e1cc1fSVitaly Kuznetsov uint64_t control;
33e2e1cc1fSVitaly Kuznetsov uint64_t expect;
342476b5a1SVitaly Kuznetsov bool ud_expected;
35e2e1cc1fSVitaly Kuznetsov };
36e2e1cc1fSVitaly Kuznetsov
is_write_only_msr(uint32_t msr)3791a0b547SVitaly Kuznetsov static bool is_write_only_msr(uint32_t msr)
3891a0b547SVitaly Kuznetsov {
3991a0b547SVitaly Kuznetsov return msr == HV_X64_MSR_EOI;
4091a0b547SVitaly Kuznetsov }
4191a0b547SVitaly Kuznetsov
guest_msr(struct msr_data * msr)42e2e1cc1fSVitaly Kuznetsov static void guest_msr(struct msr_data *msr)
43e2e1cc1fSVitaly Kuznetsov {
4491a0b547SVitaly Kuznetsov uint8_t vector = 0;
4591a0b547SVitaly Kuznetsov uint64_t msr_val = 0;
46cc5851c6SSean Christopherson
479f88d062SSean Christopherson GUEST_ASSERT(msr->idx);
48e2e1cc1fSVitaly Kuznetsov
4991a0b547SVitaly Kuznetsov if (msr->write)
50cc5851c6SSean Christopherson vector = wrmsr_safe(msr->idx, msr->write_val);
51e2e1cc1fSVitaly Kuznetsov
5291a0b547SVitaly Kuznetsov if (!vector && (!msr->write || !is_write_only_msr(msr->idx)))
5391a0b547SVitaly Kuznetsov vector = rdmsr_safe(msr->idx, &msr_val);
5491a0b547SVitaly Kuznetsov
5567b16f18SVitaly Kuznetsov if (msr->fault_expected)
568d1d3ce6SSean Christopherson __GUEST_ASSERT(vector == GP_VECTOR,
578d1d3ce6SSean Christopherson "Expected #GP on %sMSR(0x%x), got vector '0x%x'",
58f813e6d4SSean Christopherson msr->write ? "WR" : "RD", msr->idx, vector);
5967b16f18SVitaly Kuznetsov else
608d1d3ce6SSean Christopherson __GUEST_ASSERT(!vector,
618d1d3ce6SSean Christopherson "Expected success on %sMSR(0x%x), got vector '0x%x'",
62f813e6d4SSean Christopherson msr->write ? "WR" : "RD", msr->idx, vector);
6391a0b547SVitaly Kuznetsov
6491a0b547SVitaly Kuznetsov if (vector || is_write_only_msr(msr->idx))
6591a0b547SVitaly Kuznetsov goto done;
6691a0b547SVitaly Kuznetsov
6791a0b547SVitaly Kuznetsov if (msr->write)
688d1d3ce6SSean Christopherson __GUEST_ASSERT(!vector,
694d53dcc5SSean Christopherson "WRMSR(0x%x) to '0x%lx', RDMSR read '0x%lx'",
708d1d3ce6SSean Christopherson msr->idx, msr->write_val, msr_val);
71bd827bd7SVitaly Kuznetsov
72bd827bd7SVitaly Kuznetsov /* Invariant TSC bit appears when TSC invariant control MSR is written to */
73bd827bd7SVitaly Kuznetsov if (msr->idx == HV_X64_MSR_TSC_INVARIANT_CONTROL) {
74bd827bd7SVitaly Kuznetsov if (!this_cpu_has(HV_ACCESS_TSC_INVARIANT))
75bd827bd7SVitaly Kuznetsov GUEST_ASSERT(this_cpu_has(X86_FEATURE_INVTSC));
76bd827bd7SVitaly Kuznetsov else
77bd827bd7SVitaly Kuznetsov GUEST_ASSERT(this_cpu_has(X86_FEATURE_INVTSC) ==
78bd827bd7SVitaly Kuznetsov !!(msr_val & HV_INVARIANT_TSC_EXPOSED));
79bd827bd7SVitaly Kuznetsov }
80bd827bd7SVitaly Kuznetsov
8191a0b547SVitaly Kuznetsov done:
82e2e1cc1fSVitaly Kuznetsov GUEST_DONE();
83e2e1cc1fSVitaly Kuznetsov }
84e2e1cc1fSVitaly Kuznetsov
guest_hcall(vm_vaddr_t pgs_gpa,struct hcall_data * hcall)85e2e1cc1fSVitaly Kuznetsov static void guest_hcall(vm_vaddr_t pgs_gpa, struct hcall_data *hcall)
86e2e1cc1fSVitaly Kuznetsov {
872476b5a1SVitaly Kuznetsov u64 res, input, output;
88cc5851c6SSean Christopherson uint8_t vector;
89e2e1cc1fSVitaly Kuznetsov
908d1d3ce6SSean Christopherson GUEST_ASSERT_NE(hcall->control, 0);
919f88d062SSean Christopherson
92c05a0a71SVitaly Kuznetsov wrmsr(HV_X64_MSR_GUEST_OS_ID, HYPERV_LINUX_OS_ID);
93e2e1cc1fSVitaly Kuznetsov wrmsr(HV_X64_MSR_HYPERCALL, pgs_gpa);
94e2e1cc1fSVitaly Kuznetsov
952476b5a1SVitaly Kuznetsov if (!(hcall->control & HV_HYPERCALL_FAST_BIT)) {
962476b5a1SVitaly Kuznetsov input = pgs_gpa;
972476b5a1SVitaly Kuznetsov output = pgs_gpa + 4096;
982476b5a1SVitaly Kuznetsov } else {
992476b5a1SVitaly Kuznetsov input = output = 0;
1002476b5a1SVitaly Kuznetsov }
1012476b5a1SVitaly Kuznetsov
10299848924SVitaly Kuznetsov vector = __hyperv_hypercall(hcall->control, input, output, &res);
103bf3f1158SVipin Sharma if (hcall->ud_expected) {
1048d1d3ce6SSean Christopherson __GUEST_ASSERT(vector == UD_VECTOR,
105f813e6d4SSean Christopherson "Expected #UD for control '%lu', got vector '0x%x'",
1068d1d3ce6SSean Christopherson hcall->control, vector);
107bf3f1158SVipin Sharma } else {
1088d1d3ce6SSean Christopherson __GUEST_ASSERT(!vector,
109f813e6d4SSean Christopherson "Expected no exception for control '%lu', got vector '0x%x'",
1108d1d3ce6SSean Christopherson hcall->control, vector);
1118d1d3ce6SSean Christopherson GUEST_ASSERT_EQ(res, hcall->expect);
112bf3f1158SVipin Sharma }
1132476b5a1SVitaly Kuznetsov
114e2e1cc1fSVitaly Kuznetsov GUEST_DONE();
115e2e1cc1fSVitaly Kuznetsov }
116e2e1cc1fSVitaly Kuznetsov
vcpu_reset_hv_cpuid(struct kvm_vcpu * vcpu)1174dcd130cSSean Christopherson static void vcpu_reset_hv_cpuid(struct kvm_vcpu *vcpu)
118e2e1cc1fSVitaly Kuznetsov {
1194dcd130cSSean Christopherson /*
1204dcd130cSSean Christopherson * Enable all supported Hyper-V features, then clear the leafs holding
1214dcd130cSSean Christopherson * the features that will be tested one by one.
1224dcd130cSSean Christopherson */
1234dcd130cSSean Christopherson vcpu_set_hv_cpuid(vcpu);
1244dcd130cSSean Christopherson
1254dcd130cSSean Christopherson vcpu_clear_cpuid_entry(vcpu, HYPERV_CPUID_FEATURES);
1264dcd130cSSean Christopherson vcpu_clear_cpuid_entry(vcpu, HYPERV_CPUID_ENLIGHTMENT_INFO);
1274dcd130cSSean Christopherson vcpu_clear_cpuid_entry(vcpu, HYPERV_CPUID_SYNDBG_PLATFORM_CAPABILITIES);
128e2e1cc1fSVitaly Kuznetsov }
129e2e1cc1fSVitaly Kuznetsov
guest_test_msrs_access(void)1306c118643SVitaly Kuznetsov static void guest_test_msrs_access(void)
131e2e1cc1fSVitaly Kuznetsov {
1324dcd130cSSean Christopherson struct kvm_cpuid2 *prev_cpuid = NULL;
133d96b9596SSean Christopherson struct kvm_vcpu *vcpu;
1346c118643SVitaly Kuznetsov struct kvm_vm *vm;
135e2e1cc1fSVitaly Kuznetsov struct ucall uc;
136d96b9596SSean Christopherson int stage = 0;
1376c118643SVitaly Kuznetsov vm_vaddr_t msr_gva;
1386c118643SVitaly Kuznetsov struct msr_data *msr;
139bd827bd7SVitaly Kuznetsov bool has_invtsc = kvm_cpu_has(X86_FEATURE_INVTSC);
1406c118643SVitaly Kuznetsov
1416c118643SVitaly Kuznetsov while (true) {
142d96b9596SSean Christopherson vm = vm_create_with_one_vcpu(&vcpu, guest_msr);
1436c118643SVitaly Kuznetsov
1446c118643SVitaly Kuznetsov msr_gva = vm_vaddr_alloc_page(vm);
1456c118643SVitaly Kuznetsov memset(addr_gva2hva(vm, msr_gva), 0x0, getpagesize());
1466c118643SVitaly Kuznetsov msr = addr_gva2hva(vm, msr_gva);
1476c118643SVitaly Kuznetsov
148768e9a61SSean Christopherson vcpu_args_set(vcpu, 1, msr_gva);
149768e9a61SSean Christopherson vcpu_enable_cap(vcpu, KVM_CAP_HYPERV_ENFORCE_CPUID, 1);
1506c118643SVitaly Kuznetsov
1514dcd130cSSean Christopherson if (!prev_cpuid) {
1524dcd130cSSean Christopherson vcpu_reset_hv_cpuid(vcpu);
1536c118643SVitaly Kuznetsov
1544dcd130cSSean Christopherson prev_cpuid = allocate_kvm_cpuid2(vcpu->cpuid->nent);
1554dcd130cSSean Christopherson } else {
1564dcd130cSSean Christopherson vcpu_init_cpuid(vcpu, prev_cpuid);
1574dcd130cSSean Christopherson }
1584dcd130cSSean Christopherson
1599f88d062SSean Christopherson /* TODO: Make this entire test easier to maintain. */
1609f88d062SSean Christopherson if (stage >= 21)
1619f88d062SSean Christopherson vcpu_enable_cap(vcpu, KVM_CAP_HYPERV_SYNIC2, 0);
1629f88d062SSean Christopherson
163e2e1cc1fSVitaly Kuznetsov switch (stage) {
164e2e1cc1fSVitaly Kuznetsov case 0:
165e2e1cc1fSVitaly Kuznetsov /*
166e2e1cc1fSVitaly Kuznetsov * Only available when Hyper-V identification is set
167e2e1cc1fSVitaly Kuznetsov */
168e2e1cc1fSVitaly Kuznetsov msr->idx = HV_X64_MSR_GUEST_OS_ID;
16967b16f18SVitaly Kuznetsov msr->write = false;
17067b16f18SVitaly Kuznetsov msr->fault_expected = true;
171e2e1cc1fSVitaly Kuznetsov break;
172e2e1cc1fSVitaly Kuznetsov case 1:
173e2e1cc1fSVitaly Kuznetsov msr->idx = HV_X64_MSR_HYPERCALL;
17467b16f18SVitaly Kuznetsov msr->write = false;
17567b16f18SVitaly Kuznetsov msr->fault_expected = true;
176e2e1cc1fSVitaly Kuznetsov break;
177e2e1cc1fSVitaly Kuznetsov case 2:
1782f10428aSVitaly Kuznetsov vcpu_set_cpuid_feature(vcpu, HV_MSR_HYPERCALL_AVAILABLE);
179e2e1cc1fSVitaly Kuznetsov /*
180e2e1cc1fSVitaly Kuznetsov * HV_X64_MSR_GUEST_OS_ID has to be written first to make
181e2e1cc1fSVitaly Kuznetsov * HV_X64_MSR_HYPERCALL available.
182e2e1cc1fSVitaly Kuznetsov */
183e2e1cc1fSVitaly Kuznetsov msr->idx = HV_X64_MSR_GUEST_OS_ID;
18467b16f18SVitaly Kuznetsov msr->write = true;
185c05a0a71SVitaly Kuznetsov msr->write_val = HYPERV_LINUX_OS_ID;
18667b16f18SVitaly Kuznetsov msr->fault_expected = false;
187e2e1cc1fSVitaly Kuznetsov break;
188e2e1cc1fSVitaly Kuznetsov case 3:
189e2e1cc1fSVitaly Kuznetsov msr->idx = HV_X64_MSR_GUEST_OS_ID;
19067b16f18SVitaly Kuznetsov msr->write = false;
19167b16f18SVitaly Kuznetsov msr->fault_expected = false;
192e2e1cc1fSVitaly Kuznetsov break;
193e2e1cc1fSVitaly Kuznetsov case 4:
194e2e1cc1fSVitaly Kuznetsov msr->idx = HV_X64_MSR_HYPERCALL;
19567b16f18SVitaly Kuznetsov msr->write = false;
19667b16f18SVitaly Kuznetsov msr->fault_expected = false;
197e2e1cc1fSVitaly Kuznetsov break;
198e2e1cc1fSVitaly Kuznetsov
199e2e1cc1fSVitaly Kuznetsov case 5:
200e2e1cc1fSVitaly Kuznetsov msr->idx = HV_X64_MSR_VP_RUNTIME;
20167b16f18SVitaly Kuznetsov msr->write = false;
20267b16f18SVitaly Kuznetsov msr->fault_expected = true;
203e2e1cc1fSVitaly Kuznetsov break;
204e2e1cc1fSVitaly Kuznetsov case 6:
2052f10428aSVitaly Kuznetsov vcpu_set_cpuid_feature(vcpu, HV_MSR_VP_RUNTIME_AVAILABLE);
2069f88d062SSean Christopherson msr->idx = HV_X64_MSR_VP_RUNTIME;
20767b16f18SVitaly Kuznetsov msr->write = false;
20867b16f18SVitaly Kuznetsov msr->fault_expected = false;
209e2e1cc1fSVitaly Kuznetsov break;
210e2e1cc1fSVitaly Kuznetsov case 7:
211e2e1cc1fSVitaly Kuznetsov /* Read only */
2129f88d062SSean Christopherson msr->idx = HV_X64_MSR_VP_RUNTIME;
21367b16f18SVitaly Kuznetsov msr->write = true;
214e2e1cc1fSVitaly Kuznetsov msr->write_val = 1;
21567b16f18SVitaly Kuznetsov msr->fault_expected = true;
216e2e1cc1fSVitaly Kuznetsov break;
217e2e1cc1fSVitaly Kuznetsov
218e2e1cc1fSVitaly Kuznetsov case 8:
219e2e1cc1fSVitaly Kuznetsov msr->idx = HV_X64_MSR_TIME_REF_COUNT;
22067b16f18SVitaly Kuznetsov msr->write = false;
22167b16f18SVitaly Kuznetsov msr->fault_expected = true;
222e2e1cc1fSVitaly Kuznetsov break;
223e2e1cc1fSVitaly Kuznetsov case 9:
2242f10428aSVitaly Kuznetsov vcpu_set_cpuid_feature(vcpu, HV_MSR_TIME_REF_COUNT_AVAILABLE);
2259f88d062SSean Christopherson msr->idx = HV_X64_MSR_TIME_REF_COUNT;
22667b16f18SVitaly Kuznetsov msr->write = false;
22767b16f18SVitaly Kuznetsov msr->fault_expected = false;
228e2e1cc1fSVitaly Kuznetsov break;
229e2e1cc1fSVitaly Kuznetsov case 10:
230e2e1cc1fSVitaly Kuznetsov /* Read only */
2319f88d062SSean Christopherson msr->idx = HV_X64_MSR_TIME_REF_COUNT;
23267b16f18SVitaly Kuznetsov msr->write = true;
233e2e1cc1fSVitaly Kuznetsov msr->write_val = 1;
23467b16f18SVitaly Kuznetsov msr->fault_expected = true;
235e2e1cc1fSVitaly Kuznetsov break;
236e2e1cc1fSVitaly Kuznetsov
237e2e1cc1fSVitaly Kuznetsov case 11:
238e2e1cc1fSVitaly Kuznetsov msr->idx = HV_X64_MSR_VP_INDEX;
23967b16f18SVitaly Kuznetsov msr->write = false;
24067b16f18SVitaly Kuznetsov msr->fault_expected = true;
241e2e1cc1fSVitaly Kuznetsov break;
242e2e1cc1fSVitaly Kuznetsov case 12:
2432f10428aSVitaly Kuznetsov vcpu_set_cpuid_feature(vcpu, HV_MSR_VP_INDEX_AVAILABLE);
2449f88d062SSean Christopherson msr->idx = HV_X64_MSR_VP_INDEX;
24567b16f18SVitaly Kuznetsov msr->write = false;
24667b16f18SVitaly Kuznetsov msr->fault_expected = false;
247e2e1cc1fSVitaly Kuznetsov break;
248e2e1cc1fSVitaly Kuznetsov case 13:
249e2e1cc1fSVitaly Kuznetsov /* Read only */
2509f88d062SSean Christopherson msr->idx = HV_X64_MSR_VP_INDEX;
25167b16f18SVitaly Kuznetsov msr->write = true;
252e2e1cc1fSVitaly Kuznetsov msr->write_val = 1;
25367b16f18SVitaly Kuznetsov msr->fault_expected = true;
254e2e1cc1fSVitaly Kuznetsov break;
255e2e1cc1fSVitaly Kuznetsov
256e2e1cc1fSVitaly Kuznetsov case 14:
257e2e1cc1fSVitaly Kuznetsov msr->idx = HV_X64_MSR_RESET;
25867b16f18SVitaly Kuznetsov msr->write = false;
25967b16f18SVitaly Kuznetsov msr->fault_expected = true;
260e2e1cc1fSVitaly Kuznetsov break;
261e2e1cc1fSVitaly Kuznetsov case 15:
2622f10428aSVitaly Kuznetsov vcpu_set_cpuid_feature(vcpu, HV_MSR_RESET_AVAILABLE);
2639f88d062SSean Christopherson msr->idx = HV_X64_MSR_RESET;
26467b16f18SVitaly Kuznetsov msr->write = false;
26567b16f18SVitaly Kuznetsov msr->fault_expected = false;
266e2e1cc1fSVitaly Kuznetsov break;
267e2e1cc1fSVitaly Kuznetsov case 16:
2689f88d062SSean Christopherson msr->idx = HV_X64_MSR_RESET;
26967b16f18SVitaly Kuznetsov msr->write = true;
27091a0b547SVitaly Kuznetsov /*
27191a0b547SVitaly Kuznetsov * TODO: the test only writes '0' to HV_X64_MSR_RESET
27291a0b547SVitaly Kuznetsov * at the moment, writing some other value there will
27391a0b547SVitaly Kuznetsov * trigger real vCPU reset and the code is not prepared
27491a0b547SVitaly Kuznetsov * to handle it yet.
27591a0b547SVitaly Kuznetsov */
276e2e1cc1fSVitaly Kuznetsov msr->write_val = 0;
27767b16f18SVitaly Kuznetsov msr->fault_expected = false;
278e2e1cc1fSVitaly Kuznetsov break;
279e2e1cc1fSVitaly Kuznetsov
280e2e1cc1fSVitaly Kuznetsov case 17:
281e2e1cc1fSVitaly Kuznetsov msr->idx = HV_X64_MSR_REFERENCE_TSC;
28267b16f18SVitaly Kuznetsov msr->write = false;
28367b16f18SVitaly Kuznetsov msr->fault_expected = true;
284e2e1cc1fSVitaly Kuznetsov break;
285e2e1cc1fSVitaly Kuznetsov case 18:
2862f10428aSVitaly Kuznetsov vcpu_set_cpuid_feature(vcpu, HV_MSR_REFERENCE_TSC_AVAILABLE);
2879f88d062SSean Christopherson msr->idx = HV_X64_MSR_REFERENCE_TSC;
28867b16f18SVitaly Kuznetsov msr->write = false;
28967b16f18SVitaly Kuznetsov msr->fault_expected = false;
290e2e1cc1fSVitaly Kuznetsov break;
291e2e1cc1fSVitaly Kuznetsov case 19:
2929f88d062SSean Christopherson msr->idx = HV_X64_MSR_REFERENCE_TSC;
29367b16f18SVitaly Kuznetsov msr->write = true;
294e2e1cc1fSVitaly Kuznetsov msr->write_val = 0;
29567b16f18SVitaly Kuznetsov msr->fault_expected = false;
296e2e1cc1fSVitaly Kuznetsov break;
297e2e1cc1fSVitaly Kuznetsov
298e2e1cc1fSVitaly Kuznetsov case 20:
299e2e1cc1fSVitaly Kuznetsov msr->idx = HV_X64_MSR_EOM;
30067b16f18SVitaly Kuznetsov msr->write = false;
30167b16f18SVitaly Kuznetsov msr->fault_expected = true;
302e2e1cc1fSVitaly Kuznetsov break;
303e2e1cc1fSVitaly Kuznetsov case 21:
304e2e1cc1fSVitaly Kuznetsov /*
305e2e1cc1fSVitaly Kuznetsov * Remains unavailable even with KVM_CAP_HYPERV_SYNIC2
306e2e1cc1fSVitaly Kuznetsov * capability enabled and guest visible CPUID bit unset.
307e2e1cc1fSVitaly Kuznetsov */
3089f88d062SSean Christopherson msr->idx = HV_X64_MSR_EOM;
30967b16f18SVitaly Kuznetsov msr->write = false;
31067b16f18SVitaly Kuznetsov msr->fault_expected = true;
311e2e1cc1fSVitaly Kuznetsov break;
312e2e1cc1fSVitaly Kuznetsov case 22:
3132f10428aSVitaly Kuznetsov vcpu_set_cpuid_feature(vcpu, HV_MSR_SYNIC_AVAILABLE);
3149f88d062SSean Christopherson msr->idx = HV_X64_MSR_EOM;
31567b16f18SVitaly Kuznetsov msr->write = false;
31667b16f18SVitaly Kuznetsov msr->fault_expected = false;
317e2e1cc1fSVitaly Kuznetsov break;
318e2e1cc1fSVitaly Kuznetsov case 23:
3199f88d062SSean Christopherson msr->idx = HV_X64_MSR_EOM;
32067b16f18SVitaly Kuznetsov msr->write = true;
321e2e1cc1fSVitaly Kuznetsov msr->write_val = 0;
32267b16f18SVitaly Kuznetsov msr->fault_expected = false;
323e2e1cc1fSVitaly Kuznetsov break;
324e2e1cc1fSVitaly Kuznetsov
325e2e1cc1fSVitaly Kuznetsov case 24:
326e2e1cc1fSVitaly Kuznetsov msr->idx = HV_X64_MSR_STIMER0_CONFIG;
32767b16f18SVitaly Kuznetsov msr->write = false;
32867b16f18SVitaly Kuznetsov msr->fault_expected = true;
329e2e1cc1fSVitaly Kuznetsov break;
330e2e1cc1fSVitaly Kuznetsov case 25:
3312f10428aSVitaly Kuznetsov vcpu_set_cpuid_feature(vcpu, HV_MSR_SYNTIMER_AVAILABLE);
3329f88d062SSean Christopherson msr->idx = HV_X64_MSR_STIMER0_CONFIG;
33367b16f18SVitaly Kuznetsov msr->write = false;
33467b16f18SVitaly Kuznetsov msr->fault_expected = false;
335e2e1cc1fSVitaly Kuznetsov break;
336e2e1cc1fSVitaly Kuznetsov case 26:
3379f88d062SSean Christopherson msr->idx = HV_X64_MSR_STIMER0_CONFIG;
33867b16f18SVitaly Kuznetsov msr->write = true;
339e2e1cc1fSVitaly Kuznetsov msr->write_val = 0;
34067b16f18SVitaly Kuznetsov msr->fault_expected = false;
341e2e1cc1fSVitaly Kuznetsov break;
342e2e1cc1fSVitaly Kuznetsov case 27:
343e2e1cc1fSVitaly Kuznetsov /* Direct mode test */
3449f88d062SSean Christopherson msr->idx = HV_X64_MSR_STIMER0_CONFIG;
34567b16f18SVitaly Kuznetsov msr->write = true;
346e2e1cc1fSVitaly Kuznetsov msr->write_val = 1 << 12;
34767b16f18SVitaly Kuznetsov msr->fault_expected = true;
348e2e1cc1fSVitaly Kuznetsov break;
349e2e1cc1fSVitaly Kuznetsov case 28:
3502f10428aSVitaly Kuznetsov vcpu_set_cpuid_feature(vcpu, HV_STIMER_DIRECT_MODE_AVAILABLE);
3519f88d062SSean Christopherson msr->idx = HV_X64_MSR_STIMER0_CONFIG;
35267b16f18SVitaly Kuznetsov msr->write = true;
3539f88d062SSean Christopherson msr->write_val = 1 << 12;
35467b16f18SVitaly Kuznetsov msr->fault_expected = false;
355e2e1cc1fSVitaly Kuznetsov break;
356e2e1cc1fSVitaly Kuznetsov
357e2e1cc1fSVitaly Kuznetsov case 29:
358e2e1cc1fSVitaly Kuznetsov msr->idx = HV_X64_MSR_EOI;
35967b16f18SVitaly Kuznetsov msr->write = false;
36067b16f18SVitaly Kuznetsov msr->fault_expected = true;
361e2e1cc1fSVitaly Kuznetsov break;
362e2e1cc1fSVitaly Kuznetsov case 30:
3632f10428aSVitaly Kuznetsov vcpu_set_cpuid_feature(vcpu, HV_MSR_APIC_ACCESS_AVAILABLE);
3649f88d062SSean Christopherson msr->idx = HV_X64_MSR_EOI;
36567b16f18SVitaly Kuznetsov msr->write = true;
366e2e1cc1fSVitaly Kuznetsov msr->write_val = 1;
36767b16f18SVitaly Kuznetsov msr->fault_expected = false;
368e2e1cc1fSVitaly Kuznetsov break;
369e2e1cc1fSVitaly Kuznetsov
370e2e1cc1fSVitaly Kuznetsov case 31:
371e2e1cc1fSVitaly Kuznetsov msr->idx = HV_X64_MSR_TSC_FREQUENCY;
37267b16f18SVitaly Kuznetsov msr->write = false;
37367b16f18SVitaly Kuznetsov msr->fault_expected = true;
374e2e1cc1fSVitaly Kuznetsov break;
375e2e1cc1fSVitaly Kuznetsov case 32:
3762f10428aSVitaly Kuznetsov vcpu_set_cpuid_feature(vcpu, HV_ACCESS_FREQUENCY_MSRS);
3779f88d062SSean Christopherson msr->idx = HV_X64_MSR_TSC_FREQUENCY;
37867b16f18SVitaly Kuznetsov msr->write = false;
37967b16f18SVitaly Kuznetsov msr->fault_expected = false;
380e2e1cc1fSVitaly Kuznetsov break;
381e2e1cc1fSVitaly Kuznetsov case 33:
382e2e1cc1fSVitaly Kuznetsov /* Read only */
3839f88d062SSean Christopherson msr->idx = HV_X64_MSR_TSC_FREQUENCY;
38467b16f18SVitaly Kuznetsov msr->write = true;
385e2e1cc1fSVitaly Kuznetsov msr->write_val = 1;
38667b16f18SVitaly Kuznetsov msr->fault_expected = true;
387e2e1cc1fSVitaly Kuznetsov break;
388e2e1cc1fSVitaly Kuznetsov
389e2e1cc1fSVitaly Kuznetsov case 34:
390e2e1cc1fSVitaly Kuznetsov msr->idx = HV_X64_MSR_REENLIGHTENMENT_CONTROL;
39167b16f18SVitaly Kuznetsov msr->write = false;
39267b16f18SVitaly Kuznetsov msr->fault_expected = true;
393e2e1cc1fSVitaly Kuznetsov break;
394e2e1cc1fSVitaly Kuznetsov case 35:
3952f10428aSVitaly Kuznetsov vcpu_set_cpuid_feature(vcpu, HV_ACCESS_REENLIGHTENMENT);
3969f88d062SSean Christopherson msr->idx = HV_X64_MSR_REENLIGHTENMENT_CONTROL;
39767b16f18SVitaly Kuznetsov msr->write = false;
39867b16f18SVitaly Kuznetsov msr->fault_expected = false;
399e2e1cc1fSVitaly Kuznetsov break;
400e2e1cc1fSVitaly Kuznetsov case 36:
4019f88d062SSean Christopherson msr->idx = HV_X64_MSR_REENLIGHTENMENT_CONTROL;
40267b16f18SVitaly Kuznetsov msr->write = true;
403e2e1cc1fSVitaly Kuznetsov msr->write_val = 1;
40467b16f18SVitaly Kuznetsov msr->fault_expected = false;
405e2e1cc1fSVitaly Kuznetsov break;
406e2e1cc1fSVitaly Kuznetsov case 37:
407e2e1cc1fSVitaly Kuznetsov /* Can only write '0' */
408e2e1cc1fSVitaly Kuznetsov msr->idx = HV_X64_MSR_TSC_EMULATION_STATUS;
40967b16f18SVitaly Kuznetsov msr->write = true;
410e2e1cc1fSVitaly Kuznetsov msr->write_val = 1;
41167b16f18SVitaly Kuznetsov msr->fault_expected = true;
412e2e1cc1fSVitaly Kuznetsov break;
413e2e1cc1fSVitaly Kuznetsov
414e2e1cc1fSVitaly Kuznetsov case 38:
415e2e1cc1fSVitaly Kuznetsov msr->idx = HV_X64_MSR_CRASH_P0;
41667b16f18SVitaly Kuznetsov msr->write = false;
41767b16f18SVitaly Kuznetsov msr->fault_expected = true;
418e2e1cc1fSVitaly Kuznetsov break;
419e2e1cc1fSVitaly Kuznetsov case 39:
4202f10428aSVitaly Kuznetsov vcpu_set_cpuid_feature(vcpu, HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE);
4219f88d062SSean Christopherson msr->idx = HV_X64_MSR_CRASH_P0;
42267b16f18SVitaly Kuznetsov msr->write = false;
42367b16f18SVitaly Kuznetsov msr->fault_expected = false;
424e2e1cc1fSVitaly Kuznetsov break;
425e2e1cc1fSVitaly Kuznetsov case 40:
4269f88d062SSean Christopherson msr->idx = HV_X64_MSR_CRASH_P0;
42767b16f18SVitaly Kuznetsov msr->write = true;
428e2e1cc1fSVitaly Kuznetsov msr->write_val = 1;
42967b16f18SVitaly Kuznetsov msr->fault_expected = false;
430e2e1cc1fSVitaly Kuznetsov break;
431e2e1cc1fSVitaly Kuznetsov
432e2e1cc1fSVitaly Kuznetsov case 41:
433e2e1cc1fSVitaly Kuznetsov msr->idx = HV_X64_MSR_SYNDBG_STATUS;
43467b16f18SVitaly Kuznetsov msr->write = false;
43567b16f18SVitaly Kuznetsov msr->fault_expected = true;
436e2e1cc1fSVitaly Kuznetsov break;
437e2e1cc1fSVitaly Kuznetsov case 42:
4382f10428aSVitaly Kuznetsov vcpu_set_cpuid_feature(vcpu, HV_FEATURE_DEBUG_MSRS_AVAILABLE);
4392f10428aSVitaly Kuznetsov vcpu_set_cpuid_feature(vcpu, HV_X64_SYNDBG_CAP_ALLOW_KERNEL_DEBUGGING);
4409f88d062SSean Christopherson msr->idx = HV_X64_MSR_SYNDBG_STATUS;
44167b16f18SVitaly Kuznetsov msr->write = false;
44267b16f18SVitaly Kuznetsov msr->fault_expected = false;
443e2e1cc1fSVitaly Kuznetsov break;
444e2e1cc1fSVitaly Kuznetsov case 43:
4459f88d062SSean Christopherson msr->idx = HV_X64_MSR_SYNDBG_STATUS;
44667b16f18SVitaly Kuznetsov msr->write = true;
447e2e1cc1fSVitaly Kuznetsov msr->write_val = 0;
44867b16f18SVitaly Kuznetsov msr->fault_expected = false;
449e2e1cc1fSVitaly Kuznetsov break;
450e2e1cc1fSVitaly Kuznetsov
451e2e1cc1fSVitaly Kuznetsov case 44:
452bd827bd7SVitaly Kuznetsov /* MSR is not available when CPUID feature bit is unset */
453bd827bd7SVitaly Kuznetsov if (!has_invtsc)
454*8ad48552SVitaly Kuznetsov goto next_stage;
455bd827bd7SVitaly Kuznetsov msr->idx = HV_X64_MSR_TSC_INVARIANT_CONTROL;
456bd827bd7SVitaly Kuznetsov msr->write = false;
457bd827bd7SVitaly Kuznetsov msr->fault_expected = true;
458bd827bd7SVitaly Kuznetsov break;
459bd827bd7SVitaly Kuznetsov case 45:
460bd827bd7SVitaly Kuznetsov /* MSR is vailable when CPUID feature bit is set */
461bd827bd7SVitaly Kuznetsov if (!has_invtsc)
462*8ad48552SVitaly Kuznetsov goto next_stage;
463bd827bd7SVitaly Kuznetsov vcpu_set_cpuid_feature(vcpu, HV_ACCESS_TSC_INVARIANT);
464bd827bd7SVitaly Kuznetsov msr->idx = HV_X64_MSR_TSC_INVARIANT_CONTROL;
465bd827bd7SVitaly Kuznetsov msr->write = false;
466bd827bd7SVitaly Kuznetsov msr->fault_expected = false;
467bd827bd7SVitaly Kuznetsov break;
468bd827bd7SVitaly Kuznetsov case 46:
469bd827bd7SVitaly Kuznetsov /* Writing bits other than 0 is forbidden */
470bd827bd7SVitaly Kuznetsov if (!has_invtsc)
471*8ad48552SVitaly Kuznetsov goto next_stage;
472bd827bd7SVitaly Kuznetsov msr->idx = HV_X64_MSR_TSC_INVARIANT_CONTROL;
473bd827bd7SVitaly Kuznetsov msr->write = true;
474bd827bd7SVitaly Kuznetsov msr->write_val = 0xdeadbeef;
475bd827bd7SVitaly Kuznetsov msr->fault_expected = true;
476bd827bd7SVitaly Kuznetsov break;
477bd827bd7SVitaly Kuznetsov case 47:
478bd827bd7SVitaly Kuznetsov /* Setting bit 0 enables the feature */
479bd827bd7SVitaly Kuznetsov if (!has_invtsc)
480*8ad48552SVitaly Kuznetsov goto next_stage;
481bd827bd7SVitaly Kuznetsov msr->idx = HV_X64_MSR_TSC_INVARIANT_CONTROL;
482bd827bd7SVitaly Kuznetsov msr->write = true;
483bd827bd7SVitaly Kuznetsov msr->write_val = 1;
484bd827bd7SVitaly Kuznetsov msr->fault_expected = false;
485bd827bd7SVitaly Kuznetsov break;
486bd827bd7SVitaly Kuznetsov
487bd827bd7SVitaly Kuznetsov default:
4889f88d062SSean Christopherson kvm_vm_free(vm);
4899f88d062SSean Christopherson return;
490e2e1cc1fSVitaly Kuznetsov }
491e2e1cc1fSVitaly Kuznetsov
4924dcd130cSSean Christopherson vcpu_set_cpuid(vcpu);
4934dcd130cSSean Christopherson
4944dcd130cSSean Christopherson memcpy(prev_cpuid, vcpu->cpuid, kvm_cpuid2_size(vcpu->cpuid->nent));
495e2e1cc1fSVitaly Kuznetsov
496e2e1cc1fSVitaly Kuznetsov pr_debug("Stage %d: testing msr: 0x%x for %s\n", stage,
497e2e1cc1fSVitaly Kuznetsov msr->idx, msr->write ? "write" : "read");
498e2e1cc1fSVitaly Kuznetsov
499768e9a61SSean Christopherson vcpu_run(vcpu);
500c96f57b0SVipin Sharma TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_IO);
501e2e1cc1fSVitaly Kuznetsov
502768e9a61SSean Christopherson switch (get_ucall(vcpu, &uc)) {
503e2e1cc1fSVitaly Kuznetsov case UCALL_ABORT:
5048d1d3ce6SSean Christopherson REPORT_GUEST_ASSERT(uc);
505e2e1cc1fSVitaly Kuznetsov return;
506e2e1cc1fSVitaly Kuznetsov case UCALL_DONE:
5079f88d062SSean Christopherson break;
5089f88d062SSean Christopherson default:
5099f88d062SSean Christopherson TEST_FAIL("Unhandled ucall: %ld", uc.cmd);
510e2e1cc1fSVitaly Kuznetsov return;
511e2e1cc1fSVitaly Kuznetsov }
512e2e1cc1fSVitaly Kuznetsov
513*8ad48552SVitaly Kuznetsov next_stage:
514e2e1cc1fSVitaly Kuznetsov stage++;
5156c118643SVitaly Kuznetsov kvm_vm_free(vm);
516e2e1cc1fSVitaly Kuznetsov }
517e2e1cc1fSVitaly Kuznetsov }
518e2e1cc1fSVitaly Kuznetsov
guest_test_hcalls_access(void)5196c118643SVitaly Kuznetsov static void guest_test_hcalls_access(void)
520e2e1cc1fSVitaly Kuznetsov {
5214dcd130cSSean Christopherson struct kvm_cpuid2 *prev_cpuid = NULL;
522d96b9596SSean Christopherson struct kvm_vcpu *vcpu;
5236c118643SVitaly Kuznetsov struct kvm_vm *vm;
524e2e1cc1fSVitaly Kuznetsov struct ucall uc;
525d96b9596SSean Christopherson int stage = 0;
5266c118643SVitaly Kuznetsov vm_vaddr_t hcall_page, hcall_params;
5276c118643SVitaly Kuznetsov struct hcall_data *hcall;
5286c118643SVitaly Kuznetsov
5296c118643SVitaly Kuznetsov while (true) {
530d96b9596SSean Christopherson vm = vm_create_with_one_vcpu(&vcpu, guest_hcall);
5316c118643SVitaly Kuznetsov
5326c118643SVitaly Kuznetsov /* Hypercall input/output */
5336c118643SVitaly Kuznetsov hcall_page = vm_vaddr_alloc_pages(vm, 2);
5346c118643SVitaly Kuznetsov memset(addr_gva2hva(vm, hcall_page), 0x0, 2 * getpagesize());
5356c118643SVitaly Kuznetsov
5366c118643SVitaly Kuznetsov hcall_params = vm_vaddr_alloc_page(vm);
5376c118643SVitaly Kuznetsov memset(addr_gva2hva(vm, hcall_params), 0x0, getpagesize());
5389f88d062SSean Christopherson hcall = addr_gva2hva(vm, hcall_params);
5396c118643SVitaly Kuznetsov
540768e9a61SSean Christopherson vcpu_args_set(vcpu, 2, addr_gva2gpa(vm, hcall_page), hcall_params);
541768e9a61SSean Christopherson vcpu_enable_cap(vcpu, KVM_CAP_HYPERV_ENFORCE_CPUID, 1);
5426c118643SVitaly Kuznetsov
5434dcd130cSSean Christopherson if (!prev_cpuid) {
5444dcd130cSSean Christopherson vcpu_reset_hv_cpuid(vcpu);
5456c118643SVitaly Kuznetsov
5464dcd130cSSean Christopherson prev_cpuid = allocate_kvm_cpuid2(vcpu->cpuid->nent);
5474dcd130cSSean Christopherson } else {
5484dcd130cSSean Christopherson vcpu_init_cpuid(vcpu, prev_cpuid);
5494dcd130cSSean Christopherson }
5504dcd130cSSean Christopherson
551e2e1cc1fSVitaly Kuznetsov switch (stage) {
552e2e1cc1fSVitaly Kuznetsov case 0:
5532f10428aSVitaly Kuznetsov vcpu_set_cpuid_feature(vcpu, HV_MSR_HYPERCALL_AVAILABLE);
55431d3b871SVitaly Kuznetsov hcall->control = 0xbeef;
555e2e1cc1fSVitaly Kuznetsov hcall->expect = HV_STATUS_INVALID_HYPERCALL_CODE;
556e2e1cc1fSVitaly Kuznetsov break;
557e2e1cc1fSVitaly Kuznetsov
558e2e1cc1fSVitaly Kuznetsov case 1:
559e2e1cc1fSVitaly Kuznetsov hcall->control = HVCALL_POST_MESSAGE;
560e2e1cc1fSVitaly Kuznetsov hcall->expect = HV_STATUS_ACCESS_DENIED;
561e2e1cc1fSVitaly Kuznetsov break;
562e2e1cc1fSVitaly Kuznetsov case 2:
5632f10428aSVitaly Kuznetsov vcpu_set_cpuid_feature(vcpu, HV_POST_MESSAGES);
5649f88d062SSean Christopherson hcall->control = HVCALL_POST_MESSAGE;
565e2e1cc1fSVitaly Kuznetsov hcall->expect = HV_STATUS_INVALID_HYPERCALL_INPUT;
566e2e1cc1fSVitaly Kuznetsov break;
567e2e1cc1fSVitaly Kuznetsov
568e2e1cc1fSVitaly Kuznetsov case 3:
569e2e1cc1fSVitaly Kuznetsov hcall->control = HVCALL_SIGNAL_EVENT;
570e2e1cc1fSVitaly Kuznetsov hcall->expect = HV_STATUS_ACCESS_DENIED;
571e2e1cc1fSVitaly Kuznetsov break;
572e2e1cc1fSVitaly Kuznetsov case 4:
5732f10428aSVitaly Kuznetsov vcpu_set_cpuid_feature(vcpu, HV_SIGNAL_EVENTS);
5749f88d062SSean Christopherson hcall->control = HVCALL_SIGNAL_EVENT;
575e2e1cc1fSVitaly Kuznetsov hcall->expect = HV_STATUS_INVALID_HYPERCALL_INPUT;
576e2e1cc1fSVitaly Kuznetsov break;
577e2e1cc1fSVitaly Kuznetsov
578e2e1cc1fSVitaly Kuznetsov case 5:
579e2e1cc1fSVitaly Kuznetsov hcall->control = HVCALL_RESET_DEBUG_SESSION;
580e2e1cc1fSVitaly Kuznetsov hcall->expect = HV_STATUS_INVALID_HYPERCALL_CODE;
581e2e1cc1fSVitaly Kuznetsov break;
582e2e1cc1fSVitaly Kuznetsov case 6:
5832f10428aSVitaly Kuznetsov vcpu_set_cpuid_feature(vcpu, HV_X64_SYNDBG_CAP_ALLOW_KERNEL_DEBUGGING);
5849f88d062SSean Christopherson hcall->control = HVCALL_RESET_DEBUG_SESSION;
585e2e1cc1fSVitaly Kuznetsov hcall->expect = HV_STATUS_ACCESS_DENIED;
586e2e1cc1fSVitaly Kuznetsov break;
587e2e1cc1fSVitaly Kuznetsov case 7:
5882f10428aSVitaly Kuznetsov vcpu_set_cpuid_feature(vcpu, HV_DEBUGGING);
5899f88d062SSean Christopherson hcall->control = HVCALL_RESET_DEBUG_SESSION;
590e2e1cc1fSVitaly Kuznetsov hcall->expect = HV_STATUS_OPERATION_DENIED;
591e2e1cc1fSVitaly Kuznetsov break;
592e2e1cc1fSVitaly Kuznetsov
593e2e1cc1fSVitaly Kuznetsov case 8:
594e2e1cc1fSVitaly Kuznetsov hcall->control = HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE;
595e2e1cc1fSVitaly Kuznetsov hcall->expect = HV_STATUS_ACCESS_DENIED;
596e2e1cc1fSVitaly Kuznetsov break;
597e2e1cc1fSVitaly Kuznetsov case 9:
5982f10428aSVitaly Kuznetsov vcpu_set_cpuid_feature(vcpu, HV_X64_REMOTE_TLB_FLUSH_RECOMMENDED);
5999f88d062SSean Christopherson hcall->control = HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE;
600e2e1cc1fSVitaly Kuznetsov hcall->expect = HV_STATUS_SUCCESS;
601e2e1cc1fSVitaly Kuznetsov break;
602e2e1cc1fSVitaly Kuznetsov case 10:
603e2e1cc1fSVitaly Kuznetsov hcall->control = HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE_EX;
604e2e1cc1fSVitaly Kuznetsov hcall->expect = HV_STATUS_ACCESS_DENIED;
605e2e1cc1fSVitaly Kuznetsov break;
606e2e1cc1fSVitaly Kuznetsov case 11:
6072f10428aSVitaly Kuznetsov vcpu_set_cpuid_feature(vcpu, HV_X64_EX_PROCESSOR_MASKS_RECOMMENDED);
6089f88d062SSean Christopherson hcall->control = HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE_EX;
609e2e1cc1fSVitaly Kuznetsov hcall->expect = HV_STATUS_SUCCESS;
610e2e1cc1fSVitaly Kuznetsov break;
611e2e1cc1fSVitaly Kuznetsov
612e2e1cc1fSVitaly Kuznetsov case 12:
613e2e1cc1fSVitaly Kuznetsov hcall->control = HVCALL_SEND_IPI;
614e2e1cc1fSVitaly Kuznetsov hcall->expect = HV_STATUS_ACCESS_DENIED;
615e2e1cc1fSVitaly Kuznetsov break;
616e2e1cc1fSVitaly Kuznetsov case 13:
6172f10428aSVitaly Kuznetsov vcpu_set_cpuid_feature(vcpu, HV_X64_CLUSTER_IPI_RECOMMENDED);
6189f88d062SSean Christopherson hcall->control = HVCALL_SEND_IPI;
619e2e1cc1fSVitaly Kuznetsov hcall->expect = HV_STATUS_INVALID_HYPERCALL_INPUT;
620e2e1cc1fSVitaly Kuznetsov break;
621e2e1cc1fSVitaly Kuznetsov case 14:
622e2e1cc1fSVitaly Kuznetsov /* Nothing in 'sparse banks' -> success */
623e2e1cc1fSVitaly Kuznetsov hcall->control = HVCALL_SEND_IPI_EX;
624e2e1cc1fSVitaly Kuznetsov hcall->expect = HV_STATUS_SUCCESS;
625e2e1cc1fSVitaly Kuznetsov break;
626e2e1cc1fSVitaly Kuznetsov
627e2e1cc1fSVitaly Kuznetsov case 15:
628e2e1cc1fSVitaly Kuznetsov hcall->control = HVCALL_NOTIFY_LONG_SPIN_WAIT;
629e2e1cc1fSVitaly Kuznetsov hcall->expect = HV_STATUS_ACCESS_DENIED;
630e2e1cc1fSVitaly Kuznetsov break;
631e2e1cc1fSVitaly Kuznetsov case 16:
6322f10428aSVitaly Kuznetsov vcpu_set_cpuid_feature(vcpu, HV_PV_SPINLOCKS_TEST);
6339f88d062SSean Christopherson hcall->control = HVCALL_NOTIFY_LONG_SPIN_WAIT;
634e2e1cc1fSVitaly Kuznetsov hcall->expect = HV_STATUS_SUCCESS;
635e2e1cc1fSVitaly Kuznetsov break;
636e2e1cc1fSVitaly Kuznetsov case 17:
6372476b5a1SVitaly Kuznetsov /* XMM fast hypercall */
6382476b5a1SVitaly Kuznetsov hcall->control = HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE | HV_HYPERCALL_FAST_BIT;
6392476b5a1SVitaly Kuznetsov hcall->ud_expected = true;
6402476b5a1SVitaly Kuznetsov break;
6412476b5a1SVitaly Kuznetsov case 18:
6422f10428aSVitaly Kuznetsov vcpu_set_cpuid_feature(vcpu, HV_X64_HYPERCALL_XMM_INPUT_AVAILABLE);
6439f88d062SSean Christopherson hcall->control = HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE | HV_HYPERCALL_FAST_BIT;
6442476b5a1SVitaly Kuznetsov hcall->ud_expected = false;
6452476b5a1SVitaly Kuznetsov hcall->expect = HV_STATUS_SUCCESS;
6462476b5a1SVitaly Kuznetsov break;
6472476b5a1SVitaly Kuznetsov case 19:
648c4a46627SVipin Sharma hcall->control = HV_EXT_CALL_QUERY_CAPABILITIES;
649c4a46627SVipin Sharma hcall->expect = HV_STATUS_ACCESS_DENIED;
650c4a46627SVipin Sharma break;
651c4a46627SVipin Sharma case 20:
652c4a46627SVipin Sharma vcpu_set_cpuid_feature(vcpu, HV_ENABLE_EXTENDED_HYPERCALLS);
653c4a46627SVipin Sharma hcall->control = HV_EXT_CALL_QUERY_CAPABILITIES | HV_HYPERCALL_FAST_BIT;
654c4a46627SVipin Sharma hcall->expect = HV_STATUS_INVALID_PARAMETER;
655c4a46627SVipin Sharma break;
656c4a46627SVipin Sharma case 21:
6579f88d062SSean Christopherson kvm_vm_free(vm);
6589f88d062SSean Christopherson return;
659e2e1cc1fSVitaly Kuznetsov }
660e2e1cc1fSVitaly Kuznetsov
6614dcd130cSSean Christopherson vcpu_set_cpuid(vcpu);
6624dcd130cSSean Christopherson
6634dcd130cSSean Christopherson memcpy(prev_cpuid, vcpu->cpuid, kvm_cpuid2_size(vcpu->cpuid->nent));
664e2e1cc1fSVitaly Kuznetsov
6659f88d062SSean Christopherson pr_debug("Stage %d: testing hcall: 0x%lx\n", stage, hcall->control);
666e2e1cc1fSVitaly Kuznetsov
667768e9a61SSean Christopherson vcpu_run(vcpu);
668c96f57b0SVipin Sharma TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_IO);
669e2e1cc1fSVitaly Kuznetsov
670768e9a61SSean Christopherson switch (get_ucall(vcpu, &uc)) {
671e2e1cc1fSVitaly Kuznetsov case UCALL_ABORT:
6728d1d3ce6SSean Christopherson REPORT_GUEST_ASSERT(uc);
673e2e1cc1fSVitaly Kuznetsov return;
674e2e1cc1fSVitaly Kuznetsov case UCALL_DONE:
6759f88d062SSean Christopherson break;
6769f88d062SSean Christopherson default:
6779f88d062SSean Christopherson TEST_FAIL("Unhandled ucall: %ld", uc.cmd);
678e2e1cc1fSVitaly Kuznetsov return;
679e2e1cc1fSVitaly Kuznetsov }
680e2e1cc1fSVitaly Kuznetsov
681e2e1cc1fSVitaly Kuznetsov stage++;
6826c118643SVitaly Kuznetsov kvm_vm_free(vm);
683e2e1cc1fSVitaly Kuznetsov }
684e2e1cc1fSVitaly Kuznetsov }
685e2e1cc1fSVitaly Kuznetsov
main(void)686e2e1cc1fSVitaly Kuznetsov int main(void)
687e2e1cc1fSVitaly Kuznetsov {
6886dac1195SVitaly Kuznetsov TEST_REQUIRE(kvm_has_cap(KVM_CAP_HYPERV_ENFORCE_CPUID));
6896dac1195SVitaly Kuznetsov
690e2e1cc1fSVitaly Kuznetsov pr_info("Testing access to Hyper-V specific MSRs\n");
6916c118643SVitaly Kuznetsov guest_test_msrs_access();
692e2e1cc1fSVitaly Kuznetsov
693e2e1cc1fSVitaly Kuznetsov pr_info("Testing access to Hyper-V hypercalls\n");
6946c118643SVitaly Kuznetsov guest_test_hcalls_access();
695e2e1cc1fSVitaly Kuznetsov }
696