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