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(0);
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(0);
96 
97 	v ^= bits_to_flip;
98 	wrmsr(msr, v);
99 	if (rdmsr(msr) != v)
100 		GUEST_SYNC(0);
101 }
102 
103 static void intel_guest_code(void)
104 {
105 	check_msr(MSR_CORE_PERF_GLOBAL_CTRL, 1);
106 	check_msr(MSR_P6_EVNTSEL0, 0xffff);
107 	check_msr(MSR_IA32_PMC0, 0xffff);
108 	GUEST_SYNC(1);
109 
110 	for (;;) {
111 		uint64_t br0, br1;
112 
113 		wrmsr(MSR_CORE_PERF_GLOBAL_CTRL, 0);
114 		wrmsr(MSR_P6_EVNTSEL0, ARCH_PERFMON_EVENTSEL_ENABLE |
115 		      ARCH_PERFMON_EVENTSEL_OS | INTEL_BR_RETIRED);
116 		wrmsr(MSR_CORE_PERF_GLOBAL_CTRL, 1);
117 		br0 = rdmsr(MSR_IA32_PMC0);
118 		__asm__ __volatile__("loop ." : "+c"((int){NUM_BRANCHES}));
119 		br1 = rdmsr(MSR_IA32_PMC0);
120 		GUEST_SYNC(br1 - br0);
121 	}
122 }
123 
124 /*
125  * To avoid needing a check for CPUID.80000001:ECX.PerfCtrExtCore[bit 23],
126  * this code uses the always-available, legacy K7 PMU MSRs, which alias to
127  * the first four of the six extended core PMU MSRs.
128  */
129 static void amd_guest_code(void)
130 {
131 	check_msr(MSR_K7_EVNTSEL0, 0xffff);
132 	check_msr(MSR_K7_PERFCTR0, 0xffff);
133 	GUEST_SYNC(1);
134 
135 	for (;;) {
136 		uint64_t br0, br1;
137 
138 		wrmsr(MSR_K7_EVNTSEL0, 0);
139 		wrmsr(MSR_K7_EVNTSEL0, ARCH_PERFMON_EVENTSEL_ENABLE |
140 		      ARCH_PERFMON_EVENTSEL_OS | AMD_ZEN_BR_RETIRED);
141 		br0 = rdmsr(MSR_K7_PERFCTR0);
142 		__asm__ __volatile__("loop ." : "+c"((int){NUM_BRANCHES}));
143 		br1 = rdmsr(MSR_K7_PERFCTR0);
144 		GUEST_SYNC(br1 - br0);
145 	}
146 }
147 
148 /*
149  * Run the VM to the next GUEST_SYNC(value), and return the value passed
150  * to the sync. Any other exit from the guest is fatal.
151  */
152 static uint64_t run_vcpu_to_sync(struct kvm_vcpu *vcpu)
153 {
154 	struct kvm_run *run = vcpu->run;
155 	struct ucall uc;
156 
157 	vcpu_run(vcpu);
158 	TEST_ASSERT(run->exit_reason == KVM_EXIT_IO,
159 		    "Exit_reason other than KVM_EXIT_IO: %u (%s)\n",
160 		    run->exit_reason,
161 		    exit_reason_str(run->exit_reason));
162 	get_ucall(vcpu, &uc);
163 	TEST_ASSERT(uc.cmd == UCALL_SYNC,
164 		    "Received ucall other than UCALL_SYNC: %lu", uc.cmd);
165 	return uc.args[1];
166 }
167 
168 /*
169  * In a nested environment or if the vPMU is disabled, the guest PMU
170  * might not work as architected (accessing the PMU MSRs may raise
171  * #GP, or writes could simply be discarded). In those situations,
172  * there is no point in running these tests. The guest code will perform
173  * a sanity check and then GUEST_SYNC(success). In the case of failure,
174  * the behavior of the guest on resumption is undefined.
175  */
176 static bool sanity_check_pmu(struct kvm_vcpu *vcpu)
177 {
178 	bool success;
179 
180 	vm_install_exception_handler(vcpu->vm, GP_VECTOR, guest_gp_handler);
181 	success = run_vcpu_to_sync(vcpu);
182 	vm_install_exception_handler(vcpu->vm, GP_VECTOR, NULL);
183 
184 	return success;
185 }
186 
187 static struct kvm_pmu_event_filter *alloc_pmu_event_filter(uint32_t nevents)
188 {
189 	struct kvm_pmu_event_filter *f;
190 	int size = sizeof(*f) + nevents * sizeof(f->events[0]);
191 
192 	f = malloc(size);
193 	TEST_ASSERT(f, "Out of memory");
194 	memset(f, 0, size);
195 	f->nevents = nevents;
196 	return f;
197 }
198 
199 
200 static struct kvm_pmu_event_filter *
201 create_pmu_event_filter(const uint64_t event_list[],
202 			int nevents, uint32_t action)
203 {
204 	struct kvm_pmu_event_filter *f;
205 	int i;
206 
207 	f = alloc_pmu_event_filter(nevents);
208 	f->action = action;
209 	for (i = 0; i < nevents; i++)
210 		f->events[i] = event_list[i];
211 
212 	return f;
213 }
214 
215 static struct kvm_pmu_event_filter *event_filter(uint32_t action)
216 {
217 	return create_pmu_event_filter(event_list,
218 				       ARRAY_SIZE(event_list),
219 				       action);
220 }
221 
222 /*
223  * Remove the first occurrence of 'event' (if any) from the filter's
224  * event list.
225  */
226 static struct kvm_pmu_event_filter *remove_event(struct kvm_pmu_event_filter *f,
227 						 uint64_t event)
228 {
229 	bool found = false;
230 	int i;
231 
232 	for (i = 0; i < f->nevents; i++) {
233 		if (found)
234 			f->events[i - 1] = f->events[i];
235 		else
236 			found = f->events[i] == event;
237 	}
238 	if (found)
239 		f->nevents--;
240 	return f;
241 }
242 
243 static void test_without_filter(struct kvm_vcpu *vcpu)
244 {
245 	uint64_t count = run_vcpu_to_sync(vcpu);
246 
247 	if (count != NUM_BRANCHES)
248 		pr_info("%s: Branch instructions retired = %lu (expected %u)\n",
249 			__func__, count, NUM_BRANCHES);
250 	TEST_ASSERT(count, "Allowed PMU event is not counting");
251 }
252 
253 static uint64_t test_with_filter(struct kvm_vcpu *vcpu,
254 				 struct kvm_pmu_event_filter *f)
255 {
256 	vm_ioctl(vcpu->vm, KVM_SET_PMU_EVENT_FILTER, f);
257 	return run_vcpu_to_sync(vcpu);
258 }
259 
260 static void test_amd_deny_list(struct kvm_vcpu *vcpu)
261 {
262 	uint64_t event = EVENT(0x1C2, 0);
263 	struct kvm_pmu_event_filter *f;
264 	uint64_t count;
265 
266 	f = create_pmu_event_filter(&event, 1, KVM_PMU_EVENT_DENY);
267 	count = test_with_filter(vcpu, f);
268 
269 	free(f);
270 	if (count != NUM_BRANCHES)
271 		pr_info("%s: Branch instructions retired = %lu (expected %u)\n",
272 			__func__, count, NUM_BRANCHES);
273 	TEST_ASSERT(count, "Allowed PMU event is not counting");
274 }
275 
276 static void test_member_deny_list(struct kvm_vcpu *vcpu)
277 {
278 	struct kvm_pmu_event_filter *f = event_filter(KVM_PMU_EVENT_DENY);
279 	uint64_t count = test_with_filter(vcpu, f);
280 
281 	free(f);
282 	if (count)
283 		pr_info("%s: Branch instructions retired = %lu (expected 0)\n",
284 			__func__, count);
285 	TEST_ASSERT(!count, "Disallowed PMU Event is counting");
286 }
287 
288 static void test_member_allow_list(struct kvm_vcpu *vcpu)
289 {
290 	struct kvm_pmu_event_filter *f = event_filter(KVM_PMU_EVENT_ALLOW);
291 	uint64_t count = test_with_filter(vcpu, f);
292 
293 	free(f);
294 	if (count != NUM_BRANCHES)
295 		pr_info("%s: Branch instructions retired = %lu (expected %u)\n",
296 			__func__, count, NUM_BRANCHES);
297 	TEST_ASSERT(count, "Allowed PMU event is not counting");
298 }
299 
300 static void test_not_member_deny_list(struct kvm_vcpu *vcpu)
301 {
302 	struct kvm_pmu_event_filter *f = event_filter(KVM_PMU_EVENT_DENY);
303 	uint64_t count;
304 
305 	remove_event(f, INTEL_BR_RETIRED);
306 	remove_event(f, AMD_ZEN_BR_RETIRED);
307 	count = test_with_filter(vcpu, f);
308 	free(f);
309 	if (count != NUM_BRANCHES)
310 		pr_info("%s: Branch instructions retired = %lu (expected %u)\n",
311 			__func__, count, NUM_BRANCHES);
312 	TEST_ASSERT(count, "Allowed PMU event is not counting");
313 }
314 
315 static void test_not_member_allow_list(struct kvm_vcpu *vcpu)
316 {
317 	struct kvm_pmu_event_filter *f = event_filter(KVM_PMU_EVENT_ALLOW);
318 	uint64_t count;
319 
320 	remove_event(f, INTEL_BR_RETIRED);
321 	remove_event(f, AMD_ZEN_BR_RETIRED);
322 	count = test_with_filter(vcpu, f);
323 	free(f);
324 	if (count)
325 		pr_info("%s: Branch instructions retired = %lu (expected 0)\n",
326 			__func__, count);
327 	TEST_ASSERT(!count, "Disallowed PMU Event is counting");
328 }
329 
330 /*
331  * Verify that setting KVM_PMU_CAP_DISABLE prevents the use of the PMU.
332  *
333  * Note that KVM_CAP_PMU_CAPABILITY must be invoked prior to creating VCPUs.
334  */
335 static void test_pmu_config_disable(void (*guest_code)(void))
336 {
337 	struct kvm_vcpu *vcpu;
338 	int r;
339 	struct kvm_vm *vm;
340 
341 	r = kvm_check_cap(KVM_CAP_PMU_CAPABILITY);
342 	if (!(r & KVM_PMU_CAP_DISABLE))
343 		return;
344 
345 	vm = vm_create(1);
346 
347 	vm_enable_cap(vm, KVM_CAP_PMU_CAPABILITY, KVM_PMU_CAP_DISABLE);
348 
349 	vcpu = vm_vcpu_add(vm, 0, guest_code);
350 	vm_init_descriptor_tables(vm);
351 	vcpu_init_descriptor_tables(vcpu);
352 
353 	TEST_ASSERT(!sanity_check_pmu(vcpu),
354 		    "Guest should not be able to use disabled PMU.");
355 
356 	kvm_vm_free(vm);
357 }
358 
359 /*
360  * On Intel, check for a non-zero PMU version, at least one general-purpose
361  * counter per logical processor, and support for counting the number of branch
362  * instructions retired.
363  */
364 static bool use_intel_pmu(void)
365 {
366 	return is_intel_cpu() &&
367 	       kvm_cpu_property(X86_PROPERTY_PMU_VERSION) &&
368 	       kvm_cpu_property(X86_PROPERTY_PMU_NR_GP_COUNTERS) &&
369 	       kvm_pmu_has(X86_PMU_FEATURE_BRANCH_INSNS_RETIRED);
370 }
371 
372 static bool is_zen1(uint32_t family, uint32_t model)
373 {
374 	return family == 0x17 && model <= 0x0f;
375 }
376 
377 static bool is_zen2(uint32_t family, uint32_t model)
378 {
379 	return family == 0x17 && model >= 0x30 && model <= 0x3f;
380 }
381 
382 static bool is_zen3(uint32_t family, uint32_t model)
383 {
384 	return family == 0x19 && model <= 0x0f;
385 }
386 
387 /*
388  * Determining AMD support for a PMU event requires consulting the AMD
389  * PPR for the CPU or reference material derived therefrom. The AMD
390  * test code herein has been verified to work on Zen1, Zen2, and Zen3.
391  *
392  * Feel free to add more AMD CPUs that are documented to support event
393  * select 0xc2 umask 0 as "retired branch instructions."
394  */
395 static bool use_amd_pmu(void)
396 {
397 	uint32_t family = kvm_cpu_family();
398 	uint32_t model = kvm_cpu_model();
399 
400 	return is_amd_cpu() &&
401 		(is_zen1(family, model) ||
402 		 is_zen2(family, model) ||
403 		 is_zen3(family, model));
404 }
405 
406 int main(int argc, char *argv[])
407 {
408 	void (*guest_code)(void);
409 	struct kvm_vcpu *vcpu;
410 	struct kvm_vm *vm;
411 
412 	TEST_REQUIRE(kvm_has_cap(KVM_CAP_PMU_EVENT_FILTER));
413 
414 	TEST_REQUIRE(use_intel_pmu() || use_amd_pmu());
415 	guest_code = use_intel_pmu() ? intel_guest_code : amd_guest_code;
416 
417 	vm = vm_create_with_one_vcpu(&vcpu, guest_code);
418 
419 	vm_init_descriptor_tables(vm);
420 	vcpu_init_descriptor_tables(vcpu);
421 
422 	TEST_REQUIRE(sanity_check_pmu(vcpu));
423 
424 	if (use_amd_pmu())
425 		test_amd_deny_list(vcpu);
426 
427 	test_without_filter(vcpu);
428 	test_member_deny_list(vcpu);
429 	test_member_allow_list(vcpu);
430 	test_not_member_deny_list(vcpu);
431 	test_not_member_allow_list(vcpu);
432 
433 	kvm_vm_free(vm);
434 
435 	test_pmu_config_disable(guest_code);
436 
437 	return 0;
438 }
439