18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci#include <stdbool.h> 38c2ecf20Sopenharmony_ci#include <inttypes.h> 48c2ecf20Sopenharmony_ci#include <stdlib.h> 58c2ecf20Sopenharmony_ci#include <string.h> 68c2ecf20Sopenharmony_ci#include <linux/bitops.h> 78c2ecf20Sopenharmony_ci#include <linux/kernel.h> 88c2ecf20Sopenharmony_ci#include <linux/types.h> 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_ci#include "map_symbol.h" 118c2ecf20Sopenharmony_ci#include "branch.h" 128c2ecf20Sopenharmony_ci#include "event.h" 138c2ecf20Sopenharmony_ci#include "evsel.h" 148c2ecf20Sopenharmony_ci#include "debug.h" 158c2ecf20Sopenharmony_ci#include "util/synthetic-events.h" 168c2ecf20Sopenharmony_ci 178c2ecf20Sopenharmony_ci#include "tests.h" 188c2ecf20Sopenharmony_ci 198c2ecf20Sopenharmony_ci#define COMP(m) do { \ 208c2ecf20Sopenharmony_ci if (s1->m != s2->m) { \ 218c2ecf20Sopenharmony_ci pr_debug("Samples differ at '"#m"'\n"); \ 228c2ecf20Sopenharmony_ci return false; \ 238c2ecf20Sopenharmony_ci } \ 248c2ecf20Sopenharmony_ci} while (0) 258c2ecf20Sopenharmony_ci 268c2ecf20Sopenharmony_ci#define MCOMP(m) do { \ 278c2ecf20Sopenharmony_ci if (memcmp(&s1->m, &s2->m, sizeof(s1->m))) { \ 288c2ecf20Sopenharmony_ci pr_debug("Samples differ at '"#m"'\n"); \ 298c2ecf20Sopenharmony_ci return false; \ 308c2ecf20Sopenharmony_ci } \ 318c2ecf20Sopenharmony_ci} while (0) 328c2ecf20Sopenharmony_ci 338c2ecf20Sopenharmony_cistatic bool samples_same(const struct perf_sample *s1, 348c2ecf20Sopenharmony_ci const struct perf_sample *s2, 358c2ecf20Sopenharmony_ci u64 type, u64 read_format) 368c2ecf20Sopenharmony_ci{ 378c2ecf20Sopenharmony_ci size_t i; 388c2ecf20Sopenharmony_ci 398c2ecf20Sopenharmony_ci if (type & PERF_SAMPLE_IDENTIFIER) 408c2ecf20Sopenharmony_ci COMP(id); 418c2ecf20Sopenharmony_ci 428c2ecf20Sopenharmony_ci if (type & PERF_SAMPLE_IP) 438c2ecf20Sopenharmony_ci COMP(ip); 448c2ecf20Sopenharmony_ci 458c2ecf20Sopenharmony_ci if (type & PERF_SAMPLE_TID) { 468c2ecf20Sopenharmony_ci COMP(pid); 478c2ecf20Sopenharmony_ci COMP(tid); 488c2ecf20Sopenharmony_ci } 498c2ecf20Sopenharmony_ci 508c2ecf20Sopenharmony_ci if (type & PERF_SAMPLE_TIME) 518c2ecf20Sopenharmony_ci COMP(time); 528c2ecf20Sopenharmony_ci 538c2ecf20Sopenharmony_ci if (type & PERF_SAMPLE_ADDR) 548c2ecf20Sopenharmony_ci COMP(addr); 558c2ecf20Sopenharmony_ci 568c2ecf20Sopenharmony_ci if (type & PERF_SAMPLE_ID) 578c2ecf20Sopenharmony_ci COMP(id); 588c2ecf20Sopenharmony_ci 598c2ecf20Sopenharmony_ci if (type & PERF_SAMPLE_STREAM_ID) 608c2ecf20Sopenharmony_ci COMP(stream_id); 618c2ecf20Sopenharmony_ci 628c2ecf20Sopenharmony_ci if (type & PERF_SAMPLE_CPU) 638c2ecf20Sopenharmony_ci COMP(cpu); 648c2ecf20Sopenharmony_ci 658c2ecf20Sopenharmony_ci if (type & PERF_SAMPLE_PERIOD) 668c2ecf20Sopenharmony_ci COMP(period); 678c2ecf20Sopenharmony_ci 688c2ecf20Sopenharmony_ci if (type & PERF_SAMPLE_READ) { 698c2ecf20Sopenharmony_ci if (read_format & PERF_FORMAT_GROUP) 708c2ecf20Sopenharmony_ci COMP(read.group.nr); 718c2ecf20Sopenharmony_ci else 728c2ecf20Sopenharmony_ci COMP(read.one.value); 738c2ecf20Sopenharmony_ci if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED) 748c2ecf20Sopenharmony_ci COMP(read.time_enabled); 758c2ecf20Sopenharmony_ci if (read_format & PERF_FORMAT_TOTAL_TIME_RUNNING) 768c2ecf20Sopenharmony_ci COMP(read.time_running); 778c2ecf20Sopenharmony_ci /* PERF_FORMAT_ID is forced for PERF_SAMPLE_READ */ 788c2ecf20Sopenharmony_ci if (read_format & PERF_FORMAT_GROUP) { 798c2ecf20Sopenharmony_ci for (i = 0; i < s1->read.group.nr; i++) 808c2ecf20Sopenharmony_ci MCOMP(read.group.values[i]); 818c2ecf20Sopenharmony_ci } else { 828c2ecf20Sopenharmony_ci COMP(read.one.id); 838c2ecf20Sopenharmony_ci } 848c2ecf20Sopenharmony_ci } 858c2ecf20Sopenharmony_ci 868c2ecf20Sopenharmony_ci if (type & PERF_SAMPLE_CALLCHAIN) { 878c2ecf20Sopenharmony_ci COMP(callchain->nr); 888c2ecf20Sopenharmony_ci for (i = 0; i < s1->callchain->nr; i++) 898c2ecf20Sopenharmony_ci COMP(callchain->ips[i]); 908c2ecf20Sopenharmony_ci } 918c2ecf20Sopenharmony_ci 928c2ecf20Sopenharmony_ci if (type & PERF_SAMPLE_RAW) { 938c2ecf20Sopenharmony_ci COMP(raw_size); 948c2ecf20Sopenharmony_ci if (memcmp(s1->raw_data, s2->raw_data, s1->raw_size)) { 958c2ecf20Sopenharmony_ci pr_debug("Samples differ at 'raw_data'\n"); 968c2ecf20Sopenharmony_ci return false; 978c2ecf20Sopenharmony_ci } 988c2ecf20Sopenharmony_ci } 998c2ecf20Sopenharmony_ci 1008c2ecf20Sopenharmony_ci if (type & PERF_SAMPLE_BRANCH_STACK) { 1018c2ecf20Sopenharmony_ci COMP(branch_stack->nr); 1028c2ecf20Sopenharmony_ci COMP(branch_stack->hw_idx); 1038c2ecf20Sopenharmony_ci for (i = 0; i < s1->branch_stack->nr; i++) 1048c2ecf20Sopenharmony_ci MCOMP(branch_stack->entries[i]); 1058c2ecf20Sopenharmony_ci } 1068c2ecf20Sopenharmony_ci 1078c2ecf20Sopenharmony_ci if (type & PERF_SAMPLE_REGS_USER) { 1088c2ecf20Sopenharmony_ci size_t sz = hweight_long(s1->user_regs.mask) * sizeof(u64); 1098c2ecf20Sopenharmony_ci 1108c2ecf20Sopenharmony_ci COMP(user_regs.mask); 1118c2ecf20Sopenharmony_ci COMP(user_regs.abi); 1128c2ecf20Sopenharmony_ci if (s1->user_regs.abi && 1138c2ecf20Sopenharmony_ci (!s1->user_regs.regs || !s2->user_regs.regs || 1148c2ecf20Sopenharmony_ci memcmp(s1->user_regs.regs, s2->user_regs.regs, sz))) { 1158c2ecf20Sopenharmony_ci pr_debug("Samples differ at 'user_regs'\n"); 1168c2ecf20Sopenharmony_ci return false; 1178c2ecf20Sopenharmony_ci } 1188c2ecf20Sopenharmony_ci } 1198c2ecf20Sopenharmony_ci 1208c2ecf20Sopenharmony_ci if (type & PERF_SAMPLE_STACK_USER) { 1218c2ecf20Sopenharmony_ci COMP(user_stack.size); 1228c2ecf20Sopenharmony_ci if (memcmp(s1->user_stack.data, s2->user_stack.data, 1238c2ecf20Sopenharmony_ci s1->user_stack.size)) { 1248c2ecf20Sopenharmony_ci pr_debug("Samples differ at 'user_stack'\n"); 1258c2ecf20Sopenharmony_ci return false; 1268c2ecf20Sopenharmony_ci } 1278c2ecf20Sopenharmony_ci } 1288c2ecf20Sopenharmony_ci 1298c2ecf20Sopenharmony_ci if (type & PERF_SAMPLE_WEIGHT) 1308c2ecf20Sopenharmony_ci COMP(weight); 1318c2ecf20Sopenharmony_ci 1328c2ecf20Sopenharmony_ci if (type & PERF_SAMPLE_DATA_SRC) 1338c2ecf20Sopenharmony_ci COMP(data_src); 1348c2ecf20Sopenharmony_ci 1358c2ecf20Sopenharmony_ci if (type & PERF_SAMPLE_TRANSACTION) 1368c2ecf20Sopenharmony_ci COMP(transaction); 1378c2ecf20Sopenharmony_ci 1388c2ecf20Sopenharmony_ci if (type & PERF_SAMPLE_REGS_INTR) { 1398c2ecf20Sopenharmony_ci size_t sz = hweight_long(s1->intr_regs.mask) * sizeof(u64); 1408c2ecf20Sopenharmony_ci 1418c2ecf20Sopenharmony_ci COMP(intr_regs.mask); 1428c2ecf20Sopenharmony_ci COMP(intr_regs.abi); 1438c2ecf20Sopenharmony_ci if (s1->intr_regs.abi && 1448c2ecf20Sopenharmony_ci (!s1->intr_regs.regs || !s2->intr_regs.regs || 1458c2ecf20Sopenharmony_ci memcmp(s1->intr_regs.regs, s2->intr_regs.regs, sz))) { 1468c2ecf20Sopenharmony_ci pr_debug("Samples differ at 'intr_regs'\n"); 1478c2ecf20Sopenharmony_ci return false; 1488c2ecf20Sopenharmony_ci } 1498c2ecf20Sopenharmony_ci } 1508c2ecf20Sopenharmony_ci 1518c2ecf20Sopenharmony_ci if (type & PERF_SAMPLE_PHYS_ADDR) 1528c2ecf20Sopenharmony_ci COMP(phys_addr); 1538c2ecf20Sopenharmony_ci 1548c2ecf20Sopenharmony_ci if (type & PERF_SAMPLE_CGROUP) 1558c2ecf20Sopenharmony_ci COMP(cgroup); 1568c2ecf20Sopenharmony_ci 1578c2ecf20Sopenharmony_ci if (type & PERF_SAMPLE_AUX) { 1588c2ecf20Sopenharmony_ci COMP(aux_sample.size); 1598c2ecf20Sopenharmony_ci if (memcmp(s1->aux_sample.data, s2->aux_sample.data, 1608c2ecf20Sopenharmony_ci s1->aux_sample.size)) { 1618c2ecf20Sopenharmony_ci pr_debug("Samples differ at 'aux_sample'\n"); 1628c2ecf20Sopenharmony_ci return false; 1638c2ecf20Sopenharmony_ci } 1648c2ecf20Sopenharmony_ci } 1658c2ecf20Sopenharmony_ci 1668c2ecf20Sopenharmony_ci return true; 1678c2ecf20Sopenharmony_ci} 1688c2ecf20Sopenharmony_ci 1698c2ecf20Sopenharmony_cistatic int do_test(u64 sample_type, u64 sample_regs, u64 read_format) 1708c2ecf20Sopenharmony_ci{ 1718c2ecf20Sopenharmony_ci struct evsel evsel = { 1728c2ecf20Sopenharmony_ci .needs_swap = false, 1738c2ecf20Sopenharmony_ci .core = { 1748c2ecf20Sopenharmony_ci . attr = { 1758c2ecf20Sopenharmony_ci .sample_type = sample_type, 1768c2ecf20Sopenharmony_ci .read_format = read_format, 1778c2ecf20Sopenharmony_ci }, 1788c2ecf20Sopenharmony_ci }, 1798c2ecf20Sopenharmony_ci }; 1808c2ecf20Sopenharmony_ci union perf_event *event; 1818c2ecf20Sopenharmony_ci union { 1828c2ecf20Sopenharmony_ci struct ip_callchain callchain; 1838c2ecf20Sopenharmony_ci u64 data[64]; 1848c2ecf20Sopenharmony_ci } callchain = { 1858c2ecf20Sopenharmony_ci /* 3 ips */ 1868c2ecf20Sopenharmony_ci .data = {3, 201, 202, 203}, 1878c2ecf20Sopenharmony_ci }; 1888c2ecf20Sopenharmony_ci union { 1898c2ecf20Sopenharmony_ci struct branch_stack branch_stack; 1908c2ecf20Sopenharmony_ci u64 data[64]; 1918c2ecf20Sopenharmony_ci } branch_stack = { 1928c2ecf20Sopenharmony_ci /* 1 branch_entry */ 1938c2ecf20Sopenharmony_ci .data = {1, -1ULL, 211, 212, 213}, 1948c2ecf20Sopenharmony_ci }; 1958c2ecf20Sopenharmony_ci u64 regs[64]; 1968c2ecf20Sopenharmony_ci const u32 raw_data[] = {0x12345678, 0x0a0b0c0d, 0x11020304, 0x05060708, 0 }; 1978c2ecf20Sopenharmony_ci const u64 data[] = {0x2211443366558877ULL, 0, 0xaabbccddeeff4321ULL}; 1988c2ecf20Sopenharmony_ci const u64 aux_data[] = {0xa55a, 0, 0xeeddee, 0x0282028202820282}; 1998c2ecf20Sopenharmony_ci struct perf_sample sample = { 2008c2ecf20Sopenharmony_ci .ip = 101, 2018c2ecf20Sopenharmony_ci .pid = 102, 2028c2ecf20Sopenharmony_ci .tid = 103, 2038c2ecf20Sopenharmony_ci .time = 104, 2048c2ecf20Sopenharmony_ci .addr = 105, 2058c2ecf20Sopenharmony_ci .id = 106, 2068c2ecf20Sopenharmony_ci .stream_id = 107, 2078c2ecf20Sopenharmony_ci .period = 108, 2088c2ecf20Sopenharmony_ci .weight = 109, 2098c2ecf20Sopenharmony_ci .cpu = 110, 2108c2ecf20Sopenharmony_ci .raw_size = sizeof(raw_data), 2118c2ecf20Sopenharmony_ci .data_src = 111, 2128c2ecf20Sopenharmony_ci .transaction = 112, 2138c2ecf20Sopenharmony_ci .raw_data = (void *)raw_data, 2148c2ecf20Sopenharmony_ci .callchain = &callchain.callchain, 2158c2ecf20Sopenharmony_ci .no_hw_idx = false, 2168c2ecf20Sopenharmony_ci .branch_stack = &branch_stack.branch_stack, 2178c2ecf20Sopenharmony_ci .user_regs = { 2188c2ecf20Sopenharmony_ci .abi = PERF_SAMPLE_REGS_ABI_64, 2198c2ecf20Sopenharmony_ci .mask = sample_regs, 2208c2ecf20Sopenharmony_ci .regs = regs, 2218c2ecf20Sopenharmony_ci }, 2228c2ecf20Sopenharmony_ci .user_stack = { 2238c2ecf20Sopenharmony_ci .size = sizeof(data), 2248c2ecf20Sopenharmony_ci .data = (void *)data, 2258c2ecf20Sopenharmony_ci }, 2268c2ecf20Sopenharmony_ci .read = { 2278c2ecf20Sopenharmony_ci .time_enabled = 0x030a59d664fca7deULL, 2288c2ecf20Sopenharmony_ci .time_running = 0x011b6ae553eb98edULL, 2298c2ecf20Sopenharmony_ci }, 2308c2ecf20Sopenharmony_ci .intr_regs = { 2318c2ecf20Sopenharmony_ci .abi = PERF_SAMPLE_REGS_ABI_64, 2328c2ecf20Sopenharmony_ci .mask = sample_regs, 2338c2ecf20Sopenharmony_ci .regs = regs, 2348c2ecf20Sopenharmony_ci }, 2358c2ecf20Sopenharmony_ci .phys_addr = 113, 2368c2ecf20Sopenharmony_ci .cgroup = 114, 2378c2ecf20Sopenharmony_ci .aux_sample = { 2388c2ecf20Sopenharmony_ci .size = sizeof(aux_data), 2398c2ecf20Sopenharmony_ci .data = (void *)aux_data, 2408c2ecf20Sopenharmony_ci }, 2418c2ecf20Sopenharmony_ci }; 2428c2ecf20Sopenharmony_ci struct sample_read_value values[] = {{1, 5}, {9, 3}, {2, 7}, {6, 4},}; 2438c2ecf20Sopenharmony_ci struct perf_sample sample_out; 2448c2ecf20Sopenharmony_ci size_t i, sz, bufsz; 2458c2ecf20Sopenharmony_ci int err, ret = -1; 2468c2ecf20Sopenharmony_ci 2478c2ecf20Sopenharmony_ci if (sample_type & PERF_SAMPLE_REGS_USER) 2488c2ecf20Sopenharmony_ci evsel.core.attr.sample_regs_user = sample_regs; 2498c2ecf20Sopenharmony_ci 2508c2ecf20Sopenharmony_ci if (sample_type & PERF_SAMPLE_REGS_INTR) 2518c2ecf20Sopenharmony_ci evsel.core.attr.sample_regs_intr = sample_regs; 2528c2ecf20Sopenharmony_ci 2538c2ecf20Sopenharmony_ci if (sample_type & PERF_SAMPLE_BRANCH_STACK) 2548c2ecf20Sopenharmony_ci evsel.core.attr.branch_sample_type |= PERF_SAMPLE_BRANCH_HW_INDEX; 2558c2ecf20Sopenharmony_ci 2568c2ecf20Sopenharmony_ci for (i = 0; i < sizeof(regs); i++) 2578c2ecf20Sopenharmony_ci *(i + (u8 *)regs) = i & 0xfe; 2588c2ecf20Sopenharmony_ci 2598c2ecf20Sopenharmony_ci if (read_format & PERF_FORMAT_GROUP) { 2608c2ecf20Sopenharmony_ci sample.read.group.nr = 4; 2618c2ecf20Sopenharmony_ci sample.read.group.values = values; 2628c2ecf20Sopenharmony_ci } else { 2638c2ecf20Sopenharmony_ci sample.read.one.value = 0x08789faeb786aa87ULL; 2648c2ecf20Sopenharmony_ci sample.read.one.id = 99; 2658c2ecf20Sopenharmony_ci } 2668c2ecf20Sopenharmony_ci 2678c2ecf20Sopenharmony_ci sz = perf_event__sample_event_size(&sample, sample_type, read_format); 2688c2ecf20Sopenharmony_ci bufsz = sz + 4096; /* Add a bit for overrun checking */ 2698c2ecf20Sopenharmony_ci event = malloc(bufsz); 2708c2ecf20Sopenharmony_ci if (!event) { 2718c2ecf20Sopenharmony_ci pr_debug("malloc failed\n"); 2728c2ecf20Sopenharmony_ci return -1; 2738c2ecf20Sopenharmony_ci } 2748c2ecf20Sopenharmony_ci 2758c2ecf20Sopenharmony_ci memset(event, 0xff, bufsz); 2768c2ecf20Sopenharmony_ci event->header.type = PERF_RECORD_SAMPLE; 2778c2ecf20Sopenharmony_ci event->header.misc = 0; 2788c2ecf20Sopenharmony_ci event->header.size = sz; 2798c2ecf20Sopenharmony_ci 2808c2ecf20Sopenharmony_ci err = perf_event__synthesize_sample(event, sample_type, read_format, 2818c2ecf20Sopenharmony_ci &sample); 2828c2ecf20Sopenharmony_ci if (err) { 2838c2ecf20Sopenharmony_ci pr_debug("%s failed for sample_type %#"PRIx64", error %d\n", 2848c2ecf20Sopenharmony_ci "perf_event__synthesize_sample", sample_type, err); 2858c2ecf20Sopenharmony_ci goto out_free; 2868c2ecf20Sopenharmony_ci } 2878c2ecf20Sopenharmony_ci 2888c2ecf20Sopenharmony_ci /* The data does not contain 0xff so we use that to check the size */ 2898c2ecf20Sopenharmony_ci for (i = bufsz; i > 0; i--) { 2908c2ecf20Sopenharmony_ci if (*(i - 1 + (u8 *)event) != 0xff) 2918c2ecf20Sopenharmony_ci break; 2928c2ecf20Sopenharmony_ci } 2938c2ecf20Sopenharmony_ci if (i != sz) { 2948c2ecf20Sopenharmony_ci pr_debug("Event size mismatch: actual %zu vs expected %zu\n", 2958c2ecf20Sopenharmony_ci i, sz); 2968c2ecf20Sopenharmony_ci goto out_free; 2978c2ecf20Sopenharmony_ci } 2988c2ecf20Sopenharmony_ci 2998c2ecf20Sopenharmony_ci evsel.sample_size = __evsel__sample_size(sample_type); 3008c2ecf20Sopenharmony_ci 3018c2ecf20Sopenharmony_ci err = evsel__parse_sample(&evsel, event, &sample_out); 3028c2ecf20Sopenharmony_ci if (err) { 3038c2ecf20Sopenharmony_ci pr_debug("%s failed for sample_type %#"PRIx64", error %d\n", 3048c2ecf20Sopenharmony_ci "evsel__parse_sample", sample_type, err); 3058c2ecf20Sopenharmony_ci goto out_free; 3068c2ecf20Sopenharmony_ci } 3078c2ecf20Sopenharmony_ci 3088c2ecf20Sopenharmony_ci if (!samples_same(&sample, &sample_out, sample_type, read_format)) { 3098c2ecf20Sopenharmony_ci pr_debug("parsing failed for sample_type %#"PRIx64"\n", 3108c2ecf20Sopenharmony_ci sample_type); 3118c2ecf20Sopenharmony_ci goto out_free; 3128c2ecf20Sopenharmony_ci } 3138c2ecf20Sopenharmony_ci 3148c2ecf20Sopenharmony_ci ret = 0; 3158c2ecf20Sopenharmony_ciout_free: 3168c2ecf20Sopenharmony_ci free(event); 3178c2ecf20Sopenharmony_ci if (ret && read_format) 3188c2ecf20Sopenharmony_ci pr_debug("read_format %#"PRIx64"\n", read_format); 3198c2ecf20Sopenharmony_ci return ret; 3208c2ecf20Sopenharmony_ci} 3218c2ecf20Sopenharmony_ci 3228c2ecf20Sopenharmony_ci/** 3238c2ecf20Sopenharmony_ci * test__sample_parsing - test sample parsing. 3248c2ecf20Sopenharmony_ci * 3258c2ecf20Sopenharmony_ci * This function implements a test that synthesizes a sample event, parses it 3268c2ecf20Sopenharmony_ci * and then checks that the parsed sample matches the original sample. The test 3278c2ecf20Sopenharmony_ci * checks sample format bits separately and together. If the test passes %0 is 3288c2ecf20Sopenharmony_ci * returned, otherwise %-1 is returned. 3298c2ecf20Sopenharmony_ci */ 3308c2ecf20Sopenharmony_ciint test__sample_parsing(struct test *test __maybe_unused, int subtest __maybe_unused) 3318c2ecf20Sopenharmony_ci{ 3328c2ecf20Sopenharmony_ci const u64 rf[] = {4, 5, 6, 7, 12, 13, 14, 15}; 3338c2ecf20Sopenharmony_ci u64 sample_type; 3348c2ecf20Sopenharmony_ci u64 sample_regs; 3358c2ecf20Sopenharmony_ci size_t i; 3368c2ecf20Sopenharmony_ci int err; 3378c2ecf20Sopenharmony_ci 3388c2ecf20Sopenharmony_ci /* 3398c2ecf20Sopenharmony_ci * Fail the test if it has not been updated when new sample format bits 3408c2ecf20Sopenharmony_ci * were added. Please actually update the test rather than just change 3418c2ecf20Sopenharmony_ci * the condition below. 3428c2ecf20Sopenharmony_ci */ 3438c2ecf20Sopenharmony_ci if (PERF_SAMPLE_MAX > PERF_SAMPLE_CGROUP << 1) { 3448c2ecf20Sopenharmony_ci pr_debug("sample format has changed, some new PERF_SAMPLE_ bit was introduced - test needs updating\n"); 3458c2ecf20Sopenharmony_ci return -1; 3468c2ecf20Sopenharmony_ci } 3478c2ecf20Sopenharmony_ci 3488c2ecf20Sopenharmony_ci /* Test each sample format bit separately */ 3498c2ecf20Sopenharmony_ci for (sample_type = 1; sample_type != PERF_SAMPLE_MAX; 3508c2ecf20Sopenharmony_ci sample_type <<= 1) { 3518c2ecf20Sopenharmony_ci /* Test read_format variations */ 3528c2ecf20Sopenharmony_ci if (sample_type == PERF_SAMPLE_READ) { 3538c2ecf20Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(rf); i++) { 3548c2ecf20Sopenharmony_ci err = do_test(sample_type, 0, rf[i]); 3558c2ecf20Sopenharmony_ci if (err) 3568c2ecf20Sopenharmony_ci return err; 3578c2ecf20Sopenharmony_ci } 3588c2ecf20Sopenharmony_ci continue; 3598c2ecf20Sopenharmony_ci } 3608c2ecf20Sopenharmony_ci sample_regs = 0; 3618c2ecf20Sopenharmony_ci 3628c2ecf20Sopenharmony_ci if (sample_type == PERF_SAMPLE_REGS_USER) 3638c2ecf20Sopenharmony_ci sample_regs = 0x3fff; 3648c2ecf20Sopenharmony_ci 3658c2ecf20Sopenharmony_ci if (sample_type == PERF_SAMPLE_REGS_INTR) 3668c2ecf20Sopenharmony_ci sample_regs = 0xff0fff; 3678c2ecf20Sopenharmony_ci 3688c2ecf20Sopenharmony_ci err = do_test(sample_type, sample_regs, 0); 3698c2ecf20Sopenharmony_ci if (err) 3708c2ecf20Sopenharmony_ci return err; 3718c2ecf20Sopenharmony_ci } 3728c2ecf20Sopenharmony_ci 3738c2ecf20Sopenharmony_ci /* Test all sample format bits together */ 3748c2ecf20Sopenharmony_ci sample_type = PERF_SAMPLE_MAX - 1; 3758c2ecf20Sopenharmony_ci sample_regs = 0x3fff; /* shared yb intr and user regs */ 3768c2ecf20Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(rf); i++) { 3778c2ecf20Sopenharmony_ci err = do_test(sample_type, sample_regs, rf[i]); 3788c2ecf20Sopenharmony_ci if (err) 3798c2ecf20Sopenharmony_ci return err; 3808c2ecf20Sopenharmony_ci } 3818c2ecf20Sopenharmony_ci 3828c2ecf20Sopenharmony_ci return 0; 3838c2ecf20Sopenharmony_ci} 384