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 */
28 int bhrb_filter_map_valid_common[] = {
29 PERF_SAMPLE_BRANCH_ANY,
30 PERF_SAMPLE_BRANCH_ANY_CALL,
31 };
32
33 /* Valid bhrb filters in power10 */
34 int bhrb_filter_map_valid_p10[] = {
35 PERF_SAMPLE_BRANCH_IND_CALL,
36 PERF_SAMPLE_BRANCH_COND,
37 };
38
39 #define EventCode 0x1001e
40
bhrb_filter_map_test(void)41 static 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(&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(&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(&event));
76 event_close(&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(&event));
90 event_close(&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(&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(&event));
107
108 return 0;
109 }
110
main(void)111 int main(void)
112 {
113 return test_harness(bhrb_filter_map_test, "bhrb_filter_map_test");
114 }
115