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 | |
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(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 | |
111 | int main(void) |
112 | { |
113 | return test_harness(bhrb_filter_map_test, "bhrb_filter_map_test" ); |
114 | } |
115 | |