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