summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS1
-rw-r--r--bundled/linux/include/uapi/linux/perf_event.h39
-rw-r--r--src/perf.c16
-rw-r--r--src/perf_event_struct.h5
-rw-r--r--src/xlat/perf_attr_size.in1
-rw-r--r--tests/perf_event_open.c31
6 files changed, 76 insertions, 17 deletions
diff --git a/NEWS b/NEWS
index d81197f33..8050523fc 100644
--- a/NEWS
+++ b/NEWS
@@ -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;