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