2 * Copyright (c) 2013 Ben Noordhuis <info@bnoordhuis.nl>
3 * Copyright (c) 2013-2015 Dmitry V. Levin <ldv@altlinux.org>
4 * Copyright (c) 2016 Eugene Syromyatnikov <evgsyr@gmail.com>
5 * Copyright (c) 2015-2017 The strace developers.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. The name of the author may not be used to endorse or promote products
17 * derived from this software without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 #include "perf_event_struct.h"
35 #include "xlat/hw_breakpoint_len.h"
36 #include "xlat/hw_breakpoint_type.h"
37 #include "xlat/perf_attr_size.h"
38 #include "xlat/perf_branch_sample_type.h"
39 #include "xlat/perf_event_open_flags.h"
40 #include "xlat/perf_event_read_format.h"
41 #include "xlat/perf_event_sample_format.h"
42 #include "xlat/perf_hw_cache_id.h"
43 #include "xlat/perf_hw_cache_op_id.h"
44 #include "xlat/perf_hw_cache_op_result_id.h"
45 #include "xlat/perf_hw_id.h"
46 #include "xlat/perf_sw_ids.h"
47 #include "xlat/perf_type_id.h"
50 struct perf_event_attr *attr;
55 free_pea_desc(void *pea_desc_ptr)
57 struct pea_desc *desc = pea_desc_ptr;
64 fetch_perf_event_attr(struct tcb *const tcp, const kernel_ulong_t addr)
66 struct pea_desc *desc;
67 struct perf_event_attr *attr;
70 if (umove(tcp, addr + offsetof(struct perf_event_attr, size), &size)) {
75 if (size > sizeof(*attr))
79 size = PERF_ATTR_SIZE_VER0;
82 * Kernel (rightfully) deems invalid attribute structures with size less
83 * than first published format size, and we do the same.
85 if (size < PERF_ATTR_SIZE_VER0) {
91 size = offsetofend(struct perf_event_attr, config);
93 /* Size should be multiple of 8, but kernel doesn't check for it */
96 attr = xcalloc(1, sizeof(*attr));
98 if (umoven_or_printaddr(tcp, addr, size, attr)) {
104 desc = xmalloc(sizeof(*desc));
109 set_tcb_priv_data(tcp, desc, free_pea_desc);
114 #define PRINT_XLAT(prefix, xlat, x, dflt) \
117 printxval_search(xlat, x, dflt); \
121 print_perf_event_attr(struct tcb *const tcp, const kernel_ulong_t addr)
123 static const char *precise_ip_desc[] = {
126 "requested to have 0 skid",
130 struct pea_desc *desc;
131 struct perf_event_attr *attr;
134 int use_new_size = 0;
137 * Amusingly, kernel accepts structures with only part of the field
138 * present, so we making check like this (instead of checking
139 * offsetofend against size) in order to print fields as kernel sees
140 * them. This also should work great on big endian architectures.
142 #define _PERF_CHECK_FIELD(_field) \
144 if (offsetof(struct perf_event_attr, _field) >= size) \
145 goto print_perf_event_attr_out; \
148 desc = get_tcb_priv_data(tcp);
153 /* The only error which expected to change size field currently */
154 if (tcp->u_error == E2BIG) {
155 if (umove(tcp, addr + offsetof(struct perf_event_attr, size),
162 PRINT_XLAT("{type=", perf_type_id, attr->type, "PERF_TYPE_???");
164 printxval(perf_attr_size, attr->size, "PERF_ATTR_SIZE_???");
169 if (use_new_size > 0)
170 printxval(perf_attr_size, new_size,
171 "PERF_ATTR_SIZE_???");
176 switch (attr->type) {
177 case PERF_TYPE_HARDWARE:
178 PRINT_XLAT(", config=", perf_hw_id, attr->config,
179 "PERF_COUNT_HW_???");
181 case PERF_TYPE_SOFTWARE:
182 PRINT_XLAT(", config=", perf_sw_ids, attr->config,
183 "PERF_COUNT_SW_???");
185 case PERF_TYPE_TRACEPOINT:
187 * "The value to use in config can be obtained from under
188 * debugfs tracing/events/../../id if ftrace is enabled
191 tprintf(", config=%" PRIu64, attr->config);
193 case PERF_TYPE_HW_CACHE:
195 * (perf_hw_cache_id) | (perf_hw_cache_op_id << 8) |
196 * (perf_hw_cache_op_result_id << 16)
198 PRINT_XLAT(", config=", perf_hw_cache_id, attr->config & 0xFF,
199 "PERF_COUNT_HW_CACHE_???");
200 PRINT_XLAT("|", perf_hw_cache_op_id, (attr->config >> 8) & 0xFF,
201 "PERF_COUNT_HW_CACHE_OP_???");
203 * Current code (see set_ext_hw_attr in arch/x86/events/core.c,
204 * tile_map_cache_event in arch/tile/kernel/perf_event.c,
205 * arc_pmu_cache_event in arch/arc/kernel/perf_event.c,
206 * hw_perf_cache_event in arch/blackfin/kernel/perf_event.c,
207 * _hw_perf_cache_event in arch/metag/kernel/perf/perf_event.c,
208 * mipspmu_map_cache_event in arch/mips/kernel/perf_event_mipsxx.c,
209 * hw_perf_cache_event in arch/powerpc/perf/core-book3s.c,
210 * hw_perf_cache_event in arch/powerpc/perf/core-fsl-emb.c,
211 * hw_perf_cache_event in arch/sh/kernel/perf_event.c,
212 * sparc_map_cache_event in arch/sparc/kernel/perf_event.c,
213 * xtensa_pmu_cache_event in arch/xtensa/kernel/perf_event.c,
214 * armpmu_map_cache_event in drivers/perf/arm_pmu.c) assumes
215 * that cache result is 8 bits in size.
217 PRINT_XLAT("<<8|", perf_hw_cache_op_result_id,
218 (attr->config >> 16) & 0xFF,
219 "PERF_COUNT_HW_CACHE_RESULT_???");
221 if (attr->config >> 24) {
222 tprintf("|%#" PRIx64 "<<24", attr->config >> 24);
223 tprints_comment("PERF_COUNT_HW_CACHE_???");
228 * "If type is PERF_TYPE_RAW, then a custom "raw" config
229 * value is needed. Most CPUs support events that are not
230 * covered by the "generalized" events. These are
231 * implementation defined; see your CPU manual (for example the
232 * Intel Volume 3B documentation or the AMD BIOS and Kernel
233 * Developer Guide). The libpfm4 library can be used to
234 * translate from the name in the architectural manuals
235 * to the raw hex value perf_event_open() expects in this
238 case PERF_TYPE_BREAKPOINT:
240 * "If type is PERF_TYPE_BREAKPOINT, then leave config set
241 * to zero. Its parameters are set in other places."
244 tprintf(", config=%#" PRIx64, attr->config);
249 goto print_perf_event_attr_out;
252 tprintf(", sample_freq=%" PRIu64, attr->sample_freq);
254 tprintf(", sample_period=%" PRIu64, attr->sample_period);
256 tprints(", sample_type=");
257 printflags64(perf_event_sample_format, attr->sample_type,
260 tprints(", read_format=");
261 printflags64(perf_event_read_format, attr->read_format,
264 tprintf(", disabled=%u"
268 ", exclusive_user=%u"
269 ", exclude_kernel=%u"
276 ", enable_on_exec=%u"
285 attr->exclude_kernel,
292 attr->enable_on_exec,
296 tprints_comment(precise_ip_desc[attr->precise_ip]);
297 tprintf(", mmap_data=%u"
301 ", exclude_callchain_kernel=%u"
302 ", exclude_callchain_user=%u"
306 ", context_switch=%u"
307 ", write_backward=%u"
313 attr->exclude_callchain_kernel,
314 attr->exclude_callchain_user,
318 attr->context_switch,
319 attr->write_backward,
323 * Print it only in case it is non-zero, since it may contain flags we
324 * are not aware about.
326 if (attr->__reserved_1) {
327 tprintf(", __reserved_1=%#" PRIx64,
328 (uint64_t) attr->__reserved_1);
329 tprints_comment("Bits 63..29");
333 tprintf(", wakeup_watermark=%u", attr->wakeup_watermark);
335 tprintf(", wakeup_events=%u", attr->wakeup_events);
337 if (attr->type == PERF_TYPE_BREAKPOINT)
338 /* Any combination of R/W with X is deemed invalid */
339 PRINT_XLAT(", bp_type=", hw_breakpoint_type, attr->bp_type,
341 (HW_BREAKPOINT_X | HW_BREAKPOINT_RW)) ?
342 "HW_BREAKPOINT_INVALID" :
343 "HW_BREAKPOINT_???");
345 if (attr->type == PERF_TYPE_BREAKPOINT)
346 tprintf(", bp_addr=%#" PRIx64, attr->bp_addr);
348 tprintf(", config1=%#" PRIx64, attr->config1);
351 * Fields after bp_addr/config1 are optional and may not present; check
352 * against size is needed.
355 _PERF_CHECK_FIELD(bp_len);
356 if (attr->type == PERF_TYPE_BREAKPOINT)
357 tprintf(", bp_len=%" PRIu64, attr->bp_len);
359 tprintf(", config2=%#" PRIx64, attr->config2);
361 _PERF_CHECK_FIELD(branch_sample_type);
362 if (attr->sample_type & PERF_SAMPLE_BRANCH_STACK) {
363 tprints(", branch_sample_type=");
364 printflags64(perf_branch_sample_type, attr->branch_sample_type,
365 "PERF_SAMPLE_BRANCH_???");
368 _PERF_CHECK_FIELD(sample_regs_user);
370 * "This bit mask defines the set of user CPU registers to dump on
371 * samples. The layout of the register mask is architecture-specific and
372 * described in the kernel header
373 * arch/ARCH/include/uapi/asm/perf_regs.h."
375 tprintf(", sample_regs_user=%#" PRIx64, attr->sample_regs_user);
377 _PERF_CHECK_FIELD(sample_stack_user);
379 * "size of the user stack to dump if PERF_SAMPLE_STACK_USER is
382 if (attr->sample_type & PERF_SAMPLE_STACK_USER)
383 tprintf(", sample_stack_user=%#" PRIx32,
384 attr->sample_stack_user);
386 if (attr->use_clockid) {
387 _PERF_CHECK_FIELD(clockid);
388 tprints(", clockid=");
389 printxval(clocknames, attr->clockid, "CLOCK_???");
392 _PERF_CHECK_FIELD(sample_regs_intr);
393 tprintf(", sample_regs_intr=%#" PRIx64, attr->sample_regs_intr);
395 _PERF_CHECK_FIELD(aux_watermark);
396 tprintf(", aux_watermark=%" PRIu32, attr->aux_watermark);
398 _PERF_CHECK_FIELD(sample_max_stack);
399 tprintf(", sample_max_stack=%" PRIu16, attr->sample_max_stack);
401 /* _PERF_CHECK_FIELD(__reserved_2);
402 tprintf(", __reserved2=%" PRIu16, attr->__reserved_2); */
404 print_perf_event_attr_out:
405 if ((attr->size && (attr->size > size)) ||
406 (!attr->size && (size < PERF_ATTR_SIZE_VER0)))
412 SYS_FUNC(perf_event_open)
415 * We try to copy out the whole structure on entering in order to check
416 * size value on exiting. We do not check the rest of the fields because
417 * they shouldn't be changed, but copy the whole structure instead
418 * of just size field because they could.
421 if (!fetch_perf_event_attr(tcp, tcp->u_arg[0]))
424 print_perf_event_attr(tcp, tcp->u_arg[0]);
427 tprintf(", %d, %d, %d, ",
430 (int) tcp->u_arg[3]);
431 printflags64(perf_event_open_flags, tcp->u_arg[4], "PERF_FLAG_???");
433 return RVAL_DECODED | RVAL_FD;