1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3 * Copyright 2022, Athira Rajeev, IBM Corp.
4 * Copyright 2022, Madhavan Srinivasan, IBM Corp.
5 * Copyright 2022, Kajol Jain, IBM Corp.
6 */
7
8 #include <unistd.h>
9 #include <sys/syscall.h>
10 #include <string.h>
11 #include <stdio.h>
12 #include <sys/ioctl.h>
13 #include <sys/mman.h>
14 #include <stdlib.h>
15 #include <ctype.h>
16
17 #include "misc.h"
18
19 #define PAGE_SIZE sysconf(_SC_PAGESIZE)
20
21 /* Storage for platform version */
22 int pvr;
23 u64 platform_extended_mask;
24
25 /* Mask and Shift for Event code fields */
26 int ev_mask_pmcxsel, ev_shift_pmcxsel; //pmcxsel field
27 int ev_mask_marked, ev_shift_marked; //marked filed
28 int ev_mask_comb, ev_shift_comb; //combine field
29 int ev_mask_unit, ev_shift_unit; //unit field
30 int ev_mask_pmc, ev_shift_pmc; //pmc field
31 int ev_mask_cache, ev_shift_cache; //Cache sel field
32 int ev_mask_sample, ev_shift_sample; //Random sampling field
33 int ev_mask_thd_sel, ev_shift_thd_sel; //thresh_sel field
34 int ev_mask_thd_start, ev_shift_thd_start; //thresh_start field
35 int ev_mask_thd_stop, ev_shift_thd_stop; //thresh_stop field
36 int ev_mask_thd_cmp, ev_shift_thd_cmp; //thresh cmp field
37 int ev_mask_sm, ev_shift_sm; //SDAR mode field
38 int ev_mask_rsq, ev_shift_rsq; //radix scope qual field
39 int ev_mask_l2l3, ev_shift_l2l3; //l2l3 sel field
40 int ev_mask_mmcr3_src, ev_shift_mmcr3_src; //mmcr3 field
41
init_ev_encodes(void)42 static void init_ev_encodes(void)
43 {
44 ev_mask_pmcxsel = 0xff;
45 ev_shift_pmcxsel = 0;
46 ev_mask_marked = 1;
47 ev_shift_marked = 8;
48 ev_mask_unit = 0xf;
49 ev_shift_unit = 12;
50 ev_mask_pmc = 0xf;
51 ev_shift_pmc = 16;
52 ev_mask_sample = 0x1f;
53 ev_shift_sample = 24;
54 ev_mask_thd_sel = 0x7;
55 ev_shift_thd_sel = 29;
56 ev_mask_thd_start = 0xf;
57 ev_shift_thd_start = 36;
58 ev_mask_thd_stop = 0xf;
59 ev_shift_thd_stop = 32;
60
61 switch (pvr) {
62 case POWER11:
63 case POWER10:
64 ev_mask_thd_cmp = 0x3ffff;
65 ev_shift_thd_cmp = 0;
66 ev_mask_rsq = 1;
67 ev_shift_rsq = 9;
68 ev_mask_comb = 3;
69 ev_shift_comb = 10;
70 ev_mask_cache = 3;
71 ev_shift_cache = 20;
72 ev_mask_sm = 0x3;
73 ev_shift_sm = 22;
74 ev_mask_l2l3 = 0x1f;
75 ev_shift_l2l3 = 40;
76 ev_mask_mmcr3_src = 0x7fff;
77 ev_shift_mmcr3_src = 45;
78 break;
79 case POWER9:
80 ev_mask_comb = 3;
81 ev_shift_comb = 10;
82 ev_mask_cache = 0xf;
83 ev_shift_cache = 20;
84 ev_mask_thd_cmp = 0x3ff;
85 ev_shift_thd_cmp = 40;
86 ev_mask_sm = 0x3;
87 ev_shift_sm = 50;
88 break;
89 default:
90 FAIL_IF_EXIT(1);
91 }
92 }
93
94 /* Return the extended regs mask value */
perf_get_platform_reg_mask(void)95 u64 perf_get_platform_reg_mask(void)
96 {
97 if (have_hwcap2(PPC_FEATURE2_ARCH_3_1))
98 return PERF_POWER10_MASK;
99 if (have_hwcap2(PPC_FEATURE2_ARCH_3_00))
100 return PERF_POWER9_MASK;
101
102 return -1;
103 }
104
check_extended_regs_support(void)105 int check_extended_regs_support(void)
106 {
107 int fd;
108 struct event event;
109
110 event_init(&event, 0x1001e);
111
112 event.attr.type = 4;
113 event.attr.sample_period = 1;
114 event.attr.disabled = 1;
115 event.attr.sample_type = PERF_SAMPLE_REGS_INTR;
116 event.attr.sample_regs_intr = platform_extended_mask;
117
118 fd = event_open(&event);
119 if (fd != -1)
120 return 0;
121
122 return -1;
123 }
124
platform_check_for_tests(void)125 int platform_check_for_tests(void)
126 {
127 pvr = PVR_VER(mfspr(SPRN_PVR));
128
129 /*
130 * Check for supported platforms
131 * for sampling test
132 */
133 switch (pvr) {
134 case POWER11:
135 case POWER10:
136 case POWER9:
137 break;
138 default:
139 goto out;
140 }
141
142 /*
143 * Check PMU driver registered by looking for
144 * PPC_FEATURE2_EBB bit in AT_HWCAP2
145 */
146 if (!have_hwcap2(PPC_FEATURE2_EBB) || !have_hwcap2(PPC_FEATURE2_ARCH_3_00))
147 goto out;
148
149 return 0;
150
151 out:
152 printf("%s: Tests unsupported for this platform\n", __func__);
153 return -1;
154 }
155
check_pvr_for_sampling_tests(void)156 int check_pvr_for_sampling_tests(void)
157 {
158 SKIP_IF(platform_check_for_tests());
159
160 platform_extended_mask = perf_get_platform_reg_mask();
161 /* check if platform supports extended regs */
162 if (check_extended_regs_support())
163 goto out;
164
165 init_ev_encodes();
166 return 0;
167
168 out:
169 printf("%s: Sampling tests un-supported\n", __func__);
170 return -1;
171 }
172
173 /*
174 * Allocate mmap buffer of "mmap_pages" number of
175 * pages.
176 */
event_sample_buf_mmap(int fd,int mmap_pages)177 void *event_sample_buf_mmap(int fd, int mmap_pages)
178 {
179 size_t page_size = sysconf(_SC_PAGESIZE);
180 size_t mmap_size;
181 void *buff;
182
183 if (mmap_pages <= 0)
184 return NULL;
185
186 if (fd <= 0)
187 return NULL;
188
189 mmap_size = page_size * (1 + mmap_pages);
190 buff = mmap(NULL, mmap_size,
191 PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
192
193 if (buff == MAP_FAILED) {
194 perror("mmap() failed.");
195 return NULL;
196 }
197 return buff;
198 }
199
200 /*
201 * Post process the mmap buffer.
202 * - If sample_count != NULL then return count of total
203 * number of samples present in the mmap buffer.
204 * - If sample_count == NULL then return the address
205 * of first sample from the mmap buffer
206 */
__event_read_samples(void * sample_buff,size_t * size,u64 * sample_count)207 void *__event_read_samples(void *sample_buff, size_t *size, u64 *sample_count)
208 {
209 size_t page_size = sysconf(_SC_PAGESIZE);
210 struct perf_event_header *header = sample_buff + page_size;
211 struct perf_event_mmap_page *metadata_page = sample_buff;
212 unsigned long data_head, data_tail;
213
214 /*
215 * PERF_RECORD_SAMPLE:
216 * struct {
217 * struct perf_event_header hdr;
218 * u64 data[];
219 * };
220 */
221
222 data_head = metadata_page->data_head;
223 /* sync memory before reading sample */
224 mb();
225 data_tail = metadata_page->data_tail;
226
227 /* Check for sample_count */
228 if (sample_count)
229 *sample_count = 0;
230
231 while (1) {
232 /*
233 * Reads the mmap data buffer by moving
234 * the data_tail to know the last read data.
235 * data_head points to head in data buffer.
236 * refer "struct perf_event_mmap_page" in
237 * "include/uapi/linux/perf_event.h".
238 */
239 if (data_head - data_tail < sizeof(header))
240 return NULL;
241
242 data_tail += sizeof(header);
243 if (header->type == PERF_RECORD_SAMPLE) {
244 *size = (header->size - sizeof(header));
245 if (!sample_count)
246 return sample_buff + page_size + data_tail;
247 data_tail += *size;
248 *sample_count += 1;
249 } else {
250 *size = (header->size - sizeof(header));
251 if ((metadata_page->data_tail + *size) > metadata_page->data_head)
252 data_tail = metadata_page->data_head;
253 else
254 data_tail += *size;
255 }
256 header = (struct perf_event_header *)((void *)header + header->size);
257 }
258 return NULL;
259 }
260
collect_samples(void * sample_buff)261 int collect_samples(void *sample_buff)
262 {
263 u64 sample_count;
264 size_t size = 0;
265
266 __event_read_samples(sample_buff, &size, &sample_count);
267 return sample_count;
268 }
269
perf_read_first_sample(void * sample_buff,size_t * size)270 static void *perf_read_first_sample(void *sample_buff, size_t *size)
271 {
272 return __event_read_samples(sample_buff, size, NULL);
273 }
274
get_intr_regs(struct event * event,void * sample_buff)275 u64 *get_intr_regs(struct event *event, void *sample_buff)
276 {
277 u64 type = event->attr.sample_type;
278 u64 *intr_regs;
279 size_t size = 0;
280
281 if ((type ^ (PERF_SAMPLE_REGS_INTR | PERF_SAMPLE_BRANCH_STACK)) &&
282 (type ^ PERF_SAMPLE_REGS_INTR))
283 return NULL;
284
285 intr_regs = (u64 *)perf_read_first_sample(sample_buff, &size);
286 if (!intr_regs)
287 return NULL;
288
289 if (type & PERF_SAMPLE_BRANCH_STACK) {
290 /*
291 * PERF_RECORD_SAMPLE and PERF_SAMPLE_BRANCH_STACK:
292 * struct {
293 * struct perf_event_header hdr;
294 * u64 number_of_branches;
295 * struct perf_branch_entry[number_of_branches];
296 * u64 data[];
297 * };
298 * struct perf_branch_entry {
299 * u64 from;
300 * u64 to;
301 * u64 misc;
302 * };
303 */
304 intr_regs += ((*intr_regs) * 3) + 1;
305 }
306
307 /*
308 * First entry in the sample buffer used to specify
309 * PERF_SAMPLE_REGS_ABI_64, skip perf regs abi to access
310 * interrupt registers.
311 */
312 ++intr_regs;
313
314 return intr_regs;
315 }
316
__perf_reg_mask(const char * register_name)317 static const int __perf_reg_mask(const char *register_name)
318 {
319 if (!strcmp(register_name, "R0"))
320 return 0;
321 else if (!strcmp(register_name, "R1"))
322 return 1;
323 else if (!strcmp(register_name, "R2"))
324 return 2;
325 else if (!strcmp(register_name, "R3"))
326 return 3;
327 else if (!strcmp(register_name, "R4"))
328 return 4;
329 else if (!strcmp(register_name, "R5"))
330 return 5;
331 else if (!strcmp(register_name, "R6"))
332 return 6;
333 else if (!strcmp(register_name, "R7"))
334 return 7;
335 else if (!strcmp(register_name, "R8"))
336 return 8;
337 else if (!strcmp(register_name, "R9"))
338 return 9;
339 else if (!strcmp(register_name, "R10"))
340 return 10;
341 else if (!strcmp(register_name, "R11"))
342 return 11;
343 else if (!strcmp(register_name, "R12"))
344 return 12;
345 else if (!strcmp(register_name, "R13"))
346 return 13;
347 else if (!strcmp(register_name, "R14"))
348 return 14;
349 else if (!strcmp(register_name, "R15"))
350 return 15;
351 else if (!strcmp(register_name, "R16"))
352 return 16;
353 else if (!strcmp(register_name, "R17"))
354 return 17;
355 else if (!strcmp(register_name, "R18"))
356 return 18;
357 else if (!strcmp(register_name, "R19"))
358 return 19;
359 else if (!strcmp(register_name, "R20"))
360 return 20;
361 else if (!strcmp(register_name, "R21"))
362 return 21;
363 else if (!strcmp(register_name, "R22"))
364 return 22;
365 else if (!strcmp(register_name, "R23"))
366 return 23;
367 else if (!strcmp(register_name, "R24"))
368 return 24;
369 else if (!strcmp(register_name, "R25"))
370 return 25;
371 else if (!strcmp(register_name, "R26"))
372 return 26;
373 else if (!strcmp(register_name, "R27"))
374 return 27;
375 else if (!strcmp(register_name, "R28"))
376 return 28;
377 else if (!strcmp(register_name, "R29"))
378 return 29;
379 else if (!strcmp(register_name, "R30"))
380 return 30;
381 else if (!strcmp(register_name, "R31"))
382 return 31;
383 else if (!strcmp(register_name, "NIP"))
384 return 32;
385 else if (!strcmp(register_name, "MSR"))
386 return 33;
387 else if (!strcmp(register_name, "ORIG_R3"))
388 return 34;
389 else if (!strcmp(register_name, "CTR"))
390 return 35;
391 else if (!strcmp(register_name, "LINK"))
392 return 36;
393 else if (!strcmp(register_name, "XER"))
394 return 37;
395 else if (!strcmp(register_name, "CCR"))
396 return 38;
397 else if (!strcmp(register_name, "SOFTE"))
398 return 39;
399 else if (!strcmp(register_name, "TRAP"))
400 return 40;
401 else if (!strcmp(register_name, "DAR"))
402 return 41;
403 else if (!strcmp(register_name, "DSISR"))
404 return 42;
405 else if (!strcmp(register_name, "SIER"))
406 return 43;
407 else if (!strcmp(register_name, "MMCRA"))
408 return 44;
409 else if (!strcmp(register_name, "MMCR0"))
410 return 45;
411 else if (!strcmp(register_name, "MMCR1"))
412 return 46;
413 else if (!strcmp(register_name, "MMCR2"))
414 return 47;
415 else if (!strcmp(register_name, "MMCR3"))
416 return 48;
417 else if (!strcmp(register_name, "SIER2"))
418 return 49;
419 else if (!strcmp(register_name, "SIER3"))
420 return 50;
421 else if (!strcmp(register_name, "PMC1"))
422 return 51;
423 else if (!strcmp(register_name, "PMC2"))
424 return 52;
425 else if (!strcmp(register_name, "PMC3"))
426 return 53;
427 else if (!strcmp(register_name, "PMC4"))
428 return 54;
429 else if (!strcmp(register_name, "PMC5"))
430 return 55;
431 else if (!strcmp(register_name, "PMC6"))
432 return 56;
433 else if (!strcmp(register_name, "SDAR"))
434 return 57;
435 else if (!strcmp(register_name, "SIAR"))
436 return 58;
437 else
438 return -1;
439 }
440
get_reg_value(u64 * intr_regs,char * register_name)441 u64 get_reg_value(u64 *intr_regs, char *register_name)
442 {
443 int register_bit_position;
444
445 register_bit_position = __perf_reg_mask(register_name);
446
447 if (register_bit_position < 0 || (!((platform_extended_mask >>
448 (register_bit_position - 1)) & 1)))
449 return -1;
450
451 return *(intr_regs + register_bit_position);
452 }
453
get_thresh_cmp_val(struct event event)454 int get_thresh_cmp_val(struct event event)
455 {
456 int exp = 0;
457 u64 result = 0;
458 u64 value;
459
460 if (!have_hwcap2(PPC_FEATURE2_ARCH_3_1))
461 return EV_CODE_EXTRACT(event.attr.config, thd_cmp);
462
463 value = EV_CODE_EXTRACT(event.attr.config1, thd_cmp);
464
465 if (!value)
466 return value;
467
468 /*
469 * Incase of P10, thresh_cmp value is not part of raw event code
470 * and provided via attr.config1 parameter. To program threshold in MMCRA,
471 * take a 18 bit number N and shift right 2 places and increment
472 * the exponent E by 1 until the upper 10 bits of N are zero.
473 * Write E to the threshold exponent and write the lower 8 bits of N
474 * to the threshold mantissa.
475 * The max threshold that can be written is 261120.
476 */
477 if (value > 261120)
478 value = 261120;
479 while ((64 - __builtin_clzl(value)) > 8) {
480 exp++;
481 value >>= 2;
482 }
483
484 /*
485 * Note that it is invalid to write a mantissa with the
486 * upper 2 bits of mantissa being zero, unless the
487 * exponent is also zero.
488 */
489 if (!(value & 0xC0) && exp)
490 result = -1;
491 else
492 result = (exp << 8) | value;
493 return result;
494 }
495
496 /*
497 * Utility function to check for generic compat PMU
498 * by comparing base_platform value from auxv and real
499 * PVR value.
500 * auxv_base_platform() func gives information of "base platform"
501 * corresponding to PVR value. Incase, if the distro doesn't
502 * support platform PVR (missing cputable support), base platform
503 * in auxv will have a default value other than the real PVR's.
504 * In this case, ISAv3 PMU (generic compat PMU) will be registered
505 * in the system. auxv_generic_compat_pmu() makes use of the base
506 * platform value from auxv to do this check.
507 */
auxv_generic_compat_pmu(void)508 static bool auxv_generic_compat_pmu(void)
509 {
510 int base_pvr = 0;
511
512 if (!strcmp(auxv_base_platform(), "power9"))
513 base_pvr = POWER9;
514 else if (!strcmp(auxv_base_platform(), "power10"))
515 base_pvr = POWER10;
516 else if (!strcmp(auxv_base_platform(), "power11"))
517 base_pvr = POWER11;
518
519 return (!base_pvr);
520 }
521
522 /*
523 * Check for generic compat PMU.
524 * First check for presence of pmu_name from
525 * "/sys/bus/event_source/devices/cpu/caps".
526 * If doesn't exist, fallback to using value
527 * auxv.
528 */
check_for_generic_compat_pmu(void)529 bool check_for_generic_compat_pmu(void)
530 {
531 char pmu_name[256];
532
533 memset(pmu_name, 0, sizeof(pmu_name));
534 if (read_sysfs_file("bus/event_source/devices/cpu/caps/pmu_name",
535 pmu_name, sizeof(pmu_name)) < 0)
536 return auxv_generic_compat_pmu();
537
538 if (!strcmp(pmu_name, "ISAv3"))
539 return true;
540 else
541 return false;
542 }
543
544 /*
545 * Check if system is booted in compat mode.
546 */
check_for_compat_mode(void)547 bool check_for_compat_mode(void)
548 {
549 char *platform = auxv_platform();
550 char *base_platform = auxv_base_platform();
551
552 return strcmp(platform, base_platform);
553 }
554