0001
0002
0003
0004
0005
0006
0007 #include <asm/kvm_para.h>
0008 #include <linux/kvm_para.h>
0009 #include <stdint.h>
0010
0011 #include "test_util.h"
0012 #include "kvm_util.h"
0013 #include "processor.h"
0014 #include "hyperv.h"
0015
0016 #define LINUX_OS_ID ((u64)0x8100 << 48)
0017
0018 static inline uint8_t hypercall(u64 control, vm_vaddr_t input_address,
0019 vm_vaddr_t output_address, uint64_t *hv_status)
0020 {
0021 uint8_t vector;
0022
0023
0024 asm volatile("mov %[output_address], %%r8\n\t"
0025 KVM_ASM_SAFE("vmcall")
0026 : "=a" (*hv_status),
0027 "+c" (control), "+d" (input_address),
0028 KVM_ASM_SAFE_OUTPUTS(vector)
0029 : [output_address] "r"(output_address)
0030 : "cc", "memory", "r8", KVM_ASM_SAFE_CLOBBERS);
0031 return vector;
0032 }
0033
0034 struct msr_data {
0035 uint32_t idx;
0036 bool available;
0037 bool write;
0038 u64 write_val;
0039 };
0040
0041 struct hcall_data {
0042 uint64_t control;
0043 uint64_t expect;
0044 bool ud_expected;
0045 };
0046
0047 static void guest_msr(struct msr_data *msr)
0048 {
0049 uint64_t ignored;
0050 uint8_t vector;
0051
0052 GUEST_ASSERT(msr->idx);
0053
0054 if (!msr->write)
0055 vector = rdmsr_safe(msr->idx, &ignored);
0056 else
0057 vector = wrmsr_safe(msr->idx, msr->write_val);
0058
0059 if (msr->available)
0060 GUEST_ASSERT_2(!vector, msr->idx, vector);
0061 else
0062 GUEST_ASSERT_2(vector == GP_VECTOR, msr->idx, vector);
0063 GUEST_DONE();
0064 }
0065
0066 static void guest_hcall(vm_vaddr_t pgs_gpa, struct hcall_data *hcall)
0067 {
0068 u64 res, input, output;
0069 uint8_t vector;
0070
0071 GUEST_ASSERT(hcall->control);
0072
0073 wrmsr(HV_X64_MSR_GUEST_OS_ID, LINUX_OS_ID);
0074 wrmsr(HV_X64_MSR_HYPERCALL, pgs_gpa);
0075
0076 if (!(hcall->control & HV_HYPERCALL_FAST_BIT)) {
0077 input = pgs_gpa;
0078 output = pgs_gpa + 4096;
0079 } else {
0080 input = output = 0;
0081 }
0082
0083 vector = hypercall(hcall->control, input, output, &res);
0084 if (hcall->ud_expected)
0085 GUEST_ASSERT_2(vector == UD_VECTOR, hcall->control, vector);
0086 else
0087 GUEST_ASSERT_2(!vector, hcall->control, vector);
0088
0089 GUEST_ASSERT_2(!hcall->ud_expected || res == hcall->expect,
0090 hcall->expect, res);
0091 GUEST_DONE();
0092 }
0093
0094 static void vcpu_reset_hv_cpuid(struct kvm_vcpu *vcpu)
0095 {
0096
0097
0098
0099
0100 vcpu_set_hv_cpuid(vcpu);
0101
0102 vcpu_clear_cpuid_entry(vcpu, HYPERV_CPUID_FEATURES);
0103 vcpu_clear_cpuid_entry(vcpu, HYPERV_CPUID_ENLIGHTMENT_INFO);
0104 vcpu_clear_cpuid_entry(vcpu, HYPERV_CPUID_SYNDBG_PLATFORM_CAPABILITIES);
0105 }
0106
0107 static void guest_test_msrs_access(void)
0108 {
0109 struct kvm_cpuid2 *prev_cpuid = NULL;
0110 struct kvm_cpuid_entry2 *feat, *dbg;
0111 struct kvm_vcpu *vcpu;
0112 struct kvm_run *run;
0113 struct kvm_vm *vm;
0114 struct ucall uc;
0115 int stage = 0;
0116 vm_vaddr_t msr_gva;
0117 struct msr_data *msr;
0118
0119 while (true) {
0120 vm = vm_create_with_one_vcpu(&vcpu, guest_msr);
0121
0122 msr_gva = vm_vaddr_alloc_page(vm);
0123 memset(addr_gva2hva(vm, msr_gva), 0x0, getpagesize());
0124 msr = addr_gva2hva(vm, msr_gva);
0125
0126 vcpu_args_set(vcpu, 1, msr_gva);
0127 vcpu_enable_cap(vcpu, KVM_CAP_HYPERV_ENFORCE_CPUID, 1);
0128
0129 if (!prev_cpuid) {
0130 vcpu_reset_hv_cpuid(vcpu);
0131
0132 prev_cpuid = allocate_kvm_cpuid2(vcpu->cpuid->nent);
0133 } else {
0134 vcpu_init_cpuid(vcpu, prev_cpuid);
0135 }
0136
0137 feat = vcpu_get_cpuid_entry(vcpu, HYPERV_CPUID_FEATURES);
0138 dbg = vcpu_get_cpuid_entry(vcpu, HYPERV_CPUID_SYNDBG_PLATFORM_CAPABILITIES);
0139
0140 vm_init_descriptor_tables(vm);
0141 vcpu_init_descriptor_tables(vcpu);
0142
0143 run = vcpu->run;
0144
0145
0146 if (stage >= 21)
0147 vcpu_enable_cap(vcpu, KVM_CAP_HYPERV_SYNIC2, 0);
0148
0149 switch (stage) {
0150 case 0:
0151
0152
0153
0154 msr->idx = HV_X64_MSR_GUEST_OS_ID;
0155 msr->write = 0;
0156 msr->available = 0;
0157 break;
0158 case 1:
0159 msr->idx = HV_X64_MSR_HYPERCALL;
0160 msr->write = 0;
0161 msr->available = 0;
0162 break;
0163 case 2:
0164 feat->eax |= HV_MSR_HYPERCALL_AVAILABLE;
0165
0166
0167
0168
0169 msr->idx = HV_X64_MSR_GUEST_OS_ID;
0170 msr->write = 1;
0171 msr->write_val = LINUX_OS_ID;
0172 msr->available = 1;
0173 break;
0174 case 3:
0175 msr->idx = HV_X64_MSR_GUEST_OS_ID;
0176 msr->write = 0;
0177 msr->available = 1;
0178 break;
0179 case 4:
0180 msr->idx = HV_X64_MSR_HYPERCALL;
0181 msr->write = 0;
0182 msr->available = 1;
0183 break;
0184
0185 case 5:
0186 msr->idx = HV_X64_MSR_VP_RUNTIME;
0187 msr->write = 0;
0188 msr->available = 0;
0189 break;
0190 case 6:
0191 feat->eax |= HV_MSR_VP_RUNTIME_AVAILABLE;
0192 msr->idx = HV_X64_MSR_VP_RUNTIME;
0193 msr->write = 0;
0194 msr->available = 1;
0195 break;
0196 case 7:
0197
0198 msr->idx = HV_X64_MSR_VP_RUNTIME;
0199 msr->write = 1;
0200 msr->write_val = 1;
0201 msr->available = 0;
0202 break;
0203
0204 case 8:
0205 msr->idx = HV_X64_MSR_TIME_REF_COUNT;
0206 msr->write = 0;
0207 msr->available = 0;
0208 break;
0209 case 9:
0210 feat->eax |= HV_MSR_TIME_REF_COUNT_AVAILABLE;
0211 msr->idx = HV_X64_MSR_TIME_REF_COUNT;
0212 msr->write = 0;
0213 msr->available = 1;
0214 break;
0215 case 10:
0216
0217 msr->idx = HV_X64_MSR_TIME_REF_COUNT;
0218 msr->write = 1;
0219 msr->write_val = 1;
0220 msr->available = 0;
0221 break;
0222
0223 case 11:
0224 msr->idx = HV_X64_MSR_VP_INDEX;
0225 msr->write = 0;
0226 msr->available = 0;
0227 break;
0228 case 12:
0229 feat->eax |= HV_MSR_VP_INDEX_AVAILABLE;
0230 msr->idx = HV_X64_MSR_VP_INDEX;
0231 msr->write = 0;
0232 msr->available = 1;
0233 break;
0234 case 13:
0235
0236 msr->idx = HV_X64_MSR_VP_INDEX;
0237 msr->write = 1;
0238 msr->write_val = 1;
0239 msr->available = 0;
0240 break;
0241
0242 case 14:
0243 msr->idx = HV_X64_MSR_RESET;
0244 msr->write = 0;
0245 msr->available = 0;
0246 break;
0247 case 15:
0248 feat->eax |= HV_MSR_RESET_AVAILABLE;
0249 msr->idx = HV_X64_MSR_RESET;
0250 msr->write = 0;
0251 msr->available = 1;
0252 break;
0253 case 16:
0254 msr->idx = HV_X64_MSR_RESET;
0255 msr->write = 1;
0256 msr->write_val = 0;
0257 msr->available = 1;
0258 break;
0259
0260 case 17:
0261 msr->idx = HV_X64_MSR_REFERENCE_TSC;
0262 msr->write = 0;
0263 msr->available = 0;
0264 break;
0265 case 18:
0266 feat->eax |= HV_MSR_REFERENCE_TSC_AVAILABLE;
0267 msr->idx = HV_X64_MSR_REFERENCE_TSC;
0268 msr->write = 0;
0269 msr->available = 1;
0270 break;
0271 case 19:
0272 msr->idx = HV_X64_MSR_REFERENCE_TSC;
0273 msr->write = 1;
0274 msr->write_val = 0;
0275 msr->available = 1;
0276 break;
0277
0278 case 20:
0279 msr->idx = HV_X64_MSR_EOM;
0280 msr->write = 0;
0281 msr->available = 0;
0282 break;
0283 case 21:
0284
0285
0286
0287
0288 msr->idx = HV_X64_MSR_EOM;
0289 msr->write = 0;
0290 msr->available = 0;
0291 break;
0292 case 22:
0293 feat->eax |= HV_MSR_SYNIC_AVAILABLE;
0294 msr->idx = HV_X64_MSR_EOM;
0295 msr->write = 0;
0296 msr->available = 1;
0297 break;
0298 case 23:
0299 msr->idx = HV_X64_MSR_EOM;
0300 msr->write = 1;
0301 msr->write_val = 0;
0302 msr->available = 1;
0303 break;
0304
0305 case 24:
0306 msr->idx = HV_X64_MSR_STIMER0_CONFIG;
0307 msr->write = 0;
0308 msr->available = 0;
0309 break;
0310 case 25:
0311 feat->eax |= HV_MSR_SYNTIMER_AVAILABLE;
0312 msr->idx = HV_X64_MSR_STIMER0_CONFIG;
0313 msr->write = 0;
0314 msr->available = 1;
0315 break;
0316 case 26:
0317 msr->idx = HV_X64_MSR_STIMER0_CONFIG;
0318 msr->write = 1;
0319 msr->write_val = 0;
0320 msr->available = 1;
0321 break;
0322 case 27:
0323
0324 msr->idx = HV_X64_MSR_STIMER0_CONFIG;
0325 msr->write = 1;
0326 msr->write_val = 1 << 12;
0327 msr->available = 0;
0328 break;
0329 case 28:
0330 feat->edx |= HV_STIMER_DIRECT_MODE_AVAILABLE;
0331 msr->idx = HV_X64_MSR_STIMER0_CONFIG;
0332 msr->write = 1;
0333 msr->write_val = 1 << 12;
0334 msr->available = 1;
0335 break;
0336
0337 case 29:
0338 msr->idx = HV_X64_MSR_EOI;
0339 msr->write = 0;
0340 msr->available = 0;
0341 break;
0342 case 30:
0343 feat->eax |= HV_MSR_APIC_ACCESS_AVAILABLE;
0344 msr->idx = HV_X64_MSR_EOI;
0345 msr->write = 1;
0346 msr->write_val = 1;
0347 msr->available = 1;
0348 break;
0349
0350 case 31:
0351 msr->idx = HV_X64_MSR_TSC_FREQUENCY;
0352 msr->write = 0;
0353 msr->available = 0;
0354 break;
0355 case 32:
0356 feat->eax |= HV_ACCESS_FREQUENCY_MSRS;
0357 msr->idx = HV_X64_MSR_TSC_FREQUENCY;
0358 msr->write = 0;
0359 msr->available = 1;
0360 break;
0361 case 33:
0362
0363 msr->idx = HV_X64_MSR_TSC_FREQUENCY;
0364 msr->write = 1;
0365 msr->write_val = 1;
0366 msr->available = 0;
0367 break;
0368
0369 case 34:
0370 msr->idx = HV_X64_MSR_REENLIGHTENMENT_CONTROL;
0371 msr->write = 0;
0372 msr->available = 0;
0373 break;
0374 case 35:
0375 feat->eax |= HV_ACCESS_REENLIGHTENMENT;
0376 msr->idx = HV_X64_MSR_REENLIGHTENMENT_CONTROL;
0377 msr->write = 0;
0378 msr->available = 1;
0379 break;
0380 case 36:
0381 msr->idx = HV_X64_MSR_REENLIGHTENMENT_CONTROL;
0382 msr->write = 1;
0383 msr->write_val = 1;
0384 msr->available = 1;
0385 break;
0386 case 37:
0387
0388 msr->idx = HV_X64_MSR_TSC_EMULATION_STATUS;
0389 msr->write = 1;
0390 msr->write_val = 1;
0391 msr->available = 0;
0392 break;
0393
0394 case 38:
0395 msr->idx = HV_X64_MSR_CRASH_P0;
0396 msr->write = 0;
0397 msr->available = 0;
0398 break;
0399 case 39:
0400 feat->edx |= HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE;
0401 msr->idx = HV_X64_MSR_CRASH_P0;
0402 msr->write = 0;
0403 msr->available = 1;
0404 break;
0405 case 40:
0406 msr->idx = HV_X64_MSR_CRASH_P0;
0407 msr->write = 1;
0408 msr->write_val = 1;
0409 msr->available = 1;
0410 break;
0411
0412 case 41:
0413 msr->idx = HV_X64_MSR_SYNDBG_STATUS;
0414 msr->write = 0;
0415 msr->available = 0;
0416 break;
0417 case 42:
0418 feat->edx |= HV_FEATURE_DEBUG_MSRS_AVAILABLE;
0419 dbg->eax |= HV_X64_SYNDBG_CAP_ALLOW_KERNEL_DEBUGGING;
0420 msr->idx = HV_X64_MSR_SYNDBG_STATUS;
0421 msr->write = 0;
0422 msr->available = 1;
0423 break;
0424 case 43:
0425 msr->idx = HV_X64_MSR_SYNDBG_STATUS;
0426 msr->write = 1;
0427 msr->write_val = 0;
0428 msr->available = 1;
0429 break;
0430
0431 case 44:
0432 kvm_vm_free(vm);
0433 return;
0434 }
0435
0436 vcpu_set_cpuid(vcpu);
0437
0438 memcpy(prev_cpuid, vcpu->cpuid, kvm_cpuid2_size(vcpu->cpuid->nent));
0439
0440 pr_debug("Stage %d: testing msr: 0x%x for %s\n", stage,
0441 msr->idx, msr->write ? "write" : "read");
0442
0443 vcpu_run(vcpu);
0444 TEST_ASSERT(run->exit_reason == KVM_EXIT_IO,
0445 "unexpected exit reason: %u (%s)",
0446 run->exit_reason, exit_reason_str(run->exit_reason));
0447
0448 switch (get_ucall(vcpu, &uc)) {
0449 case UCALL_ABORT:
0450 REPORT_GUEST_ASSERT_2(uc, "MSR = %lx, vector = %lx");
0451 return;
0452 case UCALL_DONE:
0453 break;
0454 default:
0455 TEST_FAIL("Unhandled ucall: %ld", uc.cmd);
0456 return;
0457 }
0458
0459 stage++;
0460 kvm_vm_free(vm);
0461 }
0462 }
0463
0464 static void guest_test_hcalls_access(void)
0465 {
0466 struct kvm_cpuid_entry2 *feat, *recomm, *dbg;
0467 struct kvm_cpuid2 *prev_cpuid = NULL;
0468 struct kvm_vcpu *vcpu;
0469 struct kvm_run *run;
0470 struct kvm_vm *vm;
0471 struct ucall uc;
0472 int stage = 0;
0473 vm_vaddr_t hcall_page, hcall_params;
0474 struct hcall_data *hcall;
0475
0476 while (true) {
0477 vm = vm_create_with_one_vcpu(&vcpu, guest_hcall);
0478
0479 vm_init_descriptor_tables(vm);
0480 vcpu_init_descriptor_tables(vcpu);
0481
0482
0483 hcall_page = vm_vaddr_alloc_pages(vm, 2);
0484 memset(addr_gva2hva(vm, hcall_page), 0x0, 2 * getpagesize());
0485
0486 hcall_params = vm_vaddr_alloc_page(vm);
0487 memset(addr_gva2hva(vm, hcall_params), 0x0, getpagesize());
0488 hcall = addr_gva2hva(vm, hcall_params);
0489
0490 vcpu_args_set(vcpu, 2, addr_gva2gpa(vm, hcall_page), hcall_params);
0491 vcpu_enable_cap(vcpu, KVM_CAP_HYPERV_ENFORCE_CPUID, 1);
0492
0493 if (!prev_cpuid) {
0494 vcpu_reset_hv_cpuid(vcpu);
0495
0496 prev_cpuid = allocate_kvm_cpuid2(vcpu->cpuid->nent);
0497 } else {
0498 vcpu_init_cpuid(vcpu, prev_cpuid);
0499 }
0500
0501 feat = vcpu_get_cpuid_entry(vcpu, HYPERV_CPUID_FEATURES);
0502 recomm = vcpu_get_cpuid_entry(vcpu, HYPERV_CPUID_ENLIGHTMENT_INFO);
0503 dbg = vcpu_get_cpuid_entry(vcpu, HYPERV_CPUID_SYNDBG_PLATFORM_CAPABILITIES);
0504
0505 run = vcpu->run;
0506
0507 switch (stage) {
0508 case 0:
0509 feat->eax |= HV_MSR_HYPERCALL_AVAILABLE;
0510 hcall->control = 0xdeadbeef;
0511 hcall->expect = HV_STATUS_INVALID_HYPERCALL_CODE;
0512 break;
0513
0514 case 1:
0515 hcall->control = HVCALL_POST_MESSAGE;
0516 hcall->expect = HV_STATUS_ACCESS_DENIED;
0517 break;
0518 case 2:
0519 feat->ebx |= HV_POST_MESSAGES;
0520 hcall->control = HVCALL_POST_MESSAGE;
0521 hcall->expect = HV_STATUS_INVALID_HYPERCALL_INPUT;
0522 break;
0523
0524 case 3:
0525 hcall->control = HVCALL_SIGNAL_EVENT;
0526 hcall->expect = HV_STATUS_ACCESS_DENIED;
0527 break;
0528 case 4:
0529 feat->ebx |= HV_SIGNAL_EVENTS;
0530 hcall->control = HVCALL_SIGNAL_EVENT;
0531 hcall->expect = HV_STATUS_INVALID_HYPERCALL_INPUT;
0532 break;
0533
0534 case 5:
0535 hcall->control = HVCALL_RESET_DEBUG_SESSION;
0536 hcall->expect = HV_STATUS_INVALID_HYPERCALL_CODE;
0537 break;
0538 case 6:
0539 dbg->eax |= HV_X64_SYNDBG_CAP_ALLOW_KERNEL_DEBUGGING;
0540 hcall->control = HVCALL_RESET_DEBUG_SESSION;
0541 hcall->expect = HV_STATUS_ACCESS_DENIED;
0542 break;
0543 case 7:
0544 feat->ebx |= HV_DEBUGGING;
0545 hcall->control = HVCALL_RESET_DEBUG_SESSION;
0546 hcall->expect = HV_STATUS_OPERATION_DENIED;
0547 break;
0548
0549 case 8:
0550 hcall->control = HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE;
0551 hcall->expect = HV_STATUS_ACCESS_DENIED;
0552 break;
0553 case 9:
0554 recomm->eax |= HV_X64_REMOTE_TLB_FLUSH_RECOMMENDED;
0555 hcall->control = HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE;
0556 hcall->expect = HV_STATUS_SUCCESS;
0557 break;
0558 case 10:
0559 hcall->control = HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE_EX;
0560 hcall->expect = HV_STATUS_ACCESS_DENIED;
0561 break;
0562 case 11:
0563 recomm->eax |= HV_X64_EX_PROCESSOR_MASKS_RECOMMENDED;
0564 hcall->control = HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE_EX;
0565 hcall->expect = HV_STATUS_SUCCESS;
0566 break;
0567
0568 case 12:
0569 hcall->control = HVCALL_SEND_IPI;
0570 hcall->expect = HV_STATUS_ACCESS_DENIED;
0571 break;
0572 case 13:
0573 recomm->eax |= HV_X64_CLUSTER_IPI_RECOMMENDED;
0574 hcall->control = HVCALL_SEND_IPI;
0575 hcall->expect = HV_STATUS_INVALID_HYPERCALL_INPUT;
0576 break;
0577 case 14:
0578
0579 hcall->control = HVCALL_SEND_IPI_EX;
0580 hcall->expect = HV_STATUS_SUCCESS;
0581 break;
0582
0583 case 15:
0584 hcall->control = HVCALL_NOTIFY_LONG_SPIN_WAIT;
0585 hcall->expect = HV_STATUS_ACCESS_DENIED;
0586 break;
0587 case 16:
0588 recomm->ebx = 0xfff;
0589 hcall->control = HVCALL_NOTIFY_LONG_SPIN_WAIT;
0590 hcall->expect = HV_STATUS_SUCCESS;
0591 break;
0592 case 17:
0593
0594 hcall->control = HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE | HV_HYPERCALL_FAST_BIT;
0595 hcall->ud_expected = true;
0596 break;
0597 case 18:
0598 feat->edx |= HV_X64_HYPERCALL_XMM_INPUT_AVAILABLE;
0599 hcall->control = HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE | HV_HYPERCALL_FAST_BIT;
0600 hcall->ud_expected = false;
0601 hcall->expect = HV_STATUS_SUCCESS;
0602 break;
0603 case 19:
0604 kvm_vm_free(vm);
0605 return;
0606 }
0607
0608 vcpu_set_cpuid(vcpu);
0609
0610 memcpy(prev_cpuid, vcpu->cpuid, kvm_cpuid2_size(vcpu->cpuid->nent));
0611
0612 pr_debug("Stage %d: testing hcall: 0x%lx\n", stage, hcall->control);
0613
0614 vcpu_run(vcpu);
0615 TEST_ASSERT(run->exit_reason == KVM_EXIT_IO,
0616 "unexpected exit reason: %u (%s)",
0617 run->exit_reason, exit_reason_str(run->exit_reason));
0618
0619 switch (get_ucall(vcpu, &uc)) {
0620 case UCALL_ABORT:
0621 REPORT_GUEST_ASSERT_2(uc, "arg1 = %lx, arg2 = %lx");
0622 return;
0623 case UCALL_DONE:
0624 break;
0625 default:
0626 TEST_FAIL("Unhandled ucall: %ld", uc.cmd);
0627 return;
0628 }
0629
0630 stage++;
0631 kvm_vm_free(vm);
0632 }
0633 }
0634
0635 int main(void)
0636 {
0637 pr_info("Testing access to Hyper-V specific MSRs\n");
0638 guest_test_msrs_access();
0639
0640 pr_info("Testing access to Hyper-V hypercalls\n");
0641 guest_test_hcalls_access();
0642 }