spnego: add missing OID to oid registry
[sfrench/cifs-2.6.git] / tools / testing / selftests / kvm / x86_64 / pmu_event_filter_test.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Test for x86 KVM_SET_PMU_EVENT_FILTER.
4  *
5  * Copyright (C) 2022, Google LLC.
6  *
7  * This work is licensed under the terms of the GNU GPL, version 2.
8  *
9  * Verifies the expected behavior of allow lists and deny lists for
10  * virtual PMU events.
11  */
12
13 #define _GNU_SOURCE /* for program_invocation_short_name */
14 #include "test_util.h"
15 #include "kvm_util.h"
16 #include "processor.h"
17
18 /*
19  * In lieu of copying perf_event.h into tools...
20  */
21 #define ARCH_PERFMON_EVENTSEL_OS                        (1ULL << 17)
22 #define ARCH_PERFMON_EVENTSEL_ENABLE                    (1ULL << 22)
23
24 /* End of stuff taken from perf_event.h. */
25
26 /* Oddly, this isn't in perf_event.h. */
27 #define ARCH_PERFMON_BRANCHES_RETIRED           5
28
29 #define NUM_BRANCHES 42
30
31 /*
32  * This is how the event selector and unit mask are stored in an AMD
33  * core performance event-select register. Intel's format is similar,
34  * but the event selector is only 8 bits.
35  */
36 #define EVENT(select, umask) ((select & 0xf00UL) << 24 | (select & 0xff) | \
37                               (umask & 0xff) << 8)
38
39 /*
40  * "Branch instructions retired", from the Intel SDM, volume 3,
41  * "Pre-defined Architectural Performance Events."
42  */
43
44 #define INTEL_BR_RETIRED EVENT(0xc4, 0)
45
46 /*
47  * "Retired branch instructions", from Processor Programming Reference
48  * (PPR) for AMD Family 17h Model 01h, Revision B1 Processors,
49  * Preliminary Processor Programming Reference (PPR) for AMD Family
50  * 17h Model 31h, Revision B0 Processors, and Preliminary Processor
51  * Programming Reference (PPR) for AMD Family 19h Model 01h, Revision
52  * B1 Processors Volume 1 of 2.
53  */
54
55 #define AMD_ZEN_BR_RETIRED EVENT(0xc2, 0)
56
57
58 /*
59  * "Retired instructions", from Processor Programming Reference
60  * (PPR) for AMD Family 17h Model 01h, Revision B1 Processors,
61  * Preliminary Processor Programming Reference (PPR) for AMD Family
62  * 17h Model 31h, Revision B0 Processors, and Preliminary Processor
63  * Programming Reference (PPR) for AMD Family 19h Model 01h, Revision
64  * B1 Processors Volume 1 of 2.
65  *                      --- and ---
66  * "Instructions retired", from the Intel SDM, volume 3,
67  * "Pre-defined Architectural Performance Events."
68  */
69
70 #define INST_RETIRED EVENT(0xc0, 0)
71
72 /*
73  * This event list comprises Intel's eight architectural events plus
74  * AMD's "retired branch instructions" for Zen[123] (and possibly
75  * other AMD CPUs).
76  */
77 static const uint64_t event_list[] = {
78         EVENT(0x3c, 0),
79         INST_RETIRED,
80         EVENT(0x3c, 1),
81         EVENT(0x2e, 0x4f),
82         EVENT(0x2e, 0x41),
83         EVENT(0xc4, 0),
84         EVENT(0xc5, 0),
85         EVENT(0xa4, 1),
86         AMD_ZEN_BR_RETIRED,
87 };
88
89 struct {
90         uint64_t loads;
91         uint64_t stores;
92         uint64_t loads_stores;
93         uint64_t branches_retired;
94         uint64_t instructions_retired;
95 } pmc_results;
96
97 /*
98  * If we encounter a #GP during the guest PMU sanity check, then the guest
99  * PMU is not functional. Inform the hypervisor via GUEST_SYNC(0).
100  */
101 static void guest_gp_handler(struct ex_regs *regs)
102 {
103         GUEST_SYNC(-EFAULT);
104 }
105
106 /*
107  * Check that we can write a new value to the given MSR and read it back.
108  * The caller should provide a non-empty set of bits that are safe to flip.
109  *
110  * Return on success. GUEST_SYNC(0) on error.
111  */
112 static void check_msr(uint32_t msr, uint64_t bits_to_flip)
113 {
114         uint64_t v = rdmsr(msr) ^ bits_to_flip;
115
116         wrmsr(msr, v);
117         if (rdmsr(msr) != v)
118                 GUEST_SYNC(-EIO);
119
120         v ^= bits_to_flip;
121         wrmsr(msr, v);
122         if (rdmsr(msr) != v)
123                 GUEST_SYNC(-EIO);
124 }
125
126 static void run_and_measure_loop(uint32_t msr_base)
127 {
128         const uint64_t branches_retired = rdmsr(msr_base + 0);
129         const uint64_t insn_retired = rdmsr(msr_base + 1);
130
131         __asm__ __volatile__("loop ." : "+c"((int){NUM_BRANCHES}));
132
133         pmc_results.branches_retired = rdmsr(msr_base + 0) - branches_retired;
134         pmc_results.instructions_retired = rdmsr(msr_base + 1) - insn_retired;
135 }
136
137 static void intel_guest_code(void)
138 {
139         check_msr(MSR_CORE_PERF_GLOBAL_CTRL, 1);
140         check_msr(MSR_P6_EVNTSEL0, 0xffff);
141         check_msr(MSR_IA32_PMC0, 0xffff);
142         GUEST_SYNC(0);
143
144         for (;;) {
145                 wrmsr(MSR_CORE_PERF_GLOBAL_CTRL, 0);
146                 wrmsr(MSR_P6_EVNTSEL0, ARCH_PERFMON_EVENTSEL_ENABLE |
147                       ARCH_PERFMON_EVENTSEL_OS | INTEL_BR_RETIRED);
148                 wrmsr(MSR_P6_EVNTSEL1, ARCH_PERFMON_EVENTSEL_ENABLE |
149                       ARCH_PERFMON_EVENTSEL_OS | INST_RETIRED);
150                 wrmsr(MSR_CORE_PERF_GLOBAL_CTRL, 0x3);
151
152                 run_and_measure_loop(MSR_IA32_PMC0);
153                 GUEST_SYNC(0);
154         }
155 }
156
157 /*
158  * To avoid needing a check for CPUID.80000001:ECX.PerfCtrExtCore[bit 23],
159  * this code uses the always-available, legacy K7 PMU MSRs, which alias to
160  * the first four of the six extended core PMU MSRs.
161  */
162 static void amd_guest_code(void)
163 {
164         check_msr(MSR_K7_EVNTSEL0, 0xffff);
165         check_msr(MSR_K7_PERFCTR0, 0xffff);
166         GUEST_SYNC(0);
167
168         for (;;) {
169                 wrmsr(MSR_K7_EVNTSEL0, 0);
170                 wrmsr(MSR_K7_EVNTSEL0, ARCH_PERFMON_EVENTSEL_ENABLE |
171                       ARCH_PERFMON_EVENTSEL_OS | AMD_ZEN_BR_RETIRED);
172                 wrmsr(MSR_K7_EVNTSEL1, ARCH_PERFMON_EVENTSEL_ENABLE |
173                       ARCH_PERFMON_EVENTSEL_OS | INST_RETIRED);
174
175                 run_and_measure_loop(MSR_K7_PERFCTR0);
176                 GUEST_SYNC(0);
177         }
178 }
179
180 /*
181  * Run the VM to the next GUEST_SYNC(value), and return the value passed
182  * to the sync. Any other exit from the guest is fatal.
183  */
184 static uint64_t run_vcpu_to_sync(struct kvm_vcpu *vcpu)
185 {
186         struct ucall uc;
187
188         vcpu_run(vcpu);
189         TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_IO);
190         get_ucall(vcpu, &uc);
191         TEST_ASSERT(uc.cmd == UCALL_SYNC,
192                     "Received ucall other than UCALL_SYNC: %lu", uc.cmd);
193         return uc.args[1];
194 }
195
196 static void run_vcpu_and_sync_pmc_results(struct kvm_vcpu *vcpu)
197 {
198         uint64_t r;
199
200         memset(&pmc_results, 0, sizeof(pmc_results));
201         sync_global_to_guest(vcpu->vm, pmc_results);
202
203         r = run_vcpu_to_sync(vcpu);
204         TEST_ASSERT(!r, "Unexpected sync value: 0x%lx", r);
205
206         sync_global_from_guest(vcpu->vm, pmc_results);
207 }
208
209 /*
210  * In a nested environment or if the vPMU is disabled, the guest PMU
211  * might not work as architected (accessing the PMU MSRs may raise
212  * #GP, or writes could simply be discarded). In those situations,
213  * there is no point in running these tests. The guest code will perform
214  * a sanity check and then GUEST_SYNC(success). In the case of failure,
215  * the behavior of the guest on resumption is undefined.
216  */
217 static bool sanity_check_pmu(struct kvm_vcpu *vcpu)
218 {
219         uint64_t r;
220
221         vm_install_exception_handler(vcpu->vm, GP_VECTOR, guest_gp_handler);
222         r = run_vcpu_to_sync(vcpu);
223         vm_install_exception_handler(vcpu->vm, GP_VECTOR, NULL);
224
225         return !r;
226 }
227
228 static struct kvm_pmu_event_filter *alloc_pmu_event_filter(uint32_t nevents)
229 {
230         struct kvm_pmu_event_filter *f;
231         int size = sizeof(*f) + nevents * sizeof(f->events[0]);
232
233         f = malloc(size);
234         TEST_ASSERT(f, "Out of memory");
235         memset(f, 0, size);
236         f->nevents = nevents;
237         return f;
238 }
239
240
241 static struct kvm_pmu_event_filter *
242 create_pmu_event_filter(const uint64_t event_list[], int nevents,
243                         uint32_t action, uint32_t flags)
244 {
245         struct kvm_pmu_event_filter *f;
246         int i;
247
248         f = alloc_pmu_event_filter(nevents);
249         f->action = action;
250         f->flags = flags;
251         for (i = 0; i < nevents; i++)
252                 f->events[i] = event_list[i];
253
254         return f;
255 }
256
257 static struct kvm_pmu_event_filter *event_filter(uint32_t action)
258 {
259         return create_pmu_event_filter(event_list,
260                                        ARRAY_SIZE(event_list),
261                                        action, 0);
262 }
263
264 /*
265  * Remove the first occurrence of 'event' (if any) from the filter's
266  * event list.
267  */
268 static struct kvm_pmu_event_filter *remove_event(struct kvm_pmu_event_filter *f,
269                                                  uint64_t event)
270 {
271         bool found = false;
272         int i;
273
274         for (i = 0; i < f->nevents; i++) {
275                 if (found)
276                         f->events[i - 1] = f->events[i];
277                 else
278                         found = f->events[i] == event;
279         }
280         if (found)
281                 f->nevents--;
282         return f;
283 }
284
285 #define ASSERT_PMC_COUNTING_INSTRUCTIONS()                                              \
286 do {                                                                                    \
287         uint64_t br = pmc_results.branches_retired;                                     \
288         uint64_t ir = pmc_results.instructions_retired;                                 \
289                                                                                         \
290         if (br && br != NUM_BRANCHES)                                                   \
291                 pr_info("%s: Branch instructions retired = %lu (expected %u)\n",        \
292                         __func__, br, NUM_BRANCHES);                                    \
293         TEST_ASSERT(br, "%s: Branch instructions retired = %lu (expected > 0)",         \
294                     __func__, br);                                                      \
295         TEST_ASSERT(ir, "%s: Instructions retired = %lu (expected > 0)",                \
296                     __func__, ir);                                                      \
297 } while (0)
298
299 #define ASSERT_PMC_NOT_COUNTING_INSTRUCTIONS()                                          \
300 do {                                                                                    \
301         uint64_t br = pmc_results.branches_retired;                                     \
302         uint64_t ir = pmc_results.instructions_retired;                                 \
303                                                                                         \
304         TEST_ASSERT(!br, "%s: Branch instructions retired = %lu (expected 0)",          \
305                     __func__, br);                                                      \
306         TEST_ASSERT(!ir, "%s: Instructions retired = %lu (expected 0)",                 \
307                     __func__, ir);                                                      \
308 } while (0)
309
310 static void test_without_filter(struct kvm_vcpu *vcpu)
311 {
312         run_vcpu_and_sync_pmc_results(vcpu);
313
314         ASSERT_PMC_COUNTING_INSTRUCTIONS();
315 }
316
317 static void test_with_filter(struct kvm_vcpu *vcpu,
318                              struct kvm_pmu_event_filter *f)
319 {
320         vm_ioctl(vcpu->vm, KVM_SET_PMU_EVENT_FILTER, f);
321         run_vcpu_and_sync_pmc_results(vcpu);
322 }
323
324 static void test_amd_deny_list(struct kvm_vcpu *vcpu)
325 {
326         uint64_t event = EVENT(0x1C2, 0);
327         struct kvm_pmu_event_filter *f;
328
329         f = create_pmu_event_filter(&event, 1, KVM_PMU_EVENT_DENY, 0);
330         test_with_filter(vcpu, f);
331         free(f);
332
333         ASSERT_PMC_COUNTING_INSTRUCTIONS();
334 }
335
336 static void test_member_deny_list(struct kvm_vcpu *vcpu)
337 {
338         struct kvm_pmu_event_filter *f = event_filter(KVM_PMU_EVENT_DENY);
339
340         test_with_filter(vcpu, f);
341         free(f);
342
343         ASSERT_PMC_NOT_COUNTING_INSTRUCTIONS();
344 }
345
346 static void test_member_allow_list(struct kvm_vcpu *vcpu)
347 {
348         struct kvm_pmu_event_filter *f = event_filter(KVM_PMU_EVENT_ALLOW);
349
350         test_with_filter(vcpu, f);
351         free(f);
352
353         ASSERT_PMC_COUNTING_INSTRUCTIONS();
354 }
355
356 static void test_not_member_deny_list(struct kvm_vcpu *vcpu)
357 {
358         struct kvm_pmu_event_filter *f = event_filter(KVM_PMU_EVENT_DENY);
359
360         remove_event(f, INST_RETIRED);
361         remove_event(f, INTEL_BR_RETIRED);
362         remove_event(f, AMD_ZEN_BR_RETIRED);
363         test_with_filter(vcpu, f);
364         free(f);
365
366         ASSERT_PMC_COUNTING_INSTRUCTIONS();
367 }
368
369 static void test_not_member_allow_list(struct kvm_vcpu *vcpu)
370 {
371         struct kvm_pmu_event_filter *f = event_filter(KVM_PMU_EVENT_ALLOW);
372
373         remove_event(f, INST_RETIRED);
374         remove_event(f, INTEL_BR_RETIRED);
375         remove_event(f, AMD_ZEN_BR_RETIRED);
376         test_with_filter(vcpu, f);
377         free(f);
378
379         ASSERT_PMC_NOT_COUNTING_INSTRUCTIONS();
380 }
381
382 /*
383  * Verify that setting KVM_PMU_CAP_DISABLE prevents the use of the PMU.
384  *
385  * Note that KVM_CAP_PMU_CAPABILITY must be invoked prior to creating VCPUs.
386  */
387 static void test_pmu_config_disable(void (*guest_code)(void))
388 {
389         struct kvm_vcpu *vcpu;
390         int r;
391         struct kvm_vm *vm;
392
393         r = kvm_check_cap(KVM_CAP_PMU_CAPABILITY);
394         if (!(r & KVM_PMU_CAP_DISABLE))
395                 return;
396
397         vm = vm_create(1);
398
399         vm_enable_cap(vm, KVM_CAP_PMU_CAPABILITY, KVM_PMU_CAP_DISABLE);
400
401         vcpu = vm_vcpu_add(vm, 0, guest_code);
402         vm_init_descriptor_tables(vm);
403         vcpu_init_descriptor_tables(vcpu);
404
405         TEST_ASSERT(!sanity_check_pmu(vcpu),
406                     "Guest should not be able to use disabled PMU.");
407
408         kvm_vm_free(vm);
409 }
410
411 /*
412  * On Intel, check for a non-zero PMU version, at least one general-purpose
413  * counter per logical processor, and support for counting the number of branch
414  * instructions retired.
415  */
416 static bool use_intel_pmu(void)
417 {
418         return host_cpu_is_intel &&
419                kvm_cpu_property(X86_PROPERTY_PMU_VERSION) &&
420                kvm_cpu_property(X86_PROPERTY_PMU_NR_GP_COUNTERS) &&
421                kvm_pmu_has(X86_PMU_FEATURE_BRANCH_INSNS_RETIRED);
422 }
423
424 static bool is_zen1(uint32_t family, uint32_t model)
425 {
426         return family == 0x17 && model <= 0x0f;
427 }
428
429 static bool is_zen2(uint32_t family, uint32_t model)
430 {
431         return family == 0x17 && model >= 0x30 && model <= 0x3f;
432 }
433
434 static bool is_zen3(uint32_t family, uint32_t model)
435 {
436         return family == 0x19 && model <= 0x0f;
437 }
438
439 /*
440  * Determining AMD support for a PMU event requires consulting the AMD
441  * PPR for the CPU or reference material derived therefrom. The AMD
442  * test code herein has been verified to work on Zen1, Zen2, and Zen3.
443  *
444  * Feel free to add more AMD CPUs that are documented to support event
445  * select 0xc2 umask 0 as "retired branch instructions."
446  */
447 static bool use_amd_pmu(void)
448 {
449         uint32_t family = kvm_cpu_family();
450         uint32_t model = kvm_cpu_model();
451
452         return host_cpu_is_amd &&
453                 (is_zen1(family, model) ||
454                  is_zen2(family, model) ||
455                  is_zen3(family, model));
456 }
457
458 /*
459  * "MEM_INST_RETIRED.ALL_LOADS", "MEM_INST_RETIRED.ALL_STORES", and
460  * "MEM_INST_RETIRED.ANY" from https://perfmon-events.intel.com/
461  * supported on Intel Xeon processors:
462  *  - Sapphire Rapids, Ice Lake, Cascade Lake, Skylake.
463  */
464 #define MEM_INST_RETIRED                0xD0
465 #define MEM_INST_RETIRED_LOAD           EVENT(MEM_INST_RETIRED, 0x81)
466 #define MEM_INST_RETIRED_STORE          EVENT(MEM_INST_RETIRED, 0x82)
467 #define MEM_INST_RETIRED_LOAD_STORE     EVENT(MEM_INST_RETIRED, 0x83)
468
469 static bool supports_event_mem_inst_retired(void)
470 {
471         uint32_t eax, ebx, ecx, edx;
472
473         cpuid(1, &eax, &ebx, &ecx, &edx);
474         if (x86_family(eax) == 0x6) {
475                 switch (x86_model(eax)) {
476                 /* Sapphire Rapids */
477                 case 0x8F:
478                 /* Ice Lake */
479                 case 0x6A:
480                 /* Skylake */
481                 /* Cascade Lake */
482                 case 0x55:
483                         return true;
484                 }
485         }
486
487         return false;
488 }
489
490 /*
491  * "LS Dispatch", from Processor Programming Reference
492  * (PPR) for AMD Family 17h Model 01h, Revision B1 Processors,
493  * Preliminary Processor Programming Reference (PPR) for AMD Family
494  * 17h Model 31h, Revision B0 Processors, and Preliminary Processor
495  * Programming Reference (PPR) for AMD Family 19h Model 01h, Revision
496  * B1 Processors Volume 1 of 2.
497  */
498 #define LS_DISPATCH             0x29
499 #define LS_DISPATCH_LOAD        EVENT(LS_DISPATCH, BIT(0))
500 #define LS_DISPATCH_STORE       EVENT(LS_DISPATCH, BIT(1))
501 #define LS_DISPATCH_LOAD_STORE  EVENT(LS_DISPATCH, BIT(2))
502
503 #define INCLUDE_MASKED_ENTRY(event_select, mask, match) \
504         KVM_PMU_ENCODE_MASKED_ENTRY(event_select, mask, match, false)
505 #define EXCLUDE_MASKED_ENTRY(event_select, mask, match) \
506         KVM_PMU_ENCODE_MASKED_ENTRY(event_select, mask, match, true)
507
508 static void masked_events_guest_test(uint32_t msr_base)
509 {
510         /*
511          * The actual value of the counters don't determine the outcome of
512          * the test.  Only that they are zero or non-zero.
513          */
514         const uint64_t loads = rdmsr(msr_base + 0);
515         const uint64_t stores = rdmsr(msr_base + 1);
516         const uint64_t loads_stores = rdmsr(msr_base + 2);
517         int val;
518
519
520         __asm__ __volatile__("movl $0, %[v];"
521                              "movl %[v], %%eax;"
522                              "incl %[v];"
523                              : [v]"+m"(val) :: "eax");
524
525         pmc_results.loads = rdmsr(msr_base + 0) - loads;
526         pmc_results.stores = rdmsr(msr_base + 1) - stores;
527         pmc_results.loads_stores = rdmsr(msr_base + 2) - loads_stores;
528 }
529
530 static void intel_masked_events_guest_code(void)
531 {
532         for (;;) {
533                 wrmsr(MSR_CORE_PERF_GLOBAL_CTRL, 0);
534
535                 wrmsr(MSR_P6_EVNTSEL0 + 0, ARCH_PERFMON_EVENTSEL_ENABLE |
536                       ARCH_PERFMON_EVENTSEL_OS | MEM_INST_RETIRED_LOAD);
537                 wrmsr(MSR_P6_EVNTSEL0 + 1, ARCH_PERFMON_EVENTSEL_ENABLE |
538                       ARCH_PERFMON_EVENTSEL_OS | MEM_INST_RETIRED_STORE);
539                 wrmsr(MSR_P6_EVNTSEL0 + 2, ARCH_PERFMON_EVENTSEL_ENABLE |
540                       ARCH_PERFMON_EVENTSEL_OS | MEM_INST_RETIRED_LOAD_STORE);
541
542                 wrmsr(MSR_CORE_PERF_GLOBAL_CTRL, 0x7);
543
544                 masked_events_guest_test(MSR_IA32_PMC0);
545                 GUEST_SYNC(0);
546         }
547 }
548
549 static void amd_masked_events_guest_code(void)
550 {
551         for (;;) {
552                 wrmsr(MSR_K7_EVNTSEL0, 0);
553                 wrmsr(MSR_K7_EVNTSEL1, 0);
554                 wrmsr(MSR_K7_EVNTSEL2, 0);
555
556                 wrmsr(MSR_K7_EVNTSEL0, ARCH_PERFMON_EVENTSEL_ENABLE |
557                       ARCH_PERFMON_EVENTSEL_OS | LS_DISPATCH_LOAD);
558                 wrmsr(MSR_K7_EVNTSEL1, ARCH_PERFMON_EVENTSEL_ENABLE |
559                       ARCH_PERFMON_EVENTSEL_OS | LS_DISPATCH_STORE);
560                 wrmsr(MSR_K7_EVNTSEL2, ARCH_PERFMON_EVENTSEL_ENABLE |
561                       ARCH_PERFMON_EVENTSEL_OS | LS_DISPATCH_LOAD_STORE);
562
563                 masked_events_guest_test(MSR_K7_PERFCTR0);
564                 GUEST_SYNC(0);
565         }
566 }
567
568 static void run_masked_events_test(struct kvm_vcpu *vcpu,
569                                    const uint64_t masked_events[],
570                                    const int nmasked_events)
571 {
572         struct kvm_pmu_event_filter *f;
573
574         f = create_pmu_event_filter(masked_events, nmasked_events,
575                                     KVM_PMU_EVENT_ALLOW,
576                                     KVM_PMU_EVENT_FLAG_MASKED_EVENTS);
577         test_with_filter(vcpu, f);
578         free(f);
579 }
580
581 /* Matches KVM_PMU_EVENT_FILTER_MAX_EVENTS in pmu.c */
582 #define MAX_FILTER_EVENTS       300
583 #define MAX_TEST_EVENTS         10
584
585 #define ALLOW_LOADS             BIT(0)
586 #define ALLOW_STORES            BIT(1)
587 #define ALLOW_LOADS_STORES      BIT(2)
588
589 struct masked_events_test {
590         uint64_t intel_events[MAX_TEST_EVENTS];
591         uint64_t intel_event_end;
592         uint64_t amd_events[MAX_TEST_EVENTS];
593         uint64_t amd_event_end;
594         const char *msg;
595         uint32_t flags;
596 };
597
598 /*
599  * These are the test cases for the masked events tests.
600  *
601  * For each test, the guest enables 3 PMU counters (loads, stores,
602  * loads + stores).  The filter is then set in KVM with the masked events
603  * provided.  The test then verifies that the counters agree with which
604  * ones should be counting and which ones should be filtered.
605  */
606 const struct masked_events_test test_cases[] = {
607         {
608                 .intel_events = {
609                         INCLUDE_MASKED_ENTRY(MEM_INST_RETIRED, 0xFF, 0x81),
610                 },
611                 .amd_events = {
612                         INCLUDE_MASKED_ENTRY(LS_DISPATCH, 0xFF, BIT(0)),
613                 },
614                 .msg = "Only allow loads.",
615                 .flags = ALLOW_LOADS,
616         }, {
617                 .intel_events = {
618                         INCLUDE_MASKED_ENTRY(MEM_INST_RETIRED, 0xFF, 0x82),
619                 },
620                 .amd_events = {
621                         INCLUDE_MASKED_ENTRY(LS_DISPATCH, 0xFF, BIT(1)),
622                 },
623                 .msg = "Only allow stores.",
624                 .flags = ALLOW_STORES,
625         }, {
626                 .intel_events = {
627                         INCLUDE_MASKED_ENTRY(MEM_INST_RETIRED, 0xFF, 0x83),
628                 },
629                 .amd_events = {
630                         INCLUDE_MASKED_ENTRY(LS_DISPATCH, 0xFF, BIT(2)),
631                 },
632                 .msg = "Only allow loads + stores.",
633                 .flags = ALLOW_LOADS_STORES,
634         }, {
635                 .intel_events = {
636                         INCLUDE_MASKED_ENTRY(MEM_INST_RETIRED, 0x7C, 0),
637                         EXCLUDE_MASKED_ENTRY(MEM_INST_RETIRED, 0xFF, 0x83),
638                 },
639                 .amd_events = {
640                         INCLUDE_MASKED_ENTRY(LS_DISPATCH, ~(BIT(0) | BIT(1)), 0),
641                 },
642                 .msg = "Only allow loads and stores.",
643                 .flags = ALLOW_LOADS | ALLOW_STORES,
644         }, {
645                 .intel_events = {
646                         INCLUDE_MASKED_ENTRY(MEM_INST_RETIRED, 0x7C, 0),
647                         EXCLUDE_MASKED_ENTRY(MEM_INST_RETIRED, 0xFF, 0x82),
648                 },
649                 .amd_events = {
650                         INCLUDE_MASKED_ENTRY(LS_DISPATCH, 0xF8, 0),
651                         EXCLUDE_MASKED_ENTRY(LS_DISPATCH, 0xFF, BIT(1)),
652                 },
653                 .msg = "Only allow loads and loads + stores.",
654                 .flags = ALLOW_LOADS | ALLOW_LOADS_STORES
655         }, {
656                 .intel_events = {
657                         INCLUDE_MASKED_ENTRY(MEM_INST_RETIRED, 0xFE, 0x82),
658                 },
659                 .amd_events = {
660                         INCLUDE_MASKED_ENTRY(LS_DISPATCH, 0xF8, 0),
661                         EXCLUDE_MASKED_ENTRY(LS_DISPATCH, 0xFF, BIT(0)),
662                 },
663                 .msg = "Only allow stores and loads + stores.",
664                 .flags = ALLOW_STORES | ALLOW_LOADS_STORES
665         }, {
666                 .intel_events = {
667                         INCLUDE_MASKED_ENTRY(MEM_INST_RETIRED, 0x7C, 0),
668                 },
669                 .amd_events = {
670                         INCLUDE_MASKED_ENTRY(LS_DISPATCH, 0xF8, 0),
671                 },
672                 .msg = "Only allow loads, stores, and loads + stores.",
673                 .flags = ALLOW_LOADS | ALLOW_STORES | ALLOW_LOADS_STORES
674         },
675 };
676
677 static int append_test_events(const struct masked_events_test *test,
678                               uint64_t *events, int nevents)
679 {
680         const uint64_t *evts;
681         int i;
682
683         evts = use_intel_pmu() ? test->intel_events : test->amd_events;
684         for (i = 0; i < MAX_TEST_EVENTS; i++) {
685                 if (evts[i] == 0)
686                         break;
687
688                 events[nevents + i] = evts[i];
689         }
690
691         return nevents + i;
692 }
693
694 static bool bool_eq(bool a, bool b)
695 {
696         return a == b;
697 }
698
699 static void run_masked_events_tests(struct kvm_vcpu *vcpu, uint64_t *events,
700                                     int nevents)
701 {
702         int ntests = ARRAY_SIZE(test_cases);
703         int i, n;
704
705         for (i = 0; i < ntests; i++) {
706                 const struct masked_events_test *test = &test_cases[i];
707
708                 /* Do any test case events overflow MAX_TEST_EVENTS? */
709                 assert(test->intel_event_end == 0);
710                 assert(test->amd_event_end == 0);
711
712                 n = append_test_events(test, events, nevents);
713
714                 run_masked_events_test(vcpu, events, n);
715
716                 TEST_ASSERT(bool_eq(pmc_results.loads, test->flags & ALLOW_LOADS) &&
717                             bool_eq(pmc_results.stores, test->flags & ALLOW_STORES) &&
718                             bool_eq(pmc_results.loads_stores,
719                                     test->flags & ALLOW_LOADS_STORES),
720                             "%s  loads: %lu, stores: %lu, loads + stores: %lu",
721                             test->msg, pmc_results.loads, pmc_results.stores,
722                             pmc_results.loads_stores);
723         }
724 }
725
726 static void add_dummy_events(uint64_t *events, int nevents)
727 {
728         int i;
729
730         for (i = 0; i < nevents; i++) {
731                 int event_select = i % 0xFF;
732                 bool exclude = ((i % 4) == 0);
733
734                 if (event_select == MEM_INST_RETIRED ||
735                     event_select == LS_DISPATCH)
736                         event_select++;
737
738                 events[i] = KVM_PMU_ENCODE_MASKED_ENTRY(event_select, 0,
739                                                         0, exclude);
740         }
741 }
742
743 static void test_masked_events(struct kvm_vcpu *vcpu)
744 {
745         int nevents = MAX_FILTER_EVENTS - MAX_TEST_EVENTS;
746         uint64_t events[MAX_FILTER_EVENTS];
747
748         /* Run the test cases against a sparse PMU event filter. */
749         run_masked_events_tests(vcpu, events, 0);
750
751         /* Run the test cases against a dense PMU event filter. */
752         add_dummy_events(events, MAX_FILTER_EVENTS);
753         run_masked_events_tests(vcpu, events, nevents);
754 }
755
756 static int run_filter_test(struct kvm_vcpu *vcpu, const uint64_t *events,
757                            int nevents, uint32_t flags)
758 {
759         struct kvm_pmu_event_filter *f;
760         int r;
761
762         f = create_pmu_event_filter(events, nevents, KVM_PMU_EVENT_ALLOW, flags);
763         r = __vm_ioctl(vcpu->vm, KVM_SET_PMU_EVENT_FILTER, f);
764         free(f);
765
766         return r;
767 }
768
769 static void test_filter_ioctl(struct kvm_vcpu *vcpu)
770 {
771         uint64_t e = ~0ul;
772         int r;
773
774         /*
775          * Unfortunately having invalid bits set in event data is expected to
776          * pass when flags == 0 (bits other than eventsel+umask).
777          */
778         r = run_filter_test(vcpu, &e, 1, 0);
779         TEST_ASSERT(r == 0, "Valid PMU Event Filter is failing");
780
781         r = run_filter_test(vcpu, &e, 1, KVM_PMU_EVENT_FLAG_MASKED_EVENTS);
782         TEST_ASSERT(r != 0, "Invalid PMU Event Filter is expected to fail");
783
784         e = KVM_PMU_ENCODE_MASKED_ENTRY(0xff, 0xff, 0xff, 0xf);
785         r = run_filter_test(vcpu, &e, 1, KVM_PMU_EVENT_FLAG_MASKED_EVENTS);
786         TEST_ASSERT(r == 0, "Valid PMU Event Filter is failing");
787 }
788
789 int main(int argc, char *argv[])
790 {
791         void (*guest_code)(void);
792         struct kvm_vcpu *vcpu, *vcpu2 = NULL;
793         struct kvm_vm *vm;
794
795         TEST_REQUIRE(get_kvm_param_bool("enable_pmu"));
796         TEST_REQUIRE(kvm_has_cap(KVM_CAP_PMU_EVENT_FILTER));
797         TEST_REQUIRE(kvm_has_cap(KVM_CAP_PMU_EVENT_MASKED_EVENTS));
798
799         TEST_REQUIRE(use_intel_pmu() || use_amd_pmu());
800         guest_code = use_intel_pmu() ? intel_guest_code : amd_guest_code;
801
802         vm = vm_create_with_one_vcpu(&vcpu, guest_code);
803
804         vm_init_descriptor_tables(vm);
805         vcpu_init_descriptor_tables(vcpu);
806
807         TEST_REQUIRE(sanity_check_pmu(vcpu));
808
809         if (use_amd_pmu())
810                 test_amd_deny_list(vcpu);
811
812         test_without_filter(vcpu);
813         test_member_deny_list(vcpu);
814         test_member_allow_list(vcpu);
815         test_not_member_deny_list(vcpu);
816         test_not_member_allow_list(vcpu);
817
818         if (use_intel_pmu() &&
819             supports_event_mem_inst_retired() &&
820             kvm_cpu_property(X86_PROPERTY_PMU_NR_GP_COUNTERS) >= 3)
821                 vcpu2 = vm_vcpu_add(vm, 2, intel_masked_events_guest_code);
822         else if (use_amd_pmu())
823                 vcpu2 = vm_vcpu_add(vm, 2, amd_masked_events_guest_code);
824
825         if (vcpu2)
826                 test_masked_events(vcpu2);
827         test_filter_ioctl(vcpu);
828
829         kvm_vm_free(vm);
830
831         test_pmu_config_disable(guest_code);
832
833         return 0;
834 }