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