xref: /linux/tools/testing/selftests/kvm/x86_64/hyperv_features.c (revision f4b0c4b508364fde023e4f7b9f23f7e38c663dfe)
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