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