diff options
-rw-r--r-- | NEWS | 1 | ||||
-rw-r--r-- | bundled/linux/include/uapi/linux/perf_event.h | 39 | ||||
-rw-r--r-- | src/perf.c | 16 | ||||
-rw-r--r-- | src/perf_event_struct.h | 5 | ||||
-rw-r--r-- | src/xlat/perf_attr_size.in | 1 | ||||
-rw-r--r-- | tests/perf_event_open.c | 31 |
6 files changed, 76 insertions, 17 deletions
@@ -9,6 +9,7 @@ Noteworthy changes in release ?.?? (????-??-??) PTRACE_SETREGS, PTRACE_SETREGS64, PTRACE_GETFPREGS, and PTRACE_SETFPREGS requests. * Implemented powerpc System Call Vectored ABI support. + * Enhanced decoding of perf_event_open syscall. * Updated lists of BPF_*, IORING_*, KEXEC_*, KEY_*, KVM_*, NT_*, PR_*, PTRACE_*, RTM_*, RTPROT_*, TRAP_*, UFFD_*, UFFDIO_*, and V4L2_* constants. * Updated lists of ioctl commands from Linux 5.13. diff --git a/bundled/linux/include/uapi/linux/perf_event.h b/bundled/linux/include/uapi/linux/perf_event.h index b6f0c16dc..71cab1e07 100644 --- a/bundled/linux/include/uapi/linux/perf_event.h +++ b/bundled/linux/include/uapi/linux/perf_event.h @@ -38,6 +38,21 @@ enum perf_type_id { }; /* + * attr.config layout for type PERF_TYPE_HARDWARE and PERF_TYPE_HW_CACHE + * PERF_TYPE_HARDWARE: 0xEEEEEEEE000000AA + * AA: hardware event ID + * EEEEEEEE: PMU type ID + * PERF_TYPE_HW_CACHE: 0xEEEEEEEE00DDCCBB + * BB: hardware cache ID + * CC: hardware cache op ID + * DD: hardware cache op result ID + * EEEEEEEE: PMU type ID + * If the PMU type ID is 0, the PERF_TYPE_RAW will be applied. + */ +#define PERF_PMU_TYPE_SHIFT 32 +#define PERF_HW_EVENT_MASK 0xffffffff + +/* * Generalized performance event event_id types, used by the * attr.event_id parameter of the sys_perf_event_open() * syscall: @@ -112,6 +127,7 @@ enum perf_sw_ids { PERF_COUNT_SW_EMULATION_FAULTS = 8, PERF_COUNT_SW_DUMMY = 9, PERF_COUNT_SW_BPF_OUTPUT = 10, + PERF_COUNT_SW_CGROUP_SWITCHES = 11, PERF_COUNT_SW_MAX, /* non-ABI */ }; @@ -311,6 +327,7 @@ enum perf_event_read_format { #define PERF_ATTR_SIZE_VER4 104 /* add: sample_regs_intr */ #define PERF_ATTR_SIZE_VER5 112 /* add: aux_watermark */ #define PERF_ATTR_SIZE_VER6 120 /* add: aux_sample_size */ +#define PERF_ATTR_SIZE_VER7 128 /* add: sig_data */ /* * Hardware event_id to monitor via a performance monitoring event: @@ -391,7 +408,8 @@ struct perf_event_attr { build_id : 1, /* use build id in mmap2 events */ inherit_thread : 1, /* children only inherit if cloned with CLONE_THREAD */ remove_on_exec : 1, /* event is removed from task on exec */ - __reserved_1 : 27; + sigtrap : 1, /* send synchronous SIGTRAP on event */ + __reserved_1 : 26; union { __u32 wakeup_events; /* wakeup every n events */ @@ -443,6 +461,12 @@ struct perf_event_attr { __u16 __reserved_2; __u32 aux_sample_size; __u32 __reserved_3; + + /* + * User provided data if sigtrap=1, passed back to user via + * siginfo_t::si_perf_data, e.g. to permit user to identify the event. + */ + __u64 sig_data; }; /* @@ -1158,10 +1182,15 @@ enum perf_callchain_context { /** * PERF_RECORD_AUX::flags bits */ -#define PERF_AUX_FLAG_TRUNCATED 0x01 /* record was truncated to fit */ -#define PERF_AUX_FLAG_OVERWRITE 0x02 /* snapshot from overwrite mode */ -#define PERF_AUX_FLAG_PARTIAL 0x04 /* record contains gaps */ -#define PERF_AUX_FLAG_COLLISION 0x08 /* sample collided with another */ +#define PERF_AUX_FLAG_TRUNCATED 0x01 /* record was truncated to fit */ +#define PERF_AUX_FLAG_OVERWRITE 0x02 /* snapshot from overwrite mode */ +#define PERF_AUX_FLAG_PARTIAL 0x04 /* record contains gaps */ +#define PERF_AUX_FLAG_COLLISION 0x08 /* sample collided with another */ +#define PERF_AUX_FLAG_PMU_FORMAT_TYPE_MASK 0xff00 /* PMU specific trace format type */ + +/* CoreSight PMU AUX buffer formats */ +#define PERF_AUX_FLAG_CORESIGHT_FORMAT_CORESIGHT 0x0000 /* Default for backward compatibility */ +#define PERF_AUX_FLAG_CORESIGHT_FORMAT_RAW 0x0100 /* Raw format of the source */ #define PERF_FLAG_FD_NO_GROUP (1UL << 0) #define PERF_FLAG_FD_OUTPUT (1UL << 1) diff --git a/src/perf.c b/src/perf.c index dd83835c1..01badde1d 100644 --- a/src/perf.c +++ b/src/perf.c @@ -319,6 +319,8 @@ print_perf_event_attr(struct tcb *const tcp, const kernel_ulong_t addr) PRINT_FIELD_U_CAST(*attr, inherit_thread, unsigned int); tprint_struct_next(); PRINT_FIELD_U_CAST(*attr, remove_on_exec, unsigned int); + tprint_struct_next(); + PRINT_FIELD_U_CAST(*attr, sigtrap, unsigned int); /* * Print it only in case it is non-zero, since it may contain flags we @@ -327,7 +329,7 @@ print_perf_event_attr(struct tcb *const tcp, const kernel_ulong_t addr) if (attr->__reserved_1) { tprint_struct_next(); PRINT_FIELD_X_CAST(*attr, __reserved_1, uint64_t); - tprints_comment("Bits 63..37"); + tprints_comment("Bits 63..38"); } if (attr->watermark) { @@ -424,13 +426,13 @@ print_perf_event_attr(struct tcb *const tcp, const kernel_ulong_t addr) tprint_struct_next(); PRINT_FIELD_U(*attr, aux_sample_size); -#if 0 _PERF_CHECK_FIELD(__reserved_3); - if (attr->__reserved_3) { - tprint_struct_next(); - PRINT_FIELD_X(*attr, __reserved_3); - } -#endif + if (attr->__reserved_3) + tprintf(" /* bytes 116..119: %#x */", attr->__reserved_3); + + _PERF_CHECK_FIELD(sig_data); + tprint_struct_next(); + PRINT_FIELD_X(*attr, sig_data); print_perf_event_attr_out: if ((attr->size && (attr->size > size)) || diff --git a/src/perf_event_struct.h b/src/perf_event_struct.h index acbcaef44..4ab716599 100644 --- a/src/perf_event_struct.h +++ b/src/perf_event_struct.h @@ -57,7 +57,8 @@ struct perf_event_attr { build_id :1, inherit_thread :1, remove_on_exec :1, - __reserved_1 :27; + sigtrap :1, + __reserved_1 :26; union { uint32_t wakeup_events; uint32_t wakeup_watermark; @@ -88,6 +89,8 @@ struct perf_event_attr { uint32_t aux_sample_size; uint32_t __reserved_3; /* End of ver 6 - 120 bytes */ + uint64_t sig_data; + /* End of ver 7 - 128 bytes */ }; struct perf_event_query_bpf { diff --git a/src/xlat/perf_attr_size.in b/src/xlat/perf_attr_size.in index 9b5cf9894..4210ef43e 100644 --- a/src/xlat/perf_attr_size.in +++ b/src/xlat/perf_attr_size.in @@ -5,3 +5,4 @@ PERF_ATTR_SIZE_VER3 96 PERF_ATTR_SIZE_VER4 104 PERF_ATTR_SIZE_VER5 112 PERF_ATTR_SIZE_VER6 120 +PERF_ATTR_SIZE_VER7 128 diff --git a/tests/perf_event_open.c b/tests/perf_event_open.c index 6ee203050..8e5188fd7 100644 --- a/tests/perf_event_open.c +++ b/tests/perf_event_open.c @@ -84,7 +84,8 @@ struct pea_flags { build_id :1, inherit_thread :1, remove_on_exec :1, - __reserved_1 :27; + sigtrap :1, + __reserved_1 :26; }; static const char * @@ -139,7 +140,7 @@ print_event_attr(struct perf_event_attr *attr_ptr, size_t size, STRACE_PEA_ABBREV_SIZE = offsetof(struct perf_event_attr, config) + sizeof(attr_ptr->config), - STRACE_PEA_SIZE = 120, + STRACE_PEA_SIZE = 128, }; uint32_t read_size; @@ -300,9 +301,12 @@ print_event_attr(struct perf_event_attr *attr_ptr, size_t size, val = attr->remove_on_exec; printf(", remove_on_exec=%" PRIu64, val); + val = attr->sigtrap; + printf(", sigtrap=%" PRIu64, val); + val = flags_data.flags.__reserved_1; if (val) - printf(", __reserved_1=%#" PRIx64 " /* Bits 63..37 */", val); + printf(", __reserved_1=%#" PRIx64 " /* Bits 63..38 */", val); printf(", %s=%u", attr->watermark ? "wakeup_watermark" : "wakeup_events", @@ -419,6 +423,18 @@ print_event_attr(struct perf_event_attr *attr_ptr, size_t size, goto end; } + val = attr->__reserved_3; + if (val) + printf(" /* bytes 116..119: %#" PRIx32 " */", (uint32_t) val); + + if (size <= 120) { + cutoff = 120; + goto end; + } + + val = attr->sig_data; + printf(", sig_data=%#" PRIx64, (uint64_t) val); + cutoff = STRACE_PEA_SIZE; end: @@ -477,7 +493,9 @@ main(void) static const size_t attr_v5_5_size = PERF_ATTR_SIZE_VER5 + 4; static const size_t attr_v5_75_size = PERF_ATTR_SIZE_VER5 + 6; static const size_t attr_v6_size = PERF_ATTR_SIZE_VER6; - static const size_t attr_big_size = PERF_ATTR_SIZE_VER6 + 32; + static const size_t attr_v6_5_size = PERF_ATTR_SIZE_VER6 + 4; + static const size_t attr_v7_size = PERF_ATTR_SIZE_VER7; + static const size_t attr_big_size = PERF_ATTR_SIZE_VER7 + 32; static const struct u64_val_str attr_types[] = { { ARG_STR(PERF_TYPE_HARDWARE) }, @@ -624,6 +642,8 @@ main(void) ATTR_REC(attr_v5_5_size), ATTR_REC(attr_v5_75_size), ATTR_REC(attr_v6_size), + ATTR_REC(attr_v6_5_size), + ATTR_REC(attr_v7_size), ATTR_REC(attr_big_size), }; @@ -712,6 +732,9 @@ main(void) if (((i % 17) == 3) && (size >= 112)) ((uint16_t *) attr)[110 / sizeof(uint16_t)] = 0; + if (((i % 23) == 7) && (size >= 120)) + ((uint32_t *) attr)[116 / sizeof(uint32_t)] = 0; + if (i == 0) attr->size = size + 8; |