hyperv_features.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (C) 2021, Red Hat, Inc.
  4. *
  5. * Tests for Hyper-V features enablement
  6. */
  7. #include <asm/kvm_para.h>
  8. #include <linux/kvm_para.h>
  9. #include <stdint.h>
  10. #include "test_util.h"
  11. #include "kvm_util.h"
  12. #include "processor.h"
  13. #include "hyperv.h"
  14. /*
  15. * HYPERV_CPUID_ENLIGHTMENT_INFO.EBX is not a 'feature' CPUID leaf
  16. * but to activate the feature it is sufficient to set it to a non-zero
  17. * value. Use BIT(0) for that.
  18. */
  19. #define HV_PV_SPINLOCKS_TEST \
  20. KVM_X86_CPU_FEATURE(HYPERV_CPUID_ENLIGHTMENT_INFO, 0, EBX, 0)
  21. struct msr_data {
  22. uint32_t idx;
  23. bool fault_expected;
  24. bool write;
  25. u64 write_val;
  26. };
  27. struct hcall_data {
  28. uint64_t control;
  29. uint64_t expect;
  30. bool ud_expected;
  31. };
  32. static bool is_write_only_msr(uint32_t msr)
  33. {
  34. return msr == HV_X64_MSR_EOI;
  35. }
  36. static void guest_msr(struct msr_data *msr)
  37. {
  38. uint8_t vector = 0;
  39. uint64_t msr_val = 0;
  40. GUEST_ASSERT(msr->idx);
  41. if (msr->write)
  42. vector = wrmsr_safe(msr->idx, msr->write_val);
  43. if (!vector && (!msr->write || !is_write_only_msr(msr->idx)))
  44. vector = rdmsr_safe(msr->idx, &msr_val);
  45. if (msr->fault_expected)
  46. __GUEST_ASSERT(vector == GP_VECTOR,
  47. "Expected #GP on %sMSR(0x%x), got %s",
  48. msr->write ? "WR" : "RD", msr->idx, ex_str(vector));
  49. else
  50. __GUEST_ASSERT(!vector,
  51. "Expected success on %sMSR(0x%x), got %s",
  52. msr->write ? "WR" : "RD", msr->idx, ex_str(vector));
  53. if (vector || is_write_only_msr(msr->idx))
  54. goto done;
  55. if (msr->write)
  56. __GUEST_ASSERT(!vector,
  57. "WRMSR(0x%x) to '0x%lx', RDMSR read '0x%lx'",
  58. msr->idx, msr->write_val, msr_val);
  59. /* Invariant TSC bit appears when TSC invariant control MSR is written to */
  60. if (msr->idx == HV_X64_MSR_TSC_INVARIANT_CONTROL) {
  61. if (!this_cpu_has(HV_ACCESS_TSC_INVARIANT))
  62. GUEST_ASSERT(this_cpu_has(X86_FEATURE_INVTSC));
  63. else
  64. GUEST_ASSERT(this_cpu_has(X86_FEATURE_INVTSC) ==
  65. !!(msr_val & HV_INVARIANT_TSC_EXPOSED));
  66. }
  67. done:
  68. GUEST_DONE();
  69. }
  70. static void guest_hcall(vm_vaddr_t pgs_gpa, struct hcall_data *hcall)
  71. {
  72. u64 res, input, output;
  73. uint8_t vector;
  74. GUEST_ASSERT_NE(hcall->control, 0);
  75. wrmsr(HV_X64_MSR_GUEST_OS_ID, HYPERV_LINUX_OS_ID);
  76. wrmsr(HV_X64_MSR_HYPERCALL, pgs_gpa);
  77. if (!(hcall->control & HV_HYPERCALL_FAST_BIT)) {
  78. input = pgs_gpa;
  79. output = pgs_gpa + PAGE_SIZE;
  80. } else {
  81. input = output = 0;
  82. }
  83. vector = __hyperv_hypercall(hcall->control, input, output, &res);
  84. if (hcall->ud_expected) {
  85. __GUEST_ASSERT(vector == UD_VECTOR,
  86. "Expected #UD for control '%lu', got %s",
  87. hcall->control, ex_str(vector));
  88. } else {
  89. __GUEST_ASSERT(!vector,
  90. "Expected no exception for control '%lu', got %s",
  91. hcall->control, ex_str(vector));
  92. GUEST_ASSERT_EQ(res, hcall->expect);
  93. }
  94. GUEST_DONE();
  95. }
  96. static void vcpu_reset_hv_cpuid(struct kvm_vcpu *vcpu)
  97. {
  98. /*
  99. * Enable all supported Hyper-V features, then clear the leafs holding
  100. * the features that will be tested one by one.
  101. */
  102. vcpu_set_hv_cpuid(vcpu);
  103. vcpu_clear_cpuid_entry(vcpu, HYPERV_CPUID_FEATURES);
  104. vcpu_clear_cpuid_entry(vcpu, HYPERV_CPUID_ENLIGHTMENT_INFO);
  105. vcpu_clear_cpuid_entry(vcpu, HYPERV_CPUID_SYNDBG_PLATFORM_CAPABILITIES);
  106. }
  107. static void guest_test_msrs_access(void)
  108. {
  109. struct kvm_cpuid2 *prev_cpuid = NULL;
  110. struct kvm_vcpu *vcpu;
  111. struct kvm_vm *vm;
  112. struct ucall uc;
  113. int stage = 0;
  114. vm_vaddr_t msr_gva;
  115. struct msr_data *msr;
  116. bool has_invtsc = kvm_cpu_has(X86_FEATURE_INVTSC);
  117. while (true) {
  118. vm = vm_create_with_one_vcpu(&vcpu, guest_msr);
  119. msr_gva = vm_vaddr_alloc_page(vm);
  120. memset(addr_gva2hva(vm, msr_gva), 0x0, getpagesize());
  121. msr = addr_gva2hva(vm, msr_gva);
  122. vcpu_args_set(vcpu, 1, msr_gva);
  123. vcpu_enable_cap(vcpu, KVM_CAP_HYPERV_ENFORCE_CPUID, 1);
  124. if (!prev_cpuid) {
  125. vcpu_reset_hv_cpuid(vcpu);
  126. prev_cpuid = allocate_kvm_cpuid2(vcpu->cpuid->nent);
  127. } else {
  128. vcpu_init_cpuid(vcpu, prev_cpuid);
  129. }
  130. /* TODO: Make this entire test easier to maintain. */
  131. if (stage >= 21)
  132. vcpu_enable_cap(vcpu, KVM_CAP_HYPERV_SYNIC2, 0);
  133. switch (stage) {
  134. case 0:
  135. /*
  136. * Only available when Hyper-V identification is set
  137. */
  138. msr->idx = HV_X64_MSR_GUEST_OS_ID;
  139. msr->write = false;
  140. msr->fault_expected = true;
  141. break;
  142. case 1:
  143. msr->idx = HV_X64_MSR_HYPERCALL;
  144. msr->write = false;
  145. msr->fault_expected = true;
  146. break;
  147. case 2:
  148. vcpu_set_cpuid_feature(vcpu, HV_MSR_HYPERCALL_AVAILABLE);
  149. /*
  150. * HV_X64_MSR_GUEST_OS_ID has to be written first to make
  151. * HV_X64_MSR_HYPERCALL available.
  152. */
  153. msr->idx = HV_X64_MSR_GUEST_OS_ID;
  154. msr->write = true;
  155. msr->write_val = HYPERV_LINUX_OS_ID;
  156. msr->fault_expected = false;
  157. break;
  158. case 3:
  159. msr->idx = HV_X64_MSR_GUEST_OS_ID;
  160. msr->write = false;
  161. msr->fault_expected = false;
  162. break;
  163. case 4:
  164. msr->idx = HV_X64_MSR_HYPERCALL;
  165. msr->write = false;
  166. msr->fault_expected = false;
  167. break;
  168. case 5:
  169. msr->idx = HV_X64_MSR_VP_RUNTIME;
  170. msr->write = false;
  171. msr->fault_expected = true;
  172. break;
  173. case 6:
  174. vcpu_set_cpuid_feature(vcpu, HV_MSR_VP_RUNTIME_AVAILABLE);
  175. msr->idx = HV_X64_MSR_VP_RUNTIME;
  176. msr->write = false;
  177. msr->fault_expected = false;
  178. break;
  179. case 7:
  180. /* Read only */
  181. msr->idx = HV_X64_MSR_VP_RUNTIME;
  182. msr->write = true;
  183. msr->write_val = 1;
  184. msr->fault_expected = true;
  185. break;
  186. case 8:
  187. msr->idx = HV_X64_MSR_TIME_REF_COUNT;
  188. msr->write = false;
  189. msr->fault_expected = true;
  190. break;
  191. case 9:
  192. vcpu_set_cpuid_feature(vcpu, HV_MSR_TIME_REF_COUNT_AVAILABLE);
  193. msr->idx = HV_X64_MSR_TIME_REF_COUNT;
  194. msr->write = false;
  195. msr->fault_expected = false;
  196. break;
  197. case 10:
  198. /* Read only */
  199. msr->idx = HV_X64_MSR_TIME_REF_COUNT;
  200. msr->write = true;
  201. msr->write_val = 1;
  202. msr->fault_expected = true;
  203. break;
  204. case 11:
  205. msr->idx = HV_X64_MSR_VP_INDEX;
  206. msr->write = false;
  207. msr->fault_expected = true;
  208. break;
  209. case 12:
  210. vcpu_set_cpuid_feature(vcpu, HV_MSR_VP_INDEX_AVAILABLE);
  211. msr->idx = HV_X64_MSR_VP_INDEX;
  212. msr->write = false;
  213. msr->fault_expected = false;
  214. break;
  215. case 13:
  216. /* Read only */
  217. msr->idx = HV_X64_MSR_VP_INDEX;
  218. msr->write = true;
  219. msr->write_val = 1;
  220. msr->fault_expected = true;
  221. break;
  222. case 14:
  223. msr->idx = HV_X64_MSR_RESET;
  224. msr->write = false;
  225. msr->fault_expected = true;
  226. break;
  227. case 15:
  228. vcpu_set_cpuid_feature(vcpu, HV_MSR_RESET_AVAILABLE);
  229. msr->idx = HV_X64_MSR_RESET;
  230. msr->write = false;
  231. msr->fault_expected = false;
  232. break;
  233. case 16:
  234. msr->idx = HV_X64_MSR_RESET;
  235. msr->write = true;
  236. /*
  237. * TODO: the test only writes '0' to HV_X64_MSR_RESET
  238. * at the moment, writing some other value there will
  239. * trigger real vCPU reset and the code is not prepared
  240. * to handle it yet.
  241. */
  242. msr->write_val = 0;
  243. msr->fault_expected = false;
  244. break;
  245. case 17:
  246. msr->idx = HV_X64_MSR_REFERENCE_TSC;
  247. msr->write = false;
  248. msr->fault_expected = true;
  249. break;
  250. case 18:
  251. vcpu_set_cpuid_feature(vcpu, HV_MSR_REFERENCE_TSC_AVAILABLE);
  252. msr->idx = HV_X64_MSR_REFERENCE_TSC;
  253. msr->write = false;
  254. msr->fault_expected = false;
  255. break;
  256. case 19:
  257. msr->idx = HV_X64_MSR_REFERENCE_TSC;
  258. msr->write = true;
  259. msr->write_val = 0;
  260. msr->fault_expected = false;
  261. break;
  262. case 20:
  263. msr->idx = HV_X64_MSR_EOM;
  264. msr->write = false;
  265. msr->fault_expected = true;
  266. break;
  267. case 21:
  268. /*
  269. * Remains unavailable even with KVM_CAP_HYPERV_SYNIC2
  270. * capability enabled and guest visible CPUID bit unset.
  271. */
  272. msr->idx = HV_X64_MSR_EOM;
  273. msr->write = false;
  274. msr->fault_expected = true;
  275. break;
  276. case 22:
  277. vcpu_set_cpuid_feature(vcpu, HV_MSR_SYNIC_AVAILABLE);
  278. msr->idx = HV_X64_MSR_EOM;
  279. msr->write = false;
  280. msr->fault_expected = false;
  281. break;
  282. case 23:
  283. msr->idx = HV_X64_MSR_EOM;
  284. msr->write = true;
  285. msr->write_val = 0;
  286. msr->fault_expected = false;
  287. break;
  288. case 24:
  289. msr->idx = HV_X64_MSR_STIMER0_CONFIG;
  290. msr->write = false;
  291. msr->fault_expected = true;
  292. break;
  293. case 25:
  294. vcpu_set_cpuid_feature(vcpu, HV_MSR_SYNTIMER_AVAILABLE);
  295. msr->idx = HV_X64_MSR_STIMER0_CONFIG;
  296. msr->write = false;
  297. msr->fault_expected = false;
  298. break;
  299. case 26:
  300. msr->idx = HV_X64_MSR_STIMER0_CONFIG;
  301. msr->write = true;
  302. msr->write_val = 0;
  303. msr->fault_expected = false;
  304. break;
  305. case 27:
  306. /* Direct mode test */
  307. msr->idx = HV_X64_MSR_STIMER0_CONFIG;
  308. msr->write = true;
  309. msr->write_val = 1 << 12;
  310. msr->fault_expected = true;
  311. break;
  312. case 28:
  313. vcpu_set_cpuid_feature(vcpu, HV_STIMER_DIRECT_MODE_AVAILABLE);
  314. msr->idx = HV_X64_MSR_STIMER0_CONFIG;
  315. msr->write = true;
  316. msr->write_val = 1 << 12;
  317. msr->fault_expected = false;
  318. break;
  319. case 29:
  320. msr->idx = HV_X64_MSR_EOI;
  321. msr->write = false;
  322. msr->fault_expected = true;
  323. break;
  324. case 30:
  325. vcpu_set_cpuid_feature(vcpu, HV_MSR_APIC_ACCESS_AVAILABLE);
  326. msr->idx = HV_X64_MSR_EOI;
  327. msr->write = true;
  328. msr->write_val = 1;
  329. msr->fault_expected = false;
  330. break;
  331. case 31:
  332. msr->idx = HV_X64_MSR_TSC_FREQUENCY;
  333. msr->write = false;
  334. msr->fault_expected = true;
  335. break;
  336. case 32:
  337. vcpu_set_cpuid_feature(vcpu, HV_ACCESS_FREQUENCY_MSRS);
  338. msr->idx = HV_X64_MSR_TSC_FREQUENCY;
  339. msr->write = false;
  340. msr->fault_expected = false;
  341. break;
  342. case 33:
  343. /* Read only */
  344. msr->idx = HV_X64_MSR_TSC_FREQUENCY;
  345. msr->write = true;
  346. msr->write_val = 1;
  347. msr->fault_expected = true;
  348. break;
  349. case 34:
  350. msr->idx = HV_X64_MSR_REENLIGHTENMENT_CONTROL;
  351. msr->write = false;
  352. msr->fault_expected = true;
  353. break;
  354. case 35:
  355. vcpu_set_cpuid_feature(vcpu, HV_ACCESS_REENLIGHTENMENT);
  356. msr->idx = HV_X64_MSR_REENLIGHTENMENT_CONTROL;
  357. msr->write = false;
  358. msr->fault_expected = false;
  359. break;
  360. case 36:
  361. msr->idx = HV_X64_MSR_REENLIGHTENMENT_CONTROL;
  362. msr->write = true;
  363. msr->write_val = 1;
  364. msr->fault_expected = false;
  365. break;
  366. case 37:
  367. /* Can only write '0' */
  368. msr->idx = HV_X64_MSR_TSC_EMULATION_STATUS;
  369. msr->write = true;
  370. msr->write_val = 1;
  371. msr->fault_expected = true;
  372. break;
  373. case 38:
  374. msr->idx = HV_X64_MSR_CRASH_P0;
  375. msr->write = false;
  376. msr->fault_expected = true;
  377. break;
  378. case 39:
  379. vcpu_set_cpuid_feature(vcpu, HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE);
  380. msr->idx = HV_X64_MSR_CRASH_P0;
  381. msr->write = false;
  382. msr->fault_expected = false;
  383. break;
  384. case 40:
  385. msr->idx = HV_X64_MSR_CRASH_P0;
  386. msr->write = true;
  387. msr->write_val = 1;
  388. msr->fault_expected = false;
  389. break;
  390. case 41:
  391. msr->idx = HV_X64_MSR_SYNDBG_STATUS;
  392. msr->write = false;
  393. msr->fault_expected = true;
  394. break;
  395. case 42:
  396. vcpu_set_cpuid_feature(vcpu, HV_FEATURE_DEBUG_MSRS_AVAILABLE);
  397. vcpu_set_cpuid_feature(vcpu, HV_X64_SYNDBG_CAP_ALLOW_KERNEL_DEBUGGING);
  398. msr->idx = HV_X64_MSR_SYNDBG_STATUS;
  399. msr->write = false;
  400. msr->fault_expected = false;
  401. break;
  402. case 43:
  403. msr->idx = HV_X64_MSR_SYNDBG_STATUS;
  404. msr->write = true;
  405. msr->write_val = 0;
  406. msr->fault_expected = false;
  407. break;
  408. case 44:
  409. /* MSR is not available when CPUID feature bit is unset */
  410. if (!has_invtsc)
  411. goto next_stage;
  412. msr->idx = HV_X64_MSR_TSC_INVARIANT_CONTROL;
  413. msr->write = false;
  414. msr->fault_expected = true;
  415. break;
  416. case 45:
  417. /* MSR is vailable when CPUID feature bit is set */
  418. if (!has_invtsc)
  419. goto next_stage;
  420. vcpu_set_cpuid_feature(vcpu, HV_ACCESS_TSC_INVARIANT);
  421. msr->idx = HV_X64_MSR_TSC_INVARIANT_CONTROL;
  422. msr->write = false;
  423. msr->fault_expected = false;
  424. break;
  425. case 46:
  426. /* Writing bits other than 0 is forbidden */
  427. if (!has_invtsc)
  428. goto next_stage;
  429. msr->idx = HV_X64_MSR_TSC_INVARIANT_CONTROL;
  430. msr->write = true;
  431. msr->write_val = 0xdeadbeef;
  432. msr->fault_expected = true;
  433. break;
  434. case 47:
  435. /* Setting bit 0 enables the feature */
  436. if (!has_invtsc)
  437. goto next_stage;
  438. msr->idx = HV_X64_MSR_TSC_INVARIANT_CONTROL;
  439. msr->write = true;
  440. msr->write_val = 1;
  441. msr->fault_expected = false;
  442. break;
  443. default:
  444. kvm_vm_free(vm);
  445. return;
  446. }
  447. vcpu_set_cpuid(vcpu);
  448. memcpy(prev_cpuid, vcpu->cpuid, kvm_cpuid2_size(vcpu->cpuid->nent));
  449. pr_debug("Stage %d: testing msr: 0x%x for %s\n", stage,
  450. msr->idx, msr->write ? "write" : "read");
  451. vcpu_run(vcpu);
  452. TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_IO);
  453. switch (get_ucall(vcpu, &uc)) {
  454. case UCALL_ABORT:
  455. REPORT_GUEST_ASSERT(uc);
  456. return;
  457. case UCALL_DONE:
  458. break;
  459. default:
  460. TEST_FAIL("Unhandled ucall: %ld", uc.cmd);
  461. return;
  462. }
  463. next_stage:
  464. stage++;
  465. kvm_vm_free(vm);
  466. }
  467. }
  468. static void guest_test_hcalls_access(void)
  469. {
  470. struct kvm_cpuid2 *prev_cpuid = NULL;
  471. struct kvm_vcpu *vcpu;
  472. struct kvm_vm *vm;
  473. struct ucall uc;
  474. int stage = 0;
  475. vm_vaddr_t hcall_page, hcall_params;
  476. struct hcall_data *hcall;
  477. while (true) {
  478. vm = vm_create_with_one_vcpu(&vcpu, guest_hcall);
  479. /* Hypercall input/output */
  480. hcall_page = vm_vaddr_alloc_pages(vm, 2);
  481. memset(addr_gva2hva(vm, hcall_page), 0x0, 2 * getpagesize());
  482. hcall_params = vm_vaddr_alloc_page(vm);
  483. memset(addr_gva2hva(vm, hcall_params), 0x0, getpagesize());
  484. hcall = addr_gva2hva(vm, hcall_params);
  485. vcpu_args_set(vcpu, 2, addr_gva2gpa(vm, hcall_page), hcall_params);
  486. vcpu_enable_cap(vcpu, KVM_CAP_HYPERV_ENFORCE_CPUID, 1);
  487. if (!prev_cpuid) {
  488. vcpu_reset_hv_cpuid(vcpu);
  489. prev_cpuid = allocate_kvm_cpuid2(vcpu->cpuid->nent);
  490. } else {
  491. vcpu_init_cpuid(vcpu, prev_cpuid);
  492. }
  493. switch (stage) {
  494. case 0:
  495. vcpu_set_cpuid_feature(vcpu, HV_MSR_HYPERCALL_AVAILABLE);
  496. hcall->control = 0xbeef;
  497. hcall->expect = HV_STATUS_INVALID_HYPERCALL_CODE;
  498. break;
  499. case 1:
  500. hcall->control = HVCALL_POST_MESSAGE;
  501. hcall->expect = HV_STATUS_ACCESS_DENIED;
  502. break;
  503. case 2:
  504. vcpu_set_cpuid_feature(vcpu, HV_POST_MESSAGES);
  505. hcall->control = HVCALL_POST_MESSAGE;
  506. hcall->expect = HV_STATUS_INVALID_HYPERCALL_INPUT;
  507. break;
  508. case 3:
  509. hcall->control = HVCALL_SIGNAL_EVENT;
  510. hcall->expect = HV_STATUS_ACCESS_DENIED;
  511. break;
  512. case 4:
  513. vcpu_set_cpuid_feature(vcpu, HV_SIGNAL_EVENTS);
  514. hcall->control = HVCALL_SIGNAL_EVENT;
  515. hcall->expect = HV_STATUS_INVALID_HYPERCALL_INPUT;
  516. break;
  517. case 5:
  518. hcall->control = HVCALL_RESET_DEBUG_SESSION;
  519. hcall->expect = HV_STATUS_INVALID_HYPERCALL_CODE;
  520. break;
  521. case 6:
  522. vcpu_set_cpuid_feature(vcpu, HV_X64_SYNDBG_CAP_ALLOW_KERNEL_DEBUGGING);
  523. hcall->control = HVCALL_RESET_DEBUG_SESSION;
  524. hcall->expect = HV_STATUS_ACCESS_DENIED;
  525. break;
  526. case 7:
  527. vcpu_set_cpuid_feature(vcpu, HV_DEBUGGING);
  528. hcall->control = HVCALL_RESET_DEBUG_SESSION;
  529. hcall->expect = HV_STATUS_OPERATION_DENIED;
  530. break;
  531. case 8:
  532. hcall->control = HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE;
  533. hcall->expect = HV_STATUS_ACCESS_DENIED;
  534. break;
  535. case 9:
  536. vcpu_set_cpuid_feature(vcpu, HV_X64_REMOTE_TLB_FLUSH_RECOMMENDED);
  537. hcall->control = HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE;
  538. hcall->expect = HV_STATUS_SUCCESS;
  539. break;
  540. case 10:
  541. hcall->control = HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE_EX;
  542. hcall->expect = HV_STATUS_ACCESS_DENIED;
  543. break;
  544. case 11:
  545. vcpu_set_cpuid_feature(vcpu, HV_X64_EX_PROCESSOR_MASKS_RECOMMENDED);
  546. hcall->control = HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE_EX;
  547. hcall->expect = HV_STATUS_SUCCESS;
  548. break;
  549. case 12:
  550. hcall->control = HVCALL_SEND_IPI;
  551. hcall->expect = HV_STATUS_ACCESS_DENIED;
  552. break;
  553. case 13:
  554. vcpu_set_cpuid_feature(vcpu, HV_X64_CLUSTER_IPI_RECOMMENDED);
  555. hcall->control = HVCALL_SEND_IPI;
  556. hcall->expect = HV_STATUS_INVALID_HYPERCALL_INPUT;
  557. break;
  558. case 14:
  559. /* Nothing in 'sparse banks' -> success */
  560. hcall->control = HVCALL_SEND_IPI_EX;
  561. hcall->expect = HV_STATUS_SUCCESS;
  562. break;
  563. case 15:
  564. hcall->control = HVCALL_NOTIFY_LONG_SPIN_WAIT;
  565. hcall->expect = HV_STATUS_ACCESS_DENIED;
  566. break;
  567. case 16:
  568. vcpu_set_cpuid_feature(vcpu, HV_PV_SPINLOCKS_TEST);
  569. hcall->control = HVCALL_NOTIFY_LONG_SPIN_WAIT;
  570. hcall->expect = HV_STATUS_SUCCESS;
  571. break;
  572. case 17:
  573. /* XMM fast hypercall */
  574. hcall->control = HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE | HV_HYPERCALL_FAST_BIT;
  575. hcall->ud_expected = true;
  576. break;
  577. case 18:
  578. vcpu_set_cpuid_feature(vcpu, HV_X64_HYPERCALL_XMM_INPUT_AVAILABLE);
  579. hcall->control = HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE | HV_HYPERCALL_FAST_BIT;
  580. hcall->ud_expected = false;
  581. hcall->expect = HV_STATUS_SUCCESS;
  582. break;
  583. case 19:
  584. hcall->control = HV_EXT_CALL_QUERY_CAPABILITIES;
  585. hcall->expect = HV_STATUS_ACCESS_DENIED;
  586. break;
  587. case 20:
  588. vcpu_set_cpuid_feature(vcpu, HV_ENABLE_EXTENDED_HYPERCALLS);
  589. hcall->control = HV_EXT_CALL_QUERY_CAPABILITIES | HV_HYPERCALL_FAST_BIT;
  590. hcall->expect = HV_STATUS_INVALID_PARAMETER;
  591. break;
  592. case 21:
  593. kvm_vm_free(vm);
  594. return;
  595. }
  596. vcpu_set_cpuid(vcpu);
  597. memcpy(prev_cpuid, vcpu->cpuid, kvm_cpuid2_size(vcpu->cpuid->nent));
  598. pr_debug("Stage %d: testing hcall: 0x%lx\n", stage, hcall->control);
  599. vcpu_run(vcpu);
  600. TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_IO);
  601. switch (get_ucall(vcpu, &uc)) {
  602. case UCALL_ABORT:
  603. REPORT_GUEST_ASSERT(uc);
  604. return;
  605. case UCALL_DONE:
  606. break;
  607. default:
  608. TEST_FAIL("Unhandled ucall: %ld", uc.cmd);
  609. return;
  610. }
  611. stage++;
  612. kvm_vm_free(vm);
  613. }
  614. }
  615. int main(void)
  616. {
  617. TEST_REQUIRE(kvm_has_cap(KVM_CAP_HYPERV_ENFORCE_CPUID));
  618. pr_info("Testing access to Hyper-V specific MSRs\n");
  619. guest_test_msrs_access();
  620. pr_info("Testing access to Hyper-V hypercalls\n");
  621. guest_test_hcalls_access();
  622. }