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 
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 
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)
5691a0b547SVitaly Kuznetsov 		GUEST_ASSERT_3(vector == GP_VECTOR, msr->idx, vector, GP_VECTOR);
5767b16f18SVitaly Kuznetsov 	else
5891a0b547SVitaly Kuznetsov 		GUEST_ASSERT_3(!vector, msr->idx, vector, 0);
5991a0b547SVitaly Kuznetsov 
6091a0b547SVitaly Kuznetsov 	if (vector || is_write_only_msr(msr->idx))
6191a0b547SVitaly Kuznetsov 		goto done;
6291a0b547SVitaly Kuznetsov 
6391a0b547SVitaly Kuznetsov 	if (msr->write)
6491a0b547SVitaly Kuznetsov 		GUEST_ASSERT_3(msr_val == msr->write_val, msr->idx,
6591a0b547SVitaly Kuznetsov 			       msr_val, msr->write_val);
66bd827bd7SVitaly Kuznetsov 
67bd827bd7SVitaly Kuznetsov 	/* Invariant TSC bit appears when TSC invariant control MSR is written to */
68bd827bd7SVitaly Kuznetsov 	if (msr->idx == HV_X64_MSR_TSC_INVARIANT_CONTROL) {
69bd827bd7SVitaly Kuznetsov 		if (!this_cpu_has(HV_ACCESS_TSC_INVARIANT))
70bd827bd7SVitaly Kuznetsov 			GUEST_ASSERT(this_cpu_has(X86_FEATURE_INVTSC));
71bd827bd7SVitaly Kuznetsov 		else
72bd827bd7SVitaly Kuznetsov 			GUEST_ASSERT(this_cpu_has(X86_FEATURE_INVTSC) ==
73bd827bd7SVitaly Kuznetsov 				     !!(msr_val & HV_INVARIANT_TSC_EXPOSED));
74bd827bd7SVitaly Kuznetsov 	}
75bd827bd7SVitaly Kuznetsov 
7691a0b547SVitaly Kuznetsov done:
77e2e1cc1fSVitaly Kuznetsov 	GUEST_DONE();
78e2e1cc1fSVitaly Kuznetsov }
79e2e1cc1fSVitaly Kuznetsov 
80e2e1cc1fSVitaly Kuznetsov static void guest_hcall(vm_vaddr_t pgs_gpa, struct hcall_data *hcall)
81e2e1cc1fSVitaly Kuznetsov {
822476b5a1SVitaly Kuznetsov 	u64 res, input, output;
83cc5851c6SSean Christopherson 	uint8_t vector;
84e2e1cc1fSVitaly Kuznetsov 
859f88d062SSean Christopherson 	GUEST_ASSERT(hcall->control);
869f88d062SSean Christopherson 
87c05a0a71SVitaly Kuznetsov 	wrmsr(HV_X64_MSR_GUEST_OS_ID, HYPERV_LINUX_OS_ID);
88e2e1cc1fSVitaly Kuznetsov 	wrmsr(HV_X64_MSR_HYPERCALL, pgs_gpa);
89e2e1cc1fSVitaly Kuznetsov 
902476b5a1SVitaly Kuznetsov 	if (!(hcall->control & HV_HYPERCALL_FAST_BIT)) {
912476b5a1SVitaly Kuznetsov 		input = pgs_gpa;
922476b5a1SVitaly Kuznetsov 		output = pgs_gpa + 4096;
932476b5a1SVitaly Kuznetsov 	} else {
942476b5a1SVitaly Kuznetsov 		input = output = 0;
952476b5a1SVitaly Kuznetsov 	}
962476b5a1SVitaly Kuznetsov 
9799848924SVitaly Kuznetsov 	vector = __hyperv_hypercall(hcall->control, input, output, &res);
98bf3f1158SVipin Sharma 	if (hcall->ud_expected) {
99cc5851c6SSean Christopherson 		GUEST_ASSERT_2(vector == UD_VECTOR, hcall->control, vector);
100bf3f1158SVipin Sharma 	} else {
101cc5851c6SSean Christopherson 		GUEST_ASSERT_2(!vector, hcall->control, vector);
102bf3f1158SVipin Sharma 		GUEST_ASSERT_2(res == hcall->expect, hcall->expect, res);
103bf3f1158SVipin Sharma 	}
1042476b5a1SVitaly Kuznetsov 
105e2e1cc1fSVitaly Kuznetsov 	GUEST_DONE();
106e2e1cc1fSVitaly Kuznetsov }
107e2e1cc1fSVitaly Kuznetsov 
1084dcd130cSSean Christopherson static void vcpu_reset_hv_cpuid(struct kvm_vcpu *vcpu)
109e2e1cc1fSVitaly Kuznetsov {
1104dcd130cSSean Christopherson 	/*
1114dcd130cSSean Christopherson 	 * Enable all supported Hyper-V features, then clear the leafs holding
1124dcd130cSSean Christopherson 	 * the features that will be tested one by one.
1134dcd130cSSean Christopherson 	 */
1144dcd130cSSean Christopherson 	vcpu_set_hv_cpuid(vcpu);
1154dcd130cSSean Christopherson 
1164dcd130cSSean Christopherson 	vcpu_clear_cpuid_entry(vcpu, HYPERV_CPUID_FEATURES);
1174dcd130cSSean Christopherson 	vcpu_clear_cpuid_entry(vcpu, HYPERV_CPUID_ENLIGHTMENT_INFO);
1184dcd130cSSean Christopherson 	vcpu_clear_cpuid_entry(vcpu, HYPERV_CPUID_SYNDBG_PLATFORM_CAPABILITIES);
119e2e1cc1fSVitaly Kuznetsov }
120e2e1cc1fSVitaly Kuznetsov 
1216c118643SVitaly Kuznetsov static void guest_test_msrs_access(void)
122e2e1cc1fSVitaly Kuznetsov {
1234dcd130cSSean Christopherson 	struct kvm_cpuid2 *prev_cpuid = NULL;
124d96b9596SSean Christopherson 	struct kvm_vcpu *vcpu;
1256c118643SVitaly Kuznetsov 	struct kvm_vm *vm;
126e2e1cc1fSVitaly Kuznetsov 	struct ucall uc;
127d96b9596SSean Christopherson 	int stage = 0;
1286c118643SVitaly Kuznetsov 	vm_vaddr_t msr_gva;
1296c118643SVitaly Kuznetsov 	struct msr_data *msr;
130bd827bd7SVitaly Kuznetsov 	bool has_invtsc = kvm_cpu_has(X86_FEATURE_INVTSC);
1316c118643SVitaly Kuznetsov 
1326c118643SVitaly Kuznetsov 	while (true) {
133d96b9596SSean Christopherson 		vm = vm_create_with_one_vcpu(&vcpu, guest_msr);
1346c118643SVitaly Kuznetsov 
1356c118643SVitaly Kuznetsov 		msr_gva = vm_vaddr_alloc_page(vm);
1366c118643SVitaly Kuznetsov 		memset(addr_gva2hva(vm, msr_gva), 0x0, getpagesize());
1376c118643SVitaly Kuznetsov 		msr = addr_gva2hva(vm, msr_gva);
1386c118643SVitaly Kuznetsov 
139768e9a61SSean Christopherson 		vcpu_args_set(vcpu, 1, msr_gva);
140768e9a61SSean Christopherson 		vcpu_enable_cap(vcpu, KVM_CAP_HYPERV_ENFORCE_CPUID, 1);
1416c118643SVitaly Kuznetsov 
1424dcd130cSSean Christopherson 		if (!prev_cpuid) {
1434dcd130cSSean Christopherson 			vcpu_reset_hv_cpuid(vcpu);
1446c118643SVitaly Kuznetsov 
1454dcd130cSSean Christopherson 			prev_cpuid = allocate_kvm_cpuid2(vcpu->cpuid->nent);
1464dcd130cSSean Christopherson 		} else {
1474dcd130cSSean Christopherson 			vcpu_init_cpuid(vcpu, prev_cpuid);
1484dcd130cSSean Christopherson 		}
1494dcd130cSSean Christopherson 
1506c118643SVitaly Kuznetsov 		vm_init_descriptor_tables(vm);
151768e9a61SSean Christopherson 		vcpu_init_descriptor_tables(vcpu);
152e2e1cc1fSVitaly Kuznetsov 
1539f88d062SSean Christopherson 		/* TODO: Make this entire test easier to maintain. */
1549f88d062SSean Christopherson 		if (stage >= 21)
1559f88d062SSean Christopherson 			vcpu_enable_cap(vcpu, KVM_CAP_HYPERV_SYNIC2, 0);
1569f88d062SSean Christopherson 
157e2e1cc1fSVitaly Kuznetsov 		switch (stage) {
158e2e1cc1fSVitaly Kuznetsov 		case 0:
159e2e1cc1fSVitaly Kuznetsov 			/*
160e2e1cc1fSVitaly Kuznetsov 			 * Only available when Hyper-V identification is set
161e2e1cc1fSVitaly Kuznetsov 			 */
162e2e1cc1fSVitaly Kuznetsov 			msr->idx = HV_X64_MSR_GUEST_OS_ID;
16367b16f18SVitaly Kuznetsov 			msr->write = false;
16467b16f18SVitaly Kuznetsov 			msr->fault_expected = true;
165e2e1cc1fSVitaly Kuznetsov 			break;
166e2e1cc1fSVitaly Kuznetsov 		case 1:
167e2e1cc1fSVitaly Kuznetsov 			msr->idx = HV_X64_MSR_HYPERCALL;
16867b16f18SVitaly Kuznetsov 			msr->write = false;
16967b16f18SVitaly Kuznetsov 			msr->fault_expected = true;
170e2e1cc1fSVitaly Kuznetsov 			break;
171e2e1cc1fSVitaly Kuznetsov 		case 2:
1722f10428aSVitaly Kuznetsov 			vcpu_set_cpuid_feature(vcpu, HV_MSR_HYPERCALL_AVAILABLE);
173e2e1cc1fSVitaly Kuznetsov 			/*
174e2e1cc1fSVitaly Kuznetsov 			 * HV_X64_MSR_GUEST_OS_ID has to be written first to make
175e2e1cc1fSVitaly Kuznetsov 			 * HV_X64_MSR_HYPERCALL available.
176e2e1cc1fSVitaly Kuznetsov 			 */
177e2e1cc1fSVitaly Kuznetsov 			msr->idx = HV_X64_MSR_GUEST_OS_ID;
17867b16f18SVitaly Kuznetsov 			msr->write = true;
179c05a0a71SVitaly Kuznetsov 			msr->write_val = HYPERV_LINUX_OS_ID;
18067b16f18SVitaly Kuznetsov 			msr->fault_expected = false;
181e2e1cc1fSVitaly Kuznetsov 			break;
182e2e1cc1fSVitaly Kuznetsov 		case 3:
183e2e1cc1fSVitaly Kuznetsov 			msr->idx = HV_X64_MSR_GUEST_OS_ID;
18467b16f18SVitaly Kuznetsov 			msr->write = false;
18567b16f18SVitaly Kuznetsov 			msr->fault_expected = false;
186e2e1cc1fSVitaly Kuznetsov 			break;
187e2e1cc1fSVitaly Kuznetsov 		case 4:
188e2e1cc1fSVitaly Kuznetsov 			msr->idx = HV_X64_MSR_HYPERCALL;
18967b16f18SVitaly Kuznetsov 			msr->write = false;
19067b16f18SVitaly Kuznetsov 			msr->fault_expected = false;
191e2e1cc1fSVitaly Kuznetsov 			break;
192e2e1cc1fSVitaly Kuznetsov 
193e2e1cc1fSVitaly Kuznetsov 		case 5:
194e2e1cc1fSVitaly Kuznetsov 			msr->idx = HV_X64_MSR_VP_RUNTIME;
19567b16f18SVitaly Kuznetsov 			msr->write = false;
19667b16f18SVitaly Kuznetsov 			msr->fault_expected = true;
197e2e1cc1fSVitaly Kuznetsov 			break;
198e2e1cc1fSVitaly Kuznetsov 		case 6:
1992f10428aSVitaly Kuznetsov 			vcpu_set_cpuid_feature(vcpu, HV_MSR_VP_RUNTIME_AVAILABLE);
2009f88d062SSean Christopherson 			msr->idx = HV_X64_MSR_VP_RUNTIME;
20167b16f18SVitaly Kuznetsov 			msr->write = false;
20267b16f18SVitaly Kuznetsov 			msr->fault_expected = false;
203e2e1cc1fSVitaly Kuznetsov 			break;
204e2e1cc1fSVitaly Kuznetsov 		case 7:
205e2e1cc1fSVitaly Kuznetsov 			/* Read only */
2069f88d062SSean Christopherson 			msr->idx = HV_X64_MSR_VP_RUNTIME;
20767b16f18SVitaly Kuznetsov 			msr->write = true;
208e2e1cc1fSVitaly Kuznetsov 			msr->write_val = 1;
20967b16f18SVitaly Kuznetsov 			msr->fault_expected = true;
210e2e1cc1fSVitaly Kuznetsov 			break;
211e2e1cc1fSVitaly Kuznetsov 
212e2e1cc1fSVitaly Kuznetsov 		case 8:
213e2e1cc1fSVitaly Kuznetsov 			msr->idx = HV_X64_MSR_TIME_REF_COUNT;
21467b16f18SVitaly Kuznetsov 			msr->write = false;
21567b16f18SVitaly Kuznetsov 			msr->fault_expected = true;
216e2e1cc1fSVitaly Kuznetsov 			break;
217e2e1cc1fSVitaly Kuznetsov 		case 9:
2182f10428aSVitaly Kuznetsov 			vcpu_set_cpuid_feature(vcpu, HV_MSR_TIME_REF_COUNT_AVAILABLE);
2199f88d062SSean Christopherson 			msr->idx = HV_X64_MSR_TIME_REF_COUNT;
22067b16f18SVitaly Kuznetsov 			msr->write = false;
22167b16f18SVitaly Kuznetsov 			msr->fault_expected = false;
222e2e1cc1fSVitaly Kuznetsov 			break;
223e2e1cc1fSVitaly Kuznetsov 		case 10:
224e2e1cc1fSVitaly Kuznetsov 			/* Read only */
2259f88d062SSean Christopherson 			msr->idx = HV_X64_MSR_TIME_REF_COUNT;
22667b16f18SVitaly Kuznetsov 			msr->write = true;
227e2e1cc1fSVitaly Kuznetsov 			msr->write_val = 1;
22867b16f18SVitaly Kuznetsov 			msr->fault_expected = true;
229e2e1cc1fSVitaly Kuznetsov 			break;
230e2e1cc1fSVitaly Kuznetsov 
231e2e1cc1fSVitaly Kuznetsov 		case 11:
232e2e1cc1fSVitaly Kuznetsov 			msr->idx = HV_X64_MSR_VP_INDEX;
23367b16f18SVitaly Kuznetsov 			msr->write = false;
23467b16f18SVitaly Kuznetsov 			msr->fault_expected = true;
235e2e1cc1fSVitaly Kuznetsov 			break;
236e2e1cc1fSVitaly Kuznetsov 		case 12:
2372f10428aSVitaly Kuznetsov 			vcpu_set_cpuid_feature(vcpu, HV_MSR_VP_INDEX_AVAILABLE);
2389f88d062SSean Christopherson 			msr->idx = HV_X64_MSR_VP_INDEX;
23967b16f18SVitaly Kuznetsov 			msr->write = false;
24067b16f18SVitaly Kuznetsov 			msr->fault_expected = false;
241e2e1cc1fSVitaly Kuznetsov 			break;
242e2e1cc1fSVitaly Kuznetsov 		case 13:
243e2e1cc1fSVitaly Kuznetsov 			/* Read only */
2449f88d062SSean Christopherson 			msr->idx = HV_X64_MSR_VP_INDEX;
24567b16f18SVitaly Kuznetsov 			msr->write = true;
246e2e1cc1fSVitaly Kuznetsov 			msr->write_val = 1;
24767b16f18SVitaly Kuznetsov 			msr->fault_expected = true;
248e2e1cc1fSVitaly Kuznetsov 			break;
249e2e1cc1fSVitaly Kuznetsov 
250e2e1cc1fSVitaly Kuznetsov 		case 14:
251e2e1cc1fSVitaly Kuznetsov 			msr->idx = HV_X64_MSR_RESET;
25267b16f18SVitaly Kuznetsov 			msr->write = false;
25367b16f18SVitaly Kuznetsov 			msr->fault_expected = true;
254e2e1cc1fSVitaly Kuznetsov 			break;
255e2e1cc1fSVitaly Kuznetsov 		case 15:
2562f10428aSVitaly Kuznetsov 			vcpu_set_cpuid_feature(vcpu, HV_MSR_RESET_AVAILABLE);
2579f88d062SSean Christopherson 			msr->idx = HV_X64_MSR_RESET;
25867b16f18SVitaly Kuznetsov 			msr->write = false;
25967b16f18SVitaly Kuznetsov 			msr->fault_expected = false;
260e2e1cc1fSVitaly Kuznetsov 			break;
261e2e1cc1fSVitaly Kuznetsov 		case 16:
2629f88d062SSean Christopherson 			msr->idx = HV_X64_MSR_RESET;
26367b16f18SVitaly Kuznetsov 			msr->write = true;
26491a0b547SVitaly Kuznetsov 			/*
26591a0b547SVitaly Kuznetsov 			 * TODO: the test only writes '0' to HV_X64_MSR_RESET
26691a0b547SVitaly Kuznetsov 			 * at the moment, writing some other value there will
26791a0b547SVitaly Kuznetsov 			 * trigger real vCPU reset and the code is not prepared
26891a0b547SVitaly Kuznetsov 			 * to handle it yet.
26991a0b547SVitaly Kuznetsov 			 */
270e2e1cc1fSVitaly Kuznetsov 			msr->write_val = 0;
27167b16f18SVitaly Kuznetsov 			msr->fault_expected = false;
272e2e1cc1fSVitaly Kuznetsov 			break;
273e2e1cc1fSVitaly Kuznetsov 
274e2e1cc1fSVitaly Kuznetsov 		case 17:
275e2e1cc1fSVitaly Kuznetsov 			msr->idx = HV_X64_MSR_REFERENCE_TSC;
27667b16f18SVitaly Kuznetsov 			msr->write = false;
27767b16f18SVitaly Kuznetsov 			msr->fault_expected = true;
278e2e1cc1fSVitaly Kuznetsov 			break;
279e2e1cc1fSVitaly Kuznetsov 		case 18:
2802f10428aSVitaly Kuznetsov 			vcpu_set_cpuid_feature(vcpu, HV_MSR_REFERENCE_TSC_AVAILABLE);
2819f88d062SSean Christopherson 			msr->idx = HV_X64_MSR_REFERENCE_TSC;
28267b16f18SVitaly Kuznetsov 			msr->write = false;
28367b16f18SVitaly Kuznetsov 			msr->fault_expected = false;
284e2e1cc1fSVitaly Kuznetsov 			break;
285e2e1cc1fSVitaly Kuznetsov 		case 19:
2869f88d062SSean Christopherson 			msr->idx = HV_X64_MSR_REFERENCE_TSC;
28767b16f18SVitaly Kuznetsov 			msr->write = true;
288e2e1cc1fSVitaly Kuznetsov 			msr->write_val = 0;
28967b16f18SVitaly Kuznetsov 			msr->fault_expected = false;
290e2e1cc1fSVitaly Kuznetsov 			break;
291e2e1cc1fSVitaly Kuznetsov 
292e2e1cc1fSVitaly Kuznetsov 		case 20:
293e2e1cc1fSVitaly Kuznetsov 			msr->idx = HV_X64_MSR_EOM;
29467b16f18SVitaly Kuznetsov 			msr->write = false;
29567b16f18SVitaly Kuznetsov 			msr->fault_expected = true;
296e2e1cc1fSVitaly Kuznetsov 			break;
297e2e1cc1fSVitaly Kuznetsov 		case 21:
298e2e1cc1fSVitaly Kuznetsov 			/*
299e2e1cc1fSVitaly Kuznetsov 			 * Remains unavailable even with KVM_CAP_HYPERV_SYNIC2
300e2e1cc1fSVitaly Kuznetsov 			 * capability enabled and guest visible CPUID bit unset.
301e2e1cc1fSVitaly Kuznetsov 			 */
3029f88d062SSean Christopherson 			msr->idx = HV_X64_MSR_EOM;
30367b16f18SVitaly Kuznetsov 			msr->write = false;
30467b16f18SVitaly Kuznetsov 			msr->fault_expected = true;
305e2e1cc1fSVitaly Kuznetsov 			break;
306e2e1cc1fSVitaly Kuznetsov 		case 22:
3072f10428aSVitaly Kuznetsov 			vcpu_set_cpuid_feature(vcpu, HV_MSR_SYNIC_AVAILABLE);
3089f88d062SSean Christopherson 			msr->idx = HV_X64_MSR_EOM;
30967b16f18SVitaly Kuznetsov 			msr->write = false;
31067b16f18SVitaly Kuznetsov 			msr->fault_expected = false;
311e2e1cc1fSVitaly Kuznetsov 			break;
312e2e1cc1fSVitaly Kuznetsov 		case 23:
3139f88d062SSean Christopherson 			msr->idx = HV_X64_MSR_EOM;
31467b16f18SVitaly Kuznetsov 			msr->write = true;
315e2e1cc1fSVitaly Kuznetsov 			msr->write_val = 0;
31667b16f18SVitaly Kuznetsov 			msr->fault_expected = false;
317e2e1cc1fSVitaly Kuznetsov 			break;
318e2e1cc1fSVitaly Kuznetsov 
319e2e1cc1fSVitaly Kuznetsov 		case 24:
320e2e1cc1fSVitaly Kuznetsov 			msr->idx = HV_X64_MSR_STIMER0_CONFIG;
32167b16f18SVitaly Kuznetsov 			msr->write = false;
32267b16f18SVitaly Kuznetsov 			msr->fault_expected = true;
323e2e1cc1fSVitaly Kuznetsov 			break;
324e2e1cc1fSVitaly Kuznetsov 		case 25:
3252f10428aSVitaly Kuznetsov 			vcpu_set_cpuid_feature(vcpu, HV_MSR_SYNTIMER_AVAILABLE);
3269f88d062SSean Christopherson 			msr->idx = HV_X64_MSR_STIMER0_CONFIG;
32767b16f18SVitaly Kuznetsov 			msr->write = false;
32867b16f18SVitaly Kuznetsov 			msr->fault_expected = false;
329e2e1cc1fSVitaly Kuznetsov 			break;
330e2e1cc1fSVitaly Kuznetsov 		case 26:
3319f88d062SSean Christopherson 			msr->idx = HV_X64_MSR_STIMER0_CONFIG;
33267b16f18SVitaly Kuznetsov 			msr->write = true;
333e2e1cc1fSVitaly Kuznetsov 			msr->write_val = 0;
33467b16f18SVitaly Kuznetsov 			msr->fault_expected = false;
335e2e1cc1fSVitaly Kuznetsov 			break;
336e2e1cc1fSVitaly Kuznetsov 		case 27:
337e2e1cc1fSVitaly Kuznetsov 			/* Direct mode test */
3389f88d062SSean Christopherson 			msr->idx = HV_X64_MSR_STIMER0_CONFIG;
33967b16f18SVitaly Kuznetsov 			msr->write = true;
340e2e1cc1fSVitaly Kuznetsov 			msr->write_val = 1 << 12;
34167b16f18SVitaly Kuznetsov 			msr->fault_expected = true;
342e2e1cc1fSVitaly Kuznetsov 			break;
343e2e1cc1fSVitaly Kuznetsov 		case 28:
3442f10428aSVitaly Kuznetsov 			vcpu_set_cpuid_feature(vcpu, HV_STIMER_DIRECT_MODE_AVAILABLE);
3459f88d062SSean Christopherson 			msr->idx = HV_X64_MSR_STIMER0_CONFIG;
34667b16f18SVitaly Kuznetsov 			msr->write = true;
3479f88d062SSean Christopherson 			msr->write_val = 1 << 12;
34867b16f18SVitaly Kuznetsov 			msr->fault_expected = false;
349e2e1cc1fSVitaly Kuznetsov 			break;
350e2e1cc1fSVitaly Kuznetsov 
351e2e1cc1fSVitaly Kuznetsov 		case 29:
352e2e1cc1fSVitaly Kuznetsov 			msr->idx = HV_X64_MSR_EOI;
35367b16f18SVitaly Kuznetsov 			msr->write = false;
35467b16f18SVitaly Kuznetsov 			msr->fault_expected = true;
355e2e1cc1fSVitaly Kuznetsov 			break;
356e2e1cc1fSVitaly Kuznetsov 		case 30:
3572f10428aSVitaly Kuznetsov 			vcpu_set_cpuid_feature(vcpu, HV_MSR_APIC_ACCESS_AVAILABLE);
3589f88d062SSean Christopherson 			msr->idx = HV_X64_MSR_EOI;
35967b16f18SVitaly Kuznetsov 			msr->write = true;
360e2e1cc1fSVitaly Kuznetsov 			msr->write_val = 1;
36167b16f18SVitaly Kuznetsov 			msr->fault_expected = false;
362e2e1cc1fSVitaly Kuznetsov 			break;
363e2e1cc1fSVitaly Kuznetsov 
364e2e1cc1fSVitaly Kuznetsov 		case 31:
365e2e1cc1fSVitaly Kuznetsov 			msr->idx = HV_X64_MSR_TSC_FREQUENCY;
36667b16f18SVitaly Kuznetsov 			msr->write = false;
36767b16f18SVitaly Kuznetsov 			msr->fault_expected = true;
368e2e1cc1fSVitaly Kuznetsov 			break;
369e2e1cc1fSVitaly Kuznetsov 		case 32:
3702f10428aSVitaly Kuznetsov 			vcpu_set_cpuid_feature(vcpu, HV_ACCESS_FREQUENCY_MSRS);
3719f88d062SSean Christopherson 			msr->idx = HV_X64_MSR_TSC_FREQUENCY;
37267b16f18SVitaly Kuznetsov 			msr->write = false;
37367b16f18SVitaly Kuznetsov 			msr->fault_expected = false;
374e2e1cc1fSVitaly Kuznetsov 			break;
375e2e1cc1fSVitaly Kuznetsov 		case 33:
376e2e1cc1fSVitaly Kuznetsov 			/* Read only */
3779f88d062SSean Christopherson 			msr->idx = HV_X64_MSR_TSC_FREQUENCY;
37867b16f18SVitaly Kuznetsov 			msr->write = true;
379e2e1cc1fSVitaly Kuznetsov 			msr->write_val = 1;
38067b16f18SVitaly Kuznetsov 			msr->fault_expected = true;
381e2e1cc1fSVitaly Kuznetsov 			break;
382e2e1cc1fSVitaly Kuznetsov 
383e2e1cc1fSVitaly Kuznetsov 		case 34:
384e2e1cc1fSVitaly Kuznetsov 			msr->idx = HV_X64_MSR_REENLIGHTENMENT_CONTROL;
38567b16f18SVitaly Kuznetsov 			msr->write = false;
38667b16f18SVitaly Kuznetsov 			msr->fault_expected = true;
387e2e1cc1fSVitaly Kuznetsov 			break;
388e2e1cc1fSVitaly Kuznetsov 		case 35:
3892f10428aSVitaly Kuznetsov 			vcpu_set_cpuid_feature(vcpu, HV_ACCESS_REENLIGHTENMENT);
3909f88d062SSean Christopherson 			msr->idx = HV_X64_MSR_REENLIGHTENMENT_CONTROL;
39167b16f18SVitaly Kuznetsov 			msr->write = false;
39267b16f18SVitaly Kuznetsov 			msr->fault_expected = false;
393e2e1cc1fSVitaly Kuznetsov 			break;
394e2e1cc1fSVitaly Kuznetsov 		case 36:
3959f88d062SSean Christopherson 			msr->idx = HV_X64_MSR_REENLIGHTENMENT_CONTROL;
39667b16f18SVitaly Kuznetsov 			msr->write = true;
397e2e1cc1fSVitaly Kuznetsov 			msr->write_val = 1;
39867b16f18SVitaly Kuznetsov 			msr->fault_expected = false;
399e2e1cc1fSVitaly Kuznetsov 			break;
400e2e1cc1fSVitaly Kuznetsov 		case 37:
401e2e1cc1fSVitaly Kuznetsov 			/* Can only write '0' */
402e2e1cc1fSVitaly Kuznetsov 			msr->idx = HV_X64_MSR_TSC_EMULATION_STATUS;
40367b16f18SVitaly Kuznetsov 			msr->write = true;
404e2e1cc1fSVitaly Kuznetsov 			msr->write_val = 1;
40567b16f18SVitaly Kuznetsov 			msr->fault_expected = true;
406e2e1cc1fSVitaly Kuznetsov 			break;
407e2e1cc1fSVitaly Kuznetsov 
408e2e1cc1fSVitaly Kuznetsov 		case 38:
409e2e1cc1fSVitaly Kuznetsov 			msr->idx = HV_X64_MSR_CRASH_P0;
41067b16f18SVitaly Kuznetsov 			msr->write = false;
41167b16f18SVitaly Kuznetsov 			msr->fault_expected = true;
412e2e1cc1fSVitaly Kuznetsov 			break;
413e2e1cc1fSVitaly Kuznetsov 		case 39:
4142f10428aSVitaly Kuznetsov 			vcpu_set_cpuid_feature(vcpu, HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE);
4159f88d062SSean Christopherson 			msr->idx = HV_X64_MSR_CRASH_P0;
41667b16f18SVitaly Kuznetsov 			msr->write = false;
41767b16f18SVitaly Kuznetsov 			msr->fault_expected = false;
418e2e1cc1fSVitaly Kuznetsov 			break;
419e2e1cc1fSVitaly Kuznetsov 		case 40:
4209f88d062SSean Christopherson 			msr->idx = HV_X64_MSR_CRASH_P0;
42167b16f18SVitaly Kuznetsov 			msr->write = true;
422e2e1cc1fSVitaly Kuznetsov 			msr->write_val = 1;
42367b16f18SVitaly Kuznetsov 			msr->fault_expected = false;
424e2e1cc1fSVitaly Kuznetsov 			break;
425e2e1cc1fSVitaly Kuznetsov 
426e2e1cc1fSVitaly Kuznetsov 		case 41:
427e2e1cc1fSVitaly Kuznetsov 			msr->idx = HV_X64_MSR_SYNDBG_STATUS;
42867b16f18SVitaly Kuznetsov 			msr->write = false;
42967b16f18SVitaly Kuznetsov 			msr->fault_expected = true;
430e2e1cc1fSVitaly Kuznetsov 			break;
431e2e1cc1fSVitaly Kuznetsov 		case 42:
4322f10428aSVitaly Kuznetsov 			vcpu_set_cpuid_feature(vcpu, HV_FEATURE_DEBUG_MSRS_AVAILABLE);
4332f10428aSVitaly Kuznetsov 			vcpu_set_cpuid_feature(vcpu, HV_X64_SYNDBG_CAP_ALLOW_KERNEL_DEBUGGING);
4349f88d062SSean Christopherson 			msr->idx = HV_X64_MSR_SYNDBG_STATUS;
43567b16f18SVitaly Kuznetsov 			msr->write = false;
43667b16f18SVitaly Kuznetsov 			msr->fault_expected = false;
437e2e1cc1fSVitaly Kuznetsov 			break;
438e2e1cc1fSVitaly Kuznetsov 		case 43:
4399f88d062SSean Christopherson 			msr->idx = HV_X64_MSR_SYNDBG_STATUS;
44067b16f18SVitaly Kuznetsov 			msr->write = true;
441e2e1cc1fSVitaly Kuznetsov 			msr->write_val = 0;
44267b16f18SVitaly Kuznetsov 			msr->fault_expected = false;
443e2e1cc1fSVitaly Kuznetsov 			break;
444e2e1cc1fSVitaly Kuznetsov 
445e2e1cc1fSVitaly Kuznetsov 		case 44:
446bd827bd7SVitaly Kuznetsov 			/* MSR is not available when CPUID feature bit is unset */
447bd827bd7SVitaly Kuznetsov 			if (!has_invtsc)
448bd827bd7SVitaly Kuznetsov 				continue;
449bd827bd7SVitaly Kuznetsov 			msr->idx = HV_X64_MSR_TSC_INVARIANT_CONTROL;
450bd827bd7SVitaly Kuznetsov 			msr->write = false;
451bd827bd7SVitaly Kuznetsov 			msr->fault_expected = true;
452bd827bd7SVitaly Kuznetsov 			break;
453bd827bd7SVitaly Kuznetsov 		case 45:
454bd827bd7SVitaly Kuznetsov 			/* MSR is vailable when CPUID feature bit is set */
455bd827bd7SVitaly Kuznetsov 			if (!has_invtsc)
456bd827bd7SVitaly Kuznetsov 				continue;
457bd827bd7SVitaly Kuznetsov 			vcpu_set_cpuid_feature(vcpu, HV_ACCESS_TSC_INVARIANT);
458bd827bd7SVitaly Kuznetsov 			msr->idx = HV_X64_MSR_TSC_INVARIANT_CONTROL;
459bd827bd7SVitaly Kuznetsov 			msr->write = false;
460bd827bd7SVitaly Kuznetsov 			msr->fault_expected = false;
461bd827bd7SVitaly Kuznetsov 			break;
462bd827bd7SVitaly Kuznetsov 		case 46:
463bd827bd7SVitaly Kuznetsov 			/* Writing bits other than 0 is forbidden */
464bd827bd7SVitaly Kuznetsov 			if (!has_invtsc)
465bd827bd7SVitaly Kuznetsov 				continue;
466bd827bd7SVitaly Kuznetsov 			msr->idx = HV_X64_MSR_TSC_INVARIANT_CONTROL;
467bd827bd7SVitaly Kuznetsov 			msr->write = true;
468bd827bd7SVitaly Kuznetsov 			msr->write_val = 0xdeadbeef;
469bd827bd7SVitaly Kuznetsov 			msr->fault_expected = true;
470bd827bd7SVitaly Kuznetsov 			break;
471bd827bd7SVitaly Kuznetsov 		case 47:
472bd827bd7SVitaly Kuznetsov 			/* Setting bit 0 enables the feature */
473bd827bd7SVitaly Kuznetsov 			if (!has_invtsc)
474bd827bd7SVitaly Kuznetsov 				continue;
475bd827bd7SVitaly Kuznetsov 			msr->idx = HV_X64_MSR_TSC_INVARIANT_CONTROL;
476bd827bd7SVitaly Kuznetsov 			msr->write = true;
477bd827bd7SVitaly Kuznetsov 			msr->write_val = 1;
478bd827bd7SVitaly Kuznetsov 			msr->fault_expected = false;
479bd827bd7SVitaly Kuznetsov 			break;
480bd827bd7SVitaly Kuznetsov 
481bd827bd7SVitaly Kuznetsov 		default:
4829f88d062SSean Christopherson 			kvm_vm_free(vm);
4839f88d062SSean Christopherson 			return;
484e2e1cc1fSVitaly Kuznetsov 		}
485e2e1cc1fSVitaly Kuznetsov 
4864dcd130cSSean Christopherson 		vcpu_set_cpuid(vcpu);
4874dcd130cSSean Christopherson 
4884dcd130cSSean Christopherson 		memcpy(prev_cpuid, vcpu->cpuid, kvm_cpuid2_size(vcpu->cpuid->nent));
489e2e1cc1fSVitaly Kuznetsov 
490e2e1cc1fSVitaly Kuznetsov 		pr_debug("Stage %d: testing msr: 0x%x for %s\n", stage,
491e2e1cc1fSVitaly Kuznetsov 			 msr->idx, msr->write ? "write" : "read");
492e2e1cc1fSVitaly Kuznetsov 
493768e9a61SSean Christopherson 		vcpu_run(vcpu);
494*c96f57b0SVipin Sharma 		TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_IO);
495e2e1cc1fSVitaly Kuznetsov 
496768e9a61SSean Christopherson 		switch (get_ucall(vcpu, &uc)) {
497e2e1cc1fSVitaly Kuznetsov 		case UCALL_ABORT:
49891a0b547SVitaly Kuznetsov 			REPORT_GUEST_ASSERT_3(uc, "MSR = %lx, arg1 = %lx, arg2 = %lx");
499e2e1cc1fSVitaly Kuznetsov 			return;
500e2e1cc1fSVitaly Kuznetsov 		case UCALL_DONE:
5019f88d062SSean Christopherson 			break;
5029f88d062SSean Christopherson 		default:
5039f88d062SSean Christopherson 			TEST_FAIL("Unhandled ucall: %ld", uc.cmd);
504e2e1cc1fSVitaly Kuznetsov 			return;
505e2e1cc1fSVitaly Kuznetsov 		}
506e2e1cc1fSVitaly Kuznetsov 
507e2e1cc1fSVitaly Kuznetsov 		stage++;
5086c118643SVitaly Kuznetsov 		kvm_vm_free(vm);
509e2e1cc1fSVitaly Kuznetsov 	}
510e2e1cc1fSVitaly Kuznetsov }
511e2e1cc1fSVitaly Kuznetsov 
5126c118643SVitaly Kuznetsov static void guest_test_hcalls_access(void)
513e2e1cc1fSVitaly Kuznetsov {
5144dcd130cSSean Christopherson 	struct kvm_cpuid2 *prev_cpuid = NULL;
515d96b9596SSean Christopherson 	struct kvm_vcpu *vcpu;
5166c118643SVitaly Kuznetsov 	struct kvm_vm *vm;
517e2e1cc1fSVitaly Kuznetsov 	struct ucall uc;
518d96b9596SSean Christopherson 	int stage = 0;
5196c118643SVitaly Kuznetsov 	vm_vaddr_t hcall_page, hcall_params;
5206c118643SVitaly Kuznetsov 	struct hcall_data *hcall;
5216c118643SVitaly Kuznetsov 
5226c118643SVitaly Kuznetsov 	while (true) {
523d96b9596SSean Christopherson 		vm = vm_create_with_one_vcpu(&vcpu, guest_hcall);
5246c118643SVitaly Kuznetsov 
5256c118643SVitaly Kuznetsov 		vm_init_descriptor_tables(vm);
526768e9a61SSean Christopherson 		vcpu_init_descriptor_tables(vcpu);
5276c118643SVitaly Kuznetsov 
5286c118643SVitaly Kuznetsov 		/* Hypercall input/output */
5296c118643SVitaly Kuznetsov 		hcall_page = vm_vaddr_alloc_pages(vm, 2);
5306c118643SVitaly Kuznetsov 		memset(addr_gva2hva(vm, hcall_page), 0x0, 2 * getpagesize());
5316c118643SVitaly Kuznetsov 
5326c118643SVitaly Kuznetsov 		hcall_params = vm_vaddr_alloc_page(vm);
5336c118643SVitaly Kuznetsov 		memset(addr_gva2hva(vm, hcall_params), 0x0, getpagesize());
5349f88d062SSean Christopherson 		hcall = addr_gva2hva(vm, hcall_params);
5356c118643SVitaly Kuznetsov 
536768e9a61SSean Christopherson 		vcpu_args_set(vcpu, 2, addr_gva2gpa(vm, hcall_page), hcall_params);
537768e9a61SSean Christopherson 		vcpu_enable_cap(vcpu, KVM_CAP_HYPERV_ENFORCE_CPUID, 1);
5386c118643SVitaly Kuznetsov 
5394dcd130cSSean Christopherson 		if (!prev_cpuid) {
5404dcd130cSSean Christopherson 			vcpu_reset_hv_cpuid(vcpu);
5416c118643SVitaly Kuznetsov 
5424dcd130cSSean Christopherson 			prev_cpuid = allocate_kvm_cpuid2(vcpu->cpuid->nent);
5434dcd130cSSean Christopherson 		} else {
5444dcd130cSSean Christopherson 			vcpu_init_cpuid(vcpu, prev_cpuid);
5454dcd130cSSean Christopherson 		}
5464dcd130cSSean Christopherson 
547e2e1cc1fSVitaly Kuznetsov 		switch (stage) {
548e2e1cc1fSVitaly Kuznetsov 		case 0:
5492f10428aSVitaly Kuznetsov 			vcpu_set_cpuid_feature(vcpu, HV_MSR_HYPERCALL_AVAILABLE);
55031d3b871SVitaly Kuznetsov 			hcall->control = 0xbeef;
551e2e1cc1fSVitaly Kuznetsov 			hcall->expect = HV_STATUS_INVALID_HYPERCALL_CODE;
552e2e1cc1fSVitaly Kuznetsov 			break;
553e2e1cc1fSVitaly Kuznetsov 
554e2e1cc1fSVitaly Kuznetsov 		case 1:
555e2e1cc1fSVitaly Kuznetsov 			hcall->control = HVCALL_POST_MESSAGE;
556e2e1cc1fSVitaly Kuznetsov 			hcall->expect = HV_STATUS_ACCESS_DENIED;
557e2e1cc1fSVitaly Kuznetsov 			break;
558e2e1cc1fSVitaly Kuznetsov 		case 2:
5592f10428aSVitaly Kuznetsov 			vcpu_set_cpuid_feature(vcpu, HV_POST_MESSAGES);
5609f88d062SSean Christopherson 			hcall->control = HVCALL_POST_MESSAGE;
561e2e1cc1fSVitaly Kuznetsov 			hcall->expect = HV_STATUS_INVALID_HYPERCALL_INPUT;
562e2e1cc1fSVitaly Kuznetsov 			break;
563e2e1cc1fSVitaly Kuznetsov 
564e2e1cc1fSVitaly Kuznetsov 		case 3:
565e2e1cc1fSVitaly Kuznetsov 			hcall->control = HVCALL_SIGNAL_EVENT;
566e2e1cc1fSVitaly Kuznetsov 			hcall->expect = HV_STATUS_ACCESS_DENIED;
567e2e1cc1fSVitaly Kuznetsov 			break;
568e2e1cc1fSVitaly Kuznetsov 		case 4:
5692f10428aSVitaly Kuznetsov 			vcpu_set_cpuid_feature(vcpu, HV_SIGNAL_EVENTS);
5709f88d062SSean Christopherson 			hcall->control = HVCALL_SIGNAL_EVENT;
571e2e1cc1fSVitaly Kuznetsov 			hcall->expect = HV_STATUS_INVALID_HYPERCALL_INPUT;
572e2e1cc1fSVitaly Kuznetsov 			break;
573e2e1cc1fSVitaly Kuznetsov 
574e2e1cc1fSVitaly Kuznetsov 		case 5:
575e2e1cc1fSVitaly Kuznetsov 			hcall->control = HVCALL_RESET_DEBUG_SESSION;
576e2e1cc1fSVitaly Kuznetsov 			hcall->expect = HV_STATUS_INVALID_HYPERCALL_CODE;
577e2e1cc1fSVitaly Kuznetsov 			break;
578e2e1cc1fSVitaly Kuznetsov 		case 6:
5792f10428aSVitaly Kuznetsov 			vcpu_set_cpuid_feature(vcpu, HV_X64_SYNDBG_CAP_ALLOW_KERNEL_DEBUGGING);
5809f88d062SSean Christopherson 			hcall->control = HVCALL_RESET_DEBUG_SESSION;
581e2e1cc1fSVitaly Kuznetsov 			hcall->expect = HV_STATUS_ACCESS_DENIED;
582e2e1cc1fSVitaly Kuznetsov 			break;
583e2e1cc1fSVitaly Kuznetsov 		case 7:
5842f10428aSVitaly Kuznetsov 			vcpu_set_cpuid_feature(vcpu, HV_DEBUGGING);
5859f88d062SSean Christopherson 			hcall->control = HVCALL_RESET_DEBUG_SESSION;
586e2e1cc1fSVitaly Kuznetsov 			hcall->expect = HV_STATUS_OPERATION_DENIED;
587e2e1cc1fSVitaly Kuznetsov 			break;
588e2e1cc1fSVitaly Kuznetsov 
589e2e1cc1fSVitaly Kuznetsov 		case 8:
590e2e1cc1fSVitaly Kuznetsov 			hcall->control = HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE;
591e2e1cc1fSVitaly Kuznetsov 			hcall->expect = HV_STATUS_ACCESS_DENIED;
592e2e1cc1fSVitaly Kuznetsov 			break;
593e2e1cc1fSVitaly Kuznetsov 		case 9:
5942f10428aSVitaly Kuznetsov 			vcpu_set_cpuid_feature(vcpu, HV_X64_REMOTE_TLB_FLUSH_RECOMMENDED);
5959f88d062SSean Christopherson 			hcall->control = HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE;
596e2e1cc1fSVitaly Kuznetsov 			hcall->expect = HV_STATUS_SUCCESS;
597e2e1cc1fSVitaly Kuznetsov 			break;
598e2e1cc1fSVitaly Kuznetsov 		case 10:
599e2e1cc1fSVitaly Kuznetsov 			hcall->control = HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE_EX;
600e2e1cc1fSVitaly Kuznetsov 			hcall->expect = HV_STATUS_ACCESS_DENIED;
601e2e1cc1fSVitaly Kuznetsov 			break;
602e2e1cc1fSVitaly Kuznetsov 		case 11:
6032f10428aSVitaly Kuznetsov 			vcpu_set_cpuid_feature(vcpu, HV_X64_EX_PROCESSOR_MASKS_RECOMMENDED);
6049f88d062SSean Christopherson 			hcall->control = HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE_EX;
605e2e1cc1fSVitaly Kuznetsov 			hcall->expect = HV_STATUS_SUCCESS;
606e2e1cc1fSVitaly Kuznetsov 			break;
607e2e1cc1fSVitaly Kuznetsov 
608e2e1cc1fSVitaly Kuznetsov 		case 12:
609e2e1cc1fSVitaly Kuznetsov 			hcall->control = HVCALL_SEND_IPI;
610e2e1cc1fSVitaly Kuznetsov 			hcall->expect = HV_STATUS_ACCESS_DENIED;
611e2e1cc1fSVitaly Kuznetsov 			break;
612e2e1cc1fSVitaly Kuznetsov 		case 13:
6132f10428aSVitaly Kuznetsov 			vcpu_set_cpuid_feature(vcpu, HV_X64_CLUSTER_IPI_RECOMMENDED);
6149f88d062SSean Christopherson 			hcall->control = HVCALL_SEND_IPI;
615e2e1cc1fSVitaly Kuznetsov 			hcall->expect = HV_STATUS_INVALID_HYPERCALL_INPUT;
616e2e1cc1fSVitaly Kuznetsov 			break;
617e2e1cc1fSVitaly Kuznetsov 		case 14:
618e2e1cc1fSVitaly Kuznetsov 			/* Nothing in 'sparse banks' -> success */
619e2e1cc1fSVitaly Kuznetsov 			hcall->control = HVCALL_SEND_IPI_EX;
620e2e1cc1fSVitaly Kuznetsov 			hcall->expect = HV_STATUS_SUCCESS;
621e2e1cc1fSVitaly Kuznetsov 			break;
622e2e1cc1fSVitaly Kuznetsov 
623e2e1cc1fSVitaly Kuznetsov 		case 15:
624e2e1cc1fSVitaly Kuznetsov 			hcall->control = HVCALL_NOTIFY_LONG_SPIN_WAIT;
625e2e1cc1fSVitaly Kuznetsov 			hcall->expect = HV_STATUS_ACCESS_DENIED;
626e2e1cc1fSVitaly Kuznetsov 			break;
627e2e1cc1fSVitaly Kuznetsov 		case 16:
6282f10428aSVitaly Kuznetsov 			vcpu_set_cpuid_feature(vcpu, HV_PV_SPINLOCKS_TEST);
6299f88d062SSean Christopherson 			hcall->control = HVCALL_NOTIFY_LONG_SPIN_WAIT;
630e2e1cc1fSVitaly Kuznetsov 			hcall->expect = HV_STATUS_SUCCESS;
631e2e1cc1fSVitaly Kuznetsov 			break;
632e2e1cc1fSVitaly Kuznetsov 		case 17:
6332476b5a1SVitaly Kuznetsov 			/* XMM fast hypercall */
6342476b5a1SVitaly Kuznetsov 			hcall->control = HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE | HV_HYPERCALL_FAST_BIT;
6352476b5a1SVitaly Kuznetsov 			hcall->ud_expected = true;
6362476b5a1SVitaly Kuznetsov 			break;
6372476b5a1SVitaly Kuznetsov 		case 18:
6382f10428aSVitaly Kuznetsov 			vcpu_set_cpuid_feature(vcpu, HV_X64_HYPERCALL_XMM_INPUT_AVAILABLE);
6399f88d062SSean Christopherson 			hcall->control = HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE | HV_HYPERCALL_FAST_BIT;
6402476b5a1SVitaly Kuznetsov 			hcall->ud_expected = false;
6412476b5a1SVitaly Kuznetsov 			hcall->expect = HV_STATUS_SUCCESS;
6422476b5a1SVitaly Kuznetsov 			break;
6432476b5a1SVitaly Kuznetsov 		case 19:
644c4a46627SVipin Sharma 			hcall->control = HV_EXT_CALL_QUERY_CAPABILITIES;
645c4a46627SVipin Sharma 			hcall->expect = HV_STATUS_ACCESS_DENIED;
646c4a46627SVipin Sharma 			break;
647c4a46627SVipin Sharma 		case 20:
648c4a46627SVipin Sharma 			vcpu_set_cpuid_feature(vcpu, HV_ENABLE_EXTENDED_HYPERCALLS);
649c4a46627SVipin Sharma 			hcall->control = HV_EXT_CALL_QUERY_CAPABILITIES | HV_HYPERCALL_FAST_BIT;
650c4a46627SVipin Sharma 			hcall->expect = HV_STATUS_INVALID_PARAMETER;
651c4a46627SVipin Sharma 			break;
652c4a46627SVipin Sharma 		case 21:
6539f88d062SSean Christopherson 			kvm_vm_free(vm);
6549f88d062SSean Christopherson 			return;
655e2e1cc1fSVitaly Kuznetsov 		}
656e2e1cc1fSVitaly Kuznetsov 
6574dcd130cSSean Christopherson 		vcpu_set_cpuid(vcpu);
6584dcd130cSSean Christopherson 
6594dcd130cSSean Christopherson 		memcpy(prev_cpuid, vcpu->cpuid, kvm_cpuid2_size(vcpu->cpuid->nent));
660e2e1cc1fSVitaly Kuznetsov 
6619f88d062SSean Christopherson 		pr_debug("Stage %d: testing hcall: 0x%lx\n", stage, hcall->control);
662e2e1cc1fSVitaly Kuznetsov 
663768e9a61SSean Christopherson 		vcpu_run(vcpu);
664*c96f57b0SVipin Sharma 		TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_IO);
665e2e1cc1fSVitaly Kuznetsov 
666768e9a61SSean Christopherson 		switch (get_ucall(vcpu, &uc)) {
667e2e1cc1fSVitaly Kuznetsov 		case UCALL_ABORT:
668594a1c27SColton Lewis 			REPORT_GUEST_ASSERT_2(uc, "arg1 = %lx, arg2 = %lx");
669e2e1cc1fSVitaly Kuznetsov 			return;
670e2e1cc1fSVitaly Kuznetsov 		case UCALL_DONE:
6719f88d062SSean Christopherson 			break;
6729f88d062SSean Christopherson 		default:
6739f88d062SSean Christopherson 			TEST_FAIL("Unhandled ucall: %ld", uc.cmd);
674e2e1cc1fSVitaly Kuznetsov 			return;
675e2e1cc1fSVitaly Kuznetsov 		}
676e2e1cc1fSVitaly Kuznetsov 
677e2e1cc1fSVitaly Kuznetsov 		stage++;
6786c118643SVitaly Kuznetsov 		kvm_vm_free(vm);
679e2e1cc1fSVitaly Kuznetsov 	}
680e2e1cc1fSVitaly Kuznetsov }
681e2e1cc1fSVitaly Kuznetsov 
682e2e1cc1fSVitaly Kuznetsov int main(void)
683e2e1cc1fSVitaly Kuznetsov {
684e2e1cc1fSVitaly Kuznetsov 	pr_info("Testing access to Hyper-V specific MSRs\n");
6856c118643SVitaly Kuznetsov 	guest_test_msrs_access();
686e2e1cc1fSVitaly Kuznetsov 
687e2e1cc1fSVitaly Kuznetsov 	pr_info("Testing access to Hyper-V hypercalls\n");
6886c118643SVitaly Kuznetsov 	guest_test_hcalls_access();
689e2e1cc1fSVitaly Kuznetsov }
690