Input: wm97xx: add new AC97 bus support
[sfrench/cifs-2.6.git] / tools / perf / tests / sample-parsing.c
1 #include <stdbool.h>
2 #include <inttypes.h>
3 #include <linux/kernel.h>
4 #include <linux/types.h>
5
6 #include "util.h"
7 #include "event.h"
8 #include "evsel.h"
9 #include "debug.h"
10
11 #include "tests.h"
12
13 #define COMP(m) do {                                    \
14         if (s1->m != s2->m) {                           \
15                 pr_debug("Samples differ at '"#m"'\n"); \
16                 return false;                           \
17         }                                               \
18 } while (0)
19
20 #define MCOMP(m) do {                                   \
21         if (memcmp(&s1->m, &s2->m, sizeof(s1->m))) {    \
22                 pr_debug("Samples differ at '"#m"'\n"); \
23                 return false;                           \
24         }                                               \
25 } while (0)
26
27 static bool samples_same(const struct perf_sample *s1,
28                          const struct perf_sample *s2,
29                          u64 type, u64 read_format)
30 {
31         size_t i;
32
33         if (type & PERF_SAMPLE_IDENTIFIER)
34                 COMP(id);
35
36         if (type & PERF_SAMPLE_IP)
37                 COMP(ip);
38
39         if (type & PERF_SAMPLE_TID) {
40                 COMP(pid);
41                 COMP(tid);
42         }
43
44         if (type & PERF_SAMPLE_TIME)
45                 COMP(time);
46
47         if (type & PERF_SAMPLE_ADDR)
48                 COMP(addr);
49
50         if (type & PERF_SAMPLE_ID)
51                 COMP(id);
52
53         if (type & PERF_SAMPLE_STREAM_ID)
54                 COMP(stream_id);
55
56         if (type & PERF_SAMPLE_CPU)
57                 COMP(cpu);
58
59         if (type & PERF_SAMPLE_PERIOD)
60                 COMP(period);
61
62         if (type & PERF_SAMPLE_READ) {
63                 if (read_format & PERF_FORMAT_GROUP)
64                         COMP(read.group.nr);
65                 else
66                         COMP(read.one.value);
67                 if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED)
68                         COMP(read.time_enabled);
69                 if (read_format & PERF_FORMAT_TOTAL_TIME_RUNNING)
70                         COMP(read.time_running);
71                 /* PERF_FORMAT_ID is forced for PERF_SAMPLE_READ */
72                 if (read_format & PERF_FORMAT_GROUP) {
73                         for (i = 0; i < s1->read.group.nr; i++)
74                                 MCOMP(read.group.values[i]);
75                 } else {
76                         COMP(read.one.id);
77                 }
78         }
79
80         if (type & PERF_SAMPLE_CALLCHAIN) {
81                 COMP(callchain->nr);
82                 for (i = 0; i < s1->callchain->nr; i++)
83                         COMP(callchain->ips[i]);
84         }
85
86         if (type & PERF_SAMPLE_RAW) {
87                 COMP(raw_size);
88                 if (memcmp(s1->raw_data, s2->raw_data, s1->raw_size)) {
89                         pr_debug("Samples differ at 'raw_data'\n");
90                         return false;
91                 }
92         }
93
94         if (type & PERF_SAMPLE_BRANCH_STACK) {
95                 COMP(branch_stack->nr);
96                 for (i = 0; i < s1->branch_stack->nr; i++)
97                         MCOMP(branch_stack->entries[i]);
98         }
99
100         if (type & PERF_SAMPLE_REGS_USER) {
101                 size_t sz = hweight_long(s1->user_regs.mask) * sizeof(u64);
102
103                 COMP(user_regs.mask);
104                 COMP(user_regs.abi);
105                 if (s1->user_regs.abi &&
106                     (!s1->user_regs.regs || !s2->user_regs.regs ||
107                      memcmp(s1->user_regs.regs, s2->user_regs.regs, sz))) {
108                         pr_debug("Samples differ at 'user_regs'\n");
109                         return false;
110                 }
111         }
112
113         if (type & PERF_SAMPLE_STACK_USER) {
114                 COMP(user_stack.size);
115                 if (memcmp(s1->user_stack.data, s2->user_stack.data,
116                            s1->user_stack.size)) {
117                         pr_debug("Samples differ at 'user_stack'\n");
118                         return false;
119                 }
120         }
121
122         if (type & PERF_SAMPLE_WEIGHT)
123                 COMP(weight);
124
125         if (type & PERF_SAMPLE_DATA_SRC)
126                 COMP(data_src);
127
128         if (type & PERF_SAMPLE_TRANSACTION)
129                 COMP(transaction);
130
131         if (type & PERF_SAMPLE_REGS_INTR) {
132                 size_t sz = hweight_long(s1->intr_regs.mask) * sizeof(u64);
133
134                 COMP(intr_regs.mask);
135                 COMP(intr_regs.abi);
136                 if (s1->intr_regs.abi &&
137                     (!s1->intr_regs.regs || !s2->intr_regs.regs ||
138                      memcmp(s1->intr_regs.regs, s2->intr_regs.regs, sz))) {
139                         pr_debug("Samples differ at 'intr_regs'\n");
140                         return false;
141                 }
142         }
143
144         if (type & PERF_SAMPLE_PHYS_ADDR)
145                 COMP(phys_addr);
146
147         return true;
148 }
149
150 static int do_test(u64 sample_type, u64 sample_regs, u64 read_format)
151 {
152         struct perf_evsel evsel = {
153                 .needs_swap = false,
154                 .attr = {
155                         .sample_type = sample_type,
156                         .read_format = read_format,
157                 },
158         };
159         union perf_event *event;
160         union {
161                 struct ip_callchain callchain;
162                 u64 data[64];
163         } callchain = {
164                 /* 3 ips */
165                 .data = {3, 201, 202, 203},
166         };
167         union {
168                 struct branch_stack branch_stack;
169                 u64 data[64];
170         } branch_stack = {
171                 /* 1 branch_entry */
172                 .data = {1, 211, 212, 213},
173         };
174         u64 regs[64];
175         const u64 raw_data[] = {0x123456780a0b0c0dULL, 0x1102030405060708ULL};
176         const u64 data[] = {0x2211443366558877ULL, 0, 0xaabbccddeeff4321ULL};
177         struct perf_sample sample = {
178                 .ip             = 101,
179                 .pid            = 102,
180                 .tid            = 103,
181                 .time           = 104,
182                 .addr           = 105,
183                 .id             = 106,
184                 .stream_id      = 107,
185                 .period         = 108,
186                 .weight         = 109,
187                 .cpu            = 110,
188                 .raw_size       = sizeof(raw_data),
189                 .data_src       = 111,
190                 .transaction    = 112,
191                 .raw_data       = (void *)raw_data,
192                 .callchain      = &callchain.callchain,
193                 .branch_stack   = &branch_stack.branch_stack,
194                 .user_regs      = {
195                         .abi    = PERF_SAMPLE_REGS_ABI_64,
196                         .mask   = sample_regs,
197                         .regs   = regs,
198                 },
199                 .user_stack     = {
200                         .size   = sizeof(data),
201                         .data   = (void *)data,
202                 },
203                 .read           = {
204                         .time_enabled = 0x030a59d664fca7deULL,
205                         .time_running = 0x011b6ae553eb98edULL,
206                 },
207                 .intr_regs      = {
208                         .abi    = PERF_SAMPLE_REGS_ABI_64,
209                         .mask   = sample_regs,
210                         .regs   = regs,
211                 },
212                 .phys_addr      = 113,
213         };
214         struct sample_read_value values[] = {{1, 5}, {9, 3}, {2, 7}, {6, 4},};
215         struct perf_sample sample_out;
216         size_t i, sz, bufsz;
217         int err, ret = -1;
218
219         if (sample_type & PERF_SAMPLE_REGS_USER)
220                 evsel.attr.sample_regs_user = sample_regs;
221
222         if (sample_type & PERF_SAMPLE_REGS_INTR)
223                 evsel.attr.sample_regs_intr = sample_regs;
224
225         for (i = 0; i < sizeof(regs); i++)
226                 *(i + (u8 *)regs) = i & 0xfe;
227
228         if (read_format & PERF_FORMAT_GROUP) {
229                 sample.read.group.nr     = 4;
230                 sample.read.group.values = values;
231         } else {
232                 sample.read.one.value = 0x08789faeb786aa87ULL;
233                 sample.read.one.id    = 99;
234         }
235
236         sz = perf_event__sample_event_size(&sample, sample_type, read_format);
237         bufsz = sz + 4096; /* Add a bit for overrun checking */
238         event = malloc(bufsz);
239         if (!event) {
240                 pr_debug("malloc failed\n");
241                 return -1;
242         }
243
244         memset(event, 0xff, bufsz);
245         event->header.type = PERF_RECORD_SAMPLE;
246         event->header.misc = 0;
247         event->header.size = sz;
248
249         err = perf_event__synthesize_sample(event, sample_type, read_format,
250                                             &sample, false);
251         if (err) {
252                 pr_debug("%s failed for sample_type %#"PRIx64", error %d\n",
253                          "perf_event__synthesize_sample", sample_type, err);
254                 goto out_free;
255         }
256
257         /* The data does not contain 0xff so we use that to check the size */
258         for (i = bufsz; i > 0; i--) {
259                 if (*(i - 1 + (u8 *)event) != 0xff)
260                         break;
261         }
262         if (i != sz) {
263                 pr_debug("Event size mismatch: actual %zu vs expected %zu\n",
264                          i, sz);
265                 goto out_free;
266         }
267
268         evsel.sample_size = __perf_evsel__sample_size(sample_type);
269
270         err = perf_evsel__parse_sample(&evsel, event, &sample_out);
271         if (err) {
272                 pr_debug("%s failed for sample_type %#"PRIx64", error %d\n",
273                          "perf_evsel__parse_sample", sample_type, err);
274                 goto out_free;
275         }
276
277         if (!samples_same(&sample, &sample_out, sample_type, read_format)) {
278                 pr_debug("parsing failed for sample_type %#"PRIx64"\n",
279                          sample_type);
280                 goto out_free;
281         }
282
283         ret = 0;
284 out_free:
285         free(event);
286         if (ret && read_format)
287                 pr_debug("read_format %#"PRIx64"\n", read_format);
288         return ret;
289 }
290
291 /**
292  * test__sample_parsing - test sample parsing.
293  *
294  * This function implements a test that synthesizes a sample event, parses it
295  * and then checks that the parsed sample matches the original sample.  The test
296  * checks sample format bits separately and together.  If the test passes %0 is
297  * returned, otherwise %-1 is returned.
298  */
299 int test__sample_parsing(struct test *test __maybe_unused, int subtest __maybe_unused)
300 {
301         const u64 rf[] = {4, 5, 6, 7, 12, 13, 14, 15};
302         u64 sample_type;
303         u64 sample_regs;
304         size_t i;
305         int err;
306
307         /*
308          * Fail the test if it has not been updated when new sample format bits
309          * were added.  Please actually update the test rather than just change
310          * the condition below.
311          */
312         if (PERF_SAMPLE_MAX > PERF_SAMPLE_PHYS_ADDR << 1) {
313                 pr_debug("sample format has changed, some new PERF_SAMPLE_ bit was introduced - test needs updating\n");
314                 return -1;
315         }
316
317         /* Test each sample format bit separately */
318         for (sample_type = 1; sample_type != PERF_SAMPLE_MAX;
319              sample_type <<= 1) {
320                 /* Test read_format variations */
321                 if (sample_type == PERF_SAMPLE_READ) {
322                         for (i = 0; i < ARRAY_SIZE(rf); i++) {
323                                 err = do_test(sample_type, 0, rf[i]);
324                                 if (err)
325                                         return err;
326                         }
327                         continue;
328                 }
329                 sample_regs = 0;
330
331                 if (sample_type == PERF_SAMPLE_REGS_USER)
332                         sample_regs = 0x3fff;
333
334                 if (sample_type == PERF_SAMPLE_REGS_INTR)
335                         sample_regs = 0xff0fff;
336
337                 err = do_test(sample_type, sample_regs, 0);
338                 if (err)
339                         return err;
340         }
341
342         /* Test all sample format bits together */
343         sample_type = PERF_SAMPLE_MAX - 1;
344         sample_regs = 0x3fff; /* shared yb intr and user regs */
345         for (i = 0; i < ARRAY_SIZE(rf); i++) {
346                 err = do_test(sample_type, sample_regs, rf[i]);
347                 if (err)
348                         return err;
349         }
350
351         return 0;
352 }