summaryrefslogtreecommitdiff
path: root/tools/perf/tests/shell
diff options
context:
space:
mode:
authorIan Rogers <irogers@google.com>2024-10-14 17:01:58 -0700
committerNamhyung Kim <namhyung@kernel.org>2024-10-17 13:17:36 -0700
commit8296aa0f28c2433f213fce18bad00a97965c052f (patch)
tree7870e9a479a6339703f5c8d4585b2bbe25bce656 /tools/perf/tests/shell
parent3a447031f5fc21c4e112a5ca52d091d1ef33aeb6 (diff)
perf test: Move attr files into shell directory where they are used
Now the attr tests are shell tests move the associated python and configuration files. Update the installation build rules for the new directories. Recycle the lib install rules for python files allowing the explicit attr.py install line to be dropped. Signed-off-by: Ian Rogers <irogers@google.com> Tested-by: Athira Rajeev <atrajeev@linux.vnet.ibm.com> Cc: Stephen Rothwell <sfr@canb.auug.org.au> Cc: zhaimingbing <zhaimingbing@cmss.chinamobile.com> Cc: Howard Chu <howardchu95@gmail.com> Cc: Ze Gao <zegao2021@gmail.com> Cc: Weilin Wang <weilin.wang@intel.com> Cc: James Clark <james.clark@linaro.org> Cc: Leo Yan <leo.yan@linux.dev> Cc: Thomas Richter <tmricht@linux.ibm.com> Cc: Veronika Molnarova <vmolnaro@redhat.com> Link: https://lore.kernel.org/r/20241015000158.871828-4-irogers@google.com Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Diffstat (limited to 'tools/perf/tests/shell')
-rwxr-xr-xtools/perf/tests/shell/attr.sh2
-rw-r--r--tools/perf/tests/shell/attr/README71
-rw-r--r--tools/perf/tests/shell/attr/base-record41
-rw-r--r--tools/perf/tests/shell/attr/base-record-spe40
-rw-r--r--tools/perf/tests/shell/attr/base-stat41
-rw-r--r--tools/perf/tests/shell/attr/system-wide-dummy52
-rw-r--r--tools/perf/tests/shell/attr/test-record-C024
-rw-r--r--tools/perf/tests/shell/attr/test-record-basic6
-rw-r--r--tools/perf/tests/shell/attr/test-record-branch-any8
-rw-r--r--tools/perf/tests/shell/attr/test-record-branch-filter-any8
-rw-r--r--tools/perf/tests/shell/attr/test-record-branch-filter-any_call8
-rw-r--r--tools/perf/tests/shell/attr/test-record-branch-filter-any_ret8
-rw-r--r--tools/perf/tests/shell/attr/test-record-branch-filter-hv8
-rw-r--r--tools/perf/tests/shell/attr/test-record-branch-filter-ind_call8
-rw-r--r--tools/perf/tests/shell/attr/test-record-branch-filter-k8
-rw-r--r--tools/perf/tests/shell/attr/test-record-branch-filter-u8
-rw-r--r--tools/perf/tests/shell/attr/test-record-count9
-rw-r--r--tools/perf/tests/shell/attr/test-record-data10
-rw-r--r--tools/perf/tests/shell/attr/test-record-dummy-C055
-rw-r--r--tools/perf/tests/shell/attr/test-record-freq7
-rw-r--r--tools/perf/tests/shell/attr/test-record-graph-default9
-rw-r--r--tools/perf/tests/shell/attr/test-record-graph-default-aarch649
-rw-r--r--tools/perf/tests/shell/attr/test-record-graph-dwarf12
-rw-r--r--tools/perf/tests/shell/attr/test-record-graph-fp9
-rw-r--r--tools/perf/tests/shell/attr/test-record-graph-fp-aarch649
-rw-r--r--tools/perf/tests/shell/attr/test-record-group-sampling40
-rw-r--r--tools/perf/tests/shell/attr/test-record-group-sampling150
-rw-r--r--tools/perf/tests/shell/attr/test-record-group-sampling261
-rw-r--r--tools/perf/tests/shell/attr/test-record-group123
-rw-r--r--tools/perf/tests/shell/attr/test-record-group230
-rw-r--r--tools/perf/tests/shell/attr/test-record-group331
-rw-r--r--tools/perf/tests/shell/attr/test-record-no-buffering9
-rw-r--r--tools/perf/tests/shell/attr/test-record-no-inherit8
-rw-r--r--tools/perf/tests/shell/attr/test-record-no-samples7
-rw-r--r--tools/perf/tests/shell/attr/test-record-period8
-rw-r--r--tools/perf/tests/shell/attr/test-record-pfm-period9
-rw-r--r--tools/perf/tests/shell/attr/test-record-raw7
-rw-r--r--tools/perf/tests/shell/attr/test-record-spe-period12
-rw-r--r--tools/perf/tests/shell/attr/test-record-spe-period-term12
-rw-r--r--tools/perf/tests/shell/attr/test-record-spe-physical-address12
-rw-r--r--tools/perf/tests/shell/attr/test-record-user-regs-no-sve-aarch649
-rw-r--r--tools/perf/tests/shell/attr/test-record-user-regs-old-sve-aarch6410
-rw-r--r--tools/perf/tests/shell/attr/test-record-user-regs-sve-aarch6414
-rw-r--r--tools/perf/tests/shell/attr/test-stat-C010
-rw-r--r--tools/perf/tests/shell/attr/test-stat-basic7
-rw-r--r--tools/perf/tests/shell/attr/test-stat-default229
-rw-r--r--tools/perf/tests/shell/attr/test-stat-detailed-1271
-rw-r--r--tools/perf/tests/shell/attr/test-stat-detailed-2331
-rw-r--r--tools/perf/tests/shell/attr/test-stat-detailed-3351
-rw-r--r--tools/perf/tests/shell/attr/test-stat-group117
-rw-r--r--tools/perf/tests/shell/attr/test-stat-no-inherit8
-rw-r--r--tools/perf/tests/shell/lib/attr.py476
52 files changed, 2521 insertions, 1 deletions
diff --git a/tools/perf/tests/shell/attr.sh b/tools/perf/tests/shell/attr.sh
index e094f3baffb7..5a4e43b2471d 100755
--- a/tools/perf/tests/shell/attr.sh
+++ b/tools/perf/tests/shell/attr.sh
@@ -17,6 +17,6 @@ trap trap_cleanup EXIT TERM INT
shelldir=$(dirname "$0")
perf_path=$(which perf)
-python "${shelldir}"/../attr.py -d "${shelldir}"/../attr -v -p "$perf_path"
+python "${shelldir}"/lib/attr.py -d "${shelldir}"/attr -v -p "$perf_path"
cleanup
exit $err
diff --git a/tools/perf/tests/shell/attr/README b/tools/perf/tests/shell/attr/README
new file mode 100644
index 000000000000..67c4ca76b85d
--- /dev/null
+++ b/tools/perf/tests/shell/attr/README
@@ -0,0 +1,71 @@
+The struct perf_event_attr test (attr tests) support
+====================================================
+This testing support is embedded into perf directly and is governed
+by the PERF_TEST_ATTR environment variable and hook inside the
+sys_perf_event_open function.
+
+The general idea is to store 'struct perf_event_attr' details for
+each event created within single perf command. Each event details
+are stored into separate text file. Once perf command is finished
+these files are checked for values we expect for command.
+
+The attr tests consist of following parts:
+
+tests/attr.c
+------------
+This is the sys_perf_event_open hook implementation. The hook
+is triggered when the PERF_TEST_ATTR environment variable is
+defined. It must contain name of existing directory with access
+and write permissions.
+
+For each sys_perf_event_open call event details are stored in
+separate file. Besides 'struct perf_event_attr' values we also
+store 'fd' and 'group_fd' values to allow checking for groups.
+
+tests/attr.py
+-------------
+This is the python script that does all the hard work. It reads
+the test definition, executes it and checks results.
+
+tests/attr/
+-----------
+Directory containing all attr test definitions.
+Following tests are defined (with perf commands):
+
+ perf record kill (test-record-basic)
+ perf record -b kill (test-record-branch-any)
+ perf record -j any kill (test-record-branch-filter-any)
+ perf record -j any_call kill (test-record-branch-filter-any_call)
+ perf record -j any_ret kill (test-record-branch-filter-any_ret)
+ perf record -j hv kill (test-record-branch-filter-hv)
+ perf record -j ind_call kill (test-record-branch-filter-ind_call)
+ perf record -j k kill (test-record-branch-filter-k)
+ perf record -j u kill (test-record-branch-filter-u)
+ perf record -c 123 kill (test-record-count)
+ perf record -d kill (test-record-data)
+ perf record -F 100 kill (test-record-freq)
+ perf record -g kill (test-record-graph-default)
+ perf record -g kill (test-record-graph-default-aarch64)
+ perf record --call-graph dwarf kill (test-record-graph-dwarf)
+ perf record --call-graph fp kill (test-record-graph-fp)
+ perf record --call-graph fp kill (test-record-graph-fp-aarch64)
+ perf record -e '{cycles,instructions}' kill (test-record-group1)
+ perf record -e '{cycles/period=1/,instructions/period=2/}:S' kill (test-record-group2)
+ perf record -e '{cycles,cache-misses}:S' kill (test-record-group-sampling1)
+ perf record -c 10000 -e '{cycles,cache-misses}:S' kill (test-record-group-sampling2)
+ perf record -D kill (test-record-no-delay)
+ perf record -i kill (test-record-no-inherit)
+ perf record -n kill (test-record-no-samples)
+ perf record -c 100 -P kill (test-record-period)
+ perf record -c 1 --pfm-events=cycles:period=2 (test-record-pfm-period)
+ perf record -R kill (test-record-raw)
+ perf record -c 2 -e arm_spe_0// -- kill (test-record-spe-period)
+ perf record -e arm_spe_0/period=3/ -- kill (test-record-spe-period-term)
+ perf record -e arm_spe_0/pa_enable=1/ -- kill (test-record-spe-physical-address)
+ perf stat -e cycles kill (test-stat-basic)
+ perf stat kill (test-stat-default)
+ perf stat -d kill (test-stat-detailed-1)
+ perf stat -dd kill (test-stat-detailed-2)
+ perf stat -ddd kill (test-stat-detailed-3)
+ perf stat -e '{cycles,instructions}' kill (test-stat-group1)
+ perf stat -i -e cycles kill (test-stat-no-inherit)
diff --git a/tools/perf/tests/shell/attr/base-record b/tools/perf/tests/shell/attr/base-record
new file mode 100644
index 000000000000..b44e4e6e4443
--- /dev/null
+++ b/tools/perf/tests/shell/attr/base-record
@@ -0,0 +1,41 @@
+[event]
+fd=1
+group_fd=-1
+# 0 or PERF_FLAG_FD_CLOEXEC flag
+flags=0|8
+cpu=*
+type=0|1
+size=136
+config=0|1
+sample_period=*
+sample_type=263
+read_format=0|4|20
+disabled=1
+inherit=1
+pinned=0
+exclusive=0
+exclude_user=0
+exclude_kernel=0|1
+exclude_hv=0|1
+exclude_idle=0
+mmap=1
+comm=1
+freq=1
+inherit_stat=0
+enable_on_exec=1
+task=1
+watermark=0
+precise_ip=0|1|2|3
+mmap_data=0
+sample_id_all=1
+exclude_host=0|1
+exclude_guest=0|1
+exclude_callchain_kernel=0
+exclude_callchain_user=0
+wakeup_events=0
+bp_type=0
+config1=0
+config2=0
+branch_sample_type=0
+sample_regs_user=0
+sample_stack_user=0
diff --git a/tools/perf/tests/shell/attr/base-record-spe b/tools/perf/tests/shell/attr/base-record-spe
new file mode 100644
index 000000000000..08fa96b59240
--- /dev/null
+++ b/tools/perf/tests/shell/attr/base-record-spe
@@ -0,0 +1,40 @@
+[event]
+fd=*
+group_fd=-1
+flags=*
+cpu=*
+type=*
+size=*
+config=*
+sample_period=*
+sample_type=*
+read_format=*
+disabled=*
+inherit=*
+pinned=*
+exclusive=*
+exclude_user=*
+exclude_kernel=*
+exclude_hv=*
+exclude_idle=*
+mmap=*
+comm=*
+freq=*
+inherit_stat=*
+enable_on_exec=*
+task=*
+watermark=*
+precise_ip=*
+mmap_data=*
+sample_id_all=*
+exclude_host=*
+exclude_guest=*
+exclude_callchain_kernel=*
+exclude_callchain_user=*
+wakeup_events=*
+bp_type=*
+config1=*
+config2=*
+branch_sample_type=*
+sample_regs_user=*
+sample_stack_user=*
diff --git a/tools/perf/tests/shell/attr/base-stat b/tools/perf/tests/shell/attr/base-stat
new file mode 100644
index 000000000000..fccd8ec4d1b0
--- /dev/null
+++ b/tools/perf/tests/shell/attr/base-stat
@@ -0,0 +1,41 @@
+[event]
+fd=1
+group_fd=-1
+# 0 or PERF_FLAG_FD_CLOEXEC flag
+flags=0|8
+cpu=*
+type=0
+size=136
+config=0
+sample_period=0
+sample_type=65536
+read_format=3
+disabled=1
+inherit=1
+pinned=0
+exclusive=0
+exclude_user=0
+exclude_kernel=0|1
+exclude_hv=0|1
+exclude_idle=0
+mmap=0
+comm=0
+freq=0
+inherit_stat=0
+enable_on_exec=1
+task=0
+watermark=0
+precise_ip=0
+mmap_data=0
+sample_id_all=0
+exclude_host=0|1
+exclude_guest=0|1
+exclude_callchain_kernel=0
+exclude_callchain_user=0
+wakeup_events=0
+bp_type=0
+config1=0
+config2=0
+branch_sample_type=0
+sample_regs_user=0
+sample_stack_user=0
diff --git a/tools/perf/tests/shell/attr/system-wide-dummy b/tools/perf/tests/shell/attr/system-wide-dummy
new file mode 100644
index 000000000000..a1e1d6a263bf
--- /dev/null
+++ b/tools/perf/tests/shell/attr/system-wide-dummy
@@ -0,0 +1,52 @@
+# Event added by system-wide or CPU perf-record to handle the race of
+# processes starting while /proc is processed.
+[event]
+fd=1
+group_fd=-1
+cpu=*
+pid=-1
+flags=8
+type=1
+size=136
+config=9
+sample_period=1
+# PERF_SAMPLE_IP | PERF_SAMPLE_TID | PERF_SAMPLE_TIME |
+# PERF_SAMPLE_CPU | PERF_SAMPLE_IDENTIFIER
+sample_type=65671
+read_format=4|20
+# Event will be enabled right away.
+disabled=0
+inherit=1
+pinned=0
+exclusive=0
+exclude_user=0
+exclude_kernel=1
+exclude_hv=1
+exclude_idle=0
+mmap=1
+comm=1
+freq=0
+inherit_stat=0
+enable_on_exec=0
+task=1
+watermark=0
+precise_ip=0
+mmap_data=0
+sample_id_all=1
+exclude_host=0
+exclude_guest=1
+exclude_callchain_kernel=0
+exclude_callchain_user=0
+mmap2=1
+comm_exec=1
+context_switch=0
+write_backward=0
+namespaces=0
+use_clockid=0
+wakeup_events=0
+bp_type=0
+config1=0
+config2=0
+branch_sample_type=0
+sample_regs_user=0
+sample_stack_user=0
diff --git a/tools/perf/tests/shell/attr/test-record-C0 b/tools/perf/tests/shell/attr/test-record-C0
new file mode 100644
index 000000000000..1049ac8b52f2
--- /dev/null
+++ b/tools/perf/tests/shell/attr/test-record-C0
@@ -0,0 +1,24 @@
+[config]
+command = record
+args = --no-bpf-event -C 0 kill >/dev/null 2>&1
+ret = 1
+
+[event:base-record]
+cpu=0
+
+# no enable on exec for CPU attached
+enable_on_exec=0
+
+# PERF_SAMPLE_IP | PERF_SAMPLE_TID | PERF_SAMPLE_TIME |
+# PERF_SAMPLE_PERIOD | PERF_SAMPLE_IDENTIFIER
+# + PERF_SAMPLE_CPU added by -C 0
+sample_type=65927
+
+# Dummy event handles mmaps, comm and task.
+mmap=0
+comm=0
+task=0
+inherit=0
+
+[event:system-wide-dummy]
+inherit=0
diff --git a/tools/perf/tests/shell/attr/test-record-basic b/tools/perf/tests/shell/attr/test-record-basic
new file mode 100644
index 000000000000..b0ca42a5ecc9
--- /dev/null
+++ b/tools/perf/tests/shell/attr/test-record-basic
@@ -0,0 +1,6 @@
+[config]
+command = record
+args = --no-bpf-event kill >/dev/null 2>&1
+ret = 1
+
+[event:base-record]
diff --git a/tools/perf/tests/shell/attr/test-record-branch-any b/tools/perf/tests/shell/attr/test-record-branch-any
new file mode 100644
index 000000000000..1a99b3ce6b89
--- /dev/null
+++ b/tools/perf/tests/shell/attr/test-record-branch-any
@@ -0,0 +1,8 @@
+[config]
+command = record
+args = --no-bpf-event -b kill >/dev/null 2>&1
+ret = 1
+
+[event:base-record]
+sample_type=2311
+branch_sample_type=8
diff --git a/tools/perf/tests/shell/attr/test-record-branch-filter-any b/tools/perf/tests/shell/attr/test-record-branch-filter-any
new file mode 100644
index 000000000000..709768b508c6
--- /dev/null
+++ b/tools/perf/tests/shell/attr/test-record-branch-filter-any
@@ -0,0 +1,8 @@
+[config]
+command = record
+args = --no-bpf-event -j any kill >/dev/null 2>&1
+ret = 1
+
+[event:base-record]
+sample_type=2311
+branch_sample_type=8
diff --git a/tools/perf/tests/shell/attr/test-record-branch-filter-any_call b/tools/perf/tests/shell/attr/test-record-branch-filter-any_call
new file mode 100644
index 000000000000..f943221f7825
--- /dev/null
+++ b/tools/perf/tests/shell/attr/test-record-branch-filter-any_call
@@ -0,0 +1,8 @@
+[config]
+command = record
+args = --no-bpf-event -j any_call kill >/dev/null 2>&1
+ret = 1
+
+[event:base-record]
+sample_type=2311
+branch_sample_type=16
diff --git a/tools/perf/tests/shell/attr/test-record-branch-filter-any_ret b/tools/perf/tests/shell/attr/test-record-branch-filter-any_ret
new file mode 100644
index 000000000000..fd4f5b4154a9
--- /dev/null
+++ b/tools/perf/tests/shell/attr/test-record-branch-filter-any_ret
@@ -0,0 +1,8 @@
+[config]
+command = record
+args = --no-bpf-event -j any_ret kill >/dev/null 2>&1
+ret = 1
+
+[event:base-record]
+sample_type=2311
+branch_sample_type=32
diff --git a/tools/perf/tests/shell/attr/test-record-branch-filter-hv b/tools/perf/tests/shell/attr/test-record-branch-filter-hv
new file mode 100644
index 000000000000..4e52d685ebe1
--- /dev/null
+++ b/tools/perf/tests/shell/attr/test-record-branch-filter-hv
@@ -0,0 +1,8 @@
+[config]
+command = record
+args = --no-bpf-event -j hv kill >/dev/null 2>&1
+ret = 1
+
+[event:base-record]
+sample_type=2311
+branch_sample_type=8
diff --git a/tools/perf/tests/shell/attr/test-record-branch-filter-ind_call b/tools/perf/tests/shell/attr/test-record-branch-filter-ind_call
new file mode 100644
index 000000000000..e08c6ab3796e
--- /dev/null
+++ b/tools/perf/tests/shell/attr/test-record-branch-filter-ind_call
@@ -0,0 +1,8 @@
+[config]
+command = record
+args = --no-bpf-event -j ind_call kill >/dev/null 2>&1
+ret = 1
+
+[event:base-record]
+sample_type=2311
+branch_sample_type=64
diff --git a/tools/perf/tests/shell/attr/test-record-branch-filter-k b/tools/perf/tests/shell/attr/test-record-branch-filter-k
new file mode 100644
index 000000000000..b4b98f84fc2f
--- /dev/null
+++ b/tools/perf/tests/shell/attr/test-record-branch-filter-k
@@ -0,0 +1,8 @@
+[config]
+command = record
+args = --no-bpf-event -j k kill >/dev/null 2>&1
+ret = 1
+
+[event:base-record]
+sample_type=2311
+branch_sample_type=8
diff --git a/tools/perf/tests/shell/attr/test-record-branch-filter-u b/tools/perf/tests/shell/attr/test-record-branch-filter-u
new file mode 100644
index 000000000000..fb9610edbb0d
--- /dev/null
+++ b/tools/perf/tests/shell/attr/test-record-branch-filter-u
@@ -0,0 +1,8 @@
+[config]
+command = record
+args = --no-bpf-event -j u kill >/dev/null 2>&1
+ret = 1
+
+[event:base-record]
+sample_type=2311
+branch_sample_type=8
diff --git a/tools/perf/tests/shell/attr/test-record-count b/tools/perf/tests/shell/attr/test-record-count
new file mode 100644
index 000000000000..5e9b9019d786
--- /dev/null
+++ b/tools/perf/tests/shell/attr/test-record-count
@@ -0,0 +1,9 @@
+[config]
+command = record
+args = --no-bpf-event -c 123 kill >/dev/null 2>&1
+ret = 1
+
+[event:base-record]
+sample_period=123
+sample_type=7
+freq=0
diff --git a/tools/perf/tests/shell/attr/test-record-data b/tools/perf/tests/shell/attr/test-record-data
new file mode 100644
index 000000000000..a99bb13149c2
--- /dev/null
+++ b/tools/perf/tests/shell/attr/test-record-data
@@ -0,0 +1,10 @@
+[config]
+command = record
+args = --no-bpf-event -d kill >/dev/null 2>&1
+ret = 1
+
+[event:base-record]
+# sample_type = PERF_SAMPLE_IP | PERF_SAMPLE_TID | PERF_SAMPLE_TIME |
+# PERF_SAMPLE_ADDR | PERF_SAMPLE_PERIOD | PERF_SAMPLE_DATA_SRC
+sample_type=33039
+mmap_data=1
diff --git a/tools/perf/tests/shell/attr/test-record-dummy-C0 b/tools/perf/tests/shell/attr/test-record-dummy-C0
new file mode 100644
index 000000000000..3050298bd614
--- /dev/null
+++ b/tools/perf/tests/shell/attr/test-record-dummy-C0
@@ -0,0 +1,55 @@
+[config]
+command = record
+args = --no-bpf-event -e dummy -C 0 kill >/dev/null 2>&1
+ret = 1
+
+[event]
+fd=1
+group_fd=-1
+cpu=0
+pid=-1
+flags=8
+type=1
+size=136
+config=9
+sample_period=4000
+# PERF_SAMPLE_IP | PERF_SAMPLE_TID | PERF_SAMPLE_TIME |
+# PERF_SAMPLE_PERIOD
+# + PERF_SAMPLE_CPU added by -C 0
+sample_type=391
+read_format=4|20
+disabled=0
+inherit=0
+pinned=0
+exclusive=0
+exclude_user=0
+exclude_kernel=0
+exclude_hv=0
+exclude_idle=0
+mmap=1
+comm=1
+freq=1
+inherit_stat=0
+enable_on_exec=0
+task=1
+watermark=0
+precise_ip=0
+mmap_data=0
+sample_id_all=1
+exclude_host=0
+exclude_guest=1
+exclude_callchain_kernel=0
+exclude_callchain_user=0
+mmap2=1
+comm_exec=1
+context_switch=0
+write_backward=0
+namespaces=0
+use_clockid=0
+wakeup_events=0
+bp_type=0
+config1=0
+config2=0
+branch_sample_type=0
+sample_regs_user=0
+sample_stack_user=0
diff --git a/tools/perf/tests/shell/attr/test-record-freq b/tools/perf/tests/shell/attr/test-record-freq
new file mode 100644
index 000000000000..89e29f6b2ae0
--- /dev/null
+++ b/tools/perf/tests/shell/attr/test-record-freq
@@ -0,0 +1,7 @@
+[config]
+command = record
+args = --no-bpf-event -F 100 kill >/dev/null 2>&1
+ret = 1
+
+[event:base-record]
+sample_period=100
diff --git a/tools/perf/tests/shell/attr/test-record-graph-default b/tools/perf/tests/shell/attr/test-record-graph-default
new file mode 100644
index 000000000000..f0a18b4ea4f5
--- /dev/null
+++ b/tools/perf/tests/shell/attr/test-record-graph-default
@@ -0,0 +1,9 @@
+[config]
+command = record
+args = --no-bpf-event -g kill >/dev/null 2>&1
+ret = 1
+# arm64 enables registers in the default mode (fp)
+arch = !aarch64
+
+[event:base-record]
+sample_type=295
diff --git a/tools/perf/tests/shell/attr/test-record-graph-default-aarch64 b/tools/perf/tests/shell/attr/test-record-graph-default-aarch64
new file mode 100644
index 000000000000..e98d62efb6f7
--- /dev/null
+++ b/tools/perf/tests/shell/attr/test-record-graph-default-aarch64
@@ -0,0 +1,9 @@
+[config]
+command = record
+args = --no-bpf-event -g kill >/dev/null 2>&1
+ret = 1
+arch = aarch64
+
+[event:base-record]
+sample_type=4391
+sample_regs_user=1073741824
diff --git a/tools/perf/tests/shell/attr/test-record-graph-dwarf b/tools/perf/tests/shell/attr/test-record-graph-dwarf
new file mode 100644
index 000000000000..ae92061d611d
--- /dev/null
+++ b/tools/perf/tests/shell/attr/test-record-graph-dwarf
@@ -0,0 +1,12 @@
+[config]
+command = record
+args = --no-bpf-event --call-graph dwarf -- kill >/dev/null 2>&1
+ret = 1
+
+[event:base-record]
+sample_type=45359
+exclude_callchain_user=1
+sample_stack_user=8192
+# TODO different for each arch, no support for that now
+sample_regs_user=*
+mmap_data=1
diff --git a/tools/perf/tests/shell/attr/test-record-graph-fp b/tools/perf/tests/shell/attr/test-record-graph-fp
new file mode 100644
index 000000000000..a6e60e839205
--- /dev/null
+++ b/tools/perf/tests/shell/attr/test-record-graph-fp
@@ -0,0 +1,9 @@
+[config]
+command = record
+args = --no-bpf-event --call-graph fp kill >/dev/null 2>&1
+ret = 1
+# arm64 enables registers in fp mode
+arch = !aarch64
+
+[event:base-record]
+sample_type=295
diff --git a/tools/perf/tests/shell/attr/test-record-graph-fp-aarch64 b/tools/perf/tests/shell/attr/test-record-graph-fp-aarch64
new file mode 100644
index 000000000000..cbeea9971285
--- /dev/null
+++ b/tools/perf/tests/shell/attr/test-record-graph-fp-aarch64
@@ -0,0 +1,9 @@
+[config]
+command = record
+args = --no-bpf-event --call-graph fp kill >/dev/null 2>&1
+ret = 1
+arch = aarch64
+
+[event:base-record]
+sample_type=4391
+sample_regs_user=1073741824
diff --git a/tools/perf/tests/shell/attr/test-record-group-sampling b/tools/perf/tests/shell/attr/test-record-group-sampling
new file mode 100644
index 000000000000..86a940d7895d
--- /dev/null
+++ b/tools/perf/tests/shell/attr/test-record-group-sampling
@@ -0,0 +1,40 @@
+[config]
+command = record
+args = --no-bpf-event -e '{cycles,cache-misses}:S' kill >/dev/null 2>&1
+ret = 1
+kernel_until = 6.12
+
+[event-1:base-record]
+fd=1
+group_fd=-1
+sample_type=343
+read_format=12|28
+inherit=0
+
+[event-2:base-record]
+fd=2
+group_fd=1
+
+# cache-misses
+type=0
+config=3
+
+# default | PERF_SAMPLE_READ | PERF_SAMPLE_PERIOD
+sample_type=343
+
+# PERF_FORMAT_ID | PERF_FORMAT_GROUP | PERF_FORMAT_LOST
+read_format=12|28
+task=0
+mmap=0
+comm=0
+enable_on_exec=0
+disabled=0
+
+# inherit is disabled for group sampling
+inherit=0
+
+# sampling disabled
+sample_freq=0
+sample_period=0
+freq=0
+write_backward=0
diff --git a/tools/perf/tests/shell/attr/test-record-group-sampling1 b/tools/perf/tests/shell/attr/test-record-group-sampling1
new file mode 100644
index 000000000000..4748ab7bf684
--- /dev/null
+++ b/tools/perf/tests/shell/attr/test-record-group-sampling1
@@ -0,0 +1,50 @@
+[config]
+command = record
+args = --no-bpf-event -e '{cycles,cache-misses}:S' kill >/dev/null 2>&1
+ret = 1
+kernel_since = 6.12
+
+[event-1:base-record]
+fd=1
+group_fd=-1
+
+# cycles
+type=0
+config=0
+
+# default | PERF_SAMPLE_READ | PERF_SAMPLE_PERIOD
+sample_type=343
+
+# PERF_FORMAT_ID | PERF_FORMAT_GROUP | PERF_FORMAT_LOST | PERF_FORMAT_TOTAL_TIME_ENABLED | PERF_FORMAT_TOTAL_TIME_RUNNING
+read_format=28|31
+task=1
+mmap=1
+comm=1
+enable_on_exec=1
+disabled=1
+
+# inherit is enabled for group sampling
+inherit=1
+
+[event-2:base-record]
+fd=2
+group_fd=1
+
+# cache-misses
+type=0
+config=3
+
+# default | PERF_SAMPLE_READ | PERF_SAMPLE_PERIOD
+sample_type=343
+
+# PERF_FORMAT_ID | PERF_FORMAT_GROUP | PERF_FORMAT_LOST | PERF_FORMAT_TOTAL_TIME_ENABLED | PERF_FORMAT_TOTAL_TIME_RUNNING
+read_format=28|31
+task=0
+mmap=0
+comm=0
+enable_on_exec=0
+disabled=0
+freq=0
+
+# inherit is enabled for group sampling
+inherit=1
diff --git a/tools/perf/tests/shell/attr/test-record-group-sampling2 b/tools/perf/tests/shell/attr/test-record-group-sampling2
new file mode 100644
index 000000000000..e0432244a0eb
--- /dev/null
+++ b/tools/perf/tests/shell/attr/test-record-group-sampling2
@@ -0,0 +1,61 @@
+[config]
+command = record
+args = --no-bpf-event -c 10000 -e '{cycles,cache-misses}:S' kill >/dev/null 2>&1
+ret = 1
+kernel_since = 6.12
+
+[event-1:base-record]
+fd=1
+group_fd=-1
+
+# cycles
+type=0
+config=0
+
+# default | PERF_SAMPLE_READ
+sample_type=87
+
+# PERF_FORMAT_ID | PERF_FORMAT_GROUP | PERF_FORMAT_LOST | PERF_FORMAT_TOTAL_TIME_ENABLED | PERF_FORMAT_TOTAL_TIME_RUNNING
+read_format=28|31
+task=1
+mmap=1
+comm=1
+enable_on_exec=1
+disabled=1
+
+# inherit is enabled for group sampling
+inherit=1
+
+# sampling disabled
+sample_freq=0
+sample_period=10000
+freq=0
+write_backward=0
+
+[event-2:base-record]
+fd=2
+group_fd=1
+
+# cache-misses
+type=0
+config=3
+
+# default | PERF_SAMPLE_READ
+sample_type=87
+
+# PERF_FORMAT_ID | PERF_FORMAT_GROUP | PERF_FORMAT_LOST | PERF_FORMAT_TOTAL_TIME_ENABLED | PERF_FORMAT_TOTAL_TIME_RUNNING
+read_format=28|31
+task=0
+mmap=0
+comm=0
+enable_on_exec=0
+disabled=0
+
+# inherit is enabled for group sampling
+inherit=1
+
+# sampling disabled
+sample_freq=0
+sample_period=0
+freq=0
+write_backward=0
diff --git a/tools/perf/tests/shell/attr/test-record-group1 b/tools/perf/tests/shell/attr/test-record-group1
new file mode 100644
index 000000000000..eeb1db392bc9
--- /dev/null
+++ b/tools/perf/tests/shell/attr/test-record-group1
@@ -0,0 +1,23 @@
+[config]
+command = record
+args = --no-bpf-event -e '{cycles,instructions}' kill >/dev/null 2>&1
+ret = 1
+
+[event-1:base-record]
+fd=1
+group_fd=-1
+sample_type=327
+read_format=4|20
+
+[event-2:base-record]
+fd=2
+group_fd=1
+type=0
+config=1
+sample_type=327
+read_format=4|20
+mmap=0
+comm=0
+task=0
+enable_on_exec=0
+disabled=0
diff --git a/tools/perf/tests/shell/attr/test-record-group2 b/tools/perf/tests/shell/attr/test-record-group2
new file mode 100644
index 000000000000..891d41a7bddf
--- /dev/null
+++ b/tools/perf/tests/shell/attr/test-record-group2
@@ -0,0 +1,30 @@
+[config]
+command = record
+args = --no-bpf-event -e '{cycles/period=1234000/,instructions/period=6789000/}:S' kill >/dev/null 2>&1
+ret = 1
+kernel_until = 6.12
+
+[event-1:base-record]
+fd=1
+group_fd=-1
+config=0|1
+sample_period=1234000
+sample_type=87
+read_format=12|28
+inherit=0
+freq=0
+
+[event-2:base-record]
+fd=2
+group_fd=1
+config=0|1
+sample_period=6789000
+sample_type=87
+read_format=12|28
+disabled=0
+inherit=0
+mmap=0
+comm=0
+freq=0
+enable_on_exec=0
+task=0
diff --git a/tools/perf/tests/shell/attr/test-record-group3 b/tools/perf/tests/shell/attr/test-record-group3
new file mode 100644
index 000000000000..249be884959e
--- /dev/null
+++ b/tools/perf/tests/shell/attr/test-record-group3
@@ -0,0 +1,31 @@
+[config]
+command = record
+args = --no-bpf-event -e '{cycles/period=1234000/,instructions/period=6789000/}:S' kill >/dev/null 2>&1
+ret = 1
+kernel_since = 6.12
+
+[event-1:base-record]
+fd=1
+group_fd=-1
+config=0|1
+sample_period=1234000
+sample_type=87
+read_format=28|31
+disabled=1
+inherit=1
+freq=0
+
+[event-2:base-record]
+fd=2
+group_fd=1
+config=0|1
+sample_period=6789000
+sample_type=87
+read_format=28|31
+disabled=0
+inherit=1
+mmap=0
+comm=0
+freq=0
+enable_on_exec=0
+task=0
diff --git a/tools/perf/tests/shell/attr/test-record-no-buffering b/tools/perf/tests/shell/attr/test-record-no-buffering
new file mode 100644
index 000000000000..583dcbb078ba
--- /dev/null
+++ b/tools/perf/tests/shell/attr/test-record-no-buffering
@@ -0,0 +1,9 @@
+[config]
+command = record
+args = --no-bpf-event --no-buffering kill >/dev/null 2>&1
+ret = 1
+
+[event:base-record]
+sample_type=263
+watermark=0
+wakeup_events=1
diff --git a/tools/perf/tests/shell/attr/test-record-no-inherit b/tools/perf/tests/shell/attr/test-record-no-inherit
new file mode 100644
index 000000000000..15d1dc162e1c
--- /dev/null
+++ b/tools/perf/tests/shell/attr/test-record-no-inherit
@@ -0,0 +1,8 @@
+[config]
+command = record
+args = --no-bpf-event -i kill >/dev/null 2>&1
+ret = 1
+
+[event:base-record]
+sample_type=263
+inherit=0
diff --git a/tools/perf/tests/shell/attr/test-record-no-samples b/tools/perf/tests/shell/attr/test-record-no-samples
new file mode 100644
index 000000000000..596fbd6d5a2c
--- /dev/null
+++ b/tools/perf/tests/shell/attr/test-record-no-samples
@@ -0,0 +1,7 @@
+[config]
+command = record
+args = --no-bpf-event -n kill >/dev/null 2>&1
+ret = 1
+
+[event:base-record]
+sample_period=0
diff --git a/tools/perf/tests/shell/attr/test-record-period b/tools/perf/tests/shell/attr/test-record-period
new file mode 100644
index 000000000000..119101154c5e
--- /dev/null
+++ b/tools/perf/tests/shell/attr/test-record-period
@@ -0,0 +1,8 @@
+[config]
+command = record
+args = --no-bpf-event -c 100 -P kill >/dev/null 2>&1
+ret = 1
+
+[event:base-record]
+sample_period=100
+freq=0
diff --git a/tools/perf/tests/shell/attr/test-record-pfm-period b/tools/perf/tests/shell/attr/test-record-pfm-period
new file mode 100644
index 000000000000..368f5b814094
--- /dev/null
+++ b/tools/perf/tests/shell/attr/test-record-pfm-period
@@ -0,0 +1,9 @@
+[config]
+command = record
+args = --no-bpf-event -c 10000 --pfm-events=cycles:period=77777 kill >/dev/null 2>&1
+ret = 1
+
+[event:base-record]
+sample_period=77777
+sample_type=7
+freq=0
diff --git a/tools/perf/tests/shell/attr/test-record-raw b/tools/perf/tests/shell/attr/test-record-raw
new file mode 100644
index 000000000000..13a5f7860c78
--- /dev/null
+++ b/tools/perf/tests/shell/attr/test-record-raw
@@ -0,0 +1,7 @@
+[config]
+command = record
+args = --no-bpf-event -R kill >/dev/null 2>&1
+ret = 1
+
+[event:base-record]
+sample_type=1415
diff --git a/tools/perf/tests/shell/attr/test-record-spe-period b/tools/perf/tests/shell/attr/test-record-spe-period
new file mode 100644
index 000000000000..75f8c9cd8e3f
--- /dev/null
+++ b/tools/perf/tests/shell/attr/test-record-spe-period
@@ -0,0 +1,12 @@
+[config]
+command = record
+args = --no-bpf-event -c 2 -e arm_spe_0// -- kill >/dev/null 2>&1
+ret = 1
+arch = aarch64
+
+[event-10:base-record-spe]
+sample_period=2
+freq=0
+
+# dummy event
+[event-1:base-record-spe]
diff --git a/tools/perf/tests/shell/attr/test-record-spe-period-term b/tools/perf/tests/shell/attr/test-record-spe-period-term
new file mode 100644
index 000000000000..8f60a4fec657
--- /dev/null
+++ b/tools/perf/tests/shell/attr/test-record-spe-period-term
@@ -0,0 +1,12 @@
+[config]
+command = record
+args = --no-bpf-event -e arm_spe_0/period=3/ -- kill >/dev/null 2>&1
+ret = 1
+arch = aarch64
+
+[event-10:base-record-spe]
+sample_period=3
+freq=0
+
+# dummy event
+[event-1:base-record-spe]
diff --git a/tools/perf/tests/shell/attr/test-record-spe-physical-address b/tools/perf/tests/shell/attr/test-record-spe-physical-address
new file mode 100644
index 000000000000..7ebcf5012ce3
--- /dev/null
+++ b/tools/perf/tests/shell/attr/test-record-spe-physical-address
@@ -0,0 +1,12 @@
+[config]
+command = record
+args = --no-bpf-event -e arm_spe_0/pa_enable=1/ -- kill >/dev/null 2>&1
+ret = 1
+arch = aarch64
+
+[event-10:base-record-spe]
+# 622727 is the decimal of IP|TID|TIME|CPU|IDENTIFIER|DATA_SRC|PHYS_ADDR
+sample_type=622727
+
+# dummy event
+[event-1:base-record-spe] \ No newline at end of file
diff --git a/tools/perf/tests/shell/attr/test-record-user-regs-no-sve-aarch64 b/tools/perf/tests/shell/attr/test-record-user-regs-no-sve-aarch64
new file mode 100644
index 000000000000..bed765450ca9
--- /dev/null
+++ b/tools/perf/tests/shell/attr/test-record-user-regs-no-sve-aarch64
@@ -0,0 +1,9 @@
+# Test that asking for VG fails if the system doesn't support SVE. This
+# applies both before and after the feature was added in 6.1
+[config]
+command = record
+args = --no-bpf-event --user-regs=vg kill >/dev/null 2>&1
+ret = 129
+test_ret = true
+arch = aarch64
+auxv = auxv["AT_HWCAP"] & 0x400000 == 0
diff --git a/tools/perf/tests/shell/attr/test-record-user-regs-old-sve-aarch64 b/tools/perf/tests/shell/attr/test-record-user-regs-old-sve-aarch64
new file mode 100644
index 000000000000..15ebfc3418e3
--- /dev/null
+++ b/tools/perf/tests/shell/attr/test-record-user-regs-old-sve-aarch64
@@ -0,0 +1,10 @@
+# Test that asking for VG always fails on old kernels because it was
+# added in 6.1. This applies to systems that either support or don't
+# support SVE.
+[config]
+command = record
+args = --no-bpf-event --user-regs=vg kill >/dev/null 2>&1
+ret = 129
+test_ret = true
+arch = aarch64
+kernel_until = 6.1
diff --git a/tools/perf/tests/shell/attr/test-record-user-regs-sve-aarch64 b/tools/perf/tests/shell/attr/test-record-user-regs-sve-aarch64
new file mode 100644
index 000000000000..a65113cd7311
--- /dev/null
+++ b/tools/perf/tests/shell/attr/test-record-user-regs-sve-aarch64
@@ -0,0 +1,14 @@
+# Test that asking for VG works if the system has SVE and after the
+# feature was added in 6.1
+[config]
+command = record
+args = --no-bpf-event --user-regs=vg kill >/dev/null 2>&1
+ret = 1
+test_ret = true
+arch = aarch64
+auxv = auxv["AT_HWCAP"] & 0x400000 == 0x400000
+kernel_since = 6.1
+
+[event:base-record]
+sample_type=4359
+sample_regs_user=70368744177664
diff --git a/tools/perf/tests/shell/attr/test-stat-C0 b/tools/perf/tests/shell/attr/test-stat-C0
new file mode 100644
index 000000000000..a2c76d10b2bb
--- /dev/null
+++ b/tools/perf/tests/shell/attr/test-stat-C0
@@ -0,0 +1,10 @@
+[config]
+command = stat
+args = -e cycles -C 0 kill >/dev/null 2>&1
+ret = 1
+
+[event:base-stat]
+# events are disabled by default when attached to cpu
+disabled=1
+enable_on_exec=0
+optional=1
diff --git a/tools/perf/tests/shell/attr/test-stat-basic b/tools/perf/tests/shell/attr/test-stat-basic
new file mode 100644
index 000000000000..69867d049fda
--- /dev/null
+++ b/tools/perf/tests/shell/attr/test-stat-basic
@@ -0,0 +1,7 @@
+[config]
+command = stat
+args = -e cycles kill >/dev/null 2>&1
+ret = 1
+
+[event:base-stat]
+optional=1
diff --git a/tools/perf/tests/shell/attr/test-stat-default b/tools/perf/tests/shell/attr/test-stat-default
new file mode 100644
index 000000000000..e47fb4944679
--- /dev/null
+++ b/tools/perf/tests/shell/attr/test-stat-default
@@ -0,0 +1,229 @@
+[config]
+command = stat
+args = kill >/dev/null 2>&1
+ret = 1
+
+# PERF_TYPE_SOFTWARE / PERF_COUNT_SW_TASK_CLOCK
+[event1:base-stat]
+fd=1
+type=1
+config=1
+
+# PERF_TYPE_SOFTWARE / PERF_COUNT_SW_CONTEXT_SWITCHES
+[event2:base-stat]
+fd=2
+type=1
+config=3
+
+# PERF_TYPE_SOFTWARE / PERF_COUNT_SW_CPU_MIGRATIONS
+[event3:base-stat]
+fd=3
+type=1
+config=4
+
+# PERF_TYPE_SOFTWARE / PERF_COUNT_SW_PAGE_FAULTS
+[event4:base-stat]
+fd=4
+type=1
+config=2
+
+# PERF_TYPE_HARDWARE / PERF_COUNT_HW_CPU_CYCLES
+[event5:base-stat]
+fd=5
+type=0
+config=0
+optional=1
+
+# PERF_TYPE_HARDWARE / PERF_COUNT_HW_STALLED_CYCLES_FRONTEND
+[event6:base-stat]
+fd=6
+type=0
+config=7
+optional=1
+# PERF_TYPE_HARDWARE / PERF_COUNT_HW_STALLED_CYCLES_BACKEND
+[event7:base-stat]
+fd=7
+type=0
+config=8
+optional=1
+
+# PERF_TYPE_HARDWARE / PERF_COUNT_HW_INSTRUCTIONS
+[event8:base-stat]
+fd=8
+type=0
+config=1
+optional=1
+
+# PERF_TYPE_HARDWARE / PERF_COUNT_HW_BRANCH_INSTRUCTIONS
+[event9:base-stat]
+fd=9
+type=0
+config=4
+optional=1
+
+# PERF_TYPE_HARDWARE / PERF_COUNT_HW_BRANCH_MISSES
+[event10:base-stat]
+fd=10
+type=0
+config=5
+optional=1
+
+# PERF_TYPE_RAW / slots (0x400)
+[event11:base-stat]
+fd=11
+group_fd=-1
+type=4
+config=1024
+read_format=15
+optional=1
+
+# PERF_TYPE_RAW / topdown-retiring (0x8000)
+[event12:base-stat]
+fd=12
+group_fd=11
+type=4
+config=32768
+disabled=0
+enable_on_exec=0
+read_format=15
+optional=1
+
+# PERF_TYPE_RAW / topdown-bad-spec (0x8100)
+[event13:base-stat]
+fd=13
+group_fd=11
+type=4
+config=33024
+disabled=0
+enable_on_exec=0
+read_format=15
+optional=1
+
+# PERF_TYPE_RAW / topdown-fe-bound (0x8200)
+[event14:base-stat]
+fd=14
+group_fd=11
+type=4
+config=33280
+disabled=0
+enable_on_exec=0
+read_format=15
+optional=1
+
+# PERF_TYPE_RAW / topdown-be-bound (0x8300)
+[event15:base-stat]
+fd=15
+group_fd=11
+type=4
+config=33536
+disabled=0
+enable_on_exec=0
+read_format=15
+optional=1
+
+# PERF_TYPE_RAW / topdown-heavy-ops (0x8400)
+[event16:base-stat]
+fd=16
+group_fd=11
+type=4
+config=33792
+disabled=0
+enable_on_exec=0
+read_format=15
+optional=1
+
+# PERF_TYPE_RAW / topdown-br-mispredict (0x8500)
+[event17:base-stat]
+fd=17
+group_fd=11
+type=4
+config=34048
+disabled=0
+enable_on_exec=0
+read_format=15
+optional=1
+
+# PERF_TYPE_RAW / topdown-fetch-lat (0x8600)
+[event18:base-stat]
+fd=18
+group_fd=11
+type=4
+config=34304
+disabled=0
+enable_on_exec=0
+read_format=15
+optional=1
+
+# PERF_TYPE_RAW / topdown-mem-bound (0x8700)
+[event19:base-stat]
+fd=19
+group_fd=11
+type=4
+config=34560
+disabled=0
+enable_on_exec=0
+read_format=15
+optional=1
+
+# PERF_TYPE_RAW / INT_MISC.UOP_DROPPING
+[event20:base-stat]
+fd=20
+type=4
+config=4109
+optional=1
+
+# PERF_TYPE_RAW / cpu/INT_MISC.RECOVERY_CYCLES,cmask=1,edge/
+[event21:base-stat]
+fd=21
+type=4
+config=17039629
+optional=1
+
+# PERF_TYPE_RAW / CPU_CLK_UNHALTED.THREAD
+[event22:base-stat]
+fd=22
+type=4
+config=60
+optional=1
+
+# PERF_TYPE_RAW / INT_MISC.RECOVERY_CYCLES_ANY
+[event23:base-stat]
+fd=23
+type=4
+config=2097421
+optional=1
+
+# PERF_TYPE_RAW / CPU_CLK_UNHALTED.REF_XCLK
+[event24:base-stat]
+fd=24
+type=4
+config=316
+optional=1
+
+# PERF_TYPE_RAW / IDQ_UOPS_NOT_DELIVERED.CORE
+[event25:base-stat]
+fd=25
+type=4
+config=412
+optional=1
+
+# PERF_TYPE_RAW / CPU_CLK_UNHALTED.ONE_THREAD_ACTIVE
+[event26:base-stat]
+fd=26
+type=4
+config=572
+optional=1
+
+# PERF_TYPE_RAW / UOPS_RETIRED.RETIRE_SLOTS
+[event27:base-stat]
+fd=27
+type=4
+config=706
+optional=1
+
+# PERF_TYPE_RAW / UOPS_ISSUED.ANY
+[event28:base-stat]
+fd=28
+type=4
+config=270
+optional=1
diff --git a/tools/perf/tests/shell/attr/test-stat-detailed-1 b/tools/perf/tests/shell/attr/test-stat-detailed-1
new file mode 100644
index 000000000000..3d500d3e0c5c
--- /dev/null
+++ b/tools/perf/tests/shell/attr/test-stat-detailed-1
@@ -0,0 +1,271 @@
+[config]
+command = stat
+args = -d kill >/dev/null 2>&1
+ret = 1
+
+
+# PERF_TYPE_SOFTWARE / PERF_COUNT_SW_TASK_CLOCK
+[event1:base-stat]
+fd=1
+type=1
+config=1
+
+# PERF_TYPE_SOFTWARE / PERF_COUNT_SW_CONTEXT_SWITCHES
+[event2:base-stat]
+fd=2
+type=1
+config=3
+
+# PERF_TYPE_SOFTWARE / PERF_COUNT_SW_CPU_MIGRATIONS
+[event3:base-stat]
+fd=3
+type=1
+config=4
+
+# PERF_TYPE_SOFTWARE / PERF_COUNT_SW_PAGE_FAULTS
+[event4:base-stat]
+fd=4
+type=1
+config=2
+
+# PERF_TYPE_HARDWARE / PERF_COUNT_HW_CPU_CYCLES
+[event5:base-stat]
+fd=5
+type=0
+config=0
+optional=1
+
+# PERF_TYPE_HARDWARE / PERF_COUNT_HW_STALLED_CYCLES_FRONTEND
+[event6:base-stat]
+fd=6
+type=0
+config=7
+optional=1
+
+# PERF_TYPE_HARDWARE / PERF_COUNT_HW_STALLED_CYCLES_BACKEND
+[event7:base-stat]
+fd=7
+type=0
+config=8
+optional=1
+
+# PERF_TYPE_HARDWARE / PERF_COUNT_HW_INSTRUCTIONS
+[event8:base-stat]
+fd=8
+type=0
+config=1
+optional=1
+
+# PERF_TYPE_HARDWARE / PERF_COUNT_HW_BRANCH_INSTRUCTIONS
+[event9:base-stat]
+fd=9
+type=0
+config=4
+optional=1
+
+# PERF_TYPE_HARDWARE / PERF_COUNT_HW_BRANCH_MISSES
+[event10:base-stat]
+fd=10
+type=0
+config=5
+optional=1
+
+# PERF_TYPE_RAW / slots (0x400)
+[event11:base-stat]
+fd=11
+group_fd=-1
+type=4
+config=1024
+read_format=15
+optional=1
+
+# PERF_TYPE_RAW / topdown-retiring (0x8000)
+[event12:base-stat]
+fd=12
+group_fd=11
+type=4
+config=32768
+disabled=0
+enable_on_exec=0
+read_format=15
+optional=1
+
+# PERF_TYPE_RAW / topdown-bad-spec (0x8100)
+[event13:base-stat]
+fd=13
+group_fd=11
+type=4
+config=33024
+disabled=0
+enable_on_exec=0
+read_format=15
+optional=1
+
+# PERF_TYPE_RAW / topdown-fe-bound (0x8200)
+[event14:base-stat]
+fd=14
+group_fd=11
+type=4
+config=33280
+disabled=0
+enable_on_exec=0
+read_format=15
+optional=1
+
+# PERF_TYPE_RAW / topdown-be-bound (0x8300)
+[event15:base-stat]
+fd=15
+group_fd=11
+type=4
+config=33536
+disabled=0
+enable_on_exec=0
+read_format=15
+optional=1
+
+# PERF_TYPE_RAW / topdown-heavy-ops (0x8400)
+[event16:base-stat]
+fd=16
+group_fd=11
+type=4
+config=33792
+disabled=0
+enable_on_exec=0
+read_format=15
+optional=1
+
+# PERF_TYPE_RAW / topdown-br-mispredict (0x8500)
+[event17:base-stat]
+fd=17
+group_fd=11
+type=4
+config=34048
+disabled=0
+enable_on_exec=0
+read_format=15
+optional=1
+
+# PERF_TYPE_RAW / topdown-fetch-lat (0x8600)
+[event18:base-stat]
+fd=18
+group_fd=11
+type=4
+config=34304
+disabled=0
+enable_on_exec=0
+read_format=15
+optional=1
+
+# PERF_TYPE_RAW / topdown-mem-bound (0x8700)
+[event19:base-stat]
+fd=19
+group_fd=11
+type=4
+config=34560
+disabled=0
+enable_on_exec=0
+read_format=15
+optional=1
+
+# PERF_TYPE_RAW / INT_MISC.UOP_DROPPING
+[event20:base-stat]
+fd=20
+type=4
+config=4109
+optional=1
+
+# PERF_TYPE_RAW / cpu/INT_MISC.RECOVERY_CYCLES,cmask=1,edge/
+[event21:base-stat]
+fd=21
+type=4
+config=17039629
+optional=1
+
+# PERF_TYPE_RAW / CPU_CLK_UNHALTED.THREAD
+[event22:base-stat]
+fd=22
+type=4
+config=60
+optional=1
+
+# PERF_TYPE_RAW / INT_MISC.RECOVERY_CYCLES_ANY
+[event23:base-stat]
+fd=23
+type=4
+config=2097421
+optional=1
+
+# PERF_TYPE_RAW / CPU_CLK_UNHALTED.REF_XCLK
+[event24:base-stat]
+fd=24
+type=4
+config=316
+optional=1
+
+# PERF_TYPE_RAW / IDQ_UOPS_NOT_DELIVERED.CORE
+[event25:base-stat]
+fd=25
+type=4
+config=412
+optional=1
+
+# PERF_TYPE_RAW / CPU_CLK_UNHALTED.ONE_THREAD_ACTIVE
+[event26:base-stat]
+fd=26
+type=4
+config=572
+optional=1
+
+# PERF_TYPE_RAW / UOPS_RETIRED.RETIRE_SLOTS
+[event27:base-stat]
+fd=27
+type=4
+config=706
+optional=1
+
+# PERF_TYPE_RAW / UOPS_ISSUED.ANY
+[event28:base-stat]
+fd=28
+type=4
+config=270
+optional=1
+
+# PERF_TYPE_HW_CACHE /
+# PERF_COUNT_HW_CACHE_L1D << 0 |
+# (PERF_COUNT_HW_CACHE_OP_READ << 8) |
+# (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)
+[event29:base-stat]
+fd=29
+type=3
+config=0
+optional=1
+
+# PERF_TYPE_HW_CACHE /
+# PERF_COUNT_HW_CACHE_L1D << 0 |
+# (PERF_COUNT_HW_CACHE_OP_READ << 8) |
+# (PERF_COUNT_HW_CACHE_RESULT_MISS << 16)
+[event30:base-stat]
+fd=30
+type=3
+config=65536
+optional=1
+
+# PERF_TYPE_HW_CACHE /
+# PERF_COUNT_HW_CACHE_LL << 0 |
+# (PERF_COUNT_HW_CACHE_OP_READ << 8) |
+# (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)
+[event31:base-stat]
+fd=31
+type=3
+config=2
+optional=1
+
+# PERF_TYPE_HW_CACHE,
+# PERF_COUNT_HW_CACHE_LL << 0 |
+# (PERF_COUNT_HW_CACHE_OP_READ << 8) |
+# (PERF_COUNT_HW_CACHE_RESULT_MISS << 16)
+[event32:base-stat]
+fd=32
+type=3
+config=65538
+optional=1
diff --git a/tools/perf/tests/shell/attr/test-stat-detailed-2 b/tools/perf/tests/shell/attr/test-stat-detailed-2
new file mode 100644
index 000000000000..01777a63752f
--- /dev/null
+++ b/tools/perf/tests/shell/attr/test-stat-detailed-2
@@ -0,0 +1,331 @@
+[config]
+command = stat
+args = -dd kill >/dev/null 2>&1
+ret = 1
+
+
+# PERF_TYPE_SOFTWARE / PERF_COUNT_SW_TASK_CLOCK
+[event1:base-stat]
+fd=1
+type=1
+config=1
+
+# PERF_TYPE_SOFTWARE / PERF_COUNT_SW_CONTEXT_SWITCHES
+[event2:base-stat]
+fd=2
+type=1
+config=3
+
+# PERF_TYPE_SOFTWARE / PERF_COUNT_SW_CPU_MIGRATIONS
+[event3:base-stat]
+fd=3
+type=1
+config=4
+
+# PERF_TYPE_SOFTWARE / PERF_COUNT_SW_PAGE_FAULTS
+[event4:base-stat]
+fd=4
+type=1
+config=2
+
+# PERF_TYPE_HARDWARE / PERF_COUNT_HW_CPU_CYCLES
+[event5:base-stat]
+fd=5
+type=0
+config=0
+optional=1
+
+# PERF_TYPE_HARDWARE / PERF_COUNT_HW_STALLED_CYCLES_FRONTEND
+[event6:base-stat]
+fd=6
+type=0
+config=7
+optional=1
+
+# PERF_TYPE_HARDWARE / PERF_COUNT_HW_STALLED_CYCLES_BACKEND
+[event7:base-stat]
+fd=7
+type=0
+config=8
+optional=1
+
+# PERF_TYPE_HARDWARE / PERF_COUNT_HW_INSTRUCTIONS
+[event8:base-stat]
+fd=8
+type=0
+config=1
+optional=1
+
+# PERF_TYPE_HARDWARE / PERF_COUNT_HW_BRANCH_INSTRUCTIONS
+[event9:base-stat]
+fd=9
+type=0
+config=4
+optional=1
+
+# PERF_TYPE_HARDWARE / PERF_COUNT_HW_BRANCH_MISSES
+[event10:base-stat]
+fd=10
+type=0
+config=5
+optional=1
+
+# PERF_TYPE_RAW / slots (0x400)
+[event11:base-stat]
+fd=11
+group_fd=-1
+type=4
+config=1024
+read_format=15
+optional=1
+
+# PERF_TYPE_RAW / topdown-retiring (0x8000)
+[event12:base-stat]
+fd=12
+group_fd=11
+type=4
+config=32768
+disabled=0
+enable_on_exec=0
+read_format=15
+optional=1
+
+# PERF_TYPE_RAW / topdown-bad-spec (0x8100)
+[event13:base-stat]
+fd=13
+group_fd=11
+type=4
+config=33024
+disabled=0
+enable_on_exec=0
+read_format=15
+optional=1
+
+# PERF_TYPE_RAW / topdown-fe-bound (0x8200)
+[event14:base-stat]
+fd=14
+group_fd=11
+type=4
+config=33280
+disabled=0
+enable_on_exec=0
+read_format=15
+optional=1
+
+# PERF_TYPE_RAW / topdown-be-bound (0x8300)
+[event15:base-stat]
+fd=15
+group_fd=11
+type=4
+config=33536
+disabled=0
+enable_on_exec=0
+read_format=15
+optional=1
+
+# PERF_TYPE_RAW / topdown-heavy-ops (0x8400)
+[event16:base-stat]
+fd=16
+group_fd=11
+type=4
+config=33792
+disabled=0
+enable_on_exec=0
+read_format=15
+optional=1
+
+# PERF_TYPE_RAW / topdown-br-mispredict (0x8500)
+[event17:base-stat]
+fd=17
+group_fd=11
+type=4
+config=34048
+disabled=0
+enable_on_exec=0
+read_format=15
+optional=1
+
+# PERF_TYPE_RAW / topdown-fetch-lat (0x8600)
+[event18:base-stat]
+fd=18
+group_fd=11
+type=4
+config=34304
+disabled=0
+enable_on_exec=0
+read_format=15
+optional=1
+
+# PERF_TYPE_RAW / topdown-mem-bound (0x8700)
+[event19:base-stat]
+fd=19
+group_fd=11
+type=4
+config=34560
+disabled=0
+enable_on_exec=0
+read_format=15
+optional=1
+
+# PERF_TYPE_RAW / INT_MISC.UOP_DROPPING
+[event20:base-stat]
+fd=20
+type=4
+config=4109
+optional=1
+
+# PERF_TYPE_RAW / cpu/INT_MISC.RECOVERY_CYCLES,cmask=1,edge/
+[event21:base-stat]
+fd=21
+type=4
+config=17039629
+optional=1
+
+# PERF_TYPE_RAW / CPU_CLK_UNHALTED.THREAD
+[event22:base-stat]
+fd=22
+type=4
+config=60
+optional=1
+
+# PERF_TYPE_RAW / INT_MISC.RECOVERY_CYCLES_ANY
+[event23:base-stat]
+fd=23
+type=4
+config=2097421
+optional=1
+
+# PERF_TYPE_RAW / CPU_CLK_UNHALTED.REF_XCLK
+[event24:base-stat]
+fd=24
+type=4
+config=316
+optional=1
+
+# PERF_TYPE_RAW / IDQ_UOPS_NOT_DELIVERED.CORE
+[event25:base-stat]
+fd=25
+type=4
+config=412
+optional=1
+
+# PERF_TYPE_RAW / CPU_CLK_UNHALTED.ONE_THREAD_ACTIVE
+[event26:base-stat]
+fd=26
+type=4
+config=572
+optional=1
+
+# PERF_TYPE_RAW / UOPS_RETIRED.RETIRE_SLOTS
+[event27:base-stat]
+fd=27
+type=4
+config=706
+optional=1
+
+# PERF_TYPE_RAW / UOPS_ISSUED.ANY
+[event28:base-stat]
+fd=28
+type=4
+config=270
+optional=1
+
+# PERF_TYPE_HW_CACHE /
+# PERF_COUNT_HW_CACHE_L1D << 0 |
+# (PERF_COUNT_HW_CACHE_OP_READ << 8) |
+# (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)
+[event29:base-stat]
+fd=29
+type=3
+config=0
+optional=1
+
+# PERF_TYPE_HW_CACHE /
+# PERF_COUNT_HW_CACHE_L1D << 0 |
+# (PERF_COUNT_HW_CACHE_OP_READ << 8) |
+# (PERF_COUNT_HW_CACHE_RESULT_MISS << 16)
+[event30:base-stat]
+fd=30
+type=3
+config=65536
+optional=1
+
+# PERF_TYPE_HW_CACHE /
+# PERF_COUNT_HW_CACHE_LL << 0 |
+# (PERF_COUNT_HW_CACHE_OP_READ << 8) |
+# (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)
+[event31:base-stat]
+fd=31
+type=3
+config=2
+optional=1
+
+# PERF_TYPE_HW_CACHE,
+# PERF_COUNT_HW_CACHE_LL << 0 |
+# (PERF_COUNT_HW_CACHE_OP_READ << 8) |
+# (PERF_COUNT_HW_CACHE_RESULT_MISS << 16)
+[event32:base-stat]
+fd=32
+type=3
+config=65538
+optional=1
+
+# PERF_TYPE_HW_CACHE,
+# PERF_COUNT_HW_CACHE_L1I << 0 |
+# (PERF_COUNT_HW_CACHE_OP_READ << 8) |
+# (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)
+[event33:base-stat]
+fd=33
+type=3
+config=1
+optional=1
+
+# PERF_TYPE_HW_CACHE,
+# PERF_COUNT_HW_CACHE_L1I << 0 |
+# (PERF_COUNT_HW_CACHE_OP_READ << 8) |
+# (PERF_COUNT_HW_CACHE_RESULT_MISS << 16)
+[event34:base-stat]
+fd=34
+type=3
+config=65537
+optional=1
+
+# PERF_TYPE_HW_CACHE,
+# PERF_COUNT_HW_CACHE_DTLB << 0 |
+# (PERF_COUNT_HW_CACHE_OP_READ << 8) |
+# (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)
+[event35:base-stat]
+fd=35
+type=3
+config=3
+optional=1
+
+# PERF_TYPE_HW_CACHE,
+# PERF_COUNT_HW_CACHE_DTLB << 0 |
+# (PERF_COUNT_HW_CACHE_OP_READ << 8) |
+# (PERF_COUNT_HW_CACHE_RESULT_MISS << 16)
+[event36:base-stat]
+fd=36
+type=3
+config=65539
+optional=1
+
+# PERF_TYPE_HW_CACHE,
+# PERF_COUNT_HW_CACHE_ITLB << 0 |
+# (PERF_COUNT_HW_CACHE_OP_READ << 8) |
+# (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)
+[event37:base-stat]
+fd=37
+type=3
+config=4
+optional=1
+
+# PERF_TYPE_HW_CACHE,
+# PERF_COUNT_HW_CACHE_ITLB << 0 |
+# (PERF_COUNT_HW_CACHE_OP_READ << 8) |
+# (PERF_COUNT_HW_CACHE_RESULT_MISS << 16)
+[event38:base-stat]
+fd=38
+type=3
+config=65540
+optional=1
diff --git a/tools/perf/tests/shell/attr/test-stat-detailed-3 b/tools/perf/tests/shell/attr/test-stat-detailed-3
new file mode 100644
index 000000000000..8400abd7e1e4
--- /dev/null
+++ b/tools/perf/tests/shell/attr/test-stat-detailed-3
@@ -0,0 +1,351 @@
+[config]
+command = stat
+args = -ddd kill >/dev/null 2>&1
+ret = 1
+
+
+# PERF_TYPE_SOFTWARE / PERF_COUNT_SW_TASK_CLOCK
+[event1:base-stat]
+fd=1
+type=1
+config=1
+
+# PERF_TYPE_SOFTWARE / PERF_COUNT_SW_CONTEXT_SWITCHES
+[event2:base-stat]
+fd=2
+type=1
+config=3
+
+# PERF_TYPE_SOFTWARE / PERF_COUNT_SW_CPU_MIGRATIONS
+[event3:base-stat]
+fd=3
+type=1
+config=4
+
+# PERF_TYPE_SOFTWARE / PERF_COUNT_SW_PAGE_FAULTS
+[event4:base-stat]
+fd=4
+type=1
+config=2
+
+# PERF_TYPE_HARDWARE / PERF_COUNT_HW_CPU_CYCLES
+[event5:base-stat]
+fd=5
+type=0
+config=0
+optional=1
+
+# PERF_TYPE_HARDWARE / PERF_COUNT_HW_STALLED_CYCLES_FRONTEND
+[event6:base-stat]
+fd=6
+type=0
+config=7
+optional=1
+
+# PERF_TYPE_HARDWARE / PERF_COUNT_HW_STALLED_CYCLES_BACKEND
+[event7:base-stat]
+fd=7
+type=0
+config=8
+optional=1
+
+# PERF_TYPE_HARDWARE / PERF_COUNT_HW_INSTRUCTIONS
+[event8:base-stat]
+fd=8
+type=0
+config=1
+optional=1
+
+# PERF_TYPE_HARDWARE / PERF_COUNT_HW_BRANCH_INSTRUCTIONS
+[event9:base-stat]
+fd=9
+type=0
+config=4
+optional=1
+
+# PERF_TYPE_HARDWARE / PERF_COUNT_HW_BRANCH_MISSES
+[event10:base-stat]
+fd=10
+type=0
+config=5
+optional=1
+
+# PERF_TYPE_RAW / slots (0x400)
+[event11:base-stat]
+fd=11
+group_fd=-1
+type=4
+config=1024
+read_format=15
+optional=1
+
+# PERF_TYPE_RAW / topdown-retiring (0x8000)
+[event12:base-stat]
+fd=12
+group_fd=11
+type=4
+config=32768
+disabled=0
+enable_on_exec=0
+read_format=15
+optional=1
+
+# PERF_TYPE_RAW / topdown-bad-spec (0x8100)
+[event13:base-stat]
+fd=13
+group_fd=11
+type=4
+config=33024
+disabled=0
+enable_on_exec=0
+read_format=15
+optional=1
+
+# PERF_TYPE_RAW / topdown-fe-bound (0x8200)
+[event14:base-stat]
+fd=14
+group_fd=11
+type=4
+config=33280
+disabled=0
+enable_on_exec=0
+read_format=15
+optional=1
+
+# PERF_TYPE_RAW / topdown-be-bound (0x8300)
+[event15:base-stat]
+fd=15
+group_fd=11
+type=4
+config=33536
+disabled=0
+enable_on_exec=0
+read_format=15
+optional=1
+
+# PERF_TYPE_RAW / topdown-heavy-ops (0x8400)
+[event16:base-stat]
+fd=16
+group_fd=11
+type=4
+config=33792
+disabled=0
+enable_on_exec=0
+read_format=15
+optional=1
+
+# PERF_TYPE_RAW / topdown-br-mispredict (0x8500)
+[event17:base-stat]
+fd=17
+group_fd=11
+type=4
+config=34048
+disabled=0
+enable_on_exec=0
+read_format=15
+optional=1
+
+# PERF_TYPE_RAW / topdown-fetch-lat (0x8600)
+[event18:base-stat]
+fd=18
+group_fd=11
+type=4
+config=34304
+disabled=0
+enable_on_exec=0
+read_format=15
+optional=1
+
+# PERF_TYPE_RAW / topdown-mem-bound (0x8700)
+[event19:base-stat]
+fd=19
+group_fd=11
+type=4
+config=34560
+disabled=0
+enable_on_exec=0
+read_format=15
+optional=1
+
+# PERF_TYPE_RAW / INT_MISC.UOP_DROPPING
+[event20:base-stat]
+fd=20
+type=4
+config=4109
+optional=1
+
+# PERF_TYPE_RAW / cpu/INT_MISC.RECOVERY_CYCLES,cmask=1,edge/
+[event21:base-stat]
+fd=21
+type=4
+config=17039629
+optional=1
+
+# PERF_TYPE_RAW / CPU_CLK_UNHALTED.THREAD
+[event22:base-stat]
+fd=22
+type=4
+config=60
+optional=1
+
+# PERF_TYPE_RAW / INT_MISC.RECOVERY_CYCLES_ANY
+[event23:base-stat]
+fd=23
+type=4
+config=2097421
+optional=1
+
+# PERF_TYPE_RAW / CPU_CLK_UNHALTED.REF_XCLK
+[event24:base-stat]
+fd=24
+type=4
+config=316
+optional=1
+
+# PERF_TYPE_RAW / IDQ_UOPS_NOT_DELIVERED.CORE
+[event25:base-stat]
+fd=25
+type=4
+config=412
+optional=1
+
+# PERF_TYPE_RAW / CPU_CLK_UNHALTED.ONE_THREAD_ACTIVE
+[event26:base-stat]
+fd=26
+type=4
+config=572
+optional=1
+
+# PERF_TYPE_RAW / UOPS_RETIRED.RETIRE_SLOTS
+[event27:base-stat]
+fd=27
+type=4
+config=706
+optional=1
+
+# PERF_TYPE_RAW / UOPS_ISSUED.ANY
+[event28:base-stat]
+fd=28
+type=4
+config=270
+optional=1
+
+# PERF_TYPE_HW_CACHE /
+# PERF_COUNT_HW_CACHE_L1D << 0 |
+# (PERF_COUNT_HW_CACHE_OP_READ << 8) |
+# (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)
+[event29:base-stat]
+fd=29
+type=3
+config=0
+optional=1
+
+# PERF_TYPE_HW_CACHE /
+# PERF_COUNT_HW_CACHE_L1D << 0 |
+# (PERF_COUNT_HW_CACHE_OP_READ << 8) |
+# (PERF_COUNT_HW_CACHE_RESULT_MISS << 16)
+[event30:base-stat]
+fd=30
+type=3
+config=65536
+optional=1
+
+# PERF_TYPE_HW_CACHE /
+# PERF_COUNT_HW_CACHE_LL << 0 |
+# (PERF_COUNT_HW_CACHE_OP_READ << 8) |
+# (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)
+[event31:base-stat]
+fd=31
+type=3
+config=2
+optional=1
+
+# PERF_TYPE_HW_CACHE,
+# PERF_COUNT_HW_CACHE_LL << 0 |
+# (PERF_COUNT_HW_CACHE_OP_READ << 8) |
+# (PERF_COUNT_HW_CACHE_RESULT_MISS << 16)
+[event32:base-stat]
+fd=32
+type=3
+config=65538
+optional=1
+
+# PERF_TYPE_HW_CACHE,
+# PERF_COUNT_HW_CACHE_L1I << 0 |
+# (PERF_COUNT_HW_CACHE_OP_READ << 8) |
+# (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)
+[event33:base-stat]
+fd=33
+type=3
+config=1
+optional=1
+
+# PERF_TYPE_HW_CACHE,
+# PERF_COUNT_HW_CACHE_L1I << 0 |
+# (PERF_COUNT_HW_CACHE_OP_READ << 8) |
+# (PERF_COUNT_HW_CACHE_RESULT_MISS << 16)
+[event34:base-stat]
+fd=34
+type=3
+config=65537
+optional=1
+
+# PERF_TYPE_HW_CACHE,
+# PERF_COUNT_HW_CACHE_DTLB << 0 |
+# (PERF_COUNT_HW_CACHE_OP_READ << 8) |
+# (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)
+[event35:base-stat]
+fd=35
+type=3
+config=3
+optional=1
+
+# PERF_TYPE_HW_CACHE,
+# PERF_COUNT_HW_CACHE_DTLB << 0 |
+# (PERF_COUNT_HW_CACHE_OP_READ << 8) |
+# (PERF_COUNT_HW_CACHE_RESULT_MISS << 16)
+[event36:base-stat]
+fd=36
+type=3
+config=65539
+optional=1
+
+# PERF_TYPE_HW_CACHE,
+# PERF_COUNT_HW_CACHE_ITLB << 0 |
+# (PERF_COUNT_HW_CACHE_OP_READ << 8) |
+# (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)
+[event37:base-stat]
+fd=37
+type=3
+config=4
+optional=1
+
+# PERF_TYPE_HW_CACHE,
+# PERF_COUNT_HW_CACHE_ITLB << 0 |
+# (PERF_COUNT_HW_CACHE_OP_READ << 8) |
+# (PERF_COUNT_HW_CACHE_RESULT_MISS << 16)
+[event38:base-stat]
+fd=38
+type=3
+config=65540
+optional=1
+
+# PERF_TYPE_HW_CACHE,
+# PERF_COUNT_HW_CACHE_L1D << 0 |
+# (PERF_COUNT_HW_CACHE_OP_PREFETCH << 8) |
+# (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)
+[event39:base-stat]
+fd=39
+type=3
+config=512
+optional=1
+
+# PERF_TYPE_HW_CACHE,
+# PERF_COUNT_HW_CACHE_L1D << 0 |
+# (PERF_COUNT_HW_CACHE_OP_PREFETCH << 8) |
+# (PERF_COUNT_HW_CACHE_RESULT_MISS << 16)
+[event40:base-stat]
+fd=40
+type=3
+config=66048
+optional=1
diff --git a/tools/perf/tests/shell/attr/test-stat-group1 b/tools/perf/tests/shell/attr/test-stat-group1
new file mode 100644
index 000000000000..1746751123dc
--- /dev/null
+++ b/tools/perf/tests/shell/attr/test-stat-group1
@@ -0,0 +1,17 @@
+[config]
+command = stat
+args = -e '{cycles,instructions}' kill >/dev/null 2>&1
+ret = 1
+
+[event-1:base-stat]
+fd=1
+group_fd=-1
+read_format=3|15
+
+[event-2:base-stat]
+fd=2
+group_fd=1
+config=1
+disabled=0
+enable_on_exec=0
+read_format=3|15
diff --git a/tools/perf/tests/shell/attr/test-stat-no-inherit b/tools/perf/tests/shell/attr/test-stat-no-inherit
new file mode 100644
index 000000000000..924fbb9300d1
--- /dev/null
+++ b/tools/perf/tests/shell/attr/test-stat-no-inherit
@@ -0,0 +1,8 @@
+[config]
+command = stat
+args = -i -e cycles kill >/dev/null 2>&1
+ret = 1
+
+[event:base-stat]
+inherit=0
+optional=1
diff --git a/tools/perf/tests/shell/lib/attr.py b/tools/perf/tests/shell/lib/attr.py
new file mode 100644
index 000000000000..3db9a7d78715
--- /dev/null
+++ b/tools/perf/tests/shell/lib/attr.py
@@ -0,0 +1,476 @@
+# SPDX-License-Identifier: GPL-2.0
+
+from __future__ import print_function
+
+import os
+import sys
+import glob
+import optparse
+import platform
+import tempfile
+import logging
+import re
+import shutil
+import subprocess
+
+try:
+ import configparser
+except ImportError:
+ import ConfigParser as configparser
+
+def data_equal(a, b):
+ # Allow multiple values in assignment separated by '|'
+ a_list = a.split('|')
+ b_list = b.split('|')
+
+ for a_item in a_list:
+ for b_item in b_list:
+ if (a_item == b_item):
+ return True
+ elif (a_item == '*') or (b_item == '*'):
+ return True
+
+ return False
+
+class Fail(Exception):
+ def __init__(self, test, msg):
+ self.msg = msg
+ self.test = test
+ def getMsg(self):
+ return '\'%s\' - %s' % (self.test.path, self.msg)
+
+class Notest(Exception):
+ def __init__(self, test, arch):
+ self.arch = arch
+ self.test = test
+ def getMsg(self):
+ return '[%s] \'%s\'' % (self.arch, self.test.path)
+
+class Unsup(Exception):
+ def __init__(self, test):
+ self.test = test
+ def getMsg(self):
+ return '\'%s\'' % self.test.path
+
+class Event(dict):
+ terms = [
+ 'cpu',
+ 'flags',
+ 'type',
+ 'size',
+ 'config',
+ 'sample_period',
+ 'sample_type',
+ 'read_format',
+ 'disabled',
+ 'inherit',
+ 'pinned',
+ 'exclusive',
+ 'exclude_user',
+ 'exclude_kernel',
+ 'exclude_hv',
+ 'exclude_idle',
+ 'mmap',
+ 'comm',
+ 'freq',
+ 'inherit_stat',
+ 'enable_on_exec',
+ 'task',
+ 'watermark',
+ 'precise_ip',
+ 'mmap_data',
+ 'sample_id_all',
+ 'exclude_host',
+ 'exclude_guest',
+ 'exclude_callchain_kernel',
+ 'exclude_callchain_user',
+ 'wakeup_events',
+ 'bp_type',
+ 'config1',
+ 'config2',
+ 'branch_sample_type',
+ 'sample_regs_user',
+ 'sample_stack_user',
+ ]
+
+ def add(self, data):
+ for key, val in data:
+ log.debug(" %s = %s" % (key, val))
+ self[key] = val
+
+ def __init__(self, name, data, base):
+ log.debug(" Event %s" % name);
+ self.name = name;
+ self.group = ''
+ self.add(base)
+ self.add(data)
+
+ def equal(self, other):
+ for t in Event.terms:
+ log.debug(" [%s] %s %s" % (t, self[t], other[t]));
+ if t not in self or t not in other:
+ return False
+ if not data_equal(self[t], other[t]):
+ return False
+ return True
+
+ def optional(self):
+ if 'optional' in self and self['optional'] == '1':
+ return True
+ return False
+
+ def diff(self, other):
+ for t in Event.terms:
+ if t not in self or t not in other:
+ continue
+ if not data_equal(self[t], other[t]):
+ log.warning("expected %s=%s, got %s" % (t, self[t], other[t]))
+
+def parse_version(version):
+ if not version:
+ return None
+ return [int(v) for v in version.split(".")[0:2]]
+
+# Test file description needs to have following sections:
+# [config]
+# - just single instance in file
+# - needs to specify:
+# 'command' - perf command name
+# 'args' - special command arguments
+# 'ret' - Skip test if Perf doesn't exit with this value (0 by default)
+# 'test_ret'- If set to 'true', fail test instead of skipping for 'ret' argument
+# 'arch' - architecture specific test (optional)
+# comma separated list, ! at the beginning
+# negates it.
+# 'auxv' - Truthy statement that is evaled in the scope of the auxv map. When false,
+# the test is skipped. For example 'auxv["AT_HWCAP"] == 10'. (optional)
+# 'kernel_since' - Inclusive kernel version from which the test will start running. Only the
+# first two values are supported, for example "6.1" (optional)
+# 'kernel_until' - Exclusive kernel version from which the test will stop running. (optional)
+# [eventX:base]
+# - one or multiple instances in file
+# - expected values assignments
+class Test(object):
+ def __init__(self, path, options):
+ parser = configparser.ConfigParser()
+ parser.read(path)
+
+ log.warning("running '%s'" % path)
+
+ self.path = path
+ self.test_dir = options.test_dir
+ self.perf = options.perf
+ self.command = parser.get('config', 'command')
+ self.args = parser.get('config', 'args')
+
+ try:
+ self.ret = parser.get('config', 'ret')
+ except:
+ self.ret = 0
+
+ self.test_ret = parser.getboolean('config', 'test_ret', fallback=False)
+
+ try:
+ self.arch = parser.get('config', 'arch')
+ log.warning("test limitation '%s'" % self.arch)
+ except:
+ self.arch = ''
+
+ self.auxv = parser.get('config', 'auxv', fallback=None)
+ self.kernel_since = parse_version(parser.get('config', 'kernel_since', fallback=None))
+ self.kernel_until = parse_version(parser.get('config', 'kernel_until', fallback=None))
+ self.expect = {}
+ self.result = {}
+ log.debug(" loading expected events");
+ self.load_events(path, self.expect)
+
+ def is_event(self, name):
+ if name.find("event") == -1:
+ return False
+ else:
+ return True
+
+ def skip_test_kernel_since(self):
+ if not self.kernel_since:
+ return False
+ return not self.kernel_since <= parse_version(platform.release())
+
+ def skip_test_kernel_until(self):
+ if not self.kernel_until:
+ return False
+ return not parse_version(platform.release()) < self.kernel_until
+
+ def skip_test_auxv(self):
+ def new_auxv(a, pattern):
+ items = list(filter(None, pattern.split(a)))
+ # AT_HWCAP is hex but doesn't have a prefix, so special case it
+ if items[0] == "AT_HWCAP":
+ value = int(items[-1], 16)
+ else:
+ try:
+ value = int(items[-1], 0)
+ except:
+ value = items[-1]
+ return (items[0], value)
+
+ if not self.auxv:
+ return False
+ auxv = subprocess.check_output("LD_SHOW_AUXV=1 sleep 0", shell=True) \
+ .decode(sys.stdout.encoding)
+ pattern = re.compile(r"[: ]+")
+ auxv = dict([new_auxv(a, pattern) for a in auxv.splitlines()])
+ return not eval(self.auxv)
+
+ def skip_test_arch(self, myarch):
+ # If architecture not set always run test
+ if self.arch == '':
+ # log.warning("test for arch %s is ok" % myarch)
+ return False
+
+ # Allow multiple values in assignment separated by ','
+ arch_list = self.arch.split(',')
+
+ # Handle negated list such as !s390x,ppc
+ if arch_list[0][0] == '!':
+ arch_list[0] = arch_list[0][1:]
+ log.warning("excluded architecture list %s" % arch_list)
+ for arch_item in arch_list:
+ # log.warning("test for %s arch is %s" % (arch_item, myarch))
+ if arch_item == myarch:
+ return True
+ return False
+
+ for arch_item in arch_list:
+ # log.warning("test for architecture '%s' current '%s'" % (arch_item, myarch))
+ if arch_item == myarch:
+ return False
+ return True
+
+ def restore_sample_rate(self, value=10000):
+ try:
+ # Check value of sample_rate
+ with open("/proc/sys/kernel/perf_event_max_sample_rate", "r") as fIn:
+ curr_value = fIn.readline()
+ # If too low restore to reasonable value
+ if not curr_value or int(curr_value) < int(value):
+ with open("/proc/sys/kernel/perf_event_max_sample_rate", "w") as fOut:
+ fOut.write(str(value))
+
+ except IOError as e:
+ log.warning("couldn't restore sample_rate value: I/O error %s" % e)
+ except ValueError as e:
+ log.warning("couldn't restore sample_rate value: Value error %s" % e)
+ except TypeError as e:
+ log.warning("couldn't restore sample_rate value: Type error %s" % e)
+
+ def load_events(self, path, events):
+ parser_event = configparser.ConfigParser()
+ parser_event.read(path)
+
+ # The event record section header contains 'event' word,
+ # optionaly followed by ':' allowing to load 'parent
+ # event' first as a base
+ for section in filter(self.is_event, parser_event.sections()):
+
+ parser_items = parser_event.items(section);
+ base_items = {}
+
+ # Read parent event if there's any
+ if (':' in section):
+ base = section[section.index(':') + 1:]
+ parser_base = configparser.ConfigParser()
+ parser_base.read(self.test_dir + '/' + base)
+ base_items = parser_base.items('event')
+
+ e = Event(section, parser_items, base_items)
+ events[section] = e
+
+ def run_cmd(self, tempdir):
+ junk1, junk2, junk3, junk4, myarch = (os.uname())
+
+ if self.skip_test_arch(myarch):
+ raise Notest(self, myarch)
+
+ if self.skip_test_auxv():
+ raise Notest(self, "auxv skip")
+
+ if self.skip_test_kernel_since():
+ raise Notest(self, "old kernel skip")
+
+ if self.skip_test_kernel_until():
+ raise Notest(self, "new kernel skip")
+
+ self.restore_sample_rate()
+ cmd = "PERF_TEST_ATTR=%s %s %s -o %s/perf.data %s" % (tempdir,
+ self.perf, self.command, tempdir, self.args)
+ ret = os.WEXITSTATUS(os.system(cmd))
+
+ log.info(" '%s' ret '%s', expected '%s'" % (cmd, str(ret), str(self.ret)))
+
+ if not data_equal(str(ret), str(self.ret)):
+ if self.test_ret:
+ raise Fail(self, "Perf exit code failure")
+ else:
+ raise Unsup(self)
+
+ def compare(self, expect, result):
+ match = {}
+
+ log.debug(" compare");
+
+ # For each expected event find all matching
+ # events in result. Fail if there's not any.
+ for exp_name, exp_event in expect.items():
+ exp_list = []
+ res_event = {}
+ log.debug(" matching [%s]" % exp_name)
+ for res_name, res_event in result.items():
+ log.debug(" to [%s]" % res_name)
+ if (exp_event.equal(res_event)):
+ exp_list.append(res_name)
+ log.debug(" ->OK")
+ else:
+ log.debug(" ->FAIL");
+
+ log.debug(" match: [%s] matches %s" % (exp_name, str(exp_list)))
+
+ # we did not any matching event - fail
+ if not exp_list:
+ if exp_event.optional():
+ log.debug(" %s does not match, but is optional" % exp_name)
+ else:
+ if not res_event:
+ log.debug(" res_event is empty");
+ else:
+ exp_event.diff(res_event)
+ raise Fail(self, 'match failure');
+
+ match[exp_name] = exp_list
+
+ # For each defined group in the expected events
+ # check we match the same group in the result.
+ for exp_name, exp_event in expect.items():
+ group = exp_event.group
+
+ if (group == ''):
+ continue
+
+ for res_name in match[exp_name]:
+ res_group = result[res_name].group
+ if res_group not in match[group]:
+ raise Fail(self, 'group failure')
+
+ log.debug(" group: [%s] matches group leader %s" %
+ (exp_name, str(match[group])))
+
+ log.debug(" matched")
+
+ def resolve_groups(self, events):
+ for name, event in events.items():
+ group_fd = event['group_fd'];
+ if group_fd == '-1':
+ continue;
+
+ for iname, ievent in events.items():
+ if (ievent['fd'] == group_fd):
+ event.group = iname
+ log.debug('[%s] has group leader [%s]' % (name, iname))
+ break;
+
+ def run(self):
+ tempdir = tempfile.mkdtemp();
+
+ try:
+ # run the test script
+ self.run_cmd(tempdir);
+
+ # load events expectation for the test
+ log.debug(" loading result events");
+ for f in glob.glob(tempdir + '/event*'):
+ self.load_events(f, self.result);
+
+ # resolve group_fd to event names
+ self.resolve_groups(self.expect);
+ self.resolve_groups(self.result);
+
+ # do the expectation - results matching - both ways
+ self.compare(self.expect, self.result)
+ self.compare(self.result, self.expect)
+
+ finally:
+ # cleanup
+ shutil.rmtree(tempdir)
+
+
+def run_tests(options):
+ for f in glob.glob(options.test_dir + '/' + options.test):
+ try:
+ Test(f, options).run()
+ except Unsup as obj:
+ log.warning("unsupp %s" % obj.getMsg())
+ except Notest as obj:
+ log.warning("skipped %s" % obj.getMsg())
+
+def setup_log(verbose):
+ global log
+ level = logging.CRITICAL
+
+ if verbose == 1:
+ level = logging.WARNING
+ if verbose == 2:
+ level = logging.INFO
+ if verbose >= 3:
+ level = logging.DEBUG
+
+ log = logging.getLogger('test')
+ log.setLevel(level)
+ ch = logging.StreamHandler()
+ ch.setLevel(level)
+ formatter = logging.Formatter('%(message)s')
+ ch.setFormatter(formatter)
+ log.addHandler(ch)
+
+USAGE = '''%s [OPTIONS]
+ -d dir # tests dir
+ -p path # perf binary
+ -t test # single test
+ -v # verbose level
+''' % sys.argv[0]
+
+def main():
+ parser = optparse.OptionParser(usage=USAGE)
+
+ parser.add_option("-t", "--test",
+ action="store", type="string", dest="test")
+ parser.add_option("-d", "--test-dir",
+ action="store", type="string", dest="test_dir")
+ parser.add_option("-p", "--perf",
+ action="store", type="string", dest="perf")
+ parser.add_option("-v", "--verbose",
+ default=0, action="count", dest="verbose")
+
+ options, args = parser.parse_args()
+ if args:
+ parser.error('FAILED wrong arguments %s' % ' '.join(args))
+ return -1
+
+ setup_log(options.verbose)
+
+ if not options.test_dir:
+ print('FAILED no -d option specified')
+ sys.exit(-1)
+
+ if not options.test:
+ options.test = 'test*'
+
+ try:
+ run_tests(options)
+
+ except Fail as obj:
+ print("FAILED %s" % obj.getMsg())
+ sys.exit(-1)
+
+ sys.exit(0)
+
+if __name__ == '__main__':
+ main()