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'",
588d1d3ce6SSean Christopherson msr->idx, msr->write ? "WR" : "RD", vector);
5967b16f18SVitaly Kuznetsov else
608d1d3ce6SSean Christopherson __GUEST_ASSERT(!vector,
618d1d3ce6SSean Christopherson "Expected success on %sMSR(0x%x), got vector '0x%x'",
628d1d3ce6SSean Christopherson msr->idx, msr->write ? "WR" : "RD", 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,
698d1d3ce6SSean Christopherson "WRMSR(0x%x) to '0x%llx', RDMSR read '0x%llx'",
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,
1058d1d3ce6SSean Christopherson "Expected #UD for control '%u', got vector '0x%x'",
1068d1d3ce6SSean Christopherson hcall->control, vector);
107bf3f1158SVipin Sharma } else {
1088d1d3ce6SSean Christopherson __GUEST_ASSERT(!vector,
1098d1d3ce6SSean Christopherson "Expected no exception for control '%u', 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
1596c118643SVitaly Kuznetsov vm_init_descriptor_tables(vm);
160768e9a61SSean Christopherson vcpu_init_descriptor_tables(vcpu);
161e2e1cc1fSVitaly Kuznetsov
1629f88d062SSean Christopherson /* TODO: Make this entire test easier to maintain. */
1639f88d062SSean Christopherson if (stage >= 21)
1649f88d062SSean Christopherson vcpu_enable_cap(vcpu, KVM_CAP_HYPERV_SYNIC2, 0);
1659f88d062SSean Christopherson
166e2e1cc1fSVitaly Kuznetsov switch (stage) {
167e2e1cc1fSVitaly Kuznetsov case 0:
168e2e1cc1fSVitaly Kuznetsov /*
169e2e1cc1fSVitaly Kuznetsov * Only available when Hyper-V identification is set
170e2e1cc1fSVitaly Kuznetsov */
171e2e1cc1fSVitaly Kuznetsov msr->idx = HV_X64_MSR_GUEST_OS_ID;
17267b16f18SVitaly Kuznetsov msr->write = false;
17367b16f18SVitaly Kuznetsov msr->fault_expected = true;
174e2e1cc1fSVitaly Kuznetsov break;
175e2e1cc1fSVitaly Kuznetsov case 1:
176e2e1cc1fSVitaly Kuznetsov msr->idx = HV_X64_MSR_HYPERCALL;
17767b16f18SVitaly Kuznetsov msr->write = false;
17867b16f18SVitaly Kuznetsov msr->fault_expected = true;
179e2e1cc1fSVitaly Kuznetsov break;
180e2e1cc1fSVitaly Kuznetsov case 2:
1812f10428aSVitaly Kuznetsov vcpu_set_cpuid_feature(vcpu, HV_MSR_HYPERCALL_AVAILABLE);
182e2e1cc1fSVitaly Kuznetsov /*
183e2e1cc1fSVitaly Kuznetsov * HV_X64_MSR_GUEST_OS_ID has to be written first to make
184e2e1cc1fSVitaly Kuznetsov * HV_X64_MSR_HYPERCALL available.
185e2e1cc1fSVitaly Kuznetsov */
186e2e1cc1fSVitaly Kuznetsov msr->idx = HV_X64_MSR_GUEST_OS_ID;
18767b16f18SVitaly Kuznetsov msr->write = true;
188c05a0a71SVitaly Kuznetsov msr->write_val = HYPERV_LINUX_OS_ID;
18967b16f18SVitaly Kuznetsov msr->fault_expected = false;
190e2e1cc1fSVitaly Kuznetsov break;
191e2e1cc1fSVitaly Kuznetsov case 3:
192e2e1cc1fSVitaly Kuznetsov msr->idx = HV_X64_MSR_GUEST_OS_ID;
19367b16f18SVitaly Kuznetsov msr->write = false;
19467b16f18SVitaly Kuznetsov msr->fault_expected = false;
195e2e1cc1fSVitaly Kuznetsov break;
196e2e1cc1fSVitaly Kuznetsov case 4:
197e2e1cc1fSVitaly Kuznetsov msr->idx = HV_X64_MSR_HYPERCALL;
19867b16f18SVitaly Kuznetsov msr->write = false;
19967b16f18SVitaly Kuznetsov msr->fault_expected = false;
200e2e1cc1fSVitaly Kuznetsov break;
201e2e1cc1fSVitaly Kuznetsov
202e2e1cc1fSVitaly Kuznetsov case 5:
203e2e1cc1fSVitaly Kuznetsov msr->idx = HV_X64_MSR_VP_RUNTIME;
20467b16f18SVitaly Kuznetsov msr->write = false;
20567b16f18SVitaly Kuznetsov msr->fault_expected = true;
206e2e1cc1fSVitaly Kuznetsov break;
207e2e1cc1fSVitaly Kuznetsov case 6:
2082f10428aSVitaly Kuznetsov vcpu_set_cpuid_feature(vcpu, HV_MSR_VP_RUNTIME_AVAILABLE);
2099f88d062SSean Christopherson msr->idx = HV_X64_MSR_VP_RUNTIME;
21067b16f18SVitaly Kuznetsov msr->write = false;
21167b16f18SVitaly Kuznetsov msr->fault_expected = false;
212e2e1cc1fSVitaly Kuznetsov break;
213e2e1cc1fSVitaly Kuznetsov case 7:
214e2e1cc1fSVitaly Kuznetsov /* Read only */
2159f88d062SSean Christopherson msr->idx = HV_X64_MSR_VP_RUNTIME;
21667b16f18SVitaly Kuznetsov msr->write = true;
217e2e1cc1fSVitaly Kuznetsov msr->write_val = 1;
21867b16f18SVitaly Kuznetsov msr->fault_expected = true;
219e2e1cc1fSVitaly Kuznetsov break;
220e2e1cc1fSVitaly Kuznetsov
221e2e1cc1fSVitaly Kuznetsov case 8:
222e2e1cc1fSVitaly Kuznetsov msr->idx = HV_X64_MSR_TIME_REF_COUNT;
22367b16f18SVitaly Kuznetsov msr->write = false;
22467b16f18SVitaly Kuznetsov msr->fault_expected = true;
225e2e1cc1fSVitaly Kuznetsov break;
226e2e1cc1fSVitaly Kuznetsov case 9:
2272f10428aSVitaly Kuznetsov vcpu_set_cpuid_feature(vcpu, HV_MSR_TIME_REF_COUNT_AVAILABLE);
2289f88d062SSean Christopherson msr->idx = HV_X64_MSR_TIME_REF_COUNT;
22967b16f18SVitaly Kuznetsov msr->write = false;
23067b16f18SVitaly Kuznetsov msr->fault_expected = false;
231e2e1cc1fSVitaly Kuznetsov break;
232e2e1cc1fSVitaly Kuznetsov case 10:
233e2e1cc1fSVitaly Kuznetsov /* Read only */
2349f88d062SSean Christopherson msr->idx = HV_X64_MSR_TIME_REF_COUNT;
23567b16f18SVitaly Kuznetsov msr->write = true;
236e2e1cc1fSVitaly Kuznetsov msr->write_val = 1;
23767b16f18SVitaly Kuznetsov msr->fault_expected = true;
238e2e1cc1fSVitaly Kuznetsov break;
239e2e1cc1fSVitaly Kuznetsov
240e2e1cc1fSVitaly Kuznetsov case 11:
241e2e1cc1fSVitaly Kuznetsov msr->idx = HV_X64_MSR_VP_INDEX;
24267b16f18SVitaly Kuznetsov msr->write = false;
24367b16f18SVitaly Kuznetsov msr->fault_expected = true;
244e2e1cc1fSVitaly Kuznetsov break;
245e2e1cc1fSVitaly Kuznetsov case 12:
2462f10428aSVitaly Kuznetsov vcpu_set_cpuid_feature(vcpu, HV_MSR_VP_INDEX_AVAILABLE);
2479f88d062SSean Christopherson msr->idx = HV_X64_MSR_VP_INDEX;
24867b16f18SVitaly Kuznetsov msr->write = false;
24967b16f18SVitaly Kuznetsov msr->fault_expected = false;
250e2e1cc1fSVitaly Kuznetsov break;
251e2e1cc1fSVitaly Kuznetsov case 13:
252e2e1cc1fSVitaly Kuznetsov /* Read only */
2539f88d062SSean Christopherson msr->idx = HV_X64_MSR_VP_INDEX;
25467b16f18SVitaly Kuznetsov msr->write = true;
255e2e1cc1fSVitaly Kuznetsov msr->write_val = 1;
25667b16f18SVitaly Kuznetsov msr->fault_expected = true;
257e2e1cc1fSVitaly Kuznetsov break;
258e2e1cc1fSVitaly Kuznetsov
259e2e1cc1fSVitaly Kuznetsov case 14:
260e2e1cc1fSVitaly Kuznetsov msr->idx = HV_X64_MSR_RESET;
26167b16f18SVitaly Kuznetsov msr->write = false;
26267b16f18SVitaly Kuznetsov msr->fault_expected = true;
263e2e1cc1fSVitaly Kuznetsov break;
264e2e1cc1fSVitaly Kuznetsov case 15:
2652f10428aSVitaly Kuznetsov vcpu_set_cpuid_feature(vcpu, HV_MSR_RESET_AVAILABLE);
2669f88d062SSean Christopherson msr->idx = HV_X64_MSR_RESET;
26767b16f18SVitaly Kuznetsov msr->write = false;
26867b16f18SVitaly Kuznetsov msr->fault_expected = false;
269e2e1cc1fSVitaly Kuznetsov break;
270e2e1cc1fSVitaly Kuznetsov case 16:
2719f88d062SSean Christopherson msr->idx = HV_X64_MSR_RESET;
27267b16f18SVitaly Kuznetsov msr->write = true;
27391a0b547SVitaly Kuznetsov /*
27491a0b547SVitaly Kuznetsov * TODO: the test only writes '0' to HV_X64_MSR_RESET
27591a0b547SVitaly Kuznetsov * at the moment, writing some other value there will
27691a0b547SVitaly Kuznetsov * trigger real vCPU reset and the code is not prepared
27791a0b547SVitaly Kuznetsov * to handle it yet.
27891a0b547SVitaly Kuznetsov */
279e2e1cc1fSVitaly Kuznetsov msr->write_val = 0;
28067b16f18SVitaly Kuznetsov msr->fault_expected = false;
281e2e1cc1fSVitaly Kuznetsov break;
282e2e1cc1fSVitaly Kuznetsov
283e2e1cc1fSVitaly Kuznetsov case 17:
284e2e1cc1fSVitaly Kuznetsov msr->idx = HV_X64_MSR_REFERENCE_TSC;
28567b16f18SVitaly Kuznetsov msr->write = false;
28667b16f18SVitaly Kuznetsov msr->fault_expected = true;
287e2e1cc1fSVitaly Kuznetsov break;
288e2e1cc1fSVitaly Kuznetsov case 18:
2892f10428aSVitaly Kuznetsov vcpu_set_cpuid_feature(vcpu, HV_MSR_REFERENCE_TSC_AVAILABLE);
2909f88d062SSean Christopherson msr->idx = HV_X64_MSR_REFERENCE_TSC;
29167b16f18SVitaly Kuznetsov msr->write = false;
29267b16f18SVitaly Kuznetsov msr->fault_expected = false;
293e2e1cc1fSVitaly Kuznetsov break;
294e2e1cc1fSVitaly Kuznetsov case 19:
2959f88d062SSean Christopherson msr->idx = HV_X64_MSR_REFERENCE_TSC;
29667b16f18SVitaly Kuznetsov msr->write = true;
297e2e1cc1fSVitaly Kuznetsov msr->write_val = 0;
29867b16f18SVitaly Kuznetsov msr->fault_expected = false;
299e2e1cc1fSVitaly Kuznetsov break;
300e2e1cc1fSVitaly Kuznetsov
301e2e1cc1fSVitaly Kuznetsov case 20:
302e2e1cc1fSVitaly Kuznetsov msr->idx = HV_X64_MSR_EOM;
30367b16f18SVitaly Kuznetsov msr->write = false;
30467b16f18SVitaly Kuznetsov msr->fault_expected = true;
305e2e1cc1fSVitaly Kuznetsov break;
306e2e1cc1fSVitaly Kuznetsov case 21:
307e2e1cc1fSVitaly Kuznetsov /*
308e2e1cc1fSVitaly Kuznetsov * Remains unavailable even with KVM_CAP_HYPERV_SYNIC2
309e2e1cc1fSVitaly Kuznetsov * capability enabled and guest visible CPUID bit unset.
310e2e1cc1fSVitaly Kuznetsov */
3119f88d062SSean Christopherson msr->idx = HV_X64_MSR_EOM;
31267b16f18SVitaly Kuznetsov msr->write = false;
31367b16f18SVitaly Kuznetsov msr->fault_expected = true;
314e2e1cc1fSVitaly Kuznetsov break;
315e2e1cc1fSVitaly Kuznetsov case 22:
3162f10428aSVitaly Kuznetsov vcpu_set_cpuid_feature(vcpu, HV_MSR_SYNIC_AVAILABLE);
3179f88d062SSean Christopherson msr->idx = HV_X64_MSR_EOM;
31867b16f18SVitaly Kuznetsov msr->write = false;
31967b16f18SVitaly Kuznetsov msr->fault_expected = false;
320e2e1cc1fSVitaly Kuznetsov break;
321e2e1cc1fSVitaly Kuznetsov case 23:
3229f88d062SSean Christopherson msr->idx = HV_X64_MSR_EOM;
32367b16f18SVitaly Kuznetsov msr->write = true;
324e2e1cc1fSVitaly Kuznetsov msr->write_val = 0;
32567b16f18SVitaly Kuznetsov msr->fault_expected = false;
326e2e1cc1fSVitaly Kuznetsov break;
327e2e1cc1fSVitaly Kuznetsov
328e2e1cc1fSVitaly Kuznetsov case 24:
329e2e1cc1fSVitaly Kuznetsov msr->idx = HV_X64_MSR_STIMER0_CONFIG;
33067b16f18SVitaly Kuznetsov msr->write = false;
33167b16f18SVitaly Kuznetsov msr->fault_expected = true;
332e2e1cc1fSVitaly Kuznetsov break;
333e2e1cc1fSVitaly Kuznetsov case 25:
3342f10428aSVitaly Kuznetsov vcpu_set_cpuid_feature(vcpu, HV_MSR_SYNTIMER_AVAILABLE);
3359f88d062SSean Christopherson msr->idx = HV_X64_MSR_STIMER0_CONFIG;
33667b16f18SVitaly Kuznetsov msr->write = false;
33767b16f18SVitaly Kuznetsov msr->fault_expected = false;
338e2e1cc1fSVitaly Kuznetsov break;
339e2e1cc1fSVitaly Kuznetsov case 26:
3409f88d062SSean Christopherson msr->idx = HV_X64_MSR_STIMER0_CONFIG;
34167b16f18SVitaly Kuznetsov msr->write = true;
342e2e1cc1fSVitaly Kuznetsov msr->write_val = 0;
34367b16f18SVitaly Kuznetsov msr->fault_expected = false;
344e2e1cc1fSVitaly Kuznetsov break;
345e2e1cc1fSVitaly Kuznetsov case 27:
346e2e1cc1fSVitaly Kuznetsov /* Direct mode test */
3479f88d062SSean Christopherson msr->idx = HV_X64_MSR_STIMER0_CONFIG;
34867b16f18SVitaly Kuznetsov msr->write = true;
349e2e1cc1fSVitaly Kuznetsov msr->write_val = 1 << 12;
35067b16f18SVitaly Kuznetsov msr->fault_expected = true;
351e2e1cc1fSVitaly Kuznetsov break;
352e2e1cc1fSVitaly Kuznetsov case 28:
3532f10428aSVitaly Kuznetsov vcpu_set_cpuid_feature(vcpu, HV_STIMER_DIRECT_MODE_AVAILABLE);
3549f88d062SSean Christopherson msr->idx = HV_X64_MSR_STIMER0_CONFIG;
35567b16f18SVitaly Kuznetsov msr->write = true;
3569f88d062SSean Christopherson msr->write_val = 1 << 12;
35767b16f18SVitaly Kuznetsov msr->fault_expected = false;
358e2e1cc1fSVitaly Kuznetsov break;
359e2e1cc1fSVitaly Kuznetsov
360e2e1cc1fSVitaly Kuznetsov case 29:
361e2e1cc1fSVitaly Kuznetsov msr->idx = HV_X64_MSR_EOI;
36267b16f18SVitaly Kuznetsov msr->write = false;
36367b16f18SVitaly Kuznetsov msr->fault_expected = true;
364e2e1cc1fSVitaly Kuznetsov break;
365e2e1cc1fSVitaly Kuznetsov case 30:
3662f10428aSVitaly Kuznetsov vcpu_set_cpuid_feature(vcpu, HV_MSR_APIC_ACCESS_AVAILABLE);
3679f88d062SSean Christopherson msr->idx = HV_X64_MSR_EOI;
36867b16f18SVitaly Kuznetsov msr->write = true;
369e2e1cc1fSVitaly Kuznetsov msr->write_val = 1;
37067b16f18SVitaly Kuznetsov msr->fault_expected = false;
371e2e1cc1fSVitaly Kuznetsov break;
372e2e1cc1fSVitaly Kuznetsov
373e2e1cc1fSVitaly Kuznetsov case 31:
374e2e1cc1fSVitaly Kuznetsov msr->idx = HV_X64_MSR_TSC_FREQUENCY;
37567b16f18SVitaly Kuznetsov msr->write = false;
37667b16f18SVitaly Kuznetsov msr->fault_expected = true;
377e2e1cc1fSVitaly Kuznetsov break;
378e2e1cc1fSVitaly Kuznetsov case 32:
3792f10428aSVitaly Kuznetsov vcpu_set_cpuid_feature(vcpu, HV_ACCESS_FREQUENCY_MSRS);
3809f88d062SSean Christopherson msr->idx = HV_X64_MSR_TSC_FREQUENCY;
38167b16f18SVitaly Kuznetsov msr->write = false;
38267b16f18SVitaly Kuznetsov msr->fault_expected = false;
383e2e1cc1fSVitaly Kuznetsov break;
384e2e1cc1fSVitaly Kuznetsov case 33:
385e2e1cc1fSVitaly Kuznetsov /* Read only */
3869f88d062SSean Christopherson msr->idx = HV_X64_MSR_TSC_FREQUENCY;
38767b16f18SVitaly Kuznetsov msr->write = true;
388e2e1cc1fSVitaly Kuznetsov msr->write_val = 1;
38967b16f18SVitaly Kuznetsov msr->fault_expected = true;
390e2e1cc1fSVitaly Kuznetsov break;
391e2e1cc1fSVitaly Kuznetsov
392e2e1cc1fSVitaly Kuznetsov case 34:
393e2e1cc1fSVitaly Kuznetsov msr->idx = HV_X64_MSR_REENLIGHTENMENT_CONTROL;
39467b16f18SVitaly Kuznetsov msr->write = false;
39567b16f18SVitaly Kuznetsov msr->fault_expected = true;
396e2e1cc1fSVitaly Kuznetsov break;
397e2e1cc1fSVitaly Kuznetsov case 35:
3982f10428aSVitaly Kuznetsov vcpu_set_cpuid_feature(vcpu, HV_ACCESS_REENLIGHTENMENT);
3999f88d062SSean Christopherson msr->idx = HV_X64_MSR_REENLIGHTENMENT_CONTROL;
40067b16f18SVitaly Kuznetsov msr->write = false;
40167b16f18SVitaly Kuznetsov msr->fault_expected = false;
402e2e1cc1fSVitaly Kuznetsov break;
403e2e1cc1fSVitaly Kuznetsov case 36:
4049f88d062SSean Christopherson msr->idx = HV_X64_MSR_REENLIGHTENMENT_CONTROL;
40567b16f18SVitaly Kuznetsov msr->write = true;
406e2e1cc1fSVitaly Kuznetsov msr->write_val = 1;
40767b16f18SVitaly Kuznetsov msr->fault_expected = false;
408e2e1cc1fSVitaly Kuznetsov break;
409e2e1cc1fSVitaly Kuznetsov case 37:
410e2e1cc1fSVitaly Kuznetsov /* Can only write '0' */
411e2e1cc1fSVitaly Kuznetsov msr->idx = HV_X64_MSR_TSC_EMULATION_STATUS;
41267b16f18SVitaly Kuznetsov msr->write = true;
413e2e1cc1fSVitaly Kuznetsov msr->write_val = 1;
41467b16f18SVitaly Kuznetsov msr->fault_expected = true;
415e2e1cc1fSVitaly Kuznetsov break;
416e2e1cc1fSVitaly Kuznetsov
417e2e1cc1fSVitaly Kuznetsov case 38:
418e2e1cc1fSVitaly Kuznetsov msr->idx = HV_X64_MSR_CRASH_P0;
41967b16f18SVitaly Kuznetsov msr->write = false;
42067b16f18SVitaly Kuznetsov msr->fault_expected = true;
421e2e1cc1fSVitaly Kuznetsov break;
422e2e1cc1fSVitaly Kuznetsov case 39:
4232f10428aSVitaly Kuznetsov vcpu_set_cpuid_feature(vcpu, HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE);
4249f88d062SSean Christopherson msr->idx = HV_X64_MSR_CRASH_P0;
42567b16f18SVitaly Kuznetsov msr->write = false;
42667b16f18SVitaly Kuznetsov msr->fault_expected = false;
427e2e1cc1fSVitaly Kuznetsov break;
428e2e1cc1fSVitaly Kuznetsov case 40:
4299f88d062SSean Christopherson msr->idx = HV_X64_MSR_CRASH_P0;
43067b16f18SVitaly Kuznetsov msr->write = true;
431e2e1cc1fSVitaly Kuznetsov msr->write_val = 1;
43267b16f18SVitaly Kuznetsov msr->fault_expected = false;
433e2e1cc1fSVitaly Kuznetsov break;
434e2e1cc1fSVitaly Kuznetsov
435e2e1cc1fSVitaly Kuznetsov case 41:
436e2e1cc1fSVitaly Kuznetsov msr->idx = HV_X64_MSR_SYNDBG_STATUS;
43767b16f18SVitaly Kuznetsov msr->write = false;
43867b16f18SVitaly Kuznetsov msr->fault_expected = true;
439e2e1cc1fSVitaly Kuznetsov break;
440e2e1cc1fSVitaly Kuznetsov case 42:
4412f10428aSVitaly Kuznetsov vcpu_set_cpuid_feature(vcpu, HV_FEATURE_DEBUG_MSRS_AVAILABLE);
4422f10428aSVitaly Kuznetsov vcpu_set_cpuid_feature(vcpu, HV_X64_SYNDBG_CAP_ALLOW_KERNEL_DEBUGGING);
4439f88d062SSean Christopherson msr->idx = HV_X64_MSR_SYNDBG_STATUS;
44467b16f18SVitaly Kuznetsov msr->write = false;
44567b16f18SVitaly Kuznetsov msr->fault_expected = false;
446e2e1cc1fSVitaly Kuznetsov break;
447e2e1cc1fSVitaly Kuznetsov case 43:
4489f88d062SSean Christopherson msr->idx = HV_X64_MSR_SYNDBG_STATUS;
44967b16f18SVitaly Kuznetsov msr->write = true;
450e2e1cc1fSVitaly Kuznetsov msr->write_val = 0;
45167b16f18SVitaly Kuznetsov msr->fault_expected = false;
452e2e1cc1fSVitaly Kuznetsov break;
453e2e1cc1fSVitaly Kuznetsov
454e2e1cc1fSVitaly Kuznetsov case 44:
455bd827bd7SVitaly Kuznetsov /* MSR is not available when CPUID feature bit is unset */
456bd827bd7SVitaly Kuznetsov if (!has_invtsc)
457*267f7b04SVitaly Kuznetsov goto next_stage;
458bd827bd7SVitaly Kuznetsov msr->idx = HV_X64_MSR_TSC_INVARIANT_CONTROL;
459bd827bd7SVitaly Kuznetsov msr->write = false;
460bd827bd7SVitaly Kuznetsov msr->fault_expected = true;
461bd827bd7SVitaly Kuznetsov break;
462bd827bd7SVitaly Kuznetsov case 45:
463bd827bd7SVitaly Kuznetsov /* MSR is vailable when CPUID feature bit is set */
464bd827bd7SVitaly Kuznetsov if (!has_invtsc)
465*267f7b04SVitaly Kuznetsov goto next_stage;
466bd827bd7SVitaly Kuznetsov vcpu_set_cpuid_feature(vcpu, HV_ACCESS_TSC_INVARIANT);
467bd827bd7SVitaly Kuznetsov msr->idx = HV_X64_MSR_TSC_INVARIANT_CONTROL;
468bd827bd7SVitaly Kuznetsov msr->write = false;
469bd827bd7SVitaly Kuznetsov msr->fault_expected = false;
470bd827bd7SVitaly Kuznetsov break;
471bd827bd7SVitaly Kuznetsov case 46:
472bd827bd7SVitaly Kuznetsov /* Writing bits other than 0 is forbidden */
473bd827bd7SVitaly Kuznetsov if (!has_invtsc)
474*267f7b04SVitaly Kuznetsov goto next_stage;
475bd827bd7SVitaly Kuznetsov msr->idx = HV_X64_MSR_TSC_INVARIANT_CONTROL;
476bd827bd7SVitaly Kuznetsov msr->write = true;
477bd827bd7SVitaly Kuznetsov msr->write_val = 0xdeadbeef;
478bd827bd7SVitaly Kuznetsov msr->fault_expected = true;
479bd827bd7SVitaly Kuznetsov break;
480bd827bd7SVitaly Kuznetsov case 47:
481bd827bd7SVitaly Kuznetsov /* Setting bit 0 enables the feature */
482bd827bd7SVitaly Kuznetsov if (!has_invtsc)
483*267f7b04SVitaly Kuznetsov goto next_stage;
484bd827bd7SVitaly Kuznetsov msr->idx = HV_X64_MSR_TSC_INVARIANT_CONTROL;
485bd827bd7SVitaly Kuznetsov msr->write = true;
486bd827bd7SVitaly Kuznetsov msr->write_val = 1;
487bd827bd7SVitaly Kuznetsov msr->fault_expected = false;
488bd827bd7SVitaly Kuznetsov break;
489bd827bd7SVitaly Kuznetsov
490bd827bd7SVitaly Kuznetsov default:
4919f88d062SSean Christopherson kvm_vm_free(vm);
4929f88d062SSean Christopherson return;
493e2e1cc1fSVitaly Kuznetsov }
494e2e1cc1fSVitaly Kuznetsov
4954dcd130cSSean Christopherson vcpu_set_cpuid(vcpu);
4964dcd130cSSean Christopherson
4974dcd130cSSean Christopherson memcpy(prev_cpuid, vcpu->cpuid, kvm_cpuid2_size(vcpu->cpuid->nent));
498e2e1cc1fSVitaly Kuznetsov
499e2e1cc1fSVitaly Kuznetsov pr_debug("Stage %d: testing msr: 0x%x for %s\n", stage,
500e2e1cc1fSVitaly Kuznetsov msr->idx, msr->write ? "write" : "read");
501e2e1cc1fSVitaly Kuznetsov
502768e9a61SSean Christopherson vcpu_run(vcpu);
503c96f57b0SVipin Sharma TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_IO);
504e2e1cc1fSVitaly Kuznetsov
505768e9a61SSean Christopherson switch (get_ucall(vcpu, &uc)) {
506e2e1cc1fSVitaly Kuznetsov case UCALL_ABORT:
5078d1d3ce6SSean Christopherson REPORT_GUEST_ASSERT(uc);
508e2e1cc1fSVitaly Kuznetsov return;
509e2e1cc1fSVitaly Kuznetsov case UCALL_DONE:
5109f88d062SSean Christopherson break;
5119f88d062SSean Christopherson default:
5129f88d062SSean Christopherson TEST_FAIL("Unhandled ucall: %ld", uc.cmd);
513e2e1cc1fSVitaly Kuznetsov return;
514e2e1cc1fSVitaly Kuznetsov }
515e2e1cc1fSVitaly Kuznetsov
516*267f7b04SVitaly Kuznetsov next_stage:
517e2e1cc1fSVitaly Kuznetsov stage++;
5186c118643SVitaly Kuznetsov kvm_vm_free(vm);
519e2e1cc1fSVitaly Kuznetsov }
520e2e1cc1fSVitaly Kuznetsov }
521e2e1cc1fSVitaly Kuznetsov
guest_test_hcalls_access(void)5226c118643SVitaly Kuznetsov static void guest_test_hcalls_access(void)
523e2e1cc1fSVitaly Kuznetsov {
5244dcd130cSSean Christopherson struct kvm_cpuid2 *prev_cpuid = NULL;
525d96b9596SSean Christopherson struct kvm_vcpu *vcpu;
5266c118643SVitaly Kuznetsov struct kvm_vm *vm;
527e2e1cc1fSVitaly Kuznetsov struct ucall uc;
528d96b9596SSean Christopherson int stage = 0;
5296c118643SVitaly Kuznetsov vm_vaddr_t hcall_page, hcall_params;
5306c118643SVitaly Kuznetsov struct hcall_data *hcall;
5316c118643SVitaly Kuznetsov
5326c118643SVitaly Kuznetsov while (true) {
533d96b9596SSean Christopherson vm = vm_create_with_one_vcpu(&vcpu, guest_hcall);
5346c118643SVitaly Kuznetsov
5356c118643SVitaly Kuznetsov vm_init_descriptor_tables(vm);
536768e9a61SSean Christopherson vcpu_init_descriptor_tables(vcpu);
5376c118643SVitaly Kuznetsov
5386c118643SVitaly Kuznetsov /* Hypercall input/output */
5396c118643SVitaly Kuznetsov hcall_page = vm_vaddr_alloc_pages(vm, 2);
5406c118643SVitaly Kuznetsov memset(addr_gva2hva(vm, hcall_page), 0x0, 2 * getpagesize());
5416c118643SVitaly Kuznetsov
5426c118643SVitaly Kuznetsov hcall_params = vm_vaddr_alloc_page(vm);
5436c118643SVitaly Kuznetsov memset(addr_gva2hva(vm, hcall_params), 0x0, getpagesize());
5449f88d062SSean Christopherson hcall = addr_gva2hva(vm, hcall_params);
5456c118643SVitaly Kuznetsov
546768e9a61SSean Christopherson vcpu_args_set(vcpu, 2, addr_gva2gpa(vm, hcall_page), hcall_params);
547768e9a61SSean Christopherson vcpu_enable_cap(vcpu, KVM_CAP_HYPERV_ENFORCE_CPUID, 1);
5486c118643SVitaly Kuznetsov
5494dcd130cSSean Christopherson if (!prev_cpuid) {
5504dcd130cSSean Christopherson vcpu_reset_hv_cpuid(vcpu);
5516c118643SVitaly Kuznetsov
5524dcd130cSSean Christopherson prev_cpuid = allocate_kvm_cpuid2(vcpu->cpuid->nent);
5534dcd130cSSean Christopherson } else {
5544dcd130cSSean Christopherson vcpu_init_cpuid(vcpu, prev_cpuid);
5554dcd130cSSean Christopherson }
5564dcd130cSSean Christopherson
557e2e1cc1fSVitaly Kuznetsov switch (stage) {
558e2e1cc1fSVitaly Kuznetsov case 0:
5592f10428aSVitaly Kuznetsov vcpu_set_cpuid_feature(vcpu, HV_MSR_HYPERCALL_AVAILABLE);
56031d3b871SVitaly Kuznetsov hcall->control = 0xbeef;
561e2e1cc1fSVitaly Kuznetsov hcall->expect = HV_STATUS_INVALID_HYPERCALL_CODE;
562e2e1cc1fSVitaly Kuznetsov break;
563e2e1cc1fSVitaly Kuznetsov
564e2e1cc1fSVitaly Kuznetsov case 1:
565e2e1cc1fSVitaly Kuznetsov hcall->control = HVCALL_POST_MESSAGE;
566e2e1cc1fSVitaly Kuznetsov hcall->expect = HV_STATUS_ACCESS_DENIED;
567e2e1cc1fSVitaly Kuznetsov break;
568e2e1cc1fSVitaly Kuznetsov case 2:
5692f10428aSVitaly Kuznetsov vcpu_set_cpuid_feature(vcpu, HV_POST_MESSAGES);
5709f88d062SSean Christopherson hcall->control = HVCALL_POST_MESSAGE;
571e2e1cc1fSVitaly Kuznetsov hcall->expect = HV_STATUS_INVALID_HYPERCALL_INPUT;
572e2e1cc1fSVitaly Kuznetsov break;
573e2e1cc1fSVitaly Kuznetsov
574e2e1cc1fSVitaly Kuznetsov case 3:
575e2e1cc1fSVitaly Kuznetsov hcall->control = HVCALL_SIGNAL_EVENT;
576e2e1cc1fSVitaly Kuznetsov hcall->expect = HV_STATUS_ACCESS_DENIED;
577e2e1cc1fSVitaly Kuznetsov break;
578e2e1cc1fSVitaly Kuznetsov case 4:
5792f10428aSVitaly Kuznetsov vcpu_set_cpuid_feature(vcpu, HV_SIGNAL_EVENTS);
5809f88d062SSean Christopherson hcall->control = HVCALL_SIGNAL_EVENT;
581e2e1cc1fSVitaly Kuznetsov hcall->expect = HV_STATUS_INVALID_HYPERCALL_INPUT;
582e2e1cc1fSVitaly Kuznetsov break;
583e2e1cc1fSVitaly Kuznetsov
584e2e1cc1fSVitaly Kuznetsov case 5:
585e2e1cc1fSVitaly Kuznetsov hcall->control = HVCALL_RESET_DEBUG_SESSION;
586e2e1cc1fSVitaly Kuznetsov hcall->expect = HV_STATUS_INVALID_HYPERCALL_CODE;
587e2e1cc1fSVitaly Kuznetsov break;
588e2e1cc1fSVitaly Kuznetsov case 6:
5892f10428aSVitaly Kuznetsov vcpu_set_cpuid_feature(vcpu, HV_X64_SYNDBG_CAP_ALLOW_KERNEL_DEBUGGING);
5909f88d062SSean Christopherson hcall->control = HVCALL_RESET_DEBUG_SESSION;
591e2e1cc1fSVitaly Kuznetsov hcall->expect = HV_STATUS_ACCESS_DENIED;
592e2e1cc1fSVitaly Kuznetsov break;
593e2e1cc1fSVitaly Kuznetsov case 7:
5942f10428aSVitaly Kuznetsov vcpu_set_cpuid_feature(vcpu, HV_DEBUGGING);
5959f88d062SSean Christopherson hcall->control = HVCALL_RESET_DEBUG_SESSION;
596e2e1cc1fSVitaly Kuznetsov hcall->expect = HV_STATUS_OPERATION_DENIED;
597e2e1cc1fSVitaly Kuznetsov break;
598e2e1cc1fSVitaly Kuznetsov
599e2e1cc1fSVitaly Kuznetsov case 8:
600e2e1cc1fSVitaly Kuznetsov hcall->control = HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE;
601e2e1cc1fSVitaly Kuznetsov hcall->expect = HV_STATUS_ACCESS_DENIED;
602e2e1cc1fSVitaly Kuznetsov break;
603e2e1cc1fSVitaly Kuznetsov case 9:
6042f10428aSVitaly Kuznetsov vcpu_set_cpuid_feature(vcpu, HV_X64_REMOTE_TLB_FLUSH_RECOMMENDED);
6059f88d062SSean Christopherson hcall->control = HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE;
606e2e1cc1fSVitaly Kuznetsov hcall->expect = HV_STATUS_SUCCESS;
607e2e1cc1fSVitaly Kuznetsov break;
608e2e1cc1fSVitaly Kuznetsov case 10:
609e2e1cc1fSVitaly Kuznetsov hcall->control = HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE_EX;
610e2e1cc1fSVitaly Kuznetsov hcall->expect = HV_STATUS_ACCESS_DENIED;
611e2e1cc1fSVitaly Kuznetsov break;
612e2e1cc1fSVitaly Kuznetsov case 11:
6132f10428aSVitaly Kuznetsov vcpu_set_cpuid_feature(vcpu, HV_X64_EX_PROCESSOR_MASKS_RECOMMENDED);
6149f88d062SSean Christopherson hcall->control = HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE_EX;
615e2e1cc1fSVitaly Kuznetsov hcall->expect = HV_STATUS_SUCCESS;
616e2e1cc1fSVitaly Kuznetsov break;
617e2e1cc1fSVitaly Kuznetsov
618e2e1cc1fSVitaly Kuznetsov case 12:
619e2e1cc1fSVitaly Kuznetsov hcall->control = HVCALL_SEND_IPI;
620e2e1cc1fSVitaly Kuznetsov hcall->expect = HV_STATUS_ACCESS_DENIED;
621e2e1cc1fSVitaly Kuznetsov break;
622e2e1cc1fSVitaly Kuznetsov case 13:
6232f10428aSVitaly Kuznetsov vcpu_set_cpuid_feature(vcpu, HV_X64_CLUSTER_IPI_RECOMMENDED);
6249f88d062SSean Christopherson hcall->control = HVCALL_SEND_IPI;
625e2e1cc1fSVitaly Kuznetsov hcall->expect = HV_STATUS_INVALID_HYPERCALL_INPUT;
626e2e1cc1fSVitaly Kuznetsov break;
627e2e1cc1fSVitaly Kuznetsov case 14:
628e2e1cc1fSVitaly Kuznetsov /* Nothing in 'sparse banks' -> success */
629e2e1cc1fSVitaly Kuznetsov hcall->control = HVCALL_SEND_IPI_EX;
630e2e1cc1fSVitaly Kuznetsov hcall->expect = HV_STATUS_SUCCESS;
631e2e1cc1fSVitaly Kuznetsov break;
632e2e1cc1fSVitaly Kuznetsov
633e2e1cc1fSVitaly Kuznetsov case 15:
634e2e1cc1fSVitaly Kuznetsov hcall->control = HVCALL_NOTIFY_LONG_SPIN_WAIT;
635e2e1cc1fSVitaly Kuznetsov hcall->expect = HV_STATUS_ACCESS_DENIED;
636e2e1cc1fSVitaly Kuznetsov break;
637e2e1cc1fSVitaly Kuznetsov case 16:
6382f10428aSVitaly Kuznetsov vcpu_set_cpuid_feature(vcpu, HV_PV_SPINLOCKS_TEST);
6399f88d062SSean Christopherson hcall->control = HVCALL_NOTIFY_LONG_SPIN_WAIT;
640e2e1cc1fSVitaly Kuznetsov hcall->expect = HV_STATUS_SUCCESS;
641e2e1cc1fSVitaly Kuznetsov break;
642e2e1cc1fSVitaly Kuznetsov case 17:
6432476b5a1SVitaly Kuznetsov /* XMM fast hypercall */
6442476b5a1SVitaly Kuznetsov hcall->control = HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE | HV_HYPERCALL_FAST_BIT;
6452476b5a1SVitaly Kuznetsov hcall->ud_expected = true;
6462476b5a1SVitaly Kuznetsov break;
6472476b5a1SVitaly Kuznetsov case 18:
6482f10428aSVitaly Kuznetsov vcpu_set_cpuid_feature(vcpu, HV_X64_HYPERCALL_XMM_INPUT_AVAILABLE);
6499f88d062SSean Christopherson hcall->control = HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE | HV_HYPERCALL_FAST_BIT;
6502476b5a1SVitaly Kuznetsov hcall->ud_expected = false;
6512476b5a1SVitaly Kuznetsov hcall->expect = HV_STATUS_SUCCESS;
6522476b5a1SVitaly Kuznetsov break;
6532476b5a1SVitaly Kuznetsov case 19:
654c4a46627SVipin Sharma hcall->control = HV_EXT_CALL_QUERY_CAPABILITIES;
655c4a46627SVipin Sharma hcall->expect = HV_STATUS_ACCESS_DENIED;
656c4a46627SVipin Sharma break;
657c4a46627SVipin Sharma case 20:
658c4a46627SVipin Sharma vcpu_set_cpuid_feature(vcpu, HV_ENABLE_EXTENDED_HYPERCALLS);
659c4a46627SVipin Sharma hcall->control = HV_EXT_CALL_QUERY_CAPABILITIES | HV_HYPERCALL_FAST_BIT;
660c4a46627SVipin Sharma hcall->expect = HV_STATUS_INVALID_PARAMETER;
661c4a46627SVipin Sharma break;
662c4a46627SVipin Sharma case 21:
6639f88d062SSean Christopherson kvm_vm_free(vm);
6649f88d062SSean Christopherson return;
665e2e1cc1fSVitaly Kuznetsov }
666e2e1cc1fSVitaly Kuznetsov
6674dcd130cSSean Christopherson vcpu_set_cpuid(vcpu);
6684dcd130cSSean Christopherson
6694dcd130cSSean Christopherson memcpy(prev_cpuid, vcpu->cpuid, kvm_cpuid2_size(vcpu->cpuid->nent));
670e2e1cc1fSVitaly Kuznetsov
6719f88d062SSean Christopherson pr_debug("Stage %d: testing hcall: 0x%lx\n", stage, hcall->control);
672e2e1cc1fSVitaly Kuznetsov
673768e9a61SSean Christopherson vcpu_run(vcpu);
674c96f57b0SVipin Sharma TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_IO);
675e2e1cc1fSVitaly Kuznetsov
676768e9a61SSean Christopherson switch (get_ucall(vcpu, &uc)) {
677e2e1cc1fSVitaly Kuznetsov case UCALL_ABORT:
6788d1d3ce6SSean Christopherson REPORT_GUEST_ASSERT(uc);
679e2e1cc1fSVitaly Kuznetsov return;
680e2e1cc1fSVitaly Kuznetsov case UCALL_DONE:
6819f88d062SSean Christopherson break;
6829f88d062SSean Christopherson default:
6839f88d062SSean Christopherson TEST_FAIL("Unhandled ucall: %ld", uc.cmd);
684e2e1cc1fSVitaly Kuznetsov return;
685e2e1cc1fSVitaly Kuznetsov }
686e2e1cc1fSVitaly Kuznetsov
687e2e1cc1fSVitaly Kuznetsov stage++;
6886c118643SVitaly Kuznetsov kvm_vm_free(vm);
689e2e1cc1fSVitaly Kuznetsov }
690e2e1cc1fSVitaly Kuznetsov }
691e2e1cc1fSVitaly Kuznetsov
main(void)692e2e1cc1fSVitaly Kuznetsov int main(void)
693e2e1cc1fSVitaly Kuznetsov {
694e2e1cc1fSVitaly Kuznetsov pr_info("Testing access to Hyper-V specific MSRs\n");
6956c118643SVitaly Kuznetsov guest_test_msrs_access();
696e2e1cc1fSVitaly Kuznetsov
697e2e1cc1fSVitaly Kuznetsov pr_info("Testing access to Hyper-V hypercalls\n");
6986c118643SVitaly Kuznetsov guest_test_hcalls_access();
699e2e1cc1fSVitaly Kuznetsov }
700