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 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 */ 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 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 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 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 */ 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 */ 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 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 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 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 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 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 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 */ 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 */ 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 */ 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