1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * Copyright 2022, Athira Rajeev, IBM Corp.
4 */
5
6#include <stdio.h>
7#include <stdlib.h>
8
9#include "../event.h"
10#include "misc.h"
11#include "utils.h"
12
13/*
14 * A perf sampling test to check bhrb filter
15 * map. All the branch filters are not supported
16 * in powerpc. Supported filters in:
17 * power10: any, any_call, ind_call, cond
18 * power9: any, any_call
19 *
20 * Testcase checks event open for invalid bhrb filter
21 * types should fail and valid filter types should pass.
22 * Testcase does validity check for these branch
23 * sample types.
24 */
25
26/* Invalid types for powerpc */
27/* Valid bhrb filters in power9/power10 */
28int bhrb_filter_map_valid_common[] = {
29 PERF_SAMPLE_BRANCH_ANY,
30 PERF_SAMPLE_BRANCH_ANY_CALL,
31};
32
33/* Valid bhrb filters in power10 */
34int bhrb_filter_map_valid_p10[] = {
35 PERF_SAMPLE_BRANCH_IND_CALL,
36 PERF_SAMPLE_BRANCH_COND,
37};
38
39#define EventCode 0x1001e
40
41static int bhrb_filter_map_test(void)
42{
43 struct event event;
44 int i;
45
46 /* Check for platform support for the test */
47 SKIP_IF(platform_check_for_tests());
48
49 /*
50 * Skip for Generic compat PMU since
51 * bhrb filters is not supported
52 */
53 SKIP_IF(check_for_generic_compat_pmu());
54
55 /* Init the event for the sampling test */
56 event_init(e: &event, EventCode);
57
58 event.attr.sample_period = 1000;
59 event.attr.sample_type = PERF_SAMPLE_BRANCH_STACK;
60 event.attr.disabled = 1;
61
62 /* Invalid filter maps which are expected to fail in event_open */
63 for (i = PERF_SAMPLE_BRANCH_USER_SHIFT; i < PERF_SAMPLE_BRANCH_MAX_SHIFT; i++) {
64 /* Skip the valid branch sample type */
65 if (i == PERF_SAMPLE_BRANCH_ANY_SHIFT || i == PERF_SAMPLE_BRANCH_ANY_CALL_SHIFT \
66 || i == PERF_SAMPLE_BRANCH_IND_CALL_SHIFT || i == PERF_SAMPLE_BRANCH_COND_SHIFT)
67 continue;
68 event.attr.branch_sample_type = 1U << i;
69 FAIL_IF(!event_open(e: &event));
70 }
71
72 /* valid filter maps for power9/power10 which are expected to pass in event_open */
73 for (i = 0; i < ARRAY_SIZE(bhrb_filter_map_valid_common); i++) {
74 event.attr.branch_sample_type = bhrb_filter_map_valid_common[i];
75 FAIL_IF(event_open(e: &event));
76 event_close(e: &event);
77 }
78
79 /*
80 * filter maps which are valid in power10 and invalid in power9.
81 * PVR check is used here since PMU specific data like bhrb filter
82 * alternative tests is handled by respective PMU driver code and
83 * using PVR will work correctly for all cases including generic
84 * compat mode.
85 */
86 if (PVR_VER(mfspr(SPRN_PVR)) == POWER10) {
87 for (i = 0; i < ARRAY_SIZE(bhrb_filter_map_valid_p10); i++) {
88 event.attr.branch_sample_type = bhrb_filter_map_valid_p10[i];
89 FAIL_IF(event_open(e: &event));
90 event_close(e: &event);
91 }
92 } else {
93 for (i = 0; i < ARRAY_SIZE(bhrb_filter_map_valid_p10); i++) {
94 event.attr.branch_sample_type = bhrb_filter_map_valid_p10[i];
95 FAIL_IF(!event_open(e: &event));
96 }
97 }
98
99 /*
100 * Combine filter maps which includes a valid branch filter and an invalid branch
101 * filter. Example: any ( PERF_SAMPLE_BRANCH_ANY) and any_call
102 * (PERF_SAMPLE_BRANCH_ANY_CALL).
103 * The perf_event_open should fail in this case.
104 */
105 event.attr.branch_sample_type = PERF_SAMPLE_BRANCH_ANY | PERF_SAMPLE_BRANCH_ANY_CALL;
106 FAIL_IF(!event_open(e: &event));
107
108 return 0;
109}
110
111int main(void)
112{
113 return test_harness(bhrb_filter_map_test, "bhrb_filter_map_test");
114}
115

source code of linux/tools/testing/selftests/powerpc/pmu/sampling_tests/bhrb_filter_map_test.c