summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2019-08-09 10:53:39 -0400
committerPaolo Bonzini <pbonzini@redhat.com>2019-08-09 10:53:39 -0400
commit0e1c438c44dd9cde56effb44c5f1cfeda72e108d (patch)
treefa3492d4d7d8b7444e5d8ebe6c78210826333e4b /tools
parentc096397c78f766db972f923433031f2dec01cae0 (diff)
parentcdb2d3ee0436d74fa9092f2df46aaa6f9e03c969 (diff)
Merge tag 'kvmarm-fixes-for-5.3' of git://git.kernel.org/pub/scm/linux/kernel/git/kvmarm/kvmarm into HEAD
KVM/arm fixes for 5.3 - A bunch of switch/case fall-through annotation, fixing one actual bug - Fix PMU reset bug - Add missing exception class debug strings
Diffstat (limited to 'tools')
-rw-r--r--tools/Makefile12
-rw-r--r--tools/bpf/bpftool/main.h1
-rw-r--r--tools/include/linux/zalloc.h12
-rw-r--r--tools/include/uapi/linux/bpf.h6
-rw-r--r--tools/lib/bpf/libbpf.c4
-rw-r--r--tools/lib/bpf/xsk.c3
-rw-r--r--tools/lib/zalloc.c15
-rw-r--r--tools/objtool/arch.h36
-rw-r--r--tools/objtool/arch/x86/decode.c2
-rw-r--r--tools/objtool/check.c333
-rw-r--r--tools/objtool/check.h3
-rw-r--r--tools/objtool/elf.c8
-rw-r--r--tools/objtool/elf.h5
-rw-r--r--tools/pci/Makefile5
-rw-r--r--tools/pci/pcitest.c8
-rw-r--r--tools/perf/Documentation/perf-probe.txt3
-rw-r--r--tools/perf/MANIFEST1
-rw-r--r--tools/perf/arch/arm/annotate/instructions.c1
-rw-r--r--tools/perf/arch/arm/util/auxtrace.c1
-rw-r--r--tools/perf/arch/arm/util/cs-etm.c1
-rw-r--r--tools/perf/arch/arm64/util/arm-spe.c1
-rw-r--r--tools/perf/arch/common.c3
-rw-r--r--tools/perf/arch/powerpc/util/perf_regs.c4
-rw-r--r--tools/perf/arch/s390/util/auxtrace.c1
-rw-r--r--tools/perf/arch/s390/util/header.c3
-rw-r--r--tools/perf/arch/x86/util/event.c2
-rw-r--r--tools/perf/arch/x86/util/intel-bts.c2
-rw-r--r--tools/perf/arch/x86/util/intel-pt.c2
-rw-r--r--tools/perf/arch/x86/util/perf_regs.c2
-rw-r--r--tools/perf/bench/futex-hash.c3
-rw-r--r--tools/perf/bench/futex-lock-pi.c3
-rw-r--r--tools/perf/bench/mem-functions.c2
-rw-r--r--tools/perf/bench/numa.c2
-rw-r--r--tools/perf/builtin-annotate.c2
-rw-r--r--tools/perf/builtin-bench.c2
-rw-r--r--tools/perf/builtin-c2c.c2
-rw-r--r--tools/perf/builtin-config.c1
-rw-r--r--tools/perf/builtin-diff.c2
-rw-r--r--tools/perf/builtin-ftrace.c2
-rw-r--r--tools/perf/builtin-help.c2
-rw-r--r--tools/perf/builtin-inject.c2
-rw-r--r--tools/perf/builtin-kmem.c2
-rw-r--r--tools/perf/builtin-kvm.c2
-rw-r--r--tools/perf/builtin-lock.c10
-rw-r--r--tools/perf/builtin-probe.c2
-rw-r--r--tools/perf/builtin-record.c4
-rw-r--r--tools/perf/builtin-report.c4
-rw-r--r--tools/perf/builtin-sched.c2
-rw-r--r--tools/perf/builtin-script.c13
-rw-r--r--tools/perf/builtin-stat.c8
-rw-r--r--tools/perf/builtin-timechart.c4
-rw-r--r--tools/perf/builtin-top.c8
-rw-r--r--tools/perf/builtin-trace.c17
-rw-r--r--tools/perf/builtin-version.c1
-rw-r--r--tools/perf/perf.c2
-rw-r--r--tools/perf/pmu-events/arch/s390/cf_m8561/basic.json58
-rw-r--r--tools/perf/pmu-events/arch/s390/cf_m8561/crypto.json114
-rw-r--r--tools/perf/pmu-events/arch/s390/cf_m8561/crypto6.json30
-rw-r--r--tools/perf/pmu-events/arch/s390/cf_m8561/extended.json373
-rw-r--r--tools/perf/pmu-events/arch/s390/mapfile.csv1
-rw-r--r--tools/perf/pmu-events/jevents.c2
-rw-r--r--tools/perf/scripts/python/export-to-postgresql.py70
-rw-r--r--tools/perf/scripts/python/export-to-sqlite.py56
-rwxr-xr-xtools/perf/scripts/python/exported-sql-viewer.py34
-rw-r--r--tools/perf/tests/builtin-test.c6
-rw-r--r--tools/perf/tests/dwarf-unwind.c5
-rw-r--r--tools/perf/tests/expr.c3
-rw-r--r--tools/perf/tests/llvm.c1
-rw-r--r--tools/perf/tests/mem2node.c3
-rw-r--r--tools/perf/tests/mmap-thread-lookup.c2
-rw-r--r--tools/perf/tests/sample-parsing.c1
-rw-r--r--tools/perf/tests/switch-tracking.c3
-rw-r--r--tools/perf/tests/thread-map.c3
-rw-r--r--tools/perf/tests/vmlinux-kallsyms.c1
-rw-r--r--tools/perf/ui/browser.c2
-rw-r--r--tools/perf/ui/browser.h1
-rw-r--r--tools/perf/ui/browsers/annotate.c2
-rw-r--r--tools/perf/ui/browsers/hists.c17
-rw-r--r--tools/perf/ui/browsers/map.c1
-rw-r--r--tools/perf/ui/browsers/res_sample.c6
-rw-r--r--tools/perf/ui/browsers/scripts.c4
-rw-r--r--tools/perf/ui/gtk/annotate.c2
-rw-r--r--tools/perf/ui/gtk/util.c3
-rw-r--r--tools/perf/ui/stdio/hist.c2
-rw-r--r--tools/perf/ui/tui/setup.c1
-rw-r--r--tools/perf/ui/tui/util.c2
-rw-r--r--tools/perf/util/Build6
-rw-r--r--tools/perf/util/annotate.c13
-rw-r--r--tools/perf/util/arm-spe.c2
-rw-r--r--tools/perf/util/auxtrace.c11
-rw-r--r--tools/perf/util/bpf-loader.c3
-rw-r--r--tools/perf/util/build-id.c1
-rw-r--r--tools/perf/util/call-path.c5
-rw-r--r--tools/perf/util/callchain.c12
-rw-r--r--tools/perf/util/cgroup.c4
-rw-r--r--tools/perf/util/comm.c2
-rw-r--r--tools/perf/util/config.c3
-rw-r--r--tools/perf/util/counts.c2
-rw-r--r--tools/perf/util/cpumap.c2
-rw-r--r--tools/perf/util/cputopo.c5
-rw-r--r--tools/perf/util/cs-etm-decoder/cs-etm-decoder.c1
-rw-r--r--tools/perf/util/cs-etm.c20
-rw-r--r--tools/perf/util/data-convert-bt.c4
-rw-r--r--tools/perf/util/data.c3
-rw-r--r--tools/perf/util/db-export.c294
-rw-r--r--tools/perf/util/db-export.h19
-rw-r--r--tools/perf/util/debug.c1
-rw-r--r--tools/perf/util/demangle-java.c3
-rw-r--r--tools/perf/util/dso.c5
-rw-r--r--tools/perf/util/dwarf-aux.c2
-rw-r--r--tools/perf/util/env.c11
-rw-r--r--tools/perf/util/event.c3
-rw-r--r--tools/perf/util/evlist.c2
-rw-r--r--tools/perf/util/evsel.c4
-rw-r--r--tools/perf/util/get_current_dir_name.c6
-rw-r--r--tools/perf/util/get_current_dir_name.h8
-rw-r--r--tools/perf/util/header.c8
-rw-r--r--tools/perf/util/help-unknown-cmd.c2
-rw-r--r--tools/perf/util/hist.c20
-rw-r--r--tools/perf/util/intel-bts.c7
-rw-r--r--tools/perf/util/intel-pt-decoder/intel-pt-decoder.c2
-rw-r--r--tools/perf/util/intel-pt.c15
-rw-r--r--tools/perf/util/jitdump.c7
-rw-r--r--tools/perf/util/llvm-utils.c4
-rw-r--r--tools/perf/util/machine.c6
-rw-r--r--tools/perf/util/map.c9
-rw-r--r--tools/perf/util/mem2node.c2
-rw-r--r--tools/perf/util/metricgroup.c10
-rw-r--r--tools/perf/util/mmap.c1
-rw-r--r--tools/perf/util/namespaces.c3
-rw-r--r--tools/perf/util/namespaces.h4
-rw-r--r--tools/perf/util/ordered-events.c6
-rw-r--r--tools/perf/util/parse-branch-options.c2
-rw-r--r--tools/perf/util/parse-events.c3
-rw-r--r--tools/perf/util/parse-events.y2
-rw-r--r--tools/perf/util/parse-regs-options.c8
-rw-r--r--tools/perf/util/pmu.c4
-rw-r--r--tools/perf/util/probe-event.c66
-rw-r--r--tools/perf/util/probe-event.h2
-rw-r--r--tools/perf/util/probe-file.c9
-rw-r--r--tools/perf/util/probe-file.h1
-rw-r--r--tools/perf/util/probe-finder.c21
-rw-r--r--tools/perf/util/pstack.c2
-rw-r--r--tools/perf/util/python-ext-sources1
-rw-r--r--tools/perf/util/rlimit.c29
-rw-r--r--tools/perf/util/rlimit.h6
-rw-r--r--tools/perf/util/s390-cpumsf.c11
-rw-r--r--tools/perf/util/scripting-engines/trace-event-python.c53
-rw-r--r--tools/perf/util/session.c7
-rw-r--r--tools/perf/util/setns.c4
-rw-r--r--tools/perf/util/srccode.c11
-rw-r--r--tools/perf/util/srcline.c2
-rw-r--r--tools/perf/util/stat-shadow.c3
-rw-r--r--tools/perf/util/stat.c3
-rw-r--r--tools/perf/util/strbuf.c3
-rw-r--r--tools/perf/util/strfilter.c3
-rw-r--r--tools/perf/util/strlist.c2
-rw-r--r--tools/perf/util/svghelper.c2
-rw-r--r--tools/perf/util/symbol-elf.c18
-rw-r--r--tools/perf/util/symbol-minimal.c3
-rw-r--r--tools/perf/util/symbol.c1
-rw-r--r--tools/perf/util/syscalltbl.c2
-rw-r--r--tools/perf/util/target.c2
-rw-r--r--tools/perf/util/thread-stack.c3
-rw-r--r--tools/perf/util/thread.c6
-rw-r--r--tools/perf/util/thread_map.c4
-rw-r--r--tools/perf/util/trace-event-info.c1
-rw-r--r--tools/perf/util/trace-event-scripting.c2
-rw-r--r--tools/perf/util/trace-event.h3
-rw-r--r--tools/perf/util/unwind-libdw.c1
-rw-r--r--tools/perf/util/unwind-libunwind-local.c3
-rw-r--r--tools/perf/util/usage.c3
-rw-r--r--tools/perf/util/util.h17
-rw-r--r--tools/perf/util/values.c2
-rw-r--r--tools/perf/util/vdso.c1
-rw-r--r--tools/perf/util/xyarray.c2
-rw-r--r--tools/power/cpupower/debug/kernel/Makefile4
-rw-r--r--tools/power/x86/intel-speed-select/.gitignore2
-rw-r--r--tools/power/x86/intel-speed-select/Build1
-rw-r--r--tools/power/x86/intel-speed-select/Makefile56
-rw-r--r--tools/power/x86/intel-speed-select/isst-config.c1607
-rw-r--r--tools/power/x86/intel-speed-select/isst-core.c721
-rw-r--r--tools/power/x86/intel-speed-select/isst-display.c479
-rw-r--r--tools/power/x86/intel-speed-select/isst.h231
-rw-r--r--tools/testing/nvdimm/test/iomap.c57
-rw-r--r--tools/testing/selftests/bpf/Makefile64
-rw-r--r--tools/testing/selftests/bpf/bpf_helpers.h89
-rw-r--r--tools/testing/selftests/bpf/prog_tests/attach_probe.c10
-rw-r--r--tools/testing/selftests/bpf/prog_tests/perf_buffer.c8
-rw-r--r--tools/testing/selftests/bpf/prog_tests/send_signal.c33
-rw-r--r--tools/testing/selftests/bpf/progs/loop1.c2
-rw-r--r--tools/testing/selftests/bpf/progs/loop2.c2
-rw-r--r--tools/testing/selftests/bpf/progs/loop3.c2
-rw-r--r--tools/testing/selftests/bpf/progs/test_get_stack_rawtp.c3
-rw-r--r--tools/testing/selftests/bpf/progs/test_stacktrace_build_id.c3
-rw-r--r--tools/testing/selftests/bpf/progs/test_stacktrace_map.c2
-rw-r--r--tools/testing/selftests/bpf/progs/test_xdp_noinline.c17
-rw-r--r--tools/testing/selftests/bpf/test_btf.c88
-rw-r--r--tools/testing/selftests/bpf/test_progs.h8
-rw-r--r--tools/testing/selftests/bpf/test_verifier.c35
-rw-r--r--tools/testing/selftests/bpf/verifier/array_access.c2
-rw-r--r--tools/testing/selftests/bpf/verifier/value_ptr_arith.c2
-rw-r--r--tools/testing/selftests/bpf/verifier/wide_access.c73
-rw-r--r--tools/testing/selftests/bpf/verifier/wide_store.c36
-rwxr-xr-xtools/testing/selftests/ftrace/ftracetest38
-rw-r--r--tools/testing/selftests/ftrace/test.d/functions4
-rw-r--r--tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args_user.tc32
-rwxr-xr-xtools/testing/selftests/net/fib_tests.sh35
-rwxr-xr-xtools/testing/selftests/ntb/ntb_test.sh54
-rw-r--r--tools/testing/selftests/powerpc/mm/.gitignore2
-rw-r--r--tools/testing/selftests/powerpc/stringloops/asm/ppc_asm.h2
-rw-r--r--tools/testing/selftests/powerpc/tm/tm-vmxcopy.c2
-rw-r--r--tools/testing/selftests/powerpc/vphn/Makefile2
l---------tools/testing/selftests/powerpc/vphn/asm/lppaca.h1
l---------tools/testing/selftests/powerpc/vphn/vphn.c2
l---------tools/testing/selftests/powerpc/vphn/vphn.h1
-rw-r--r--tools/testing/selftests/proc/.gitignore1
-rw-r--r--tools/testing/selftests/proc/Makefile1
-rw-r--r--tools/testing/selftests/proc/proc-pid-vm.c17
-rw-r--r--tools/testing/selftests/proc/setns-sysvipc.c133
-rw-r--r--tools/testing/selftests/ptrace/.gitignore1
-rw-r--r--tools/testing/selftests/ptrace/Makefile2
-rw-r--r--tools/testing/selftests/ptrace/get_syscall_info.c271
-rw-r--r--tools/testing/selftests/safesetid/safesetid-test.c18
-rw-r--r--tools/testing/selftests/seccomp/seccomp_bpf.c13
-rw-r--r--tools/testing/selftests/tc-testing/tc-tests/actions/skbedit.json117
-rw-r--r--tools/testing/selftests/x86/fsgsbase.c22
-rw-r--r--tools/testing/selftests/zram/README2
228 files changed, 5860 insertions, 840 deletions
diff --git a/tools/Makefile b/tools/Makefile
index 3dfd72ae6c1a..68defd7ecf5d 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -19,6 +19,7 @@ help:
19 @echo ' gpio - GPIO tools' 19 @echo ' gpio - GPIO tools'
20 @echo ' hv - tools used when in Hyper-V clients' 20 @echo ' hv - tools used when in Hyper-V clients'
21 @echo ' iio - IIO tools' 21 @echo ' iio - IIO tools'
22 @echo ' intel-speed-select - Intel Speed Select tool'
22 @echo ' kvm_stat - top-like utility for displaying kvm statistics' 23 @echo ' kvm_stat - top-like utility for displaying kvm statistics'
23 @echo ' leds - LEDs tools' 24 @echo ' leds - LEDs tools'
24 @echo ' liblockdep - user-space wrapper for kernel locking-validator' 25 @echo ' liblockdep - user-space wrapper for kernel locking-validator'
@@ -82,7 +83,7 @@ perf: FORCE
82selftests: FORCE 83selftests: FORCE
83 $(call descend,testing/$@) 84 $(call descend,testing/$@)
84 85
85turbostat x86_energy_perf_policy: FORCE 86turbostat x86_energy_perf_policy intel-speed-select: FORCE
86 $(call descend,power/x86/$@) 87 $(call descend,power/x86/$@)
87 88
88tmon: FORCE 89tmon: FORCE
@@ -115,7 +116,7 @@ liblockdep_install:
115selftests_install: 116selftests_install:
116 $(call descend,testing/$(@:_install=),install) 117 $(call descend,testing/$(@:_install=),install)
117 118
118turbostat_install x86_energy_perf_policy_install: 119turbostat_install x86_energy_perf_policy_install intel-speed-select_install:
119 $(call descend,power/x86/$(@:_install=),install) 120 $(call descend,power/x86/$(@:_install=),install)
120 121
121tmon_install: 122tmon_install:
@@ -132,7 +133,7 @@ install: acpi_install cgroup_install cpupower_install gpio_install \
132 perf_install selftests_install turbostat_install usb_install \ 133 perf_install selftests_install turbostat_install usb_install \
133 virtio_install vm_install bpf_install x86_energy_perf_policy_install \ 134 virtio_install vm_install bpf_install x86_energy_perf_policy_install \
134 tmon_install freefall_install objtool_install kvm_stat_install \ 135 tmon_install freefall_install objtool_install kvm_stat_install \
135 wmi_install pci_install debugging_install 136 wmi_install pci_install debugging_install intel-speed-select_install
136 137
137acpi_clean: 138acpi_clean:
138 $(call descend,power/acpi,clean) 139 $(call descend,power/acpi,clean)
@@ -162,7 +163,7 @@ perf_clean:
162selftests_clean: 163selftests_clean:
163 $(call descend,testing/$(@:_clean=),clean) 164 $(call descend,testing/$(@:_clean=),clean)
164 165
165turbostat_clean x86_energy_perf_policy_clean: 166turbostat_clean x86_energy_perf_policy_clean intel-speed-select_clean:
166 $(call descend,power/x86/$(@:_clean=),clean) 167 $(call descend,power/x86/$(@:_clean=),clean)
167 168
168tmon_clean: 169tmon_clean:
@@ -178,6 +179,7 @@ clean: acpi_clean cgroup_clean cpupower_clean hv_clean firewire_clean \
178 perf_clean selftests_clean turbostat_clean spi_clean usb_clean virtio_clean \ 179 perf_clean selftests_clean turbostat_clean spi_clean usb_clean virtio_clean \
179 vm_clean bpf_clean iio_clean x86_energy_perf_policy_clean tmon_clean \ 180 vm_clean bpf_clean iio_clean x86_energy_perf_policy_clean tmon_clean \
180 freefall_clean build_clean libbpf_clean libsubcmd_clean liblockdep_clean \ 181 freefall_clean build_clean libbpf_clean libsubcmd_clean liblockdep_clean \
181 gpio_clean objtool_clean leds_clean wmi_clean pci_clean firmware_clean debugging_clean 182 gpio_clean objtool_clean leds_clean wmi_clean pci_clean firmware_clean debugging_clean \
183 intel-speed-select_clean
182 184
183.PHONY: FORCE 185.PHONY: FORCE
diff --git a/tools/bpf/bpftool/main.h b/tools/bpf/bpftool/main.h
index 3ef0d9051e10..7031a4bf87a0 100644
--- a/tools/bpf/bpftool/main.h
+++ b/tools/bpf/bpftool/main.h
@@ -74,6 +74,7 @@ static const char * const prog_type_name[] = {
74 [BPF_PROG_TYPE_SK_REUSEPORT] = "sk_reuseport", 74 [BPF_PROG_TYPE_SK_REUSEPORT] = "sk_reuseport",
75 [BPF_PROG_TYPE_FLOW_DISSECTOR] = "flow_dissector", 75 [BPF_PROG_TYPE_FLOW_DISSECTOR] = "flow_dissector",
76 [BPF_PROG_TYPE_CGROUP_SYSCTL] = "cgroup_sysctl", 76 [BPF_PROG_TYPE_CGROUP_SYSCTL] = "cgroup_sysctl",
77 [BPF_PROG_TYPE_RAW_TRACEPOINT_WRITABLE] = "raw_tracepoint_writable",
77 [BPF_PROG_TYPE_CGROUP_SOCKOPT] = "cgroup_sockopt", 78 [BPF_PROG_TYPE_CGROUP_SOCKOPT] = "cgroup_sockopt",
78}; 79};
79 80
diff --git a/tools/include/linux/zalloc.h b/tools/include/linux/zalloc.h
new file mode 100644
index 000000000000..81099c84043f
--- /dev/null
+++ b/tools/include/linux/zalloc.h
@@ -0,0 +1,12 @@
1// SPDX-License-Identifier: LGPL-2.1
2#ifndef __TOOLS_LINUX_ZALLOC_H
3#define __TOOLS_LINUX_ZALLOC_H
4
5#include <stddef.h>
6
7void *zalloc(size_t size);
8void __zfree(void **ptr);
9
10#define zfree(ptr) __zfree((void **)(ptr))
11
12#endif // __TOOLS_LINUX_ZALLOC_H
diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h
index f506c68b2612..4e455018da65 100644
--- a/tools/include/uapi/linux/bpf.h
+++ b/tools/include/uapi/linux/bpf.h
@@ -806,7 +806,7 @@ union bpf_attr {
806 * based on a user-provided identifier for all traffic coming from 806 * based on a user-provided identifier for all traffic coming from
807 * the tasks belonging to the related cgroup. See also the related 807 * the tasks belonging to the related cgroup. See also the related
808 * kernel documentation, available from the Linux sources in file 808 * kernel documentation, available from the Linux sources in file
809 * *Documentation/cgroup-v1/net_cls.rst*. 809 * *Documentation/admin-guide/cgroup-v1/net_cls.rst*.
810 * 810 *
811 * The Linux kernel has two versions for cgroups: there are 811 * The Linux kernel has two versions for cgroups: there are
812 * cgroups v1 and cgroups v2. Both are available to users, who can 812 * cgroups v1 and cgroups v2. Both are available to users, who can
@@ -3245,7 +3245,7 @@ struct bpf_sock_addr {
3245 __u32 user_ip4; /* Allows 1,2,4-byte read and 4-byte write. 3245 __u32 user_ip4; /* Allows 1,2,4-byte read and 4-byte write.
3246 * Stored in network byte order. 3246 * Stored in network byte order.
3247 */ 3247 */
3248 __u32 user_ip6[4]; /* Allows 1,2,4-byte read and 4,8-byte write. 3248 __u32 user_ip6[4]; /* Allows 1,2,4,8-byte read and 4,8-byte write.
3249 * Stored in network byte order. 3249 * Stored in network byte order.
3250 */ 3250 */
3251 __u32 user_port; /* Allows 4-byte read and write. 3251 __u32 user_port; /* Allows 4-byte read and write.
@@ -3257,7 +3257,7 @@ struct bpf_sock_addr {
3257 __u32 msg_src_ip4; /* Allows 1,2,4-byte read and 4-byte write. 3257 __u32 msg_src_ip4; /* Allows 1,2,4-byte read and 4-byte write.
3258 * Stored in network byte order. 3258 * Stored in network byte order.
3259 */ 3259 */
3260 __u32 msg_src_ip6[4]; /* Allows 1,2,4-byte read and 4,8-byte write. 3260 __u32 msg_src_ip6[4]; /* Allows 1,2,4,8-byte read and 4,8-byte write.
3261 * Stored in network byte order. 3261 * Stored in network byte order.
3262 */ 3262 */
3263 __bpf_md_ptr(struct bpf_sock *, sk); 3263 __bpf_md_ptr(struct bpf_sock *, sk);
diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index ed07789b3e62..794dd5064ae8 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -4126,8 +4126,8 @@ static int perf_event_open_probe(bool uprobe, bool retprobe, const char *name,
4126 } 4126 }
4127 attr.size = sizeof(attr); 4127 attr.size = sizeof(attr);
4128 attr.type = type; 4128 attr.type = type;
4129 attr.config1 = (uint64_t)(void *)name; /* kprobe_func or uprobe_path */ 4129 attr.config1 = ptr_to_u64(name); /* kprobe_func or uprobe_path */
4130 attr.config2 = offset; /* kprobe_addr or probe_offset */ 4130 attr.config2 = offset; /* kprobe_addr or probe_offset */
4131 4131
4132 /* pid filter is meaningful only for uprobes */ 4132 /* pid filter is meaningful only for uprobes */
4133 pfd = syscall(__NR_perf_event_open, &attr, 4133 pfd = syscall(__NR_perf_event_open, &attr,
diff --git a/tools/lib/bpf/xsk.c b/tools/lib/bpf/xsk.c
index b33740221b7e..5007b5d4fd2c 100644
--- a/tools/lib/bpf/xsk.c
+++ b/tools/lib/bpf/xsk.c
@@ -517,7 +517,8 @@ int xsk_socket__create(struct xsk_socket **xsk_ptr, const char *ifname,
517 err = -errno; 517 err = -errno;
518 goto out_socket; 518 goto out_socket;
519 } 519 }
520 strncpy(xsk->ifname, ifname, IFNAMSIZ); 520 strncpy(xsk->ifname, ifname, IFNAMSIZ - 1);
521 xsk->ifname[IFNAMSIZ - 1] = '\0';
521 522
522 err = xsk_set_xdp_socket_config(&xsk->config, usr_config); 523 err = xsk_set_xdp_socket_config(&xsk->config, usr_config);
523 if (err) 524 if (err)
diff --git a/tools/lib/zalloc.c b/tools/lib/zalloc.c
new file mode 100644
index 000000000000..9c856d59f56e
--- /dev/null
+++ b/tools/lib/zalloc.c
@@ -0,0 +1,15 @@
1// SPDX-License-Identifier: LGPL-2.1
2
3#include <stdlib.h>
4#include <linux/zalloc.h>
5
6void *zalloc(size_t size)
7{
8 return calloc(1, size);
9}
10
11void __zfree(void **ptr)
12{
13 free(*ptr);
14 *ptr = NULL;
15}
diff --git a/tools/objtool/arch.h b/tools/objtool/arch.h
index 580e344db3dd..ced3765c4f44 100644
--- a/tools/objtool/arch.h
+++ b/tools/objtool/arch.h
@@ -11,22 +11,24 @@
11#include "elf.h" 11#include "elf.h"
12#include "cfi.h" 12#include "cfi.h"
13 13
14#define INSN_JUMP_CONDITIONAL 1 14enum insn_type {
15#define INSN_JUMP_UNCONDITIONAL 2 15 INSN_JUMP_CONDITIONAL,
16#define INSN_JUMP_DYNAMIC 3 16 INSN_JUMP_UNCONDITIONAL,
17#define INSN_CALL 4 17 INSN_JUMP_DYNAMIC,
18#define INSN_CALL_DYNAMIC 5 18 INSN_JUMP_DYNAMIC_CONDITIONAL,
19#define INSN_RETURN 6 19 INSN_CALL,
20#define INSN_CONTEXT_SWITCH 7 20 INSN_CALL_DYNAMIC,
21#define INSN_STACK 8 21 INSN_RETURN,
22#define INSN_BUG 9 22 INSN_CONTEXT_SWITCH,
23#define INSN_NOP 10 23 INSN_STACK,
24#define INSN_STAC 11 24 INSN_BUG,
25#define INSN_CLAC 12 25 INSN_NOP,
26#define INSN_STD 13 26 INSN_STAC,
27#define INSN_CLD 14 27 INSN_CLAC,
28#define INSN_OTHER 15 28 INSN_STD,
29#define INSN_LAST INSN_OTHER 29 INSN_CLD,
30 INSN_OTHER,
31};
30 32
31enum op_dest_type { 33enum op_dest_type {
32 OP_DEST_REG, 34 OP_DEST_REG,
@@ -68,7 +70,7 @@ void arch_initial_func_cfi_state(struct cfi_state *state);
68 70
69int arch_decode_instruction(struct elf *elf, struct section *sec, 71int arch_decode_instruction(struct elf *elf, struct section *sec,
70 unsigned long offset, unsigned int maxlen, 72 unsigned long offset, unsigned int maxlen,
71 unsigned int *len, unsigned char *type, 73 unsigned int *len, enum insn_type *type,
72 unsigned long *immediate, struct stack_op *op); 74 unsigned long *immediate, struct stack_op *op);
73 75
74bool arch_callee_saved_reg(unsigned char reg); 76bool arch_callee_saved_reg(unsigned char reg);
diff --git a/tools/objtool/arch/x86/decode.c b/tools/objtool/arch/x86/decode.c
index 584568f27a83..0567c47a91b1 100644
--- a/tools/objtool/arch/x86/decode.c
+++ b/tools/objtool/arch/x86/decode.c
@@ -68,7 +68,7 @@ bool arch_callee_saved_reg(unsigned char reg)
68 68
69int arch_decode_instruction(struct elf *elf, struct section *sec, 69int arch_decode_instruction(struct elf *elf, struct section *sec,
70 unsigned long offset, unsigned int maxlen, 70 unsigned long offset, unsigned int maxlen,
71 unsigned int *len, unsigned char *type, 71 unsigned int *len, enum insn_type *type,
72 unsigned long *immediate, struct stack_op *op) 72 unsigned long *immediate, struct stack_op *op)
73{ 73{
74 struct insn insn; 74 struct insn insn;
diff --git a/tools/objtool/check.c b/tools/objtool/check.c
index 172f99195726..5f26620f13f5 100644
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -18,6 +18,8 @@
18 18
19#define FAKE_JUMP_OFFSET -1 19#define FAKE_JUMP_OFFSET -1
20 20
21#define C_JUMP_TABLE_SECTION ".rodata..c_jump_table"
22
21struct alternative { 23struct alternative {
22 struct list_head list; 24 struct list_head list;
23 struct instruction *insn; 25 struct instruction *insn;
@@ -95,6 +97,20 @@ static struct instruction *next_insn_same_func(struct objtool_file *file,
95 for (insn = next_insn_same_sec(file, insn); insn; \ 97 for (insn = next_insn_same_sec(file, insn); insn; \
96 insn = next_insn_same_sec(file, insn)) 98 insn = next_insn_same_sec(file, insn))
97 99
100static bool is_sibling_call(struct instruction *insn)
101{
102 /* An indirect jump is either a sibling call or a jump to a table. */
103 if (insn->type == INSN_JUMP_DYNAMIC)
104 return list_empty(&insn->alts);
105
106 if (insn->type != INSN_JUMP_CONDITIONAL &&
107 insn->type != INSN_JUMP_UNCONDITIONAL)
108 return false;
109
110 /* add_jump_destinations() sets insn->call_dest for sibling calls. */
111 return !!insn->call_dest;
112}
113
98/* 114/*
99 * This checks to see if the given function is a "noreturn" function. 115 * This checks to see if the given function is a "noreturn" function.
100 * 116 *
@@ -103,14 +119,9 @@ static struct instruction *next_insn_same_func(struct objtool_file *file,
103 * 119 *
104 * For local functions, we have to detect them manually by simply looking for 120 * For local functions, we have to detect them manually by simply looking for
105 * the lack of a return instruction. 121 * the lack of a return instruction.
106 *
107 * Returns:
108 * -1: error
109 * 0: no dead end
110 * 1: dead end
111 */ 122 */
112static int __dead_end_function(struct objtool_file *file, struct symbol *func, 123static bool __dead_end_function(struct objtool_file *file, struct symbol *func,
113 int recursion) 124 int recursion)
114{ 125{
115 int i; 126 int i;
116 struct instruction *insn; 127 struct instruction *insn;
@@ -136,30 +147,33 @@ static int __dead_end_function(struct objtool_file *file, struct symbol *func,
136 "rewind_stack_do_exit", 147 "rewind_stack_do_exit",
137 }; 148 };
138 149
150 if (!func)
151 return false;
152
139 if (func->bind == STB_WEAK) 153 if (func->bind == STB_WEAK)
140 return 0; 154 return false;
141 155
142 if (func->bind == STB_GLOBAL) 156 if (func->bind == STB_GLOBAL)
143 for (i = 0; i < ARRAY_SIZE(global_noreturns); i++) 157 for (i = 0; i < ARRAY_SIZE(global_noreturns); i++)
144 if (!strcmp(func->name, global_noreturns[i])) 158 if (!strcmp(func->name, global_noreturns[i]))
145 return 1; 159 return true;
146 160
147 if (!func->len) 161 if (!func->len)
148 return 0; 162 return false;
149 163
150 insn = find_insn(file, func->sec, func->offset); 164 insn = find_insn(file, func->sec, func->offset);
151 if (!insn->func) 165 if (!insn->func)
152 return 0; 166 return false;
153 167
154 func_for_each_insn_all(file, func, insn) { 168 func_for_each_insn_all(file, func, insn) {
155 empty = false; 169 empty = false;
156 170
157 if (insn->type == INSN_RETURN) 171 if (insn->type == INSN_RETURN)
158 return 0; 172 return false;
159 } 173 }
160 174
161 if (empty) 175 if (empty)
162 return 0; 176 return false;
163 177
164 /* 178 /*
165 * A function can have a sibling call instead of a return. In that 179 * A function can have a sibling call instead of a return. In that
@@ -167,40 +181,31 @@ static int __dead_end_function(struct objtool_file *file, struct symbol *func,
167 * of the sibling call returns. 181 * of the sibling call returns.
168 */ 182 */
169 func_for_each_insn_all(file, func, insn) { 183 func_for_each_insn_all(file, func, insn) {
170 if (insn->type == INSN_JUMP_UNCONDITIONAL) { 184 if (is_sibling_call(insn)) {
171 struct instruction *dest = insn->jump_dest; 185 struct instruction *dest = insn->jump_dest;
172 186
173 if (!dest) 187 if (!dest)
174 /* sibling call to another file */ 188 /* sibling call to another file */
175 return 0; 189 return false;
176
177 if (dest->func && dest->func->pfunc != insn->func->pfunc) {
178 190
179 /* local sibling call */ 191 /* local sibling call */
180 if (recursion == 5) { 192 if (recursion == 5) {
181 /* 193 /*
182 * Infinite recursion: two functions 194 * Infinite recursion: two functions have
183 * have sibling calls to each other. 195 * sibling calls to each other. This is a very
184 * This is a very rare case. It means 196 * rare case. It means they aren't dead ends.
185 * they aren't dead ends. 197 */
186 */ 198 return false;
187 return 0;
188 }
189
190 return __dead_end_function(file, dest->func,
191 recursion + 1);
192 } 199 }
193 }
194 200
195 if (insn->type == INSN_JUMP_DYNAMIC && list_empty(&insn->alts)) 201 return __dead_end_function(file, dest->func, recursion+1);
196 /* sibling call */ 202 }
197 return 0;
198 } 203 }
199 204
200 return 1; 205 return true;
201} 206}
202 207
203static int dead_end_function(struct objtool_file *file, struct symbol *func) 208static bool dead_end_function(struct objtool_file *file, struct symbol *func)
204{ 209{
205 return __dead_end_function(file, func, 0); 210 return __dead_end_function(file, func, 0);
206} 211}
@@ -262,19 +267,12 @@ static int decode_instructions(struct objtool_file *file)
262 if (ret) 267 if (ret)
263 goto err; 268 goto err;
264 269
265 if (!insn->type || insn->type > INSN_LAST) {
266 WARN_FUNC("invalid instruction type %d",
267 insn->sec, insn->offset, insn->type);
268 ret = -1;
269 goto err;
270 }
271
272 hash_add(file->insn_hash, &insn->hash, insn->offset); 270 hash_add(file->insn_hash, &insn->hash, insn->offset);
273 list_add_tail(&insn->list, &file->insn_list); 271 list_add_tail(&insn->list, &file->insn_list);
274 } 272 }
275 273
276 list_for_each_entry(func, &sec->symbol_list, list) { 274 list_for_each_entry(func, &sec->symbol_list, list) {
277 if (func->type != STT_FUNC) 275 if (func->type != STT_FUNC || func->alias != func)
278 continue; 276 continue;
279 277
280 if (!find_insn(file, sec, func->offset)) { 278 if (!find_insn(file, sec, func->offset)) {
@@ -284,8 +282,7 @@ static int decode_instructions(struct objtool_file *file)
284 } 282 }
285 283
286 func_for_each_insn(file, func, insn) 284 func_for_each_insn(file, func, insn)
287 if (!insn->func) 285 insn->func = func;
288 insn->func = func;
289 } 286 }
290 } 287 }
291 288
@@ -488,6 +485,7 @@ static const char *uaccess_safe_builtin[] = {
488 /* misc */ 485 /* misc */
489 "csum_partial_copy_generic", 486 "csum_partial_copy_generic",
490 "__memcpy_mcsafe", 487 "__memcpy_mcsafe",
488 "mcsafe_handle_tail",
491 "ftrace_likely_update", /* CONFIG_TRACE_BRANCH_PROFILING */ 489 "ftrace_likely_update", /* CONFIG_TRACE_BRANCH_PROFILING */
492 NULL 490 NULL
493}; 491};
@@ -505,7 +503,7 @@ static void add_uaccess_safe(struct objtool_file *file)
505 if (!func) 503 if (!func)
506 continue; 504 continue;
507 505
508 func->alias->uaccess_safe = true; 506 func->uaccess_safe = true;
509 } 507 }
510} 508}
511 509
@@ -577,13 +575,16 @@ static int add_jump_destinations(struct objtool_file *file)
577 * Retpoline jumps are really dynamic jumps in 575 * Retpoline jumps are really dynamic jumps in
578 * disguise, so convert them accordingly. 576 * disguise, so convert them accordingly.
579 */ 577 */
580 insn->type = INSN_JUMP_DYNAMIC; 578 if (insn->type == INSN_JUMP_UNCONDITIONAL)
579 insn->type = INSN_JUMP_DYNAMIC;
580 else
581 insn->type = INSN_JUMP_DYNAMIC_CONDITIONAL;
582
581 insn->retpoline_safe = true; 583 insn->retpoline_safe = true;
582 continue; 584 continue;
583 } else { 585 } else {
584 /* sibling call */ 586 /* external sibling call */
585 insn->call_dest = rela->sym; 587 insn->call_dest = rela->sym;
586 insn->jump_dest = NULL;
587 continue; 588 continue;
588 } 589 }
589 590
@@ -623,7 +624,7 @@ static int add_jump_destinations(struct objtool_file *file)
623 * However this code can't completely replace the 624 * However this code can't completely replace the
624 * read_symbols() code because this doesn't detect the 625 * read_symbols() code because this doesn't detect the
625 * case where the parent function's only reference to a 626 * case where the parent function's only reference to a
626 * subfunction is through a switch table. 627 * subfunction is through a jump table.
627 */ 628 */
628 if (!strstr(insn->func->name, ".cold.") && 629 if (!strstr(insn->func->name, ".cold.") &&
629 strstr(insn->jump_dest->func->name, ".cold.")) { 630 strstr(insn->jump_dest->func->name, ".cold.")) {
@@ -633,9 +634,8 @@ static int add_jump_destinations(struct objtool_file *file)
633 } else if (insn->jump_dest->func->pfunc != insn->func->pfunc && 634 } else if (insn->jump_dest->func->pfunc != insn->func->pfunc &&
634 insn->jump_dest->offset == insn->jump_dest->func->offset) { 635 insn->jump_dest->offset == insn->jump_dest->func->offset) {
635 636
636 /* sibling class */ 637 /* internal sibling call */
637 insn->call_dest = insn->jump_dest->func; 638 insn->call_dest = insn->jump_dest->func;
638 insn->jump_dest = NULL;
639 } 639 }
640 } 640 }
641 } 641 }
@@ -896,20 +896,26 @@ out:
896 return ret; 896 return ret;
897} 897}
898 898
899static int add_switch_table(struct objtool_file *file, struct instruction *insn, 899static int add_jump_table(struct objtool_file *file, struct instruction *insn,
900 struct rela *table, struct rela *next_table) 900 struct rela *table)
901{ 901{
902 struct rela *rela = table; 902 struct rela *rela = table;
903 struct instruction *alt_insn; 903 struct instruction *dest_insn;
904 struct alternative *alt; 904 struct alternative *alt;
905 struct symbol *pfunc = insn->func->pfunc; 905 struct symbol *pfunc = insn->func->pfunc;
906 unsigned int prev_offset = 0; 906 unsigned int prev_offset = 0;
907 907
908 list_for_each_entry_from(rela, &table->rela_sec->rela_list, list) { 908 /*
909 if (rela == next_table) 909 * Each @rela is a switch table relocation which points to the target
910 * instruction.
911 */
912 list_for_each_entry_from(rela, &table->sec->rela_list, list) {
913
914 /* Check for the end of the table: */
915 if (rela != table && rela->jump_table_start)
910 break; 916 break;
911 917
912 /* Make sure the switch table entries are consecutive: */ 918 /* Make sure the table entries are consecutive: */
913 if (prev_offset && rela->offset != prev_offset + 8) 919 if (prev_offset && rela->offset != prev_offset + 8)
914 break; 920 break;
915 921
@@ -918,12 +924,12 @@ static int add_switch_table(struct objtool_file *file, struct instruction *insn,
918 rela->addend == pfunc->offset) 924 rela->addend == pfunc->offset)
919 break; 925 break;
920 926
921 alt_insn = find_insn(file, rela->sym->sec, rela->addend); 927 dest_insn = find_insn(file, rela->sym->sec, rela->addend);
922 if (!alt_insn) 928 if (!dest_insn)
923 break; 929 break;
924 930
925 /* Make sure the jmp dest is in the function or subfunction: */ 931 /* Make sure the destination is in the same function: */
926 if (alt_insn->func->pfunc != pfunc) 932 if (!dest_insn->func || dest_insn->func->pfunc != pfunc)
927 break; 933 break;
928 934
929 alt = malloc(sizeof(*alt)); 935 alt = malloc(sizeof(*alt));
@@ -932,7 +938,7 @@ static int add_switch_table(struct objtool_file *file, struct instruction *insn,
932 return -1; 938 return -1;
933 } 939 }
934 940
935 alt->insn = alt_insn; 941 alt->insn = dest_insn;
936 list_add_tail(&alt->list, &insn->alts); 942 list_add_tail(&alt->list, &insn->alts);
937 prev_offset = rela->offset; 943 prev_offset = rela->offset;
938 } 944 }
@@ -947,7 +953,7 @@ static int add_switch_table(struct objtool_file *file, struct instruction *insn,
947} 953}
948 954
949/* 955/*
950 * find_switch_table() - Given a dynamic jump, find the switch jump table in 956 * find_jump_table() - Given a dynamic jump, find the switch jump table in
951 * .rodata associated with it. 957 * .rodata associated with it.
952 * 958 *
953 * There are 3 basic patterns: 959 * There are 3 basic patterns:
@@ -989,13 +995,13 @@ static int add_switch_table(struct objtool_file *file, struct instruction *insn,
989 * 995 *
990 * NOTE: RETPOLINE made it harder still to decode dynamic jumps. 996 * NOTE: RETPOLINE made it harder still to decode dynamic jumps.
991 */ 997 */
992static struct rela *find_switch_table(struct objtool_file *file, 998static struct rela *find_jump_table(struct objtool_file *file,
993 struct symbol *func, 999 struct symbol *func,
994 struct instruction *insn) 1000 struct instruction *insn)
995{ 1001{
996 struct rela *text_rela, *rodata_rela; 1002 struct rela *text_rela, *table_rela;
997 struct instruction *orig_insn = insn; 1003 struct instruction *orig_insn = insn;
998 struct section *rodata_sec; 1004 struct section *table_sec;
999 unsigned long table_offset; 1005 unsigned long table_offset;
1000 1006
1001 /* 1007 /*
@@ -1028,42 +1034,52 @@ static struct rela *find_switch_table(struct objtool_file *file,
1028 continue; 1034 continue;
1029 1035
1030 table_offset = text_rela->addend; 1036 table_offset = text_rela->addend;
1031 rodata_sec = text_rela->sym->sec; 1037 table_sec = text_rela->sym->sec;
1032 1038
1033 if (text_rela->type == R_X86_64_PC32) 1039 if (text_rela->type == R_X86_64_PC32)
1034 table_offset += 4; 1040 table_offset += 4;
1035 1041
1036 /* 1042 /*
1037 * Make sure the .rodata address isn't associated with a 1043 * Make sure the .rodata address isn't associated with a
1038 * symbol. gcc jump tables are anonymous data. 1044 * symbol. GCC jump tables are anonymous data.
1045 *
1046 * Also support C jump tables which are in the same format as
1047 * switch jump tables. For objtool to recognize them, they
1048 * need to be placed in the C_JUMP_TABLE_SECTION section. They
1049 * have symbols associated with them.
1039 */ 1050 */
1040 if (find_symbol_containing(rodata_sec, table_offset)) 1051 if (find_symbol_containing(table_sec, table_offset) &&
1052 strcmp(table_sec->name, C_JUMP_TABLE_SECTION))
1041 continue; 1053 continue;
1042 1054
1043 rodata_rela = find_rela_by_dest(rodata_sec, table_offset); 1055 /* Each table entry has a rela associated with it. */
1044 if (rodata_rela) { 1056 table_rela = find_rela_by_dest(table_sec, table_offset);
1045 /* 1057 if (!table_rela)
1046 * Use of RIP-relative switch jumps is quite rare, and 1058 continue;
1047 * indicates a rare GCC quirk/bug which can leave dead
1048 * code behind.
1049 */
1050 if (text_rela->type == R_X86_64_PC32)
1051 file->ignore_unreachables = true;
1052 1059
1053 return rodata_rela; 1060 /*
1054 } 1061 * Use of RIP-relative switch jumps is quite rare, and
1062 * indicates a rare GCC quirk/bug which can leave dead code
1063 * behind.
1064 */
1065 if (text_rela->type == R_X86_64_PC32)
1066 file->ignore_unreachables = true;
1067
1068 return table_rela;
1055 } 1069 }
1056 1070
1057 return NULL; 1071 return NULL;
1058} 1072}
1059 1073
1060 1074/*
1061static int add_func_switch_tables(struct objtool_file *file, 1075 * First pass: Mark the head of each jump table so that in the next pass,
1062 struct symbol *func) 1076 * we know when a given jump table ends and the next one starts.
1077 */
1078static void mark_func_jump_tables(struct objtool_file *file,
1079 struct symbol *func)
1063{ 1080{
1064 struct instruction *insn, *last = NULL, *prev_jump = NULL; 1081 struct instruction *insn, *last = NULL;
1065 struct rela *rela, *prev_rela = NULL; 1082 struct rela *rela;
1066 int ret;
1067 1083
1068 func_for_each_insn_all(file, func, insn) { 1084 func_for_each_insn_all(file, func, insn) {
1069 if (!last) 1085 if (!last)
@@ -1071,7 +1087,7 @@ static int add_func_switch_tables(struct objtool_file *file,
1071 1087
1072 /* 1088 /*
1073 * Store back-pointers for unconditional forward jumps such 1089 * Store back-pointers for unconditional forward jumps such
1074 * that find_switch_table() can back-track using those and 1090 * that find_jump_table() can back-track using those and
1075 * avoid some potentially confusing code. 1091 * avoid some potentially confusing code.
1076 */ 1092 */
1077 if (insn->type == INSN_JUMP_UNCONDITIONAL && insn->jump_dest && 1093 if (insn->type == INSN_JUMP_UNCONDITIONAL && insn->jump_dest &&
@@ -1086,27 +1102,25 @@ static int add_func_switch_tables(struct objtool_file *file,
1086 if (insn->type != INSN_JUMP_DYNAMIC) 1102 if (insn->type != INSN_JUMP_DYNAMIC)
1087 continue; 1103 continue;
1088 1104
1089 rela = find_switch_table(file, func, insn); 1105 rela = find_jump_table(file, func, insn);
1090 if (!rela) 1106 if (rela) {
1091 continue; 1107 rela->jump_table_start = true;
1092 1108 insn->jump_table = rela;
1093 /*
1094 * We found a switch table, but we don't know yet how big it
1095 * is. Don't add it until we reach the end of the function or
1096 * the beginning of another switch table in the same function.
1097 */
1098 if (prev_jump) {
1099 ret = add_switch_table(file, prev_jump, prev_rela, rela);
1100 if (ret)
1101 return ret;
1102 } 1109 }
1103
1104 prev_jump = insn;
1105 prev_rela = rela;
1106 } 1110 }
1111}
1112
1113static int add_func_jump_tables(struct objtool_file *file,
1114 struct symbol *func)
1115{
1116 struct instruction *insn;
1117 int ret;
1107 1118
1108 if (prev_jump) { 1119 func_for_each_insn_all(file, func, insn) {
1109 ret = add_switch_table(file, prev_jump, prev_rela, NULL); 1120 if (!insn->jump_table)
1121 continue;
1122
1123 ret = add_jump_table(file, insn, insn->jump_table);
1110 if (ret) 1124 if (ret)
1111 return ret; 1125 return ret;
1112 } 1126 }
@@ -1119,7 +1133,7 @@ static int add_func_switch_tables(struct objtool_file *file,
1119 * section which contains a list of addresses within the function to jump to. 1133 * section which contains a list of addresses within the function to jump to.
1120 * This finds these jump tables and adds them to the insn->alts lists. 1134 * This finds these jump tables and adds them to the insn->alts lists.
1121 */ 1135 */
1122static int add_switch_table_alts(struct objtool_file *file) 1136static int add_jump_table_alts(struct objtool_file *file)
1123{ 1137{
1124 struct section *sec; 1138 struct section *sec;
1125 struct symbol *func; 1139 struct symbol *func;
@@ -1133,7 +1147,8 @@ static int add_switch_table_alts(struct objtool_file *file)
1133 if (func->type != STT_FUNC) 1147 if (func->type != STT_FUNC)
1134 continue; 1148 continue;
1135 1149
1136 ret = add_func_switch_tables(file, func); 1150 mark_func_jump_tables(file, func);
1151 ret = add_func_jump_tables(file, func);
1137 if (ret) 1152 if (ret)
1138 return ret; 1153 return ret;
1139 } 1154 }
@@ -1277,13 +1292,18 @@ static void mark_rodata(struct objtool_file *file)
1277 bool found = false; 1292 bool found = false;
1278 1293
1279 /* 1294 /*
1280 * This searches for the .rodata section or multiple .rodata.func_name 1295 * Search for the following rodata sections, each of which can
1281 * sections if -fdata-sections is being used. The .str.1.1 and .str.1.8 1296 * potentially contain jump tables:
1282 * rodata sections are ignored as they don't contain jump tables. 1297 *
1298 * - .rodata: can contain GCC switch tables
1299 * - .rodata.<func>: same, if -fdata-sections is being used
1300 * - .rodata..c_jump_table: contains C annotated jump tables
1301 *
1302 * .rodata.str1.* sections are ignored; they don't contain jump tables.
1283 */ 1303 */
1284 for_each_sec(file, sec) { 1304 for_each_sec(file, sec) {
1285 if (!strncmp(sec->name, ".rodata", 7) && 1305 if ((!strncmp(sec->name, ".rodata", 7) && !strstr(sec->name, ".str1.")) ||
1286 !strstr(sec->name, ".str1.")) { 1306 !strcmp(sec->name, C_JUMP_TABLE_SECTION)) {
1287 sec->rodata = true; 1307 sec->rodata = true;
1288 found = true; 1308 found = true;
1289 } 1309 }
@@ -1325,7 +1345,7 @@ static int decode_sections(struct objtool_file *file)
1325 if (ret) 1345 if (ret)
1326 return ret; 1346 return ret;
1327 1347
1328 ret = add_switch_table_alts(file); 1348 ret = add_jump_table_alts(file);
1329 if (ret) 1349 if (ret)
1330 return ret; 1350 return ret;
1331 1351
@@ -1873,12 +1893,12 @@ static bool insn_state_match(struct instruction *insn, struct insn_state *state)
1873static inline bool func_uaccess_safe(struct symbol *func) 1893static inline bool func_uaccess_safe(struct symbol *func)
1874{ 1894{
1875 if (func) 1895 if (func)
1876 return func->alias->uaccess_safe; 1896 return func->uaccess_safe;
1877 1897
1878 return false; 1898 return false;
1879} 1899}
1880 1900
1881static inline const char *insn_dest_name(struct instruction *insn) 1901static inline const char *call_dest_name(struct instruction *insn)
1882{ 1902{
1883 if (insn->call_dest) 1903 if (insn->call_dest)
1884 return insn->call_dest->name; 1904 return insn->call_dest->name;
@@ -1890,13 +1910,13 @@ static int validate_call(struct instruction *insn, struct insn_state *state)
1890{ 1910{
1891 if (state->uaccess && !func_uaccess_safe(insn->call_dest)) { 1911 if (state->uaccess && !func_uaccess_safe(insn->call_dest)) {
1892 WARN_FUNC("call to %s() with UACCESS enabled", 1912 WARN_FUNC("call to %s() with UACCESS enabled",
1893 insn->sec, insn->offset, insn_dest_name(insn)); 1913 insn->sec, insn->offset, call_dest_name(insn));
1894 return 1; 1914 return 1;
1895 } 1915 }
1896 1916
1897 if (state->df) { 1917 if (state->df) {
1898 WARN_FUNC("call to %s() with DF set", 1918 WARN_FUNC("call to %s() with DF set",
1899 insn->sec, insn->offset, insn_dest_name(insn)); 1919 insn->sec, insn->offset, call_dest_name(insn));
1900 return 1; 1920 return 1;
1901 } 1921 }
1902 1922
@@ -1920,13 +1940,12 @@ static int validate_sibling_call(struct instruction *insn, struct insn_state *st
1920 * each instruction and validate all the rules described in 1940 * each instruction and validate all the rules described in
1921 * tools/objtool/Documentation/stack-validation.txt. 1941 * tools/objtool/Documentation/stack-validation.txt.
1922 */ 1942 */
1923static int validate_branch(struct objtool_file *file, struct instruction *first, 1943static int validate_branch(struct objtool_file *file, struct symbol *func,
1924 struct insn_state state) 1944 struct instruction *first, struct insn_state state)
1925{ 1945{
1926 struct alternative *alt; 1946 struct alternative *alt;
1927 struct instruction *insn, *next_insn; 1947 struct instruction *insn, *next_insn;
1928 struct section *sec; 1948 struct section *sec;
1929 struct symbol *func = NULL;
1930 int ret; 1949 int ret;
1931 1950
1932 insn = first; 1951 insn = first;
@@ -1947,9 +1966,6 @@ static int validate_branch(struct objtool_file *file, struct instruction *first,
1947 return 1; 1966 return 1;
1948 } 1967 }
1949 1968
1950 if (insn->func)
1951 func = insn->func->pfunc;
1952
1953 if (func && insn->ignore) { 1969 if (func && insn->ignore) {
1954 WARN_FUNC("BUG: why am I validating an ignored function?", 1970 WARN_FUNC("BUG: why am I validating an ignored function?",
1955 sec, insn->offset); 1971 sec, insn->offset);
@@ -1971,7 +1987,7 @@ static int validate_branch(struct objtool_file *file, struct instruction *first,
1971 1987
1972 i = insn; 1988 i = insn;
1973 save_insn = NULL; 1989 save_insn = NULL;
1974 func_for_each_insn_continue_reverse(file, insn->func, i) { 1990 func_for_each_insn_continue_reverse(file, func, i) {
1975 if (i->save) { 1991 if (i->save) {
1976 save_insn = i; 1992 save_insn = i;
1977 break; 1993 break;
@@ -2017,7 +2033,7 @@ static int validate_branch(struct objtool_file *file, struct instruction *first,
2017 if (alt->skip_orig) 2033 if (alt->skip_orig)
2018 skip_orig = true; 2034 skip_orig = true;
2019 2035
2020 ret = validate_branch(file, alt->insn, state); 2036 ret = validate_branch(file, func, alt->insn, state);
2021 if (ret) { 2037 if (ret) {
2022 if (backtrace) 2038 if (backtrace)
2023 BT_FUNC("(alt)", insn); 2039 BT_FUNC("(alt)", insn);
@@ -2055,7 +2071,7 @@ static int validate_branch(struct objtool_file *file, struct instruction *first,
2055 2071
2056 if (state.bp_scratch) { 2072 if (state.bp_scratch) {
2057 WARN("%s uses BP as a scratch register", 2073 WARN("%s uses BP as a scratch register",
2058 insn->func->name); 2074 func->name);
2059 return 1; 2075 return 1;
2060 } 2076 }
2061 2077
@@ -2067,36 +2083,28 @@ static int validate_branch(struct objtool_file *file, struct instruction *first,
2067 if (ret) 2083 if (ret)
2068 return ret; 2084 return ret;
2069 2085
2070 if (insn->type == INSN_CALL) { 2086 if (!no_fp && func && !is_fentry_call(insn) &&
2071 if (is_fentry_call(insn)) 2087 !has_valid_stack_frame(&state)) {
2072 break;
2073
2074 ret = dead_end_function(file, insn->call_dest);
2075 if (ret == 1)
2076 return 0;
2077 if (ret == -1)
2078 return 1;
2079 }
2080
2081 if (!no_fp && func && !has_valid_stack_frame(&state)) {
2082 WARN_FUNC("call without frame pointer save/setup", 2088 WARN_FUNC("call without frame pointer save/setup",
2083 sec, insn->offset); 2089 sec, insn->offset);
2084 return 1; 2090 return 1;
2085 } 2091 }
2092
2093 if (dead_end_function(file, insn->call_dest))
2094 return 0;
2095
2086 break; 2096 break;
2087 2097
2088 case INSN_JUMP_CONDITIONAL: 2098 case INSN_JUMP_CONDITIONAL:
2089 case INSN_JUMP_UNCONDITIONAL: 2099 case INSN_JUMP_UNCONDITIONAL:
2090 if (func && !insn->jump_dest) { 2100 if (func && is_sibling_call(insn)) {
2091 ret = validate_sibling_call(insn, &state); 2101 ret = validate_sibling_call(insn, &state);
2092 if (ret) 2102 if (ret)
2093 return ret; 2103 return ret;
2094 2104
2095 } else if (insn->jump_dest && 2105 } else if (insn->jump_dest) {
2096 (!func || !insn->jump_dest->func || 2106 ret = validate_branch(file, func,
2097 insn->jump_dest->func->pfunc == func)) { 2107 insn->jump_dest, state);
2098 ret = validate_branch(file, insn->jump_dest,
2099 state);
2100 if (ret) { 2108 if (ret) {
2101 if (backtrace) 2109 if (backtrace)
2102 BT_FUNC("(branch)", insn); 2110 BT_FUNC("(branch)", insn);
@@ -2110,13 +2118,17 @@ static int validate_branch(struct objtool_file *file, struct instruction *first,
2110 break; 2118 break;
2111 2119
2112 case INSN_JUMP_DYNAMIC: 2120 case INSN_JUMP_DYNAMIC:
2113 if (func && list_empty(&insn->alts)) { 2121 case INSN_JUMP_DYNAMIC_CONDITIONAL:
2122 if (func && is_sibling_call(insn)) {
2114 ret = validate_sibling_call(insn, &state); 2123 ret = validate_sibling_call(insn, &state);
2115 if (ret) 2124 if (ret)
2116 return ret; 2125 return ret;
2117 } 2126 }
2118 2127
2119 return 0; 2128 if (insn->type == INSN_JUMP_DYNAMIC)
2129 return 0;
2130
2131 break;
2120 2132
2121 case INSN_CONTEXT_SWITCH: 2133 case INSN_CONTEXT_SWITCH:
2122 if (func && (!next_insn || !next_insn->hint)) { 2134 if (func && (!next_insn || !next_insn->hint)) {
@@ -2162,7 +2174,7 @@ static int validate_branch(struct objtool_file *file, struct instruction *first,
2162 break; 2174 break;
2163 2175
2164 case INSN_CLAC: 2176 case INSN_CLAC:
2165 if (!state.uaccess && insn->func) { 2177 if (!state.uaccess && func) {
2166 WARN_FUNC("redundant UACCESS disable", sec, insn->offset); 2178 WARN_FUNC("redundant UACCESS disable", sec, insn->offset);
2167 return 1; 2179 return 1;
2168 } 2180 }
@@ -2183,7 +2195,7 @@ static int validate_branch(struct objtool_file *file, struct instruction *first,
2183 break; 2195 break;
2184 2196
2185 case INSN_CLD: 2197 case INSN_CLD:
2186 if (!state.df && insn->func) 2198 if (!state.df && func)
2187 WARN_FUNC("redundant CLD", sec, insn->offset); 2199 WARN_FUNC("redundant CLD", sec, insn->offset);
2188 2200
2189 state.df = false; 2201 state.df = false;
@@ -2222,7 +2234,7 @@ static int validate_unwind_hints(struct objtool_file *file)
2222 2234
2223 for_each_insn(file, insn) { 2235 for_each_insn(file, insn) {
2224 if (insn->hint && !insn->visited) { 2236 if (insn->hint && !insn->visited) {
2225 ret = validate_branch(file, insn, state); 2237 ret = validate_branch(file, insn->func, insn, state);
2226 if (ret && backtrace) 2238 if (ret && backtrace)
2227 BT_FUNC("<=== (hint)", insn); 2239 BT_FUNC("<=== (hint)", insn);
2228 warnings += ret; 2240 warnings += ret;
@@ -2345,16 +2357,25 @@ static int validate_functions(struct objtool_file *file)
2345 2357
2346 for_each_sec(file, sec) { 2358 for_each_sec(file, sec) {
2347 list_for_each_entry(func, &sec->symbol_list, list) { 2359 list_for_each_entry(func, &sec->symbol_list, list) {
2348 if (func->type != STT_FUNC || func->pfunc != func) 2360 if (func->type != STT_FUNC)
2361 continue;
2362
2363 if (!func->len) {
2364 WARN("%s() is missing an ELF size annotation",
2365 func->name);
2366 warnings++;
2367 }
2368
2369 if (func->pfunc != func || func->alias != func)
2349 continue; 2370 continue;
2350 2371
2351 insn = find_insn(file, sec, func->offset); 2372 insn = find_insn(file, sec, func->offset);
2352 if (!insn || insn->ignore) 2373 if (!insn || insn->ignore || insn->visited)
2353 continue; 2374 continue;
2354 2375
2355 state.uaccess = func->alias->uaccess_safe; 2376 state.uaccess = func->uaccess_safe;
2356 2377
2357 ret = validate_branch(file, insn, state); 2378 ret = validate_branch(file, func, insn, state);
2358 if (ret && backtrace) 2379 if (ret && backtrace)
2359 BT_FUNC("<=== (func)", insn); 2380 BT_FUNC("<=== (func)", insn);
2360 warnings += ret; 2381 warnings += ret;
@@ -2407,7 +2428,7 @@ int check(const char *_objname, bool orc)
2407 2428
2408 objname = _objname; 2429 objname = _objname;
2409 2430
2410 file.elf = elf_open(objname, orc ? O_RDWR : O_RDONLY); 2431 file.elf = elf_read(objname, orc ? O_RDWR : O_RDONLY);
2411 if (!file.elf) 2432 if (!file.elf)
2412 return 1; 2433 return 1;
2413 2434
diff --git a/tools/objtool/check.h b/tools/objtool/check.h
index cb60b9acf5cf..b881fafcf55d 100644
--- a/tools/objtool/check.h
+++ b/tools/objtool/check.h
@@ -31,13 +31,14 @@ struct instruction {
31 struct section *sec; 31 struct section *sec;
32 unsigned long offset; 32 unsigned long offset;
33 unsigned int len; 33 unsigned int len;
34 unsigned char type; 34 enum insn_type type;
35 unsigned long immediate; 35 unsigned long immediate;
36 bool alt_group, visited, dead_end, ignore, hint, save, restore, ignore_alts; 36 bool alt_group, visited, dead_end, ignore, hint, save, restore, ignore_alts;
37 bool retpoline_safe; 37 bool retpoline_safe;
38 struct symbol *call_dest; 38 struct symbol *call_dest;
39 struct instruction *jump_dest; 39 struct instruction *jump_dest;
40 struct instruction *first_jump_src; 40 struct instruction *first_jump_src;
41 struct rela *jump_table;
41 struct list_head alts; 42 struct list_head alts;
42 struct symbol *func; 43 struct symbol *func;
43 struct stack_op stack_op; 44 struct stack_op stack_op;
diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c
index e99e1be19ad9..edba4745f25a 100644
--- a/tools/objtool/elf.c
+++ b/tools/objtool/elf.c
@@ -278,7 +278,7 @@ static int read_symbols(struct elf *elf)
278 } 278 }
279 279
280 if (sym->offset == s->offset) { 280 if (sym->offset == s->offset) {
281 if (sym->len == s->len && alias == sym) 281 if (sym->len && sym->len == s->len && alias == sym)
282 alias = s; 282 alias = s;
283 283
284 if (sym->len >= s->len) { 284 if (sym->len >= s->len) {
@@ -385,7 +385,7 @@ static int read_relas(struct elf *elf)
385 rela->offset = rela->rela.r_offset; 385 rela->offset = rela->rela.r_offset;
386 symndx = GELF_R_SYM(rela->rela.r_info); 386 symndx = GELF_R_SYM(rela->rela.r_info);
387 rela->sym = find_symbol_by_index(elf, symndx); 387 rela->sym = find_symbol_by_index(elf, symndx);
388 rela->rela_sec = sec; 388 rela->sec = sec;
389 if (!rela->sym) { 389 if (!rela->sym) {
390 WARN("can't find rela entry symbol %d for %s", 390 WARN("can't find rela entry symbol %d for %s",
391 symndx, sec->name); 391 symndx, sec->name);
@@ -401,7 +401,7 @@ static int read_relas(struct elf *elf)
401 return 0; 401 return 0;
402} 402}
403 403
404struct elf *elf_open(const char *name, int flags) 404struct elf *elf_read(const char *name, int flags)
405{ 405{
406 struct elf *elf; 406 struct elf *elf;
407 Elf_Cmd cmd; 407 Elf_Cmd cmd;
@@ -463,7 +463,7 @@ struct section *elf_create_section(struct elf *elf, const char *name,
463{ 463{
464 struct section *sec, *shstrtab; 464 struct section *sec, *shstrtab;
465 size_t size = entsize * nr; 465 size_t size = entsize * nr;
466 struct Elf_Scn *s; 466 Elf_Scn *s;
467 Elf_Data *data; 467 Elf_Data *data;
468 468
469 sec = malloc(sizeof(*sec)); 469 sec = malloc(sizeof(*sec));
diff --git a/tools/objtool/elf.h b/tools/objtool/elf.h
index e44ca5d51871..44150204db4d 100644
--- a/tools/objtool/elf.h
+++ b/tools/objtool/elf.h
@@ -57,11 +57,12 @@ struct rela {
57 struct list_head list; 57 struct list_head list;
58 struct hlist_node hash; 58 struct hlist_node hash;
59 GElf_Rela rela; 59 GElf_Rela rela;
60 struct section *rela_sec; 60 struct section *sec;
61 struct symbol *sym; 61 struct symbol *sym;
62 unsigned int type; 62 unsigned int type;
63 unsigned long offset; 63 unsigned long offset;
64 int addend; 64 int addend;
65 bool jump_table_start;
65}; 66};
66 67
67struct elf { 68struct elf {
@@ -74,7 +75,7 @@ struct elf {
74}; 75};
75 76
76 77
77struct elf *elf_open(const char *name, int flags); 78struct elf *elf_read(const char *name, int flags);
78struct section *find_section_by_name(struct elf *elf, const char *name); 79struct section *find_section_by_name(struct elf *elf, const char *name);
79struct symbol *find_symbol_by_offset(struct section *sec, unsigned long offset); 80struct symbol *find_symbol_by_offset(struct section *sec, unsigned long offset);
80struct symbol *find_symbol_by_name(struct elf *elf, const char *name); 81struct symbol *find_symbol_by_name(struct elf *elf, const char *name);
diff --git a/tools/pci/Makefile b/tools/pci/Makefile
index 6876ee4bd78c..4b95a5176355 100644
--- a/tools/pci/Makefile
+++ b/tools/pci/Makefile
@@ -18,7 +18,6 @@ ALL_TARGETS := pcitest
18ALL_PROGRAMS := $(patsubst %,$(OUTPUT)%,$(ALL_TARGETS)) 18ALL_PROGRAMS := $(patsubst %,$(OUTPUT)%,$(ALL_TARGETS))
19 19
20SCRIPTS := pcitest.sh 20SCRIPTS := pcitest.sh
21ALL_SCRIPTS := $(patsubst %,$(OUTPUT)%,$(SCRIPTS))
22 21
23all: $(ALL_PROGRAMS) 22all: $(ALL_PROGRAMS)
24 23
@@ -47,10 +46,10 @@ clean:
47 46
48install: $(ALL_PROGRAMS) 47install: $(ALL_PROGRAMS)
49 install -d -m 755 $(DESTDIR)$(bindir); \ 48 install -d -m 755 $(DESTDIR)$(bindir); \
50 for program in $(ALL_PROGRAMS) pcitest.sh; do \ 49 for program in $(ALL_PROGRAMS); do \
51 install $$program $(DESTDIR)$(bindir); \ 50 install $$program $(DESTDIR)$(bindir); \
52 done; \ 51 done; \
53 for script in $(ALL_SCRIPTS); do \ 52 for script in $(SCRIPTS); do \
54 install $$script $(DESTDIR)$(bindir); \ 53 install $$script $(DESTDIR)$(bindir); \
55 done 54 done
56 55
diff --git a/tools/pci/pcitest.c b/tools/pci/pcitest.c
index cb7a47dfd8b6..cb1e51fcc84e 100644
--- a/tools/pci/pcitest.c
+++ b/tools/pci/pcitest.c
@@ -36,15 +36,15 @@ struct pci_test {
36 unsigned long size; 36 unsigned long size;
37}; 37};
38 38
39static void run_test(struct pci_test *test) 39static int run_test(struct pci_test *test)
40{ 40{
41 long ret; 41 int ret = -EINVAL;
42 int fd; 42 int fd;
43 43
44 fd = open(test->device, O_RDWR); 44 fd = open(test->device, O_RDWR);
45 if (fd < 0) { 45 if (fd < 0) {
46 perror("can't open PCI Endpoint Test device"); 46 perror("can't open PCI Endpoint Test device");
47 return; 47 return -ENODEV;
48 } 48 }
49 49
50 if (test->barnum >= 0 && test->barnum <= 5) { 50 if (test->barnum >= 0 && test->barnum <= 5) {
@@ -212,7 +212,7 @@ usage:
212 "\t-r Read buffer test\n" 212 "\t-r Read buffer test\n"
213 "\t-w Write buffer test\n" 213 "\t-w Write buffer test\n"
214 "\t-c Copy buffer test\n" 214 "\t-c Copy buffer test\n"
215 "\t-s <size> Size of buffer {default: 100KB}\n", 215 "\t-s <size> Size of buffer {default: 100KB}\n"
216 "\t-h Print this help message\n", 216 "\t-h Print this help message\n",
217 argv[0]); 217 argv[0]);
218 return -EINVAL; 218 return -EINVAL;
diff --git a/tools/perf/Documentation/perf-probe.txt b/tools/perf/Documentation/perf-probe.txt
index b6866a05edd2..ed3ecfa422e1 100644
--- a/tools/perf/Documentation/perf-probe.txt
+++ b/tools/perf/Documentation/perf-probe.txt
@@ -194,12 +194,13 @@ PROBE ARGUMENT
194-------------- 194--------------
195Each probe argument follows below syntax. 195Each probe argument follows below syntax.
196 196
197 [NAME=]LOCALVAR|$retval|%REG|@SYMBOL[:TYPE] 197 [NAME=]LOCALVAR|$retval|%REG|@SYMBOL[:TYPE][@user]
198 198
199'NAME' specifies the name of this argument (optional). You can use the name of local variable, local data structure member (e.g. var->field, var.field2), local array with fixed index (e.g. array[1], var->array[0], var->pointer[2]), or kprobe-tracer argument format (e.g. $retval, %ax, etc). Note that the name of this argument will be set as the last member name if you specify a local data structure member (e.g. field2 for 'var->field1.field2'.) 199'NAME' specifies the name of this argument (optional). You can use the name of local variable, local data structure member (e.g. var->field, var.field2), local array with fixed index (e.g. array[1], var->array[0], var->pointer[2]), or kprobe-tracer argument format (e.g. $retval, %ax, etc). Note that the name of this argument will be set as the last member name if you specify a local data structure member (e.g. field2 for 'var->field1.field2'.)
200'$vars' and '$params' special arguments are also available for NAME, '$vars' is expanded to the local variables (including function parameters) which can access at given probe point. '$params' is expanded to only the function parameters. 200'$vars' and '$params' special arguments are also available for NAME, '$vars' is expanded to the local variables (including function parameters) which can access at given probe point. '$params' is expanded to only the function parameters.
201'TYPE' casts the type of this argument (optional). If omitted, perf probe automatically set the type based on debuginfo (*). Currently, basic types (u8/u16/u32/u64/s8/s16/s32/s64), hexadecimal integers (x/x8/x16/x32/x64), signedness casting (u/s), "string" and bitfield are supported. (see TYPES for detail) 201'TYPE' casts the type of this argument (optional). If omitted, perf probe automatically set the type based on debuginfo (*). Currently, basic types (u8/u16/u32/u64/s8/s16/s32/s64), hexadecimal integers (x/x8/x16/x32/x64), signedness casting (u/s), "string" and bitfield are supported. (see TYPES for detail)
202On x86 systems %REG is always the short form of the register: for example %AX. %RAX or %EAX is not valid. 202On x86 systems %REG is always the short form of the register: for example %AX. %RAX or %EAX is not valid.
203"@user" is a special attribute which means the LOCALVAR will be treated as a user-space memory. This is only valid for kprobe event.
203 204
204TYPES 205TYPES
205----- 206-----
diff --git a/tools/perf/MANIFEST b/tools/perf/MANIFEST
index 6a5de44b2de9..70f1ff4e2eb4 100644
--- a/tools/perf/MANIFEST
+++ b/tools/perf/MANIFEST
@@ -18,3 +18,4 @@ tools/lib/find_bit.c
18tools/lib/bitmap.c 18tools/lib/bitmap.c
19tools/lib/str_error_r.c 19tools/lib/str_error_r.c
20tools/lib/vsprintf.c 20tools/lib/vsprintf.c
21tools/lib/zalloc.c
diff --git a/tools/perf/arch/arm/annotate/instructions.c b/tools/perf/arch/arm/annotate/instructions.c
index f64516d5b23e..c7d1a69b894f 100644
--- a/tools/perf/arch/arm/annotate/instructions.c
+++ b/tools/perf/arch/arm/annotate/instructions.c
@@ -1,5 +1,6 @@
1// SPDX-License-Identifier: GPL-2.0 1// SPDX-License-Identifier: GPL-2.0
2#include <linux/compiler.h> 2#include <linux/compiler.h>
3#include <linux/zalloc.h>
3#include <sys/types.h> 4#include <sys/types.h>
4#include <regex.h> 5#include <regex.h>
5 6
diff --git a/tools/perf/arch/arm/util/auxtrace.c b/tools/perf/arch/arm/util/auxtrace.c
index 1ce6bdbda561..02014740a1aa 100644
--- a/tools/perf/arch/arm/util/auxtrace.c
+++ b/tools/perf/arch/arm/util/auxtrace.c
@@ -6,6 +6,7 @@
6 6
7#include <stdbool.h> 7#include <stdbool.h>
8#include <linux/coresight-pmu.h> 8#include <linux/coresight-pmu.h>
9#include <linux/zalloc.h>
9 10
10#include "../../util/auxtrace.h" 11#include "../../util/auxtrace.h"
11#include "../../util/evlist.h" 12#include "../../util/evlist.h"
diff --git a/tools/perf/arch/arm/util/cs-etm.c b/tools/perf/arch/arm/util/cs-etm.c
index 2b83cc8e4796..4208974c24f8 100644
--- a/tools/perf/arch/arm/util/cs-etm.c
+++ b/tools/perf/arch/arm/util/cs-etm.c
@@ -12,6 +12,7 @@
12#include <linux/kernel.h> 12#include <linux/kernel.h>
13#include <linux/log2.h> 13#include <linux/log2.h>
14#include <linux/types.h> 14#include <linux/types.h>
15#include <linux/zalloc.h>
15 16
16#include "cs-etm.h" 17#include "cs-etm.h"
17#include "../../perf.h" 18#include "../../perf.h"
diff --git a/tools/perf/arch/arm64/util/arm-spe.c b/tools/perf/arch/arm64/util/arm-spe.c
index 5ccfce87e693..2c009aa74633 100644
--- a/tools/perf/arch/arm64/util/arm-spe.c
+++ b/tools/perf/arch/arm64/util/arm-spe.c
@@ -8,6 +8,7 @@
8#include <linux/types.h> 8#include <linux/types.h>
9#include <linux/bitops.h> 9#include <linux/bitops.h>
10#include <linux/log2.h> 10#include <linux/log2.h>
11#include <linux/zalloc.h>
11#include <time.h> 12#include <time.h>
12 13
13#include "../../util/cpumap.h" 14#include "../../util/cpumap.h"
diff --git a/tools/perf/arch/common.c b/tools/perf/arch/common.c
index f3824ca7c20b..1a9e22f78c22 100644
--- a/tools/perf/arch/common.c
+++ b/tools/perf/arch/common.c
@@ -1,9 +1,10 @@
1// SPDX-License-Identifier: GPL-2.0 1// SPDX-License-Identifier: GPL-2.0
2#include <stdio.h> 2#include <stdio.h>
3#include <stdlib.h>
3#include "common.h" 4#include "common.h"
4#include "../util/env.h" 5#include "../util/env.h"
5#include "../util/util.h"
6#include "../util/debug.h" 6#include "../util/debug.h"
7#include <linux/zalloc.h>
7 8
8const char *const arc_triplets[] = { 9const char *const arc_triplets[] = {
9 "arc-linux-", 10 "arc-linux-",
diff --git a/tools/perf/arch/powerpc/util/perf_regs.c b/tools/perf/arch/powerpc/util/perf_regs.c
index 34d5134681d9..f14102b85509 100644
--- a/tools/perf/arch/powerpc/util/perf_regs.c
+++ b/tools/perf/arch/powerpc/util/perf_regs.c
@@ -2,12 +2,14 @@
2#include <errno.h> 2#include <errno.h>
3#include <string.h> 3#include <string.h>
4#include <regex.h> 4#include <regex.h>
5#include <linux/zalloc.h>
5 6
6#include "../../perf.h" 7#include "../../perf.h"
7#include "../../util/util.h"
8#include "../../util/perf_regs.h" 8#include "../../util/perf_regs.h"
9#include "../../util/debug.h" 9#include "../../util/debug.h"
10 10
11#include <linux/kernel.h>
12
11const struct sample_reg sample_reg_masks[] = { 13const struct sample_reg sample_reg_masks[] = {
12 SMPL_REG(r0, PERF_REG_POWERPC_R0), 14 SMPL_REG(r0, PERF_REG_POWERPC_R0),
13 SMPL_REG(r1, PERF_REG_POWERPC_R1), 15 SMPL_REG(r1, PERF_REG_POWERPC_R1),
diff --git a/tools/perf/arch/s390/util/auxtrace.c b/tools/perf/arch/s390/util/auxtrace.c
index 44c857388897..0fe1be93f375 100644
--- a/tools/perf/arch/s390/util/auxtrace.c
+++ b/tools/perf/arch/s390/util/auxtrace.c
@@ -3,6 +3,7 @@
3#include <linux/types.h> 3#include <linux/types.h>
4#include <linux/bitops.h> 4#include <linux/bitops.h>
5#include <linux/log2.h> 5#include <linux/log2.h>
6#include <linux/zalloc.h>
6 7
7#include "../../util/evlist.h" 8#include "../../util/evlist.h"
8#include "../../util/auxtrace.h" 9#include "../../util/auxtrace.h"
diff --git a/tools/perf/arch/s390/util/header.c b/tools/perf/arch/s390/util/header.c
index a25896135abe..8b0b018d896a 100644
--- a/tools/perf/arch/s390/util/header.c
+++ b/tools/perf/arch/s390/util/header.c
@@ -12,9 +12,10 @@
12#include <stdio.h> 12#include <stdio.h>
13#include <string.h> 13#include <string.h>
14#include <linux/ctype.h> 14#include <linux/ctype.h>
15#include <linux/kernel.h>
16#include <linux/zalloc.h>
15 17
16#include "../../util/header.h" 18#include "../../util/header.h"
17#include "../../util/util.h"
18 19
19#define SYSINFO_MANU "Manufacturer:" 20#define SYSINFO_MANU "Manufacturer:"
20#define SYSINFO_TYPE "Type:" 21#define SYSINFO_TYPE "Type:"
diff --git a/tools/perf/arch/x86/util/event.c b/tools/perf/arch/x86/util/event.c
index 675a0213044d..a3a0b6884779 100644
--- a/tools/perf/arch/x86/util/event.c
+++ b/tools/perf/arch/x86/util/event.c
@@ -1,11 +1,11 @@
1// SPDX-License-Identifier: GPL-2.0 1// SPDX-License-Identifier: GPL-2.0
2#include <linux/types.h> 2#include <linux/types.h>
3#include <linux/string.h> 3#include <linux/string.h>
4#include <linux/zalloc.h>
4 5
5#include "../../util/machine.h" 6#include "../../util/machine.h"
6#include "../../util/tool.h" 7#include "../../util/tool.h"
7#include "../../util/map.h" 8#include "../../util/map.h"
8#include "../../util/util.h"
9#include "../../util/debug.h" 9#include "../../util/debug.h"
10 10
11#if defined(__x86_64__) 11#if defined(__x86_64__)
diff --git a/tools/perf/arch/x86/util/intel-bts.c b/tools/perf/arch/x86/util/intel-bts.c
index e6d4d9591c79..ec5c1bb84095 100644
--- a/tools/perf/arch/x86/util/intel-bts.c
+++ b/tools/perf/arch/x86/util/intel-bts.c
@@ -9,12 +9,12 @@
9#include <linux/types.h> 9#include <linux/types.h>
10#include <linux/bitops.h> 10#include <linux/bitops.h>
11#include <linux/log2.h> 11#include <linux/log2.h>
12#include <linux/zalloc.h>
12 13
13#include "../../util/cpumap.h" 14#include "../../util/cpumap.h"
14#include "../../util/evsel.h" 15#include "../../util/evsel.h"
15#include "../../util/evlist.h" 16#include "../../util/evlist.h"
16#include "../../util/session.h" 17#include "../../util/session.h"
17#include "../../util/util.h"
18#include "../../util/pmu.h" 18#include "../../util/pmu.h"
19#include "../../util/debug.h" 19#include "../../util/debug.h"
20#include "../../util/tsc.h" 20#include "../../util/tsc.h"
diff --git a/tools/perf/arch/x86/util/intel-pt.c b/tools/perf/arch/x86/util/intel-pt.c
index 9804098dcefb..609088c01e3a 100644
--- a/tools/perf/arch/x86/util/intel-pt.c
+++ b/tools/perf/arch/x86/util/intel-pt.c
@@ -10,6 +10,7 @@
10#include <linux/types.h> 10#include <linux/types.h>
11#include <linux/bitops.h> 11#include <linux/bitops.h>
12#include <linux/log2.h> 12#include <linux/log2.h>
13#include <linux/zalloc.h>
13#include <cpuid.h> 14#include <cpuid.h>
14 15
15#include "../../perf.h" 16#include "../../perf.h"
@@ -25,7 +26,6 @@
25#include "../../util/auxtrace.h" 26#include "../../util/auxtrace.h"
26#include "../../util/tsc.h" 27#include "../../util/tsc.h"
27#include "../../util/intel-pt.h" 28#include "../../util/intel-pt.h"
28#include "../../util/util.h"
29 29
30#define KiB(x) ((x) * 1024) 30#define KiB(x) ((x) * 1024)
31#define MiB(x) ((x) * 1024 * 1024) 31#define MiB(x) ((x) * 1024 * 1024)
diff --git a/tools/perf/arch/x86/util/perf_regs.c b/tools/perf/arch/x86/util/perf_regs.c
index 3666c0076df9..0d7b77ff0ae6 100644
--- a/tools/perf/arch/x86/util/perf_regs.c
+++ b/tools/perf/arch/x86/util/perf_regs.c
@@ -2,9 +2,9 @@
2#include <errno.h> 2#include <errno.h>
3#include <string.h> 3#include <string.h>
4#include <regex.h> 4#include <regex.h>
5#include <linux/zalloc.h>
5 6
6#include "../../perf.h" 7#include "../../perf.h"
7#include "../../util/util.h"
8#include "../../util/perf_regs.h" 8#include "../../util/perf_regs.h"
9#include "../../util/debug.h" 9#include "../../util/debug.h"
10 10
diff --git a/tools/perf/bench/futex-hash.c b/tools/perf/bench/futex-hash.c
index 9aa3a674829b..a80797763e1f 100644
--- a/tools/perf/bench/futex-hash.c
+++ b/tools/perf/bench/futex-hash.c
@@ -18,6 +18,7 @@
18#include <stdlib.h> 18#include <stdlib.h>
19#include <linux/compiler.h> 19#include <linux/compiler.h>
20#include <linux/kernel.h> 20#include <linux/kernel.h>
21#include <linux/zalloc.h>
21#include <sys/time.h> 22#include <sys/time.h>
22 23
23#include "../util/stat.h" 24#include "../util/stat.h"
@@ -214,7 +215,7 @@ int bench_futex_hash(int argc, const char **argv)
214 &worker[i].futex[nfutexes-1], t); 215 &worker[i].futex[nfutexes-1], t);
215 } 216 }
216 217
217 free(worker[i].futex); 218 zfree(&worker[i].futex);
218 } 219 }
219 220
220 print_summary(); 221 print_summary();
diff --git a/tools/perf/bench/futex-lock-pi.c b/tools/perf/bench/futex-lock-pi.c
index 8e9c4753e304..d02330a69745 100644
--- a/tools/perf/bench/futex-lock-pi.c
+++ b/tools/perf/bench/futex-lock-pi.c
@@ -12,6 +12,7 @@
12#include <subcmd/parse-options.h> 12#include <subcmd/parse-options.h>
13#include <linux/compiler.h> 13#include <linux/compiler.h>
14#include <linux/kernel.h> 14#include <linux/kernel.h>
15#include <linux/zalloc.h>
15#include <errno.h> 16#include <errno.h>
16#include "bench.h" 17#include "bench.h"
17#include "futex.h" 18#include "futex.h"
@@ -217,7 +218,7 @@ int bench_futex_lock_pi(int argc, const char **argv)
217 worker[i].tid, worker[i].futex, t); 218 worker[i].tid, worker[i].futex, t);
218 219
219 if (multi) 220 if (multi)
220 free(worker[i].futex); 221 zfree(&worker[i].futex);
221 } 222 }
222 223
223 print_summary(); 224 print_summary();
diff --git a/tools/perf/bench/mem-functions.c b/tools/perf/bench/mem-functions.c
index 0251dd348124..64dc994c72ea 100644
--- a/tools/perf/bench/mem-functions.c
+++ b/tools/perf/bench/mem-functions.c
@@ -9,7 +9,6 @@
9 9
10#include "debug.h" 10#include "debug.h"
11#include "../perf.h" 11#include "../perf.h"
12#include "../util/util.h"
13#include <subcmd/parse-options.h> 12#include <subcmd/parse-options.h>
14#include "../util/header.h" 13#include "../util/header.h"
15#include "../util/cloexec.h" 14#include "../util/cloexec.h"
@@ -24,6 +23,7 @@
24#include <sys/time.h> 23#include <sys/time.h>
25#include <errno.h> 24#include <errno.h>
26#include <linux/time64.h> 25#include <linux/time64.h>
26#include <linux/zalloc.h>
27 27
28#define K 1024 28#define K 1024
29 29
diff --git a/tools/perf/bench/numa.c b/tools/perf/bench/numa.c
index a7784554a80d..a640ca7aaada 100644
--- a/tools/perf/bench/numa.c
+++ b/tools/perf/bench/numa.c
@@ -11,7 +11,6 @@
11 11
12#include "../perf.h" 12#include "../perf.h"
13#include "../builtin.h" 13#include "../builtin.h"
14#include "../util/util.h"
15#include <subcmd/parse-options.h> 14#include <subcmd/parse-options.h>
16#include "../util/cloexec.h" 15#include "../util/cloexec.h"
17 16
@@ -35,6 +34,7 @@
35#include <linux/kernel.h> 34#include <linux/kernel.h>
36#include <linux/time64.h> 35#include <linux/time64.h>
37#include <linux/numa.h> 36#include <linux/numa.h>
37#include <linux/zalloc.h>
38 38
39#include <numa.h> 39#include <numa.h>
40#include <numaif.h> 40#include <numaif.h>
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
index 77deb3a40596..e0aa14faf2b5 100644
--- a/tools/perf/builtin-annotate.c
+++ b/tools/perf/builtin-annotate.c
@@ -8,11 +8,11 @@
8 */ 8 */
9#include "builtin.h" 9#include "builtin.h"
10 10
11#include "util/util.h"
12#include "util/color.h" 11#include "util/color.h"
13#include <linux/list.h> 12#include <linux/list.h>
14#include "util/cache.h" 13#include "util/cache.h"
15#include <linux/rbtree.h> 14#include <linux/rbtree.h>
15#include <linux/zalloc.h>
16#include "util/symbol.h" 16#include "util/symbol.h"
17 17
18#include "perf.h" 18#include "perf.h"
diff --git a/tools/perf/builtin-bench.c b/tools/perf/builtin-bench.c
index 334c77ffc1d9..b8e7c38ef221 100644
--- a/tools/perf/builtin-bench.c
+++ b/tools/perf/builtin-bench.c
@@ -17,7 +17,6 @@
17 * epoll ... Event poll performance 17 * epoll ... Event poll performance
18 */ 18 */
19#include "perf.h" 19#include "perf.h"
20#include "util/util.h"
21#include <subcmd/parse-options.h> 20#include <subcmd/parse-options.h>
22#include "builtin.h" 21#include "builtin.h"
23#include "bench/bench.h" 22#include "bench/bench.h"
@@ -26,6 +25,7 @@
26#include <stdlib.h> 25#include <stdlib.h>
27#include <string.h> 26#include <string.h>
28#include <sys/prctl.h> 27#include <sys/prctl.h>
28#include <linux/zalloc.h>
29 29
30typedef int (*bench_fn_t)(int argc, const char **argv); 30typedef int (*bench_fn_t)(int argc, const char **argv);
31 31
diff --git a/tools/perf/builtin-c2c.c b/tools/perf/builtin-c2c.c
index 9e6cc868bdb4..e3776f5c2e01 100644
--- a/tools/perf/builtin-c2c.c
+++ b/tools/perf/builtin-c2c.c
@@ -15,9 +15,9 @@
15#include <linux/compiler.h> 15#include <linux/compiler.h>
16#include <linux/kernel.h> 16#include <linux/kernel.h>
17#include <linux/stringify.h> 17#include <linux/stringify.h>
18#include <linux/zalloc.h>
18#include <asm/bug.h> 19#include <asm/bug.h>
19#include <sys/param.h> 20#include <sys/param.h>
20#include "util.h"
21#include "debug.h" 21#include "debug.h"
22#include "builtin.h" 22#include "builtin.h"
23#include <subcmd/parse-options.h> 23#include <subcmd/parse-options.h>
diff --git a/tools/perf/builtin-config.c b/tools/perf/builtin-config.c
index d76f831f94c7..6c1284c87aaa 100644
--- a/tools/perf/builtin-config.c
+++ b/tools/perf/builtin-config.c
@@ -15,6 +15,7 @@
15#include "util/debug.h" 15#include "util/debug.h"
16#include "util/config.h" 16#include "util/config.h"
17#include <linux/string.h> 17#include <linux/string.h>
18#include <stdlib.h>
18 19
19static bool use_system_config, use_user_config; 20static bool use_system_config, use_user_config;
20 21
diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c
index f924b46910b5..f6f5dd15bea7 100644
--- a/tools/perf/builtin-diff.c
+++ b/tools/perf/builtin-diff.c
@@ -16,12 +16,12 @@
16#include "util/tool.h" 16#include "util/tool.h"
17#include "util/sort.h" 17#include "util/sort.h"
18#include "util/symbol.h" 18#include "util/symbol.h"
19#include "util/util.h"
20#include "util/data.h" 19#include "util/data.h"
21#include "util/config.h" 20#include "util/config.h"
22#include "util/time-utils.h" 21#include "util/time-utils.h"
23#include "util/annotate.h" 22#include "util/annotate.h"
24#include "util/map.h" 23#include "util/map.h"
24#include <linux/zalloc.h>
25 25
26#include <errno.h> 26#include <errno.h>
27#include <inttypes.h> 27#include <inttypes.h>
diff --git a/tools/perf/builtin-ftrace.c b/tools/perf/builtin-ftrace.c
index 9c228c55e1fb..66d5a6658daf 100644
--- a/tools/perf/builtin-ftrace.c
+++ b/tools/perf/builtin-ftrace.c
@@ -431,7 +431,7 @@ static void delete_filter_func(struct list_head *head)
431 struct filter_entry *pos, *tmp; 431 struct filter_entry *pos, *tmp;
432 432
433 list_for_each_entry_safe(pos, tmp, head, list) { 433 list_for_each_entry_safe(pos, tmp, head, list) {
434 list_del(&pos->list); 434 list_del_init(&pos->list);
435 free(pos); 435 free(pos);
436 } 436 }
437} 437}
diff --git a/tools/perf/builtin-help.c b/tools/perf/builtin-help.c
index 3d29d0524a89..a83af92fb0d1 100644
--- a/tools/perf/builtin-help.c
+++ b/tools/perf/builtin-help.c
@@ -14,8 +14,10 @@
14#include <subcmd/help.h> 14#include <subcmd/help.h>
15#include "util/debug.h" 15#include "util/debug.h"
16#include <linux/kernel.h> 16#include <linux/kernel.h>
17#include <linux/zalloc.h>
17#include <errno.h> 18#include <errno.h>
18#include <stdio.h> 19#include <stdio.h>
20#include <stdlib.h>
19#include <sys/types.h> 21#include <sys/types.h>
20#include <sys/stat.h> 22#include <sys/stat.h>
21#include <unistd.h> 23#include <unistd.h>
diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c
index 8e0e06d3edfc..f4591a1438b4 100644
--- a/tools/perf/builtin-inject.c
+++ b/tools/perf/builtin-inject.c
@@ -224,7 +224,7 @@ static int perf_event__repipe_sample(struct perf_tool *tool,
224 struct perf_evsel *evsel, 224 struct perf_evsel *evsel,
225 struct machine *machine) 225 struct machine *machine)
226{ 226{
227 if (evsel->handler) { 227 if (evsel && evsel->handler) {
228 inject_handler f = evsel->handler; 228 inject_handler f = evsel->handler;
229 return f(tool, event, sample, evsel, machine); 229 return f(tool, event, sample, evsel, machine);
230 } 230 }
diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c
index 9bd3829de76d..9e5e60898083 100644
--- a/tools/perf/builtin-kmem.c
+++ b/tools/perf/builtin-kmem.c
@@ -4,7 +4,6 @@
4 4
5#include "util/evlist.h" 5#include "util/evlist.h"
6#include "util/evsel.h" 6#include "util/evsel.h"
7#include "util/util.h"
8#include "util/config.h" 7#include "util/config.h"
9#include "util/map.h" 8#include "util/map.h"
10#include "util/symbol.h" 9#include "util/symbol.h"
@@ -26,6 +25,7 @@
26#include <linux/kernel.h> 25#include <linux/kernel.h>
27#include <linux/rbtree.h> 26#include <linux/rbtree.h>
28#include <linux/string.h> 27#include <linux/string.h>
28#include <linux/zalloc.h>
29#include <errno.h> 29#include <errno.h>
30#include <inttypes.h> 30#include <inttypes.h>
31#include <locale.h> 31#include <locale.h>
diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c
index dbb6f737a3e2..b33c83489120 100644
--- a/tools/perf/builtin-kvm.c
+++ b/tools/perf/builtin-kvm.c
@@ -5,7 +5,6 @@
5#include "util/evsel.h" 5#include "util/evsel.h"
6#include "util/evlist.h" 6#include "util/evlist.h"
7#include "util/term.h" 7#include "util/term.h"
8#include "util/util.h"
9#include "util/cache.h" 8#include "util/cache.h"
10#include "util/symbol.h" 9#include "util/symbol.h"
11#include "util/thread.h" 10#include "util/thread.h"
@@ -32,6 +31,7 @@
32 31
33#include <linux/kernel.h> 32#include <linux/kernel.h>
34#include <linux/time64.h> 33#include <linux/time64.h>
34#include <linux/zalloc.h>
35#include <errno.h> 35#include <errno.h>
36#include <inttypes.h> 36#include <inttypes.h>
37#include <poll.h> 37#include <poll.h>
diff --git a/tools/perf/builtin-lock.c b/tools/perf/builtin-lock.c
index b9810a8d350a..574e30ec6d7c 100644
--- a/tools/perf/builtin-lock.c
+++ b/tools/perf/builtin-lock.c
@@ -6,7 +6,6 @@
6 6
7#include "util/evlist.h" 7#include "util/evlist.h"
8#include "util/evsel.h" 8#include "util/evsel.h"
9#include "util/util.h"
10#include "util/cache.h" 9#include "util/cache.h"
11#include "util/symbol.h" 10#include "util/symbol.h"
12#include "util/thread.h" 11#include "util/thread.h"
@@ -30,6 +29,7 @@
30#include <linux/list.h> 29#include <linux/list.h>
31#include <linux/hash.h> 30#include <linux/hash.h>
32#include <linux/kernel.h> 31#include <linux/kernel.h>
32#include <linux/zalloc.h>
33 33
34static struct perf_session *session; 34static struct perf_session *session;
35 35
@@ -454,7 +454,7 @@ broken:
454 /* broken lock sequence, discard it */ 454 /* broken lock sequence, discard it */
455 ls->discard = 1; 455 ls->discard = 1;
456 bad_hist[BROKEN_ACQUIRE]++; 456 bad_hist[BROKEN_ACQUIRE]++;
457 list_del(&seq->list); 457 list_del_init(&seq->list);
458 free(seq); 458 free(seq);
459 goto end; 459 goto end;
460 default: 460 default:
@@ -515,7 +515,7 @@ static int report_lock_acquired_event(struct perf_evsel *evsel,
515 /* broken lock sequence, discard it */ 515 /* broken lock sequence, discard it */
516 ls->discard = 1; 516 ls->discard = 1;
517 bad_hist[BROKEN_ACQUIRED]++; 517 bad_hist[BROKEN_ACQUIRED]++;
518 list_del(&seq->list); 518 list_del_init(&seq->list);
519 free(seq); 519 free(seq);
520 goto end; 520 goto end;
521 default: 521 default:
@@ -570,7 +570,7 @@ static int report_lock_contended_event(struct perf_evsel *evsel,
570 /* broken lock sequence, discard it */ 570 /* broken lock sequence, discard it */
571 ls->discard = 1; 571 ls->discard = 1;
572 bad_hist[BROKEN_CONTENDED]++; 572 bad_hist[BROKEN_CONTENDED]++;
573 list_del(&seq->list); 573 list_del_init(&seq->list);
574 free(seq); 574 free(seq);
575 goto end; 575 goto end;
576 default: 576 default:
@@ -639,7 +639,7 @@ static int report_lock_release_event(struct perf_evsel *evsel,
639 639
640 ls->nr_release++; 640 ls->nr_release++;
641free_seq: 641free_seq:
642 list_del(&seq->list); 642 list_del_init(&seq->list);
643 free(seq); 643 free(seq);
644end: 644end:
645 return 0; 645 return 0;
diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c
index 8bb124e55c6d..6418782951a4 100644
--- a/tools/perf/builtin-probe.c
+++ b/tools/perf/builtin-probe.c
@@ -19,7 +19,6 @@
19#include "perf.h" 19#include "perf.h"
20#include "builtin.h" 20#include "builtin.h"
21#include "namespaces.h" 21#include "namespaces.h"
22#include "util/util.h"
23#include "util/strlist.h" 22#include "util/strlist.h"
24#include "util/strfilter.h" 23#include "util/strfilter.h"
25#include "util/symbol.h" 24#include "util/symbol.h"
@@ -28,6 +27,7 @@
28#include "util/probe-finder.h" 27#include "util/probe-finder.h"
29#include "util/probe-event.h" 28#include "util/probe-event.h"
30#include "util/probe-file.h" 29#include "util/probe-file.h"
30#include <linux/zalloc.h>
31 31
32#define DEFAULT_VAR_FILTER "!__k???tab_* & !__crc_*" 32#define DEFAULT_VAR_FILTER "!__k???tab_* & !__crc_*"
33#define DEFAULT_FUNC_FILTER "!_*" 33#define DEFAULT_FUNC_FILTER "!_*"
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index dca55997934e..8779cee58185 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -11,7 +11,6 @@
11#include "perf.h" 11#include "perf.h"
12 12
13#include "util/build-id.h" 13#include "util/build-id.h"
14#include "util/util.h"
15#include <subcmd/parse-options.h> 14#include <subcmd/parse-options.h>
16#include "util/parse-events.h" 15#include "util/parse-events.h"
17#include "util/config.h" 16#include "util/config.h"
@@ -54,6 +53,7 @@
54#include <sys/mman.h> 53#include <sys/mman.h>
55#include <sys/wait.h> 54#include <sys/wait.h>
56#include <linux/time64.h> 55#include <linux/time64.h>
56#include <linux/zalloc.h>
57 57
58struct switch_output { 58struct switch_output {
59 bool enabled; 59 bool enabled;
@@ -1110,7 +1110,7 @@ record__switch_output(struct record *rec, bool at_exit)
1110 rec->switch_output.cur_file = n; 1110 rec->switch_output.cur_file = n;
1111 if (rec->switch_output.filenames[n]) { 1111 if (rec->switch_output.filenames[n]) {
1112 remove(rec->switch_output.filenames[n]); 1112 remove(rec->switch_output.filenames[n]);
1113 free(rec->switch_output.filenames[n]); 1113 zfree(&rec->switch_output.filenames[n]);
1114 } 1114 }
1115 rec->switch_output.filenames[n] = new_filename; 1115 rec->switch_output.filenames[n] = new_filename;
1116 } else { 1116 } else {
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index aef59f318a67..abf0b9b8f566 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -8,7 +8,6 @@
8 */ 8 */
9#include "builtin.h" 9#include "builtin.h"
10 10
11#include "util/util.h"
12#include "util/config.h" 11#include "util/config.h"
13 12
14#include "util/annotate.h" 13#include "util/annotate.h"
@@ -16,6 +15,7 @@
16#include <linux/list.h> 15#include <linux/list.h>
17#include <linux/rbtree.h> 16#include <linux/rbtree.h>
18#include <linux/err.h> 17#include <linux/err.h>
18#include <linux/zalloc.h>
19#include "util/map.h" 19#include "util/map.h"
20#include "util/symbol.h" 20#include "util/symbol.h"
21#include "util/callchain.h" 21#include "util/callchain.h"
@@ -298,7 +298,7 @@ static int process_read_event(struct perf_tool *tool,
298 struct report *rep = container_of(tool, struct report, tool); 298 struct report *rep = container_of(tool, struct report, tool);
299 299
300 if (rep->show_threads) { 300 if (rep->show_threads) {
301 const char *name = evsel ? perf_evsel__name(evsel) : "unknown"; 301 const char *name = perf_evsel__name(evsel);
302 int err = perf_read_values_add_value(&rep->show_threads_values, 302 int err = perf_read_values_add_value(&rep->show_threads_values,
303 event->read.pid, event->read.tid, 303 event->read.pid, event->read.tid,
304 evsel->idx, 304 evsel->idx,
diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c
index 1519989961ff..56d1907b1215 100644
--- a/tools/perf/builtin-sched.c
+++ b/tools/perf/builtin-sched.c
@@ -2,7 +2,6 @@
2#include "builtin.h" 2#include "builtin.h"
3#include "perf.h" 3#include "perf.h"
4 4
5#include "util/util.h"
6#include "util/evlist.h" 5#include "util/evlist.h"
7#include "util/cache.h" 6#include "util/cache.h"
8#include "util/evsel.h" 7#include "util/evsel.h"
@@ -26,6 +25,7 @@
26 25
27#include <linux/kernel.h> 26#include <linux/kernel.h>
28#include <linux/log2.h> 27#include <linux/log2.h>
28#include <linux/zalloc.h>
29#include <sys/prctl.h> 29#include <sys/prctl.h>
30#include <sys/resource.h> 30#include <sys/resource.h>
31#include <inttypes.h> 31#include <inttypes.h>
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index 2f6232f1bfdc..8f24865596af 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -14,7 +14,6 @@
14#include "util/symbol.h" 14#include "util/symbol.h"
15#include "util/thread.h" 15#include "util/thread.h"
16#include "util/trace-event.h" 16#include "util/trace-event.h"
17#include "util/util.h"
18#include "util/evlist.h" 17#include "util/evlist.h"
19#include "util/evsel.h" 18#include "util/evsel.h"
20#include "util/sort.h" 19#include "util/sort.h"
@@ -34,6 +33,7 @@
34#include <linux/kernel.h> 33#include <linux/kernel.h>
35#include <linux/stringify.h> 34#include <linux/stringify.h>
36#include <linux/time64.h> 35#include <linux/time64.h>
36#include <linux/zalloc.h>
37#include <sys/utsname.h> 37#include <sys/utsname.h>
38#include "asm/bug.h" 38#include "asm/bug.h"
39#include "util/mem-events.h" 39#include "util/mem-events.h"
@@ -2289,6 +2289,12 @@ static int process_switch_event(struct perf_tool *tool,
2289 if (perf_event__process_switch(tool, event, sample, machine) < 0) 2289 if (perf_event__process_switch(tool, event, sample, machine) < 0)
2290 return -1; 2290 return -1;
2291 2291
2292 if (scripting_ops && scripting_ops->process_switch)
2293 scripting_ops->process_switch(event, sample, machine);
2294
2295 if (!script->show_switch_events)
2296 return 0;
2297
2292 thread = machine__findnew_thread(machine, sample->pid, 2298 thread = machine__findnew_thread(machine, sample->pid,
2293 sample->tid); 2299 sample->tid);
2294 if (thread == NULL) { 2300 if (thread == NULL) {
@@ -2467,7 +2473,7 @@ static int __cmd_script(struct perf_script *script)
2467 script->tool.mmap = process_mmap_event; 2473 script->tool.mmap = process_mmap_event;
2468 script->tool.mmap2 = process_mmap2_event; 2474 script->tool.mmap2 = process_mmap2_event;
2469 } 2475 }
2470 if (script->show_switch_events) 2476 if (script->show_switch_events || (scripting_ops && scripting_ops->process_switch))
2471 script->tool.context_switch = process_switch_event; 2477 script->tool.context_switch = process_switch_event;
2472 if (script->show_namespace_events) 2478 if (script->show_namespace_events)
2473 script->tool.namespaces = process_namespaces_event; 2479 script->tool.namespaces = process_namespaces_event;
@@ -3752,7 +3758,8 @@ int cmd_script(int argc, const char **argv)
3752 goto out_delete; 3758 goto out_delete;
3753 3759
3754 uname(&uts); 3760 uname(&uts);
3755 if (!strcmp(uts.machine, session->header.env.arch) || 3761 if (data.is_pipe || /* assume pipe_mode indicates native_arch */
3762 !strcmp(uts.machine, session->header.env.arch) ||
3756 (!strcmp(uts.machine, "x86_64") && 3763 (!strcmp(uts.machine, "x86_64") &&
3757 !strcmp(session->header.env.arch, "i386"))) 3764 !strcmp(session->header.env.arch, "i386")))
3758 native_arch = true; 3765 native_arch = true;
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index e5e19b461061..b55a534b4de0 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -43,7 +43,6 @@
43#include "perf.h" 43#include "perf.h"
44#include "builtin.h" 44#include "builtin.h"
45#include "util/cgroup.h" 45#include "util/cgroup.h"
46#include "util/util.h"
47#include <subcmd/parse-options.h> 46#include <subcmd/parse-options.h>
48#include "util/parse-events.h" 47#include "util/parse-events.h"
49#include "util/pmu.h" 48#include "util/pmu.h"
@@ -67,6 +66,7 @@
67#include "asm/bug.h" 66#include "asm/bug.h"
68 67
69#include <linux/time64.h> 68#include <linux/time64.h>
69#include <linux/zalloc.h>
70#include <api/fs/fs.h> 70#include <api/fs/fs.h>
71#include <errno.h> 71#include <errno.h>
72#include <signal.h> 72#include <signal.h>
@@ -1349,8 +1349,8 @@ static int add_default_attributes(void)
1349 fprintf(stderr, 1349 fprintf(stderr,
1350 "Cannot set up top down events %s: %d\n", 1350 "Cannot set up top down events %s: %d\n",
1351 str, err); 1351 str, err);
1352 free(str);
1353 parse_events_print_error(&errinfo, str); 1352 parse_events_print_error(&errinfo, str);
1353 free(str);
1354 return -1; 1354 return -1;
1355 } 1355 }
1356 } else { 1356 } else {
@@ -1586,7 +1586,7 @@ static void runtime_stat_delete(struct perf_stat_config *config)
1586 for (i = 0; i < config->stats_num; i++) 1586 for (i = 0; i < config->stats_num; i++)
1587 runtime_stat__exit(&config->stats[i]); 1587 runtime_stat__exit(&config->stats[i]);
1588 1588
1589 free(config->stats); 1589 zfree(&config->stats);
1590} 1590}
1591 1591
1592static const char * const stat_report_usage[] = { 1592static const char * const stat_report_usage[] = {
@@ -2003,7 +2003,7 @@ int cmd_stat(int argc, const char **argv)
2003 perf_stat__exit_aggr_mode(); 2003 perf_stat__exit_aggr_mode();
2004 perf_evlist__free_stats(evsel_list); 2004 perf_evlist__free_stats(evsel_list);
2005out: 2005out:
2006 free(stat_config.walltime_run); 2006 zfree(&stat_config.walltime_run);
2007 2007
2008 if (smi_cost && smi_reset) 2008 if (smi_cost && smi_reset)
2009 sysfs__write_int(FREEZE_ON_SMI_PATH, 0); 2009 sysfs__write_int(FREEZE_ON_SMI_PATH, 0);
diff --git a/tools/perf/builtin-timechart.c b/tools/perf/builtin-timechart.c
index 145a19668114..4bde3fa245d1 100644
--- a/tools/perf/builtin-timechart.c
+++ b/tools/perf/builtin-timechart.c
@@ -13,9 +13,6 @@
13#include <traceevent/event-parse.h> 13#include <traceevent/event-parse.h>
14 14
15#include "builtin.h" 15#include "builtin.h"
16
17#include "util/util.h"
18
19#include "util/color.h" 16#include "util/color.h"
20#include <linux/list.h> 17#include <linux/list.h>
21#include "util/cache.h" 18#include "util/cache.h"
@@ -24,6 +21,7 @@
24#include <linux/kernel.h> 21#include <linux/kernel.h>
25#include <linux/rbtree.h> 22#include <linux/rbtree.h>
26#include <linux/time64.h> 23#include <linux/time64.h>
24#include <linux/zalloc.h>
27#include "util/symbol.h" 25#include "util/symbol.h"
28#include "util/thread.h" 26#include "util/thread.h"
29#include "util/callchain.h" 27#include "util/callchain.h"
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index 6d40a4ef58c5..b46b3c9f57a0 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -101,7 +101,7 @@ static void perf_top__resize(struct perf_top *top)
101 101
102static int perf_top__parse_source(struct perf_top *top, struct hist_entry *he) 102static int perf_top__parse_source(struct perf_top *top, struct hist_entry *he)
103{ 103{
104 struct perf_evsel *evsel = hists_to_evsel(he->hists); 104 struct perf_evsel *evsel;
105 struct symbol *sym; 105 struct symbol *sym;
106 struct annotation *notes; 106 struct annotation *notes;
107 struct map *map; 107 struct map *map;
@@ -110,6 +110,8 @@ static int perf_top__parse_source(struct perf_top *top, struct hist_entry *he)
110 if (!he || !he->ms.sym) 110 if (!he || !he->ms.sym)
111 return -1; 111 return -1;
112 112
113 evsel = hists_to_evsel(he->hists);
114
113 sym = he->ms.sym; 115 sym = he->ms.sym;
114 map = he->ms.map; 116 map = he->ms.map;
115 117
@@ -226,7 +228,7 @@ static void perf_top__record_precise_ip(struct perf_top *top,
226static void perf_top__show_details(struct perf_top *top) 228static void perf_top__show_details(struct perf_top *top)
227{ 229{
228 struct hist_entry *he = top->sym_filter_entry; 230 struct hist_entry *he = top->sym_filter_entry;
229 struct perf_evsel *evsel = hists_to_evsel(he->hists); 231 struct perf_evsel *evsel;
230 struct annotation *notes; 232 struct annotation *notes;
231 struct symbol *symbol; 233 struct symbol *symbol;
232 int more; 234 int more;
@@ -234,6 +236,8 @@ static void perf_top__show_details(struct perf_top *top)
234 if (!he) 236 if (!he)
235 return; 237 return;
236 238
239 evsel = hists_to_evsel(he->hists);
240
237 symbol = he->ms.sym; 241 symbol = he->ms.sym;
238 notes = symbol__annotation(symbol); 242 notes = symbol__annotation(symbol);
239 243
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index d0eb7224dd36..4f0bbffee05f 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -19,6 +19,7 @@
19#include <api/fs/tracing_path.h> 19#include <api/fs/tracing_path.h>
20#include <bpf/bpf.h> 20#include <bpf/bpf.h>
21#include "util/bpf_map.h" 21#include "util/bpf_map.h"
22#include "util/rlimit.h"
22#include "builtin.h" 23#include "builtin.h"
23#include "util/cgroup.h" 24#include "util/cgroup.h"
24#include "util/color.h" 25#include "util/color.h"
@@ -61,6 +62,7 @@
61#include <linux/random.h> 62#include <linux/random.h>
62#include <linux/stringify.h> 63#include <linux/stringify.h>
63#include <linux/time64.h> 64#include <linux/time64.h>
65#include <linux/zalloc.h>
64#include <fcntl.h> 66#include <fcntl.h>
65#include <sys/sysmacros.h> 67#include <sys/sysmacros.h>
66 68
@@ -1038,10 +1040,10 @@ static struct thread_trace *thread_trace__new(void)
1038{ 1040{
1039 struct thread_trace *ttrace = zalloc(sizeof(struct thread_trace)); 1041 struct thread_trace *ttrace = zalloc(sizeof(struct thread_trace));
1040 1042
1041 if (ttrace) 1043 if (ttrace) {
1042 ttrace->files.max = -1; 1044 ttrace->files.max = -1;
1043 1045 ttrace->syscall_stats = intlist__new(NULL);
1044 ttrace->syscall_stats = intlist__new(NULL); 1046 }
1045 1047
1046 return ttrace; 1048 return ttrace;
1047} 1049}
@@ -3863,6 +3865,15 @@ int cmd_trace(int argc, const char **argv)
3863 goto out; 3865 goto out;
3864 } 3866 }
3865 3867
3868 /*
3869 * Parsing .perfconfig may entail creating a BPF event, that may need
3870 * to create BPF maps, so bump RLIM_MEMLOCK as the default 64K setting
3871 * is too small. This affects just this process, not touching the
3872 * global setting. If it fails we'll get something in 'perf trace -v'
3873 * to help diagnose the problem.
3874 */
3875 rlimit__bump_memlock();
3876
3866 err = perf_config(trace__config, &trace); 3877 err = perf_config(trace__config, &trace);
3867 if (err) 3878 if (err)
3868 goto out; 3879 goto out;
diff --git a/tools/perf/builtin-version.c b/tools/perf/builtin-version.c
index f470144d1a70..bf114ca9ca87 100644
--- a/tools/perf/builtin-version.c
+++ b/tools/perf/builtin-version.c
@@ -19,6 +19,7 @@ static struct version version;
19static struct option version_options[] = { 19static struct option version_options[] = {
20 OPT_BOOLEAN(0, "build-options", &version.build_options, 20 OPT_BOOLEAN(0, "build-options", &version.build_options,
21 "display the build options"), 21 "display the build options"),
22 OPT_END(),
22}; 23};
23 24
24static const char * const version_usage[] = { 25static const char * const version_usage[] = {
diff --git a/tools/perf/perf.c b/tools/perf/perf.c
index 2123b3cc4dcf..97e2628ea5dd 100644
--- a/tools/perf/perf.c
+++ b/tools/perf/perf.c
@@ -18,7 +18,6 @@
18#include "util/bpf-loader.h" 18#include "util/bpf-loader.h"
19#include "util/debug.h" 19#include "util/debug.h"
20#include "util/event.h" 20#include "util/event.h"
21#include "util/util.h"
22#include <api/fs/fs.h> 21#include <api/fs/fs.h>
23#include <api/fs/tracing_path.h> 22#include <api/fs/tracing_path.h>
24#include <errno.h> 23#include <errno.h>
@@ -30,6 +29,7 @@
30#include <sys/stat.h> 29#include <sys/stat.h>
31#include <unistd.h> 30#include <unistd.h>
32#include <linux/kernel.h> 31#include <linux/kernel.h>
32#include <linux/zalloc.h>
33 33
34const char perf_usage_string[] = 34const char perf_usage_string[] =
35 "perf [--version] [--help] [OPTIONS] COMMAND [ARGS]"; 35 "perf [--version] [--help] [OPTIONS] COMMAND [ARGS]";
diff --git a/tools/perf/pmu-events/arch/s390/cf_m8561/basic.json b/tools/perf/pmu-events/arch/s390/cf_m8561/basic.json
new file mode 100644
index 000000000000..17fb5241928b
--- /dev/null
+++ b/tools/perf/pmu-events/arch/s390/cf_m8561/basic.json
@@ -0,0 +1,58 @@
1[
2 {
3 "Unit": "CPU-M-CF",
4 "EventCode": "0",
5 "EventName": "CPU_CYCLES",
6 "BriefDescription": "CPU Cycles",
7 "PublicDescription": "Cycle Count"
8 },
9 {
10 "Unit": "CPU-M-CF",
11 "EventCode": "1",
12 "EventName": "INSTRUCTIONS",
13 "BriefDescription": "Instructions",
14 "PublicDescription": "Instruction Count"
15 },
16 {
17 "Unit": "CPU-M-CF",
18 "EventCode": "2",
19 "EventName": "L1I_DIR_WRITES",
20 "BriefDescription": "L1I Directory Writes",
21 "PublicDescription": "Level-1 I-Cache Directory Write Count"
22 },
23 {
24 "Unit": "CPU-M-CF",
25 "EventCode": "3",
26 "EventName": "L1I_PENALTY_CYCLES",
27 "BriefDescription": "L1I Penalty Cycles",
28 "PublicDescription": "Level-1 I-Cache Penalty Cycle Count"
29 },
30 {
31 "Unit": "CPU-M-CF",
32 "EventCode": "4",
33 "EventName": "L1D_DIR_WRITES",
34 "BriefDescription": "L1D Directory Writes",
35 "PublicDescription": "Level-1 D-Cache Directory Write Count"
36 },
37 {
38 "Unit": "CPU-M-CF",
39 "EventCode": "5",
40 "EventName": "L1D_PENALTY_CYCLES",
41 "BriefDescription": "L1D Penalty Cycles",
42 "PublicDescription": "Level-1 D-Cache Penalty Cycle Count"
43 },
44 {
45 "Unit": "CPU-M-CF",
46 "EventCode": "32",
47 "EventName": "PROBLEM_STATE_CPU_CYCLES",
48 "BriefDescription": "Problem-State CPU Cycles",
49 "PublicDescription": "Problem-State Cycle Count"
50 },
51 {
52 "Unit": "CPU-M-CF",
53 "EventCode": "33",
54 "EventName": "PROBLEM_STATE_INSTRUCTIONS",
55 "BriefDescription": "Problem-State Instructions",
56 "PublicDescription": "Problem-State Instruction Count"
57 },
58]
diff --git a/tools/perf/pmu-events/arch/s390/cf_m8561/crypto.json b/tools/perf/pmu-events/arch/s390/cf_m8561/crypto.json
new file mode 100644
index 000000000000..db286f19e7b6
--- /dev/null
+++ b/tools/perf/pmu-events/arch/s390/cf_m8561/crypto.json
@@ -0,0 +1,114 @@
1[
2 {
3 "Unit": "CPU-M-CF",
4 "EventCode": "64",
5 "EventName": "PRNG_FUNCTIONS",
6 "BriefDescription": "PRNG Functions",
7 "PublicDescription": "Total number of the PRNG functions issued by the CPU"
8 },
9 {
10 "Unit": "CPU-M-CF",
11 "EventCode": "65",
12 "EventName": "PRNG_CYCLES",
13 "BriefDescription": "PRNG Cycles",
14 "PublicDescription": "Total number of CPU cycles when the DEA/AES coprocessor is busy performing PRNG functions issued by the CPU"
15 },
16 {
17 "Unit": "CPU-M-CF",
18 "EventCode": "66",
19 "EventName": "PRNG_BLOCKED_FUNCTIONS",
20 "BriefDescription": "PRNG Blocked Functions",
21 "PublicDescription": "Total number of the PRNG functions that are issued by the CPU and are blocked because the DEA/AES coprocessor is busy performing a function issued by another CPU"
22 },
23 {
24 "Unit": "CPU-M-CF",
25 "EventCode": "67",
26 "EventName": "PRNG_BLOCKED_CYCLES",
27 "BriefDescription": "PRNG Blocked Cycles",
28 "PublicDescription": "Total number of CPU cycles blocked for the PRNG functions issued by the CPU because the DEA/AES coprocessor is busy performing a function issued by another CPU"
29 },
30 {
31 "Unit": "CPU-M-CF",
32 "EventCode": "68",
33 "EventName": "SHA_FUNCTIONS",
34 "BriefDescription": "SHA Functions",
35 "PublicDescription": "Total number of SHA functions issued by the CPU"
36 },
37 {
38 "Unit": "CPU-M-CF",
39 "EventCode": "69",
40 "EventName": "SHA_CYCLES",
41 "BriefDescription": "SHA Cycles",
42 "PublicDescription": "Total number of CPU cycles when the SHA coprocessor is busy performing the SHA functions issued by the CPU"
43 },
44 {
45 "Unit": "CPU-M-CF",
46 "EventCode": "70",
47 "EventName": "SHA_BLOCKED_FUNCTIONS",
48 "BriefDescription": "SHA Blocked Functions",
49 "PublicDescription": "Total number of the SHA functions that are issued by the CPU and are blocked because the SHA coprocessor is busy performing a function issued by another CPU"
50 },
51 {
52 "Unit": "CPU-M-CF",
53 "EventCode": "71",
54 "EventName": "SHA_BLOCKED_CYCLES",
55 "BriefDescription": "SHA Bloced Cycles",
56 "PublicDescription": "Total number of CPU cycles blocked for the SHA functions issued by the CPU because the SHA coprocessor is busy performing a function issued by another CPU"
57 },
58 {
59 "Unit": "CPU-M-CF",
60 "EventCode": "72",
61 "EventName": "DEA_FUNCTIONS",
62 "BriefDescription": "DEA Functions",
63 "PublicDescription": "Total number of the DEA functions issued by the CPU"
64 },
65 {
66 "Unit": "CPU-M-CF",
67 "EventCode": "73",
68 "EventName": "DEA_CYCLES",
69 "BriefDescription": "DEA Cycles",
70 "PublicDescription": "Total number of CPU cycles when the DEA/AES coprocessor is busy performing the DEA functions issued by the CPU"
71 },
72 {
73 "Unit": "CPU-M-CF",
74 "EventCode": "74",
75 "EventName": "DEA_BLOCKED_FUNCTIONS",
76 "BriefDescription": "DEA Blocked Functions",
77 "PublicDescription": "Total number of the DEA functions that are issued by the CPU and are blocked because the DEA/AES coprocessor is busy performing a function issued by another CPU"
78 },
79 {
80 "Unit": "CPU-M-CF",
81 "EventCode": "75",
82 "EventName": "DEA_BLOCKED_CYCLES",
83 "BriefDescription": "DEA Blocked Cycles",
84 "PublicDescription": "Total number of CPU cycles blocked for the DEA functions issued by the CPU because the DEA/AES coprocessor is busy performing a function issued by another CPU"
85 },
86 {
87 "Unit": "CPU-M-CF",
88 "EventCode": "76",
89 "EventName": "AES_FUNCTIONS",
90 "BriefDescription": "AES Functions",
91 "PublicDescription": "Total number of AES functions issued by the CPU"
92 },
93 {
94 "Unit": "CPU-M-CF",
95 "EventCode": "77",
96 "EventName": "AES_CYCLES",
97 "BriefDescription": "AES Cycles",
98 "PublicDescription": "Total number of CPU cycles when the DEA/AES coprocessor is busy performing the AES functions issued by the CPU"
99 },
100 {
101 "Unit": "CPU-M-CF",
102 "EventCode": "78",
103 "EventName": "AES_BLOCKED_FUNCTIONS",
104 "BriefDescription": "AES Blocked Functions",
105 "PublicDescription": "Total number of AES functions that are issued by the CPU and are blocked because the DEA/AES coprocessor is busy performing a function issued by another CPU"
106 },
107 {
108 "Unit": "CPU-M-CF",
109 "EventCode": "79",
110 "EventName": "AES_BLOCKED_CYCLES",
111 "BriefDescription": "AES Blocked Cycles",
112 "PublicDescription": "Total number of CPU cycles blocked for the AES functions issued by the CPU because the DEA/AES coprocessor is busy performing a function issued by another CPU"
113 },
114]
diff --git a/tools/perf/pmu-events/arch/s390/cf_m8561/crypto6.json b/tools/perf/pmu-events/arch/s390/cf_m8561/crypto6.json
new file mode 100644
index 000000000000..5e36bc2468d0
--- /dev/null
+++ b/tools/perf/pmu-events/arch/s390/cf_m8561/crypto6.json
@@ -0,0 +1,30 @@
1[
2 {
3 "Unit": "CPU-M-CF",
4 "EventCode": "80",
5 "EventName": "ECC_FUNCTION_COUNT",
6 "BriefDescription": "ECC Function Count",
7 "PublicDescription": "Long ECC function Count"
8 },
9 {
10 "Unit": "CPU-M-CF",
11 "EventCode": "81",
12 "EventName": "ECC_CYCLES_COUNT",
13 "BriefDescription": "ECC Cycles Count",
14 "PublicDescription": "Long ECC Function cycles count"
15 },
16 {
17 "Unit": "CPU-M-CF",
18 "EventCode": "82",
19 "EventName": "ECC_BLOCKED_FUNCTION_COUNT",
20 "BriefDescription": "Ecc Blocked Function Count",
21 "PublicDescription": "Long ECC blocked function count"
22 },
23 {
24 "Unit": "CPU-M-CF",
25 "EventCode": "83",
26 "EventName": "ECC_BLOCKED_CYCLES_COUNT",
27 "BriefDescription": "ECC Blocked Cycles Count",
28 "PublicDescription": "Long ECC blocked cycles count"
29 },
30]
diff --git a/tools/perf/pmu-events/arch/s390/cf_m8561/extended.json b/tools/perf/pmu-events/arch/s390/cf_m8561/extended.json
new file mode 100644
index 000000000000..89e070727e1b
--- /dev/null
+++ b/tools/perf/pmu-events/arch/s390/cf_m8561/extended.json
@@ -0,0 +1,373 @@
1[
2 {
3 "Unit": "CPU-M-CF",
4 "EventCode": "128",
5 "EventName": "L1D_RO_EXCL_WRITES",
6 "BriefDescription": "L1D Read-only Exclusive Writes",
7 "PublicDescription": "A directory write to the Level-1 Data cache where the line was originally in a Read-Only state in the cache but has been updated to be in the Exclusive state that allows stores to the cache line"
8 },
9 {
10 "Unit": "CPU-M-CF",
11 "EventCode": "129",
12 "EventName": "DTLB2_WRITES",
13 "BriefDescription": "DTLB2 Writes",
14 "PublicDescription": "A translation has been written into The Translation Lookaside Buffer 2 (TLB2) and the request was made by the data cache"
15 },
16 {
17 "Unit": "CPU-M-CF",
18 "EventCode": "130",
19 "EventName": "DTLB2_MISSES",
20 "BriefDescription": "DTLB2 Misses",
21 "PublicDescription": "A TLB2 miss is in progress for a request made by the data cache. Incremented by one for every TLB2 miss in progress for the Level-1 Data cache on this cycle"
22 },
23 {
24 "Unit": "CPU-M-CF",
25 "EventCode": "131",
26 "EventName": "DTLB2_HPAGE_WRITES",
27 "BriefDescription": "DTLB2 One-Megabyte Page Writes",
28 "PublicDescription": "A translation entry was written into the Combined Region and Segment Table Entry array in the Level-2 TLB for a one-megabyte page or a Last Host Translation was done"
29 },
30 {
31 "Unit": "CPU-M-CF",
32 "EventCode": "132",
33 "EventName": "DTLB2_GPAGE_WRITES",
34 "BriefDescription": "DTLB2 Two-Gigabyte Page Writes",
35 "PublicDescription": "A translation entry for a two-gigabyte page was written into the Level-2 TLB"
36 },
37 {
38 "Unit": "CPU-M-CF",
39 "EventCode": "133",
40 "EventName": "L1D_L2D_SOURCED_WRITES",
41 "BriefDescription": "L1D L2D Sourced Writes",
42 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from the Level-2 Data cache"
43 },
44 {
45 "Unit": "CPU-M-CF",
46 "EventCode": "134",
47 "EventName": "ITLB2_WRITES",
48 "BriefDescription": "ITLB2 Writes",
49 "PublicDescription": "A translation entry has been written into the Translation Lookaside Buffer 2 (TLB2) and the request was made by the instruction cache"
50 },
51 {
52 "Unit": "CPU-M-CF",
53 "EventCode": "135",
54 "EventName": "ITLB2_MISSES",
55 "BriefDescription": "ITLB2 Misses",
56 "PublicDescription": "A TLB2 miss is in progress for a request made by the instruction cache. Incremented by one for every TLB2 miss in progress for the Level-1 Instruction cache in a cycle"
57 },
58 {
59 "Unit": "CPU-M-CF",
60 "EventCode": "136",
61 "EventName": "L1I_L2I_SOURCED_WRITES",
62 "BriefDescription": "L1I L2I Sourced Writes",
63 "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from the Level-2 Instruction cache"
64 },
65 {
66 "Unit": "CPU-M-CF",
67 "EventCode": "137",
68 "EventName": "TLB2_PTE_WRITES",
69 "BriefDescription": "TLB2 PTE Writes",
70 "PublicDescription": "A translation entry was written into the Page Table Entry array in the Level-2 TLB"
71 },
72 {
73 "Unit": "CPU-M-CF",
74 "EventCode": "138",
75 "EventName": "TLB2_CRSTE_WRITES",
76 "BriefDescription": "TLB2 CRSTE Writes",
77 "PublicDescription": "Translation entries were written into the Combined Region and Segment Table Entry array and the Page Table Entry array in the Level-2 TLB"
78 },
79 {
80 "Unit": "CPU-M-CF",
81 "EventCode": "139",
82 "EventName": "TLB2_ENGINES_BUSY",
83 "BriefDescription": "TLB2 Engines Busy",
84 "PublicDescription": "The number of Level-2 TLB translation engines busy in a cycle"
85 },
86 {
87 "Unit": "CPU-M-CF",
88 "EventCode": "140",
89 "EventName": "TX_C_TEND",
90 "BriefDescription": "Completed TEND instructions in constrained TX mode",
91 "PublicDescription": "A TEND instruction has completed in a constrained transactional-execution mode"
92 },
93 {
94 "Unit": "CPU-M-CF",
95 "EventCode": "141",
96 "EventName": "TX_NC_TEND",
97 "BriefDescription": "Completed TEND instructions in non-constrained TX mode",
98 "PublicDescription": "A TEND instruction has completed in a non-constrained transactional-execution mode"
99 },
100 {
101 "Unit": "CPU-M-CF",
102 "EventCode": "143",
103 "EventName": "L1C_TLB2_MISSES",
104 "BriefDescription": "L1C TLB2 Misses",
105 "PublicDescription": "Increments by one for any cycle where a level-1 cache or level-2 TLB miss is in progress"
106 },
107 {
108 "Unit": "CPU-M-CF",
109 "EventCode": "144",
110 "EventName": "L1D_ONCHIP_L3_SOURCED_WRITES",
111 "BriefDescription": "L1D On-Chip L3 Sourced Writes",
112 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an On-Chip Level-3 cache without intervention"
113 },
114 {
115 "Unit": "CPU-M-CF",
116 "EventCode": "145",
117 "EventName": "L1D_ONCHIP_MEMORY_SOURCED_WRITES",
118 "BriefDescription": "L1D On-Chip Memory Sourced Writes",
119 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from On-Chip memory"
120 },
121 {
122 "Unit": "CPU-M-CF",
123 "EventCode": "146",
124 "EventName": "L1D_ONCHIP_L3_SOURCED_WRITES_IV",
125 "BriefDescription": "L1D On-Chip L3 Sourced Writes with Intervention",
126 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an On-Chip Level-3 cache with intervention"
127 },
128 {
129 "Unit": "CPU-M-CF",
130 "EventCode": "147",
131 "EventName": "L1D_ONCLUSTER_L3_SOURCED_WRITES",
132 "BriefDescription": "L1D On-Cluster L3 Sourced Writes",
133 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from On-Cluster Level-3 cache withountervention"
134 },
135 {
136 "Unit": "CPU-M-CF",
137 "EventCode": "148",
138 "EventName": "L1D_ONCLUSTER_MEMORY_SOURCED_WRITES",
139 "BriefDescription": "L1D On-Cluster Memory Sourced Writes",
140 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an On-Cluster memory"
141 },
142 {
143 "Unit": "CPU-M-CF",
144 "EventCode": "149",
145 "EventName": "L1D_ONCLUSTER_L3_SOURCED_WRITES_IV",
146 "BriefDescription": "L1D On-Cluster L3 Sourced Writes with Intervention",
147 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an On-Cluster Level-3 cache with intervention"
148 },
149 {
150 "Unit": "CPU-M-CF",
151 "EventCode": "150",
152 "EventName": "L1D_OFFCLUSTER_L3_SOURCED_WRITES",
153 "BriefDescription": "L1D Off-Cluster L3 Sourced Writes",
154 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an Off-Cluster Level-3 cache without intervention"
155 },
156 {
157 "Unit": "CPU-M-CF",
158 "EventCode": "151",
159 "EventName": "L1D_OFFCLUSTER_MEMORY_SOURCED_WRITES",
160 "BriefDescription": "L1D Off-Cluster Memory Sourced Writes",
161 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from Off-Cluster memory"
162 },
163 {
164 "Unit": "CPU-M-CF",
165 "EventCode": "152",
166 "EventName": "L1D_OFFCLUSTER_L3_SOURCED_WRITES_IV",
167 "BriefDescription": "L1D Off-Cluster L3 Sourced Writes with Intervention",
168 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an Off-Cluster Level-3 cache with intervention"
169 },
170 {
171 "Unit": "CPU-M-CF",
172 "EventCode": "153",
173 "EventName": "L1D_OFFDRAWER_L3_SOURCED_WRITES",
174 "BriefDescription": "L1D Off-Drawer L3 Sourced Writes",
175 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an Off-Drawer Level-3 cache without intervention"
176 },
177 {
178 "Unit": "CPU-M-CF",
179 "EventCode": "154",
180 "EventName": "L1D_OFFDRAWER_MEMORY_SOURCED_WRITES",
181 "BriefDescription": "L1D Off-Drawer Memory Sourced Writes",
182 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from Off-Drawer memory"
183 },
184 {
185 "Unit": "CPU-M-CF",
186 "EventCode": "155",
187 "EventName": "L1D_OFFDRAWER_L3_SOURCED_WRITES_IV",
188 "BriefDescription": "L1D Off-Drawer L3 Sourced Writes with Intervention",
189 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an Off-Drawer Level-3 cache with intervention"
190 },
191 {
192 "Unit": "CPU-M-CF",
193 "EventCode": "156",
194 "EventName": "L1D_ONDRAWER_L4_SOURCED_WRITES",
195 "BriefDescription": "L1D On-Drawer L4 Sourced Writes",
196 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from On-Drawer Level-4 cache"
197 },
198 {
199 "Unit": "CPU-M-CF",
200 "EventCode": "157",
201 "EventName": "L1D_OFFDRAWER_L4_SOURCED_WRITES",
202 "BriefDescription": "L1D Off-Drawer L4 Sourced Writes",
203 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from Off-Drawer Level-4 cache"
204 },
205 {
206 "Unit": "CPU-M-CF",
207 "EventCode": "158",
208 "EventName": "L1D_ONCHIP_L3_SOURCED_WRITES_RO",
209 "BriefDescription": "L1D On-Chip L3 Sourced Writes read-only",
210 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from On-Chip L3 but a read-only invalidate was done to remove other copies of the cache line"
211 },
212 {
213 "Unit": "CPU-M-CF",
214 "EventCode": "162",
215 "EventName": "L1I_ONCHIP_L3_SOURCED_WRITES",
216 "BriefDescription": "L1I On-Chip L3 Sourced Writes",
217 "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache ine was sourced from an On-Chip Level-3 cache without intervention"
218 },
219 {
220 "Unit": "CPU-M-CF",
221 "EventCode": "163",
222 "EventName": "L1I_ONCHIP_MEMORY_SOURCED_WRITES",
223 "BriefDescription": "L1I On-Chip Memory Sourced Writes",
224 "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache ine was sourced from On-Chip memory"
225 },
226 {
227 "Unit": "CPU-M-CF",
228 "EventCode": "164",
229 "EventName": "L1I_ONCHIP_L3_SOURCED_WRITES_IV",
230 "BriefDescription": "L1I On-Chip L3 Sourced Writes with Intervention",
231 "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache ine was sourced from an On-Chip Level-3 cache with intervention"
232 },
233 {
234 "Unit": "CPU-M-CF",
235 "EventCode": "165",
236 "EventName": "L1I_ONCLUSTER_L3_SOURCED_WRITES",
237 "BriefDescription": "L1I On-Cluster L3 Sourced Writes",
238 "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an On-Cluster Level-3 cache without intervention"
239 },
240 {
241 "Unit": "CPU-M-CF",
242 "EventCode": "166",
243 "EventName": "L1I_ONCLUSTER_MEMORY_SOURCED_WRITES",
244 "BriefDescription": "L1I On-Cluster Memory Sourced Writes",
245 "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an On-Cluster memory"
246 },
247 {
248 "Unit": "CPU-M-CF",
249 "EventCode": "167",
250 "EventName": "L1I_ONCLUSTER_L3_SOURCED_WRITES_IV",
251 "BriefDescription": "L1I On-Cluster L3 Sourced Writes with Intervention",
252 "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from On-Cluster Level-3 cache with intervention"
253 },
254 {
255 "Unit": "CPU-M-CF",
256 "EventCode": "168",
257 "EventName": "L1I_OFFCLUSTER_L3_SOURCED_WRITES",
258 "BriefDescription": "L1I Off-Cluster L3 Sourced Writes",
259 "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an Off-Cluster Level-3 cache without intervention"
260 },
261 {
262 "Unit": "CPU-M-CF",
263 "EventCode": "169",
264 "EventName": "L1I_OFFCLUSTER_MEMORY_SOURCED_WRITES",
265 "BriefDescription": "L1I Off-Cluster Memory Sourced Writes",
266 "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from Off-Cluster memory"
267 },
268 {
269 "Unit": "CPU-M-CF",
270 "EventCode": "170",
271 "EventName": "L1I_OFFCLUSTER_L3_SOURCED_WRITES_IV",
272 "BriefDescription": "L1I Off-Cluster L3 Sourced Writes with Intervention",
273 "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an Off-Cluster Level-3 cache with intervention"
274 },
275 {
276 "Unit": "CPU-M-CF",
277 "EventCode": "171",
278 "EventName": "L1I_OFFDRAWER_L3_SOURCED_WRITES",
279 "BriefDescription": "L1I Off-Drawer L3 Sourced Writes",
280 "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an Off-Drawer Level-3 cache without intervention"
281 },
282 {
283 "Unit": "CPU-M-CF",
284 "EventCode": "172",
285 "EventName": "L1I_OFFDRAWER_MEMORY_SOURCED_WRITES",
286 "BriefDescription": "L1I Off-Drawer Memory Sourced Writes",
287 "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from Off-Drawer memory"
288 },
289 {
290 "Unit": "CPU-M-CF",
291 "EventCode": "173",
292 "EventName": "L1I_OFFDRAWER_L3_SOURCED_WRITES_IV",
293 "BriefDescription": "L1I Off-Drawer L3 Sourced Writes with Intervention",
294 "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an Off-Drawer Level-3 cache with intervention"
295 },
296 {
297 "Unit": "CPU-M-CF",
298 "EventCode": "174",
299 "EventName": "L1I_ONDRAWER_L4_SOURCED_WRITES",
300 "BriefDescription": "L1I On-Drawer L4 Sourced Writes",
301 "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from On-Drawer Level-4 cache"
302 },
303 {
304 "Unit": "CPU-M-CF",
305 "EventCode": "175",
306 "EventName": "L1I_OFFDRAWER_L4_SOURCED_WRITES",
307 "BriefDescription": "L1I Off-Drawer L4 Sourced Writes",
308 "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from Off-Drawer Level-4 cache"
309 },
310 {
311 "Unit": "CPU-M-CF",
312 "EventCode": "224",
313 "EventName": "BCD_DFP_EXECUTION_SLOTS",
314 "BriefDescription": "BCD DFP Execution Slots",
315 "PublicDescription": "Count of floating point execution slots used for finished Binary Coded Decimal to Decimal Floating Point conversions. Instructions: CDZT, CXZT, CZDT, CZXT"
316 },
317 {
318 "Unit": "CPU-M-CF",
319 "EventCode": "225",
320 "EventName": "VX_BCD_EXECUTION_SLOTS",
321 "BriefDescription": "VX BCD Execution Slots",
322 "PublicDescription": "Count of floating point execution slots used for finished vector arithmetic Binary Coded Decimal instructions. Instructions: VAP, VSP, VMPVMSP, VDP, VSDP, VRP, VLIP, VSRP, VPSOPVCP, VTP, VPKZ, VUPKZ, VCVB, VCVBG, VCVDVCVDG"
323 },
324 {
325 "Unit": "CPU-M-CF",
326 "EventCode": "226",
327 "EventName": "DECIMAL_INSTRUCTIONS",
328 "BriefDescription": "Decimal Instructions",
329 "PublicDescription": "Decimal instructions dispatched. Instructions: CVB, CVD, AP, CP, DP, ED, EDMK, MP, SRP, SP, ZAP"
330 },
331 {
332 "Unit": "CPU-M-CF",
333 "EventCode": "232",
334 "EventName": "LAST_HOST_TRANSLATIONS",
335 "BriefDescription": "Last host translation done",
336 "PublicDescription": "Last Host Translation done"
337 },
338 {
339 "Unit": "CPU-M-CF",
340 "EventCode": "243",
341 "EventName": "TX_NC_TABORT",
342 "BriefDescription": "Aborted transactions in non-constrained TX mode",
343 "PublicDescription": "A transaction abort has occurred in a non-constrained transactional-execution mode"
344 },
345 {
346 "Unit": "CPU-M-CF",
347 "EventCode": "244",
348 "EventName": "TX_C_TABORT_NO_SPECIAL",
349 "BriefDescription": "Aborted transactions in constrained TX mode not using special completion logic",
350 "PublicDescription": "A transaction abort has occurred in a constrained transactional-execution mode and the CPU is not using any special logic to allow the transaction to complete"
351 },
352 {
353 "Unit": "CPU-M-CF",
354 "EventCode": "245",
355 "EventName": "TX_C_TABORT_SPECIAL",
356 "BriefDescription": "Aborted transactions in constrained TX mode using special completion logic",
357 "PublicDescription": "A transaction abort has occurred in a constrained transactional-execution mode and the CPU is using special logic to allow the transaction to complete"
358 },
359 {
360 "Unit": "CPU-M-CF",
361 "EventCode": "448",
362 "EventName": "MT_DIAG_CYCLES_ONE_THR_ACTIVE",
363 "BriefDescription": "Cycle count with one thread active",
364 "PublicDescription": "Cycle count with one thread active"
365 },
366 {
367 "Unit": "CPU-M-CF",
368 "EventCode": "449",
369 "EventName": "MT_DIAG_CYCLES_TWO_THR_ACTIVE",
370 "BriefDescription": "Cycle count with two threads active",
371 "PublicDescription": "Cycle count with two threads active"
372 },
373]
diff --git a/tools/perf/pmu-events/arch/s390/mapfile.csv b/tools/perf/pmu-events/arch/s390/mapfile.csv
index 78bcf7f8e206..bd3fc577139c 100644
--- a/tools/perf/pmu-events/arch/s390/mapfile.csv
+++ b/tools/perf/pmu-events/arch/s390/mapfile.csv
@@ -4,3 +4,4 @@ Family-model,Version,Filename,EventType
4^IBM.282[78].*[13]\.[1-5].[[:xdigit:]]+$,1,cf_zec12,core 4^IBM.282[78].*[13]\.[1-5].[[:xdigit:]]+$,1,cf_zec12,core
5^IBM.296[45].*[13]\.[1-5].[[:xdigit:]]+$,1,cf_z13,core 5^IBM.296[45].*[13]\.[1-5].[[:xdigit:]]+$,1,cf_z13,core
6^IBM.390[67].*[13]\.[1-5].[[:xdigit:]]+$,3,cf_z14,core 6^IBM.390[67].*[13]\.[1-5].[[:xdigit:]]+$,3,cf_z14,core
7^IBM.856[12].*3\.6.[[:xdigit:]]+$,3,cf_m8561,core
diff --git a/tools/perf/pmu-events/jevents.c b/tools/perf/pmu-events/jevents.c
index 287a6f10ca48..1a91a197cafb 100644
--- a/tools/perf/pmu-events/jevents.c
+++ b/tools/perf/pmu-events/jevents.c
@@ -407,7 +407,7 @@ static void free_arch_std_events(void)
407 407
408 list_for_each_entry_safe(es, next, &arch_std_events, list) { 408 list_for_each_entry_safe(es, next, &arch_std_events, list) {
409 FOR_ALL_EVENT_STRUCT_FIELDS(FREE_EVENT_FIELD); 409 FOR_ALL_EVENT_STRUCT_FIELDS(FREE_EVENT_FIELD);
410 list_del(&es->list); 410 list_del_init(&es->list);
411 free(es); 411 free(es);
412 } 412 }
413} 413}
diff --git a/tools/perf/scripts/python/export-to-postgresql.py b/tools/perf/scripts/python/export-to-postgresql.py
index 4447f0d7c754..7bd73a904b4e 100644
--- a/tools/perf/scripts/python/export-to-postgresql.py
+++ b/tools/perf/scripts/python/export-to-postgresql.py
@@ -353,7 +353,10 @@ do_query(query, 'CREATE TABLE threads ('
353 'tid integer)') 353 'tid integer)')
354do_query(query, 'CREATE TABLE comms (' 354do_query(query, 'CREATE TABLE comms ('
355 'id bigint NOT NULL,' 355 'id bigint NOT NULL,'
356 'comm varchar(16))') 356 'comm varchar(16),'
357 'c_thread_id bigint,'
358 'c_time bigint,'
359 'exec_flag boolean)')
357do_query(query, 'CREATE TABLE comm_threads (' 360do_query(query, 'CREATE TABLE comm_threads ('
358 'id bigint NOT NULL,' 361 'id bigint NOT NULL,'
359 'comm_id bigint,' 362 'comm_id bigint,'
@@ -479,6 +482,17 @@ do_query(query, 'CREATE TABLE pwrx ('
479 'last_cstate integer,' 482 'last_cstate integer,'
480 'wake_reason integer)') 483 'wake_reason integer)')
481 484
485do_query(query, 'CREATE TABLE context_switches ('
486 'id bigint NOT NULL,'
487 'machine_id bigint,'
488 'time bigint,'
489 'cpu integer,'
490 'thread_out_id bigint,'
491 'comm_out_id bigint,'
492 'thread_in_id bigint,'
493 'comm_in_id bigint,'
494 'flags integer)')
495
482do_query(query, 'CREATE VIEW machines_view AS ' 496do_query(query, 'CREATE VIEW machines_view AS '
483 'SELECT ' 497 'SELECT '
484 'id,' 498 'id,'
@@ -692,6 +706,29 @@ do_query(query, 'CREATE VIEW power_events_view AS '
692 ' INNER JOIN selected_events ON selected_events.id = samples.evsel_id' 706 ' INNER JOIN selected_events ON selected_events.id = samples.evsel_id'
693 ' ORDER BY samples.id') 707 ' ORDER BY samples.id')
694 708
709do_query(query, 'CREATE VIEW context_switches_view AS '
710 'SELECT '
711 'context_switches.id,'
712 'context_switches.machine_id,'
713 'context_switches.time,'
714 'context_switches.cpu,'
715 'th_out.pid AS pid_out,'
716 'th_out.tid AS tid_out,'
717 'comm_out.comm AS comm_out,'
718 'th_in.pid AS pid_in,'
719 'th_in.tid AS tid_in,'
720 'comm_in.comm AS comm_in,'
721 'CASE WHEN context_switches.flags = 0 THEN \'in\''
722 ' WHEN context_switches.flags = 1 THEN \'out\''
723 ' WHEN context_switches.flags = 3 THEN \'out preempt\''
724 ' ELSE CAST ( context_switches.flags AS VARCHAR(11) )'
725 'END AS flags'
726 ' FROM context_switches'
727 ' INNER JOIN threads AS th_out ON th_out.id = context_switches.thread_out_id'
728 ' INNER JOIN threads AS th_in ON th_in.id = context_switches.thread_in_id'
729 ' INNER JOIN comms AS comm_out ON comm_out.id = context_switches.comm_out_id'
730 ' INNER JOIN comms AS comm_in ON comm_in.id = context_switches.comm_in_id')
731
695file_header = struct.pack("!11sii", b"PGCOPY\n\377\r\n\0", 0, 0) 732file_header = struct.pack("!11sii", b"PGCOPY\n\377\r\n\0", 0, 0)
696file_trailer = b"\377\377" 733file_trailer = b"\377\377"
697 734
@@ -756,6 +793,7 @@ mwait_file = open_output_file("mwait_table.bin")
756pwre_file = open_output_file("pwre_table.bin") 793pwre_file = open_output_file("pwre_table.bin")
757exstop_file = open_output_file("exstop_table.bin") 794exstop_file = open_output_file("exstop_table.bin")
758pwrx_file = open_output_file("pwrx_table.bin") 795pwrx_file = open_output_file("pwrx_table.bin")
796context_switches_file = open_output_file("context_switches_table.bin")
759 797
760def trace_begin(): 798def trace_begin():
761 printdate("Writing to intermediate files...") 799 printdate("Writing to intermediate files...")
@@ -763,7 +801,7 @@ def trace_begin():
763 evsel_table(0, "unknown") 801 evsel_table(0, "unknown")
764 machine_table(0, 0, "unknown") 802 machine_table(0, 0, "unknown")
765 thread_table(0, 0, 0, -1, -1) 803 thread_table(0, 0, 0, -1, -1)
766 comm_table(0, "unknown") 804 comm_table(0, "unknown", 0, 0, 0)
767 dso_table(0, 0, "unknown", "unknown", "") 805 dso_table(0, 0, "unknown", "unknown", "")
768 symbol_table(0, 0, 0, 0, 0, "unknown") 806 symbol_table(0, 0, 0, 0, 0, "unknown")
769 sample_table(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) 807 sample_table(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
@@ -804,6 +842,7 @@ def trace_end():
804 copy_output_file(pwre_file, "pwre") 842 copy_output_file(pwre_file, "pwre")
805 copy_output_file(exstop_file, "exstop") 843 copy_output_file(exstop_file, "exstop")
806 copy_output_file(pwrx_file, "pwrx") 844 copy_output_file(pwrx_file, "pwrx")
845 copy_output_file(context_switches_file, "context_switches")
807 846
808 printdate("Removing intermediate files...") 847 printdate("Removing intermediate files...")
809 remove_output_file(evsel_file) 848 remove_output_file(evsel_file)
@@ -825,6 +864,7 @@ def trace_end():
825 remove_output_file(pwre_file) 864 remove_output_file(pwre_file)
826 remove_output_file(exstop_file) 865 remove_output_file(exstop_file)
827 remove_output_file(pwrx_file) 866 remove_output_file(pwrx_file)
867 remove_output_file(context_switches_file)
828 os.rmdir(output_dir_name) 868 os.rmdir(output_dir_name)
829 printdate("Adding primary keys") 869 printdate("Adding primary keys")
830 do_query(query, 'ALTER TABLE selected_events ADD PRIMARY KEY (id)') 870 do_query(query, 'ALTER TABLE selected_events ADD PRIMARY KEY (id)')
@@ -846,11 +886,14 @@ def trace_end():
846 do_query(query, 'ALTER TABLE pwre ADD PRIMARY KEY (id)') 886 do_query(query, 'ALTER TABLE pwre ADD PRIMARY KEY (id)')
847 do_query(query, 'ALTER TABLE exstop ADD PRIMARY KEY (id)') 887 do_query(query, 'ALTER TABLE exstop ADD PRIMARY KEY (id)')
848 do_query(query, 'ALTER TABLE pwrx ADD PRIMARY KEY (id)') 888 do_query(query, 'ALTER TABLE pwrx ADD PRIMARY KEY (id)')
889 do_query(query, 'ALTER TABLE context_switches ADD PRIMARY KEY (id)')
849 890
850 printdate("Adding foreign keys") 891 printdate("Adding foreign keys")
851 do_query(query, 'ALTER TABLE threads ' 892 do_query(query, 'ALTER TABLE threads '
852 'ADD CONSTRAINT machinefk FOREIGN KEY (machine_id) REFERENCES machines (id),' 893 'ADD CONSTRAINT machinefk FOREIGN KEY (machine_id) REFERENCES machines (id),'
853 'ADD CONSTRAINT processfk FOREIGN KEY (process_id) REFERENCES threads (id)') 894 'ADD CONSTRAINT processfk FOREIGN KEY (process_id) REFERENCES threads (id)')
895 do_query(query, 'ALTER TABLE comms '
896 'ADD CONSTRAINT threadfk FOREIGN KEY (c_thread_id) REFERENCES threads (id)')
854 do_query(query, 'ALTER TABLE comm_threads ' 897 do_query(query, 'ALTER TABLE comm_threads '
855 'ADD CONSTRAINT commfk FOREIGN KEY (comm_id) REFERENCES comms (id),' 898 'ADD CONSTRAINT commfk FOREIGN KEY (comm_id) REFERENCES comms (id),'
856 'ADD CONSTRAINT threadfk FOREIGN KEY (thread_id) REFERENCES threads (id)') 899 'ADD CONSTRAINT threadfk FOREIGN KEY (thread_id) REFERENCES threads (id)')
@@ -881,6 +924,8 @@ def trace_end():
881 'ADD CONSTRAINT parent_call_pathfk FOREIGN KEY (parent_call_path_id) REFERENCES call_paths (id)') 924 'ADD CONSTRAINT parent_call_pathfk FOREIGN KEY (parent_call_path_id) REFERENCES call_paths (id)')
882 do_query(query, 'CREATE INDEX pcpid_idx ON calls (parent_call_path_id)') 925 do_query(query, 'CREATE INDEX pcpid_idx ON calls (parent_call_path_id)')
883 do_query(query, 'CREATE INDEX pid_idx ON calls (parent_id)') 926 do_query(query, 'CREATE INDEX pid_idx ON calls (parent_id)')
927 do_query(query, 'ALTER TABLE comms ADD has_calls boolean')
928 do_query(query, 'UPDATE comms SET has_calls = TRUE WHERE comms.id IN (SELECT DISTINCT comm_id FROM calls)')
884 do_query(query, 'ALTER TABLE ptwrite ' 929 do_query(query, 'ALTER TABLE ptwrite '
885 'ADD CONSTRAINT idfk FOREIGN KEY (id) REFERENCES samples (id)') 930 'ADD CONSTRAINT idfk FOREIGN KEY (id) REFERENCES samples (id)')
886 do_query(query, 'ALTER TABLE cbr ' 931 do_query(query, 'ALTER TABLE cbr '
@@ -893,18 +938,26 @@ def trace_end():
893 'ADD CONSTRAINT idfk FOREIGN KEY (id) REFERENCES samples (id)') 938 'ADD CONSTRAINT idfk FOREIGN KEY (id) REFERENCES samples (id)')
894 do_query(query, 'ALTER TABLE pwrx ' 939 do_query(query, 'ALTER TABLE pwrx '
895 'ADD CONSTRAINT idfk FOREIGN KEY (id) REFERENCES samples (id)') 940 'ADD CONSTRAINT idfk FOREIGN KEY (id) REFERENCES samples (id)')
941 do_query(query, 'ALTER TABLE context_switches '
942 'ADD CONSTRAINT machinefk FOREIGN KEY (machine_id) REFERENCES machines (id),'
943 'ADD CONSTRAINT toutfk FOREIGN KEY (thread_out_id) REFERENCES threads (id),'
944 'ADD CONSTRAINT tinfk FOREIGN KEY (thread_in_id) REFERENCES threads (id),'
945 'ADD CONSTRAINT coutfk FOREIGN KEY (comm_out_id) REFERENCES comms (id),'
946 'ADD CONSTRAINT cinfk FOREIGN KEY (comm_in_id) REFERENCES comms (id)')
896 947
897 printdate("Dropping unused tables") 948 printdate("Dropping unused tables")
898 if is_table_empty("ptwrite"): 949 if is_table_empty("ptwrite"):
899 drop("ptwrite") 950 drop("ptwrite")
900 if is_table_empty("mwait") and is_table_empty("pwre") and is_table_empty("exstop") and is_table_empty("pwrx"): 951 if is_table_empty("mwait") and is_table_empty("pwre") and is_table_empty("exstop") and is_table_empty("pwrx"):
952 do_query(query, 'DROP VIEW power_events_view');
901 drop("mwait") 953 drop("mwait")
902 drop("pwre") 954 drop("pwre")
903 drop("exstop") 955 drop("exstop")
904 drop("pwrx") 956 drop("pwrx")
905 do_query(query, 'DROP VIEW power_events_view');
906 if is_table_empty("cbr"): 957 if is_table_empty("cbr"):
907 drop("cbr") 958 drop("cbr")
959 if is_table_empty("context_switches"):
960 drop("context_switches")
908 961
909 if (unhandled_count): 962 if (unhandled_count):
910 printdate("Warning: ", unhandled_count, " unhandled events") 963 printdate("Warning: ", unhandled_count, " unhandled events")
@@ -935,11 +988,11 @@ def thread_table(thread_id, machine_id, process_id, pid, tid, *x):
935 value = struct.pack("!hiqiqiqiiii", 5, 8, thread_id, 8, machine_id, 8, process_id, 4, pid, 4, tid) 988 value = struct.pack("!hiqiqiqiiii", 5, 8, thread_id, 8, machine_id, 8, process_id, 4, pid, 4, tid)
936 thread_file.write(value) 989 thread_file.write(value)
937 990
938def comm_table(comm_id, comm_str, *x): 991def comm_table(comm_id, comm_str, thread_id, time, exec_flag, *x):
939 comm_str = toserverstr(comm_str) 992 comm_str = toserverstr(comm_str)
940 n = len(comm_str) 993 n = len(comm_str)
941 fmt = "!hiqi" + str(n) + "s" 994 fmt = "!hiqi" + str(n) + "s" + "iqiqiB"
942 value = struct.pack(fmt, 2, 8, comm_id, n, comm_str) 995 value = struct.pack(fmt, 5, 8, comm_id, n, comm_str, 8, thread_id, 8, time, 1, exec_flag)
943 comm_file.write(value) 996 comm_file.write(value)
944 997
945def comm_thread_table(comm_thread_id, comm_id, thread_id, *x): 998def comm_thread_table(comm_thread_id, comm_id, thread_id, *x):
@@ -1051,3 +1104,8 @@ def synth_data(id, config, raw_buf, *x):
1051 pwrx(id, raw_buf) 1104 pwrx(id, raw_buf)
1052 elif config == 5: 1105 elif config == 5:
1053 cbr(id, raw_buf) 1106 cbr(id, raw_buf)
1107
1108def context_switch_table(id, machine_id, time, cpu, thread_out_id, comm_out_id, thread_in_id, comm_in_id, flags, *x):
1109 fmt = "!hiqiqiqiiiqiqiqiqii"
1110 value = struct.pack(fmt, 9, 8, id, 8, machine_id, 8, time, 4, cpu, 8, thread_out_id, 8, comm_out_id, 8, thread_in_id, 8, comm_in_id, 4, flags)
1111 context_switches_file.write(value)
diff --git a/tools/perf/scripts/python/export-to-sqlite.py b/tools/perf/scripts/python/export-to-sqlite.py
index 3222a83f4184..8043a7272a56 100644
--- a/tools/perf/scripts/python/export-to-sqlite.py
+++ b/tools/perf/scripts/python/export-to-sqlite.py
@@ -177,7 +177,10 @@ do_query(query, 'CREATE TABLE threads ('
177 'tid integer)') 177 'tid integer)')
178do_query(query, 'CREATE TABLE comms (' 178do_query(query, 'CREATE TABLE comms ('
179 'id integer NOT NULL PRIMARY KEY,' 179 'id integer NOT NULL PRIMARY KEY,'
180 'comm varchar(16))') 180 'comm varchar(16),'
181 'c_thread_id bigint,'
182 'c_time bigint,'
183 'exec_flag boolean)')
181do_query(query, 'CREATE TABLE comm_threads (' 184do_query(query, 'CREATE TABLE comm_threads ('
182 'id integer NOT NULL PRIMARY KEY,' 185 'id integer NOT NULL PRIMARY KEY,'
183 'comm_id bigint,' 186 'comm_id bigint,'
@@ -303,6 +306,17 @@ do_query(query, 'CREATE TABLE pwrx ('
303 'last_cstate integer,' 306 'last_cstate integer,'
304 'wake_reason integer)') 307 'wake_reason integer)')
305 308
309do_query(query, 'CREATE TABLE context_switches ('
310 'id integer NOT NULL PRIMARY KEY,'
311 'machine_id bigint,'
312 'time bigint,'
313 'cpu integer,'
314 'thread_out_id bigint,'
315 'comm_out_id bigint,'
316 'thread_in_id bigint,'
317 'comm_in_id bigint,'
318 'flags integer)')
319
306# printf was added to sqlite in version 3.8.3 320# printf was added to sqlite in version 3.8.3
307sqlite_has_printf = False 321sqlite_has_printf = False
308try: 322try:
@@ -527,6 +541,29 @@ do_query(query, 'CREATE VIEW power_events_view AS '
527 ' INNER JOIN selected_events ON selected_events.id = evsel_id' 541 ' INNER JOIN selected_events ON selected_events.id = evsel_id'
528 ' WHERE selected_events.name IN (\'cbr\',\'mwait\',\'exstop\',\'pwre\',\'pwrx\')') 542 ' WHERE selected_events.name IN (\'cbr\',\'mwait\',\'exstop\',\'pwre\',\'pwrx\')')
529 543
544do_query(query, 'CREATE VIEW context_switches_view AS '
545 'SELECT '
546 'context_switches.id,'
547 'context_switches.machine_id,'
548 'context_switches.time,'
549 'context_switches.cpu,'
550 'th_out.pid AS pid_out,'
551 'th_out.tid AS tid_out,'
552 'comm_out.comm AS comm_out,'
553 'th_in.pid AS pid_in,'
554 'th_in.tid AS tid_in,'
555 'comm_in.comm AS comm_in,'
556 'CASE WHEN context_switches.flags = 0 THEN \'in\''
557 ' WHEN context_switches.flags = 1 THEN \'out\''
558 ' WHEN context_switches.flags = 3 THEN \'out preempt\''
559 ' ELSE context_switches.flags '
560 'END AS flags'
561 ' FROM context_switches'
562 ' INNER JOIN threads AS th_out ON th_out.id = context_switches.thread_out_id'
563 ' INNER JOIN threads AS th_in ON th_in.id = context_switches.thread_in_id'
564 ' INNER JOIN comms AS comm_out ON comm_out.id = context_switches.comm_out_id'
565 ' INNER JOIN comms AS comm_in ON comm_in.id = context_switches.comm_in_id')
566
530do_query(query, 'END TRANSACTION') 567do_query(query, 'END TRANSACTION')
531 568
532evsel_query = QSqlQuery(db) 569evsel_query = QSqlQuery(db)
@@ -536,7 +573,7 @@ machine_query.prepare("INSERT INTO machines VALUES (?, ?, ?)")
536thread_query = QSqlQuery(db) 573thread_query = QSqlQuery(db)
537thread_query.prepare("INSERT INTO threads VALUES (?, ?, ?, ?, ?)") 574thread_query.prepare("INSERT INTO threads VALUES (?, ?, ?, ?, ?)")
538comm_query = QSqlQuery(db) 575comm_query = QSqlQuery(db)
539comm_query.prepare("INSERT INTO comms VALUES (?, ?)") 576comm_query.prepare("INSERT INTO comms VALUES (?, ?, ?, ?, ?)")
540comm_thread_query = QSqlQuery(db) 577comm_thread_query = QSqlQuery(db)
541comm_thread_query.prepare("INSERT INTO comm_threads VALUES (?, ?, ?)") 578comm_thread_query.prepare("INSERT INTO comm_threads VALUES (?, ?, ?)")
542dso_query = QSqlQuery(db) 579dso_query = QSqlQuery(db)
@@ -568,6 +605,8 @@ exstop_query = QSqlQuery(db)
568exstop_query.prepare("INSERT INTO exstop VALUES (?, ?)") 605exstop_query.prepare("INSERT INTO exstop VALUES (?, ?)")
569pwrx_query = QSqlQuery(db) 606pwrx_query = QSqlQuery(db)
570pwrx_query.prepare("INSERT INTO pwrx VALUES (?, ?, ?, ?)") 607pwrx_query.prepare("INSERT INTO pwrx VALUES (?, ?, ?, ?)")
608context_switch_query = QSqlQuery(db)
609context_switch_query.prepare("INSERT INTO context_switches VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)")
571 610
572def trace_begin(): 611def trace_begin():
573 printdate("Writing records...") 612 printdate("Writing records...")
@@ -576,7 +615,7 @@ def trace_begin():
576 evsel_table(0, "unknown") 615 evsel_table(0, "unknown")
577 machine_table(0, 0, "unknown") 616 machine_table(0, 0, "unknown")
578 thread_table(0, 0, 0, -1, -1) 617 thread_table(0, 0, 0, -1, -1)
579 comm_table(0, "unknown") 618 comm_table(0, "unknown", 0, 0, 0)
580 dso_table(0, 0, "unknown", "unknown", "") 619 dso_table(0, 0, "unknown", "unknown", "")
581 symbol_table(0, 0, 0, 0, 0, "unknown") 620 symbol_table(0, 0, 0, 0, 0, "unknown")
582 sample_table(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) 621 sample_table(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
@@ -603,18 +642,22 @@ def trace_end():
603 if perf_db_export_calls: 642 if perf_db_export_calls:
604 do_query(query, 'CREATE INDEX pcpid_idx ON calls (parent_call_path_id)') 643 do_query(query, 'CREATE INDEX pcpid_idx ON calls (parent_call_path_id)')
605 do_query(query, 'CREATE INDEX pid_idx ON calls (parent_id)') 644 do_query(query, 'CREATE INDEX pid_idx ON calls (parent_id)')
645 do_query(query, 'ALTER TABLE comms ADD has_calls boolean')
646 do_query(query, 'UPDATE comms SET has_calls = 1 WHERE comms.id IN (SELECT DISTINCT comm_id FROM calls)')
606 647
607 printdate("Dropping unused tables") 648 printdate("Dropping unused tables")
608 if is_table_empty("ptwrite"): 649 if is_table_empty("ptwrite"):
609 drop("ptwrite") 650 drop("ptwrite")
610 if is_table_empty("mwait") and is_table_empty("pwre") and is_table_empty("exstop") and is_table_empty("pwrx"): 651 if is_table_empty("mwait") and is_table_empty("pwre") and is_table_empty("exstop") and is_table_empty("pwrx"):
652 do_query(query, 'DROP VIEW power_events_view');
611 drop("mwait") 653 drop("mwait")
612 drop("pwre") 654 drop("pwre")
613 drop("exstop") 655 drop("exstop")
614 drop("pwrx") 656 drop("pwrx")
615 do_query(query, 'DROP VIEW power_events_view');
616 if is_table_empty("cbr"): 657 if is_table_empty("cbr"):
617 drop("cbr") 658 drop("cbr")
659 if is_table_empty("context_switches"):
660 drop("context_switches")
618 661
619 if (unhandled_count): 662 if (unhandled_count):
620 printdate("Warning: ", unhandled_count, " unhandled events") 663 printdate("Warning: ", unhandled_count, " unhandled events")
@@ -642,7 +685,7 @@ def thread_table(*x):
642 bind_exec(thread_query, 5, x) 685 bind_exec(thread_query, 5, x)
643 686
644def comm_table(*x): 687def comm_table(*x):
645 bind_exec(comm_query, 2, x) 688 bind_exec(comm_query, 5, x)
646 689
647def comm_thread_table(*x): 690def comm_thread_table(*x):
648 bind_exec(comm_thread_query, 3, x) 691 bind_exec(comm_thread_query, 3, x)
@@ -748,3 +791,6 @@ def synth_data(id, config, raw_buf, *x):
748 pwrx(id, raw_buf) 791 pwrx(id, raw_buf)
749 elif config == 5: 792 elif config == 5:
750 cbr(id, raw_buf) 793 cbr(id, raw_buf)
794
795def context_switch_table(*x):
796 bind_exec(context_switch_query, 9, x)
diff --git a/tools/perf/scripts/python/exported-sql-viewer.py b/tools/perf/scripts/python/exported-sql-viewer.py
index 6e7934f2ac9a..61b3911d91e6 100755
--- a/tools/perf/scripts/python/exported-sql-viewer.py
+++ b/tools/perf/scripts/python/exported-sql-viewer.py
@@ -392,7 +392,7 @@ class FindBar():
392 self.hbox.addWidget(self.close_button) 392 self.hbox.addWidget(self.close_button)
393 393
394 self.bar = QWidget() 394 self.bar = QWidget()
395 self.bar.setLayout(self.hbox); 395 self.bar.setLayout(self.hbox)
396 self.bar.hide() 396 self.bar.hide()
397 397
398 def Widget(self): 398 def Widget(self):
@@ -470,7 +470,7 @@ class CallGraphLevelItemBase(object):
470 self.params = params 470 self.params = params
471 self.row = row 471 self.row = row
472 self.parent_item = parent_item 472 self.parent_item = parent_item
473 self.query_done = False; 473 self.query_done = False
474 self.child_count = 0 474 self.child_count = 0
475 self.child_items = [] 475 self.child_items = []
476 if parent_item: 476 if parent_item:
@@ -517,7 +517,7 @@ class CallGraphLevelTwoPlusItemBase(CallGraphLevelItemBase):
517 self.time = time 517 self.time = time
518 518
519 def Select(self): 519 def Select(self):
520 self.query_done = True; 520 self.query_done = True
521 query = QSqlQuery(self.glb.db) 521 query = QSqlQuery(self.glb.db)
522 if self.params.have_ipc: 522 if self.params.have_ipc:
523 ipc_str = ", SUM(insn_count), SUM(cyc_count)" 523 ipc_str = ", SUM(insn_count), SUM(cyc_count)"
@@ -604,7 +604,7 @@ class CallGraphLevelOneItem(CallGraphLevelItemBase):
604 self.dbid = comm_id 604 self.dbid = comm_id
605 605
606 def Select(self): 606 def Select(self):
607 self.query_done = True; 607 self.query_done = True
608 query = QSqlQuery(self.glb.db) 608 query = QSqlQuery(self.glb.db)
609 QueryExec(query, "SELECT thread_id, pid, tid" 609 QueryExec(query, "SELECT thread_id, pid, tid"
610 " FROM comm_threads" 610 " FROM comm_threads"
@@ -622,9 +622,12 @@ class CallGraphRootItem(CallGraphLevelItemBase):
622 def __init__(self, glb, params): 622 def __init__(self, glb, params):
623 super(CallGraphRootItem, self).__init__(glb, params, 0, None) 623 super(CallGraphRootItem, self).__init__(glb, params, 0, None)
624 self.dbid = 0 624 self.dbid = 0
625 self.query_done = True; 625 self.query_done = True
626 if_has_calls = ""
627 if IsSelectable(glb.db, "comms", columns = "has_calls"):
628 if_has_calls = " WHERE has_calls = TRUE"
626 query = QSqlQuery(glb.db) 629 query = QSqlQuery(glb.db)
627 QueryExec(query, "SELECT id, comm FROM comms") 630 QueryExec(query, "SELECT id, comm FROM comms" + if_has_calls)
628 while query.next(): 631 while query.next():
629 if not query.value(0): 632 if not query.value(0):
630 continue 633 continue
@@ -793,7 +796,7 @@ class CallTreeLevelTwoPlusItemBase(CallGraphLevelItemBase):
793 self.time = time 796 self.time = time
794 797
795 def Select(self): 798 def Select(self):
796 self.query_done = True; 799 self.query_done = True
797 if self.calls_id == 0: 800 if self.calls_id == 0:
798 comm_thread = " AND comm_id = " + str(self.comm_id) + " AND thread_id = " + str(self.thread_id) 801 comm_thread = " AND comm_id = " + str(self.comm_id) + " AND thread_id = " + str(self.thread_id)
799 else: 802 else:
@@ -881,7 +884,7 @@ class CallTreeLevelOneItem(CallGraphLevelItemBase):
881 self.dbid = comm_id 884 self.dbid = comm_id
882 885
883 def Select(self): 886 def Select(self):
884 self.query_done = True; 887 self.query_done = True
885 query = QSqlQuery(self.glb.db) 888 query = QSqlQuery(self.glb.db)
886 QueryExec(query, "SELECT thread_id, pid, tid" 889 QueryExec(query, "SELECT thread_id, pid, tid"
887 " FROM comm_threads" 890 " FROM comm_threads"
@@ -899,9 +902,12 @@ class CallTreeRootItem(CallGraphLevelItemBase):
899 def __init__(self, glb, params): 902 def __init__(self, glb, params):
900 super(CallTreeRootItem, self).__init__(glb, params, 0, None) 903 super(CallTreeRootItem, self).__init__(glb, params, 0, None)
901 self.dbid = 0 904 self.dbid = 0
902 self.query_done = True; 905 self.query_done = True
906 if_has_calls = ""
907 if IsSelectable(glb.db, "comms", columns = "has_calls"):
908 if_has_calls = " WHERE has_calls = TRUE"
903 query = QSqlQuery(glb.db) 909 query = QSqlQuery(glb.db)
904 QueryExec(query, "SELECT id, comm FROM comms") 910 QueryExec(query, "SELECT id, comm FROM comms" + if_has_calls)
905 while query.next(): 911 while query.next():
906 if not query.value(0): 912 if not query.value(0):
907 continue 913 continue
@@ -971,7 +977,7 @@ class VBox():
971 977
972 def __init__(self, w1, w2, w3=None): 978 def __init__(self, w1, w2, w3=None):
973 self.vbox = QWidget() 979 self.vbox = QWidget()
974 self.vbox.setLayout(QVBoxLayout()); 980 self.vbox.setLayout(QVBoxLayout())
975 981
976 self.vbox.layout().setContentsMargins(0, 0, 0, 0) 982 self.vbox.layout().setContentsMargins(0, 0, 0, 0)
977 983
@@ -1391,7 +1397,7 @@ class FetchMoreRecordsBar():
1391 self.hbox.addWidget(self.close_button) 1397 self.hbox.addWidget(self.close_button)
1392 1398
1393 self.bar = QWidget() 1399 self.bar = QWidget()
1394 self.bar.setLayout(self.hbox); 1400 self.bar.setLayout(self.hbox)
1395 self.bar.show() 1401 self.bar.show()
1396 1402
1397 self.in_progress = False 1403 self.in_progress = False
@@ -2206,7 +2212,7 @@ class ReportDialogBase(QDialog):
2206 self.vbox.addLayout(self.grid) 2212 self.vbox.addLayout(self.grid)
2207 self.vbox.addLayout(self.hbox) 2213 self.vbox.addLayout(self.hbox)
2208 2214
2209 self.setLayout(self.vbox); 2215 self.setLayout(self.vbox)
2210 2216
2211 def Ok(self): 2217 def Ok(self):
2212 vars = self.report_vars 2218 vars = self.report_vars
@@ -3139,7 +3145,7 @@ class AboutDialog(QDialog):
3139 self.vbox = QVBoxLayout() 3145 self.vbox = QVBoxLayout()
3140 self.vbox.addWidget(self.text) 3146 self.vbox.addWidget(self.text)
3141 3147
3142 self.setLayout(self.vbox); 3148 self.setLayout(self.vbox)
3143 3149
3144# Font resize 3150# Font resize
3145 3151
diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c
index 66a82badc1d1..c3bec9d2c201 100644
--- a/tools/perf/tests/builtin-test.c
+++ b/tools/perf/tests/builtin-test.c
@@ -21,6 +21,7 @@
21#include <subcmd/parse-options.h> 21#include <subcmd/parse-options.h>
22#include "string2.h" 22#include "string2.h"
23#include "symbol.h" 23#include "symbol.h"
24#include "util/rlimit.h"
24#include <linux/kernel.h> 25#include <linux/kernel.h>
25#include <linux/string.h> 26#include <linux/string.h>
26#include <subcmd/exec-cmd.h> 27#include <subcmd/exec-cmd.h>
@@ -727,6 +728,11 @@ int cmd_test(int argc, const char **argv)
727 728
728 if (skip != NULL) 729 if (skip != NULL)
729 skiplist = intlist__new(skip); 730 skiplist = intlist__new(skip);
731 /*
732 * Tests that create BPF maps, for instance, need more than the 64K
733 * default:
734 */
735 rlimit__bump_memlock();
730 736
731 return __cmd_test(argc, argv, skiplist); 737 return __cmd_test(argc, argv, skiplist);
732} 738}
diff --git a/tools/perf/tests/dwarf-unwind.c b/tools/perf/tests/dwarf-unwind.c
index 077c306c1cae..f33709a79335 100644
--- a/tools/perf/tests/dwarf-unwind.c
+++ b/tools/perf/tests/dwarf-unwind.c
@@ -1,6 +1,7 @@
1// SPDX-License-Identifier: GPL-2.0 1// SPDX-License-Identifier: GPL-2.0
2#include <linux/compiler.h> 2#include <linux/compiler.h>
3#include <linux/types.h> 3#include <linux/types.h>
4#include <linux/zalloc.h>
4#include <inttypes.h> 5#include <inttypes.h>
5#include <unistd.h> 6#include <unistd.h>
6#include "tests.h" 7#include "tests.h"
@@ -115,8 +116,8 @@ noinline int test_dwarf_unwind__thread(struct thread *thread)
115 } 116 }
116 117
117 out: 118 out:
118 free(sample.user_stack.data); 119 zfree(&sample.user_stack.data);
119 free(sample.user_regs.regs); 120 zfree(&sample.user_regs.regs);
120 return err; 121 return err;
121} 122}
122 123
diff --git a/tools/perf/tests/expr.c b/tools/perf/tests/expr.c
index 9acc1e80b936..ee1d88650e69 100644
--- a/tools/perf/tests/expr.c
+++ b/tools/perf/tests/expr.c
@@ -3,6 +3,7 @@
3#include "util/expr.h" 3#include "util/expr.h"
4#include "tests.h" 4#include "tests.h"
5#include <stdlib.h> 5#include <stdlib.h>
6#include <linux/zalloc.h>
6 7
7static int test(struct parse_ctx *ctx, const char *e, double val2) 8static int test(struct parse_ctx *ctx, const char *e, double val2)
8{ 9{
@@ -58,7 +59,7 @@ int test__expr(struct test *t __maybe_unused, int subtest __maybe_unused)
58 TEST_ASSERT_VAL("find other", other[3] == NULL); 59 TEST_ASSERT_VAL("find other", other[3] == NULL);
59 60
60 for (i = 0; i < num_other; i++) 61 for (i = 0; i < num_other; i++)
61 free((void *)other[i]); 62 zfree(&other[i]);
62 free((void *)other); 63 free((void *)other);
63 64
64 return 0; 65 return 0;
diff --git a/tools/perf/tests/llvm.c b/tools/perf/tests/llvm.c
index a039f93199e5..ca5a5f94ce79 100644
--- a/tools/perf/tests/llvm.c
+++ b/tools/perf/tests/llvm.c
@@ -1,5 +1,6 @@
1// SPDX-License-Identifier: GPL-2.0 1// SPDX-License-Identifier: GPL-2.0
2#include <stdio.h> 2#include <stdio.h>
3#include <stdlib.h>
3#include <bpf/libbpf.h> 4#include <bpf/libbpf.h>
4#include <util/llvm-utils.h> 5#include <util/llvm-utils.h>
5#include <util/cache.h> 6#include <util/cache.h>
diff --git a/tools/perf/tests/mem2node.c b/tools/perf/tests/mem2node.c
index d23ff1b68eba..520cc91af256 100644
--- a/tools/perf/tests/mem2node.c
+++ b/tools/perf/tests/mem2node.c
@@ -1,6 +1,7 @@
1// SPDX-License-Identifier: GPL-2.0 1// SPDX-License-Identifier: GPL-2.0
2#include <linux/compiler.h> 2#include <linux/compiler.h>
3#include <linux/bitmap.h> 3#include <linux/bitmap.h>
4#include <linux/zalloc.h>
4#include "cpumap.h" 5#include "cpumap.h"
5#include "mem2node.h" 6#include "mem2node.h"
6#include "tests.h" 7#include "tests.h"
@@ -67,7 +68,7 @@ int test__mem2node(struct test *t __maybe_unused, int subtest __maybe_unused)
67 T("failed: mem2node__node", -1 == mem2node__node(&map, 0x1050)); 68 T("failed: mem2node__node", -1 == mem2node__node(&map, 0x1050));
68 69
69 for (i = 0; i < ARRAY_SIZE(nodes); i++) 70 for (i = 0; i < ARRAY_SIZE(nodes); i++)
70 free(nodes[i].set); 71 zfree(&nodes[i].set);
71 72
72 mem2node__exit(&map); 73 mem2node__exit(&map);
73 return 0; 74 return 0;
diff --git a/tools/perf/tests/mmap-thread-lookup.c b/tools/perf/tests/mmap-thread-lookup.c
index ba87e6e8d18c..0a4301a5155c 100644
--- a/tools/perf/tests/mmap-thread-lookup.c
+++ b/tools/perf/tests/mmap-thread-lookup.c
@@ -53,7 +53,7 @@ static void *thread_fn(void *arg)
53{ 53{
54 struct thread_data *td = arg; 54 struct thread_data *td = arg;
55 ssize_t ret; 55 ssize_t ret;
56 int go; 56 int go = 0;
57 57
58 if (thread_init(td)) 58 if (thread_init(td))
59 return NULL; 59 return NULL;
diff --git a/tools/perf/tests/sample-parsing.c b/tools/perf/tests/sample-parsing.c
index 236ce0d6c826..361714e2583c 100644
--- a/tools/perf/tests/sample-parsing.c
+++ b/tools/perf/tests/sample-parsing.c
@@ -1,6 +1,7 @@
1// SPDX-License-Identifier: GPL-2.0 1// SPDX-License-Identifier: GPL-2.0
2#include <stdbool.h> 2#include <stdbool.h>
3#include <inttypes.h> 3#include <inttypes.h>
4#include <stdlib.h>
4#include <linux/bitops.h> 5#include <linux/bitops.h>
5#include <linux/kernel.h> 6#include <linux/kernel.h>
6#include <linux/types.h> 7#include <linux/types.h>
diff --git a/tools/perf/tests/switch-tracking.c b/tools/perf/tests/switch-tracking.c
index 9b5be51e5e7b..6cdab5f4812a 100644
--- a/tools/perf/tests/switch-tracking.c
+++ b/tools/perf/tests/switch-tracking.c
@@ -4,6 +4,7 @@
4#include <errno.h> 4#include <errno.h>
5#include <time.h> 5#include <time.h>
6#include <stdlib.h> 6#include <stdlib.h>
7#include <linux/zalloc.h>
7 8
8#include "parse-events.h" 9#include "parse-events.h"
9#include "evlist.h" 10#include "evlist.h"
@@ -237,7 +238,7 @@ static void free_event_nodes(struct list_head *events)
237 238
238 while (!list_empty(events)) { 239 while (!list_empty(events)) {
239 node = list_entry(events->next, struct event_node, list); 240 node = list_entry(events->next, struct event_node, list);
240 list_del(&node->list); 241 list_del_init(&node->list);
241 free(node); 242 free(node);
242 } 243 }
243} 244}
diff --git a/tools/perf/tests/thread-map.c b/tools/perf/tests/thread-map.c
index 4de1939b58ba..ccc17aced49e 100644
--- a/tools/perf/tests/thread-map.c
+++ b/tools/perf/tests/thread-map.c
@@ -6,6 +6,7 @@
6#include "tests.h" 6#include "tests.h"
7#include "thread_map.h" 7#include "thread_map.h"
8#include "debug.h" 8#include "debug.h"
9#include <linux/zalloc.h>
9 10
10#define NAME (const char *) "perf" 11#define NAME (const char *) "perf"
11#define NAMEUL (unsigned long) NAME 12#define NAMEUL (unsigned long) NAME
@@ -133,7 +134,7 @@ int test__thread_map_remove(struct test *test __maybe_unused, int subtest __mayb
133 thread_map__remove(threads, 0)); 134 thread_map__remove(threads, 0));
134 135
135 for (i = 0; i < threads->nr; i++) 136 for (i = 0; i < threads->nr; i++)
136 free(threads->map[i].comm); 137 zfree(&threads->map[i].comm);
137 138
138 free(threads); 139 free(threads);
139 return 0; 140 return 0;
diff --git a/tools/perf/tests/vmlinux-kallsyms.c b/tools/perf/tests/vmlinux-kallsyms.c
index f101576d1c72..5e8834fc7dec 100644
--- a/tools/perf/tests/vmlinux-kallsyms.c
+++ b/tools/perf/tests/vmlinux-kallsyms.c
@@ -3,6 +3,7 @@
3#include <linux/rbtree.h> 3#include <linux/rbtree.h>
4#include <inttypes.h> 4#include <inttypes.h>
5#include <string.h> 5#include <string.h>
6#include <stdlib.h>
6#include "map.h" 7#include "map.h"
7#include "symbol.h" 8#include "symbol.h"
8#include "util.h" 9#include "util.h"
diff --git a/tools/perf/ui/browser.c b/tools/perf/ui/browser.c
index 55ff05a46e0b..f80c51d53565 100644
--- a/tools/perf/ui/browser.c
+++ b/tools/perf/ui/browser.c
@@ -1,5 +1,4 @@
1// SPDX-License-Identifier: GPL-2.0 1// SPDX-License-Identifier: GPL-2.0
2#include "../util.h"
3#include "../string2.h" 2#include "../string2.h"
4#include "../config.h" 3#include "../config.h"
5#include "../../perf.h" 4#include "../../perf.h"
@@ -17,6 +16,7 @@
17#include "keysyms.h" 16#include "keysyms.h"
18#include "../color.h" 17#include "../color.h"
19#include <linux/ctype.h> 18#include <linux/ctype.h>
19#include <linux/zalloc.h>
20 20
21static int ui_browser__percent_color(struct ui_browser *browser, 21static int ui_browser__percent_color(struct ui_browser *browser,
22 double percent, bool current) 22 double percent, bool current)
diff --git a/tools/perf/ui/browser.h b/tools/perf/ui/browser.h
index aa5932e1d62e..dc1444136658 100644
--- a/tools/perf/ui/browser.h
+++ b/tools/perf/ui/browser.h
@@ -4,6 +4,7 @@
4 4
5#include <linux/types.h> 5#include <linux/types.h>
6#include <stdarg.h> 6#include <stdarg.h>
7#include <sys/types.h>
7 8
8#define HE_COLORSET_TOP 50 9#define HE_COLORSET_TOP 50
9#define HE_COLORSET_MEDIUM 51 10#define HE_COLORSET_MEDIUM 51
diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/annotate.c
index b0d089a95dac..e67880bf1efe 100644
--- a/tools/perf/ui/browsers/annotate.c
+++ b/tools/perf/ui/browsers/annotate.c
@@ -1,5 +1,4 @@
1// SPDX-License-Identifier: GPL-2.0 1// SPDX-License-Identifier: GPL-2.0
2#include "../../util/util.h"
3#include "../browser.h" 2#include "../browser.h"
4#include "../helpline.h" 3#include "../helpline.h"
5#include "../ui.h" 4#include "../ui.h"
@@ -15,6 +14,7 @@
15#include <pthread.h> 14#include <pthread.h>
16#include <linux/kernel.h> 15#include <linux/kernel.h>
17#include <linux/string.h> 16#include <linux/string.h>
17#include <linux/zalloc.h>
18#include <sys/ttydefaults.h> 18#include <sys/ttydefaults.h>
19#include <asm/bug.h> 19#include <asm/bug.h>
20 20
diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c
index 33e67aa91347..a94eb0755e8b 100644
--- a/tools/perf/ui/browsers/hists.c
+++ b/tools/perf/ui/browsers/hists.c
@@ -9,6 +9,7 @@
9#include <linux/string.h> 9#include <linux/string.h>
10#include <sys/ttydefaults.h> 10#include <sys/ttydefaults.h>
11#include <linux/time64.h> 11#include <linux/time64.h>
12#include <linux/zalloc.h>
12 13
13#include "../../util/callchain.h" 14#include "../../util/callchain.h"
14#include "../../util/evsel.h" 15#include "../../util/evsel.h"
@@ -18,7 +19,6 @@
18#include "../../util/symbol.h" 19#include "../../util/symbol.h"
19#include "../../util/pstack.h" 20#include "../../util/pstack.h"
20#include "../../util/sort.h" 21#include "../../util/sort.h"
21#include "../../util/util.h"
22#include "../../util/top.h" 22#include "../../util/top.h"
23#include "../../util/thread.h" 23#include "../../util/thread.h"
24#include "../../arch/common.h" 24#include "../../arch/common.h"
@@ -639,7 +639,11 @@ int hist_browser__run(struct hist_browser *browser, const char *help,
639 switch (key) { 639 switch (key) {
640 case K_TIMER: { 640 case K_TIMER: {
641 u64 nr_entries; 641 u64 nr_entries;
642 hbt->timer(hbt->arg); 642
643 WARN_ON_ONCE(!hbt);
644
645 if (hbt)
646 hbt->timer(hbt->arg);
643 647
644 if (hist_browser__has_filter(browser) || 648 if (hist_browser__has_filter(browser) ||
645 symbol_conf.report_hierarchy) 649 symbol_conf.report_hierarchy)
@@ -2821,7 +2825,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
2821{ 2825{
2822 struct hists *hists = evsel__hists(evsel); 2826 struct hists *hists = evsel__hists(evsel);
2823 struct hist_browser *browser = perf_evsel_browser__new(evsel, hbt, env, annotation_opts); 2827 struct hist_browser *browser = perf_evsel_browser__new(evsel, hbt, env, annotation_opts);
2824 struct branch_info *bi; 2828 struct branch_info *bi = NULL;
2825#define MAX_OPTIONS 16 2829#define MAX_OPTIONS 16
2826 char *options[MAX_OPTIONS]; 2830 char *options[MAX_OPTIONS];
2827 struct popup_action actions[MAX_OPTIONS]; 2831 struct popup_action actions[MAX_OPTIONS];
@@ -3087,7 +3091,9 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
3087 goto skip_annotation; 3091 goto skip_annotation;
3088 3092
3089 if (sort__mode == SORT_MODE__BRANCH) { 3093 if (sort__mode == SORT_MODE__BRANCH) {
3090 bi = browser->he_selection->branch_info; 3094
3095 if (browser->he_selection)
3096 bi = browser->he_selection->branch_info;
3091 3097
3092 if (bi == NULL) 3098 if (bi == NULL)
3093 goto skip_annotation; 3099 goto skip_annotation;
@@ -3271,7 +3277,8 @@ static int perf_evsel_menu__run(struct perf_evsel_menu *menu,
3271 3277
3272 switch (key) { 3278 switch (key) {
3273 case K_TIMER: 3279 case K_TIMER:
3274 hbt->timer(hbt->arg); 3280 if (hbt)
3281 hbt->timer(hbt->arg);
3275 3282
3276 if (!menu->lost_events_warned && 3283 if (!menu->lost_events_warned &&
3277 menu->lost_events && 3284 menu->lost_events &&
diff --git a/tools/perf/ui/browsers/map.c b/tools/perf/ui/browsers/map.c
index 5f6529c9eb8e..4c545b92e20d 100644
--- a/tools/perf/ui/browsers/map.c
+++ b/tools/perf/ui/browsers/map.c
@@ -2,6 +2,7 @@
2#include <elf.h> 2#include <elf.h>
3#include <inttypes.h> 3#include <inttypes.h>
4#include <sys/ttydefaults.h> 4#include <sys/ttydefaults.h>
5#include <stdlib.h>
5#include <string.h> 6#include <string.h>
6#include <linux/bitops.h> 7#include <linux/bitops.h>
7#include "../../util/util.h" 8#include "../../util/util.h"
diff --git a/tools/perf/ui/browsers/res_sample.c b/tools/perf/ui/browsers/res_sample.c
index c0dd73176d42..8aa3547bb9ff 100644
--- a/tools/perf/ui/browsers/res_sample.c
+++ b/tools/perf/ui/browsers/res_sample.c
@@ -1,6 +1,5 @@
1// SPDX-License-Identifier: GPL-2.0 1// SPDX-License-Identifier: GPL-2.0
2/* Display a menu with individual samples to browse with perf script */ 2/* Display a menu with individual samples to browse with perf script */
3#include "util.h"
4#include "hist.h" 3#include "hist.h"
5#include "evsel.h" 4#include "evsel.h"
6#include "hists.h" 5#include "hists.h"
@@ -8,6 +7,7 @@
8#include "config.h" 7#include "config.h"
9#include "time-utils.h" 8#include "time-utils.h"
10#include <linux/time64.h> 9#include <linux/time64.h>
10#include <linux/zalloc.h>
11 11
12static u64 context_len = 10 * NSEC_PER_MSEC; 12static u64 context_len = 10 * NSEC_PER_MSEC;
13 13
@@ -46,14 +46,14 @@ int res_sample_browse(struct res_sample *res_samples, int num_res,
46 if (asprintf(&names[i], "%s: CPU %d tid %d", tbuf, 46 if (asprintf(&names[i], "%s: CPU %d tid %d", tbuf,
47 res_samples[i].cpu, res_samples[i].tid) < 0) { 47 res_samples[i].cpu, res_samples[i].tid) < 0) {
48 while (--i >= 0) 48 while (--i >= 0)
49 free(names[i]); 49 zfree(&names[i]);
50 free(names); 50 free(names);
51 return -1; 51 return -1;
52 } 52 }
53 } 53 }
54 choice = ui__popup_menu(num_res, names); 54 choice = ui__popup_menu(num_res, names);
55 for (i = 0; i < num_res; i++) 55 for (i = 0; i < num_res; i++)
56 free(names[i]); 56 zfree(&names[i]);
57 free(names); 57 free(names);
58 58
59 if (choice < 0 || choice >= num_res) 59 if (choice < 0 || choice >= num_res)
diff --git a/tools/perf/ui/browsers/scripts.c b/tools/perf/ui/browsers/scripts.c
index 27cf3ab88d13..4d565cc14076 100644
--- a/tools/perf/ui/browsers/scripts.c
+++ b/tools/perf/ui/browsers/scripts.c
@@ -1,12 +1,12 @@
1// SPDX-License-Identifier: GPL-2.0 1// SPDX-License-Identifier: GPL-2.0
2#include "../../util/sort.h" 2#include "../../util/sort.h"
3#include "../../util/util.h"
4#include "../../util/hist.h" 3#include "../../util/hist.h"
5#include "../../util/debug.h" 4#include "../../util/debug.h"
6#include "../../util/symbol.h" 5#include "../../util/symbol.h"
7#include "../browser.h" 6#include "../browser.h"
8#include "../libslang.h" 7#include "../libslang.h"
9#include "config.h" 8#include "config.h"
9#include <linux/zalloc.h>
10 10
11#define SCRIPT_NAMELEN 128 11#define SCRIPT_NAMELEN 128
12#define SCRIPT_MAX_NO 64 12#define SCRIPT_MAX_NO 64
@@ -142,7 +142,7 @@ static int list_scripts(char *script_name, bool *custom,
142out: 142out:
143 free(buf); 143 free(buf);
144 for (i = 0; i < max_std; i++) 144 for (i = 0; i < max_std; i++)
145 free(paths[i]); 145 zfree(&paths[i]);
146 return ret; 146 return ret;
147} 147}
148 148
diff --git a/tools/perf/ui/gtk/annotate.c b/tools/perf/ui/gtk/annotate.c
index df49c9ba1785..3af87c18a914 100644
--- a/tools/perf/ui/gtk/annotate.c
+++ b/tools/perf/ui/gtk/annotate.c
@@ -152,7 +152,7 @@ static int perf_gtk__annotate_symbol(GtkWidget *window, struct symbol *sym,
152 gtk_container_add(GTK_CONTAINER(window), view); 152 gtk_container_add(GTK_CONTAINER(window), view);
153 153
154 list_for_each_entry_safe(pos, n, &notes->src->source, al.node) { 154 list_for_each_entry_safe(pos, n, &notes->src->source, al.node) {
155 list_del(&pos->al.node); 155 list_del_init(&pos->al.node);
156 disasm_line__free(pos); 156 disasm_line__free(pos);
157 } 157 }
158 158
diff --git a/tools/perf/ui/gtk/util.c b/tools/perf/ui/gtk/util.c
index 7250d8101c8f..c28bdb7517ac 100644
--- a/tools/perf/ui/gtk/util.c
+++ b/tools/perf/ui/gtk/util.c
@@ -1,11 +1,10 @@
1// SPDX-License-Identifier: GPL-2.0 1// SPDX-License-Identifier: GPL-2.0
2#include "../util.h" 2#include "../util.h"
3#include "../../util/util.h"
4#include "../../util/debug.h" 3#include "../../util/debug.h"
5#include "gtk.h" 4#include "gtk.h"
6 5
7#include <string.h> 6#include <string.h>
8 7#include <linux/zalloc.h>
9 8
10struct perf_gtk_context *pgctx; 9struct perf_gtk_context *pgctx;
11 10
diff --git a/tools/perf/ui/stdio/hist.c b/tools/perf/ui/stdio/hist.c
index 89393c79d870..ee7ea6deed21 100644
--- a/tools/perf/ui/stdio/hist.c
+++ b/tools/perf/ui/stdio/hist.c
@@ -3,7 +3,6 @@
3#include <linux/string.h> 3#include <linux/string.h>
4 4
5#include "../../util/callchain.h" 5#include "../../util/callchain.h"
6#include "../../util/util.h"
7#include "../../util/hist.h" 6#include "../../util/hist.h"
8#include "../../util/map.h" 7#include "../../util/map.h"
9#include "../../util/map_groups.h" 8#include "../../util/map_groups.h"
@@ -14,6 +13,7 @@
14#include "../../util/string2.h" 13#include "../../util/string2.h"
15#include "../../util/thread.h" 14#include "../../util/thread.h"
16#include <linux/ctype.h> 15#include <linux/ctype.h>
16#include <linux/zalloc.h>
17 17
18static size_t callchain__fprintf_left_margin(FILE *fp, int left_margin) 18static size_t callchain__fprintf_left_margin(FILE *fp, int left_margin)
19{ 19{
diff --git a/tools/perf/ui/tui/setup.c b/tools/perf/ui/tui/setup.c
index d4ac41679721..3ad0d3363ac6 100644
--- a/tools/perf/ui/tui/setup.c
+++ b/tools/perf/ui/tui/setup.c
@@ -2,6 +2,7 @@
2#include <errno.h> 2#include <errno.h>
3#include <signal.h> 3#include <signal.h>
4#include <stdbool.h> 4#include <stdbool.h>
5#include <stdlib.h>
5#include <linux/kernel.h> 6#include <linux/kernel.h>
6#ifdef HAVE_BACKTRACE_SUPPORT 7#ifdef HAVE_BACKTRACE_SUPPORT
7#include <execinfo.h> 8#include <execinfo.h>
diff --git a/tools/perf/ui/tui/util.c b/tools/perf/ui/tui/util.c
index b9794d6185af..fe5e571816fc 100644
--- a/tools/perf/ui/tui/util.c
+++ b/tools/perf/ui/tui/util.c
@@ -1,8 +1,8 @@
1// SPDX-License-Identifier: GPL-2.0 1// SPDX-License-Identifier: GPL-2.0
2#include "../../util/util.h"
3#include <signal.h> 2#include <signal.h>
4#include <stdbool.h> 3#include <stdbool.h>
5#include <string.h> 4#include <string.h>
5#include <stdlib.h>
6#include <sys/ttydefaults.h> 6#include <sys/ttydefaults.h>
7 7
8#include "../../util/cache.h" 8#include "../../util/cache.h"
diff --git a/tools/perf/util/Build b/tools/perf/util/Build
index d3408a463060..14f812bb07a7 100644
--- a/tools/perf/util/Build
+++ b/tools/perf/util/Build
@@ -20,11 +20,13 @@ perf-y += parse-events.o
20perf-y += perf_regs.o 20perf-y += perf_regs.o
21perf-y += path.o 21perf-y += path.o
22perf-y += print_binary.o 22perf-y += print_binary.o
23perf-y += rlimit.o
23perf-y += argv_split.o 24perf-y += argv_split.o
24perf-y += rbtree.o 25perf-y += rbtree.o
25perf-y += libstring.o 26perf-y += libstring.o
26perf-y += bitmap.o 27perf-y += bitmap.o
27perf-y += hweight.o 28perf-y += hweight.o
29perf-y += zalloc.o
28perf-y += smt.o 30perf-y += smt.o
29perf-y += strbuf.o 31perf-y += strbuf.o
30perf-y += string.o 32perf-y += string.o
@@ -241,3 +243,7 @@ $(OUTPUT)util/hweight.o: ../lib/hweight.c FORCE
241$(OUTPUT)util/vsprintf.o: ../lib/vsprintf.c FORCE 243$(OUTPUT)util/vsprintf.o: ../lib/vsprintf.c FORCE
242 $(call rule_mkdir) 244 $(call rule_mkdir)
243 $(call if_changed_dep,cc_o_c) 245 $(call if_changed_dep,cc_o_c)
246
247$(OUTPUT)util/zalloc.o: ../lib/zalloc.c FORCE
248 $(call rule_mkdir)
249 $(call if_changed_dep,cc_o_c)
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
index ec7aaf31c2b2..ac9ad2330f93 100644
--- a/tools/perf/util/annotate.c
+++ b/tools/perf/util/annotate.c
@@ -1119,16 +1119,14 @@ static int disasm_line__parse(char *line, const char **namep, char **rawp)
1119 *namep = strdup(name); 1119 *namep = strdup(name);
1120 1120
1121 if (*namep == NULL) 1121 if (*namep == NULL)
1122 goto out_free_name; 1122 goto out;
1123 1123
1124 (*rawp)[0] = tmp; 1124 (*rawp)[0] = tmp;
1125 *rawp = skip_spaces(*rawp); 1125 *rawp = skip_spaces(*rawp);
1126 1126
1127 return 0; 1127 return 0;
1128 1128
1129out_free_name: 1129out:
1130 free((void *)namep);
1131 *namep = NULL;
1132 return -1; 1130 return -1;
1133} 1131}
1134 1132
@@ -1237,8 +1235,7 @@ void disasm_line__free(struct disasm_line *dl)
1237 dl->ins.ops->free(&dl->ops); 1235 dl->ins.ops->free(&dl->ops);
1238 else 1236 else
1239 ins__delete(&dl->ops); 1237 ins__delete(&dl->ops);
1240 free((void *)dl->ins.name); 1238 zfree(&dl->ins.name);
1241 dl->ins.name = NULL;
1242 annotation_line__delete(&dl->al); 1239 annotation_line__delete(&dl->al);
1243} 1240}
1244 1241
@@ -1589,7 +1586,7 @@ static void delete_last_nop(struct symbol *sym)
1589 return; 1586 return;
1590 } 1587 }
1591 1588
1592 list_del(&dl->al.node); 1589 list_del_init(&dl->al.node);
1593 disasm_line__free(dl); 1590 disasm_line__free(dl);
1594 } 1591 }
1595} 1592}
@@ -2466,7 +2463,7 @@ void annotated_source__purge(struct annotated_source *as)
2466 struct annotation_line *al, *n; 2463 struct annotation_line *al, *n;
2467 2464
2468 list_for_each_entry_safe(al, n, &as->source, node) { 2465 list_for_each_entry_safe(al, n, &as->source, node) {
2469 list_del(&al->node); 2466 list_del_init(&al->node);
2470 disasm_line__free(disasm_line(al)); 2467 disasm_line__free(disasm_line(al));
2471 } 2468 }
2472} 2469}
diff --git a/tools/perf/util/arm-spe.c b/tools/perf/util/arm-spe.c
index 6067267cc76c..a314e5b26e9d 100644
--- a/tools/perf/util/arm-spe.c
+++ b/tools/perf/util/arm-spe.c
@@ -12,6 +12,7 @@
12#include <linux/types.h> 12#include <linux/types.h>
13#include <linux/bitops.h> 13#include <linux/bitops.h>
14#include <linux/log2.h> 14#include <linux/log2.h>
15#include <linux/zalloc.h>
15 16
16#include "cpumap.h" 17#include "cpumap.h"
17#include "color.h" 18#include "color.h"
@@ -19,7 +20,6 @@
19#include "evlist.h" 20#include "evlist.h"
20#include "machine.h" 21#include "machine.h"
21#include "session.h" 22#include "session.h"
22#include "util.h"
23#include "thread.h" 23#include "thread.h"
24#include "debug.h" 24#include "debug.h"
25#include "auxtrace.h" 25#include "auxtrace.h"
diff --git a/tools/perf/util/auxtrace.c b/tools/perf/util/auxtrace.c
index bc215fe0b4b4..ec0af36697c4 100644
--- a/tools/perf/util/auxtrace.c
+++ b/tools/perf/util/auxtrace.c
@@ -24,9 +24,9 @@
24#include <stdlib.h> 24#include <stdlib.h>
25#include <stdio.h> 25#include <stdio.h>
26#include <linux/list.h> 26#include <linux/list.h>
27#include <linux/zalloc.h>
27 28
28#include "../perf.h" 29#include "../perf.h"
29#include "util.h"
30#include "evlist.h" 30#include "evlist.h"
31#include "dso.h" 31#include "dso.h"
32#include "map.h" 32#include "map.h"
@@ -408,7 +408,7 @@ void auxtrace_queues__free(struct auxtrace_queues *queues)
408 408
409 buffer = list_entry(queues->queue_array[i].head.next, 409 buffer = list_entry(queues->queue_array[i].head.next,
410 struct auxtrace_buffer, list); 410 struct auxtrace_buffer, list);
411 list_del(&buffer->list); 411 list_del_init(&buffer->list);
412 auxtrace_buffer__free(buffer); 412 auxtrace_buffer__free(buffer);
413 } 413 }
414 } 414 }
@@ -612,7 +612,7 @@ void auxtrace_index__free(struct list_head *head)
612 struct auxtrace_index *auxtrace_index, *n; 612 struct auxtrace_index *auxtrace_index, *n;
613 613
614 list_for_each_entry_safe(auxtrace_index, n, head, list) { 614 list_for_each_entry_safe(auxtrace_index, n, head, list) {
615 list_del(&auxtrace_index->list); 615 list_del_init(&auxtrace_index->list);
616 free(auxtrace_index); 616 free(auxtrace_index);
617 } 617 }
618} 618}
@@ -1413,7 +1413,7 @@ void auxtrace_cache__free(struct auxtrace_cache *c)
1413 return; 1413 return;
1414 1414
1415 auxtrace_cache__drop(c); 1415 auxtrace_cache__drop(c);
1416 free(c->hashtable); 1416 zfree(&c->hashtable);
1417 free(c); 1417 free(c);
1418} 1418}
1419 1419
@@ -1459,12 +1459,11 @@ void *auxtrace_cache__lookup(struct auxtrace_cache *c, u32 key)
1459 1459
1460static void addr_filter__free_str(struct addr_filter *filt) 1460static void addr_filter__free_str(struct addr_filter *filt)
1461{ 1461{
1462 free(filt->str); 1462 zfree(&filt->str);
1463 filt->action = NULL; 1463 filt->action = NULL;
1464 filt->sym_from = NULL; 1464 filt->sym_from = NULL;
1465 filt->sym_to = NULL; 1465 filt->sym_to = NULL;
1466 filt->filename = NULL; 1466 filt->filename = NULL;
1467 filt->str = NULL;
1468} 1467}
1469 1468
1470static struct addr_filter *addr_filter__new(void) 1469static struct addr_filter *addr_filter__new(void)
diff --git a/tools/perf/util/bpf-loader.c b/tools/perf/util/bpf-loader.c
index 251d9ea6252f..c61974a50aa5 100644
--- a/tools/perf/util/bpf-loader.c
+++ b/tools/perf/util/bpf-loader.c
@@ -12,6 +12,7 @@
12#include <linux/err.h> 12#include <linux/err.h>
13#include <linux/kernel.h> 13#include <linux/kernel.h>
14#include <linux/string.h> 14#include <linux/string.h>
15#include <linux/zalloc.h>
15#include <errno.h> 16#include <errno.h>
16#include "perf.h" 17#include "perf.h"
17#include "debug.h" 18#include "debug.h"
@@ -828,7 +829,7 @@ static void
828bpf_map_op__delete(struct bpf_map_op *op) 829bpf_map_op__delete(struct bpf_map_op *op)
829{ 830{
830 if (!list_empty(&op->list)) 831 if (!list_empty(&op->list))
831 list_del(&op->list); 832 list_del_init(&op->list);
832 if (op->key_type == BPF_MAP_KEY_RANGES) 833 if (op->key_type == BPF_MAP_KEY_RANGES)
833 parse_events__clear_array(&op->k.array); 834 parse_events__clear_array(&op->k.array);
834 free(op); 835 free(op);
diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c
index 89c6913dfc25..f1abfab7aa8c 100644
--- a/tools/perf/util/build-id.c
+++ b/tools/perf/util/build-id.c
@@ -30,6 +30,7 @@
30#include "strlist.h" 30#include "strlist.h"
31 31
32#include <linux/ctype.h> 32#include <linux/ctype.h>
33#include <linux/zalloc.h>
33 34
34static bool no_buildid_cache; 35static bool no_buildid_cache;
35 36
diff --git a/tools/perf/util/call-path.c b/tools/perf/util/call-path.c
index c5b90300304d..5c60b8be1cf6 100644
--- a/tools/perf/util/call-path.c
+++ b/tools/perf/util/call-path.c
@@ -6,8 +6,9 @@
6 6
7#include <linux/rbtree.h> 7#include <linux/rbtree.h>
8#include <linux/list.h> 8#include <linux/list.h>
9#include <linux/zalloc.h>
10#include <stdlib.h>
9 11
10#include "util.h"
11#include "call-path.h" 12#include "call-path.h"
12 13
13static void call_path__init(struct call_path *cp, struct call_path *parent, 14static void call_path__init(struct call_path *cp, struct call_path *parent,
@@ -39,7 +40,7 @@ void call_path_root__free(struct call_path_root *cpr)
39 struct call_path_block *pos, *n; 40 struct call_path_block *pos, *n;
40 41
41 list_for_each_entry_safe(pos, n, &cpr->blocks, node) { 42 list_for_each_entry_safe(pos, n, &cpr->blocks, node) {
42 list_del(&pos->node); 43 list_del_init(&pos->node);
43 free(pos); 44 free(pos);
44 } 45 }
45 free(cpr); 46 free(cpr);
diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c
index abb608b09269..8d7d8f62fcca 100644
--- a/tools/perf/util/callchain.c
+++ b/tools/perf/util/callchain.c
@@ -16,11 +16,11 @@
16#include <stdbool.h> 16#include <stdbool.h>
17#include <errno.h> 17#include <errno.h>
18#include <math.h> 18#include <math.h>
19#include <linux/zalloc.h>
19 20
20#include "asm/bug.h" 21#include "asm/bug.h"
21 22
22#include "hist.h" 23#include "hist.h"
23#include "util.h"
24#include "sort.h" 24#include "sort.h"
25#include "machine.h" 25#include "machine.h"
26#include "map.h" 26#include "map.h"
@@ -636,7 +636,7 @@ add_child(struct callchain_node *parent,
636 struct callchain_list *call, *tmp; 636 struct callchain_list *call, *tmp;
637 637
638 list_for_each_entry_safe(call, tmp, &new->val, list) { 638 list_for_each_entry_safe(call, tmp, &new->val, list) {
639 list_del(&call->list); 639 list_del_init(&call->list);
640 map__zput(call->ms.map); 640 map__zput(call->ms.map);
641 free(call); 641 free(call);
642 } 642 }
@@ -1002,7 +1002,7 @@ merge_chain_branch(struct callchain_cursor *cursor,
1002 callchain_cursor_append(cursor, list->ip, 1002 callchain_cursor_append(cursor, list->ip,
1003 list->ms.map, list->ms.sym, 1003 list->ms.map, list->ms.sym,
1004 false, NULL, 0, 0, 0, list->srcline); 1004 false, NULL, 0, 0, 0, list->srcline);
1005 list_del(&list->list); 1005 list_del_init(&list->list);
1006 map__zput(list->ms.map); 1006 map__zput(list->ms.map);
1007 free(list); 1007 free(list);
1008 } 1008 }
@@ -1453,13 +1453,13 @@ static void free_callchain_node(struct callchain_node *node)
1453 struct rb_node *n; 1453 struct rb_node *n;
1454 1454
1455 list_for_each_entry_safe(list, tmp, &node->parent_val, list) { 1455 list_for_each_entry_safe(list, tmp, &node->parent_val, list) {
1456 list_del(&list->list); 1456 list_del_init(&list->list);
1457 map__zput(list->ms.map); 1457 map__zput(list->ms.map);
1458 free(list); 1458 free(list);
1459 } 1459 }
1460 1460
1461 list_for_each_entry_safe(list, tmp, &node->val, list) { 1461 list_for_each_entry_safe(list, tmp, &node->val, list) {
1462 list_del(&list->list); 1462 list_del_init(&list->list);
1463 map__zput(list->ms.map); 1463 map__zput(list->ms.map);
1464 free(list); 1464 free(list);
1465 } 1465 }
@@ -1544,7 +1544,7 @@ int callchain_node__make_parent_list(struct callchain_node *node)
1544 1544
1545out: 1545out:
1546 list_for_each_entry_safe(chain, new, &head, list) { 1546 list_for_each_entry_safe(chain, new, &head, list) {
1547 list_del(&chain->list); 1547 list_del_init(&chain->list);
1548 map__zput(chain->ms.map); 1548 map__zput(chain->ms.map);
1549 free(chain); 1549 free(chain);
1550 } 1550 }
diff --git a/tools/perf/util/cgroup.c b/tools/perf/util/cgroup.c
index ccd02634a616..484c29830a81 100644
--- a/tools/perf/util/cgroup.c
+++ b/tools/perf/util/cgroup.c
@@ -1,11 +1,11 @@
1// SPDX-License-Identifier: GPL-2.0 1// SPDX-License-Identifier: GPL-2.0
2#include "util.h"
3#include "../perf.h" 2#include "../perf.h"
4#include <subcmd/parse-options.h> 3#include <subcmd/parse-options.h>
5#include "evsel.h" 4#include "evsel.h"
6#include "cgroup.h" 5#include "cgroup.h"
7#include "evlist.h" 6#include "evlist.h"
8#include <linux/stringify.h> 7#include <linux/stringify.h>
8#include <linux/zalloc.h>
9#include <sys/types.h> 9#include <sys/types.h>
10#include <sys/stat.h> 10#include <sys/stat.h>
11#include <fcntl.h> 11#include <fcntl.h>
@@ -124,7 +124,7 @@ static struct cgroup *cgroup__new(const char *name)
124 return cgroup; 124 return cgroup;
125 125
126out_free_name: 126out_free_name:
127 free(cgroup->name); 127 zfree(&cgroup->name);
128out_err: 128out_err:
129 free(cgroup); 129 free(cgroup);
130 return NULL; 130 return NULL;
diff --git a/tools/perf/util/comm.c b/tools/perf/util/comm.c
index 1066de92af12..afb8d4fd2644 100644
--- a/tools/perf/util/comm.c
+++ b/tools/perf/util/comm.c
@@ -1,12 +1,12 @@
1// SPDX-License-Identifier: GPL-2.0 1// SPDX-License-Identifier: GPL-2.0
2#include "comm.h" 2#include "comm.h"
3#include "util.h"
4#include <errno.h> 3#include <errno.h>
5#include <stdlib.h> 4#include <stdlib.h>
6#include <stdio.h> 5#include <stdio.h>
7#include <string.h> 6#include <string.h>
8#include <linux/refcount.h> 7#include <linux/refcount.h>
9#include <linux/rbtree.h> 8#include <linux/rbtree.h>
9#include <linux/zalloc.h>
10#include "rwsem.h" 10#include "rwsem.h"
11 11
12struct comm_str { 12struct comm_str {
diff --git a/tools/perf/util/config.c b/tools/perf/util/config.c
index 752cce853e51..042ffbc8c53f 100644
--- a/tools/perf/util/config.c
+++ b/tools/perf/util/config.c
@@ -11,7 +11,6 @@
11 */ 11 */
12#include <errno.h> 12#include <errno.h>
13#include <sys/param.h> 13#include <sys/param.h>
14#include "util.h"
15#include "cache.h" 14#include "cache.h"
16#include "callchain.h" 15#include "callchain.h"
17#include <subcmd/exec-cmd.h> 16#include <subcmd/exec-cmd.h>
@@ -23,7 +22,7 @@
23#include <sys/stat.h> 22#include <sys/stat.h>
24#include <unistd.h> 23#include <unistd.h>
25#include <linux/string.h> 24#include <linux/string.h>
26 25#include <linux/zalloc.h>
27#include <linux/ctype.h> 26#include <linux/ctype.h>
28 27
29#define MAXNAME (256) 28#define MAXNAME (256)
diff --git a/tools/perf/util/counts.c b/tools/perf/util/counts.c
index 03032b410c29..88be9c4365e0 100644
--- a/tools/perf/util/counts.c
+++ b/tools/perf/util/counts.c
@@ -3,7 +3,7 @@
3#include <stdlib.h> 3#include <stdlib.h>
4#include "evsel.h" 4#include "evsel.h"
5#include "counts.h" 5#include "counts.h"
6#include "util.h" 6#include <linux/zalloc.h>
7 7
8struct perf_counts *perf_counts__new(int ncpus, int nthreads) 8struct perf_counts *perf_counts__new(int ncpus, int nthreads)
9{ 9{
diff --git a/tools/perf/util/cpumap.c b/tools/perf/util/cpumap.c
index 0d8fbedf7bd5..3acfbe34ebaf 100644
--- a/tools/perf/util/cpumap.c
+++ b/tools/perf/util/cpumap.c
@@ -1,5 +1,4 @@
1// SPDX-License-Identifier: GPL-2.0 1// SPDX-License-Identifier: GPL-2.0
2#include "util.h"
3#include <api/fs/fs.h> 2#include <api/fs/fs.h>
4#include "../perf.h" 3#include "../perf.h"
5#include "cpumap.h" 4#include "cpumap.h"
@@ -11,6 +10,7 @@
11#include "asm/bug.h" 10#include "asm/bug.h"
12 11
13#include <linux/ctype.h> 12#include <linux/ctype.h>
13#include <linux/zalloc.h>
14 14
15static int max_cpu_num; 15static int max_cpu_num;
16static int max_present_cpu_num; 16static int max_present_cpu_num;
diff --git a/tools/perf/util/cputopo.c b/tools/perf/util/cputopo.c
index 26e73a4bd4fe..64336a280967 100644
--- a/tools/perf/util/cputopo.c
+++ b/tools/perf/util/cputopo.c
@@ -2,11 +2,12 @@
2#include <sys/param.h> 2#include <sys/param.h>
3#include <sys/utsname.h> 3#include <sys/utsname.h>
4#include <inttypes.h> 4#include <inttypes.h>
5#include <stdlib.h>
5#include <api/fs/fs.h> 6#include <api/fs/fs.h>
7#include <linux/zalloc.h>
6 8
7#include "cputopo.h" 9#include "cputopo.h"
8#include "cpumap.h" 10#include "cpumap.h"
9#include "util.h"
10#include "env.h" 11#include "env.h"
11 12
12#define CORE_SIB_FMT \ 13#define CORE_SIB_FMT \
@@ -343,7 +344,7 @@ void numa_topology__delete(struct numa_topology *tp)
343 u32 i; 344 u32 i;
344 345
345 for (i = 0; i < tp->nr; i++) 346 for (i = 0; i < tp->nr; i++)
346 free(tp->nodes[i].cpus); 347 zfree(&tp->nodes[i].cpus);
347 348
348 free(tp); 349 free(tp);
349} 350}
diff --git a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c
index bb45e23018ee..37d7c492b155 100644
--- a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c
+++ b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c
@@ -8,6 +8,7 @@
8 8
9#include <linux/err.h> 9#include <linux/err.h>
10#include <linux/list.h> 10#include <linux/list.h>
11#include <linux/zalloc.h>
11#include <stdlib.h> 12#include <stdlib.h>
12#include <opencsd/c_api/opencsd_c_api.h> 13#include <opencsd/c_api/opencsd_c_api.h>
13#include <opencsd/etmv4/trc_pkt_types_etmv4.h> 14#include <opencsd/etmv4/trc_pkt_types_etmv4.h>
diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c
index 0c7776b51045..3d1c34fc4d68 100644
--- a/tools/perf/util/cs-etm.c
+++ b/tools/perf/util/cs-etm.c
@@ -11,6 +11,7 @@
11#include <linux/kernel.h> 11#include <linux/kernel.h>
12#include <linux/log2.h> 12#include <linux/log2.h>
13#include <linux/types.h> 13#include <linux/types.h>
14#include <linux/zalloc.h>
14 15
15#include <opencsd/ocsd_if_types.h> 16#include <opencsd/ocsd_if_types.h>
16#include <stdlib.h> 17#include <stdlib.h>
@@ -554,8 +555,7 @@ static void cs_etm__free_traceid_queues(struct cs_etm_queue *etmq)
554 etmq->traceid_queues_list = NULL; 555 etmq->traceid_queues_list = NULL;
555 556
556 /* finally free the traceid_queues array */ 557 /* finally free the traceid_queues array */
557 free(etmq->traceid_queues); 558 zfree(&etmq->traceid_queues);
558 etmq->traceid_queues = NULL;
559} 559}
560 560
561static void cs_etm__free_queue(void *priv) 561static void cs_etm__free_queue(void *priv)
@@ -2460,7 +2460,7 @@ int cs_etm__process_auxtrace_info(union perf_event *event,
2460 2460
2461 /* Something went wrong, no need to continue */ 2461 /* Something went wrong, no need to continue */
2462 if (!inode) { 2462 if (!inode) {
2463 err = PTR_ERR(inode); 2463 err = -ENOMEM;
2464 goto err_free_metadata; 2464 goto err_free_metadata;
2465 } 2465 }
2466 2466
@@ -2517,8 +2517,10 @@ int cs_etm__process_auxtrace_info(union perf_event *event,
2517 session->auxtrace = &etm->auxtrace; 2517 session->auxtrace = &etm->auxtrace;
2518 2518
2519 etm->unknown_thread = thread__new(999999999, 999999999); 2519 etm->unknown_thread = thread__new(999999999, 999999999);
2520 if (!etm->unknown_thread) 2520 if (!etm->unknown_thread) {
2521 err = -ENOMEM;
2521 goto err_free_queues; 2522 goto err_free_queues;
2523 }
2522 2524
2523 /* 2525 /*
2524 * Initialize list node so that at thread__zput() we can avoid 2526 * Initialize list node so that at thread__zput() we can avoid
@@ -2530,15 +2532,17 @@ int cs_etm__process_auxtrace_info(union perf_event *event,
2530 if (err) 2532 if (err)
2531 goto err_delete_thread; 2533 goto err_delete_thread;
2532 2534
2533 if (thread__init_map_groups(etm->unknown_thread, etm->machine)) 2535 if (thread__init_map_groups(etm->unknown_thread, etm->machine)) {
2536 err = -ENOMEM;
2534 goto err_delete_thread; 2537 goto err_delete_thread;
2538 }
2535 2539
2536 if (dump_trace) { 2540 if (dump_trace) {
2537 cs_etm__print_auxtrace_info(auxtrace_info->priv, num_cpu); 2541 cs_etm__print_auxtrace_info(auxtrace_info->priv, num_cpu);
2538 return 0; 2542 return 0;
2539 } 2543 }
2540 2544
2541 if (session->itrace_synth_opts && session->itrace_synth_opts->set) { 2545 if (session->itrace_synth_opts->set) {
2542 etm->synth_opts = *session->itrace_synth_opts; 2546 etm->synth_opts = *session->itrace_synth_opts;
2543 } else { 2547 } else {
2544 itrace_synth_opts__set_default(&etm->synth_opts, 2548 itrace_synth_opts__set_default(&etm->synth_opts,
@@ -2568,12 +2572,12 @@ err_free_etm:
2568err_free_metadata: 2572err_free_metadata:
2569 /* No need to check @metadata[j], free(NULL) is supported */ 2573 /* No need to check @metadata[j], free(NULL) is supported */
2570 for (j = 0; j < num_cpu; j++) 2574 for (j = 0; j < num_cpu; j++)
2571 free(metadata[j]); 2575 zfree(&metadata[j]);
2572 zfree(&metadata); 2576 zfree(&metadata);
2573err_free_traceid_list: 2577err_free_traceid_list:
2574 intlist__delete(traceid_list); 2578 intlist__delete(traceid_list);
2575err_free_hdr: 2579err_free_hdr:
2576 zfree(&hdr); 2580 zfree(&hdr);
2577 2581
2578 return -EINVAL; 2582 return err;
2579} 2583}
diff --git a/tools/perf/util/data-convert-bt.c b/tools/perf/util/data-convert-bt.c
index 7b06e7373b9e..ddbcd59f2d9b 100644
--- a/tools/perf/util/data-convert-bt.c
+++ b/tools/perf/util/data-convert-bt.c
@@ -10,6 +10,7 @@
10#include <inttypes.h> 10#include <inttypes.h>
11#include <linux/compiler.h> 11#include <linux/compiler.h>
12#include <linux/kernel.h> 12#include <linux/kernel.h>
13#include <linux/zalloc.h>
13#include <babeltrace/ctf-writer/writer.h> 14#include <babeltrace/ctf-writer/writer.h>
14#include <babeltrace/ctf-writer/clock.h> 15#include <babeltrace/ctf-writer/clock.h>
15#include <babeltrace/ctf-writer/stream.h> 16#include <babeltrace/ctf-writer/stream.h>
@@ -22,7 +23,6 @@
22#include "asm/bug.h" 23#include "asm/bug.h"
23#include "data-convert-bt.h" 24#include "data-convert-bt.h"
24#include "session.h" 25#include "session.h"
25#include "util.h"
26#include "debug.h" 26#include "debug.h"
27#include "tool.h" 27#include "tool.h"
28#include "evlist.h" 28#include "evlist.h"
@@ -1353,7 +1353,7 @@ static void free_streams(struct ctf_writer *cw)
1353 for (cpu = 0; cpu < cw->stream_cnt; cpu++) 1353 for (cpu = 0; cpu < cw->stream_cnt; cpu++)
1354 ctf_stream__delete(cw->stream[cpu]); 1354 ctf_stream__delete(cw->stream[cpu]);
1355 1355
1356 free(cw->stream); 1356 zfree(&cw->stream);
1357} 1357}
1358 1358
1359static int ctf_writer__setup_env(struct ctf_writer *cw, 1359static int ctf_writer__setup_env(struct ctf_writer *cw,
diff --git a/tools/perf/util/data.c b/tools/perf/util/data.c
index 6a64f713710d..1d1b97a92c3f 100644
--- a/tools/perf/util/data.c
+++ b/tools/perf/util/data.c
@@ -1,6 +1,7 @@
1// SPDX-License-Identifier: GPL-2.0 1// SPDX-License-Identifier: GPL-2.0
2#include <linux/compiler.h> 2#include <linux/compiler.h>
3#include <linux/kernel.h> 3#include <linux/kernel.h>
4#include <linux/zalloc.h>
4#include <sys/types.h> 5#include <sys/types.h>
5#include <sys/stat.h> 6#include <sys/stat.h>
6#include <errno.h> 7#include <errno.h>
@@ -20,7 +21,7 @@ static void close_dir(struct perf_data_file *files, int nr)
20{ 21{
21 while (--nr >= 1) { 22 while (--nr >= 1) {
22 close(files[nr].fd); 23 close(files[nr].fd);
23 free(files[nr].path); 24 zfree(&files[nr].path);
24 } 25 }
25 free(files); 26 free(files);
26} 27}
diff --git a/tools/perf/util/db-export.c b/tools/perf/util/db-export.c
index 2182f552aac6..ffbb3e7d3288 100644
--- a/tools/perf/util/db-export.c
+++ b/tools/perf/util/db-export.c
@@ -5,6 +5,7 @@
5 */ 5 */
6 6
7#include <errno.h> 7#include <errno.h>
8#include <stdlib.h>
8 9
9#include "evsel.h" 10#include "evsel.h"
10#include "machine.h" 11#include "machine.h"
@@ -13,76 +14,20 @@
13#include "symbol.h" 14#include "symbol.h"
14#include "map.h" 15#include "map.h"
15#include "event.h" 16#include "event.h"
16#include "util.h"
17#include "thread-stack.h" 17#include "thread-stack.h"
18#include "callchain.h" 18#include "callchain.h"
19#include "call-path.h" 19#include "call-path.h"
20#include "db-export.h" 20#include "db-export.h"
21 21#include <linux/zalloc.h>
22struct deferred_export {
23 struct list_head node;
24 struct comm *comm;
25};
26
27static int db_export__deferred(struct db_export *dbe)
28{
29 struct deferred_export *de;
30 int err;
31
32 while (!list_empty(&dbe->deferred)) {
33 de = list_entry(dbe->deferred.next, struct deferred_export,
34 node);
35 err = dbe->export_comm(dbe, de->comm);
36 list_del(&de->node);
37 free(de);
38 if (err)
39 return err;
40 }
41
42 return 0;
43}
44
45static void db_export__free_deferred(struct db_export *dbe)
46{
47 struct deferred_export *de;
48
49 while (!list_empty(&dbe->deferred)) {
50 de = list_entry(dbe->deferred.next, struct deferred_export,
51 node);
52 list_del(&de->node);
53 free(de);
54 }
55}
56
57static int db_export__defer_comm(struct db_export *dbe, struct comm *comm)
58{
59 struct deferred_export *de;
60
61 de = zalloc(sizeof(struct deferred_export));
62 if (!de)
63 return -ENOMEM;
64
65 de->comm = comm;
66 list_add_tail(&de->node, &dbe->deferred);
67
68 return 0;
69}
70 22
71int db_export__init(struct db_export *dbe) 23int db_export__init(struct db_export *dbe)
72{ 24{
73 memset(dbe, 0, sizeof(struct db_export)); 25 memset(dbe, 0, sizeof(struct db_export));
74 INIT_LIST_HEAD(&dbe->deferred);
75 return 0; 26 return 0;
76} 27}
77 28
78int db_export__flush(struct db_export *dbe)
79{
80 return db_export__deferred(dbe);
81}
82
83void db_export__exit(struct db_export *dbe) 29void db_export__exit(struct db_export *dbe)
84{ 30{
85 db_export__free_deferred(dbe);
86 call_return_processor__free(dbe->crp); 31 call_return_processor__free(dbe->crp);
87 dbe->crp = NULL; 32 dbe->crp = NULL;
88} 33}
@@ -114,71 +59,73 @@ int db_export__machine(struct db_export *dbe, struct machine *machine)
114} 59}
115 60
116int db_export__thread(struct db_export *dbe, struct thread *thread, 61int db_export__thread(struct db_export *dbe, struct thread *thread,
117 struct machine *machine, struct comm *comm) 62 struct machine *machine, struct thread *main_thread)
118{ 63{
119 struct thread *main_thread;
120 u64 main_thread_db_id = 0; 64 u64 main_thread_db_id = 0;
121 int err;
122 65
123 if (thread->db_id) 66 if (thread->db_id)
124 return 0; 67 return 0;
125 68
126 thread->db_id = ++dbe->thread_last_db_id; 69 thread->db_id = ++dbe->thread_last_db_id;
127 70
128 if (thread->pid_ != -1) { 71 if (main_thread)
129 if (thread->pid_ == thread->tid) {
130 main_thread = thread;
131 } else {
132 main_thread = machine__findnew_thread(machine,
133 thread->pid_,
134 thread->pid_);
135 if (!main_thread)
136 return -ENOMEM;
137 err = db_export__thread(dbe, main_thread, machine,
138 comm);
139 if (err)
140 goto out_put;
141 if (comm) {
142 err = db_export__comm_thread(dbe, comm, thread);
143 if (err)
144 goto out_put;
145 }
146 }
147 main_thread_db_id = main_thread->db_id; 72 main_thread_db_id = main_thread->db_id;
148 if (main_thread != thread)
149 thread__put(main_thread);
150 }
151 73
152 if (dbe->export_thread) 74 if (dbe->export_thread)
153 return dbe->export_thread(dbe, thread, main_thread_db_id, 75 return dbe->export_thread(dbe, thread, main_thread_db_id,
154 machine); 76 machine);
155 77
156 return 0; 78 return 0;
79}
157 80
158out_put: 81static int __db_export__comm(struct db_export *dbe, struct comm *comm,
159 thread__put(main_thread); 82 struct thread *thread)
160 return err; 83{
84 comm->db_id = ++dbe->comm_last_db_id;
85
86 if (dbe->export_comm)
87 return dbe->export_comm(dbe, comm, thread);
88
89 return 0;
161} 90}
162 91
163int db_export__comm(struct db_export *dbe, struct comm *comm, 92int db_export__comm(struct db_export *dbe, struct comm *comm,
164 struct thread *main_thread) 93 struct thread *thread)
94{
95 if (comm->db_id)
96 return 0;
97
98 return __db_export__comm(dbe, comm, thread);
99}
100
101/*
102 * Export the "exec" comm. The "exec" comm is the program / application command
103 * name at the time it first executes. It is used to group threads for the same
104 * program. Note that the main thread pid (or thread group id tgid) cannot be
105 * used because it does not change when a new program is exec'ed.
106 */
107int db_export__exec_comm(struct db_export *dbe, struct comm *comm,
108 struct thread *main_thread)
165{ 109{
166 int err; 110 int err;
167 111
168 if (comm->db_id) 112 if (comm->db_id)
169 return 0; 113 return 0;
170 114
171 comm->db_id = ++dbe->comm_last_db_id; 115 err = __db_export__comm(dbe, comm, main_thread);
172 116 if (err)
173 if (dbe->export_comm) { 117 return err;
174 if (main_thread->comm_set)
175 err = dbe->export_comm(dbe, comm);
176 else
177 err = db_export__defer_comm(dbe, comm);
178 if (err)
179 return err;
180 }
181 118
119 /*
120 * Record the main thread for this comm. Note that the main thread can
121 * have many "exec" comms because there will be a new one every time it
122 * exec's. An "exec" comm however will only ever have 1 main thread.
123 * That is different to any other threads for that same program because
124 * exec() will effectively kill them, so the relationship between the
125 * "exec" comm and non-main threads is 1-to-1. That is why
126 * db_export__comm_thread() is called here for the main thread, but it
127 * is called for non-main threads when they are exported.
128 */
182 return db_export__comm_thread(dbe, comm, main_thread); 129 return db_export__comm_thread(dbe, comm, main_thread);
183} 130}
184 131
@@ -339,11 +286,65 @@ int db_export__branch_type(struct db_export *dbe, u32 branch_type,
339 return 0; 286 return 0;
340} 287}
341 288
289static int db_export__threads(struct db_export *dbe, struct thread *thread,
290 struct thread *main_thread,
291 struct machine *machine, struct comm **comm_ptr)
292{
293 struct comm *comm = NULL;
294 struct comm *curr_comm;
295 int err;
296
297 if (main_thread) {
298 /*
299 * A thread has a reference to the main thread, so export the
300 * main thread first.
301 */
302 err = db_export__thread(dbe, main_thread, machine, main_thread);
303 if (err)
304 return err;
305 /*
306 * Export comm before exporting the non-main thread because
307 * db_export__comm_thread() can be called further below.
308 */
309 comm = machine__thread_exec_comm(machine, main_thread);
310 if (comm) {
311 err = db_export__exec_comm(dbe, comm, main_thread);
312 if (err)
313 return err;
314 *comm_ptr = comm;
315 }
316 }
317
318 if (thread != main_thread) {
319 /*
320 * For a non-main thread, db_export__comm_thread() must be
321 * called only if thread has not previously been exported.
322 */
323 bool export_comm_thread = comm && !thread->db_id;
324
325 err = db_export__thread(dbe, thread, machine, main_thread);
326 if (err)
327 return err;
328
329 if (export_comm_thread) {
330 err = db_export__comm_thread(dbe, comm, thread);
331 if (err)
332 return err;
333 }
334 }
335
336 curr_comm = thread__comm(thread);
337 if (curr_comm)
338 return db_export__comm(dbe, curr_comm, thread);
339
340 return 0;
341}
342
342int db_export__sample(struct db_export *dbe, union perf_event *event, 343int db_export__sample(struct db_export *dbe, union perf_event *event,
343 struct perf_sample *sample, struct perf_evsel *evsel, 344 struct perf_sample *sample, struct perf_evsel *evsel,
344 struct addr_location *al) 345 struct addr_location *al)
345{ 346{
346 struct thread* thread = al->thread; 347 struct thread *thread = al->thread;
347 struct export_sample es = { 348 struct export_sample es = {
348 .event = event, 349 .event = event,
349 .sample = sample, 350 .sample = sample,
@@ -363,19 +364,13 @@ int db_export__sample(struct db_export *dbe, union perf_event *event,
363 return err; 364 return err;
364 365
365 main_thread = thread__main_thread(al->machine, thread); 366 main_thread = thread__main_thread(al->machine, thread);
366 if (main_thread)
367 comm = machine__thread_exec_comm(al->machine, main_thread);
368 367
369 err = db_export__thread(dbe, thread, al->machine, comm); 368 err = db_export__threads(dbe, thread, main_thread, al->machine, &comm);
370 if (err) 369 if (err)
371 goto out_put; 370 goto out_put;
372 371
373 if (comm) { 372 if (comm)
374 err = db_export__comm(dbe, comm, main_thread);
375 if (err)
376 goto out_put;
377 es.comm_db_id = comm->db_id; 373 es.comm_db_id = comm->db_id;
378 }
379 374
380 es.db_id = ++dbe->sample_last_db_id; 375 es.db_id = ++dbe->sample_last_db_id;
381 376
@@ -524,3 +519,92 @@ int db_export__call_return(struct db_export *dbe, struct call_return *cr,
524 519
525 return 0; 520 return 0;
526} 521}
522
523static int db_export__pid_tid(struct db_export *dbe, struct machine *machine,
524 pid_t pid, pid_t tid, u64 *db_id,
525 struct comm **comm_ptr, bool *is_idle)
526{
527 struct thread *thread = machine__find_thread(machine, pid, tid);
528 struct thread *main_thread;
529 int err = 0;
530
531 if (!thread || !thread->comm_set)
532 goto out_put;
533
534 *is_idle = !thread->pid_ && !thread->tid;
535
536 main_thread = thread__main_thread(machine, thread);
537
538 err = db_export__threads(dbe, thread, main_thread, machine, comm_ptr);
539
540 *db_id = thread->db_id;
541
542 thread__put(main_thread);
543out_put:
544 thread__put(thread);
545
546 return err;
547}
548
549int db_export__switch(struct db_export *dbe, union perf_event *event,
550 struct perf_sample *sample, struct machine *machine)
551{
552 bool out = event->header.misc & PERF_RECORD_MISC_SWITCH_OUT;
553 bool out_preempt = out &&
554 (event->header.misc & PERF_RECORD_MISC_SWITCH_OUT_PREEMPT);
555 int flags = out | (out_preempt << 1);
556 bool is_idle_a = false, is_idle_b = false;
557 u64 th_a_id = 0, th_b_id = 0;
558 u64 comm_out_id, comm_in_id;
559 struct comm *comm_a = NULL;
560 struct comm *comm_b = NULL;
561 u64 th_out_id, th_in_id;
562 u64 db_id;
563 int err;
564
565 err = db_export__machine(dbe, machine);
566 if (err)
567 return err;
568
569 err = db_export__pid_tid(dbe, machine, sample->pid, sample->tid,
570 &th_a_id, &comm_a, &is_idle_a);
571 if (err)
572 return err;
573
574 if (event->header.type == PERF_RECORD_SWITCH_CPU_WIDE) {
575 pid_t pid = event->context_switch.next_prev_pid;
576 pid_t tid = event->context_switch.next_prev_tid;
577
578 err = db_export__pid_tid(dbe, machine, pid, tid, &th_b_id,
579 &comm_b, &is_idle_b);
580 if (err)
581 return err;
582 }
583
584 /*
585 * Do not export if both threads are unknown (i.e. not being traced),
586 * or one is unknown and the other is the idle task.
587 */
588 if ((!th_a_id || is_idle_a) && (!th_b_id || is_idle_b))
589 return 0;
590
591 db_id = ++dbe->context_switch_last_db_id;
592
593 if (out) {
594 th_out_id = th_a_id;
595 th_in_id = th_b_id;
596 comm_out_id = comm_a ? comm_a->db_id : 0;
597 comm_in_id = comm_b ? comm_b->db_id : 0;
598 } else {
599 th_out_id = th_b_id;
600 th_in_id = th_a_id;
601 comm_out_id = comm_b ? comm_b->db_id : 0;
602 comm_in_id = comm_a ? comm_a->db_id : 0;
603 }
604
605 if (dbe->export_context_switch)
606 return dbe->export_context_switch(dbe, db_id, machine, sample,
607 th_out_id, comm_out_id,
608 th_in_id, comm_in_id, flags);
609 return 0;
610}
diff --git a/tools/perf/util/db-export.h b/tools/perf/util/db-export.h
index e8a64028a386..ba1f62a5fe10 100644
--- a/tools/perf/util/db-export.h
+++ b/tools/perf/util/db-export.h
@@ -43,7 +43,8 @@ struct db_export {
43 int (*export_machine)(struct db_export *dbe, struct machine *machine); 43 int (*export_machine)(struct db_export *dbe, struct machine *machine);
44 int (*export_thread)(struct db_export *dbe, struct thread *thread, 44 int (*export_thread)(struct db_export *dbe, struct thread *thread,
45 u64 main_thread_db_id, struct machine *machine); 45 u64 main_thread_db_id, struct machine *machine);
46 int (*export_comm)(struct db_export *dbe, struct comm *comm); 46 int (*export_comm)(struct db_export *dbe, struct comm *comm,
47 struct thread *thread);
47 int (*export_comm_thread)(struct db_export *dbe, u64 db_id, 48 int (*export_comm_thread)(struct db_export *dbe, u64 db_id,
48 struct comm *comm, struct thread *thread); 49 struct comm *comm, struct thread *thread);
49 int (*export_dso)(struct db_export *dbe, struct dso *dso, 50 int (*export_dso)(struct db_export *dbe, struct dso *dso,
@@ -56,6 +57,11 @@ struct db_export {
56 int (*export_call_path)(struct db_export *dbe, struct call_path *cp); 57 int (*export_call_path)(struct db_export *dbe, struct call_path *cp);
57 int (*export_call_return)(struct db_export *dbe, 58 int (*export_call_return)(struct db_export *dbe,
58 struct call_return *cr); 59 struct call_return *cr);
60 int (*export_context_switch)(struct db_export *dbe, u64 db_id,
61 struct machine *machine,
62 struct perf_sample *sample,
63 u64 th_out_id, u64 comm_out_id,
64 u64 th_in_id, u64 comm_in_id, int flags);
59 struct call_return_processor *crp; 65 struct call_return_processor *crp;
60 struct call_path_root *cpr; 66 struct call_path_root *cpr;
61 u64 evsel_last_db_id; 67 u64 evsel_last_db_id;
@@ -68,18 +74,19 @@ struct db_export {
68 u64 sample_last_db_id; 74 u64 sample_last_db_id;
69 u64 call_path_last_db_id; 75 u64 call_path_last_db_id;
70 u64 call_return_last_db_id; 76 u64 call_return_last_db_id;
71 struct list_head deferred; 77 u64 context_switch_last_db_id;
72}; 78};
73 79
74int db_export__init(struct db_export *dbe); 80int db_export__init(struct db_export *dbe);
75int db_export__flush(struct db_export *dbe);
76void db_export__exit(struct db_export *dbe); 81void db_export__exit(struct db_export *dbe);
77int db_export__evsel(struct db_export *dbe, struct perf_evsel *evsel); 82int db_export__evsel(struct db_export *dbe, struct perf_evsel *evsel);
78int db_export__machine(struct db_export *dbe, struct machine *machine); 83int db_export__machine(struct db_export *dbe, struct machine *machine);
79int db_export__thread(struct db_export *dbe, struct thread *thread, 84int db_export__thread(struct db_export *dbe, struct thread *thread,
80 struct machine *machine, struct comm *comm); 85 struct machine *machine, struct thread *main_thread);
81int db_export__comm(struct db_export *dbe, struct comm *comm, 86int db_export__comm(struct db_export *dbe, struct comm *comm,
82 struct thread *main_thread); 87 struct thread *thread);
88int db_export__exec_comm(struct db_export *dbe, struct comm *comm,
89 struct thread *main_thread);
83int db_export__comm_thread(struct db_export *dbe, struct comm *comm, 90int db_export__comm_thread(struct db_export *dbe, struct comm *comm,
84 struct thread *thread); 91 struct thread *thread);
85int db_export__dso(struct db_export *dbe, struct dso *dso, 92int db_export__dso(struct db_export *dbe, struct dso *dso,
@@ -97,5 +104,7 @@ int db_export__branch_types(struct db_export *dbe);
97int db_export__call_path(struct db_export *dbe, struct call_path *cp); 104int db_export__call_path(struct db_export *dbe, struct call_path *cp);
98int db_export__call_return(struct db_export *dbe, struct call_return *cr, 105int db_export__call_return(struct db_export *dbe, struct call_return *cr,
99 u64 *parent_db_id); 106 u64 *parent_db_id);
107int db_export__switch(struct db_export *dbe, union perf_event *event,
108 struct perf_sample *sample, struct machine *machine);
100 109
101#endif 110#endif
diff --git a/tools/perf/util/debug.c b/tools/perf/util/debug.c
index 3cc578343f48..3780fe42453b 100644
--- a/tools/perf/util/debug.c
+++ b/tools/perf/util/debug.c
@@ -7,6 +7,7 @@
7#include <string.h> 7#include <string.h>
8#include <stdarg.h> 8#include <stdarg.h>
9#include <stdio.h> 9#include <stdio.h>
10#include <stdlib.h>
10#include <sys/wait.h> 11#include <sys/wait.h>
11#include <api/debug.h> 12#include <api/debug.h>
12#include <linux/time64.h> 13#include <linux/time64.h>
diff --git a/tools/perf/util/demangle-java.c b/tools/perf/util/demangle-java.c
index 5b4900d67c80..763328c151e9 100644
--- a/tools/perf/util/demangle-java.c
+++ b/tools/perf/util/demangle-java.c
@@ -1,14 +1,15 @@
1// SPDX-License-Identifier: GPL-2.0 1// SPDX-License-Identifier: GPL-2.0
2#include <sys/types.h> 2#include <sys/types.h>
3#include <stdio.h> 3#include <stdio.h>
4#include <stdlib.h>
4#include <string.h> 5#include <string.h>
5#include "util.h"
6#include "debug.h" 6#include "debug.h"
7#include "symbol.h" 7#include "symbol.h"
8 8
9#include "demangle-java.h" 9#include "demangle-java.h"
10 10
11#include <linux/ctype.h> 11#include <linux/ctype.h>
12#include <linux/kernel.h>
12 13
13enum { 14enum {
14 MODE_PREFIX = 0, 15 MODE_PREFIX = 0,
diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c
index c7fde04400f7..ebc9d46c15a7 100644
--- a/tools/perf/util/dso.c
+++ b/tools/perf/util/dso.c
@@ -2,6 +2,7 @@
2#include <asm/bug.h> 2#include <asm/bug.h>
3#include <linux/kernel.h> 3#include <linux/kernel.h>
4#include <linux/string.h> 4#include <linux/string.h>
5#include <linux/zalloc.h>
5#include <sys/time.h> 6#include <sys/time.h>
6#include <sys/resource.h> 7#include <sys/resource.h>
7#include <sys/types.h> 8#include <sys/types.h>
@@ -21,7 +22,7 @@
21#include "dso.h" 22#include "dso.h"
22#include "machine.h" 23#include "machine.h"
23#include "auxtrace.h" 24#include "auxtrace.h"
24#include "util.h" 25#include "util.h" /* O_CLOEXEC for older systems */
25#include "debug.h" 26#include "debug.h"
26#include "string2.h" 27#include "string2.h"
27#include "vdso.h" 28#include "vdso.h"
@@ -433,7 +434,7 @@ static void dso__list_add(struct dso *dso)
433 434
434static void dso__list_del(struct dso *dso) 435static void dso__list_del(struct dso *dso)
435{ 436{
436 list_del(&dso->data.open_entry); 437 list_del_init(&dso->data.open_entry);
437 WARN_ONCE(dso__data_open_cnt <= 0, 438 WARN_ONCE(dso__data_open_cnt <= 0,
438 "DSO data fd counter out of bounds."); 439 "DSO data fd counter out of bounds.");
439 dso__data_open_cnt--; 440 dso__data_open_cnt--;
diff --git a/tools/perf/util/dwarf-aux.c b/tools/perf/util/dwarf-aux.c
index 218bfea8f8a8..03b2de1f5a35 100644
--- a/tools/perf/util/dwarf-aux.c
+++ b/tools/perf/util/dwarf-aux.c
@@ -6,7 +6,7 @@
6#include <errno.h> 6#include <errno.h>
7#include <inttypes.h> 7#include <inttypes.h>
8#include <stdbool.h> 8#include <stdbool.h>
9#include "util.h" 9#include <stdlib.h>
10#include "debug.h" 10#include "debug.h"
11#include "dwarf-aux.h" 11#include "dwarf-aux.h"
12#include "string2.h" 12#include "string2.h"
diff --git a/tools/perf/util/env.c b/tools/perf/util/env.c
index 22eee8942527..9909ec40c6d2 100644
--- a/tools/perf/util/env.c
+++ b/tools/perf/util/env.c
@@ -2,11 +2,12 @@
2#include "cpumap.h" 2#include "cpumap.h"
3#include "env.h" 3#include "env.h"
4#include <linux/ctype.h> 4#include <linux/ctype.h>
5#include "util.h" 5#include <linux/zalloc.h>
6#include "bpf-event.h" 6#include "bpf-event.h"
7#include <errno.h> 7#include <errno.h>
8#include <sys/utsname.h> 8#include <sys/utsname.h>
9#include <bpf/libbpf.h> 9#include <bpf/libbpf.h>
10#include <stdlib.h>
10 11
11struct perf_env perf_env; 12struct perf_env perf_env;
12 13
@@ -186,7 +187,7 @@ void perf_env__exit(struct perf_env *env)
186 zfree(&env->caches); 187 zfree(&env->caches);
187 188
188 for (i = 0; i < env->nr_memory_nodes; i++) 189 for (i = 0; i < env->nr_memory_nodes; i++)
189 free(env->memory_nodes[i].set); 190 zfree(&env->memory_nodes[i].set);
190 zfree(&env->memory_nodes); 191 zfree(&env->memory_nodes);
191} 192}
192 193
@@ -286,9 +287,9 @@ int perf_env__nr_cpus_avail(struct perf_env *env)
286 287
287void cpu_cache_level__free(struct cpu_cache_level *cache) 288void cpu_cache_level__free(struct cpu_cache_level *cache)
288{ 289{
289 free(cache->type); 290 zfree(&cache->type);
290 free(cache->map); 291 zfree(&cache->map);
291 free(cache->size); 292 zfree(&cache->size);
292} 293}
293 294
294/* 295/*
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index e1d0c5ba1f92..f1f4848947ce 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -11,6 +11,7 @@
11#include <uapi/linux/mman.h> /* To get things like MAP_HUGETLB even on older libc headers */ 11#include <uapi/linux/mman.h> /* To get things like MAP_HUGETLB even on older libc headers */
12#include <api/fs/fs.h> 12#include <api/fs/fs.h>
13#include <linux/perf_event.h> 13#include <linux/perf_event.h>
14#include <linux/zalloc.h>
14#include "event.h" 15#include "event.h"
15#include "debug.h" 16#include "debug.h"
16#include "hist.h" 17#include "hist.h"
@@ -855,7 +856,7 @@ free_threads:
855 free(synthesize_threads); 856 free(synthesize_threads);
856free_dirent: 857free_dirent:
857 for (i = 0; i < n; i++) 858 for (i = 0; i < n; i++)
858 free(dirent[i]); 859 zfree(&dirent[i]);
859 free(dirent); 860 free(dirent);
860 861
861 return err; 862 return err;
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index a474ede17cd6..b0364d923f76 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -5,7 +5,6 @@
5 * Parts came from builtin-{top,stat,record}.c, see those files for further 5 * Parts came from builtin-{top,stat,record}.c, see those files for further
6 * copyright notes. 6 * copyright notes.
7 */ 7 */
8#include "util.h"
9#include <api/fs/fs.h> 8#include <api/fs/fs.h>
10#include <errno.h> 9#include <errno.h>
11#include <inttypes.h> 10#include <inttypes.h>
@@ -33,6 +32,7 @@
33#include <linux/hash.h> 32#include <linux/hash.h>
34#include <linux/log2.h> 33#include <linux/log2.h>
35#include <linux/err.h> 34#include <linux/err.h>
35#include <linux/zalloc.h>
36 36
37#ifdef LACKS_SIGQUEUE_PROTOTYPE 37#ifdef LACKS_SIGQUEUE_PROTOTYPE
38int sigqueue(pid_t pid, int sig, const union sigval value); 38int sigqueue(pid_t pid, int sig, const union sigval value);
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 7fb4ae82f34c..ebb46da4dfe5 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -17,6 +17,7 @@
17#include <linux/perf_event.h> 17#include <linux/perf_event.h>
18#include <linux/compiler.h> 18#include <linux/compiler.h>
19#include <linux/err.h> 19#include <linux/err.h>
20#include <linux/zalloc.h>
20#include <sys/ioctl.h> 21#include <sys/ioctl.h>
21#include <sys/resource.h> 22#include <sys/resource.h>
22#include <sys/types.h> 23#include <sys/types.h>
@@ -27,7 +28,6 @@
27#include "event.h" 28#include "event.h"
28#include "evsel.h" 29#include "evsel.h"
29#include "evlist.h" 30#include "evlist.h"
30#include "util.h"
31#include "cpumap.h" 31#include "cpumap.h"
32#include "thread_map.h" 32#include "thread_map.h"
33#include "target.h" 33#include "target.h"
@@ -1298,7 +1298,7 @@ static void perf_evsel__free_config_terms(struct perf_evsel *evsel)
1298 struct perf_evsel_config_term *term, *h; 1298 struct perf_evsel_config_term *term, *h;
1299 1299
1300 list_for_each_entry_safe(term, h, &evsel->config_terms, list) { 1300 list_for_each_entry_safe(term, h, &evsel->config_terms, list) {
1301 list_del(&term->list); 1301 list_del_init(&term->list);
1302 free(term); 1302 free(term);
1303 } 1303 }
1304} 1304}
diff --git a/tools/perf/util/get_current_dir_name.c b/tools/perf/util/get_current_dir_name.c
index 267aa609a582..01f32f26552d 100644
--- a/tools/perf/util/get_current_dir_name.c
+++ b/tools/perf/util/get_current_dir_name.c
@@ -1,8 +1,8 @@
1// SPDX-License-Identifier: GPL-2.0 1// SPDX-License-Identifier: LGPL-2.1
2// Copyright (C) 2018, Red Hat Inc, Arnaldo Carvalho de Melo <acme@redhat.com> 2// Copyright (C) 2018, 2019 Red Hat Inc, Arnaldo Carvalho de Melo <acme@redhat.com>
3// 3//
4#ifndef HAVE_GET_CURRENT_DIR_NAME 4#ifndef HAVE_GET_CURRENT_DIR_NAME
5#include "util.h" 5#include "get_current_dir_name.h"
6#include <unistd.h> 6#include <unistd.h>
7#include <stdlib.h> 7#include <stdlib.h>
8#include <stdlib.h> 8#include <stdlib.h>
diff --git a/tools/perf/util/get_current_dir_name.h b/tools/perf/util/get_current_dir_name.h
new file mode 100644
index 000000000000..69f7d5537d32
--- /dev/null
+++ b/tools/perf/util/get_current_dir_name.h
@@ -0,0 +1,8 @@
1// SPDX-License-Identifier: LGPL-2.1
2// Copyright (C) 2018, 2019 Red Hat Inc, Arnaldo Carvalho de Melo <acme@redhat.com>
3//
4#ifndef __PERF_GET_CURRENT_DIR_NAME_H
5#ifndef HAVE_GET_CURRENT_DIR_NAME
6char *get_current_dir_name(void);
7#endif // HAVE_GET_CURRENT_DIR_NAME
8#endif // __PERF_GET_CURRENT_DIR_NAME_H
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index 6a93ff5d8db5..c24db7f4909c 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -1,7 +1,6 @@
1// SPDX-License-Identifier: GPL-2.0 1// SPDX-License-Identifier: GPL-2.0
2#include <errno.h> 2#include <errno.h>
3#include <inttypes.h> 3#include <inttypes.h>
4#include "util.h"
5#include "string2.h" 4#include "string2.h"
6#include <sys/param.h> 5#include <sys/param.h>
7#include <sys/types.h> 6#include <sys/types.h>
@@ -15,6 +14,7 @@
15#include <linux/bitops.h> 14#include <linux/bitops.h>
16#include <linux/string.h> 15#include <linux/string.h>
17#include <linux/stringify.h> 16#include <linux/stringify.h>
17#include <linux/zalloc.h>
18#include <sys/stat.h> 18#include <sys/stat.h>
19#include <sys/utsname.h> 19#include <sys/utsname.h>
20#include <linux/time64.h> 20#include <linux/time64.h>
@@ -1052,7 +1052,7 @@ static int cpu_cache_level__read(struct cpu_cache_level *cache, u32 cpu, u16 lev
1052 1052
1053 scnprintf(file, PATH_MAX, "%s/size", path); 1053 scnprintf(file, PATH_MAX, "%s/size", path);
1054 if (sysfs__read_str(file, &cache->size, &len)) { 1054 if (sysfs__read_str(file, &cache->size, &len)) {
1055 free(cache->type); 1055 zfree(&cache->type);
1056 return -1; 1056 return -1;
1057 } 1057 }
1058 1058
@@ -1061,8 +1061,8 @@ static int cpu_cache_level__read(struct cpu_cache_level *cache, u32 cpu, u16 lev
1061 1061
1062 scnprintf(file, PATH_MAX, "%s/shared_cpu_list", path); 1062 scnprintf(file, PATH_MAX, "%s/shared_cpu_list", path);
1063 if (sysfs__read_str(file, &cache->map, &len)) { 1063 if (sysfs__read_str(file, &cache->map, &len)) {
1064 free(cache->map); 1064 zfree(&cache->map);
1065 free(cache->type); 1065 zfree(&cache->type);
1066 return -1; 1066 return -1;
1067 } 1067 }
1068 1068
diff --git a/tools/perf/util/help-unknown-cmd.c b/tools/perf/util/help-unknown-cmd.c
index 4f07a5ba5030..ab9e16123626 100644
--- a/tools/perf/util/help-unknown-cmd.c
+++ b/tools/perf/util/help-unknown-cmd.c
@@ -3,9 +3,11 @@
3#include "config.h" 3#include "config.h"
4#include <poll.h> 4#include <poll.h>
5#include <stdio.h> 5#include <stdio.h>
6#include <stdlib.h>
6#include <subcmd/help.h> 7#include <subcmd/help.h>
7#include "../builtin.h" 8#include "../builtin.h"
8#include "levenshtein.h" 9#include "levenshtein.h"
10#include <linux/zalloc.h>
9 11
10static int autocorrect; 12static int autocorrect;
11 13
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index 27cecb59f866..f24fd1954f6c 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -1,6 +1,5 @@
1// SPDX-License-Identifier: GPL-2.0 1// SPDX-License-Identifier: GPL-2.0
2#include "callchain.h" 2#include "callchain.h"
3#include "util.h"
4#include "build-id.h" 3#include "build-id.h"
5#include "hist.h" 4#include "hist.h"
6#include "map.h" 5#include "map.h"
@@ -20,6 +19,7 @@
20#include <inttypes.h> 19#include <inttypes.h>
21#include <sys/param.h> 20#include <sys/param.h>
22#include <linux/time64.h> 21#include <linux/time64.h>
22#include <linux/zalloc.h>
23 23
24static bool hists__filter_entry_by_dso(struct hists *hists, 24static bool hists__filter_entry_by_dso(struct hists *hists,
25 struct hist_entry *he); 25 struct hist_entry *he);
@@ -472,16 +472,16 @@ static int hist_entry__init(struct hist_entry *he,
472 return 0; 472 return 0;
473 473
474err_srcline: 474err_srcline:
475 free(he->srcline); 475 zfree(&he->srcline);
476 476
477err_rawdata: 477err_rawdata:
478 free(he->raw_data); 478 zfree(&he->raw_data);
479 479
480err_infos: 480err_infos:
481 if (he->branch_info) { 481 if (he->branch_info) {
482 map__put(he->branch_info->from.map); 482 map__put(he->branch_info->from.map);
483 map__put(he->branch_info->to.map); 483 map__put(he->branch_info->to.map);
484 free(he->branch_info); 484 zfree(&he->branch_info);
485 } 485 }
486 if (he->mem_info) { 486 if (he->mem_info) {
487 map__put(he->mem_info->iaddr.map); 487 map__put(he->mem_info->iaddr.map);
@@ -489,7 +489,7 @@ err_infos:
489 } 489 }
490err: 490err:
491 map__zput(he->ms.map); 491 map__zput(he->ms.map);
492 free(he->stat_acc); 492 zfree(&he->stat_acc);
493 return -ENOMEM; 493 return -ENOMEM;
494} 494}
495 495
@@ -1254,10 +1254,10 @@ void hist_entry__delete(struct hist_entry *he)
1254 zfree(&he->stat_acc); 1254 zfree(&he->stat_acc);
1255 free_srcline(he->srcline); 1255 free_srcline(he->srcline);
1256 if (he->srcfile && he->srcfile[0]) 1256 if (he->srcfile && he->srcfile[0])
1257 free(he->srcfile); 1257 zfree(&he->srcfile);
1258 free_callchain(he->callchain); 1258 free_callchain(he->callchain);
1259 free(he->trace_output); 1259 zfree(&he->trace_output);
1260 free(he->raw_data); 1260 zfree(&he->raw_data);
1261 ops->free(he); 1261 ops->free(he);
1262} 1262}
1263 1263
@@ -2741,10 +2741,10 @@ static void hists_evsel__exit(struct perf_evsel *evsel)
2741 2741
2742 list_for_each_entry_safe(node, tmp, &hists->hpp_formats, list) { 2742 list_for_each_entry_safe(node, tmp, &hists->hpp_formats, list) {
2743 perf_hpp_list__for_each_format_safe(&node->hpp, fmt, pos) { 2743 perf_hpp_list__for_each_format_safe(&node->hpp, fmt, pos) {
2744 list_del(&fmt->list); 2744 list_del_init(&fmt->list);
2745 free(fmt); 2745 free(fmt);
2746 } 2746 }
2747 list_del(&node->list); 2747 list_del_init(&node->list);
2748 free(node); 2748 free(node);
2749 } 2749 }
2750} 2750}
diff --git a/tools/perf/util/intel-bts.c b/tools/perf/util/intel-bts.c
index e32dbffebb2f..5560e95afdda 100644
--- a/tools/perf/util/intel-bts.c
+++ b/tools/perf/util/intel-bts.c
@@ -12,6 +12,7 @@
12#include <linux/types.h> 12#include <linux/types.h>
13#include <linux/bitops.h> 13#include <linux/bitops.h>
14#include <linux/log2.h> 14#include <linux/log2.h>
15#include <linux/zalloc.h>
15 16
16#include "cpumap.h" 17#include "cpumap.h"
17#include "color.h" 18#include "color.h"
@@ -21,7 +22,6 @@
21#include "map.h" 22#include "map.h"
22#include "symbol.h" 23#include "symbol.h"
23#include "session.h" 24#include "session.h"
24#include "util.h"
25#include "thread.h" 25#include "thread.h"
26#include "thread-stack.h" 26#include "thread-stack.h"
27#include "debug.h" 27#include "debug.h"
@@ -891,13 +891,12 @@ int intel_bts_process_auxtrace_info(union perf_event *event,
891 if (dump_trace) 891 if (dump_trace)
892 return 0; 892 return 0;
893 893
894 if (session->itrace_synth_opts && session->itrace_synth_opts->set) { 894 if (session->itrace_synth_opts->set) {
895 bts->synth_opts = *session->itrace_synth_opts; 895 bts->synth_opts = *session->itrace_synth_opts;
896 } else { 896 } else {
897 itrace_synth_opts__set_default(&bts->synth_opts, 897 itrace_synth_opts__set_default(&bts->synth_opts,
898 session->itrace_synth_opts->default_no_sample); 898 session->itrace_synth_opts->default_no_sample);
899 if (session->itrace_synth_opts) 899 bts->synth_opts.thread_stack =
900 bts->synth_opts.thread_stack =
901 session->itrace_synth_opts->thread_stack; 900 session->itrace_synth_opts->thread_stack;
902 } 901 }
903 902
diff --git a/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c b/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c
index 4d14e78c5927..3bfdf2b7a96a 100644
--- a/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c
+++ b/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c
@@ -14,9 +14,9 @@
14#include <stdint.h> 14#include <stdint.h>
15#include <inttypes.h> 15#include <inttypes.h>
16#include <linux/compiler.h> 16#include <linux/compiler.h>
17#include <linux/zalloc.h>
17 18
18#include "../cache.h" 19#include "../cache.h"
19#include "../util.h"
20#include "../auxtrace.h" 20#include "../auxtrace.h"
21 21
22#include "intel-pt-insn-decoder.h" 22#include "intel-pt-insn-decoder.h"
diff --git a/tools/perf/util/intel-pt.c b/tools/perf/util/intel-pt.c
index 470aaae9d930..df061599fef4 100644
--- a/tools/perf/util/intel-pt.c
+++ b/tools/perf/util/intel-pt.c
@@ -10,6 +10,7 @@
10#include <errno.h> 10#include <errno.h>
11#include <linux/kernel.h> 11#include <linux/kernel.h>
12#include <linux/types.h> 12#include <linux/types.h>
13#include <linux/zalloc.h>
13 14
14#include "../perf.h" 15#include "../perf.h"
15#include "session.h" 16#include "session.h"
@@ -22,7 +23,6 @@
22#include "evsel.h" 23#include "evsel.h"
23#include "map.h" 24#include "map.h"
24#include "color.h" 25#include "color.h"
25#include "util.h"
26#include "thread.h" 26#include "thread.h"
27#include "thread-stack.h" 27#include "thread-stack.h"
28#include "symbol.h" 28#include "symbol.h"
@@ -3210,7 +3210,7 @@ int intel_pt_process_auxtrace_info(union perf_event *event,
3210 goto err_delete_thread; 3210 goto err_delete_thread;
3211 } 3211 }
3212 3212
3213 if (session->itrace_synth_opts && session->itrace_synth_opts->set) { 3213 if (session->itrace_synth_opts->set) {
3214 pt->synth_opts = *session->itrace_synth_opts; 3214 pt->synth_opts = *session->itrace_synth_opts;
3215 } else { 3215 } else {
3216 itrace_synth_opts__set_default(&pt->synth_opts, 3216 itrace_synth_opts__set_default(&pt->synth_opts,
@@ -3220,8 +3220,7 @@ int intel_pt_process_auxtrace_info(union perf_event *event,
3220 pt->synth_opts.branches = false; 3220 pt->synth_opts.branches = false;
3221 pt->synth_opts.callchain = true; 3221 pt->synth_opts.callchain = true;
3222 } 3222 }
3223 if (session->itrace_synth_opts) 3223 pt->synth_opts.thread_stack =
3224 pt->synth_opts.thread_stack =
3225 session->itrace_synth_opts->thread_stack; 3224 session->itrace_synth_opts->thread_stack;
3226 } 3225 }
3227 3226
@@ -3241,11 +3240,9 @@ int intel_pt_process_auxtrace_info(union perf_event *event,
3241 pt->cbr2khz = tsc_freq / pt->max_non_turbo_ratio / 1000; 3240 pt->cbr2khz = tsc_freq / pt->max_non_turbo_ratio / 1000;
3242 } 3241 }
3243 3242
3244 if (session->itrace_synth_opts) { 3243 err = intel_pt_setup_time_ranges(pt, session->itrace_synth_opts);
3245 err = intel_pt_setup_time_ranges(pt, session->itrace_synth_opts); 3244 if (err)
3246 if (err) 3245 goto err_delete_thread;
3247 goto err_delete_thread;
3248 }
3249 3246
3250 if (pt->synth_opts.calls) 3247 if (pt->synth_opts.calls)
3251 pt->branches_filter |= PERF_IP_FLAG_CALL | PERF_IP_FLAG_ASYNC | 3248 pt->branches_filter |= PERF_IP_FLAG_CALL | PERF_IP_FLAG_ASYNC |
diff --git a/tools/perf/util/jitdump.c b/tools/perf/util/jitdump.c
index 28908afedec4..18c34f0c1966 100644
--- a/tools/perf/util/jitdump.c
+++ b/tools/perf/util/jitdump.c
@@ -29,6 +29,7 @@
29#include "../builtin.h" 29#include "../builtin.h"
30 30
31#include <linux/ctype.h> 31#include <linux/ctype.h>
32#include <linux/zalloc.h>
32 33
33struct jit_buf_desc { 34struct jit_buf_desc {
34 struct perf_data *output; 35 struct perf_data *output;
@@ -431,14 +432,12 @@ static int jit_repipe_code_load(struct jit_buf_desc *jd, union jr_entry *jr)
431 jd->unwinding_data, jd->eh_frame_hdr_size, jd->unwinding_size); 432 jd->unwinding_data, jd->eh_frame_hdr_size, jd->unwinding_size);
432 433
433 if (jd->debug_data && jd->nr_debug_entries) { 434 if (jd->debug_data && jd->nr_debug_entries) {
434 free(jd->debug_data); 435 zfree(&jd->debug_data);
435 jd->debug_data = NULL;
436 jd->nr_debug_entries = 0; 436 jd->nr_debug_entries = 0;
437 } 437 }
438 438
439 if (jd->unwinding_data && jd->eh_frame_hdr_size) { 439 if (jd->unwinding_data && jd->eh_frame_hdr_size) {
440 free(jd->unwinding_data); 440 zfree(&jd->unwinding_data);
441 jd->unwinding_data = NULL;
442 jd->eh_frame_hdr_size = 0; 441 jd->eh_frame_hdr_size = 0;
443 jd->unwinding_mapped_size = 0; 442 jd->unwinding_mapped_size = 0;
444 jd->unwinding_size = 0; 443 jd->unwinding_size = 0;
diff --git a/tools/perf/util/llvm-utils.c b/tools/perf/util/llvm-utils.c
index 5b0b60f00275..9f0470ecbca9 100644
--- a/tools/perf/util/llvm-utils.c
+++ b/tools/perf/util/llvm-utils.c
@@ -9,6 +9,7 @@
9#include <stdio.h> 9#include <stdio.h>
10#include <stdlib.h> 10#include <stdlib.h>
11#include <linux/err.h> 11#include <linux/err.h>
12#include <linux/zalloc.h>
12#include "debug.h" 13#include "debug.h"
13#include "llvm-utils.h" 14#include "llvm-utils.h"
14#include "config.h" 15#include "config.h"
@@ -352,8 +353,7 @@ void llvm__get_kbuild_opts(char **kbuild_dir, char **kbuild_include_opts)
352" \toption in [llvm] to \"\" to suppress this detection.\n\n", 353" \toption in [llvm] to \"\" to suppress this detection.\n\n",
353 *kbuild_dir); 354 *kbuild_dir);
354 355
355 free(*kbuild_dir); 356 zfree(kbuild_dir);
356 *kbuild_dir = NULL;
357 goto errout; 357 goto errout;
358 } 358 }
359 359
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index 147ed85ea2bc..cf826eca3aaf 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -15,7 +15,6 @@
15#include "strlist.h" 15#include "strlist.h"
16#include "thread.h" 16#include "thread.h"
17#include "vdso.h" 17#include "vdso.h"
18#include "util.h"
19#include <stdbool.h> 18#include <stdbool.h>
20#include <sys/types.h> 19#include <sys/types.h>
21#include <sys/stat.h> 20#include <sys/stat.h>
@@ -28,6 +27,7 @@
28#include <linux/ctype.h> 27#include <linux/ctype.h>
29#include <symbol/kallsyms.h> 28#include <symbol/kallsyms.h>
30#include <linux/mman.h> 29#include <linux/mman.h>
30#include <linux/zalloc.h>
31 31
32static void __machine__remove_thread(struct machine *machine, struct thread *th, bool lock); 32static void __machine__remove_thread(struct machine *machine, struct thread *th, bool lock);
33 33
@@ -810,7 +810,7 @@ struct map *machine__findnew_module_map(struct machine *machine, u64 start,
810out: 810out:
811 /* put the dso here, corresponding to machine__findnew_module_dso */ 811 /* put the dso here, corresponding to machine__findnew_module_dso */
812 dso__put(dso); 812 dso__put(dso);
813 free(m.name); 813 zfree(&m.name);
814 return map; 814 return map;
815} 815}
816 816
@@ -1350,7 +1350,7 @@ static int map_groups__set_modules_path_dir(struct map_groups *mg,
1350 if (m.kmod) 1350 if (m.kmod)
1351 ret = map_groups__set_module_path(mg, path, &m); 1351 ret = map_groups__set_module_path(mg, path, &m);
1352 1352
1353 free(m.name); 1353 zfree(&m.name);
1354 1354
1355 if (ret) 1355 if (ret)
1356 goto out; 1356 goto out;
diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c
index 6fce983c6115..668410b1d426 100644
--- a/tools/perf/util/map.c
+++ b/tools/perf/util/map.c
@@ -12,10 +12,10 @@
12#include "thread.h" 12#include "thread.h"
13#include "vdso.h" 13#include "vdso.h"
14#include "build-id.h" 14#include "build-id.h"
15#include "util.h"
16#include "debug.h" 15#include "debug.h"
17#include "machine.h" 16#include "machine.h"
18#include <linux/string.h> 17#include <linux/string.h>
18#include <linux/zalloc.h>
19#include "srcline.h" 19#include "srcline.h"
20#include "namespaces.h" 20#include "namespaces.h"
21#include "unwind.h" 21#include "unwind.h"
@@ -476,8 +476,11 @@ int map__fprintf_srccode(struct map *map, u64 addr,
476 goto out_free_line; 476 goto out_free_line;
477 477
478 ret = fprintf(fp, "|%-8d %.*s", line, len, srccode); 478 ret = fprintf(fp, "|%-8d %.*s", line, len, srccode);
479 state->srcfile = srcfile; 479
480 state->line = line; 480 if (state) {
481 state->srcfile = srcfile;
482 state->line = line;
483 }
481 return ret; 484 return ret;
482 485
483out_free_line: 486out_free_line:
diff --git a/tools/perf/util/mem2node.c b/tools/perf/util/mem2node.c
index c6fd81c02586..cacc2fc4dcbd 100644
--- a/tools/perf/util/mem2node.c
+++ b/tools/perf/util/mem2node.c
@@ -1,8 +1,8 @@
1#include <errno.h> 1#include <errno.h>
2#include <inttypes.h> 2#include <inttypes.h>
3#include <linux/bitmap.h> 3#include <linux/bitmap.h>
4#include <linux/zalloc.h>
4#include "mem2node.h" 5#include "mem2node.h"
5#include "util.h"
6 6
7struct phys_entry { 7struct phys_entry {
8 struct rb_node rb_node; 8 struct rb_node rb_node;
diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c
index d8164574cb16..416a9015405e 100644
--- a/tools/perf/util/metricgroup.c
+++ b/tools/perf/util/metricgroup.c
@@ -18,6 +18,7 @@
18#include "strlist.h" 18#include "strlist.h"
19#include <assert.h> 19#include <assert.h>
20#include <linux/ctype.h> 20#include <linux/ctype.h>
21#include <linux/zalloc.h>
21 22
22struct metric_event *metricgroup__lookup(struct rblist *metric_events, 23struct metric_event *metricgroup__lookup(struct rblist *metric_events,
23 struct perf_evsel *evsel, 24 struct perf_evsel *evsel,
@@ -235,7 +236,7 @@ static struct rb_node *mep_new(struct rblist *rl __maybe_unused,
235 goto out_name; 236 goto out_name;
236 return &me->nd; 237 return &me->nd;
237out_name: 238out_name:
238 free((char *)me->name); 239 zfree(&me->name);
239out_me: 240out_me:
240 free(me); 241 free(me);
241 return NULL; 242 return NULL;
@@ -263,7 +264,7 @@ static void mep_delete(struct rblist *rl __maybe_unused,
263 struct mep *me = container_of(nd, struct mep, nd); 264 struct mep *me = container_of(nd, struct mep, nd);
264 265
265 strlist__delete(me->metrics); 266 strlist__delete(me->metrics);
266 free((void *)me->name); 267 zfree(&me->name);
267 free(me); 268 free(me);
268} 269}
269 270
@@ -489,8 +490,9 @@ static void metricgroup__free_egroups(struct list_head *group_list)
489 490
490 list_for_each_entry_safe (eg, egtmp, group_list, nd) { 491 list_for_each_entry_safe (eg, egtmp, group_list, nd) {
491 for (i = 0; i < eg->idnum; i++) 492 for (i = 0; i < eg->idnum; i++)
492 free((char *)eg->ids[i]); 493 zfree(&eg->ids[i]);
493 free(eg->ids); 494 zfree(&eg->ids);
495 list_del_init(&eg->nd);
494 free(eg); 496 free(eg);
495 } 497 }
496} 498}
diff --git a/tools/perf/util/mmap.c b/tools/perf/util/mmap.c
index 768c632b0d82..9f0b6391af33 100644
--- a/tools/perf/util/mmap.c
+++ b/tools/perf/util/mmap.c
@@ -9,6 +9,7 @@
9#include <sys/mman.h> 9#include <sys/mman.h>
10#include <inttypes.h> 10#include <inttypes.h>
11#include <asm/bug.h> 11#include <asm/bug.h>
12#include <linux/zalloc.h>
12#ifdef HAVE_LIBNUMA_SUPPORT 13#ifdef HAVE_LIBNUMA_SUPPORT
13#include <numaif.h> 14#include <numaif.h>
14#endif 15#endif
diff --git a/tools/perf/util/namespaces.c b/tools/perf/util/namespaces.c
index 023c4efd788d..46d3a7754897 100644
--- a/tools/perf/util/namespaces.c
+++ b/tools/perf/util/namespaces.c
@@ -5,8 +5,8 @@
5 */ 5 */
6 6
7#include "namespaces.h" 7#include "namespaces.h"
8#include "util.h"
9#include "event.h" 8#include "event.h"
9#include "get_current_dir_name.h"
10#include <sys/types.h> 10#include <sys/types.h>
11#include <sys/stat.h> 11#include <sys/stat.h>
12#include <fcntl.h> 12#include <fcntl.h>
@@ -17,6 +17,7 @@
17#include <string.h> 17#include <string.h>
18#include <unistd.h> 18#include <unistd.h>
19#include <asm/bug.h> 19#include <asm/bug.h>
20#include <linux/zalloc.h>
20 21
21struct namespaces *namespaces__new(struct namespaces_event *event) 22struct namespaces *namespaces__new(struct namespaces_event *event)
22{ 23{
diff --git a/tools/perf/util/namespaces.h b/tools/perf/util/namespaces.h
index 15a5a276c478..004430c0de93 100644
--- a/tools/perf/util/namespaces.h
+++ b/tools/perf/util/namespaces.h
@@ -13,6 +13,10 @@
13#include <linux/refcount.h> 13#include <linux/refcount.h>
14#include <linux/types.h> 14#include <linux/types.h>
15 15
16#ifndef HAVE_SETNS_SUPPORT
17int setns(int fd, int nstype);
18#endif
19
16struct namespaces_event; 20struct namespaces_event;
17 21
18struct namespaces { 22struct namespaces {
diff --git a/tools/perf/util/ordered-events.c b/tools/perf/util/ordered-events.c
index 989fed6f43b5..bb5f34b7ab44 100644
--- a/tools/perf/util/ordered-events.c
+++ b/tools/perf/util/ordered-events.c
@@ -138,7 +138,7 @@ static struct ordered_event *alloc_event(struct ordered_events *oe,
138 138
139 if (!list_empty(cache)) { 139 if (!list_empty(cache)) {
140 new = list_entry(cache->next, struct ordered_event, list); 140 new = list_entry(cache->next, struct ordered_event, list);
141 list_del(&new->list); 141 list_del_init(&new->list);
142 } else if (oe->buffer) { 142 } else if (oe->buffer) {
143 new = &oe->buffer->event[oe->buffer_idx]; 143 new = &oe->buffer->event[oe->buffer_idx];
144 if (++oe->buffer_idx == MAX_SAMPLE_BUFFER) 144 if (++oe->buffer_idx == MAX_SAMPLE_BUFFER)
@@ -394,13 +394,13 @@ void ordered_events__free(struct ordered_events *oe)
394 * yet, we need to free only allocated ones ... 394 * yet, we need to free only allocated ones ...
395 */ 395 */
396 if (oe->buffer) { 396 if (oe->buffer) {
397 list_del(&oe->buffer->list); 397 list_del_init(&oe->buffer->list);
398 ordered_events_buffer__free(oe->buffer, oe->buffer_idx, oe); 398 ordered_events_buffer__free(oe->buffer, oe->buffer_idx, oe);
399 } 399 }
400 400
401 /* ... and continue with the rest */ 401 /* ... and continue with the rest */
402 list_for_each_entry_safe(buffer, tmp, &oe->to_free, list) { 402 list_for_each_entry_safe(buffer, tmp, &oe->to_free, list) {
403 list_del(&buffer->list); 403 list_del_init(&buffer->list);
404 ordered_events_buffer__free(buffer, MAX_SAMPLE_BUFFER, oe); 404 ordered_events_buffer__free(buffer, MAX_SAMPLE_BUFFER, oe);
405 } 405 }
406} 406}
diff --git a/tools/perf/util/parse-branch-options.c b/tools/perf/util/parse-branch-options.c
index bd779d9f4d1e..726e8d9e8c54 100644
--- a/tools/perf/util/parse-branch-options.c
+++ b/tools/perf/util/parse-branch-options.c
@@ -1,9 +1,9 @@
1// SPDX-License-Identifier: GPL-2.0 1// SPDX-License-Identifier: GPL-2.0
2#include "perf.h" 2#include "perf.h"
3#include "util/util.h"
4#include "util/debug.h" 3#include "util/debug.h"
5#include <subcmd/parse-options.h> 4#include <subcmd/parse-options.h>
6#include "util/parse-branch-options.h" 5#include "util/parse-branch-options.h"
6#include <stdlib.h>
7 7
8#define BRANCH_OPT(n, m) \ 8#define BRANCH_OPT(n, m) \
9 { .name = n, .mode = (m) } 9 { .name = n, .mode = (m) }
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index cf0b9b81c5aa..371ff3aee769 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -1,6 +1,7 @@
1// SPDX-License-Identifier: GPL-2.0 1// SPDX-License-Identifier: GPL-2.0
2#include <linux/hw_breakpoint.h> 2#include <linux/hw_breakpoint.h>
3#include <linux/err.h> 3#include <linux/err.h>
4#include <linux/zalloc.h>
4#include <dirent.h> 5#include <dirent.h>
5#include <errno.h> 6#include <errno.h>
6#include <sys/ioctl.h> 7#include <sys/ioctl.h>
@@ -651,7 +652,7 @@ static int add_bpf_event(const char *group, const char *event, int fd,
651 pr_debug("Failed to add BPF event %s:%s\n", 652 pr_debug("Failed to add BPF event %s:%s\n",
652 group, event); 653 group, event);
653 list_for_each_entry_safe(evsel, tmp, &new_evsels, node) { 654 list_for_each_entry_safe(evsel, tmp, &new_evsels, node) {
654 list_del(&evsel->node); 655 list_del_init(&evsel->node);
655 perf_evsel__delete(evsel); 656 perf_evsel__delete(evsel);
656 } 657 }
657 return err; 658 return err;
diff --git a/tools/perf/util/parse-events.y b/tools/perf/util/parse-events.y
index 6ad8d4914969..f1c36ed1cf36 100644
--- a/tools/perf/util/parse-events.y
+++ b/tools/perf/util/parse-events.y
@@ -480,7 +480,6 @@ event_bpf_file:
480PE_BPF_OBJECT opt_event_config 480PE_BPF_OBJECT opt_event_config
481{ 481{
482 struct parse_events_state *parse_state = _parse_state; 482 struct parse_events_state *parse_state = _parse_state;
483 struct parse_events_error *error = parse_state->error;
484 struct list_head *list; 483 struct list_head *list;
485 484
486 ALLOC_LIST(list); 485 ALLOC_LIST(list);
@@ -626,7 +625,6 @@ PE_TERM
626PE_NAME array '=' PE_NAME 625PE_NAME array '=' PE_NAME
627{ 626{
628 struct parse_events_term *term; 627 struct parse_events_term *term;
629 int i;
630 628
631 ABORT_ON(parse_events_term__str(&term, PARSE_EVENTS__TERM_TYPE_USER, 629 ABORT_ON(parse_events_term__str(&term, PARSE_EVENTS__TERM_TYPE_USER,
632 $1, $4, &@1, &@4)); 630 $1, $4, &@1, &@4));
diff --git a/tools/perf/util/parse-regs-options.c b/tools/perf/util/parse-regs-options.c
index 08581e276225..ef46c2848808 100644
--- a/tools/perf/util/parse-regs-options.c
+++ b/tools/perf/util/parse-regs-options.c
@@ -1,8 +1,12 @@
1// SPDX-License-Identifier: GPL-2.0 1// SPDX-License-Identifier: GPL-2.0
2#include "perf.h" 2#include <stdbool.h>
3#include "util/util.h" 3#include <stdlib.h>
4#include <stdint.h>
5#include <string.h>
6#include <stdio.h>
4#include "util/debug.h" 7#include "util/debug.h"
5#include <subcmd/parse-options.h> 8#include <subcmd/parse-options.h>
9#include "util/perf_regs.h"
6#include "util/parse-regs-options.h" 10#include "util/parse-regs-options.h"
7 11
8static int 12static int
diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
index 55f4de6442e3..f32b710347db 100644
--- a/tools/perf/util/pmu.c
+++ b/tools/perf/util/pmu.c
@@ -2,6 +2,7 @@
2#include <linux/list.h> 2#include <linux/list.h>
3#include <linux/compiler.h> 3#include <linux/compiler.h>
4#include <linux/string.h> 4#include <linux/string.h>
5#include <linux/zalloc.h>
5#include <sys/types.h> 6#include <sys/types.h>
6#include <errno.h> 7#include <errno.h>
7#include <fcntl.h> 8#include <fcntl.h>
@@ -14,7 +15,6 @@
14#include <api/fs/fs.h> 15#include <api/fs/fs.h>
15#include <locale.h> 16#include <locale.h>
16#include <regex.h> 17#include <regex.h>
17#include "util.h"
18#include "pmu.h" 18#include "pmu.h"
19#include "parse-events.h" 19#include "parse-events.h"
20#include "cpumap.h" 20#include "cpumap.h"
@@ -1245,7 +1245,7 @@ int perf_pmu__check_alias(struct perf_pmu *pmu, struct list_head *head_terms,
1245 info->metric_expr = alias->metric_expr; 1245 info->metric_expr = alias->metric_expr;
1246 info->metric_name = alias->metric_name; 1246 info->metric_name = alias->metric_name;
1247 1247
1248 list_del(&term->list); 1248 list_del_init(&term->list);
1249 free(term); 1249 free(term);
1250 } 1250 }
1251 1251
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index 6f24eaf6e504..cd1eb73cfe83 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -19,7 +19,6 @@
19#include <limits.h> 19#include <limits.h>
20#include <elf.h> 20#include <elf.h>
21 21
22#include "util.h"
23#include "event.h" 22#include "event.h"
24#include "namespaces.h" 23#include "namespaces.h"
25#include "strlist.h" 24#include "strlist.h"
@@ -40,6 +39,7 @@
40#include "string2.h" 39#include "string2.h"
41 40
42#include <linux/ctype.h> 41#include <linux/ctype.h>
42#include <linux/zalloc.h>
43 43
44#define PERFPROBE_GROUP "probe" 44#define PERFPROBE_GROUP "probe"
45 45
@@ -214,9 +214,9 @@ out:
214 214
215static void clear_perf_probe_point(struct perf_probe_point *pp) 215static void clear_perf_probe_point(struct perf_probe_point *pp)
216{ 216{
217 free(pp->file); 217 zfree(&pp->file);
218 free(pp->function); 218 zfree(&pp->function);
219 free(pp->lazy_line); 219 zfree(&pp->lazy_line);
220} 220}
221 221
222static void clear_probe_trace_events(struct probe_trace_event *tevs, int ntevs) 222static void clear_probe_trace_events(struct probe_trace_event *tevs, int ntevs)
@@ -1175,12 +1175,11 @@ int show_available_vars(struct perf_probe_event *pevs __maybe_unused,
1175 1175
1176void line_range__clear(struct line_range *lr) 1176void line_range__clear(struct line_range *lr)
1177{ 1177{
1178 free(lr->function); 1178 zfree(&lr->function);
1179 free(lr->file); 1179 zfree(&lr->file);
1180 free(lr->path); 1180 zfree(&lr->path);
1181 free(lr->comp_dir); 1181 zfree(&lr->comp_dir);
1182 intlist__delete(lr->line_list); 1182 intlist__delete(lr->line_list);
1183 memset(lr, 0, sizeof(*lr));
1184} 1183}
1185 1184
1186int line_range__init(struct line_range *lr) 1185int line_range__init(struct line_range *lr)
@@ -1563,6 +1562,17 @@ static int parse_perf_probe_arg(char *str, struct perf_probe_arg *arg)
1563 str = tmp + 1; 1562 str = tmp + 1;
1564 } 1563 }
1565 1564
1565 tmp = strchr(str, '@');
1566 if (tmp && tmp != str && strcmp(tmp + 1, "user")) { /* user attr */
1567 if (!user_access_is_supported()) {
1568 semantic_error("ftrace does not support user access\n");
1569 return -EINVAL;
1570 }
1571 *tmp = '\0';
1572 arg->user_access = true;
1573 pr_debug("user_access ");
1574 }
1575
1566 tmp = strchr(str, ':'); 1576 tmp = strchr(str, ':');
1567 if (tmp) { /* Type setting */ 1577 if (tmp) { /* Type setting */
1568 *tmp = '\0'; 1578 *tmp = '\0';
@@ -2203,15 +2213,15 @@ void clear_perf_probe_event(struct perf_probe_event *pev)
2203 struct perf_probe_arg_field *field, *next; 2213 struct perf_probe_arg_field *field, *next;
2204 int i; 2214 int i;
2205 2215
2206 free(pev->event); 2216 zfree(&pev->event);
2207 free(pev->group); 2217 zfree(&pev->group);
2208 free(pev->target); 2218 zfree(&pev->target);
2209 clear_perf_probe_point(&pev->point); 2219 clear_perf_probe_point(&pev->point);
2210 2220
2211 for (i = 0; i < pev->nargs; i++) { 2221 for (i = 0; i < pev->nargs; i++) {
2212 free(pev->args[i].name); 2222 zfree(&pev->args[i].name);
2213 free(pev->args[i].var); 2223 zfree(&pev->args[i].var);
2214 free(pev->args[i].type); 2224 zfree(&pev->args[i].type);
2215 field = pev->args[i].field; 2225 field = pev->args[i].field;
2216 while (field) { 2226 while (field) {
2217 next = field->next; 2227 next = field->next;
@@ -2220,8 +2230,7 @@ void clear_perf_probe_event(struct perf_probe_event *pev)
2220 field = next; 2230 field = next;
2221 } 2231 }
2222 } 2232 }
2223 free(pev->args); 2233 zfree(&pev->args);
2224 memset(pev, 0, sizeof(*pev));
2225} 2234}
2226 2235
2227#define strdup_or_goto(str, label) \ 2236#define strdup_or_goto(str, label) \
@@ -2302,15 +2311,15 @@ void clear_probe_trace_event(struct probe_trace_event *tev)
2302 struct probe_trace_arg_ref *ref, *next; 2311 struct probe_trace_arg_ref *ref, *next;
2303 int i; 2312 int i;
2304 2313
2305 free(tev->event); 2314 zfree(&tev->event);
2306 free(tev->group); 2315 zfree(&tev->group);
2307 free(tev->point.symbol); 2316 zfree(&tev->point.symbol);
2308 free(tev->point.realname); 2317 zfree(&tev->point.realname);
2309 free(tev->point.module); 2318 zfree(&tev->point.module);
2310 for (i = 0; i < tev->nargs; i++) { 2319 for (i = 0; i < tev->nargs; i++) {
2311 free(tev->args[i].name); 2320 zfree(&tev->args[i].name);
2312 free(tev->args[i].value); 2321 zfree(&tev->args[i].value);
2313 free(tev->args[i].type); 2322 zfree(&tev->args[i].type);
2314 ref = tev->args[i].ref; 2323 ref = tev->args[i].ref;
2315 while (ref) { 2324 while (ref) {
2316 next = ref->next; 2325 next = ref->next;
@@ -2318,8 +2327,7 @@ void clear_probe_trace_event(struct probe_trace_event *tev)
2318 ref = next; 2327 ref = next;
2319 } 2328 }
2320 } 2329 }
2321 free(tev->args); 2330 zfree(&tev->args);
2322 memset(tev, 0, sizeof(*tev));
2323} 2331}
2324 2332
2325struct kprobe_blacklist_node { 2333struct kprobe_blacklist_node {
@@ -2336,8 +2344,8 @@ static void kprobe_blacklist__delete(struct list_head *blacklist)
2336 while (!list_empty(blacklist)) { 2344 while (!list_empty(blacklist)) {
2337 node = list_first_entry(blacklist, 2345 node = list_first_entry(blacklist,
2338 struct kprobe_blacklist_node, list); 2346 struct kprobe_blacklist_node, list);
2339 list_del(&node->list); 2347 list_del_init(&node->list);
2340 free(node->symbol); 2348 zfree(&node->symbol);
2341 free(node); 2349 free(node);
2342 } 2350 }
2343} 2351}
diff --git a/tools/perf/util/probe-event.h b/tools/perf/util/probe-event.h
index 05c8d571a901..96a319cd2378 100644
--- a/tools/perf/util/probe-event.h
+++ b/tools/perf/util/probe-event.h
@@ -37,6 +37,7 @@ struct probe_trace_point {
37struct probe_trace_arg_ref { 37struct probe_trace_arg_ref {
38 struct probe_trace_arg_ref *next; /* Next reference */ 38 struct probe_trace_arg_ref *next; /* Next reference */
39 long offset; /* Offset value */ 39 long offset; /* Offset value */
40 bool user_access; /* User-memory access */
40}; 41};
41 42
42/* kprobe-tracer and uprobe-tracer tracing argument */ 43/* kprobe-tracer and uprobe-tracer tracing argument */
@@ -82,6 +83,7 @@ struct perf_probe_arg {
82 char *var; /* Variable name */ 83 char *var; /* Variable name */
83 char *type; /* Type name */ 84 char *type; /* Type name */
84 struct perf_probe_arg_field *field; /* Structure fields */ 85 struct perf_probe_arg_field *field; /* Structure fields */
86 bool user_access; /* User-memory access */
85}; 87};
86 88
87/* Perf probe probing event (point + arg) */ 89/* Perf probe probing event (point + arg) */
diff --git a/tools/perf/util/probe-file.c b/tools/perf/util/probe-file.c
index 0ed1900454eb..5b4d49382932 100644
--- a/tools/perf/util/probe-file.c
+++ b/tools/perf/util/probe-file.c
@@ -10,8 +10,8 @@
10#include <sys/types.h> 10#include <sys/types.h>
11#include <sys/uio.h> 11#include <sys/uio.h>
12#include <unistd.h> 12#include <unistd.h>
13#include <linux/zalloc.h>
13#include "namespaces.h" 14#include "namespaces.h"
14#include "util.h"
15#include "event.h" 15#include "event.h"
16#include "strlist.h" 16#include "strlist.h"
17#include "strfilter.h" 17#include "strfilter.h"
@@ -1005,6 +1005,7 @@ enum ftrace_readme {
1005 FTRACE_README_PROBE_TYPE_X = 0, 1005 FTRACE_README_PROBE_TYPE_X = 0,
1006 FTRACE_README_KRETPROBE_OFFSET, 1006 FTRACE_README_KRETPROBE_OFFSET,
1007 FTRACE_README_UPROBE_REF_CTR, 1007 FTRACE_README_UPROBE_REF_CTR,
1008 FTRACE_README_USER_ACCESS,
1008 FTRACE_README_END, 1009 FTRACE_README_END,
1009}; 1010};
1010 1011
@@ -1017,6 +1018,7 @@ static struct {
1017 DEFINE_TYPE(FTRACE_README_PROBE_TYPE_X, "*type: * x8/16/32/64,*"), 1018 DEFINE_TYPE(FTRACE_README_PROBE_TYPE_X, "*type: * x8/16/32/64,*"),
1018 DEFINE_TYPE(FTRACE_README_KRETPROBE_OFFSET, "*place (kretprobe): *"), 1019 DEFINE_TYPE(FTRACE_README_KRETPROBE_OFFSET, "*place (kretprobe): *"),
1019 DEFINE_TYPE(FTRACE_README_UPROBE_REF_CTR, "*ref_ctr_offset*"), 1020 DEFINE_TYPE(FTRACE_README_UPROBE_REF_CTR, "*ref_ctr_offset*"),
1021 DEFINE_TYPE(FTRACE_README_USER_ACCESS, "*[u]<offset>*"),
1020}; 1022};
1021 1023
1022static bool scan_ftrace_readme(enum ftrace_readme type) 1024static bool scan_ftrace_readme(enum ftrace_readme type)
@@ -1077,3 +1079,8 @@ bool uprobe_ref_ctr_is_supported(void)
1077{ 1079{
1078 return scan_ftrace_readme(FTRACE_README_UPROBE_REF_CTR); 1080 return scan_ftrace_readme(FTRACE_README_UPROBE_REF_CTR);
1079} 1081}
1082
1083bool user_access_is_supported(void)
1084{
1085 return scan_ftrace_readme(FTRACE_README_USER_ACCESS);
1086}
diff --git a/tools/perf/util/probe-file.h b/tools/perf/util/probe-file.h
index 2a249182f2a6..986c1c94f64f 100644
--- a/tools/perf/util/probe-file.h
+++ b/tools/perf/util/probe-file.h
@@ -70,6 +70,7 @@ int probe_cache__show_all_caches(struct strfilter *filter);
70bool probe_type_is_available(enum probe_type type); 70bool probe_type_is_available(enum probe_type type);
71bool kretprobe_offset_is_supported(void); 71bool kretprobe_offset_is_supported(void);
72bool uprobe_ref_ctr_is_supported(void); 72bool uprobe_ref_ctr_is_supported(void);
73bool user_access_is_supported(void);
73#else /* ! HAVE_LIBELF_SUPPORT */ 74#else /* ! HAVE_LIBELF_SUPPORT */
74static inline struct probe_cache *probe_cache__new(const char *tgt __maybe_unused, struct nsinfo *nsi __maybe_unused) 75static inline struct probe_cache *probe_cache__new(const char *tgt __maybe_unused, struct nsinfo *nsi __maybe_unused)
75{ 76{
diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c
index 6b40cc691a2d..025fc4491993 100644
--- a/tools/perf/util/probe-finder.c
+++ b/tools/perf/util/probe-finder.c
@@ -19,11 +19,11 @@
19#include <dwarf-regs.h> 19#include <dwarf-regs.h>
20 20
21#include <linux/bitops.h> 21#include <linux/bitops.h>
22#include <linux/zalloc.h>
22#include "event.h" 23#include "event.h"
23#include "dso.h" 24#include "dso.h"
24#include "debug.h" 25#include "debug.h"
25#include "intlist.h" 26#include "intlist.h"
26#include "util.h"
27#include "strlist.h" 27#include "strlist.h"
28#include "symbol.h" 28#include "symbol.h"
29#include "probe-finder.h" 29#include "probe-finder.h"
@@ -280,7 +280,7 @@ static_var:
280 280
281static int convert_variable_type(Dwarf_Die *vr_die, 281static int convert_variable_type(Dwarf_Die *vr_die,
282 struct probe_trace_arg *tvar, 282 struct probe_trace_arg *tvar,
283 const char *cast) 283 const char *cast, bool user_access)
284{ 284{
285 struct probe_trace_arg_ref **ref_ptr = &tvar->ref; 285 struct probe_trace_arg_ref **ref_ptr = &tvar->ref;
286 Dwarf_Die type; 286 Dwarf_Die type;
@@ -320,7 +320,8 @@ static int convert_variable_type(Dwarf_Die *vr_die,
320 pr_debug("%s type is %s.\n", 320 pr_debug("%s type is %s.\n",
321 dwarf_diename(vr_die), dwarf_diename(&type)); 321 dwarf_diename(vr_die), dwarf_diename(&type));
322 322
323 if (cast && strcmp(cast, "string") == 0) { /* String type */ 323 if (cast && (!strcmp(cast, "string") || !strcmp(cast, "ustring"))) {
324 /* String type */
324 ret = dwarf_tag(&type); 325 ret = dwarf_tag(&type);
325 if (ret != DW_TAG_pointer_type && 326 if (ret != DW_TAG_pointer_type &&
326 ret != DW_TAG_array_type) { 327 ret != DW_TAG_array_type) {
@@ -343,6 +344,7 @@ static int convert_variable_type(Dwarf_Die *vr_die,
343 pr_warning("Out of memory error\n"); 344 pr_warning("Out of memory error\n");
344 return -ENOMEM; 345 return -ENOMEM;
345 } 346 }
347 (*ref_ptr)->user_access = user_access;
346 } 348 }
347 if (!die_compare_name(&type, "char") && 349 if (!die_compare_name(&type, "char") &&
348 !die_compare_name(&type, "unsigned char")) { 350 !die_compare_name(&type, "unsigned char")) {
@@ -397,7 +399,7 @@ formatted:
397static int convert_variable_fields(Dwarf_Die *vr_die, const char *varname, 399static int convert_variable_fields(Dwarf_Die *vr_die, const char *varname,
398 struct perf_probe_arg_field *field, 400 struct perf_probe_arg_field *field,
399 struct probe_trace_arg_ref **ref_ptr, 401 struct probe_trace_arg_ref **ref_ptr,
400 Dwarf_Die *die_mem) 402 Dwarf_Die *die_mem, bool user_access)
401{ 403{
402 struct probe_trace_arg_ref *ref = *ref_ptr; 404 struct probe_trace_arg_ref *ref = *ref_ptr;
403 Dwarf_Die type; 405 Dwarf_Die type;
@@ -434,6 +436,7 @@ static int convert_variable_fields(Dwarf_Die *vr_die, const char *varname,
434 *ref_ptr = ref; 436 *ref_ptr = ref;
435 } 437 }
436 ref->offset += dwarf_bytesize(&type) * field->index; 438 ref->offset += dwarf_bytesize(&type) * field->index;
439 ref->user_access = user_access;
437 goto next; 440 goto next;
438 } else if (tag == DW_TAG_pointer_type) { 441 } else if (tag == DW_TAG_pointer_type) {
439 /* Check the pointer and dereference */ 442 /* Check the pointer and dereference */
@@ -505,17 +508,18 @@ static int convert_variable_fields(Dwarf_Die *vr_die, const char *varname,
505 } 508 }
506 } 509 }
507 ref->offset += (long)offs; 510 ref->offset += (long)offs;
511 ref->user_access = user_access;
508 512
509 /* If this member is unnamed, we need to reuse this field */ 513 /* If this member is unnamed, we need to reuse this field */
510 if (!dwarf_diename(die_mem)) 514 if (!dwarf_diename(die_mem))
511 return convert_variable_fields(die_mem, varname, field, 515 return convert_variable_fields(die_mem, varname, field,
512 &ref, die_mem); 516 &ref, die_mem, user_access);
513 517
514next: 518next:
515 /* Converting next field */ 519 /* Converting next field */
516 if (field->next) 520 if (field->next)
517 return convert_variable_fields(die_mem, field->name, 521 return convert_variable_fields(die_mem, field->name,
518 field->next, &ref, die_mem); 522 field->next, &ref, die_mem, user_access);
519 else 523 else
520 return 0; 524 return 0;
521} 525}
@@ -541,11 +545,12 @@ static int convert_variable(Dwarf_Die *vr_die, struct probe_finder *pf)
541 else if (ret == 0 && pf->pvar->field) { 545 else if (ret == 0 && pf->pvar->field) {
542 ret = convert_variable_fields(vr_die, pf->pvar->var, 546 ret = convert_variable_fields(vr_die, pf->pvar->var,
543 pf->pvar->field, &pf->tvar->ref, 547 pf->pvar->field, &pf->tvar->ref,
544 &die_mem); 548 &die_mem, pf->pvar->user_access);
545 vr_die = &die_mem; 549 vr_die = &die_mem;
546 } 550 }
547 if (ret == 0) 551 if (ret == 0)
548 ret = convert_variable_type(vr_die, pf->tvar, pf->pvar->type); 552 ret = convert_variable_type(vr_die, pf->tvar, pf->pvar->type,
553 pf->pvar->user_access);
549 /* *expr will be cached in libdw. Don't free it. */ 554 /* *expr will be cached in libdw. Don't free it. */
550 return ret; 555 return ret;
551} 556}
diff --git a/tools/perf/util/pstack.c b/tools/perf/util/pstack.c
index 797fe1ae2d2e..28de8a4c2ce8 100644
--- a/tools/perf/util/pstack.c
+++ b/tools/perf/util/pstack.c
@@ -5,10 +5,10 @@
5 * (c) 2010 Arnaldo Carvalho de Melo <acme@redhat.com> 5 * (c) 2010 Arnaldo Carvalho de Melo <acme@redhat.com>
6 */ 6 */
7 7
8#include "util.h"
9#include "pstack.h" 8#include "pstack.h"
10#include "debug.h" 9#include "debug.h"
11#include <linux/kernel.h> 10#include <linux/kernel.h>
11#include <linux/zalloc.h>
12#include <stdlib.h> 12#include <stdlib.h>
13 13
14struct pstack { 14struct pstack {
diff --git a/tools/perf/util/python-ext-sources b/tools/perf/util/python-ext-sources
index 2237bac9fadb..ceb8afdf9a89 100644
--- a/tools/perf/util/python-ext-sources
+++ b/tools/perf/util/python-ext-sources
@@ -18,6 +18,7 @@ util/namespaces.c
18../lib/hweight.c 18../lib/hweight.c
19../lib/string.c 19../lib/string.c
20../lib/vsprintf.c 20../lib/vsprintf.c
21../lib/zalloc.c
21util/thread_map.c 22util/thread_map.c
22util/util.c 23util/util.c
23util/xyarray.c 24util/xyarray.c
diff --git a/tools/perf/util/rlimit.c b/tools/perf/util/rlimit.c
new file mode 100644
index 000000000000..13521d392a22
--- /dev/null
+++ b/tools/perf/util/rlimit.c
@@ -0,0 +1,29 @@
1/* SPDX-License-Identifier: LGPL-2.1 */
2
3#include "util/debug.h"
4#include "util/rlimit.h"
5#include <sys/time.h>
6#include <sys/resource.h>
7
8/*
9 * Bump the memlock so that we can get bpf maps of a reasonable size,
10 * like the ones used with 'perf trace' and with 'perf test bpf',
11 * improve this to some specific request if needed.
12 */
13void rlimit__bump_memlock(void)
14{
15 struct rlimit rlim;
16
17 if (getrlimit(RLIMIT_MEMLOCK, &rlim) == 0) {
18 rlim.rlim_cur *= 4;
19 rlim.rlim_max *= 4;
20
21 if (setrlimit(RLIMIT_MEMLOCK, &rlim) < 0) {
22 rlim.rlim_cur /= 2;
23 rlim.rlim_max /= 2;
24
25 if (setrlimit(RLIMIT_MEMLOCK, &rlim) < 0)
26 pr_debug("Couldn't bump rlimit(MEMLOCK), failures may take place when creating BPF maps, etc\n");
27 }
28 }
29}
diff --git a/tools/perf/util/rlimit.h b/tools/perf/util/rlimit.h
new file mode 100644
index 000000000000..9f59d8e710a3
--- /dev/null
+++ b/tools/perf/util/rlimit.h
@@ -0,0 +1,6 @@
1#ifndef __PERF_RLIMIT_H_
2#define __PERF_RLIMIT_H_
3/* SPDX-License-Identifier: LGPL-2.1 */
4
5void rlimit__bump_memlock(void);
6#endif // __PERF_RLIMIT_H_
diff --git a/tools/perf/util/s390-cpumsf.c b/tools/perf/util/s390-cpumsf.c
index 10d36d9b7909..83d2e149ef19 100644
--- a/tools/perf/util/s390-cpumsf.c
+++ b/tools/perf/util/s390-cpumsf.c
@@ -146,6 +146,7 @@
146#include <linux/types.h> 146#include <linux/types.h>
147#include <linux/bitops.h> 147#include <linux/bitops.h>
148#include <linux/log2.h> 148#include <linux/log2.h>
149#include <linux/zalloc.h>
149 150
150#include <sys/stat.h> 151#include <sys/stat.h>
151#include <sys/types.h> 152#include <sys/types.h>
@@ -156,7 +157,6 @@
156#include "evlist.h" 157#include "evlist.h"
157#include "machine.h" 158#include "machine.h"
158#include "session.h" 159#include "session.h"
159#include "util.h"
160#include "thread.h" 160#include "thread.h"
161#include "debug.h" 161#include "debug.h"
162#include "auxtrace.h" 162#include "auxtrace.h"
@@ -756,7 +756,7 @@ static int s390_cpumsf_run_decoder(struct s390_cpumsf_queue *sfq,
756 */ 756 */
757 if (err) { 757 if (err) {
758 sfq->buffer = NULL; 758 sfq->buffer = NULL;
759 list_del(&buffer->list); 759 list_del_init(&buffer->list);
760 auxtrace_buffer__free(buffer); 760 auxtrace_buffer__free(buffer);
761 if (err > 0) /* Buffer done, no error */ 761 if (err > 0) /* Buffer done, no error */
762 err = 0; 762 err = 0;
@@ -1044,7 +1044,7 @@ static void s390_cpumsf_free(struct perf_session *session)
1044 auxtrace_heap__free(&sf->heap); 1044 auxtrace_heap__free(&sf->heap);
1045 s390_cpumsf_free_queues(session); 1045 s390_cpumsf_free_queues(session);
1046 session->auxtrace = NULL; 1046 session->auxtrace = NULL;
1047 free(sf->logdir); 1047 zfree(&sf->logdir);
1048 free(sf); 1048 free(sf);
1049} 1049}
1050 1050
@@ -1101,8 +1101,7 @@ static int s390_cpumsf__config(const char *var, const char *value, void *cb)
1101 if (rc == -1 || !S_ISDIR(stbuf.st_mode)) { 1101 if (rc == -1 || !S_ISDIR(stbuf.st_mode)) {
1102 pr_err("Missing auxtrace log directory %s," 1102 pr_err("Missing auxtrace log directory %s,"
1103 " continue with current directory...\n", value); 1103 " continue with current directory...\n", value);
1104 free(sf->logdir); 1104 zfree(&sf->logdir);
1105 sf->logdir = NULL;
1106 } 1105 }
1107 return 1; 1106 return 1;
1108} 1107}
@@ -1162,7 +1161,7 @@ err_free_queues:
1162 auxtrace_queues__free(&sf->queues); 1161 auxtrace_queues__free(&sf->queues);
1163 session->auxtrace = NULL; 1162 session->auxtrace = NULL;
1164err_free: 1163err_free:
1165 free(sf->logdir); 1164 zfree(&sf->logdir);
1166 free(sf); 1165 free(sf);
1167 return err; 1166 return err;
1168} 1167}
diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c
index 112bed65232f..25dc1d765553 100644
--- a/tools/perf/util/scripting-engines/trace-event-python.c
+++ b/tools/perf/util/scripting-engines/trace-event-python.c
@@ -113,6 +113,7 @@ struct tables {
113 PyObject *call_path_handler; 113 PyObject *call_path_handler;
114 PyObject *call_return_handler; 114 PyObject *call_return_handler;
115 PyObject *synth_handler; 115 PyObject *synth_handler;
116 PyObject *context_switch_handler;
116 bool db_export_mode; 117 bool db_export_mode;
117}; 118};
118 119
@@ -1011,15 +1012,19 @@ static int python_export_thread(struct db_export *dbe, struct thread *thread,
1011 return 0; 1012 return 0;
1012} 1013}
1013 1014
1014static int python_export_comm(struct db_export *dbe, struct comm *comm) 1015static int python_export_comm(struct db_export *dbe, struct comm *comm,
1016 struct thread *thread)
1015{ 1017{
1016 struct tables *tables = container_of(dbe, struct tables, dbe); 1018 struct tables *tables = container_of(dbe, struct tables, dbe);
1017 PyObject *t; 1019 PyObject *t;
1018 1020
1019 t = tuple_new(2); 1021 t = tuple_new(5);
1020 1022
1021 tuple_set_u64(t, 0, comm->db_id); 1023 tuple_set_u64(t, 0, comm->db_id);
1022 tuple_set_string(t, 1, comm__str(comm)); 1024 tuple_set_string(t, 1, comm__str(comm));
1025 tuple_set_u64(t, 2, thread->db_id);
1026 tuple_set_u64(t, 3, comm->start);
1027 tuple_set_s32(t, 4, comm->exec);
1023 1028
1024 call_object(tables->comm_handler, t, "comm_table"); 1029 call_object(tables->comm_handler, t, "comm_table");
1025 1030
@@ -1233,6 +1238,34 @@ static int python_export_call_return(struct db_export *dbe,
1233 return 0; 1238 return 0;
1234} 1239}
1235 1240
1241static int python_export_context_switch(struct db_export *dbe, u64 db_id,
1242 struct machine *machine,
1243 struct perf_sample *sample,
1244 u64 th_out_id, u64 comm_out_id,
1245 u64 th_in_id, u64 comm_in_id, int flags)
1246{
1247 struct tables *tables = container_of(dbe, struct tables, dbe);
1248 PyObject *t;
1249
1250 t = tuple_new(9);
1251
1252 tuple_set_u64(t, 0, db_id);
1253 tuple_set_u64(t, 1, machine->db_id);
1254 tuple_set_u64(t, 2, sample->time);
1255 tuple_set_s32(t, 3, sample->cpu);
1256 tuple_set_u64(t, 4, th_out_id);
1257 tuple_set_u64(t, 5, comm_out_id);
1258 tuple_set_u64(t, 6, th_in_id);
1259 tuple_set_u64(t, 7, comm_in_id);
1260 tuple_set_s32(t, 8, flags);
1261
1262 call_object(tables->context_switch_handler, t, "context_switch");
1263
1264 Py_DECREF(t);
1265
1266 return 0;
1267}
1268
1236static int python_process_call_return(struct call_return *cr, u64 *parent_db_id, 1269static int python_process_call_return(struct call_return *cr, u64 *parent_db_id,
1237 void *data) 1270 void *data)
1238{ 1271{
@@ -1296,6 +1329,16 @@ static void python_process_event(union perf_event *event,
1296 } 1329 }
1297} 1330}
1298 1331
1332static void python_process_switch(union perf_event *event,
1333 struct perf_sample *sample,
1334 struct machine *machine)
1335{
1336 struct tables *tables = &tables_global;
1337
1338 if (tables->db_export_mode)
1339 db_export__switch(&tables->dbe, event, sample, machine);
1340}
1341
1299static void get_handler_name(char *str, size_t size, 1342static void get_handler_name(char *str, size_t size,
1300 struct perf_evsel *evsel) 1343 struct perf_evsel *evsel)
1301{ 1344{
@@ -1511,6 +1554,7 @@ static void set_table_handlers(struct tables *tables)
1511 SET_TABLE_HANDLER(sample); 1554 SET_TABLE_HANDLER(sample);
1512 SET_TABLE_HANDLER(call_path); 1555 SET_TABLE_HANDLER(call_path);
1513 SET_TABLE_HANDLER(call_return); 1556 SET_TABLE_HANDLER(call_return);
1557 SET_TABLE_HANDLER(context_switch);
1514 1558
1515 /* 1559 /*
1516 * Synthesized events are samples but with architecture-specific data 1560 * Synthesized events are samples but with architecture-specific data
@@ -1620,9 +1664,7 @@ error:
1620 1664
1621static int python_flush_script(void) 1665static int python_flush_script(void)
1622{ 1666{
1623 struct tables *tables = &tables_global; 1667 return 0;
1624
1625 return db_export__flush(&tables->dbe);
1626} 1668}
1627 1669
1628/* 1670/*
@@ -1831,6 +1873,7 @@ struct scripting_ops python_scripting_ops = {
1831 .flush_script = python_flush_script, 1873 .flush_script = python_flush_script,
1832 .stop_script = python_stop_script, 1874 .stop_script = python_stop_script,
1833 .process_event = python_process_event, 1875 .process_event = python_process_event,
1876 .process_switch = python_process_switch,
1834 .process_stat = python_process_stat, 1877 .process_stat = python_process_stat,
1835 .process_stat_interval = python_process_stat_interval, 1878 .process_stat_interval = python_process_stat_interval,
1836 .generate_script = python_generate_script, 1879 .generate_script = python_generate_script,
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 54cf163347f7..d0fd6c614e68 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -2,6 +2,7 @@
2#include <errno.h> 2#include <errno.h>
3#include <inttypes.h> 3#include <inttypes.h>
4#include <linux/kernel.h> 4#include <linux/kernel.h>
5#include <linux/zalloc.h>
5#include <traceevent/event-parse.h> 6#include <traceevent/event-parse.h>
6#include <api/fs/fs.h> 7#include <api/fs/fs.h>
7 8
@@ -18,7 +19,6 @@
18#include "session.h" 19#include "session.h"
19#include "tool.h" 20#include "tool.h"
20#include "sort.h" 21#include "sort.h"
21#include "util.h"
22#include "cpumap.h" 22#include "cpumap.h"
23#include "perf_regs.h" 23#include "perf_regs.h"
24#include "asm/bug.h" 24#include "asm/bug.h"
@@ -1246,9 +1246,12 @@ static void dump_read(struct perf_evsel *evsel, union perf_event *event)
1246 return; 1246 return;
1247 1247
1248 printf(": %d %d %s %" PRIu64 "\n", event->read.pid, event->read.tid, 1248 printf(": %d %d %s %" PRIu64 "\n", event->read.pid, event->read.tid,
1249 evsel ? perf_evsel__name(evsel) : "FAIL", 1249 perf_evsel__name(evsel),
1250 event->read.value); 1250 event->read.value);
1251 1251
1252 if (!evsel)
1253 return;
1254
1252 read_format = evsel->attr.read_format; 1255 read_format = evsel->attr.read_format;
1253 1256
1254 if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED) 1257 if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED)
diff --git a/tools/perf/util/setns.c b/tools/perf/util/setns.c
index ce8fc290fce8..48f9c0af63b2 100644
--- a/tools/perf/util/setns.c
+++ b/tools/perf/util/setns.c
@@ -1,4 +1,6 @@
1#include "util.h" 1// SPDX-License-Identifier: LGPL-2.1
2
3#include "namespaces.h"
2#include <unistd.h> 4#include <unistd.h>
3#include <sys/syscall.h> 5#include <sys/syscall.h>
4 6
diff --git a/tools/perf/util/srccode.c b/tools/perf/util/srccode.c
index 684b155c222a..adfcf1ff464c 100644
--- a/tools/perf/util/srccode.c
+++ b/tools/perf/util/srccode.c
@@ -4,7 +4,8 @@
4 * Copyright (c) 2017, Intel Corporation. 4 * Copyright (c) 2017, Intel Corporation.
5 * Author: Andi Kleen 5 * Author: Andi Kleen
6 */ 6 */
7#include "linux/list.h" 7#include <linux/list.h>
8#include <linux/zalloc.h>
8#include <stdlib.h> 9#include <stdlib.h>
9#include <sys/mman.h> 10#include <sys/mman.h>
10#include <sys/stat.h> 11#include <sys/stat.h>
@@ -82,12 +83,12 @@ static void fill_lines(char **lines, int maxline, char *map, int maplen)
82 83
83static void free_srcfile(struct srcfile *sf) 84static void free_srcfile(struct srcfile *sf)
84{ 85{
85 list_del(&sf->nd); 86 list_del_init(&sf->nd);
86 hlist_del(&sf->hash_nd); 87 hlist_del(&sf->hash_nd);
87 map_total_sz -= sf->maplen; 88 map_total_sz -= sf->maplen;
88 munmap(sf->map, sf->maplen); 89 munmap(sf->map, sf->maplen);
89 free(sf->lines); 90 zfree(&sf->lines);
90 free(sf->fn); 91 zfree(&sf->fn);
91 free(sf); 92 free(sf);
92 num_srcfiles--; 93 num_srcfiles--;
93} 94}
@@ -153,7 +154,7 @@ static struct srcfile *find_srcfile(char *fn)
153out_map: 154out_map:
154 munmap(h->map, sz); 155 munmap(h->map, sz);
155out_fn: 156out_fn:
156 free(h->fn); 157 zfree(&h->fn);
157out_h: 158out_h:
158 free(h); 159 free(h);
159 return NULL; 160 return NULL;
diff --git a/tools/perf/util/srcline.c b/tools/perf/util/srcline.c
index dcad75daf5e4..6ccf6f6d09df 100644
--- a/tools/perf/util/srcline.c
+++ b/tools/perf/util/srcline.c
@@ -6,9 +6,9 @@
6 6
7#include <linux/kernel.h> 7#include <linux/kernel.h>
8#include <linux/string.h> 8#include <linux/string.h>
9#include <linux/zalloc.h>
9 10
10#include "util/dso.h" 11#include "util/dso.h"
11#include "util/util.h"
12#include "util/debug.h" 12#include "util/debug.h"
13#include "util/callchain.h" 13#include "util/callchain.h"
14#include "util/symbol_conf.h" 14#include "util/symbol_conf.h"
diff --git a/tools/perf/util/stat-shadow.c b/tools/perf/util/stat-shadow.c
index cb891e5c2969..656065af4971 100644
--- a/tools/perf/util/stat-shadow.c
+++ b/tools/perf/util/stat-shadow.c
@@ -8,6 +8,7 @@
8#include "evlist.h" 8#include "evlist.h"
9#include "expr.h" 9#include "expr.h"
10#include "metricgroup.h" 10#include "metricgroup.h"
11#include <linux/zalloc.h>
11 12
12/* 13/*
13 * AGGR_GLOBAL: Use CPU 0 14 * AGGR_GLOBAL: Use CPU 0
@@ -775,7 +776,7 @@ static void generic_metric(struct perf_stat_config *config,
775 print_metric(config, ctxp, NULL, NULL, "", 0); 776 print_metric(config, ctxp, NULL, NULL, "", 0);
776 777
777 for (i = 1; i < pctx.num_ids; i++) 778 for (i = 1; i < pctx.num_ids; i++)
778 free((void *)pctx.ids[i].name); 779 zfree(&pctx.ids[i].name);
779} 780}
780 781
781void perf_stat__print_shadow_stats(struct perf_stat_config *config, 782void perf_stat__print_shadow_stats(struct perf_stat_config *config,
diff --git a/tools/perf/util/stat.c b/tools/perf/util/stat.c
index d91fe754b6d2..db8a6cf336be 100644
--- a/tools/perf/util/stat.c
+++ b/tools/perf/util/stat.c
@@ -6,6 +6,7 @@
6#include "evlist.h" 6#include "evlist.h"
7#include "evsel.h" 7#include "evsel.h"
8#include "thread_map.h" 8#include "thread_map.h"
9#include <linux/zalloc.h>
9 10
10void update_stats(struct stats *stats, u64 val) 11void update_stats(struct stats *stats, u64 val)
11{ 12{
@@ -132,7 +133,7 @@ static void perf_evsel__free_stat_priv(struct perf_evsel *evsel)
132 struct perf_stat_evsel *ps = evsel->stats; 133 struct perf_stat_evsel *ps = evsel->stats;
133 134
134 if (ps) 135 if (ps)
135 free(ps->group_data); 136 zfree(&ps->group_data);
136 zfree(&evsel->stats); 137 zfree(&evsel->stats);
137} 138}
138 139
diff --git a/tools/perf/util/strbuf.c b/tools/perf/util/strbuf.c
index 23092fd6451d..2ce0dc887364 100644
--- a/tools/perf/util/strbuf.c
+++ b/tools/perf/util/strbuf.c
@@ -1,8 +1,9 @@
1// SPDX-License-Identifier: GPL-2.0 1// SPDX-License-Identifier: GPL-2.0
2#include "debug.h" 2#include "debug.h"
3#include "util.h"
4#include <linux/kernel.h> 3#include <linux/kernel.h>
4#include <linux/zalloc.h>
5#include <errno.h> 5#include <errno.h>
6#include <stdlib.h>
6 7
7/* 8/*
8 * Used as the default ->buf value, so that people can always assume 9 * Used as the default ->buf value, so that people can always assume
diff --git a/tools/perf/util/strfilter.c b/tools/perf/util/strfilter.c
index 90ea2b209cbb..78aa4c3b990d 100644
--- a/tools/perf/util/strfilter.c
+++ b/tools/perf/util/strfilter.c
@@ -1,11 +1,12 @@
1// SPDX-License-Identifier: GPL-2.0 1// SPDX-License-Identifier: GPL-2.0
2#include "util.h"
3#include "string2.h" 2#include "string2.h"
4#include "strfilter.h" 3#include "strfilter.h"
5 4
6#include <errno.h> 5#include <errno.h>
6#include <stdlib.h>
7#include <linux/ctype.h> 7#include <linux/ctype.h>
8#include <linux/string.h> 8#include <linux/string.h>
9#include <linux/zalloc.h>
9 10
10/* Operators */ 11/* Operators */
11static const char *OP_and = "&"; /* Logical AND */ 12static const char *OP_and = "&"; /* Logical AND */
diff --git a/tools/perf/util/strlist.c b/tools/perf/util/strlist.c
index af45c6fd97db..8a868cbeffae 100644
--- a/tools/perf/util/strlist.c
+++ b/tools/perf/util/strlist.c
@@ -4,12 +4,12 @@
4 */ 4 */
5 5
6#include "strlist.h" 6#include "strlist.h"
7#include "util.h"
8#include <errno.h> 7#include <errno.h>
9#include <stdio.h> 8#include <stdio.h>
10#include <stdlib.h> 9#include <stdlib.h>
11#include <string.h> 10#include <string.h>
12#include <unistd.h> 11#include <unistd.h>
12#include <linux/zalloc.h>
13 13
14static 14static
15struct rb_node *strlist__node_new(struct rblist *rblist, const void *entry) 15struct rb_node *strlist__node_new(struct rblist *rblist, const void *entry)
diff --git a/tools/perf/util/svghelper.c b/tools/perf/util/svghelper.c
index fab8a048d31b..76cc54000483 100644
--- a/tools/perf/util/svghelper.c
+++ b/tools/perf/util/svghelper.c
@@ -15,10 +15,10 @@
15#include <string.h> 15#include <string.h>
16#include <linux/bitmap.h> 16#include <linux/bitmap.h>
17#include <linux/time64.h> 17#include <linux/time64.h>
18#include <linux/zalloc.h>
18 19
19#include "perf.h" 20#include "perf.h"
20#include "svghelper.h" 21#include "svghelper.h"
21#include "util.h"
22#include "cpumap.h" 22#include "cpumap.h"
23 23
24static u64 first_time, last_time; 24static u64 first_time, last_time;
diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c
index 62008756d8cc..7d504dc22108 100644
--- a/tools/perf/util/symbol-elf.c
+++ b/tools/perf/util/symbol-elf.c
@@ -2,6 +2,7 @@
2#include <fcntl.h> 2#include <fcntl.h>
3#include <stdio.h> 3#include <stdio.h>
4#include <errno.h> 4#include <errno.h>
5#include <stdlib.h>
5#include <string.h> 6#include <string.h>
6#include <unistd.h> 7#include <unistd.h>
7#include <inttypes.h> 8#include <inttypes.h>
@@ -16,6 +17,7 @@
16#include "debug.h" 17#include "debug.h"
17#include "util.h" 18#include "util.h"
18#include <linux/ctype.h> 19#include <linux/ctype.h>
20#include <linux/zalloc.h>
19#include <symbol/kallsyms.h> 21#include <symbol/kallsyms.h>
20 22
21#ifndef EM_AARCH64 23#ifndef EM_AARCH64
@@ -1476,7 +1478,7 @@ static void kcore_copy__free_phdrs(struct kcore_copy_info *kci)
1476 struct phdr_data *p, *tmp; 1478 struct phdr_data *p, *tmp;
1477 1479
1478 list_for_each_entry_safe(p, tmp, &kci->phdrs, node) { 1480 list_for_each_entry_safe(p, tmp, &kci->phdrs, node) {
1479 list_del(&p->node); 1481 list_del_init(&p->node);
1480 free(p); 1482 free(p);
1481 } 1483 }
1482} 1484}
@@ -1499,7 +1501,7 @@ static void kcore_copy__free_syms(struct kcore_copy_info *kci)
1499 struct sym_data *s, *tmp; 1501 struct sym_data *s, *tmp;
1500 1502
1501 list_for_each_entry_safe(s, tmp, &kci->syms, node) { 1503 list_for_each_entry_safe(s, tmp, &kci->syms, node) {
1502 list_del(&s->node); 1504 list_del_init(&s->node);
1503 free(s); 1505 free(s);
1504 } 1506 }
1505} 1507}
@@ -2131,11 +2133,11 @@ static int populate_sdt_note(Elf **elf, const char *data, size_t len,
2131 return 0; 2133 return 0;
2132 2134
2133out_free_args: 2135out_free_args:
2134 free(tmp->args); 2136 zfree(&tmp->args);
2135out_free_name: 2137out_free_name:
2136 free(tmp->name); 2138 zfree(&tmp->name);
2137out_free_prov: 2139out_free_prov:
2138 free(tmp->provider); 2140 zfree(&tmp->provider);
2139out_free_note: 2141out_free_note:
2140 free(tmp); 2142 free(tmp);
2141out_err: 2143out_err:
@@ -2250,9 +2252,9 @@ int cleanup_sdt_note_list(struct list_head *sdt_notes)
2250 int nr_free = 0; 2252 int nr_free = 0;
2251 2253
2252 list_for_each_entry_safe(pos, tmp, sdt_notes, note_list) { 2254 list_for_each_entry_safe(pos, tmp, sdt_notes, note_list) {
2253 list_del(&pos->note_list); 2255 list_del_init(&pos->note_list);
2254 free(pos->name); 2256 zfree(&pos->name);
2255 free(pos->provider); 2257 zfree(&pos->provider);
2256 free(pos); 2258 free(pos);
2257 nr_free++; 2259 nr_free++;
2258 } 2260 }
diff --git a/tools/perf/util/symbol-minimal.c b/tools/perf/util/symbol-minimal.c
index 17edbd4f6f85..3bc8b7e3300e 100644
--- a/tools/perf/util/symbol-minimal.c
+++ b/tools/perf/util/symbol-minimal.c
@@ -7,9 +7,10 @@
7#include <stdio.h> 7#include <stdio.h>
8#include <fcntl.h> 8#include <fcntl.h>
9#include <string.h> 9#include <string.h>
10#include <stdlib.h>
10#include <byteswap.h> 11#include <byteswap.h>
11#include <sys/stat.h> 12#include <sys/stat.h>
12 13#include <linux/zalloc.h>
13 14
14static bool check_need_swap(int file_endian) 15static bool check_need_swap(int file_endian)
15{ 16{
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index ae2ce255e848..173f3378aaa0 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -26,6 +26,7 @@
26#include "header.h" 26#include "header.h"
27#include "path.h" 27#include "path.h"
28#include <linux/ctype.h> 28#include <linux/ctype.h>
29#include <linux/zalloc.h>
29 30
30#include <elf.h> 31#include <elf.h>
31#include <limits.h> 32#include <limits.h>
diff --git a/tools/perf/util/syscalltbl.c b/tools/perf/util/syscalltbl.c
index c2037ac533f3..022a9c670338 100644
--- a/tools/perf/util/syscalltbl.c
+++ b/tools/perf/util/syscalltbl.c
@@ -10,9 +10,9 @@
10#include <linux/compiler.h> 10#include <linux/compiler.h>
11 11
12#ifdef HAVE_SYSCALL_TABLE_SUPPORT 12#ifdef HAVE_SYSCALL_TABLE_SUPPORT
13#include <linux/zalloc.h>
13#include <string.h> 14#include <string.h>
14#include "string2.h" 15#include "string2.h"
15#include "util.h"
16 16
17#if defined(__x86_64__) 17#if defined(__x86_64__)
18#include <asm/syscalls_64.c> 18#include <asm/syscalls_64.c>
diff --git a/tools/perf/util/target.c b/tools/perf/util/target.c
index 3852d07c49bd..3adc65480349 100644
--- a/tools/perf/util/target.c
+++ b/tools/perf/util/target.c
@@ -10,9 +10,9 @@
10#include "debug.h" 10#include "debug.h"
11 11
12#include <pwd.h> 12#include <pwd.h>
13#include <stdlib.h>
13#include <string.h> 14#include <string.h>
14 15
15
16enum target_errno target__validate(struct target *target) 16enum target_errno target__validate(struct target *target)
17{ 17{
18 enum target_errno ret = TARGET_ERRNO__SUCCESS; 18 enum target_errno ret = TARGET_ERRNO__SUCCESS;
diff --git a/tools/perf/util/thread-stack.c b/tools/perf/util/thread-stack.c
index 6ff1ff4d4ce7..15134ac9b8f1 100644
--- a/tools/perf/util/thread-stack.c
+++ b/tools/perf/util/thread-stack.c
@@ -7,12 +7,13 @@
7#include <linux/rbtree.h> 7#include <linux/rbtree.h>
8#include <linux/list.h> 8#include <linux/list.h>
9#include <linux/log2.h> 9#include <linux/log2.h>
10#include <linux/zalloc.h>
10#include <errno.h> 11#include <errno.h>
12#include <stdlib.h>
11#include "thread.h" 13#include "thread.h"
12#include "event.h" 14#include "event.h"
13#include "machine.h" 15#include "machine.h"
14#include "env.h" 16#include "env.h"
15#include "util.h"
16#include "debug.h" 17#include "debug.h"
17#include "symbol.h" 18#include "symbol.h"
18#include "comm.h" 19#include "comm.h"
diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c
index 3e29a4e8b5e6..873ab505ca80 100644
--- a/tools/perf/util/thread.c
+++ b/tools/perf/util/thread.c
@@ -5,10 +5,10 @@
5#include <stdio.h> 5#include <stdio.h>
6#include <string.h> 6#include <string.h>
7#include <linux/kernel.h> 7#include <linux/kernel.h>
8#include <linux/zalloc.h>
8#include "session.h" 9#include "session.h"
9#include "thread.h" 10#include "thread.h"
10#include "thread-stack.h" 11#include "thread-stack.h"
11#include "util.h"
12#include "debug.h" 12#include "debug.h"
13#include "namespaces.h" 13#include "namespaces.h"
14#include "comm.h" 14#include "comm.h"
@@ -93,14 +93,14 @@ void thread__delete(struct thread *thread)
93 down_write(&thread->namespaces_lock); 93 down_write(&thread->namespaces_lock);
94 list_for_each_entry_safe(namespaces, tmp_namespaces, 94 list_for_each_entry_safe(namespaces, tmp_namespaces,
95 &thread->namespaces_list, list) { 95 &thread->namespaces_list, list) {
96 list_del(&namespaces->list); 96 list_del_init(&namespaces->list);
97 namespaces__free(namespaces); 97 namespaces__free(namespaces);
98 } 98 }
99 up_write(&thread->namespaces_lock); 99 up_write(&thread->namespaces_lock);
100 100
101 down_write(&thread->comm_lock); 101 down_write(&thread->comm_lock);
102 list_for_each_entry_safe(comm, tmp_comm, &thread->comm_list, list) { 102 list_for_each_entry_safe(comm, tmp_comm, &thread->comm_list, list) {
103 list_del(&comm->list); 103 list_del_init(&comm->list);
104 comm__free(comm); 104 comm__free(comm);
105 } 105 }
106 up_write(&thread->comm_lock); 106 up_write(&thread->comm_lock);
diff --git a/tools/perf/util/thread_map.c b/tools/perf/util/thread_map.c
index 281bf06f10f2..5b3511f2b6b1 100644
--- a/tools/perf/util/thread_map.c
+++ b/tools/perf/util/thread_map.c
@@ -13,9 +13,9 @@
13#include <string.h> 13#include <string.h>
14#include <api/fs/fs.h> 14#include <api/fs/fs.h>
15#include <linux/string.h> 15#include <linux/string.h>
16#include <linux/zalloc.h>
16#include "asm/bug.h" 17#include "asm/bug.h"
17#include "thread_map.h" 18#include "thread_map.h"
18#include "util.h"
19#include "debug.h" 19#include "debug.h"
20#include "event.h" 20#include "event.h"
21 21
@@ -480,7 +480,7 @@ int thread_map__remove(struct thread_map *threads, int idx)
480 /* 480 /*
481 * Free the 'idx' item and shift the rest up. 481 * Free the 'idx' item and shift the rest up.
482 */ 482 */
483 free(threads->map[idx].comm); 483 zfree(&threads->map[idx].comm);
484 484
485 for (i = idx; i < threads->nr - 1; i++) 485 for (i = idx; i < threads->nr - 1; i++)
486 threads->map[i] = threads->map[i + 1]; 486 threads->map[i] = threads->map[i + 1];
diff --git a/tools/perf/util/trace-event-info.c b/tools/perf/util/trace-event-info.c
index 806a11b334d3..4550015b9d5d 100644
--- a/tools/perf/util/trace-event-info.c
+++ b/tools/perf/util/trace-event-info.c
@@ -18,6 +18,7 @@
18#include <stdbool.h> 18#include <stdbool.h>
19#include <linux/list.h> 19#include <linux/list.h>
20#include <linux/kernel.h> 20#include <linux/kernel.h>
21#include <linux/zalloc.h>
21 22
22#include "../perf.h" 23#include "../perf.h"
23#include "trace-event.h" 24#include "trace-event.h"
diff --git a/tools/perf/util/trace-event-scripting.c b/tools/perf/util/trace-event-scripting.c
index b023db136ef3..ba58f69777a1 100644
--- a/tools/perf/util/trace-event-scripting.c
+++ b/tools/perf/util/trace-event-scripting.c
@@ -12,8 +12,8 @@
12 12
13#include "../perf.h" 13#include "../perf.h"
14#include "debug.h" 14#include "debug.h"
15#include "util.h"
16#include "trace-event.h" 15#include "trace-event.h"
16#include <linux/zalloc.h>
17 17
18struct scripting_context *scripting_context; 18struct scripting_context *scripting_context;
19 19
diff --git a/tools/perf/util/trace-event.h b/tools/perf/util/trace-event.h
index d9b0a942090a..c7002fe11673 100644
--- a/tools/perf/util/trace-event.h
+++ b/tools/perf/util/trace-event.h
@@ -81,6 +81,9 @@ struct scripting_ops {
81 struct perf_sample *sample, 81 struct perf_sample *sample,
82 struct perf_evsel *evsel, 82 struct perf_evsel *evsel,
83 struct addr_location *al); 83 struct addr_location *al);
84 void (*process_switch)(union perf_event *event,
85 struct perf_sample *sample,
86 struct machine *machine);
84 void (*process_stat)(struct perf_stat_config *config, 87 void (*process_stat)(struct perf_stat_config *config,
85 struct perf_evsel *evsel, u64 tstamp); 88 struct perf_evsel *evsel, u64 tstamp);
86 void (*process_stat_interval)(u64 tstamp); 89 void (*process_stat_interval)(u64 tstamp);
diff --git a/tools/perf/util/unwind-libdw.c b/tools/perf/util/unwind-libdw.c
index 407d0167b942..28f71ca6ce1c 100644
--- a/tools/perf/util/unwind-libdw.c
+++ b/tools/perf/util/unwind-libdw.c
@@ -12,6 +12,7 @@
12#include "symbol.h" 12#include "symbol.h"
13#include "thread.h" 13#include "thread.h"
14#include <linux/types.h> 14#include <linux/types.h>
15#include <linux/zalloc.h>
15#include "event.h" 16#include "event.h"
16#include "perf_regs.h" 17#include "perf_regs.h"
17#include "callchain.h" 18#include "callchain.h"
diff --git a/tools/perf/util/unwind-libunwind-local.c b/tools/perf/util/unwind-libunwind-local.c
index 25e1406b1f8b..71a788921b62 100644
--- a/tools/perf/util/unwind-libunwind-local.c
+++ b/tools/perf/util/unwind-libunwind-local.c
@@ -25,6 +25,7 @@
25#include <unistd.h> 25#include <unistd.h>
26#include <sys/mman.h> 26#include <sys/mman.h>
27#include <linux/list.h> 27#include <linux/list.h>
28#include <linux/zalloc.h>
28#ifndef REMOTE_UNWIND_LIBUNWIND 29#ifndef REMOTE_UNWIND_LIBUNWIND
29#include <libunwind.h> 30#include <libunwind.h>
30#include <libunwind-ptrace.h> 31#include <libunwind-ptrace.h>
@@ -345,7 +346,7 @@ static int read_unwind_spec_debug_frame(struct dso *dso,
345 __func__, 346 __func__,
346 dso->symsrc_filename, 347 dso->symsrc_filename,
347 debuglink); 348 debuglink);
348 free(dso->symsrc_filename); 349 zfree(&dso->symsrc_filename);
349 } 350 }
350 dso->symsrc_filename = debuglink; 351 dso->symsrc_filename = debuglink;
351 } else { 352 } else {
diff --git a/tools/perf/util/usage.c b/tools/perf/util/usage.c
index 070d25ceea6a..3949a60b00ae 100644
--- a/tools/perf/util/usage.c
+++ b/tools/perf/util/usage.c
@@ -9,6 +9,9 @@
9 */ 9 */
10#include "util.h" 10#include "util.h"
11#include "debug.h" 11#include "debug.h"
12#include <stdio.h>
13#include <stdlib.h>
14#include <linux/compiler.h>
12 15
13static __noreturn void usage_builtin(const char *err) 16static __noreturn void usage_builtin(const char *err)
14{ 17{
diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h
index 125e215dd3d8..dc7a469921e9 100644
--- a/tools/perf/util/util.h
+++ b/tools/perf/util/util.h
@@ -9,8 +9,6 @@
9#include <fcntl.h> 9#include <fcntl.h>
10#include <stdbool.h> 10#include <stdbool.h>
11#include <stddef.h> 11#include <stddef.h>
12#include <stdlib.h>
13#include <stdarg.h>
14#include <linux/compiler.h> 12#include <linux/compiler.h>
15#include <sys/types.h> 13#include <sys/types.h>
16 14
@@ -18,13 +16,6 @@
18void usage(const char *err) __noreturn; 16void usage(const char *err) __noreturn;
19void die(const char *err, ...) __noreturn __printf(1, 2); 17void die(const char *err, ...) __noreturn __printf(1, 2);
20 18
21static inline void *zalloc(size_t size)
22{
23 return calloc(1, size);
24}
25
26#define zfree(ptr) ({ free(*ptr); *ptr = NULL; })
27
28struct dirent; 19struct dirent;
29struct nsinfo; 20struct nsinfo;
30struct strlist; 21struct strlist;
@@ -59,18 +50,10 @@ int fetch_kernel_version(unsigned int *puint,
59 50
60const char *perf_tip(const char *dirpath); 51const char *perf_tip(const char *dirpath);
61 52
62#ifndef HAVE_GET_CURRENT_DIR_NAME
63char *get_current_dir_name(void);
64#endif
65
66#ifndef HAVE_SCHED_GETCPU_SUPPORT 53#ifndef HAVE_SCHED_GETCPU_SUPPORT
67int sched_getcpu(void); 54int sched_getcpu(void);
68#endif 55#endif
69 56
70#ifndef HAVE_SETNS_SUPPORT
71int setns(int fd, int nstype);
72#endif
73
74extern bool perf_singlethreaded; 57extern bool perf_singlethreaded;
75 58
76void perf_set_singlethreaded(void); 59void perf_set_singlethreaded(void);
diff --git a/tools/perf/util/values.c b/tools/perf/util/values.c
index 4b7a303e4ba8..c59154e2d124 100644
--- a/tools/perf/util/values.c
+++ b/tools/perf/util/values.c
@@ -3,8 +3,8 @@
3#include <stdio.h> 3#include <stdio.h>
4#include <stdlib.h> 4#include <stdlib.h>
5#include <errno.h> 5#include <errno.h>
6#include <linux/zalloc.h>
6 7
7#include "util.h"
8#include "values.h" 8#include "values.h"
9#include "debug.h" 9#include "debug.h"
10 10
diff --git a/tools/perf/util/vdso.c b/tools/perf/util/vdso.c
index 5031b7b22bbd..7f427bab6c12 100644
--- a/tools/perf/util/vdso.c
+++ b/tools/perf/util/vdso.c
@@ -16,6 +16,7 @@
16#include "machine.h" 16#include "machine.h"
17#include "thread.h" 17#include "thread.h"
18#include "linux/string.h" 18#include "linux/string.h"
19#include <linux/zalloc.h>
19#include "debug.h" 20#include "debug.h"
20 21
21/* 22/*
diff --git a/tools/perf/util/xyarray.c b/tools/perf/util/xyarray.c
index dc95154f5646..86889ebc3514 100644
--- a/tools/perf/util/xyarray.c
+++ b/tools/perf/util/xyarray.c
@@ -1,8 +1,8 @@
1// SPDX-License-Identifier: GPL-2.0 1// SPDX-License-Identifier: GPL-2.0
2#include "xyarray.h" 2#include "xyarray.h"
3#include "util.h"
4#include <stdlib.h> 3#include <stdlib.h>
5#include <string.h> 4#include <string.h>
5#include <linux/zalloc.h>
6 6
7struct xyarray *xyarray__new(int xlen, int ylen, size_t entry_size) 7struct xyarray *xyarray__new(int xlen, int ylen, size_t entry_size)
8{ 8{
diff --git a/tools/power/cpupower/debug/kernel/Makefile b/tools/power/cpupower/debug/kernel/Makefile
index c23e5a6ceb7e..7b5c43684be1 100644
--- a/tools/power/cpupower/debug/kernel/Makefile
+++ b/tools/power/cpupower/debug/kernel/Makefile
@@ -12,8 +12,8 @@ default:
12 $(MAKE) -C $(KDIR) M=$(CURDIR) 12 $(MAKE) -C $(KDIR) M=$(CURDIR)
13 13
14clean: 14clean:
15 - rm -rf *.o *.ko .tmp-versions .*.cmd .*.mod.* *.mod.c 15 - rm -rf *.o *.ko .*.cmd .*.mod.* *.mod.c
16 - rm -rf .tmp_versions* Module.symvers modules.order 16 - rm -rf Module.symvers modules.order
17 17
18install: default 18install: default
19 install -d $(KMISC) 19 install -d $(KMISC)
diff --git a/tools/power/x86/intel-speed-select/.gitignore b/tools/power/x86/intel-speed-select/.gitignore
new file mode 100644
index 000000000000..f61145925ce9
--- /dev/null
+++ b/tools/power/x86/intel-speed-select/.gitignore
@@ -0,0 +1,2 @@
1include/
2intel-speed-select
diff --git a/tools/power/x86/intel-speed-select/Build b/tools/power/x86/intel-speed-select/Build
new file mode 100644
index 000000000000..b61456d75190
--- /dev/null
+++ b/tools/power/x86/intel-speed-select/Build
@@ -0,0 +1 @@
intel-speed-select-y += isst-config.o isst-core.o isst-display.o
diff --git a/tools/power/x86/intel-speed-select/Makefile b/tools/power/x86/intel-speed-select/Makefile
new file mode 100644
index 000000000000..12c6939dca2a
--- /dev/null
+++ b/tools/power/x86/intel-speed-select/Makefile
@@ -0,0 +1,56 @@
1# SPDX-License-Identifier: GPL-2.0
2include ../../../scripts/Makefile.include
3
4bindir ?= /usr/bin
5
6ifeq ($(srctree),)
7srctree := $(patsubst %/,%,$(dir $(CURDIR)))
8srctree := $(patsubst %/,%,$(dir $(srctree)))
9srctree := $(patsubst %/,%,$(dir $(srctree)))
10srctree := $(patsubst %/,%,$(dir $(srctree)))
11endif
12
13# Do not use make's built-in rules
14# (this improves performance and avoids hard-to-debug behaviour);
15MAKEFLAGS += -r
16
17override CFLAGS += -O2 -Wall -g -D_GNU_SOURCE -I$(OUTPUT)include
18
19ALL_TARGETS := intel-speed-select
20ALL_PROGRAMS := $(patsubst %,$(OUTPUT)%,$(ALL_TARGETS))
21
22all: $(ALL_PROGRAMS)
23
24export srctree OUTPUT CC LD CFLAGS
25include $(srctree)/tools/build/Makefile.include
26
27#
28# We need the following to be outside of kernel tree
29#
30$(OUTPUT)include/linux/isst_if.h: ../../../../include/uapi/linux/isst_if.h
31 mkdir -p $(OUTPUT)include/linux 2>&1 || true
32 ln -sf $(CURDIR)/../../../../include/uapi/linux/isst_if.h $@
33
34prepare: $(OUTPUT)include/linux/isst_if.h
35
36ISST_IN := $(OUTPUT)intel-speed-select-in.o
37
38$(ISST_IN): prepare FORCE
39 $(Q)$(MAKE) $(build)=intel-speed-select
40$(OUTPUT)intel-speed-select: $(ISST_IN)
41 $(QUIET_LINK)$(CC) $(CFLAGS) $(LDFLAGS) $< -o $@
42
43clean:
44 rm -f $(ALL_PROGRAMS)
45 rm -rf $(OUTPUT)include/linux/isst_if.h
46 find $(if $(OUTPUT),$(OUTPUT),.) -name '*.o' -delete -o -name '\.*.d' -delete
47
48install: $(ALL_PROGRAMS)
49 install -d -m 755 $(DESTDIR)$(bindir); \
50 for program in $(ALL_PROGRAMS); do \
51 install $$program $(DESTDIR)$(bindir); \
52 done
53
54FORCE:
55
56.PHONY: all install clean FORCE prepare
diff --git a/tools/power/x86/intel-speed-select/isst-config.c b/tools/power/x86/intel-speed-select/isst-config.c
new file mode 100644
index 000000000000..91c5ad1685a1
--- /dev/null
+++ b/tools/power/x86/intel-speed-select/isst-config.c
@@ -0,0 +1,1607 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Intel Speed Select -- Enumerate and control features
4 * Copyright (c) 2019 Intel Corporation.
5 */
6
7#include <linux/isst_if.h>
8
9#include "isst.h"
10
11struct process_cmd_struct {
12 char *feature;
13 char *command;
14 void (*process_fn)(void);
15};
16
17static const char *version_str = "v1.0";
18static const int supported_api_ver = 1;
19static struct isst_if_platform_info isst_platform_info;
20static char *progname;
21static int debug_flag;
22static FILE *outf;
23
24static int cpu_model;
25
26#define MAX_CPUS_IN_ONE_REQ 64
27static short max_target_cpus;
28static unsigned short target_cpus[MAX_CPUS_IN_ONE_REQ];
29
30static int topo_max_cpus;
31static size_t present_cpumask_size;
32static cpu_set_t *present_cpumask;
33static size_t target_cpumask_size;
34static cpu_set_t *target_cpumask;
35static int tdp_level = 0xFF;
36static int fact_bucket = 0xFF;
37static int fact_avx = 0xFF;
38static unsigned long long fact_trl;
39static int out_format_json;
40static int cmd_help;
41
42/* clos related */
43static int current_clos = -1;
44static int clos_epp = -1;
45static int clos_prop_prio = -1;
46static int clos_min = -1;
47static int clos_max = -1;
48static int clos_desired = -1;
49static int clos_priority_type;
50
51struct _cpu_map {
52 unsigned short core_id;
53 unsigned short pkg_id;
54 unsigned short die_id;
55 unsigned short punit_cpu;
56 unsigned short punit_cpu_core;
57};
58struct _cpu_map *cpu_map;
59
60void debug_printf(const char *format, ...)
61{
62 va_list args;
63
64 va_start(args, format);
65
66 if (debug_flag)
67 vprintf(format, args);
68
69 va_end(args);
70}
71
72static void update_cpu_model(void)
73{
74 unsigned int ebx, ecx, edx;
75 unsigned int fms, family;
76
77 __cpuid(1, fms, ebx, ecx, edx);
78 family = (fms >> 8) & 0xf;
79 cpu_model = (fms >> 4) & 0xf;
80 if (family == 6 || family == 0xf)
81 cpu_model += ((fms >> 16) & 0xf) << 4;
82}
83
84/* Open a file, and exit on failure */
85static FILE *fopen_or_exit(const char *path, const char *mode)
86{
87 FILE *filep = fopen(path, mode);
88
89 if (!filep)
90 err(1, "%s: open failed", path);
91
92 return filep;
93}
94
95/* Parse a file containing a single int */
96static int parse_int_file(int fatal, const char *fmt, ...)
97{
98 va_list args;
99 char path[PATH_MAX];
100 FILE *filep;
101 int value;
102
103 va_start(args, fmt);
104 vsnprintf(path, sizeof(path), fmt, args);
105 va_end(args);
106 if (fatal) {
107 filep = fopen_or_exit(path, "r");
108 } else {
109 filep = fopen(path, "r");
110 if (!filep)
111 return -1;
112 }
113 if (fscanf(filep, "%d", &value) != 1)
114 err(1, "%s: failed to parse number from file", path);
115 fclose(filep);
116
117 return value;
118}
119
120int cpufreq_sysfs_present(void)
121{
122 DIR *dir;
123
124 dir = opendir("/sys/devices/system/cpu/cpu0/cpufreq");
125 if (dir) {
126 closedir(dir);
127 return 1;
128 }
129
130 return 0;
131}
132
133int out_format_is_json(void)
134{
135 return out_format_json;
136}
137
138int get_physical_package_id(int cpu)
139{
140 return parse_int_file(
141 1, "/sys/devices/system/cpu/cpu%d/topology/physical_package_id",
142 cpu);
143}
144
145int get_physical_core_id(int cpu)
146{
147 return parse_int_file(
148 1, "/sys/devices/system/cpu/cpu%d/topology/core_id", cpu);
149}
150
151int get_physical_die_id(int cpu)
152{
153 int ret;
154
155 ret = parse_int_file(0, "/sys/devices/system/cpu/cpu%d/topology/die_id",
156 cpu);
157 if (ret < 0)
158 ret = 0;
159
160 return ret;
161}
162
163int get_topo_max_cpus(void)
164{
165 return topo_max_cpus;
166}
167
168#define MAX_PACKAGE_COUNT 8
169#define MAX_DIE_PER_PACKAGE 2
170static void for_each_online_package_in_set(void (*callback)(int, void *, void *,
171 void *, void *),
172 void *arg1, void *arg2, void *arg3,
173 void *arg4)
174{
175 int max_packages[MAX_PACKAGE_COUNT * MAX_PACKAGE_COUNT];
176 int pkg_index = 0, i;
177
178 memset(max_packages, 0xff, sizeof(max_packages));
179 for (i = 0; i < topo_max_cpus; ++i) {
180 int j, online, pkg_id, die_id = 0, skip = 0;
181
182 if (!CPU_ISSET_S(i, present_cpumask_size, present_cpumask))
183 continue;
184 if (i)
185 online = parse_int_file(
186 1, "/sys/devices/system/cpu/cpu%d/online", i);
187 else
188 online =
189 1; /* online entry for CPU 0 needs some special configs */
190
191 die_id = get_physical_die_id(i);
192 if (die_id < 0)
193 die_id = 0;
194 pkg_id = get_physical_package_id(i);
195 /* Create an unique id for package, die combination to store */
196 pkg_id = (MAX_PACKAGE_COUNT * pkg_id + die_id);
197
198 for (j = 0; j < pkg_index; ++j) {
199 if (max_packages[j] == pkg_id) {
200 skip = 1;
201 break;
202 }
203 }
204
205 if (!skip && online && callback) {
206 callback(i, arg1, arg2, arg3, arg4);
207 max_packages[pkg_index++] = pkg_id;
208 }
209 }
210}
211
212static void for_each_online_target_cpu_in_set(
213 void (*callback)(int, void *, void *, void *, void *), void *arg1,
214 void *arg2, void *arg3, void *arg4)
215{
216 int i;
217
218 for (i = 0; i < topo_max_cpus; ++i) {
219 int online;
220
221 if (!CPU_ISSET_S(i, target_cpumask_size, target_cpumask))
222 continue;
223 if (i)
224 online = parse_int_file(
225 1, "/sys/devices/system/cpu/cpu%d/online", i);
226 else
227 online =
228 1; /* online entry for CPU 0 needs some special configs */
229
230 if (online && callback)
231 callback(i, arg1, arg2, arg3, arg4);
232 }
233}
234
235#define BITMASK_SIZE 32
236static void set_max_cpu_num(void)
237{
238 FILE *filep;
239 unsigned long dummy;
240
241 topo_max_cpus = 0;
242 filep = fopen_or_exit(
243 "/sys/devices/system/cpu/cpu0/topology/thread_siblings", "r");
244 while (fscanf(filep, "%lx,", &dummy) == 1)
245 topo_max_cpus += BITMASK_SIZE;
246 fclose(filep);
247 topo_max_cpus--; /* 0 based */
248
249 debug_printf("max cpus %d\n", topo_max_cpus);
250}
251
252size_t alloc_cpu_set(cpu_set_t **cpu_set)
253{
254 cpu_set_t *_cpu_set;
255 size_t size;
256
257 _cpu_set = CPU_ALLOC((topo_max_cpus + 1));
258 if (_cpu_set == NULL)
259 err(3, "CPU_ALLOC");
260 size = CPU_ALLOC_SIZE((topo_max_cpus + 1));
261 CPU_ZERO_S(size, _cpu_set);
262
263 *cpu_set = _cpu_set;
264 return size;
265}
266
267void free_cpu_set(cpu_set_t *cpu_set)
268{
269 CPU_FREE(cpu_set);
270}
271
272static int cpu_cnt[MAX_PACKAGE_COUNT][MAX_DIE_PER_PACKAGE];
273static void set_cpu_present_cpu_mask(void)
274{
275 size_t size;
276 DIR *dir;
277 int i;
278
279 size = alloc_cpu_set(&present_cpumask);
280 present_cpumask_size = size;
281 for (i = 0; i < topo_max_cpus; ++i) {
282 char buffer[256];
283
284 snprintf(buffer, sizeof(buffer),
285 "/sys/devices/system/cpu/cpu%d", i);
286 dir = opendir(buffer);
287 if (dir) {
288 int pkg_id, die_id;
289
290 CPU_SET_S(i, size, present_cpumask);
291 die_id = get_physical_die_id(i);
292 if (die_id < 0)
293 die_id = 0;
294
295 pkg_id = get_physical_package_id(i);
296 if (pkg_id < MAX_PACKAGE_COUNT &&
297 die_id < MAX_DIE_PER_PACKAGE)
298 cpu_cnt[pkg_id][die_id]++;
299 }
300 closedir(dir);
301 }
302}
303
304int get_cpu_count(int pkg_id, int die_id)
305{
306 if (pkg_id < MAX_PACKAGE_COUNT && die_id < MAX_DIE_PER_PACKAGE)
307 return cpu_cnt[pkg_id][die_id] + 1;
308
309 return 0;
310}
311
312static void set_cpu_target_cpu_mask(void)
313{
314 size_t size;
315 int i;
316
317 size = alloc_cpu_set(&target_cpumask);
318 target_cpumask_size = size;
319 for (i = 0; i < max_target_cpus; ++i) {
320 if (!CPU_ISSET_S(target_cpus[i], present_cpumask_size,
321 present_cpumask))
322 continue;
323
324 CPU_SET_S(target_cpus[i], size, target_cpumask);
325 }
326}
327
328static void create_cpu_map(void)
329{
330 const char *pathname = "/dev/isst_interface";
331 int i, fd = 0;
332 struct isst_if_cpu_maps map;
333
334 cpu_map = malloc(sizeof(*cpu_map) * topo_max_cpus);
335 if (!cpu_map)
336 err(3, "cpumap");
337
338 fd = open(pathname, O_RDWR);
339 if (fd < 0)
340 err(-1, "%s open failed", pathname);
341
342 for (i = 0; i < topo_max_cpus; ++i) {
343 if (!CPU_ISSET_S(i, present_cpumask_size, present_cpumask))
344 continue;
345
346 map.cmd_count = 1;
347 map.cpu_map[0].logical_cpu = i;
348
349 debug_printf(" map logical_cpu:%d\n",
350 map.cpu_map[0].logical_cpu);
351 if (ioctl(fd, ISST_IF_GET_PHY_ID, &map) == -1) {
352 perror("ISST_IF_GET_PHY_ID");
353 fprintf(outf, "Error: map logical_cpu:%d\n",
354 map.cpu_map[0].logical_cpu);
355 continue;
356 }
357 cpu_map[i].core_id = get_physical_core_id(i);
358 cpu_map[i].pkg_id = get_physical_package_id(i);
359 cpu_map[i].die_id = get_physical_die_id(i);
360 cpu_map[i].punit_cpu = map.cpu_map[0].physical_cpu;
361 cpu_map[i].punit_cpu_core = (map.cpu_map[0].physical_cpu >>
362 1); // shift to get core id
363
364 debug_printf(
365 "map logical_cpu:%d core: %d die:%d pkg:%d punit_cpu:%d punit_core:%d\n",
366 i, cpu_map[i].core_id, cpu_map[i].die_id,
367 cpu_map[i].pkg_id, cpu_map[i].punit_cpu,
368 cpu_map[i].punit_cpu_core);
369 }
370
371 if (fd)
372 close(fd);
373}
374
375int find_logical_cpu(int pkg_id, int die_id, int punit_core_id)
376{
377 int i;
378
379 for (i = 0; i < topo_max_cpus; ++i) {
380 if (cpu_map[i].pkg_id == pkg_id &&
381 cpu_map[i].die_id == die_id &&
382 cpu_map[i].punit_cpu_core == punit_core_id)
383 return i;
384 }
385
386 return -EINVAL;
387}
388
389void set_cpu_mask_from_punit_coremask(int cpu, unsigned long long core_mask,
390 size_t core_cpumask_size,
391 cpu_set_t *core_cpumask, int *cpu_cnt)
392{
393 int i, cnt = 0;
394 int die_id, pkg_id;
395
396 *cpu_cnt = 0;
397 die_id = get_physical_die_id(cpu);
398 pkg_id = get_physical_package_id(cpu);
399
400 for (i = 0; i < 64; ++i) {
401 if (core_mask & BIT(i)) {
402 int j;
403
404 for (j = 0; j < topo_max_cpus; ++j) {
405 if (cpu_map[j].pkg_id == pkg_id &&
406 cpu_map[j].die_id == die_id &&
407 cpu_map[j].punit_cpu_core == i) {
408 CPU_SET_S(j, core_cpumask_size,
409 core_cpumask);
410 ++cnt;
411 }
412 }
413 }
414 }
415
416 *cpu_cnt = cnt;
417}
418
419int find_phy_core_num(int logical_cpu)
420{
421 if (logical_cpu < topo_max_cpus)
422 return cpu_map[logical_cpu].punit_cpu_core;
423
424 return -EINVAL;
425}
426
427static int isst_send_mmio_command(unsigned int cpu, unsigned int reg, int write,
428 unsigned int *value)
429{
430 struct isst_if_io_regs io_regs;
431 const char *pathname = "/dev/isst_interface";
432 int cmd;
433 int fd;
434
435 debug_printf("mmio_cmd cpu:%d reg:%d write:%d\n", cpu, reg, write);
436
437 fd = open(pathname, O_RDWR);
438 if (fd < 0)
439 err(-1, "%s open failed", pathname);
440
441 io_regs.req_count = 1;
442 io_regs.io_reg[0].logical_cpu = cpu;
443 io_regs.io_reg[0].reg = reg;
444 cmd = ISST_IF_IO_CMD;
445 if (write) {
446 io_regs.io_reg[0].read_write = 1;
447 io_regs.io_reg[0].value = *value;
448 } else {
449 io_regs.io_reg[0].read_write = 0;
450 }
451
452 if (ioctl(fd, cmd, &io_regs) == -1) {
453 perror("ISST_IF_IO_CMD");
454 fprintf(outf, "Error: mmio_cmd cpu:%d reg:%x read_write:%x\n",
455 cpu, reg, write);
456 } else {
457 if (!write)
458 *value = io_regs.io_reg[0].value;
459
460 debug_printf(
461 "mmio_cmd response: cpu:%d reg:%x rd_write:%x resp:%x\n",
462 cpu, reg, write, *value);
463 }
464
465 close(fd);
466
467 return 0;
468}
469
470int isst_send_mbox_command(unsigned int cpu, unsigned char command,
471 unsigned char sub_command, unsigned int parameter,
472 unsigned int req_data, unsigned int *resp)
473{
474 const char *pathname = "/dev/isst_interface";
475 int fd;
476 struct isst_if_mbox_cmds mbox_cmds = { 0 };
477
478 debug_printf(
479 "mbox_send: cpu:%d command:%x sub_command:%x parameter:%x req_data:%x\n",
480 cpu, command, sub_command, parameter, req_data);
481
482 if (isst_platform_info.mmio_supported && command == CONFIG_CLOS) {
483 unsigned int value;
484 int write = 0;
485 int clos_id, core_id, ret = 0;
486
487 debug_printf("CLOS %d\n", cpu);
488
489 if (parameter & BIT(MBOX_CMD_WRITE_BIT)) {
490 value = req_data;
491 write = 1;
492 }
493
494 switch (sub_command) {
495 case CLOS_PQR_ASSOC:
496 core_id = parameter & 0xff;
497 ret = isst_send_mmio_command(
498 cpu, PQR_ASSOC_OFFSET + core_id * 4, write,
499 &value);
500 if (!ret && !write)
501 *resp = value;
502 break;
503 case CLOS_PM_CLOS:
504 clos_id = parameter & 0x03;
505 ret = isst_send_mmio_command(
506 cpu, PM_CLOS_OFFSET + clos_id * 4, write,
507 &value);
508 if (!ret && !write)
509 *resp = value;
510 break;
511 case CLOS_PM_QOS_CONFIG:
512 ret = isst_send_mmio_command(cpu, PM_QOS_CONFIG_OFFSET,
513 write, &value);
514 if (!ret && !write)
515 *resp = value;
516 break;
517 case CLOS_STATUS:
518 break;
519 default:
520 break;
521 }
522 return ret;
523 }
524
525 mbox_cmds.cmd_count = 1;
526 mbox_cmds.mbox_cmd[0].logical_cpu = cpu;
527 mbox_cmds.mbox_cmd[0].command = command;
528 mbox_cmds.mbox_cmd[0].sub_command = sub_command;
529 mbox_cmds.mbox_cmd[0].parameter = parameter;
530 mbox_cmds.mbox_cmd[0].req_data = req_data;
531
532 fd = open(pathname, O_RDWR);
533 if (fd < 0)
534 err(-1, "%s open failed", pathname);
535
536 if (ioctl(fd, ISST_IF_MBOX_COMMAND, &mbox_cmds) == -1) {
537 perror("ISST_IF_MBOX_COMMAND");
538 fprintf(outf,
539 "Error: mbox_cmd cpu:%d command:%x sub_command:%x parameter:%x req_data:%x\n",
540 cpu, command, sub_command, parameter, req_data);
541 } else {
542 *resp = mbox_cmds.mbox_cmd[0].resp_data;
543 debug_printf(
544 "mbox_cmd response: cpu:%d command:%x sub_command:%x parameter:%x req_data:%x resp:%x\n",
545 cpu, command, sub_command, parameter, req_data, *resp);
546 }
547
548 close(fd);
549
550 return 0;
551}
552
553int isst_send_msr_command(unsigned int cpu, unsigned int msr, int write,
554 unsigned long long *req_resp)
555{
556 struct isst_if_msr_cmds msr_cmds;
557 const char *pathname = "/dev/isst_interface";
558 int fd;
559
560 fd = open(pathname, O_RDWR);
561 if (fd < 0)
562 err(-1, "%s open failed", pathname);
563
564 msr_cmds.cmd_count = 1;
565 msr_cmds.msr_cmd[0].logical_cpu = cpu;
566 msr_cmds.msr_cmd[0].msr = msr;
567 msr_cmds.msr_cmd[0].read_write = write;
568 if (write)
569 msr_cmds.msr_cmd[0].data = *req_resp;
570
571 if (ioctl(fd, ISST_IF_MSR_COMMAND, &msr_cmds) == -1) {
572 perror("ISST_IF_MSR_COMMAD");
573 fprintf(outf, "Error: msr_cmd cpu:%d msr:%x read_write:%d\n",
574 cpu, msr, write);
575 } else {
576 if (!write)
577 *req_resp = msr_cmds.msr_cmd[0].data;
578
579 debug_printf(
580 "msr_cmd response: cpu:%d msr:%x rd_write:%x resp:%llx %llx\n",
581 cpu, msr, write, *req_resp, msr_cmds.msr_cmd[0].data);
582 }
583
584 close(fd);
585
586 return 0;
587}
588
589static int isst_fill_platform_info(void)
590{
591 const char *pathname = "/dev/isst_interface";
592 int fd;
593
594 fd = open(pathname, O_RDWR);
595 if (fd < 0)
596 err(-1, "%s open failed", pathname);
597
598 if (ioctl(fd, ISST_IF_GET_PLATFORM_INFO, &isst_platform_info) == -1) {
599 perror("ISST_IF_GET_PLATFORM_INFO");
600 close(fd);
601 return -1;
602 }
603
604 close(fd);
605
606 return 0;
607}
608
609static void isst_print_platform_information(void)
610{
611 struct isst_if_platform_info platform_info;
612 const char *pathname = "/dev/isst_interface";
613 int fd;
614
615 fd = open(pathname, O_RDWR);
616 if (fd < 0)
617 err(-1, "%s open failed", pathname);
618
619 if (ioctl(fd, ISST_IF_GET_PLATFORM_INFO, &platform_info) == -1) {
620 perror("ISST_IF_GET_PLATFORM_INFO");
621 } else {
622 fprintf(outf, "Platform: API version : %d\n",
623 platform_info.api_version);
624 fprintf(outf, "Platform: Driver version : %d\n",
625 platform_info.driver_version);
626 fprintf(outf, "Platform: mbox supported : %d\n",
627 platform_info.mbox_supported);
628 fprintf(outf, "Platform: mmio supported : %d\n",
629 platform_info.mmio_supported);
630 }
631
632 close(fd);
633
634 exit(0);
635}
636
637static void exec_on_get_ctdp_cpu(int cpu, void *arg1, void *arg2, void *arg3,
638 void *arg4)
639{
640 int (*fn_ptr)(int cpu, void *arg);
641 int ret;
642
643 fn_ptr = arg1;
644 ret = fn_ptr(cpu, arg2);
645 if (ret)
646 perror("get_tdp_*");
647 else
648 isst_display_result(cpu, outf, "perf-profile", (char *)arg3,
649 *(unsigned int *)arg4);
650}
651
652#define _get_tdp_level(desc, suffix, object, help) \
653 static void get_tdp_##object(void) \
654 { \
655 struct isst_pkg_ctdp ctdp; \
656\
657 if (cmd_help) { \
658 fprintf(stderr, \
659 "Print %s [No command arguments are required]\n", \
660 help); \
661 exit(0); \
662 } \
663 isst_ctdp_display_information_start(outf); \
664 if (max_target_cpus) \
665 for_each_online_target_cpu_in_set( \
666 exec_on_get_ctdp_cpu, isst_get_ctdp_##suffix, \
667 &ctdp, desc, &ctdp.object); \
668 else \
669 for_each_online_package_in_set(exec_on_get_ctdp_cpu, \
670 isst_get_ctdp_##suffix, \
671 &ctdp, desc, \
672 &ctdp.object); \
673 isst_ctdp_display_information_end(outf); \
674 }
675
676_get_tdp_level("get-config-levels", levels, levels, "TDP levels");
677_get_tdp_level("get-config-version", levels, version, "TDP version");
678_get_tdp_level("get-config-enabled", levels, enabled, "TDP enable status");
679_get_tdp_level("get-config-current_level", levels, current_level,
680 "Current TDP Level");
681_get_tdp_level("get-lock-status", levels, locked, "TDP lock status");
682
683static void dump_isst_config_for_cpu(int cpu, void *arg1, void *arg2,
684 void *arg3, void *arg4)
685{
686 struct isst_pkg_ctdp pkg_dev;
687 int ret;
688
689 memset(&pkg_dev, 0, sizeof(pkg_dev));
690 ret = isst_get_process_ctdp(cpu, tdp_level, &pkg_dev);
691 if (ret) {
692 perror("isst_get_process_ctdp");
693 } else {
694 isst_ctdp_display_information(cpu, outf, tdp_level, &pkg_dev);
695 isst_get_process_ctdp_complete(cpu, &pkg_dev);
696 }
697}
698
699static void dump_isst_config(void)
700{
701 if (cmd_help) {
702 fprintf(stderr,
703 "Print Intel(R) Speed Select Technology Performance profile configuration\n");
704 fprintf(stderr,
705 "including base frequency and turbo frequency configurations\n");
706 fprintf(stderr, "Optional: -l|--level : Specify tdp level\n");
707 fprintf(stderr,
708 "\tIf no arguments, dump information for all TDP levels\n");
709 exit(0);
710 }
711
712 isst_ctdp_display_information_start(outf);
713
714 if (max_target_cpus)
715 for_each_online_target_cpu_in_set(dump_isst_config_for_cpu,
716 NULL, NULL, NULL, NULL);
717 else
718 for_each_online_package_in_set(dump_isst_config_for_cpu, NULL,
719 NULL, NULL, NULL);
720
721 isst_ctdp_display_information_end(outf);
722}
723
724static void set_tdp_level_for_cpu(int cpu, void *arg1, void *arg2, void *arg3,
725 void *arg4)
726{
727 int ret;
728
729 ret = isst_set_tdp_level(cpu, tdp_level);
730 if (ret)
731 perror("set_tdp_level_for_cpu");
732 else
733 isst_display_result(cpu, outf, "perf-profile", "set_tdp_level",
734 ret);
735}
736
737static void set_tdp_level(void)
738{
739 if (cmd_help) {
740 fprintf(stderr, "Set Config TDP level\n");
741 fprintf(stderr,
742 "\t Arguments: -l|--level : Specify tdp level\n");
743 exit(0);
744 }
745
746 if (tdp_level == 0xff) {
747 fprintf(outf, "Invalid command: specify tdp_level\n");
748 exit(1);
749 }
750 isst_ctdp_display_information_start(outf);
751 if (max_target_cpus)
752 for_each_online_target_cpu_in_set(set_tdp_level_for_cpu, NULL,
753 NULL, NULL, NULL);
754 else
755 for_each_online_package_in_set(set_tdp_level_for_cpu, NULL,
756 NULL, NULL, NULL);
757 isst_ctdp_display_information_end(outf);
758}
759
760static void dump_pbf_config_for_cpu(int cpu, void *arg1, void *arg2, void *arg3,
761 void *arg4)
762{
763 struct isst_pbf_info pbf_info;
764 int ret;
765
766 ret = isst_get_pbf_info(cpu, tdp_level, &pbf_info);
767 if (ret) {
768 perror("isst_get_pbf_info");
769 } else {
770 isst_pbf_display_information(cpu, outf, tdp_level, &pbf_info);
771 isst_get_pbf_info_complete(&pbf_info);
772 }
773}
774
775static void dump_pbf_config(void)
776{
777 if (cmd_help) {
778 fprintf(stderr,
779 "Print Intel(R) Speed Select Technology base frequency configuration for a TDP level\n");
780 fprintf(stderr,
781 "\tArguments: -l|--level : Specify tdp level\n");
782 exit(0);
783 }
784
785 if (tdp_level == 0xff) {
786 fprintf(outf, "Invalid command: specify tdp_level\n");
787 exit(1);
788 }
789
790 isst_ctdp_display_information_start(outf);
791 if (max_target_cpus)
792 for_each_online_target_cpu_in_set(dump_pbf_config_for_cpu, NULL,
793 NULL, NULL, NULL);
794 else
795 for_each_online_package_in_set(dump_pbf_config_for_cpu, NULL,
796 NULL, NULL, NULL);
797 isst_ctdp_display_information_end(outf);
798}
799
800static void set_pbf_for_cpu(int cpu, void *arg1, void *arg2, void *arg3,
801 void *arg4)
802{
803 int ret;
804 int status = *(int *)arg4;
805
806 ret = isst_set_pbf_fact_status(cpu, 1, status);
807 if (ret) {
808 perror("isst_set_pbf");
809 } else {
810 if (status)
811 isst_display_result(cpu, outf, "base-freq", "enable",
812 ret);
813 else
814 isst_display_result(cpu, outf, "base-freq", "disable",
815 ret);
816 }
817}
818
819static void set_pbf_enable(void)
820{
821 int status = 1;
822
823 if (cmd_help) {
824 fprintf(stderr,
825 "Enable Intel Speed Select Technology base frequency feature [No command arguments are required]\n");
826 exit(0);
827 }
828
829 isst_ctdp_display_information_start(outf);
830 if (max_target_cpus)
831 for_each_online_target_cpu_in_set(set_pbf_for_cpu, NULL, NULL,
832 NULL, &status);
833 else
834 for_each_online_package_in_set(set_pbf_for_cpu, NULL, NULL,
835 NULL, &status);
836 isst_ctdp_display_information_end(outf);
837}
838
839static void set_pbf_disable(void)
840{
841 int status = 0;
842
843 if (cmd_help) {
844 fprintf(stderr,
845 "Disable Intel Speed Select Technology base frequency feature [No command arguments are required]\n");
846 exit(0);
847 }
848
849 isst_ctdp_display_information_start(outf);
850 if (max_target_cpus)
851 for_each_online_target_cpu_in_set(set_pbf_for_cpu, NULL, NULL,
852 NULL, &status);
853 else
854 for_each_online_package_in_set(set_pbf_for_cpu, NULL, NULL,
855 NULL, &status);
856 isst_ctdp_display_information_end(outf);
857}
858
859static void dump_fact_config_for_cpu(int cpu, void *arg1, void *arg2,
860 void *arg3, void *arg4)
861{
862 struct isst_fact_info fact_info;
863 int ret;
864
865 ret = isst_get_fact_info(cpu, tdp_level, &fact_info);
866 if (ret)
867 perror("isst_get_fact_bucket_info");
868 else
869 isst_fact_display_information(cpu, outf, tdp_level, fact_bucket,
870 fact_avx, &fact_info);
871}
872
873static void dump_fact_config(void)
874{
875 if (cmd_help) {
876 fprintf(stderr,
877 "Print complete Intel Speed Select Technology turbo frequency configuration for a TDP level. Other arguments are optional.\n");
878 fprintf(stderr,
879 "\tArguments: -l|--level : Specify tdp level\n");
880 fprintf(stderr,
881 "\tArguments: -b|--bucket : Bucket index to dump\n");
882 fprintf(stderr,
883 "\tArguments: -r|--trl-type : Specify trl type: sse|avx2|avx512\n");
884 exit(0);
885 }
886
887 if (tdp_level == 0xff) {
888 fprintf(outf, "Invalid command: specify tdp_level\n");
889 exit(1);
890 }
891
892 isst_ctdp_display_information_start(outf);
893 if (max_target_cpus)
894 for_each_online_target_cpu_in_set(dump_fact_config_for_cpu,
895 NULL, NULL, NULL, NULL);
896 else
897 for_each_online_package_in_set(dump_fact_config_for_cpu, NULL,
898 NULL, NULL, NULL);
899 isst_ctdp_display_information_end(outf);
900}
901
902static void set_fact_for_cpu(int cpu, void *arg1, void *arg2, void *arg3,
903 void *arg4)
904{
905 int ret;
906 int status = *(int *)arg4;
907
908 ret = isst_set_pbf_fact_status(cpu, 0, status);
909 if (ret)
910 perror("isst_set_fact");
911 else {
912 if (status) {
913 struct isst_pkg_ctdp pkg_dev;
914
915 ret = isst_get_ctdp_levels(cpu, &pkg_dev);
916 if (ret) {
917 isst_display_result(cpu, outf, "turbo-freq",
918 "enable", ret);
919 return;
920 }
921 ret = isst_set_trl(cpu, fact_trl);
922 isst_display_result(cpu, outf, "turbo-freq", "enable",
923 ret);
924 } else {
925 /* Since we modified TRL during Fact enable, restore it */
926 isst_set_trl_from_current_tdp(cpu, fact_trl);
927 isst_display_result(cpu, outf, "turbo-freq", "disable",
928 ret);
929 }
930 }
931}
932
933static void set_fact_enable(void)
934{
935 int status = 1;
936
937 if (cmd_help) {
938 fprintf(stderr,
939 "Enable Intel Speed Select Technology Turbo frequency feature\n");
940 fprintf(stderr,
941 "Optional: -t|--trl : Specify turbo ratio limit\n");
942 exit(0);
943 }
944
945 isst_ctdp_display_information_start(outf);
946 if (max_target_cpus)
947 for_each_online_target_cpu_in_set(set_fact_for_cpu, NULL, NULL,
948 NULL, &status);
949 else
950 for_each_online_package_in_set(set_fact_for_cpu, NULL, NULL,
951 NULL, &status);
952 isst_ctdp_display_information_end(outf);
953}
954
955static void set_fact_disable(void)
956{
957 int status = 0;
958
959 if (cmd_help) {
960 fprintf(stderr,
961 "Disable Intel Speed Select Technology turbo frequency feature\n");
962 fprintf(stderr,
963 "Optional: -t|--trl : Specify turbo ratio limit\n");
964 exit(0);
965 }
966
967 isst_ctdp_display_information_start(outf);
968 if (max_target_cpus)
969 for_each_online_target_cpu_in_set(set_fact_for_cpu, NULL, NULL,
970 NULL, &status);
971 else
972 for_each_online_package_in_set(set_fact_for_cpu, NULL, NULL,
973 NULL, &status);
974 isst_ctdp_display_information_end(outf);
975}
976
977static void enable_clos_qos_config(int cpu, void *arg1, void *arg2, void *arg3,
978 void *arg4)
979{
980 int ret;
981 int status = *(int *)arg4;
982
983 ret = isst_pm_qos_config(cpu, status, clos_priority_type);
984 if (ret) {
985 perror("isst_pm_qos_config");
986 } else {
987 if (status)
988 isst_display_result(cpu, outf, "core-power", "enable",
989 ret);
990 else
991 isst_display_result(cpu, outf, "core-power", "disable",
992 ret);
993 }
994}
995
996static void set_clos_enable(void)
997{
998 int status = 1;
999
1000 if (cmd_help) {
1001 fprintf(stderr, "Enable core-power for a package/die\n");
1002 fprintf(stderr,
1003 "\tClos Enable: Specify priority type with [--priority|-p]\n");
1004 fprintf(stderr, "\t\t 0: Proportional, 1: Ordered\n");
1005 exit(0);
1006 }
1007
1008 if (cpufreq_sysfs_present()) {
1009 fprintf(stderr,
1010 "cpufreq subsystem and core-power enable will interfere with each other!\n");
1011 }
1012
1013 isst_ctdp_display_information_start(outf);
1014 if (max_target_cpus)
1015 for_each_online_target_cpu_in_set(enable_clos_qos_config, NULL,
1016 NULL, NULL, &status);
1017 else
1018 for_each_online_package_in_set(enable_clos_qos_config, NULL,
1019 NULL, NULL, &status);
1020 isst_ctdp_display_information_end(outf);
1021}
1022
1023static void set_clos_disable(void)
1024{
1025 int status = 0;
1026
1027 if (cmd_help) {
1028 fprintf(stderr,
1029 "Disable core-power: [No command arguments are required]\n");
1030 exit(0);
1031 }
1032
1033 isst_ctdp_display_information_start(outf);
1034 if (max_target_cpus)
1035 for_each_online_target_cpu_in_set(enable_clos_qos_config, NULL,
1036 NULL, NULL, &status);
1037 else
1038 for_each_online_package_in_set(enable_clos_qos_config, NULL,
1039 NULL, NULL, &status);
1040 isst_ctdp_display_information_end(outf);
1041}
1042
1043static void dump_clos_config_for_cpu(int cpu, void *arg1, void *arg2,
1044 void *arg3, void *arg4)
1045{
1046 struct isst_clos_config clos_config;
1047 int ret;
1048
1049 ret = isst_pm_get_clos(cpu, current_clos, &clos_config);
1050 if (ret)
1051 perror("isst_pm_get_clos");
1052 else
1053 isst_clos_display_information(cpu, outf, current_clos,
1054 &clos_config);
1055}
1056
1057static void dump_clos_config(void)
1058{
1059 if (cmd_help) {
1060 fprintf(stderr,
1061 "Print Intel Speed Select Technology core power configuration\n");
1062 fprintf(stderr,
1063 "\tArguments: [-c | --clos]: Specify clos id\n");
1064 exit(0);
1065 }
1066 if (current_clos < 0 || current_clos > 3) {
1067 fprintf(stderr, "Invalid clos id\n");
1068 exit(0);
1069 }
1070
1071 isst_ctdp_display_information_start(outf);
1072 if (max_target_cpus)
1073 for_each_online_target_cpu_in_set(dump_clos_config_for_cpu,
1074 NULL, NULL, NULL, NULL);
1075 else
1076 for_each_online_package_in_set(dump_clos_config_for_cpu, NULL,
1077 NULL, NULL, NULL);
1078 isst_ctdp_display_information_end(outf);
1079}
1080
1081static void set_clos_config_for_cpu(int cpu, void *arg1, void *arg2, void *arg3,
1082 void *arg4)
1083{
1084 struct isst_clos_config clos_config;
1085 int ret;
1086
1087 clos_config.pkg_id = get_physical_package_id(cpu);
1088 clos_config.die_id = get_physical_die_id(cpu);
1089
1090 clos_config.epp = clos_epp;
1091 clos_config.clos_prop_prio = clos_prop_prio;
1092 clos_config.clos_min = clos_min;
1093 clos_config.clos_max = clos_max;
1094 clos_config.clos_desired = clos_desired;
1095 ret = isst_set_clos(cpu, current_clos, &clos_config);
1096 if (ret)
1097 perror("isst_set_clos");
1098 else
1099 isst_display_result(cpu, outf, "core-power", "config", ret);
1100}
1101
1102static void set_clos_config(void)
1103{
1104 if (cmd_help) {
1105 fprintf(stderr,
1106 "Set core-power configuration for one of the four clos ids\n");
1107 fprintf(stderr,
1108 "\tSpecify targeted clos id with [--clos|-c]\n");
1109 fprintf(stderr, "\tSpecify clos EPP with [--epp|-e]\n");
1110 fprintf(stderr,
1111 "\tSpecify clos Proportional Priority [--weight|-w]\n");
1112 fprintf(stderr, "\tSpecify clos min with [--min|-n]\n");
1113 fprintf(stderr, "\tSpecify clos max with [--max|-m]\n");
1114 fprintf(stderr, "\tSpecify clos desired with [--desired|-d]\n");
1115 exit(0);
1116 }
1117
1118 if (current_clos < 0 || current_clos > 3) {
1119 fprintf(stderr, "Invalid clos id\n");
1120 exit(0);
1121 }
1122 if (clos_epp < 0 || clos_epp > 0x0F) {
1123 fprintf(stderr, "clos epp is not specified, default: 0\n");
1124 clos_epp = 0;
1125 }
1126 if (clos_prop_prio < 0 || clos_prop_prio > 0x0F) {
1127 fprintf(stderr,
1128 "clos frequency weight is not specified, default: 0\n");
1129 clos_prop_prio = 0;
1130 }
1131 if (clos_min < 0) {
1132 fprintf(stderr, "clos min is not specified, default: 0\n");
1133 clos_min = 0;
1134 }
1135 if (clos_max < 0) {
1136 fprintf(stderr, "clos max is not specified, default: 0xff\n");
1137 clos_max = 0xff;
1138 }
1139 if (clos_desired < 0) {
1140 fprintf(stderr, "clos desired is not specified, default: 0\n");
1141 clos_desired = 0x00;
1142 }
1143
1144 isst_ctdp_display_information_start(outf);
1145 if (max_target_cpus)
1146 for_each_online_target_cpu_in_set(set_clos_config_for_cpu, NULL,
1147 NULL, NULL, NULL);
1148 else
1149 for_each_online_package_in_set(set_clos_config_for_cpu, NULL,
1150 NULL, NULL, NULL);
1151 isst_ctdp_display_information_end(outf);
1152}
1153
1154static void set_clos_assoc_for_cpu(int cpu, void *arg1, void *arg2, void *arg3,
1155 void *arg4)
1156{
1157 int ret;
1158
1159 ret = isst_clos_associate(cpu, current_clos);
1160 if (ret)
1161 perror("isst_clos_associate");
1162 else
1163 isst_display_result(cpu, outf, "core-power", "assoc", ret);
1164}
1165
1166static void set_clos_assoc(void)
1167{
1168 if (cmd_help) {
1169 fprintf(stderr, "Associate a clos id to a CPU\n");
1170 fprintf(stderr,
1171 "\tSpecify targeted clos id with [--clos|-c]\n");
1172 exit(0);
1173 }
1174
1175 if (current_clos < 0 || current_clos > 3) {
1176 fprintf(stderr, "Invalid clos id\n");
1177 exit(0);
1178 }
1179 if (max_target_cpus)
1180 for_each_online_target_cpu_in_set(set_clos_assoc_for_cpu, NULL,
1181 NULL, NULL, NULL);
1182 else {
1183 fprintf(stderr,
1184 "Invalid target cpu. Specify with [-c|--cpu]\n");
1185 }
1186}
1187
1188static void get_clos_assoc_for_cpu(int cpu, void *arg1, void *arg2, void *arg3,
1189 void *arg4)
1190{
1191 int clos, ret;
1192
1193 ret = isst_clos_get_assoc_status(cpu, &clos);
1194 if (ret)
1195 perror("isst_clos_get_assoc_status");
1196 else
1197 isst_display_result(cpu, outf, "core-power", "get-assoc", clos);
1198}
1199
1200static void get_clos_assoc(void)
1201{
1202 if (cmd_help) {
1203 fprintf(stderr, "Get associate clos id to a CPU\n");
1204 fprintf(stderr, "\tSpecify targeted cpu id with [--cpu|-c]\n");
1205 exit(0);
1206 }
1207 if (max_target_cpus)
1208 for_each_online_target_cpu_in_set(get_clos_assoc_for_cpu, NULL,
1209 NULL, NULL, NULL);
1210 else {
1211 fprintf(stderr,
1212 "Invalid target cpu. Specify with [-c|--cpu]\n");
1213 }
1214}
1215
1216static struct process_cmd_struct isst_cmds[] = {
1217 { "perf-profile", "get-lock-status", get_tdp_locked },
1218 { "perf-profile", "get-config-levels", get_tdp_levels },
1219 { "perf-profile", "get-config-version", get_tdp_version },
1220 { "perf-profile", "get-config-enabled", get_tdp_enabled },
1221 { "perf-profile", "get-config-current-level", get_tdp_current_level },
1222 { "perf-profile", "set-config-level", set_tdp_level },
1223 { "perf-profile", "info", dump_isst_config },
1224 { "base-freq", "info", dump_pbf_config },
1225 { "base-freq", "enable", set_pbf_enable },
1226 { "base-freq", "disable", set_pbf_disable },
1227 { "turbo-freq", "info", dump_fact_config },
1228 { "turbo-freq", "enable", set_fact_enable },
1229 { "turbo-freq", "disable", set_fact_disable },
1230 { "core-power", "info", dump_clos_config },
1231 { "core-power", "enable", set_clos_enable },
1232 { "core-power", "disable", set_clos_disable },
1233 { "core-power", "config", set_clos_config },
1234 { "core-power", "assoc", set_clos_assoc },
1235 { "core-power", "get-assoc", get_clos_assoc },
1236 { NULL, NULL, NULL }
1237};
1238
1239/*
1240 * parse cpuset with following syntax
1241 * 1,2,4..6,8-10 and set bits in cpu_subset
1242 */
1243void parse_cpu_command(char *optarg)
1244{
1245 unsigned int start, end;
1246 char *next;
1247
1248 next = optarg;
1249
1250 while (next && *next) {
1251 if (*next == '-') /* no negative cpu numbers */
1252 goto error;
1253
1254 start = strtoul(next, &next, 10);
1255
1256 if (max_target_cpus < MAX_CPUS_IN_ONE_REQ)
1257 target_cpus[max_target_cpus++] = start;
1258
1259 if (*next == '\0')
1260 break;
1261
1262 if (*next == ',') {
1263 next += 1;
1264 continue;
1265 }
1266
1267 if (*next == '-') {
1268 next += 1; /* start range */
1269 } else if (*next == '.') {
1270 next += 1;
1271 if (*next == '.')
1272 next += 1; /* start range */
1273 else
1274 goto error;
1275 }
1276
1277 end = strtoul(next, &next, 10);
1278 if (end <= start)
1279 goto error;
1280
1281 while (++start <= end) {
1282 if (max_target_cpus < MAX_CPUS_IN_ONE_REQ)
1283 target_cpus[max_target_cpus++] = start;
1284 }
1285
1286 if (*next == ',')
1287 next += 1;
1288 else if (*next != '\0')
1289 goto error;
1290 }
1291
1292#ifdef DEBUG
1293 {
1294 int i;
1295
1296 for (i = 0; i < max_target_cpus; ++i)
1297 printf("cpu [%d] in arg\n", target_cpus[i]);
1298 }
1299#endif
1300 return;
1301
1302error:
1303 fprintf(stderr, "\"--cpu %s\" malformed\n", optarg);
1304 exit(-1);
1305}
1306
1307static void parse_cmd_args(int argc, int start, char **argv)
1308{
1309 int opt;
1310 int option_index;
1311
1312 static struct option long_options[] = {
1313 { "bucket", required_argument, 0, 'b' },
1314 { "level", required_argument, 0, 'l' },
1315 { "trl-type", required_argument, 0, 'r' },
1316 { "trl", required_argument, 0, 't' },
1317 { "help", no_argument, 0, 'h' },
1318 { "clos", required_argument, 0, 'c' },
1319 { "desired", required_argument, 0, 'd' },
1320 { "epp", required_argument, 0, 'e' },
1321 { "min", required_argument, 0, 'n' },
1322 { "max", required_argument, 0, 'm' },
1323 { "priority", required_argument, 0, 'p' },
1324 { "weight", required_argument, 0, 'w' },
1325 { 0, 0, 0, 0 }
1326 };
1327
1328 option_index = start;
1329
1330 optind = start + 1;
1331 while ((opt = getopt_long(argc, argv, "b:l:t:c:d:e:n:m:p:w:h",
1332 long_options, &option_index)) != -1) {
1333 switch (opt) {
1334 case 'b':
1335 fact_bucket = atoi(optarg);
1336 break;
1337 case 'h':
1338 cmd_help = 1;
1339 break;
1340 case 'l':
1341 tdp_level = atoi(optarg);
1342 break;
1343 case 't':
1344 sscanf(optarg, "0x%llx", &fact_trl);
1345 break;
1346 case 'r':
1347 if (!strncmp(optarg, "sse", 3)) {
1348 fact_avx = 0x01;
1349 } else if (!strncmp(optarg, "avx2", 4)) {
1350 fact_avx = 0x02;
1351 } else if (!strncmp(optarg, "avx512", 4)) {
1352 fact_avx = 0x04;
1353 } else {
1354 fprintf(outf, "Invalid sse,avx options\n");
1355 exit(1);
1356 }
1357 break;
1358 /* CLOS related */
1359 case 'c':
1360 current_clos = atoi(optarg);
1361 printf("clos %d\n", current_clos);
1362 break;
1363 case 'd':
1364 clos_desired = atoi(optarg);
1365 break;
1366 case 'e':
1367 clos_epp = atoi(optarg);
1368 break;
1369 case 'n':
1370 clos_min = atoi(optarg);
1371 break;
1372 case 'm':
1373 clos_max = atoi(optarg);
1374 break;
1375 case 'p':
1376 clos_priority_type = atoi(optarg);
1377 break;
1378 case 'w':
1379 clos_prop_prio = atoi(optarg);
1380 break;
1381 default:
1382 printf("no match\n");
1383 }
1384 }
1385}
1386
1387static void isst_help(void)
1388{
1389 printf("perf-profile:\tAn architectural mechanism that allows multiple optimized \n\
1390 performance profiles per system via static and/or dynamic\n\
1391 adjustment of core count, workload, Tjmax, and\n\
1392 TDP, etc.\n");
1393 printf("\nCommands : For feature=perf-profile\n");
1394 printf("\tinfo\n");
1395 printf("\tget-lock-status\n");
1396 printf("\tget-config-levels\n");
1397 printf("\tget-config-version\n");
1398 printf("\tget-config-enabled\n");
1399 printf("\tget-config-current-level\n");
1400 printf("\tset-config-level\n");
1401}
1402
1403static void pbf_help(void)
1404{
1405 printf("base-freq:\tEnables users to increase guaranteed base frequency\n\
1406 on certain cores (high priority cores) in exchange for lower\n\
1407 base frequency on remaining cores (low priority cores).\n");
1408 printf("\tcommand : info\n");
1409 printf("\tcommand : enable\n");
1410 printf("\tcommand : disable\n");
1411}
1412
1413static void fact_help(void)
1414{
1415 printf("turbo-freq:\tEnables the ability to set different turbo ratio\n\
1416 limits to cores based on priority.\n");
1417 printf("\nCommand: For feature=turbo-freq\n");
1418 printf("\tcommand : info\n");
1419 printf("\tcommand : enable\n");
1420 printf("\tcommand : disable\n");
1421}
1422
1423static void core_power_help(void)
1424{
1425 printf("core-power:\tInterface that allows user to define per core/tile\n\
1426 priority.\n");
1427 printf("\nCommands : For feature=core-power\n");
1428 printf("\tinfo\n");
1429 printf("\tenable\n");
1430 printf("\tdisable\n");
1431 printf("\tconfig\n");
1432 printf("\tassoc\n");
1433 printf("\tget-assoc\n");
1434}
1435
1436struct process_cmd_help_struct {
1437 char *feature;
1438 void (*process_fn)(void);
1439};
1440
1441static struct process_cmd_help_struct isst_help_cmds[] = {
1442 { "perf-profile", isst_help },
1443 { "base-freq", pbf_help },
1444 { "turbo-freq", fact_help },
1445 { "core-power", core_power_help },
1446 { NULL, NULL }
1447};
1448
1449void process_command(int argc, char **argv)
1450{
1451 int i = 0, matched = 0;
1452 char *feature = argv[optind];
1453 char *cmd = argv[optind + 1];
1454
1455 if (!feature || !cmd)
1456 return;
1457
1458 debug_printf("feature name [%s] command [%s]\n", feature, cmd);
1459 if (!strcmp(cmd, "-h") || !strcmp(cmd, "--help")) {
1460 while (isst_help_cmds[i].feature) {
1461 if (!strcmp(isst_help_cmds[i].feature, feature)) {
1462 isst_help_cmds[i].process_fn();
1463 exit(0);
1464 }
1465 ++i;
1466 }
1467 }
1468
1469 create_cpu_map();
1470
1471 i = 0;
1472 while (isst_cmds[i].feature) {
1473 if (!strcmp(isst_cmds[i].feature, feature) &&
1474 !strcmp(isst_cmds[i].command, cmd)) {
1475 parse_cmd_args(argc, optind + 1, argv);
1476 isst_cmds[i].process_fn();
1477 matched = 1;
1478 break;
1479 }
1480 ++i;
1481 }
1482
1483 if (!matched)
1484 fprintf(stderr, "Invalid command\n");
1485}
1486
1487static void usage(void)
1488{
1489 printf("Intel(R) Speed Select Technology\n");
1490 printf("\nUsage:\n");
1491 printf("intel-speed-select [OPTIONS] FEATURE COMMAND COMMAND_ARGUMENTS\n");
1492 printf("\nUse this tool to enumerate and control the Intel Speed Select Technology features,\n");
1493 printf("\nFEATURE : [perf-profile|base-freq|turbo-freq|core-power]\n");
1494 printf("\nFor help on each feature, use --h|--help\n");
1495 printf("\tFor example: intel-speed-select perf-profile -h\n");
1496
1497 printf("\nFor additional help on each command for a feature, use --h|--help\n");
1498 printf("\tFor example: intel-speed-select perf-profile get-lock-status -h\n");
1499 printf("\t\t This will print help for the command \"get-lock-status\" for the feature \"perf-profile\"\n");
1500
1501 printf("\nOPTIONS\n");
1502 printf("\t[-c|--cpu] : logical cpu number\n");
1503 printf("\t\tDefault: Die scoped for all dies in the system with multiple dies/package\n");
1504 printf("\t\t\t Or Package scoped for all Packages when each package contains one die\n");
1505 printf("\t[-d|--debug] : Debug mode\n");
1506 printf("\t[-h|--help] : Print help\n");
1507 printf("\t[-i|--info] : Print platform information\n");
1508 printf("\t[-o|--out] : Output file\n");
1509 printf("\t\t\tDefault : stderr\n");
1510 printf("\t[-f|--format] : output format [json|text]. Default: text\n");
1511 printf("\t[-v|--version] : Print version\n");
1512
1513 printf("\nResult format\n");
1514 printf("\tResult display uses a common format for each command:\n");
1515 printf("\tResults are formatted in text/JSON with\n");
1516 printf("\t\tPackage, Die, CPU, and command specific results.\n");
1517 printf("\t\t\tFor Set commands, status is 0 for success and rest for failures\n");
1518 exit(1);
1519}
1520
1521static void print_version(void)
1522{
1523 fprintf(outf, "Version %s\n", version_str);
1524 fprintf(outf, "Build date %s time %s\n", __DATE__, __TIME__);
1525 exit(0);
1526}
1527
1528static void cmdline(int argc, char **argv)
1529{
1530 int opt;
1531 int option_index = 0;
1532
1533 static struct option long_options[] = {
1534 { "cpu", required_argument, 0, 'c' },
1535 { "debug", no_argument, 0, 'd' },
1536 { "format", required_argument, 0, 'f' },
1537 { "help", no_argument, 0, 'h' },
1538 { "info", no_argument, 0, 'i' },
1539 { "out", required_argument, 0, 'o' },
1540 { "version", no_argument, 0, 'v' },
1541 { 0, 0, 0, 0 }
1542 };
1543
1544 progname = argv[0];
1545 while ((opt = getopt_long_only(argc, argv, "+c:df:hio:v", long_options,
1546 &option_index)) != -1) {
1547 switch (opt) {
1548 case 'c':
1549 parse_cpu_command(optarg);
1550 break;
1551 case 'd':
1552 debug_flag = 1;
1553 printf("Debug Mode ON\n");
1554 break;
1555 case 'f':
1556 if (!strncmp(optarg, "json", 4))
1557 out_format_json = 1;
1558 break;
1559 case 'h':
1560 usage();
1561 break;
1562 case 'i':
1563 isst_print_platform_information();
1564 break;
1565 case 'o':
1566 if (outf)
1567 fclose(outf);
1568 outf = fopen_or_exit(optarg, "w");
1569 break;
1570 case 'v':
1571 print_version();
1572 break;
1573 default:
1574 usage();
1575 }
1576 }
1577
1578 if (geteuid() != 0) {
1579 fprintf(stderr, "Must run as root\n");
1580 exit(0);
1581 }
1582
1583 if (optind > (argc - 2)) {
1584 fprintf(stderr, "Feature name and|or command not specified\n");
1585 exit(0);
1586 }
1587 update_cpu_model();
1588 printf("Intel(R) Speed Select Technology\n");
1589 printf("Executing on CPU model:%d[0x%x]\n", cpu_model, cpu_model);
1590 set_max_cpu_num();
1591 set_cpu_present_cpu_mask();
1592 set_cpu_target_cpu_mask();
1593 isst_fill_platform_info();
1594 if (isst_platform_info.api_version > supported_api_ver) {
1595 printf("Incompatible API versions; Upgrade of tool is required\n");
1596 exit(0);
1597 }
1598
1599 process_command(argc, argv);
1600}
1601
1602int main(int argc, char **argv)
1603{
1604 outf = stderr;
1605 cmdline(argc, argv);
1606 return 0;
1607}
diff --git a/tools/power/x86/intel-speed-select/isst-core.c b/tools/power/x86/intel-speed-select/isst-core.c
new file mode 100644
index 000000000000..8de4ac39a008
--- /dev/null
+++ b/tools/power/x86/intel-speed-select/isst-core.c
@@ -0,0 +1,721 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Intel Speed Select -- Enumerate and control features
4 * Copyright (c) 2019 Intel Corporation.
5 */
6
7#include "isst.h"
8
9int isst_get_ctdp_levels(int cpu, struct isst_pkg_ctdp *pkg_dev)
10{
11 unsigned int resp;
12 int ret;
13
14 ret = isst_send_mbox_command(cpu, CONFIG_TDP,
15 CONFIG_TDP_GET_LEVELS_INFO, 0, 0, &resp);
16 if (ret)
17 return ret;
18
19 debug_printf("cpu:%d CONFIG_TDP_GET_LEVELS_INFO resp:%x\n", cpu, resp);
20
21 pkg_dev->version = resp & 0xff;
22 pkg_dev->levels = (resp >> 8) & 0xff;
23 pkg_dev->current_level = (resp >> 16) & 0xff;
24 pkg_dev->locked = !!(resp & BIT(24));
25 pkg_dev->enabled = !!(resp & BIT(31));
26
27 return 0;
28}
29
30int isst_get_ctdp_control(int cpu, int config_index,
31 struct isst_pkg_ctdp_level_info *ctdp_level)
32{
33 unsigned int resp;
34 int ret;
35
36 ret = isst_send_mbox_command(cpu, CONFIG_TDP,
37 CONFIG_TDP_GET_TDP_CONTROL, 0,
38 config_index, &resp);
39 if (ret)
40 return ret;
41
42 ctdp_level->fact_support = resp & BIT(0);
43 ctdp_level->pbf_support = !!(resp & BIT(1));
44 ctdp_level->fact_enabled = !!(resp & BIT(16));
45 ctdp_level->pbf_enabled = !!(resp & BIT(17));
46
47 debug_printf(
48 "cpu:%d CONFIG_TDP_GET_TDP_CONTROL resp:%x fact_support:%d pbf_support: %d fact_enabled:%d pbf_enabled:%d\n",
49 cpu, resp, ctdp_level->fact_support, ctdp_level->pbf_support,
50 ctdp_level->fact_enabled, ctdp_level->pbf_enabled);
51
52 return 0;
53}
54
55int isst_get_tdp_info(int cpu, int config_index,
56 struct isst_pkg_ctdp_level_info *ctdp_level)
57{
58 unsigned int resp;
59 int ret;
60
61 ret = isst_send_mbox_command(cpu, CONFIG_TDP, CONFIG_TDP_GET_TDP_INFO,
62 0, config_index, &resp);
63 if (ret)
64 return ret;
65
66 ctdp_level->pkg_tdp = resp & GENMASK(14, 0);
67 ctdp_level->tdp_ratio = (resp & GENMASK(23, 16)) >> 16;
68
69 debug_printf(
70 "cpu:%d ctdp:%d CONFIG_TDP_GET_TDP_INFO resp:%x tdp_ratio:%d pkg_tdp:%d\n",
71 cpu, config_index, resp, ctdp_level->tdp_ratio,
72 ctdp_level->pkg_tdp);
73 return 0;
74}
75
76int isst_get_pwr_info(int cpu, int config_index,
77 struct isst_pkg_ctdp_level_info *ctdp_level)
78{
79 unsigned int resp;
80 int ret;
81
82 ret = isst_send_mbox_command(cpu, CONFIG_TDP, CONFIG_TDP_GET_PWR_INFO,
83 0, config_index, &resp);
84 if (ret)
85 return ret;
86
87 ctdp_level->pkg_max_power = resp & GENMASK(14, 0);
88 ctdp_level->pkg_min_power = (resp & GENMASK(30, 16)) >> 16;
89
90 debug_printf(
91 "cpu:%d ctdp:%d CONFIG_TDP_GET_PWR_INFO resp:%x pkg_max_power:%d pkg_min_power:%d\n",
92 cpu, config_index, resp, ctdp_level->pkg_max_power,
93 ctdp_level->pkg_min_power);
94
95 return 0;
96}
97
98int isst_get_tjmax_info(int cpu, int config_index,
99 struct isst_pkg_ctdp_level_info *ctdp_level)
100{
101 unsigned int resp;
102 int ret;
103
104 ret = isst_send_mbox_command(cpu, CONFIG_TDP, CONFIG_TDP_GET_TJMAX_INFO,
105 0, config_index, &resp);
106 if (ret)
107 return ret;
108
109 ctdp_level->t_proc_hot = resp & GENMASK(7, 0);
110
111 debug_printf(
112 "cpu:%d ctdp:%d CONFIG_TDP_GET_TJMAX_INFO resp:%x t_proc_hot:%d\n",
113 cpu, config_index, resp, ctdp_level->t_proc_hot);
114
115 return 0;
116}
117
118int isst_get_coremask_info(int cpu, int config_index,
119 struct isst_pkg_ctdp_level_info *ctdp_level)
120{
121 unsigned int resp;
122 int i, ret;
123
124 ctdp_level->cpu_count = 0;
125 for (i = 0; i < 2; ++i) {
126 unsigned long long mask;
127 int cpu_count = 0;
128
129 ret = isst_send_mbox_command(cpu, CONFIG_TDP,
130 CONFIG_TDP_GET_CORE_MASK, 0,
131 (i << 8) | config_index, &resp);
132 if (ret)
133 return ret;
134
135 debug_printf(
136 "cpu:%d ctdp:%d mask:%d CONFIG_TDP_GET_CORE_MASK resp:%x\n",
137 cpu, config_index, i, resp);
138
139 mask = (unsigned long long)resp << (32 * i);
140 set_cpu_mask_from_punit_coremask(cpu, mask,
141 ctdp_level->core_cpumask_size,
142 ctdp_level->core_cpumask,
143 &cpu_count);
144 ctdp_level->cpu_count += cpu_count;
145 debug_printf("cpu:%d ctdp:%d mask:%d cpu count:%d\n", cpu,
146 config_index, i, ctdp_level->cpu_count);
147 }
148
149 return 0;
150}
151
152int isst_get_get_trl(int cpu, int level, int avx_level, int *trl)
153{
154 unsigned int req, resp;
155 int ret;
156
157 req = level | (avx_level << 16);
158 ret = isst_send_mbox_command(cpu, CONFIG_TDP,
159 CONFIG_TDP_GET_TURBO_LIMIT_RATIOS, 0, req,
160 &resp);
161 if (ret)
162 return ret;
163
164 debug_printf(
165 "cpu:%d CONFIG_TDP_GET_TURBO_LIMIT_RATIOS req:%x resp:%x\n",
166 cpu, req, resp);
167
168 trl[0] = resp & GENMASK(7, 0);
169 trl[1] = (resp & GENMASK(15, 8)) >> 8;
170 trl[2] = (resp & GENMASK(23, 16)) >> 16;
171 trl[3] = (resp & GENMASK(31, 24)) >> 24;
172
173 req = level | BIT(8) | (avx_level << 16);
174 ret = isst_send_mbox_command(cpu, CONFIG_TDP,
175 CONFIG_TDP_GET_TURBO_LIMIT_RATIOS, 0, req,
176 &resp);
177 if (ret)
178 return ret;
179
180 debug_printf("cpu:%d CONFIG_TDP_GET_TURBO_LIMIT req:%x resp:%x\n", cpu,
181 req, resp);
182
183 trl[4] = resp & GENMASK(7, 0);
184 trl[5] = (resp & GENMASK(15, 8)) >> 8;
185 trl[6] = (resp & GENMASK(23, 16)) >> 16;
186 trl[7] = (resp & GENMASK(31, 24)) >> 24;
187
188 return 0;
189}
190
191int isst_set_tdp_level_msr(int cpu, int tdp_level)
192{
193 int ret;
194
195 debug_printf("cpu: tdp_level via MSR %d\n", cpu, tdp_level);
196
197 if (isst_get_config_tdp_lock_status(cpu)) {
198 debug_printf("cpu: tdp_locked %d\n", cpu);
199 return -1;
200 }
201
202 if (tdp_level > 2)
203 return -1; /* invalid value */
204
205 ret = isst_send_msr_command(cpu, 0x64b, 1,
206 (unsigned long long *)&tdp_level);
207 if (ret)
208 return ret;
209
210 debug_printf("cpu: tdp_level via MSR successful %d\n", cpu, tdp_level);
211
212 return 0;
213}
214
215int isst_set_tdp_level(int cpu, int tdp_level)
216{
217 unsigned int resp;
218 int ret;
219
220 ret = isst_send_mbox_command(cpu, CONFIG_TDP, CONFIG_TDP_SET_LEVEL, 0,
221 tdp_level, &resp);
222 if (ret)
223 return isst_set_tdp_level_msr(cpu, tdp_level);
224
225 return 0;
226}
227
228int isst_get_pbf_info(int cpu, int level, struct isst_pbf_info *pbf_info)
229{
230 unsigned int req, resp;
231 int i, ret;
232
233 pbf_info->core_cpumask_size = alloc_cpu_set(&pbf_info->core_cpumask);
234
235 for (i = 0; i < 2; ++i) {
236 unsigned long long mask;
237 int count;
238
239 ret = isst_send_mbox_command(cpu, CONFIG_TDP,
240 CONFIG_TDP_PBF_GET_CORE_MASK_INFO,
241 0, (i << 8) | level, &resp);
242 if (ret)
243 return ret;
244
245 debug_printf(
246 "cpu:%d CONFIG_TDP_PBF_GET_CORE_MASK_INFO resp:%x\n",
247 cpu, resp);
248
249 mask = (unsigned long long)resp << (32 * i);
250 set_cpu_mask_from_punit_coremask(cpu, mask,
251 pbf_info->core_cpumask_size,
252 pbf_info->core_cpumask,
253 &count);
254 }
255
256 req = level;
257 ret = isst_send_mbox_command(cpu, CONFIG_TDP,
258 CONFIG_TDP_PBF_GET_P1HI_P1LO_INFO, 0, req,
259 &resp);
260 if (ret)
261 return ret;
262
263 debug_printf("cpu:%d CONFIG_TDP_PBF_GET_P1HI_P1LO_INFO resp:%x\n", cpu,
264 resp);
265
266 pbf_info->p1_low = resp & 0xff;
267 pbf_info->p1_high = (resp & GENMASK(15, 8)) >> 8;
268
269 req = level;
270 ret = isst_send_mbox_command(
271 cpu, CONFIG_TDP, CONFIG_TDP_PBF_GET_TDP_INFO, 0, req, &resp);
272 if (ret)
273 return ret;
274
275 debug_printf("cpu:%d CONFIG_TDP_PBF_GET_TDP_INFO resp:%x\n", cpu, resp);
276
277 pbf_info->tdp = resp & 0xffff;
278
279 req = level;
280 ret = isst_send_mbox_command(
281 cpu, CONFIG_TDP, CONFIG_TDP_PBF_GET_TJ_MAX_INFO, 0, req, &resp);
282 if (ret)
283 return ret;
284
285 debug_printf("cpu:%d CONFIG_TDP_PBF_GET_TJ_MAX_INFO resp:%x\n", cpu,
286 resp);
287 pbf_info->t_control = (resp >> 8) & 0xff;
288 pbf_info->t_prochot = resp & 0xff;
289
290 return 0;
291}
292
293void isst_get_pbf_info_complete(struct isst_pbf_info *pbf_info)
294{
295 free_cpu_set(pbf_info->core_cpumask);
296}
297
298int isst_set_pbf_fact_status(int cpu, int pbf, int enable)
299{
300 struct isst_pkg_ctdp pkg_dev;
301 struct isst_pkg_ctdp_level_info ctdp_level;
302 int current_level;
303 unsigned int req = 0, resp;
304 int ret;
305
306 ret = isst_get_ctdp_levels(cpu, &pkg_dev);
307 if (ret)
308 return ret;
309
310 current_level = pkg_dev.current_level;
311
312 ret = isst_get_ctdp_control(cpu, current_level, &ctdp_level);
313 if (ret)
314 return ret;
315
316 if (pbf) {
317 if (ctdp_level.fact_enabled)
318 req = BIT(16);
319
320 if (enable)
321 req |= BIT(17);
322 else
323 req &= ~BIT(17);
324 } else {
325 if (ctdp_level.pbf_enabled)
326 req = BIT(17);
327
328 if (enable)
329 req |= BIT(16);
330 else
331 req &= ~BIT(16);
332 }
333
334 ret = isst_send_mbox_command(cpu, CONFIG_TDP,
335 CONFIG_TDP_SET_TDP_CONTROL, 0, req, &resp);
336 if (ret)
337 return ret;
338
339 debug_printf("cpu:%d CONFIG_TDP_SET_TDP_CONTROL pbf/fact:%d req:%x\n",
340 cpu, pbf, req);
341
342 return 0;
343}
344
345int isst_get_fact_bucket_info(int cpu, int level,
346 struct isst_fact_bucket_info *bucket_info)
347{
348 unsigned int resp;
349 int i, k, ret;
350
351 for (i = 0; i < 2; ++i) {
352 int j;
353
354 ret = isst_send_mbox_command(
355 cpu, CONFIG_TDP,
356 CONFIG_TDP_GET_FACT_HP_TURBO_LIMIT_NUMCORES, 0,
357 (i << 8) | level, &resp);
358 if (ret)
359 return ret;
360
361 debug_printf(
362 "cpu:%d CONFIG_TDP_GET_FACT_HP_TURBO_LIMIT_NUMCORES index:%d level:%d resp:%x\n",
363 cpu, i, level, resp);
364
365 for (j = 0; j < 4; ++j) {
366 bucket_info[j + (i * 4)].high_priority_cores_count =
367 (resp >> (j * 8)) & 0xff;
368 }
369 }
370
371 for (k = 0; k < 3; ++k) {
372 for (i = 0; i < 2; ++i) {
373 int j;
374
375 ret = isst_send_mbox_command(
376 cpu, CONFIG_TDP,
377 CONFIG_TDP_GET_FACT_HP_TURBO_LIMIT_RATIOS, 0,
378 (k << 16) | (i << 8) | level, &resp);
379 if (ret)
380 return ret;
381
382 debug_printf(
383 "cpu:%d CONFIG_TDP_GET_FACT_HP_TURBO_LIMIT_RATIOS index:%d level:%d avx:%d resp:%x\n",
384 cpu, i, level, k, resp);
385
386 for (j = 0; j < 4; ++j) {
387 switch (k) {
388 case 0:
389 bucket_info[j + (i * 4)].sse_trl =
390 (resp >> (j * 8)) & 0xff;
391 break;
392 case 1:
393 bucket_info[j + (i * 4)].avx_trl =
394 (resp >> (j * 8)) & 0xff;
395 break;
396 case 2:
397 bucket_info[j + (i * 4)].avx512_trl =
398 (resp >> (j * 8)) & 0xff;
399 break;
400 default:
401 break;
402 }
403 }
404 }
405 }
406
407 return 0;
408}
409
410int isst_get_fact_info(int cpu, int level, struct isst_fact_info *fact_info)
411{
412 unsigned int resp;
413 int ret;
414
415 ret = isst_send_mbox_command(cpu, CONFIG_TDP,
416 CONFIG_TDP_GET_FACT_LP_CLIPPING_RATIO, 0,
417 level, &resp);
418 if (ret)
419 return ret;
420
421 debug_printf("cpu:%d CONFIG_TDP_GET_FACT_LP_CLIPPING_RATIO resp:%x\n",
422 cpu, resp);
423
424 fact_info->lp_clipping_ratio_license_sse = resp & 0xff;
425 fact_info->lp_clipping_ratio_license_avx2 = (resp >> 8) & 0xff;
426 fact_info->lp_clipping_ratio_license_avx512 = (resp >> 16) & 0xff;
427
428 ret = isst_get_fact_bucket_info(cpu, level, fact_info->bucket_info);
429
430 return ret;
431}
432
433int isst_set_trl(int cpu, unsigned long long trl)
434{
435 int ret;
436
437 if (!trl)
438 trl = 0xFFFFFFFFFFFFFFFFULL;
439
440 ret = isst_send_msr_command(cpu, 0x1AD, 1, &trl);
441 if (ret)
442 return ret;
443
444 return 0;
445}
446
447int isst_set_trl_from_current_tdp(int cpu, unsigned long long trl)
448{
449 unsigned long long msr_trl;
450 int ret;
451
452 if (trl) {
453 msr_trl = trl;
454 } else {
455 struct isst_pkg_ctdp pkg_dev;
456 int trl[8];
457 int i;
458
459 ret = isst_get_ctdp_levels(cpu, &pkg_dev);
460 if (ret)
461 return ret;
462
463 ret = isst_get_get_trl(cpu, pkg_dev.current_level, 0, trl);
464 if (ret)
465 return ret;
466
467 msr_trl = 0;
468 for (i = 0; i < 8; ++i) {
469 unsigned long long _trl = trl[i];
470
471 msr_trl |= (_trl << (i * 8));
472 }
473 }
474 ret = isst_send_msr_command(cpu, 0x1AD, 1, &msr_trl);
475 if (ret)
476 return ret;
477
478 return 0;
479}
480
481/* Return 1 if locked */
482int isst_get_config_tdp_lock_status(int cpu)
483{
484 unsigned long long tdp_control = 0;
485 int ret;
486
487 ret = isst_send_msr_command(cpu, 0x64b, 0, &tdp_control);
488 if (ret)
489 return ret;
490
491 ret = !!(tdp_control & BIT(31));
492
493 return ret;
494}
495
496void isst_get_process_ctdp_complete(int cpu, struct isst_pkg_ctdp *pkg_dev)
497{
498 int i;
499
500 if (!pkg_dev->processed)
501 return;
502
503 for (i = 0; i < pkg_dev->levels; ++i) {
504 struct isst_pkg_ctdp_level_info *ctdp_level;
505
506 ctdp_level = &pkg_dev->ctdp_level[i];
507 if (ctdp_level->pbf_support)
508 free_cpu_set(ctdp_level->pbf_info.core_cpumask);
509 free_cpu_set(ctdp_level->core_cpumask);
510 }
511}
512
513int isst_get_process_ctdp(int cpu, int tdp_level, struct isst_pkg_ctdp *pkg_dev)
514{
515 int i, ret;
516
517 if (pkg_dev->processed)
518 return 0;
519
520 ret = isst_get_ctdp_levels(cpu, pkg_dev);
521 if (ret)
522 return ret;
523
524 debug_printf("cpu: %d ctdp enable:%d current level: %d levels:%d\n",
525 cpu, pkg_dev->enabled, pkg_dev->current_level,
526 pkg_dev->levels);
527
528 for (i = 0; i <= pkg_dev->levels; ++i) {
529 struct isst_pkg_ctdp_level_info *ctdp_level;
530
531 if (tdp_level != 0xff && i != tdp_level)
532 continue;
533
534 debug_printf("cpu:%d Get Information for TDP level:%d\n", cpu,
535 i);
536 ctdp_level = &pkg_dev->ctdp_level[i];
537
538 ctdp_level->processed = 1;
539 ctdp_level->level = i;
540 ctdp_level->control_cpu = cpu;
541 ctdp_level->pkg_id = get_physical_package_id(cpu);
542 ctdp_level->die_id = get_physical_die_id(cpu);
543
544 ret = isst_get_ctdp_control(cpu, i, ctdp_level);
545 if (ret)
546 return ret;
547
548 ret = isst_get_tdp_info(cpu, i, ctdp_level);
549 if (ret)
550 return ret;
551
552 ret = isst_get_pwr_info(cpu, i, ctdp_level);
553 if (ret)
554 return ret;
555
556 ret = isst_get_tjmax_info(cpu, i, ctdp_level);
557 if (ret)
558 return ret;
559
560 ctdp_level->core_cpumask_size =
561 alloc_cpu_set(&ctdp_level->core_cpumask);
562 ret = isst_get_coremask_info(cpu, i, ctdp_level);
563 if (ret)
564 return ret;
565
566 ret = isst_get_get_trl(cpu, i, 0,
567 ctdp_level->trl_sse_active_cores);
568 if (ret)
569 return ret;
570
571 ret = isst_get_get_trl(cpu, i, 1,
572 ctdp_level->trl_avx_active_cores);
573 if (ret)
574 return ret;
575
576 ret = isst_get_get_trl(cpu, i, 2,
577 ctdp_level->trl_avx_512_active_cores);
578 if (ret)
579 return ret;
580
581 if (ctdp_level->pbf_support) {
582 ret = isst_get_pbf_info(cpu, i, &ctdp_level->pbf_info);
583 if (!ret)
584 ctdp_level->pbf_found = 1;
585 }
586
587 if (ctdp_level->fact_support) {
588 ret = isst_get_fact_info(cpu, i,
589 &ctdp_level->fact_info);
590 if (ret)
591 return ret;
592 }
593 }
594
595 pkg_dev->processed = 1;
596
597 return 0;
598}
599
600int isst_pm_qos_config(int cpu, int enable_clos, int priority_type)
601{
602 unsigned int req, resp;
603 int ret;
604
605 ret = isst_send_mbox_command(cpu, CONFIG_CLOS, CLOS_PM_QOS_CONFIG, 0, 0,
606 &resp);
607 if (ret)
608 return ret;
609
610 debug_printf("cpu:%d CLOS_PM_QOS_CONFIG resp:%x\n", cpu, resp);
611
612 req = resp;
613
614 if (enable_clos)
615 req = req | BIT(1);
616 else
617 req = req & ~BIT(1);
618
619 if (priority_type)
620 req = req | BIT(2);
621 else
622 req = req & ~BIT(2);
623
624 ret = isst_send_mbox_command(cpu, CONFIG_CLOS, CLOS_PM_QOS_CONFIG,
625 BIT(MBOX_CMD_WRITE_BIT), req, &resp);
626 if (ret)
627 return ret;
628
629 debug_printf("cpu:%d CLOS_PM_QOS_CONFIG priority type:%d req:%x\n", cpu,
630 priority_type, req);
631
632 return 0;
633}
634
635int isst_pm_get_clos(int cpu, int clos, struct isst_clos_config *clos_config)
636{
637 unsigned int resp;
638 int ret;
639
640 ret = isst_send_mbox_command(cpu, CONFIG_CLOS, CLOS_PM_CLOS, clos, 0,
641 &resp);
642 if (ret)
643 return ret;
644
645 clos_config->pkg_id = get_physical_package_id(cpu);
646 clos_config->die_id = get_physical_die_id(cpu);
647
648 clos_config->epp = resp & 0x0f;
649 clos_config->clos_prop_prio = (resp >> 4) & 0x0f;
650 clos_config->clos_min = (resp >> 8) & 0xff;
651 clos_config->clos_max = (resp >> 16) & 0xff;
652 clos_config->clos_desired = (resp >> 24) & 0xff;
653
654 return 0;
655}
656
657int isst_set_clos(int cpu, int clos, struct isst_clos_config *clos_config)
658{
659 unsigned int req, resp;
660 unsigned int param;
661 int ret;
662
663 req = clos_config->epp & 0x0f;
664 req |= (clos_config->clos_prop_prio & 0x0f) << 4;
665 req |= (clos_config->clos_min & 0xff) << 8;
666 req |= (clos_config->clos_max & 0xff) << 16;
667 req |= (clos_config->clos_desired & 0xff) << 24;
668
669 param = BIT(MBOX_CMD_WRITE_BIT) | clos;
670
671 ret = isst_send_mbox_command(cpu, CONFIG_CLOS, CLOS_PM_CLOS, param, req,
672 &resp);
673 if (ret)
674 return ret;
675
676 debug_printf("cpu:%d CLOS_PM_CLOS param:%x req:%x\n", cpu, param, req);
677
678 return 0;
679}
680
681int isst_clos_get_assoc_status(int cpu, int *clos_id)
682{
683 unsigned int resp;
684 unsigned int param;
685 int core_id, ret;
686
687 core_id = find_phy_core_num(cpu);
688 param = core_id;
689
690 ret = isst_send_mbox_command(cpu, CONFIG_CLOS, CLOS_PQR_ASSOC, param, 0,
691 &resp);
692 if (ret)
693 return ret;
694
695 debug_printf("cpu:%d CLOS_PQR_ASSOC param:%x resp:%x\n", cpu, param,
696 resp);
697 *clos_id = (resp >> 16) & 0x03;
698
699 return 0;
700}
701
702int isst_clos_associate(int cpu, int clos_id)
703{
704 unsigned int req, resp;
705 unsigned int param;
706 int core_id, ret;
707
708 req = (clos_id & 0x03) << 16;
709 core_id = find_phy_core_num(cpu);
710 param = BIT(MBOX_CMD_WRITE_BIT) | core_id;
711
712 ret = isst_send_mbox_command(cpu, CONFIG_CLOS, CLOS_PQR_ASSOC, param,
713 req, &resp);
714 if (ret)
715 return ret;
716
717 debug_printf("cpu:%d CLOS_PQR_ASSOC param:%x req:%x\n", cpu, param,
718 req);
719
720 return 0;
721}
diff --git a/tools/power/x86/intel-speed-select/isst-display.c b/tools/power/x86/intel-speed-select/isst-display.c
new file mode 100644
index 000000000000..f368b8323742
--- /dev/null
+++ b/tools/power/x86/intel-speed-select/isst-display.c
@@ -0,0 +1,479 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Intel dynamic_speed_select -- Enumerate and control features
4 * Copyright (c) 2019 Intel Corporation.
5 */
6
7#include "isst.h"
8
9#define DISP_FREQ_MULTIPLIER 100000
10
11static void printcpumask(int str_len, char *str, int mask_size,
12 cpu_set_t *cpu_mask)
13{
14 int i, max_cpus = get_topo_max_cpus();
15 unsigned int *mask;
16 int size, index, curr_index;
17
18 size = max_cpus / (sizeof(unsigned int) * 8);
19 if (max_cpus % (sizeof(unsigned int) * 8))
20 size++;
21
22 mask = calloc(size, sizeof(unsigned int));
23 if (!mask)
24 return;
25
26 for (i = 0; i < max_cpus; ++i) {
27 int mask_index, bit_index;
28
29 if (!CPU_ISSET_S(i, mask_size, cpu_mask))
30 continue;
31
32 mask_index = i / (sizeof(unsigned int) * 8);
33 bit_index = i % (sizeof(unsigned int) * 8);
34 mask[mask_index] |= BIT(bit_index);
35 }
36
37 curr_index = 0;
38 for (i = size - 1; i >= 0; --i) {
39 index = snprintf(&str[curr_index], str_len - curr_index, "%08x",
40 mask[i]);
41 curr_index += index;
42 if (i) {
43 strncat(&str[curr_index], ",", str_len - curr_index);
44 curr_index++;
45 }
46 }
47
48 free(mask);
49}
50
51static void format_and_print_txt(FILE *outf, int level, char *header,
52 char *value)
53{
54 char *spaces = " ";
55 static char delimiters[256];
56 int i, j = 0;
57
58 if (!level)
59 return;
60
61 if (level == 1) {
62 strcpy(delimiters, " ");
63 } else {
64 for (i = 0; i < level - 1; ++i)
65 j += snprintf(&delimiters[j], sizeof(delimiters) - j,
66 "%s", spaces);
67 }
68
69 if (header && value) {
70 fprintf(outf, "%s", delimiters);
71 fprintf(outf, "%s:%s\n", header, value);
72 } else if (header) {
73 fprintf(outf, "%s", delimiters);
74 fprintf(outf, "%s\n", header);
75 }
76}
77
78static int last_level;
79static void format_and_print(FILE *outf, int level, char *header, char *value)
80{
81 char *spaces = " ";
82 static char delimiters[256];
83 int i;
84
85 if (!out_format_is_json()) {
86 format_and_print_txt(outf, level, header, value);
87 return;
88 }
89
90 if (level == 0) {
91 if (header)
92 fprintf(outf, "{");
93 else
94 fprintf(outf, "\n}\n");
95
96 } else {
97 int j = 0;
98
99 for (i = 0; i < level; ++i)
100 j += snprintf(&delimiters[j], sizeof(delimiters) - j,
101 "%s", spaces);
102
103 if (last_level == level)
104 fprintf(outf, ",\n");
105
106 if (value) {
107 if (last_level != level)
108 fprintf(outf, "\n");
109
110 fprintf(outf, "%s\"%s\": ", delimiters, header);
111 fprintf(outf, "\"%s\"", value);
112 } else {
113 for (i = last_level - 1; i >= level; --i) {
114 int k = 0;
115
116 for (j = i; j > 0; --j)
117 k += snprintf(&delimiters[k],
118 sizeof(delimiters) - k,
119 "%s", spaces);
120 if (i == level && header)
121 fprintf(outf, "\n%s},", delimiters);
122 else
123 fprintf(outf, "\n%s}", delimiters);
124 }
125 if (abs(last_level - level) < 3)
126 fprintf(outf, "\n");
127 if (header)
128 fprintf(outf, "%s\"%s\": {", delimiters,
129 header);
130 }
131 }
132
133 last_level = level;
134}
135
136static void print_packag_info(int cpu, FILE *outf)
137{
138 char header[256];
139
140 snprintf(header, sizeof(header), "package-%d",
141 get_physical_package_id(cpu));
142 format_and_print(outf, 1, header, NULL);
143 snprintf(header, sizeof(header), "die-%d", get_physical_die_id(cpu));
144 format_and_print(outf, 2, header, NULL);
145 snprintf(header, sizeof(header), "cpu-%d", cpu);
146 format_and_print(outf, 3, header, NULL);
147}
148
149static void _isst_pbf_display_information(int cpu, FILE *outf, int level,
150 struct isst_pbf_info *pbf_info,
151 int disp_level)
152{
153 char header[256];
154 char value[256];
155
156 snprintf(header, sizeof(header), "speed-select-base-freq");
157 format_and_print(outf, disp_level, header, NULL);
158
159 snprintf(header, sizeof(header), "high-priority-base-frequency(KHz)");
160 snprintf(value, sizeof(value), "%d",
161 pbf_info->p1_high * DISP_FREQ_MULTIPLIER);
162 format_and_print(outf, disp_level + 1, header, value);
163
164 snprintf(header, sizeof(header), "high-priority-cpu-mask");
165 printcpumask(sizeof(value), value, pbf_info->core_cpumask_size,
166 pbf_info->core_cpumask);
167 format_and_print(outf, disp_level + 1, header, value);
168
169 snprintf(header, sizeof(header), "low-priority-base-frequency(KHz)");
170 snprintf(value, sizeof(value), "%d",
171 pbf_info->p1_low * DISP_FREQ_MULTIPLIER);
172 format_and_print(outf, disp_level + 1, header, value);
173
174 snprintf(header, sizeof(header), "tjunction-temperature(C)");
175 snprintf(value, sizeof(value), "%d", pbf_info->t_prochot);
176 format_and_print(outf, disp_level + 1, header, value);
177
178 snprintf(header, sizeof(header), "thermal-design-power(W)");
179 snprintf(value, sizeof(value), "%d", pbf_info->tdp);
180 format_and_print(outf, disp_level + 1, header, value);
181}
182
183static void _isst_fact_display_information(int cpu, FILE *outf, int level,
184 int fact_bucket, int fact_avx,
185 struct isst_fact_info *fact_info,
186 int base_level)
187{
188 struct isst_fact_bucket_info *bucket_info = fact_info->bucket_info;
189 char header[256];
190 char value[256];
191 int j;
192
193 snprintf(header, sizeof(header), "speed-select-turbo-freq");
194 format_and_print(outf, base_level, header, NULL);
195 for (j = 0; j < ISST_FACT_MAX_BUCKETS; ++j) {
196 if (fact_bucket != 0xff && fact_bucket != j)
197 continue;
198
199 if (!bucket_info[j].high_priority_cores_count)
200 break;
201
202 snprintf(header, sizeof(header), "bucket-%d", j);
203 format_and_print(outf, base_level + 1, header, NULL);
204
205 snprintf(header, sizeof(header), "high-priority-cores-count");
206 snprintf(value, sizeof(value), "%d",
207 bucket_info[j].high_priority_cores_count);
208 format_and_print(outf, base_level + 2, header, value);
209
210 if (fact_avx & 0x01) {
211 snprintf(header, sizeof(header),
212 "high-priority-max-frequency(KHz)");
213 snprintf(value, sizeof(value), "%d",
214 bucket_info[j].sse_trl * DISP_FREQ_MULTIPLIER);
215 format_and_print(outf, base_level + 2, header, value);
216 }
217
218 if (fact_avx & 0x02) {
219 snprintf(header, sizeof(header),
220 "high-priority-max-avx2-frequency(KHz)");
221 snprintf(value, sizeof(value), "%d",
222 bucket_info[j].avx_trl * DISP_FREQ_MULTIPLIER);
223 format_and_print(outf, base_level + 2, header, value);
224 }
225
226 if (fact_avx & 0x04) {
227 snprintf(header, sizeof(header),
228 "high-priority-max-avx512-frequency(KHz)");
229 snprintf(value, sizeof(value), "%d",
230 bucket_info[j].avx512_trl *
231 DISP_FREQ_MULTIPLIER);
232 format_and_print(outf, base_level + 2, header, value);
233 }
234 }
235 snprintf(header, sizeof(header),
236 "speed-select-turbo-freq-clip-frequencies");
237 format_and_print(outf, base_level + 1, header, NULL);
238 snprintf(header, sizeof(header), "low-priority-max-frequency(KHz)");
239 snprintf(value, sizeof(value), "%d",
240 fact_info->lp_clipping_ratio_license_sse *
241 DISP_FREQ_MULTIPLIER);
242 format_and_print(outf, base_level + 2, header, value);
243 snprintf(header, sizeof(header),
244 "low-priority-max-avx2-frequency(KHz)");
245 snprintf(value, sizeof(value), "%d",
246 fact_info->lp_clipping_ratio_license_avx2 *
247 DISP_FREQ_MULTIPLIER);
248 format_and_print(outf, base_level + 2, header, value);
249 snprintf(header, sizeof(header),
250 "low-priority-max-avx512-frequency(KHz)");
251 snprintf(value, sizeof(value), "%d",
252 fact_info->lp_clipping_ratio_license_avx512 *
253 DISP_FREQ_MULTIPLIER);
254 format_and_print(outf, base_level + 2, header, value);
255}
256
257void isst_ctdp_display_information(int cpu, FILE *outf, int tdp_level,
258 struct isst_pkg_ctdp *pkg_dev)
259{
260 char header[256];
261 char value[256];
262 int i, base_level = 1;
263
264 print_packag_info(cpu, outf);
265
266 for (i = 0; i <= pkg_dev->levels; ++i) {
267 struct isst_pkg_ctdp_level_info *ctdp_level;
268 int j;
269
270 ctdp_level = &pkg_dev->ctdp_level[i];
271 if (!ctdp_level->processed)
272 continue;
273
274 snprintf(header, sizeof(header), "perf-profile-level-%d",
275 ctdp_level->level);
276 format_and_print(outf, base_level + 3, header, NULL);
277
278 snprintf(header, sizeof(header), "cpu-count");
279 j = get_cpu_count(get_physical_die_id(cpu),
280 get_physical_die_id(cpu));
281 snprintf(value, sizeof(value), "%d", j);
282 format_and_print(outf, base_level + 4, header, value);
283
284 snprintf(header, sizeof(header), "enable-cpu-mask");
285 printcpumask(sizeof(value), value,
286 ctdp_level->core_cpumask_size,
287 ctdp_level->core_cpumask);
288 format_and_print(outf, base_level + 4, header, value);
289
290 snprintf(header, sizeof(header), "thermal-design-power-ratio");
291 snprintf(value, sizeof(value), "%d", ctdp_level->tdp_ratio);
292 format_and_print(outf, base_level + 4, header, value);
293
294 snprintf(header, sizeof(header), "base-frequency(KHz)");
295 snprintf(value, sizeof(value), "%d",
296 ctdp_level->tdp_ratio * DISP_FREQ_MULTIPLIER);
297 format_and_print(outf, base_level + 4, header, value);
298
299 snprintf(header, sizeof(header),
300 "speed-select-turbo-freq-support");
301 snprintf(value, sizeof(value), "%d", ctdp_level->fact_support);
302 format_and_print(outf, base_level + 4, header, value);
303
304 snprintf(header, sizeof(header),
305 "speed-select-base-freq-support");
306 snprintf(value, sizeof(value), "%d", ctdp_level->pbf_support);
307 format_and_print(outf, base_level + 4, header, value);
308
309 snprintf(header, sizeof(header),
310 "speed-select-base-freq-enabled");
311 snprintf(value, sizeof(value), "%d", ctdp_level->pbf_enabled);
312 format_and_print(outf, base_level + 4, header, value);
313
314 snprintf(header, sizeof(header),
315 "speed-select-turbo-freq-enabled");
316 snprintf(value, sizeof(value), "%d", ctdp_level->fact_enabled);
317 format_and_print(outf, base_level + 4, header, value);
318
319 snprintf(header, sizeof(header), "thermal-design-power(W)");
320 snprintf(value, sizeof(value), "%d", ctdp_level->pkg_tdp);
321 format_and_print(outf, base_level + 4, header, value);
322
323 snprintf(header, sizeof(header), "tjunction-max(C)");
324 snprintf(value, sizeof(value), "%d", ctdp_level->t_proc_hot);
325 format_and_print(outf, base_level + 4, header, value);
326
327 snprintf(header, sizeof(header), "turbo-ratio-limits-sse");
328 format_and_print(outf, base_level + 4, header, NULL);
329 for (j = 0; j < 8; ++j) {
330 snprintf(header, sizeof(header), "bucket-%d", j);
331 format_and_print(outf, base_level + 5, header, NULL);
332
333 snprintf(header, sizeof(header), "core-count");
334 snprintf(value, sizeof(value), "%d", j);
335 format_and_print(outf, base_level + 6, header, value);
336
337 snprintf(header, sizeof(header), "turbo-ratio");
338 snprintf(value, sizeof(value), "%d",
339 ctdp_level->trl_sse_active_cores[j]);
340 format_and_print(outf, base_level + 6, header, value);
341 }
342 snprintf(header, sizeof(header), "turbo-ratio-limits-avx");
343 format_and_print(outf, base_level + 4, header, NULL);
344 for (j = 0; j < 8; ++j) {
345 snprintf(header, sizeof(header), "bucket-%d", j);
346 format_and_print(outf, base_level + 5, header, NULL);
347
348 snprintf(header, sizeof(header), "core-count");
349 snprintf(value, sizeof(value), "%d", j);
350 format_and_print(outf, base_level + 6, header, value);
351
352 snprintf(header, sizeof(header), "turbo-ratio");
353 snprintf(value, sizeof(value), "%d",
354 ctdp_level->trl_avx_active_cores[j]);
355 format_and_print(outf, base_level + 6, header, value);
356 }
357
358 snprintf(header, sizeof(header), "turbo-ratio-limits-avx512");
359 format_and_print(outf, base_level + 4, header, NULL);
360 for (j = 0; j < 8; ++j) {
361 snprintf(header, sizeof(header), "bucket-%d", j);
362 format_and_print(outf, base_level + 5, header, NULL);
363
364 snprintf(header, sizeof(header), "core-count");
365 snprintf(value, sizeof(value), "%d", j);
366 format_and_print(outf, base_level + 6, header, value);
367
368 snprintf(header, sizeof(header), "turbo-ratio");
369 snprintf(value, sizeof(value), "%d",
370 ctdp_level->trl_avx_512_active_cores[j]);
371 format_and_print(outf, base_level + 6, header, value);
372 }
373 if (ctdp_level->pbf_support)
374 _isst_pbf_display_information(cpu, outf, i,
375 &ctdp_level->pbf_info,
376 base_level + 4);
377 if (ctdp_level->fact_support)
378 _isst_fact_display_information(cpu, outf, i, 0xff, 0xff,
379 &ctdp_level->fact_info,
380 base_level + 4);
381 }
382
383 format_and_print(outf, 1, NULL, NULL);
384}
385
386void isst_ctdp_display_information_start(FILE *outf)
387{
388 last_level = 0;
389 format_and_print(outf, 0, "start", NULL);
390}
391
392void isst_ctdp_display_information_end(FILE *outf)
393{
394 format_and_print(outf, 0, NULL, NULL);
395}
396
397void isst_pbf_display_information(int cpu, FILE *outf, int level,
398 struct isst_pbf_info *pbf_info)
399{
400 print_packag_info(cpu, outf);
401 _isst_pbf_display_information(cpu, outf, level, pbf_info, 4);
402 format_and_print(outf, 1, NULL, NULL);
403}
404
405void isst_fact_display_information(int cpu, FILE *outf, int level,
406 int fact_bucket, int fact_avx,
407 struct isst_fact_info *fact_info)
408{
409 print_packag_info(cpu, outf);
410 _isst_fact_display_information(cpu, outf, level, fact_bucket, fact_avx,
411 fact_info, 4);
412 format_and_print(outf, 1, NULL, NULL);
413}
414
415void isst_clos_display_information(int cpu, FILE *outf, int clos,
416 struct isst_clos_config *clos_config)
417{
418 char header[256];
419 char value[256];
420
421 snprintf(header, sizeof(header), "package-%d",
422 get_physical_package_id(cpu));
423 format_and_print(outf, 1, header, NULL);
424 snprintf(header, sizeof(header), "die-%d", get_physical_die_id(cpu));
425 format_and_print(outf, 2, header, NULL);
426 snprintf(header, sizeof(header), "cpu-%d", cpu);
427 format_and_print(outf, 3, header, NULL);
428
429 snprintf(header, sizeof(header), "core-power");
430 format_and_print(outf, 4, header, NULL);
431
432 snprintf(header, sizeof(header), "clos");
433 snprintf(value, sizeof(value), "%d", clos);
434 format_and_print(outf, 5, header, value);
435
436 snprintf(header, sizeof(header), "epp");
437 snprintf(value, sizeof(value), "%d", clos_config->epp);
438 format_and_print(outf, 5, header, value);
439
440 snprintf(header, sizeof(header), "clos-proportional-priority");
441 snprintf(value, sizeof(value), "%d", clos_config->clos_prop_prio);
442 format_and_print(outf, 5, header, value);
443
444 snprintf(header, sizeof(header), "clos-min");
445 snprintf(value, sizeof(value), "%d", clos_config->clos_min);
446 format_and_print(outf, 5, header, value);
447
448 snprintf(header, sizeof(header), "clos-max");
449 snprintf(value, sizeof(value), "%d", clos_config->clos_max);
450 format_and_print(outf, 5, header, value);
451
452 snprintf(header, sizeof(header), "clos-desired");
453 snprintf(value, sizeof(value), "%d", clos_config->clos_desired);
454 format_and_print(outf, 5, header, value);
455
456 format_and_print(outf, 1, NULL, NULL);
457}
458
459void isst_display_result(int cpu, FILE *outf, char *feature, char *cmd,
460 int result)
461{
462 char header[256];
463 char value[256];
464
465 snprintf(header, sizeof(header), "package-%d",
466 get_physical_package_id(cpu));
467 format_and_print(outf, 1, header, NULL);
468 snprintf(header, sizeof(header), "die-%d", get_physical_die_id(cpu));
469 format_and_print(outf, 2, header, NULL);
470 snprintf(header, sizeof(header), "cpu-%d", cpu);
471 format_and_print(outf, 3, header, NULL);
472 snprintf(header, sizeof(header), "%s", feature);
473 format_and_print(outf, 4, header, NULL);
474 snprintf(header, sizeof(header), "%s", cmd);
475 snprintf(value, sizeof(value), "%d", result);
476 format_and_print(outf, 5, header, value);
477
478 format_and_print(outf, 1, NULL, NULL);
479}
diff --git a/tools/power/x86/intel-speed-select/isst.h b/tools/power/x86/intel-speed-select/isst.h
new file mode 100644
index 000000000000..221881761609
--- /dev/null
+++ b/tools/power/x86/intel-speed-select/isst.h
@@ -0,0 +1,231 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * Intel Speed Select -- Enumerate and control features
4 * Copyright (c) 2019 Intel Corporation.
5 */
6
7#ifndef _ISST_H_
8#define _ISST_H_
9
10#include <stdio.h>
11#include <unistd.h>
12#include <sys/types.h>
13#include <sched.h>
14#include <sys/stat.h>
15#include <sys/resource.h>
16#include <getopt.h>
17#include <err.h>
18#include <fcntl.h>
19#include <signal.h>
20#include <sys/time.h>
21#include <limits.h>
22#include <stdlib.h>
23#include <string.h>
24#include <cpuid.h>
25#include <dirent.h>
26#include <errno.h>
27
28#include <stdarg.h>
29#include <sys/ioctl.h>
30
31#define BIT(x) (1 << (x))
32#define GENMASK(h, l) (((~0UL) << (l)) & (~0UL >> (sizeof(long) * 8 - 1 - (h))))
33#define GENMASK_ULL(h, l) \
34 (((~0ULL) << (l)) & (~0ULL >> (sizeof(long long) * 8 - 1 - (h))))
35
36#define CONFIG_TDP 0x7f
37#define CONFIG_TDP_GET_LEVELS_INFO 0x00
38#define CONFIG_TDP_GET_TDP_CONTROL 0x01
39#define CONFIG_TDP_SET_TDP_CONTROL 0x02
40#define CONFIG_TDP_GET_TDP_INFO 0x03
41#define CONFIG_TDP_GET_PWR_INFO 0x04
42#define CONFIG_TDP_GET_TJMAX_INFO 0x05
43#define CONFIG_TDP_GET_CORE_MASK 0x06
44#define CONFIG_TDP_GET_TURBO_LIMIT_RATIOS 0x07
45#define CONFIG_TDP_SET_LEVEL 0x08
46#define CONFIG_TDP_GET_UNCORE_P0_P1_INFO 0X09
47#define CONFIG_TDP_GET_P1_INFO 0x0a
48#define CONFIG_TDP_GET_MEM_FREQ 0x0b
49
50#define CONFIG_TDP_GET_FACT_HP_TURBO_LIMIT_NUMCORES 0x10
51#define CONFIG_TDP_GET_FACT_HP_TURBO_LIMIT_RATIOS 0x11
52#define CONFIG_TDP_GET_FACT_LP_CLIPPING_RATIO 0x12
53
54#define CONFIG_TDP_PBF_GET_CORE_MASK_INFO 0x20
55#define CONFIG_TDP_PBF_GET_P1HI_P1LO_INFO 0x21
56#define CONFIG_TDP_PBF_GET_TJ_MAX_INFO 0x22
57#define CONFIG_TDP_PBF_GET_TDP_INFO 0X23
58
59#define CONFIG_CLOS 0xd0
60#define CLOS_PQR_ASSOC 0x00
61#define CLOS_PM_CLOS 0x01
62#define CLOS_PM_QOS_CONFIG 0x02
63#define CLOS_STATUS 0x03
64
65#define MBOX_CMD_WRITE_BIT 0x08
66
67#define PM_QOS_INFO_OFFSET 0x00
68#define PM_QOS_CONFIG_OFFSET 0x04
69#define PM_CLOS_OFFSET 0x08
70#define PQR_ASSOC_OFFSET 0x20
71
72struct isst_clos_config {
73 int pkg_id;
74 int die_id;
75 unsigned char epp;
76 unsigned char clos_prop_prio;
77 unsigned char clos_min;
78 unsigned char clos_max;
79 unsigned char clos_desired;
80};
81
82struct isst_fact_bucket_info {
83 int high_priority_cores_count;
84 int sse_trl;
85 int avx_trl;
86 int avx512_trl;
87};
88
89struct isst_pbf_info {
90 int pbf_acticated;
91 int pbf_available;
92 size_t core_cpumask_size;
93 cpu_set_t *core_cpumask;
94 int p1_high;
95 int p1_low;
96 int t_control;
97 int t_prochot;
98 int tdp;
99};
100
101#define ISST_TRL_MAX_ACTIVE_CORES 8
102#define ISST_FACT_MAX_BUCKETS 8
103struct isst_fact_info {
104 int lp_clipping_ratio_license_sse;
105 int lp_clipping_ratio_license_avx2;
106 int lp_clipping_ratio_license_avx512;
107 struct isst_fact_bucket_info bucket_info[ISST_FACT_MAX_BUCKETS];
108};
109
110struct isst_pkg_ctdp_level_info {
111 int processed;
112 int control_cpu;
113 int pkg_id;
114 int die_id;
115 int level;
116 int fact_support;
117 int pbf_support;
118 int fact_enabled;
119 int pbf_enabled;
120 int tdp_ratio;
121 int active;
122 int tdp_control;
123 int pkg_tdp;
124 int pkg_min_power;
125 int pkg_max_power;
126 int fact;
127 int t_proc_hot;
128 int uncore_p0;
129 int uncore_p1;
130 int sse_p1;
131 int avx2_p1;
132 int avx512_p1;
133 int mem_freq;
134 size_t core_cpumask_size;
135 cpu_set_t *core_cpumask;
136 int cpu_count;
137 int trl_sse_active_cores[ISST_TRL_MAX_ACTIVE_CORES];
138 int trl_avx_active_cores[ISST_TRL_MAX_ACTIVE_CORES];
139 int trl_avx_512_active_cores[ISST_TRL_MAX_ACTIVE_CORES];
140 int kobj_bucket_index;
141 int active_bucket;
142 int fact_max_index;
143 int fact_max_config;
144 int pbf_found;
145 int pbf_active;
146 struct isst_pbf_info pbf_info;
147 struct isst_fact_info fact_info;
148};
149
150#define ISST_MAX_TDP_LEVELS (4 + 1) /* +1 for base config */
151struct isst_pkg_ctdp {
152 int locked;
153 int version;
154 int processed;
155 int levels;
156 int current_level;
157 int enabled;
158 struct isst_pkg_ctdp_level_info ctdp_level[ISST_MAX_TDP_LEVELS];
159};
160
161extern int get_topo_max_cpus(void);
162extern int get_cpu_count(int pkg_id, int die_id);
163
164/* Common interfaces */
165extern void debug_printf(const char *format, ...);
166extern int out_format_is_json(void);
167extern int get_physical_package_id(int cpu);
168extern int get_physical_die_id(int cpu);
169extern size_t alloc_cpu_set(cpu_set_t **cpu_set);
170extern void free_cpu_set(cpu_set_t *cpu_set);
171extern int find_logical_cpu(int pkg_id, int die_id, int phy_cpu);
172extern int find_phy_cpu_num(int logical_cpu);
173extern int find_phy_core_num(int logical_cpu);
174extern void set_cpu_mask_from_punit_coremask(int cpu,
175 unsigned long long core_mask,
176 size_t core_cpumask_size,
177 cpu_set_t *core_cpumask,
178 int *cpu_cnt);
179
180extern int isst_send_mbox_command(unsigned int cpu, unsigned char command,
181 unsigned char sub_command,
182 unsigned int write,
183 unsigned int req_data, unsigned int *resp);
184
185extern int isst_send_msr_command(unsigned int cpu, unsigned int command,
186 int write, unsigned long long *req_resp);
187
188extern int isst_get_ctdp_levels(int cpu, struct isst_pkg_ctdp *pkg_dev);
189extern int isst_get_process_ctdp(int cpu, int tdp_level,
190 struct isst_pkg_ctdp *pkg_dev);
191extern void isst_get_process_ctdp_complete(int cpu,
192 struct isst_pkg_ctdp *pkg_dev);
193extern void isst_ctdp_display_information(int cpu, FILE *outf, int tdp_level,
194 struct isst_pkg_ctdp *pkg_dev);
195extern void isst_ctdp_display_information_start(FILE *outf);
196extern void isst_ctdp_display_information_end(FILE *outf);
197extern void isst_pbf_display_information(int cpu, FILE *outf, int level,
198 struct isst_pbf_info *info);
199extern int isst_set_tdp_level(int cpu, int tdp_level);
200extern int isst_set_tdp_level_msr(int cpu, int tdp_level);
201extern int isst_set_pbf_fact_status(int cpu, int pbf, int enable);
202extern int isst_get_pbf_info(int cpu, int level,
203 struct isst_pbf_info *pbf_info);
204extern void isst_get_pbf_info_complete(struct isst_pbf_info *pbf_info);
205extern int isst_get_fact_info(int cpu, int level,
206 struct isst_fact_info *fact_info);
207extern int isst_get_fact_bucket_info(int cpu, int level,
208 struct isst_fact_bucket_info *bucket_info);
209extern void isst_fact_display_information(int cpu, FILE *outf, int level,
210 int fact_bucket, int fact_avx,
211 struct isst_fact_info *fact_info);
212extern int isst_set_trl(int cpu, unsigned long long trl);
213extern int isst_set_trl_from_current_tdp(int cpu, unsigned long long trl);
214extern int isst_get_config_tdp_lock_status(int cpu);
215
216extern int isst_pm_qos_config(int cpu, int enable_clos, int priority_type);
217extern int isst_pm_get_clos(int cpu, int clos,
218 struct isst_clos_config *clos_config);
219extern int isst_set_clos(int cpu, int clos,
220 struct isst_clos_config *clos_config);
221extern int isst_clos_associate(int cpu, int clos);
222extern int isst_clos_get_assoc_status(int cpu, int *clos_id);
223extern void isst_clos_display_information(int cpu, FILE *outf, int clos,
224 struct isst_clos_config *clos_config);
225
226extern int isst_read_reg(unsigned short reg, unsigned int *val);
227extern int isst_write_reg(int reg, unsigned int val);
228
229extern void isst_display_result(int cpu, FILE *outf, char *feature, char *cmd,
230 int result);
231#endif
diff --git a/tools/testing/nvdimm/test/iomap.c b/tools/testing/nvdimm/test/iomap.c
index 076df22e4bda..cd040b5abffe 100644
--- a/tools/testing/nvdimm/test/iomap.c
+++ b/tools/testing/nvdimm/test/iomap.c
@@ -100,25 +100,60 @@ static void nfit_test_kill(void *_pgmap)
100{ 100{
101 struct dev_pagemap *pgmap = _pgmap; 101 struct dev_pagemap *pgmap = _pgmap;
102 102
103 WARN_ON(!pgmap || !pgmap->ref || !pgmap->kill || !pgmap->cleanup); 103 WARN_ON(!pgmap || !pgmap->ref);
104 pgmap->kill(pgmap->ref); 104
105 pgmap->cleanup(pgmap->ref); 105 if (pgmap->ops && pgmap->ops->kill)
106 pgmap->ops->kill(pgmap);
107 else
108 percpu_ref_kill(pgmap->ref);
109
110 if (pgmap->ops && pgmap->ops->cleanup) {
111 pgmap->ops->cleanup(pgmap);
112 } else {
113 wait_for_completion(&pgmap->done);
114 percpu_ref_exit(pgmap->ref);
115 }
116}
117
118static void dev_pagemap_percpu_release(struct percpu_ref *ref)
119{
120 struct dev_pagemap *pgmap =
121 container_of(ref, struct dev_pagemap, internal_ref);
122
123 complete(&pgmap->done);
106} 124}
107 125
108void *__wrap_devm_memremap_pages(struct device *dev, struct dev_pagemap *pgmap) 126void *__wrap_devm_memremap_pages(struct device *dev, struct dev_pagemap *pgmap)
109{ 127{
128 int error;
110 resource_size_t offset = pgmap->res.start; 129 resource_size_t offset = pgmap->res.start;
111 struct nfit_test_resource *nfit_res = get_nfit_res(offset); 130 struct nfit_test_resource *nfit_res = get_nfit_res(offset);
112 131
113 if (nfit_res) { 132 if (!nfit_res)
114 int rc; 133 return devm_memremap_pages(dev, pgmap);
115 134
116 rc = devm_add_action_or_reset(dev, nfit_test_kill, pgmap); 135 pgmap->dev = dev;
117 if (rc) 136 if (!pgmap->ref) {
118 return ERR_PTR(rc); 137 if (pgmap->ops && (pgmap->ops->kill || pgmap->ops->cleanup))
119 return nfit_res->buf + offset - nfit_res->res.start; 138 return ERR_PTR(-EINVAL);
139
140 init_completion(&pgmap->done);
141 error = percpu_ref_init(&pgmap->internal_ref,
142 dev_pagemap_percpu_release, 0, GFP_KERNEL);
143 if (error)
144 return ERR_PTR(error);
145 pgmap->ref = &pgmap->internal_ref;
146 } else {
147 if (!pgmap->ops || !pgmap->ops->kill || !pgmap->ops->cleanup) {
148 WARN(1, "Missing reference count teardown definition\n");
149 return ERR_PTR(-EINVAL);
150 }
120 } 151 }
121 return devm_memremap_pages(dev, pgmap); 152
153 error = devm_add_action_or_reset(dev, nfit_test_kill, pgmap);
154 if (error)
155 return ERR_PTR(error);
156 return nfit_res->buf + offset - nfit_res->res.start;
122} 157}
123EXPORT_SYMBOL_GPL(__wrap_devm_memremap_pages); 158EXPORT_SYMBOL_GPL(__wrap_devm_memremap_pages);
124 159
diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile
index 2620406a53ec..11c9c62c3362 100644
--- a/tools/testing/selftests/bpf/Makefile
+++ b/tools/testing/selftests/bpf/Makefile
@@ -1,4 +1,6 @@
1# SPDX-License-Identifier: GPL-2.0 1# SPDX-License-Identifier: GPL-2.0
2include ../../../../scripts/Kbuild.include
3include ../../../scripts/Makefile.arch
2 4
3LIBDIR := ../../../lib 5LIBDIR := ../../../lib
4BPFDIR := $(LIBDIR)/bpf 6BPFDIR := $(LIBDIR)/bpf
@@ -81,13 +83,14 @@ all: $(TEST_CUSTOM_PROGS)
81$(OUTPUT)/urandom_read: $(OUTPUT)/%: %.c 83$(OUTPUT)/urandom_read: $(OUTPUT)/%: %.c
82 $(CC) -o $@ $< -Wl,--build-id 84 $(CC) -o $@ $< -Wl,--build-id
83 85
84$(OUTPUT)/test_maps: map_tests/*.c 86$(OUTPUT)/test_stub.o: test_stub.c
87 $(CC) $(TEST_PROGS_CFLAGS) $(CFLAGS) -c -o $@ $<
85 88
86BPFOBJ := $(OUTPUT)/libbpf.a 89BPFOBJ := $(OUTPUT)/libbpf.a
87 90
88$(TEST_GEN_PROGS): test_stub.o $(BPFOBJ) 91$(TEST_GEN_PROGS): $(OUTPUT)/test_stub.o $(BPFOBJ)
89 92
90$(TEST_GEN_PROGS_EXTENDED): test_stub.o $(OUTPUT)/libbpf.a 93$(TEST_GEN_PROGS_EXTENDED): $(OUTPUT)/test_stub.o $(OUTPUT)/libbpf.a
91 94
92$(OUTPUT)/test_dev_cgroup: cgroup_helpers.c 95$(OUTPUT)/test_dev_cgroup: cgroup_helpers.c
93$(OUTPUT)/test_skb_cgroup_id_user: cgroup_helpers.c 96$(OUTPUT)/test_skb_cgroup_id_user: cgroup_helpers.c
@@ -138,7 +141,8 @@ CLANG_SYS_INCLUDES := $(shell $(CLANG) -v -E - </dev/null 2>&1 \
138 141
139CLANG_FLAGS = -I. -I./include/uapi -I../../../include/uapi \ 142CLANG_FLAGS = -I. -I./include/uapi -I../../../include/uapi \
140 $(CLANG_SYS_INCLUDES) \ 143 $(CLANG_SYS_INCLUDES) \
141 -Wno-compare-distinct-pointer-types 144 -Wno-compare-distinct-pointer-types \
145 -D__TARGET_ARCH_$(SRCARCH)
142 146
143$(OUTPUT)/test_l4lb_noinline.o: CLANG_FLAGS += -fno-inline 147$(OUTPUT)/test_l4lb_noinline.o: CLANG_FLAGS += -fno-inline
144$(OUTPUT)/test_xdp_noinline.o: CLANG_FLAGS += -fno-inline 148$(OUTPUT)/test_xdp_noinline.o: CLANG_FLAGS += -fno-inline
@@ -172,6 +176,7 @@ endif
172endif 176endif
173 177
174TEST_PROGS_CFLAGS := -I. -I$(OUTPUT) 178TEST_PROGS_CFLAGS := -I. -I$(OUTPUT)
179TEST_MAPS_CFLAGS := -I. -I$(OUTPUT)
175TEST_VERIFIER_CFLAGS := -I. -I$(OUTPUT) -Iverifier 180TEST_VERIFIER_CFLAGS := -I. -I$(OUTPUT) -Iverifier
176 181
177ifneq ($(SUBREG_CODEGEN),) 182ifneq ($(SUBREG_CODEGEN),)
@@ -180,12 +185,12 @@ TEST_CUSTOM_PROGS += $(ALU32_BUILD_DIR)/test_progs_32
180$(ALU32_BUILD_DIR): 185$(ALU32_BUILD_DIR):
181 mkdir -p $@ 186 mkdir -p $@
182 187
183$(ALU32_BUILD_DIR)/urandom_read: $(OUTPUT)/urandom_read 188$(ALU32_BUILD_DIR)/urandom_read: $(OUTPUT)/urandom_read | $(ALU32_BUILD_DIR)
184 cp $< $@ 189 cp $< $@
185 190
186$(ALU32_BUILD_DIR)/test_progs_32: test_progs.c $(OUTPUT)/libbpf.a\ 191$(ALU32_BUILD_DIR)/test_progs_32: test_progs.c $(OUTPUT)/libbpf.a\
187 $(ALU32_BUILD_DIR) \ 192 $(ALU32_BUILD_DIR)/urandom_read \
188 $(ALU32_BUILD_DIR)/urandom_read 193 | $(ALU32_BUILD_DIR)
189 $(CC) $(TEST_PROGS_CFLAGS) $(CFLAGS) \ 194 $(CC) $(TEST_PROGS_CFLAGS) $(CFLAGS) \
190 -o $(ALU32_BUILD_DIR)/test_progs_32 \ 195 -o $(ALU32_BUILD_DIR)/test_progs_32 \
191 test_progs.c test_stub.c trace_helpers.c prog_tests/*.c \ 196 test_progs.c test_stub.c trace_helpers.c prog_tests/*.c \
@@ -194,10 +199,10 @@ $(ALU32_BUILD_DIR)/test_progs_32: test_progs.c $(OUTPUT)/libbpf.a\
194$(ALU32_BUILD_DIR)/test_progs_32: $(PROG_TESTS_H) 199$(ALU32_BUILD_DIR)/test_progs_32: $(PROG_TESTS_H)
195$(ALU32_BUILD_DIR)/test_progs_32: prog_tests/*.c 200$(ALU32_BUILD_DIR)/test_progs_32: prog_tests/*.c
196 201
197$(ALU32_BUILD_DIR)/%.o: progs/%.c $(ALU32_BUILD_DIR) \ 202$(ALU32_BUILD_DIR)/%.o: progs/%.c $(ALU32_BUILD_DIR)/test_progs_32 \
198 $(ALU32_BUILD_DIR)/test_progs_32 203 | $(ALU32_BUILD_DIR)
199 $(CLANG) $(CLANG_FLAGS) \ 204 ($(CLANG) $(CLANG_FLAGS) -O2 -target bpf -emit-llvm -c $< -o - || \
200 -O2 -target bpf -emit-llvm -c $< -o - | \ 205 echo "clang failed") | \
201 $(LLC) -march=bpf -mattr=+alu32 -mcpu=$(CPU) $(LLC_FLAGS) \ 206 $(LLC) -march=bpf -mattr=+alu32 -mcpu=$(CPU) $(LLC_FLAGS) \
202 -filetype=obj -o $@ 207 -filetype=obj -o $@
203ifeq ($(DWARF2BTF),y) 208ifeq ($(DWARF2BTF),y)
@@ -208,32 +213,30 @@ endif
208# Have one program compiled without "-target bpf" to test whether libbpf loads 213# Have one program compiled without "-target bpf" to test whether libbpf loads
209# it successfully 214# it successfully
210$(OUTPUT)/test_xdp.o: progs/test_xdp.c 215$(OUTPUT)/test_xdp.o: progs/test_xdp.c
211 $(CLANG) $(CLANG_FLAGS) \ 216 ($(CLANG) $(CLANG_FLAGS) -O2 -emit-llvm -c $< -o - || \
212 -O2 -emit-llvm -c $< -o - | \ 217 echo "clang failed") | \
213 $(LLC) -march=bpf -mcpu=$(CPU) $(LLC_FLAGS) -filetype=obj -o $@ 218 $(LLC) -march=bpf -mcpu=$(CPU) $(LLC_FLAGS) -filetype=obj -o $@
214ifeq ($(DWARF2BTF),y) 219ifeq ($(DWARF2BTF),y)
215 $(BTF_PAHOLE) -J $@ 220 $(BTF_PAHOLE) -J $@
216endif 221endif
217 222
218$(OUTPUT)/%.o: progs/%.c 223$(OUTPUT)/%.o: progs/%.c
219 $(CLANG) $(CLANG_FLAGS) \ 224 ($(CLANG) $(CLANG_FLAGS) -O2 -target bpf -emit-llvm -c $< -o - || \
220 -O2 -target bpf -emit-llvm -c $< -o - | \ 225 echo "clang failed") | \
221 $(LLC) -march=bpf -mcpu=$(CPU) $(LLC_FLAGS) -filetype=obj -o $@ 226 $(LLC) -march=bpf -mcpu=$(CPU) $(LLC_FLAGS) -filetype=obj -o $@
222ifeq ($(DWARF2BTF),y) 227ifeq ($(DWARF2BTF),y)
223 $(BTF_PAHOLE) -J $@ 228 $(BTF_PAHOLE) -J $@
224endif 229endif
225 230
226PROG_TESTS_H := $(OUTPUT)/prog_tests/tests.h
227test_progs.c: $(PROG_TESTS_H)
228$(OUTPUT)/test_progs: CFLAGS += $(TEST_PROGS_CFLAGS)
229$(OUTPUT)/test_progs: prog_tests/*.c
230
231PROG_TESTS_DIR = $(OUTPUT)/prog_tests 231PROG_TESTS_DIR = $(OUTPUT)/prog_tests
232$(PROG_TESTS_DIR): 232$(PROG_TESTS_DIR):
233 mkdir -p $@ 233 mkdir -p $@
234 234PROG_TESTS_H := $(PROG_TESTS_DIR)/tests.h
235PROG_TESTS_FILES := $(wildcard prog_tests/*.c) 235PROG_TESTS_FILES := $(wildcard prog_tests/*.c)
236$(PROG_TESTS_H): $(PROG_TESTS_DIR) $(PROG_TESTS_FILES) 236test_progs.c: $(PROG_TESTS_H)
237$(OUTPUT)/test_progs: CFLAGS += $(TEST_PROGS_CFLAGS)
238$(OUTPUT)/test_progs: test_progs.c $(PROG_TESTS_H) $(PROG_TESTS_FILES)
239$(PROG_TESTS_H): $(PROG_TESTS_FILES) | $(PROG_TESTS_DIR)
237 $(shell ( cd prog_tests/; \ 240 $(shell ( cd prog_tests/; \
238 echo '/* Generated header, do not edit */'; \ 241 echo '/* Generated header, do not edit */'; \
239 echo '#ifdef DECLARE'; \ 242 echo '#ifdef DECLARE'; \
@@ -246,15 +249,15 @@ $(PROG_TESTS_H): $(PROG_TESTS_DIR) $(PROG_TESTS_FILES)
246 echo '#endif' \ 249 echo '#endif' \
247 ) > $(PROG_TESTS_H)) 250 ) > $(PROG_TESTS_H))
248 251
249TEST_MAPS_CFLAGS := -I. -I$(OUTPUT)
250MAP_TESTS_DIR = $(OUTPUT)/map_tests 252MAP_TESTS_DIR = $(OUTPUT)/map_tests
251$(MAP_TESTS_DIR): 253$(MAP_TESTS_DIR):
252 mkdir -p $@ 254 mkdir -p $@
253MAP_TESTS_H := $(MAP_TESTS_DIR)/tests.h 255MAP_TESTS_H := $(MAP_TESTS_DIR)/tests.h
256MAP_TESTS_FILES := $(wildcard map_tests/*.c)
254test_maps.c: $(MAP_TESTS_H) 257test_maps.c: $(MAP_TESTS_H)
255$(OUTPUT)/test_maps: CFLAGS += $(TEST_MAPS_CFLAGS) 258$(OUTPUT)/test_maps: CFLAGS += $(TEST_MAPS_CFLAGS)
256MAP_TESTS_FILES := $(wildcard map_tests/*.c) 259$(OUTPUT)/test_maps: test_maps.c $(MAP_TESTS_H) $(MAP_TESTS_FILES)
257$(MAP_TESTS_H): $(MAP_TESTS_DIR) $(MAP_TESTS_FILES) 260$(MAP_TESTS_H): $(MAP_TESTS_FILES) | $(MAP_TESTS_DIR)
258 $(shell ( cd map_tests/; \ 261 $(shell ( cd map_tests/; \
259 echo '/* Generated header, do not edit */'; \ 262 echo '/* Generated header, do not edit */'; \
260 echo '#ifdef DECLARE'; \ 263 echo '#ifdef DECLARE'; \
@@ -267,16 +270,15 @@ $(MAP_TESTS_H): $(MAP_TESTS_DIR) $(MAP_TESTS_FILES)
267 echo '#endif' \ 270 echo '#endif' \
268 ) > $(MAP_TESTS_H)) 271 ) > $(MAP_TESTS_H))
269 272
270VERIFIER_TESTS_H := $(OUTPUT)/verifier/tests.h
271test_verifier.c: $(VERIFIER_TESTS_H)
272$(OUTPUT)/test_verifier: CFLAGS += $(TEST_VERIFIER_CFLAGS)
273
274VERIFIER_TESTS_DIR = $(OUTPUT)/verifier 273VERIFIER_TESTS_DIR = $(OUTPUT)/verifier
275$(VERIFIER_TESTS_DIR): 274$(VERIFIER_TESTS_DIR):
276 mkdir -p $@ 275 mkdir -p $@
277 276VERIFIER_TESTS_H := $(VERIFIER_TESTS_DIR)/tests.h
278VERIFIER_TEST_FILES := $(wildcard verifier/*.c) 277VERIFIER_TEST_FILES := $(wildcard verifier/*.c)
279$(OUTPUT)/verifier/tests.h: $(VERIFIER_TESTS_DIR) $(VERIFIER_TEST_FILES) 278test_verifier.c: $(VERIFIER_TESTS_H)
279$(OUTPUT)/test_verifier: CFLAGS += $(TEST_VERIFIER_CFLAGS)
280$(OUTPUT)/test_verifier: test_verifier.c $(VERIFIER_TESTS_H)
281$(VERIFIER_TESTS_H): $(VERIFIER_TEST_FILES) | $(VERIFIER_TESTS_DIR)
280 $(shell ( cd verifier/; \ 282 $(shell ( cd verifier/; \
281 echo '/* Generated header, do not edit */'; \ 283 echo '/* Generated header, do not edit */'; \
282 echo '#ifdef FILL_ARRAY'; \ 284 echo '#ifdef FILL_ARRAY'; \
diff --git a/tools/testing/selftests/bpf/bpf_helpers.h b/tools/testing/selftests/bpf/bpf_helpers.h
index 5a3d92c8bec8..f804f210244e 100644
--- a/tools/testing/selftests/bpf/bpf_helpers.h
+++ b/tools/testing/selftests/bpf/bpf_helpers.h
@@ -315,8 +315,8 @@ static int (*bpf_skb_adjust_room)(void *ctx, __s32 len_diff, __u32 mode,
315#if defined(__TARGET_ARCH_x86) 315#if defined(__TARGET_ARCH_x86)
316 #define bpf_target_x86 316 #define bpf_target_x86
317 #define bpf_target_defined 317 #define bpf_target_defined
318#elif defined(__TARGET_ARCH_s930x) 318#elif defined(__TARGET_ARCH_s390)
319 #define bpf_target_s930x 319 #define bpf_target_s390
320 #define bpf_target_defined 320 #define bpf_target_defined
321#elif defined(__TARGET_ARCH_arm) 321#elif defined(__TARGET_ARCH_arm)
322 #define bpf_target_arm 322 #define bpf_target_arm
@@ -341,8 +341,8 @@ static int (*bpf_skb_adjust_room)(void *ctx, __s32 len_diff, __u32 mode,
341#ifndef bpf_target_defined 341#ifndef bpf_target_defined
342#if defined(__x86_64__) 342#if defined(__x86_64__)
343 #define bpf_target_x86 343 #define bpf_target_x86
344#elif defined(__s390x__) 344#elif defined(__s390__)
345 #define bpf_target_s930x 345 #define bpf_target_s390
346#elif defined(__arm__) 346#elif defined(__arm__)
347 #define bpf_target_arm 347 #define bpf_target_arm
348#elif defined(__aarch64__) 348#elif defined(__aarch64__)
@@ -358,6 +358,7 @@ static int (*bpf_skb_adjust_room)(void *ctx, __s32 len_diff, __u32 mode,
358 358
359#if defined(bpf_target_x86) 359#if defined(bpf_target_x86)
360 360
361#ifdef __KERNEL__
361#define PT_REGS_PARM1(x) ((x)->di) 362#define PT_REGS_PARM1(x) ((x)->di)
362#define PT_REGS_PARM2(x) ((x)->si) 363#define PT_REGS_PARM2(x) ((x)->si)
363#define PT_REGS_PARM3(x) ((x)->dx) 364#define PT_REGS_PARM3(x) ((x)->dx)
@@ -368,19 +369,49 @@ static int (*bpf_skb_adjust_room)(void *ctx, __s32 len_diff, __u32 mode,
368#define PT_REGS_RC(x) ((x)->ax) 369#define PT_REGS_RC(x) ((x)->ax)
369#define PT_REGS_SP(x) ((x)->sp) 370#define PT_REGS_SP(x) ((x)->sp)
370#define PT_REGS_IP(x) ((x)->ip) 371#define PT_REGS_IP(x) ((x)->ip)
372#else
373#ifdef __i386__
374/* i386 kernel is built with -mregparm=3 */
375#define PT_REGS_PARM1(x) ((x)->eax)
376#define PT_REGS_PARM2(x) ((x)->edx)
377#define PT_REGS_PARM3(x) ((x)->ecx)
378#define PT_REGS_PARM4(x) 0
379#define PT_REGS_PARM5(x) 0
380#define PT_REGS_RET(x) ((x)->esp)
381#define PT_REGS_FP(x) ((x)->ebp)
382#define PT_REGS_RC(x) ((x)->eax)
383#define PT_REGS_SP(x) ((x)->esp)
384#define PT_REGS_IP(x) ((x)->eip)
385#else
386#define PT_REGS_PARM1(x) ((x)->rdi)
387#define PT_REGS_PARM2(x) ((x)->rsi)
388#define PT_REGS_PARM3(x) ((x)->rdx)
389#define PT_REGS_PARM4(x) ((x)->rcx)
390#define PT_REGS_PARM5(x) ((x)->r8)
391#define PT_REGS_RET(x) ((x)->rsp)
392#define PT_REGS_FP(x) ((x)->rbp)
393#define PT_REGS_RC(x) ((x)->rax)
394#define PT_REGS_SP(x) ((x)->rsp)
395#define PT_REGS_IP(x) ((x)->rip)
396#endif
397#endif
371 398
372#elif defined(bpf_target_s390x) 399#elif defined(bpf_target_s390)
373 400
374#define PT_REGS_PARM1(x) ((x)->gprs[2]) 401/* s390 provides user_pt_regs instead of struct pt_regs to userspace */
375#define PT_REGS_PARM2(x) ((x)->gprs[3]) 402struct pt_regs;
376#define PT_REGS_PARM3(x) ((x)->gprs[4]) 403#define PT_REGS_S390 const volatile user_pt_regs
377#define PT_REGS_PARM4(x) ((x)->gprs[5]) 404#define PT_REGS_PARM1(x) (((PT_REGS_S390 *)(x))->gprs[2])
378#define PT_REGS_PARM5(x) ((x)->gprs[6]) 405#define PT_REGS_PARM2(x) (((PT_REGS_S390 *)(x))->gprs[3])
379#define PT_REGS_RET(x) ((x)->gprs[14]) 406#define PT_REGS_PARM3(x) (((PT_REGS_S390 *)(x))->gprs[4])
380#define PT_REGS_FP(x) ((x)->gprs[11]) /* Works only with CONFIG_FRAME_POINTER */ 407#define PT_REGS_PARM4(x) (((PT_REGS_S390 *)(x))->gprs[5])
381#define PT_REGS_RC(x) ((x)->gprs[2]) 408#define PT_REGS_PARM5(x) (((PT_REGS_S390 *)(x))->gprs[6])
382#define PT_REGS_SP(x) ((x)->gprs[15]) 409#define PT_REGS_RET(x) (((PT_REGS_S390 *)(x))->gprs[14])
383#define PT_REGS_IP(x) ((x)->psw.addr) 410/* Works only with CONFIG_FRAME_POINTER */
411#define PT_REGS_FP(x) (((PT_REGS_S390 *)(x))->gprs[11])
412#define PT_REGS_RC(x) (((PT_REGS_S390 *)(x))->gprs[2])
413#define PT_REGS_SP(x) (((PT_REGS_S390 *)(x))->gprs[15])
414#define PT_REGS_IP(x) (((PT_REGS_S390 *)(x))->psw.addr)
384 415
385#elif defined(bpf_target_arm) 416#elif defined(bpf_target_arm)
386 417
@@ -397,16 +428,20 @@ static int (*bpf_skb_adjust_room)(void *ctx, __s32 len_diff, __u32 mode,
397 428
398#elif defined(bpf_target_arm64) 429#elif defined(bpf_target_arm64)
399 430
400#define PT_REGS_PARM1(x) ((x)->regs[0]) 431/* arm64 provides struct user_pt_regs instead of struct pt_regs to userspace */
401#define PT_REGS_PARM2(x) ((x)->regs[1]) 432struct pt_regs;
402#define PT_REGS_PARM3(x) ((x)->regs[2]) 433#define PT_REGS_ARM64 const volatile struct user_pt_regs
403#define PT_REGS_PARM4(x) ((x)->regs[3]) 434#define PT_REGS_PARM1(x) (((PT_REGS_ARM64 *)(x))->regs[0])
404#define PT_REGS_PARM5(x) ((x)->regs[4]) 435#define PT_REGS_PARM2(x) (((PT_REGS_ARM64 *)(x))->regs[1])
405#define PT_REGS_RET(x) ((x)->regs[30]) 436#define PT_REGS_PARM3(x) (((PT_REGS_ARM64 *)(x))->regs[2])
406#define PT_REGS_FP(x) ((x)->regs[29]) /* Works only with CONFIG_FRAME_POINTER */ 437#define PT_REGS_PARM4(x) (((PT_REGS_ARM64 *)(x))->regs[3])
407#define PT_REGS_RC(x) ((x)->regs[0]) 438#define PT_REGS_PARM5(x) (((PT_REGS_ARM64 *)(x))->regs[4])
408#define PT_REGS_SP(x) ((x)->sp) 439#define PT_REGS_RET(x) (((PT_REGS_ARM64 *)(x))->regs[30])
409#define PT_REGS_IP(x) ((x)->pc) 440/* Works only with CONFIG_FRAME_POINTER */
441#define PT_REGS_FP(x) (((PT_REGS_ARM64 *)(x))->regs[29])
442#define PT_REGS_RC(x) (((PT_REGS_ARM64 *)(x))->regs[0])
443#define PT_REGS_SP(x) (((PT_REGS_ARM64 *)(x))->sp)
444#define PT_REGS_IP(x) (((PT_REGS_ARM64 *)(x))->pc)
410 445
411#elif defined(bpf_target_mips) 446#elif defined(bpf_target_mips)
412 447
@@ -452,10 +487,10 @@ static int (*bpf_skb_adjust_room)(void *ctx, __s32 len_diff, __u32 mode,
452 487
453#endif 488#endif
454 489
455#ifdef bpf_target_powerpc 490#if defined(bpf_target_powerpc)
456#define BPF_KPROBE_READ_RET_IP(ip, ctx) ({ (ip) = (ctx)->link; }) 491#define BPF_KPROBE_READ_RET_IP(ip, ctx) ({ (ip) = (ctx)->link; })
457#define BPF_KRETPROBE_READ_RET_IP BPF_KPROBE_READ_RET_IP 492#define BPF_KRETPROBE_READ_RET_IP BPF_KPROBE_READ_RET_IP
458#elif bpf_target_sparc 493#elif defined(bpf_target_sparc)
459#define BPF_KPROBE_READ_RET_IP(ip, ctx) ({ (ip) = PT_REGS_RET(ctx); }) 494#define BPF_KPROBE_READ_RET_IP(ip, ctx) ({ (ip) = PT_REGS_RET(ctx); })
460#define BPF_KRETPROBE_READ_RET_IP BPF_KPROBE_READ_RET_IP 495#define BPF_KRETPROBE_READ_RET_IP BPF_KPROBE_READ_RET_IP
461#else 496#else
diff --git a/tools/testing/selftests/bpf/prog_tests/attach_probe.c b/tools/testing/selftests/bpf/prog_tests/attach_probe.c
index a4686395522c..5ecc267d98b0 100644
--- a/tools/testing/selftests/bpf/prog_tests/attach_probe.c
+++ b/tools/testing/selftests/bpf/prog_tests/attach_probe.c
@@ -21,12 +21,6 @@ ssize_t get_base_addr() {
21 return -EINVAL; 21 return -EINVAL;
22} 22}
23 23
24#ifdef __x86_64__
25#define SYS_KPROBE_NAME "__x64_sys_nanosleep"
26#else
27#define SYS_KPROBE_NAME "sys_nanosleep"
28#endif
29
30void test_attach_probe(void) 24void test_attach_probe(void)
31{ 25{
32 const char *kprobe_name = "kprobe/sys_nanosleep"; 26 const char *kprobe_name = "kprobe/sys_nanosleep";
@@ -84,7 +78,7 @@ void test_attach_probe(void)
84 78
85 kprobe_link = bpf_program__attach_kprobe(kprobe_prog, 79 kprobe_link = bpf_program__attach_kprobe(kprobe_prog,
86 false /* retprobe */, 80 false /* retprobe */,
87 SYS_KPROBE_NAME); 81 SYS_NANOSLEEP_KPROBE_NAME);
88 if (CHECK(IS_ERR(kprobe_link), "attach_kprobe", 82 if (CHECK(IS_ERR(kprobe_link), "attach_kprobe",
89 "err %ld\n", PTR_ERR(kprobe_link))) { 83 "err %ld\n", PTR_ERR(kprobe_link))) {
90 kprobe_link = NULL; 84 kprobe_link = NULL;
@@ -92,7 +86,7 @@ void test_attach_probe(void)
92 } 86 }
93 kretprobe_link = bpf_program__attach_kprobe(kretprobe_prog, 87 kretprobe_link = bpf_program__attach_kprobe(kretprobe_prog,
94 true /* retprobe */, 88 true /* retprobe */,
95 SYS_KPROBE_NAME); 89 SYS_NANOSLEEP_KPROBE_NAME);
96 if (CHECK(IS_ERR(kretprobe_link), "attach_kretprobe", 90 if (CHECK(IS_ERR(kretprobe_link), "attach_kretprobe",
97 "err %ld\n", PTR_ERR(kretprobe_link))) { 91 "err %ld\n", PTR_ERR(kretprobe_link))) {
98 kretprobe_link = NULL; 92 kretprobe_link = NULL;
diff --git a/tools/testing/selftests/bpf/prog_tests/perf_buffer.c b/tools/testing/selftests/bpf/prog_tests/perf_buffer.c
index 3f1ef95865ff..3003fddc0613 100644
--- a/tools/testing/selftests/bpf/prog_tests/perf_buffer.c
+++ b/tools/testing/selftests/bpf/prog_tests/perf_buffer.c
@@ -5,12 +5,6 @@
5#include <sys/socket.h> 5#include <sys/socket.h>
6#include <test_progs.h> 6#include <test_progs.h>
7 7
8#ifdef __x86_64__
9#define SYS_KPROBE_NAME "__x64_sys_nanosleep"
10#else
11#define SYS_KPROBE_NAME "sys_nanosleep"
12#endif
13
14static void on_sample(void *ctx, int cpu, void *data, __u32 size) 8static void on_sample(void *ctx, int cpu, void *data, __u32 size)
15{ 9{
16 int cpu_data = *(int *)data, duration = 0; 10 int cpu_data = *(int *)data, duration = 0;
@@ -56,7 +50,7 @@ void test_perf_buffer(void)
56 50
57 /* attach kprobe */ 51 /* attach kprobe */
58 link = bpf_program__attach_kprobe(prog, false /* retprobe */, 52 link = bpf_program__attach_kprobe(prog, false /* retprobe */,
59 SYS_KPROBE_NAME); 53 SYS_NANOSLEEP_KPROBE_NAME);
60 if (CHECK(IS_ERR(link), "attach_kprobe", "err %ld\n", PTR_ERR(link))) 54 if (CHECK(IS_ERR(link), "attach_kprobe", "err %ld\n", PTR_ERR(link)))
61 goto out_close; 55 goto out_close;
62 56
diff --git a/tools/testing/selftests/bpf/prog_tests/send_signal.c b/tools/testing/selftests/bpf/prog_tests/send_signal.c
index 67cea1686305..54218ee3c004 100644
--- a/tools/testing/selftests/bpf/prog_tests/send_signal.c
+++ b/tools/testing/selftests/bpf/prog_tests/send_signal.c
@@ -173,6 +173,18 @@ static int test_send_signal_tracepoint(void)
173 return test_send_signal_common(&attr, BPF_PROG_TYPE_TRACEPOINT, "tracepoint"); 173 return test_send_signal_common(&attr, BPF_PROG_TYPE_TRACEPOINT, "tracepoint");
174} 174}
175 175
176static int test_send_signal_perf(void)
177{
178 struct perf_event_attr attr = {
179 .sample_period = 1,
180 .type = PERF_TYPE_SOFTWARE,
181 .config = PERF_COUNT_SW_CPU_CLOCK,
182 };
183
184 return test_send_signal_common(&attr, BPF_PROG_TYPE_PERF_EVENT,
185 "perf_sw_event");
186}
187
176static int test_send_signal_nmi(void) 188static int test_send_signal_nmi(void)
177{ 189{
178 struct perf_event_attr attr = { 190 struct perf_event_attr attr = {
@@ -181,8 +193,26 @@ static int test_send_signal_nmi(void)
181 .type = PERF_TYPE_HARDWARE, 193 .type = PERF_TYPE_HARDWARE,
182 .config = PERF_COUNT_HW_CPU_CYCLES, 194 .config = PERF_COUNT_HW_CPU_CYCLES,
183 }; 195 };
196 int pmu_fd;
197
198 /* Some setups (e.g. virtual machines) might run with hardware
199 * perf events disabled. If this is the case, skip this test.
200 */
201 pmu_fd = syscall(__NR_perf_event_open, &attr, 0 /* pid */,
202 -1 /* cpu */, -1 /* group_fd */, 0 /* flags */);
203 if (pmu_fd == -1) {
204 if (errno == ENOENT) {
205 printf("%s:SKIP:no PERF_COUNT_HW_CPU_CYCLES\n",
206 __func__);
207 return 0;
208 }
209 /* Let the test fail with a more informative message */
210 } else {
211 close(pmu_fd);
212 }
184 213
185 return test_send_signal_common(&attr, BPF_PROG_TYPE_PERF_EVENT, "perf_event"); 214 return test_send_signal_common(&attr, BPF_PROG_TYPE_PERF_EVENT,
215 "perf_hw_event");
186} 216}
187 217
188void test_send_signal(void) 218void test_send_signal(void)
@@ -190,6 +220,7 @@ void test_send_signal(void)
190 int ret = 0; 220 int ret = 0;
191 221
192 ret |= test_send_signal_tracepoint(); 222 ret |= test_send_signal_tracepoint();
223 ret |= test_send_signal_perf();
193 ret |= test_send_signal_nmi(); 224 ret |= test_send_signal_nmi();
194 if (!ret) 225 if (!ret)
195 printf("test_send_signal:OK\n"); 226 printf("test_send_signal:OK\n");
diff --git a/tools/testing/selftests/bpf/progs/loop1.c b/tools/testing/selftests/bpf/progs/loop1.c
index dea395af9ea9..7cdb7f878310 100644
--- a/tools/testing/selftests/bpf/progs/loop1.c
+++ b/tools/testing/selftests/bpf/progs/loop1.c
@@ -18,7 +18,7 @@ int nested_loops(volatile struct pt_regs* ctx)
18 for (j = 0; j < 300; j++) 18 for (j = 0; j < 300; j++)
19 for (i = 0; i < j; i++) { 19 for (i = 0; i < j; i++) {
20 if (j & 1) 20 if (j & 1)
21 m = ctx->rax; 21 m = PT_REGS_RC(ctx);
22 else 22 else
23 m = j; 23 m = j;
24 sum += i * m; 24 sum += i * m;
diff --git a/tools/testing/selftests/bpf/progs/loop2.c b/tools/testing/selftests/bpf/progs/loop2.c
index 0637bd8e8bcf..9b2f808a2863 100644
--- a/tools/testing/selftests/bpf/progs/loop2.c
+++ b/tools/testing/selftests/bpf/progs/loop2.c
@@ -16,7 +16,7 @@ int while_true(volatile struct pt_regs* ctx)
16 int i = 0; 16 int i = 0;
17 17
18 while (true) { 18 while (true) {
19 if (ctx->rax & 1) 19 if (PT_REGS_RC(ctx) & 1)
20 i += 3; 20 i += 3;
21 else 21 else
22 i += 7; 22 i += 7;
diff --git a/tools/testing/selftests/bpf/progs/loop3.c b/tools/testing/selftests/bpf/progs/loop3.c
index 30a0f6cba080..d727657d51e2 100644
--- a/tools/testing/selftests/bpf/progs/loop3.c
+++ b/tools/testing/selftests/bpf/progs/loop3.c
@@ -16,7 +16,7 @@ int while_true(volatile struct pt_regs* ctx)
16 __u64 i = 0, sum = 0; 16 __u64 i = 0, sum = 0;
17 do { 17 do {
18 i++; 18 i++;
19 sum += ctx->rax; 19 sum += PT_REGS_RC(ctx);
20 } while (i < 0x100000000ULL); 20 } while (i < 0x100000000ULL);
21 return sum; 21 return sum;
22} 22}
diff --git a/tools/testing/selftests/bpf/progs/test_get_stack_rawtp.c b/tools/testing/selftests/bpf/progs/test_get_stack_rawtp.c
index d06b47a09097..33254b771384 100644
--- a/tools/testing/selftests/bpf/progs/test_get_stack_rawtp.c
+++ b/tools/testing/selftests/bpf/progs/test_get_stack_rawtp.c
@@ -47,11 +47,12 @@ struct {
47 * issue and avoid complicated C programming massaging. 47 * issue and avoid complicated C programming massaging.
48 * This is an acceptable workaround since there is one entry here. 48 * This is an acceptable workaround since there is one entry here.
49 */ 49 */
50typedef __u64 raw_stack_trace_t[2 * MAX_STACK_RAWTP];
50struct { 51struct {
51 __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY); 52 __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
52 __uint(max_entries, 1); 53 __uint(max_entries, 1);
53 __type(key, __u32); 54 __type(key, __u32);
54 __u64 (*value)[2 * MAX_STACK_RAWTP]; 55 __type(value, raw_stack_trace_t);
55} rawdata_map SEC(".maps"); 56} rawdata_map SEC(".maps");
56 57
57SEC("tracepoint/raw_syscalls/sys_enter") 58SEC("tracepoint/raw_syscalls/sys_enter")
diff --git a/tools/testing/selftests/bpf/progs/test_stacktrace_build_id.c b/tools/testing/selftests/bpf/progs/test_stacktrace_build_id.c
index bbfc8337b6f0..f5638e26865d 100644
--- a/tools/testing/selftests/bpf/progs/test_stacktrace_build_id.c
+++ b/tools/testing/selftests/bpf/progs/test_stacktrace_build_id.c
@@ -36,8 +36,7 @@ struct {
36 __uint(type, BPF_MAP_TYPE_ARRAY); 36 __uint(type, BPF_MAP_TYPE_ARRAY);
37 __uint(max_entries, 128); 37 __uint(max_entries, 128);
38 __type(key, __u32); 38 __type(key, __u32);
39 /* there seems to be a bug in kernel not handling typedef properly */ 39 __type(value, stack_trace_t);
40 struct bpf_stack_build_id (*value)[PERF_MAX_STACK_DEPTH];
41} stack_amap SEC(".maps"); 40} stack_amap SEC(".maps");
42 41
43/* taken from /sys/kernel/debug/tracing/events/random/urandom_read/format */ 42/* taken from /sys/kernel/debug/tracing/events/random/urandom_read/format */
diff --git a/tools/testing/selftests/bpf/progs/test_stacktrace_map.c b/tools/testing/selftests/bpf/progs/test_stacktrace_map.c
index 803c15dc109d..fa0be3e10a10 100644
--- a/tools/testing/selftests/bpf/progs/test_stacktrace_map.c
+++ b/tools/testing/selftests/bpf/progs/test_stacktrace_map.c
@@ -35,7 +35,7 @@ struct {
35 __uint(type, BPF_MAP_TYPE_ARRAY); 35 __uint(type, BPF_MAP_TYPE_ARRAY);
36 __uint(max_entries, 16384); 36 __uint(max_entries, 16384);
37 __type(key, __u32); 37 __type(key, __u32);
38 __u64 (*value)[PERF_MAX_STACK_DEPTH]; 38 __type(value, stack_trace_t);
39} stack_amap SEC(".maps"); 39} stack_amap SEC(".maps");
40 40
41/* taken from /sys/kernel/debug/tracing/events/sched/sched_switch/format */ 41/* taken from /sys/kernel/debug/tracing/events/sched/sched_switch/format */
diff --git a/tools/testing/selftests/bpf/progs/test_xdp_noinline.c b/tools/testing/selftests/bpf/progs/test_xdp_noinline.c
index dad8a7e33eaa..e88d7b9d65ab 100644
--- a/tools/testing/selftests/bpf/progs/test_xdp_noinline.c
+++ b/tools/testing/selftests/bpf/progs/test_xdp_noinline.c
@@ -14,6 +14,7 @@
14#include <linux/tcp.h> 14#include <linux/tcp.h>
15#include <linux/udp.h> 15#include <linux/udp.h>
16#include "bpf_helpers.h" 16#include "bpf_helpers.h"
17#include "bpf_endian.h"
17 18
18static __u32 rol32(__u32 word, unsigned int shift) 19static __u32 rol32(__u32 word, unsigned int shift)
19{ 20{
@@ -305,7 +306,7 @@ bool encap_v6(struct xdp_md *xdp, struct ctl_value *cval,
305 ip6h->nexthdr = IPPROTO_IPV6; 306 ip6h->nexthdr = IPPROTO_IPV6;
306 ip_suffix = pckt->flow.srcv6[3] ^ pckt->flow.port16[0]; 307 ip_suffix = pckt->flow.srcv6[3] ^ pckt->flow.port16[0];
307 ip6h->payload_len = 308 ip6h->payload_len =
308 __builtin_bswap16(pkt_bytes + sizeof(struct ipv6hdr)); 309 bpf_htons(pkt_bytes + sizeof(struct ipv6hdr));
309 ip6h->hop_limit = 4; 310 ip6h->hop_limit = 4;
310 311
311 ip6h->saddr.in6_u.u6_addr32[0] = 1; 312 ip6h->saddr.in6_u.u6_addr32[0] = 1;
@@ -322,7 +323,7 @@ bool encap_v4(struct xdp_md *xdp, struct ctl_value *cval,
322 struct real_definition *dst, __u32 pkt_bytes) 323 struct real_definition *dst, __u32 pkt_bytes)
323{ 324{
324 325
325 __u32 ip_suffix = __builtin_bswap16(pckt->flow.port16[0]); 326 __u32 ip_suffix = bpf_ntohs(pckt->flow.port16[0]);
326 struct eth_hdr *new_eth; 327 struct eth_hdr *new_eth;
327 struct eth_hdr *old_eth; 328 struct eth_hdr *old_eth;
328 __u16 *next_iph_u16; 329 __u16 *next_iph_u16;
@@ -352,7 +353,7 @@ bool encap_v4(struct xdp_md *xdp, struct ctl_value *cval,
352 iph->protocol = IPPROTO_IPIP; 353 iph->protocol = IPPROTO_IPIP;
353 iph->check = 0; 354 iph->check = 0;
354 iph->tos = 1; 355 iph->tos = 1;
355 iph->tot_len = __builtin_bswap16(pkt_bytes + sizeof(struct iphdr)); 356 iph->tot_len = bpf_htons(pkt_bytes + sizeof(struct iphdr));
356 /* don't update iph->daddr, since it will overwrite old eth_proto 357 /* don't update iph->daddr, since it will overwrite old eth_proto
357 * and multiple iterations of bpf_prog_run() will fail 358 * and multiple iterations of bpf_prog_run() will fail
358 */ 359 */
@@ -639,7 +640,7 @@ static int process_l3_headers_v6(struct packet_description *pckt,
639 iph_len = sizeof(struct ipv6hdr); 640 iph_len = sizeof(struct ipv6hdr);
640 *protocol = ip6h->nexthdr; 641 *protocol = ip6h->nexthdr;
641 pckt->flow.proto = *protocol; 642 pckt->flow.proto = *protocol;
642 *pkt_bytes = __builtin_bswap16(ip6h->payload_len); 643 *pkt_bytes = bpf_ntohs(ip6h->payload_len);
643 off += iph_len; 644 off += iph_len;
644 if (*protocol == 45) { 645 if (*protocol == 45) {
645 return XDP_DROP; 646 return XDP_DROP;
@@ -671,7 +672,7 @@ static int process_l3_headers_v4(struct packet_description *pckt,
671 return XDP_DROP; 672 return XDP_DROP;
672 *protocol = iph->protocol; 673 *protocol = iph->protocol;
673 pckt->flow.proto = *protocol; 674 pckt->flow.proto = *protocol;
674 *pkt_bytes = __builtin_bswap16(iph->tot_len); 675 *pkt_bytes = bpf_ntohs(iph->tot_len);
675 off += 20; 676 off += 20;
676 if (iph->frag_off & 65343) 677 if (iph->frag_off & 65343)
677 return XDP_DROP; 678 return XDP_DROP;
@@ -808,10 +809,10 @@ int balancer_ingress(struct xdp_md *ctx)
808 nh_off = sizeof(struct eth_hdr); 809 nh_off = sizeof(struct eth_hdr);
809 if (data + nh_off > data_end) 810 if (data + nh_off > data_end)
810 return XDP_DROP; 811 return XDP_DROP;
811 eth_proto = eth->eth_proto; 812 eth_proto = bpf_ntohs(eth->eth_proto);
812 if (eth_proto == 8) 813 if (eth_proto == ETH_P_IP)
813 return process_packet(data, nh_off, data_end, 0, ctx); 814 return process_packet(data, nh_off, data_end, 0, ctx);
814 else if (eth_proto == 56710) 815 else if (eth_proto == ETH_P_IPV6)
815 return process_packet(data, nh_off, data_end, 1, ctx); 816 return process_packet(data, nh_off, data_end, 1, ctx);
816 else 817 else
817 return XDP_DROP; 818 return XDP_DROP;
diff --git a/tools/testing/selftests/bpf/test_btf.c b/tools/testing/selftests/bpf/test_btf.c
index 8351cb5f4a20..3d617e806054 100644
--- a/tools/testing/selftests/bpf/test_btf.c
+++ b/tools/testing/selftests/bpf/test_btf.c
@@ -3417,6 +3417,94 @@ static struct btf_raw_test raw_tests[] = {
3417 .value_type_id = 1, 3417 .value_type_id = 1,
3418 .max_entries = 4, 3418 .max_entries = 4,
3419}, 3419},
3420/*
3421 * typedef int arr_t[16];
3422 * struct s {
3423 * arr_t *a;
3424 * };
3425 */
3426{
3427 .descr = "struct->ptr->typedef->array->int size resolution",
3428 .raw_types = {
3429 BTF_STRUCT_ENC(NAME_TBD, 1, 8), /* [1] */
3430 BTF_MEMBER_ENC(NAME_TBD, 2, 0),
3431 BTF_PTR_ENC(3), /* [2] */
3432 BTF_TYPEDEF_ENC(NAME_TBD, 4), /* [3] */
3433 BTF_TYPE_ARRAY_ENC(5, 5, 16), /* [4] */
3434 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [5] */
3435 BTF_END_RAW,
3436 },
3437 BTF_STR_SEC("\0s\0a\0arr_t"),
3438 .map_type = BPF_MAP_TYPE_ARRAY,
3439 .map_name = "ptr_mod_chain_size_resolve_map",
3440 .key_size = sizeof(int),
3441 .value_size = sizeof(int) * 16,
3442 .key_type_id = 5 /* int */,
3443 .value_type_id = 3 /* arr_t */,
3444 .max_entries = 4,
3445},
3446/*
3447 * typedef int arr_t[16][8][4];
3448 * struct s {
3449 * arr_t *a;
3450 * };
3451 */
3452{
3453 .descr = "struct->ptr->typedef->multi-array->int size resolution",
3454 .raw_types = {
3455 BTF_STRUCT_ENC(NAME_TBD, 1, 8), /* [1] */
3456 BTF_MEMBER_ENC(NAME_TBD, 2, 0),
3457 BTF_PTR_ENC(3), /* [2] */
3458 BTF_TYPEDEF_ENC(NAME_TBD, 4), /* [3] */
3459 BTF_TYPE_ARRAY_ENC(5, 7, 16), /* [4] */
3460 BTF_TYPE_ARRAY_ENC(6, 7, 8), /* [5] */
3461 BTF_TYPE_ARRAY_ENC(7, 7, 4), /* [6] */
3462 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [7] */
3463 BTF_END_RAW,
3464 },
3465 BTF_STR_SEC("\0s\0a\0arr_t"),
3466 .map_type = BPF_MAP_TYPE_ARRAY,
3467 .map_name = "multi_arr_size_resolve_map",
3468 .key_size = sizeof(int),
3469 .value_size = sizeof(int) * 16 * 8 * 4,
3470 .key_type_id = 7 /* int */,
3471 .value_type_id = 3 /* arr_t */,
3472 .max_entries = 4,
3473},
3474/*
3475 * typedef int int_t;
3476 * typedef int_t arr3_t[4];
3477 * typedef arr3_t arr2_t[8];
3478 * typedef arr2_t arr1_t[16];
3479 * struct s {
3480 * arr1_t *a;
3481 * };
3482 */
3483{
3484 .descr = "typedef/multi-arr mix size resolution",
3485 .raw_types = {
3486 BTF_STRUCT_ENC(NAME_TBD, 1, 8), /* [1] */
3487 BTF_MEMBER_ENC(NAME_TBD, 2, 0),
3488 BTF_PTR_ENC(3), /* [2] */
3489 BTF_TYPEDEF_ENC(NAME_TBD, 4), /* [3] */
3490 BTF_TYPE_ARRAY_ENC(5, 10, 16), /* [4] */
3491 BTF_TYPEDEF_ENC(NAME_TBD, 6), /* [5] */
3492 BTF_TYPE_ARRAY_ENC(7, 10, 8), /* [6] */
3493 BTF_TYPEDEF_ENC(NAME_TBD, 8), /* [7] */
3494 BTF_TYPE_ARRAY_ENC(9, 10, 4), /* [8] */
3495 BTF_TYPEDEF_ENC(NAME_TBD, 10), /* [9] */
3496 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [10] */
3497 BTF_END_RAW,
3498 },
3499 BTF_STR_SEC("\0s\0a\0arr1_t\0arr2_t\0arr3_t\0int_t"),
3500 .map_type = BPF_MAP_TYPE_ARRAY,
3501 .map_name = "typedef_arra_mix_size_resolve_map",
3502 .key_size = sizeof(int),
3503 .value_size = sizeof(int) * 16 * 8 * 4,
3504 .key_type_id = 10 /* int */,
3505 .value_type_id = 3 /* arr_t */,
3506 .max_entries = 4,
3507},
3420 3508
3421}; /* struct btf_raw_test raw_tests[] */ 3509}; /* struct btf_raw_test raw_tests[] */
3422 3510
diff --git a/tools/testing/selftests/bpf/test_progs.h b/tools/testing/selftests/bpf/test_progs.h
index f095e1d4c657..49e0f7d85643 100644
--- a/tools/testing/selftests/bpf/test_progs.h
+++ b/tools/testing/selftests/bpf/test_progs.h
@@ -92,3 +92,11 @@ int compare_map_keys(int map1_fd, int map2_fd);
92int compare_stack_ips(int smap_fd, int amap_fd, int stack_trace_len); 92int compare_stack_ips(int smap_fd, int amap_fd, int stack_trace_len);
93int extract_build_id(char *build_id, size_t size); 93int extract_build_id(char *build_id, size_t size);
94void *spin_lock_thread(void *arg); 94void *spin_lock_thread(void *arg);
95
96#ifdef __x86_64__
97#define SYS_NANOSLEEP_KPROBE_NAME "__x64_sys_nanosleep"
98#elif defined(__s390x__)
99#define SYS_NANOSLEEP_KPROBE_NAME "__s390x_sys_nanosleep"
100#else
101#define SYS_NANOSLEEP_KPROBE_NAME "sys_nanosleep"
102#endif
diff --git a/tools/testing/selftests/bpf/test_verifier.c b/tools/testing/selftests/bpf/test_verifier.c
index b0773291012a..84135d5f4b35 100644
--- a/tools/testing/selftests/bpf/test_verifier.c
+++ b/tools/testing/selftests/bpf/test_verifier.c
@@ -86,7 +86,7 @@ struct bpf_test {
86 int fixup_sk_storage_map[MAX_FIXUPS]; 86 int fixup_sk_storage_map[MAX_FIXUPS];
87 const char *errstr; 87 const char *errstr;
88 const char *errstr_unpriv; 88 const char *errstr_unpriv;
89 uint32_t retval, retval_unpriv, insn_processed; 89 uint32_t insn_processed;
90 int prog_len; 90 int prog_len;
91 enum { 91 enum {
92 UNDEF, 92 UNDEF,
@@ -95,16 +95,20 @@ struct bpf_test {
95 } result, result_unpriv; 95 } result, result_unpriv;
96 enum bpf_prog_type prog_type; 96 enum bpf_prog_type prog_type;
97 uint8_t flags; 97 uint8_t flags;
98 __u8 data[TEST_DATA_LEN];
99 void (*fill_helper)(struct bpf_test *self); 98 void (*fill_helper)(struct bpf_test *self);
100 uint8_t runs; 99 uint8_t runs;
101 struct { 100#define bpf_testdata_struct_t \
102 uint32_t retval, retval_unpriv; 101 struct { \
103 union { 102 uint32_t retval, retval_unpriv; \
104 __u8 data[TEST_DATA_LEN]; 103 union { \
105 __u64 data64[TEST_DATA_LEN / 8]; 104 __u8 data[TEST_DATA_LEN]; \
106 }; 105 __u64 data64[TEST_DATA_LEN / 8]; \
107 } retvals[MAX_TEST_RUNS]; 106 }; \
107 }
108 union {
109 bpf_testdata_struct_t;
110 bpf_testdata_struct_t retvals[MAX_TEST_RUNS];
111 };
108 enum bpf_attach_type expected_attach_type; 112 enum bpf_attach_type expected_attach_type;
109}; 113};
110 114
@@ -949,17 +953,8 @@ static void do_test_single(struct bpf_test *test, bool unpriv,
949 uint32_t expected_val; 953 uint32_t expected_val;
950 int i; 954 int i;
951 955
952 if (!test->runs) { 956 if (!test->runs)
953 expected_val = unpriv && test->retval_unpriv ? 957 test->runs = 1;
954 test->retval_unpriv : test->retval;
955
956 err = do_prog_test_run(fd_prog, unpriv, expected_val,
957 test->data, sizeof(test->data));
958 if (err)
959 run_errs++;
960 else
961 run_successes++;
962 }
963 958
964 for (i = 0; i < test->runs; i++) { 959 for (i = 0; i < test->runs; i++) {
965 if (unpriv && test->retvals[i].retval_unpriv) 960 if (unpriv && test->retvals[i].retval_unpriv)
diff --git a/tools/testing/selftests/bpf/verifier/array_access.c b/tools/testing/selftests/bpf/verifier/array_access.c
index bcb83196e459..f3c33e128709 100644
--- a/tools/testing/selftests/bpf/verifier/array_access.c
+++ b/tools/testing/selftests/bpf/verifier/array_access.c
@@ -226,7 +226,7 @@
226 BPF_LD_MAP_FD(BPF_REG_1, 0), 226 BPF_LD_MAP_FD(BPF_REG_1, 0),
227 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), 227 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
228 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1), 228 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
229 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 0), 229 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0, 0),
230 BPF_EXIT_INSN(), 230 BPF_EXIT_INSN(),
231 }, 231 },
232 .fixup_map_array_ro = { 3 }, 232 .fixup_map_array_ro = { 3 },
diff --git a/tools/testing/selftests/bpf/verifier/value_ptr_arith.c b/tools/testing/selftests/bpf/verifier/value_ptr_arith.c
index c3de1a2c9dc5..a53d99cebd9f 100644
--- a/tools/testing/selftests/bpf/verifier/value_ptr_arith.c
+++ b/tools/testing/selftests/bpf/verifier/value_ptr_arith.c
@@ -183,7 +183,7 @@
183 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem), 183 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
184 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1), 184 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
185 BPF_EXIT_INSN(), 185 BPF_EXIT_INSN(),
186 BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0), 186 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
187 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 3), 187 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 3),
188 BPF_MOV64_IMM(BPF_REG_2, 0), 188 BPF_MOV64_IMM(BPF_REG_2, 0),
189 BPF_MOV64_IMM(BPF_REG_3, 0x100000), 189 BPF_MOV64_IMM(BPF_REG_3, 0x100000),
diff --git a/tools/testing/selftests/bpf/verifier/wide_access.c b/tools/testing/selftests/bpf/verifier/wide_access.c
new file mode 100644
index 000000000000..ccade9312d21
--- /dev/null
+++ b/tools/testing/selftests/bpf/verifier/wide_access.c
@@ -0,0 +1,73 @@
1#define BPF_SOCK_ADDR_STORE(field, off, res, err) \
2{ \
3 "wide store to bpf_sock_addr." #field "[" #off "]", \
4 .insns = { \
5 BPF_MOV64_IMM(BPF_REG_0, 1), \
6 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, \
7 offsetof(struct bpf_sock_addr, field[off])), \
8 BPF_EXIT_INSN(), \
9 }, \
10 .result = res, \
11 .prog_type = BPF_PROG_TYPE_CGROUP_SOCK_ADDR, \
12 .expected_attach_type = BPF_CGROUP_UDP6_SENDMSG, \
13 .errstr = err, \
14}
15
16/* user_ip6[0] is u64 aligned */
17BPF_SOCK_ADDR_STORE(user_ip6, 0, ACCEPT,
18 NULL),
19BPF_SOCK_ADDR_STORE(user_ip6, 1, REJECT,
20 "invalid bpf_context access off=12 size=8"),
21BPF_SOCK_ADDR_STORE(user_ip6, 2, ACCEPT,
22 NULL),
23BPF_SOCK_ADDR_STORE(user_ip6, 3, REJECT,
24 "invalid bpf_context access off=20 size=8"),
25
26/* msg_src_ip6[0] is _not_ u64 aligned */
27BPF_SOCK_ADDR_STORE(msg_src_ip6, 0, REJECT,
28 "invalid bpf_context access off=44 size=8"),
29BPF_SOCK_ADDR_STORE(msg_src_ip6, 1, ACCEPT,
30 NULL),
31BPF_SOCK_ADDR_STORE(msg_src_ip6, 2, REJECT,
32 "invalid bpf_context access off=52 size=8"),
33BPF_SOCK_ADDR_STORE(msg_src_ip6, 3, REJECT,
34 "invalid bpf_context access off=56 size=8"),
35
36#undef BPF_SOCK_ADDR_STORE
37
38#define BPF_SOCK_ADDR_LOAD(field, off, res, err) \
39{ \
40 "wide load from bpf_sock_addr." #field "[" #off "]", \
41 .insns = { \
42 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, \
43 offsetof(struct bpf_sock_addr, field[off])), \
44 BPF_MOV64_IMM(BPF_REG_0, 1), \
45 BPF_EXIT_INSN(), \
46 }, \
47 .result = res, \
48 .prog_type = BPF_PROG_TYPE_CGROUP_SOCK_ADDR, \
49 .expected_attach_type = BPF_CGROUP_UDP6_SENDMSG, \
50 .errstr = err, \
51}
52
53/* user_ip6[0] is u64 aligned */
54BPF_SOCK_ADDR_LOAD(user_ip6, 0, ACCEPT,
55 NULL),
56BPF_SOCK_ADDR_LOAD(user_ip6, 1, REJECT,
57 "invalid bpf_context access off=12 size=8"),
58BPF_SOCK_ADDR_LOAD(user_ip6, 2, ACCEPT,
59 NULL),
60BPF_SOCK_ADDR_LOAD(user_ip6, 3, REJECT,
61 "invalid bpf_context access off=20 size=8"),
62
63/* msg_src_ip6[0] is _not_ u64 aligned */
64BPF_SOCK_ADDR_LOAD(msg_src_ip6, 0, REJECT,
65 "invalid bpf_context access off=44 size=8"),
66BPF_SOCK_ADDR_LOAD(msg_src_ip6, 1, ACCEPT,
67 NULL),
68BPF_SOCK_ADDR_LOAD(msg_src_ip6, 2, REJECT,
69 "invalid bpf_context access off=52 size=8"),
70BPF_SOCK_ADDR_LOAD(msg_src_ip6, 3, REJECT,
71 "invalid bpf_context access off=56 size=8"),
72
73#undef BPF_SOCK_ADDR_LOAD
diff --git a/tools/testing/selftests/bpf/verifier/wide_store.c b/tools/testing/selftests/bpf/verifier/wide_store.c
deleted file mode 100644
index 8fe99602ded4..000000000000
--- a/tools/testing/selftests/bpf/verifier/wide_store.c
+++ /dev/null
@@ -1,36 +0,0 @@
1#define BPF_SOCK_ADDR(field, off, res, err) \
2{ \
3 "wide store to bpf_sock_addr." #field "[" #off "]", \
4 .insns = { \
5 BPF_MOV64_IMM(BPF_REG_0, 1), \
6 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, \
7 offsetof(struct bpf_sock_addr, field[off])), \
8 BPF_EXIT_INSN(), \
9 }, \
10 .result = res, \
11 .prog_type = BPF_PROG_TYPE_CGROUP_SOCK_ADDR, \
12 .expected_attach_type = BPF_CGROUP_UDP6_SENDMSG, \
13 .errstr = err, \
14}
15
16/* user_ip6[0] is u64 aligned */
17BPF_SOCK_ADDR(user_ip6, 0, ACCEPT,
18 NULL),
19BPF_SOCK_ADDR(user_ip6, 1, REJECT,
20 "invalid bpf_context access off=12 size=8"),
21BPF_SOCK_ADDR(user_ip6, 2, ACCEPT,
22 NULL),
23BPF_SOCK_ADDR(user_ip6, 3, REJECT,
24 "invalid bpf_context access off=20 size=8"),
25
26/* msg_src_ip6[0] is _not_ u64 aligned */
27BPF_SOCK_ADDR(msg_src_ip6, 0, REJECT,
28 "invalid bpf_context access off=44 size=8"),
29BPF_SOCK_ADDR(msg_src_ip6, 1, ACCEPT,
30 NULL),
31BPF_SOCK_ADDR(msg_src_ip6, 2, REJECT,
32 "invalid bpf_context access off=52 size=8"),
33BPF_SOCK_ADDR(msg_src_ip6, 3, REJECT,
34 "invalid bpf_context access off=56 size=8"),
35
36#undef BPF_SOCK_ADDR
diff --git a/tools/testing/selftests/ftrace/ftracetest b/tools/testing/selftests/ftrace/ftracetest
index 6d5e9e87c4b7..063ecb290a5a 100755
--- a/tools/testing/selftests/ftrace/ftracetest
+++ b/tools/testing/selftests/ftrace/ftracetest
@@ -23,9 +23,15 @@ echo " If <dir> is -, all logs output in console only"
23exit $1 23exit $1
24} 24}
25 25
26# default error
27err_ret=1
28
29# kselftest skip code is 4
30err_skip=4
31
26errexit() { # message 32errexit() { # message
27 echo "Error: $1" 1>&2 33 echo "Error: $1" 1>&2
28 exit 1 34 exit $err_ret
29} 35}
30 36
31# Ensuring user privilege 37# Ensuring user privilege
@@ -116,11 +122,31 @@ parse_opts() { # opts
116} 122}
117 123
118# Parameters 124# Parameters
119DEBUGFS_DIR=`grep debugfs /proc/mounts | cut -f2 -d' ' | head -1` 125TRACING_DIR=`grep tracefs /proc/mounts | cut -f2 -d' ' | head -1`
120if [ -z "$DEBUGFS_DIR" ]; then 126if [ -z "$TRACING_DIR" ]; then
121 TRACING_DIR=`grep tracefs /proc/mounts | cut -f2 -d' ' | head -1` 127 DEBUGFS_DIR=`grep debugfs /proc/mounts | cut -f2 -d' ' | head -1`
122else 128 if [ -z "$DEBUGFS_DIR" ]; then
123 TRACING_DIR=$DEBUGFS_DIR/tracing 129 # If tracefs exists, then so does /sys/kernel/tracing
130 if [ -d "/sys/kernel/tracing" ]; then
131 mount -t tracefs nodev /sys/kernel/tracing ||
132 errexit "Failed to mount /sys/kernel/tracing"
133 TRACING_DIR="/sys/kernel/tracing"
134 # If debugfs exists, then so does /sys/kernel/debug
135 elif [ -d "/sys/kernel/debug" ]; then
136 mount -t debugfs nodev /sys/kernel/debug ||
137 errexit "Failed to mount /sys/kernel/debug"
138 TRACING_DIR="/sys/kernel/debug/tracing"
139 else
140 err_ret=$err_skip
141 errexit "debugfs and tracefs are not configured in this kernel"
142 fi
143 else
144 TRACING_DIR="$DEBUGFS_DIR/tracing"
145 fi
146fi
147if [ ! -d "$TRACING_DIR" ]; then
148 err_ret=$err_skip
149 errexit "ftrace is not configured in this kernel"
124fi 150fi
125 151
126TOP_DIR=`absdir $0` 152TOP_DIR=`absdir $0`
diff --git a/tools/testing/selftests/ftrace/test.d/functions b/tools/testing/selftests/ftrace/test.d/functions
index 779ec11f61bd..1d96c5f7e402 100644
--- a/tools/testing/selftests/ftrace/test.d/functions
+++ b/tools/testing/selftests/ftrace/test.d/functions
@@ -91,8 +91,8 @@ initialize_ftrace() { # Reset ftrace to initial-state
91 reset_events_filter 91 reset_events_filter
92 reset_ftrace_filter 92 reset_ftrace_filter
93 disable_events 93 disable_events
94 echo > set_event_pid # event tracer is always on 94 [ -f set_event_pid ] && echo > set_event_pid
95 echo > set_ftrace_pid 95 [ -f set_ftrace_pid ] && echo > set_ftrace_pid
96 [ -f set_ftrace_filter ] && echo | tee set_ftrace_* 96 [ -f set_ftrace_filter ] && echo | tee set_ftrace_*
97 [ -f set_graph_function ] && echo | tee set_graph_* 97 [ -f set_graph_function ] && echo | tee set_graph_*
98 [ -f stack_trace_filter ] && echo > stack_trace_filter 98 [ -f stack_trace_filter ] && echo > stack_trace_filter
diff --git a/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args_user.tc b/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args_user.tc
new file mode 100644
index 000000000000..0f60087583d8
--- /dev/null
+++ b/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args_user.tc
@@ -0,0 +1,32 @@
1#!/bin/sh
2# SPDX-License-Identifier: GPL-2.0
3# description: Kprobe event user-memory access
4
5[ -f kprobe_events ] || exit_unsupported # this is configurable
6
7grep -q '\$arg<N>' README || exit_unresolved # depends on arch
8grep -A10 "fetcharg:" README | grep -q 'ustring' || exit_unsupported
9grep -A10 "fetcharg:" README | grep -q '\[u\]<offset>' || exit_unsupported
10
11:;: "user-memory access syntax and ustring working on user memory";:
12echo 'p:myevent do_sys_open path=+0($arg2):ustring path2=+u0($arg2):string' \
13 > kprobe_events
14
15grep myevent kprobe_events | \
16 grep -q 'path=+0($arg2):ustring path2=+u0($arg2):string'
17echo 1 > events/kprobes/myevent/enable
18echo > /dev/null
19echo 0 > events/kprobes/myevent/enable
20
21grep myevent trace | grep -q 'path="/dev/null" path2="/dev/null"'
22
23:;: "user-memory access syntax and ustring not working with kernel memory";:
24echo 'p:myevent vfs_symlink path=+0($arg3):ustring path2=+u0($arg3):string' \
25 > kprobe_events
26echo 1 > events/kprobes/myevent/enable
27ln -s foo $TMPDIR/bar
28echo 0 > events/kprobes/myevent/enable
29
30grep myevent trace | grep -q 'path=(fault) path2=(fault)'
31
32exit 0
diff --git a/tools/testing/selftests/net/fib_tests.sh b/tools/testing/selftests/net/fib_tests.sh
index 9457aaeae092..4465fc2dae14 100755
--- a/tools/testing/selftests/net/fib_tests.sh
+++ b/tools/testing/selftests/net/fib_tests.sh
@@ -9,12 +9,13 @@ ret=0
9ksft_skip=4 9ksft_skip=4
10 10
11# all tests in this script. Can be overridden with -t option 11# all tests in this script. Can be overridden with -t option
12TESTS="unregister down carrier nexthop ipv6_rt ipv4_rt ipv6_addr_metric ipv4_addr_metric ipv6_route_metrics ipv4_route_metrics ipv4_route_v6_gw" 12TESTS="unregister down carrier nexthop ipv6_rt ipv4_rt ipv6_addr_metric ipv4_addr_metric ipv6_route_metrics ipv4_route_metrics ipv4_route_v6_gw rp_filter"
13 13
14VERBOSE=0 14VERBOSE=0
15PAUSE_ON_FAIL=no 15PAUSE_ON_FAIL=no
16PAUSE=no 16PAUSE=no
17IP="ip -netns ns1" 17IP="ip -netns ns1"
18NS_EXEC="ip netns exec ns1"
18 19
19log_test() 20log_test()
20{ 21{
@@ -433,6 +434,37 @@ fib_carrier_test()
433 fib_carrier_unicast_test 434 fib_carrier_unicast_test
434} 435}
435 436
437fib_rp_filter_test()
438{
439 echo
440 echo "IPv4 rp_filter tests"
441
442 setup
443
444 set -e
445 $IP link set dev lo address 52:54:00:6a:c7:5e
446 $IP link set dummy0 address 52:54:00:6a:c7:5e
447 $IP link add dummy1 type dummy
448 $IP link set dummy1 address 52:54:00:6a:c7:5e
449 $IP link set dev dummy1 up
450 $NS_EXEC sysctl -qw net.ipv4.conf.all.rp_filter=1
451 $NS_EXEC sysctl -qw net.ipv4.conf.all.accept_local=1
452 $NS_EXEC sysctl -qw net.ipv4.conf.all.route_localnet=1
453
454 $NS_EXEC tc qd add dev dummy1 parent root handle 1: fq_codel
455 $NS_EXEC tc filter add dev dummy1 parent 1: protocol arp basic action mirred egress redirect dev lo
456 $NS_EXEC tc filter add dev dummy1 parent 1: protocol ip basic action mirred egress redirect dev lo
457 set +e
458
459 run_cmd "ip netns exec ns1 ping -I dummy1 -w1 -c1 198.51.100.1"
460 log_test $? 0 "rp_filter passes local packets"
461
462 run_cmd "ip netns exec ns1 ping -I dummy1 -w1 -c1 127.0.0.1"
463 log_test $? 0 "rp_filter passes loopback packets"
464
465 cleanup
466}
467
436################################################################################ 468################################################################################
437# Tests on nexthop spec 469# Tests on nexthop spec
438 470
@@ -1557,6 +1589,7 @@ do
1557 fib_unreg_test|unregister) fib_unreg_test;; 1589 fib_unreg_test|unregister) fib_unreg_test;;
1558 fib_down_test|down) fib_down_test;; 1590 fib_down_test|down) fib_down_test;;
1559 fib_carrier_test|carrier) fib_carrier_test;; 1591 fib_carrier_test|carrier) fib_carrier_test;;
1592 fib_rp_filter_test|rp_filter) fib_rp_filter_test;;
1560 fib_nexthop_test|nexthop) fib_nexthop_test;; 1593 fib_nexthop_test|nexthop) fib_nexthop_test;;
1561 ipv6_route_test|ipv6_rt) ipv6_route_test;; 1594 ipv6_route_test|ipv6_rt) ipv6_route_test;;
1562 ipv4_route_test|ipv4_rt) ipv4_route_test;; 1595 ipv4_route_test|ipv4_rt) ipv4_route_test;;
diff --git a/tools/testing/selftests/ntb/ntb_test.sh b/tools/testing/selftests/ntb/ntb_test.sh
index 8a20e03d4cb7..9c60337317c6 100755
--- a/tools/testing/selftests/ntb/ntb_test.sh
+++ b/tools/testing/selftests/ntb/ntb_test.sh
@@ -78,10 +78,10 @@ set -e
78 78
79function _modprobe() 79function _modprobe()
80{ 80{
81 modprobe "$@" 81 modprobe "$@" || return 1
82 82
83 if [[ "$REMOTE_HOST" != "" ]]; then 83 if [[ "$REMOTE_HOST" != "" ]]; then
84 ssh "$REMOTE_HOST" modprobe "$@" 84 ssh "$REMOTE_HOST" modprobe "$@" || return 1
85 fi 85 fi
86} 86}
87 87
@@ -442,6 +442,30 @@ function pingpong_test()
442 echo " Passed" 442 echo " Passed"
443} 443}
444 444
445function msi_test()
446{
447 LOC=$1
448 REM=$2
449
450 write_file 1 $LOC/ready
451
452 echo "Running MSI interrupt tests on: $(subdirname $LOC) / $(subdirname $REM)"
453
454 CNT=$(read_file "$LOC/count")
455 for ((i = 0; i < $CNT; i++)); do
456 START=$(read_file $REM/../irq${i}_occurrences)
457 write_file $i $LOC/trigger
458 END=$(read_file $REM/../irq${i}_occurrences)
459
460 if [[ $(($END - $START)) != 1 ]]; then
461 echo "MSI did not trigger the interrupt on the remote side!" >&2
462 exit 1
463 fi
464 done
465
466 echo " Passed"
467}
468
445function perf_test() 469function perf_test()
446{ 470{
447 USE_DMA=$1 471 USE_DMA=$1
@@ -520,6 +544,29 @@ function ntb_pingpong_tests()
520 _modprobe -r ntb_pingpong 544 _modprobe -r ntb_pingpong
521} 545}
522 546
547function ntb_msi_tests()
548{
549 LOCAL_MSI="$DEBUGFS/ntb_msi_test/$LOCAL_DEV"
550 REMOTE_MSI="$REMOTE_HOST:$DEBUGFS/ntb_msi_test/$REMOTE_DEV"
551
552 echo "Starting ntb_msi_test tests..."
553
554 if ! _modprobe ntb_msi_test 2> /dev/null; then
555 echo " Not doing MSI tests seeing the module is not available."
556 return
557 fi
558
559 port_test $LOCAL_MSI $REMOTE_MSI
560
561 LOCAL_PEER="$LOCAL_MSI/peer$LOCAL_PIDX"
562 REMOTE_PEER="$REMOTE_MSI/peer$REMOTE_PIDX"
563
564 msi_test $LOCAL_PEER $REMOTE_PEER
565 msi_test $REMOTE_PEER $LOCAL_PEER
566
567 _modprobe -r ntb_msi_test
568}
569
523function ntb_perf_tests() 570function ntb_perf_tests()
524{ 571{
525 LOCAL_PERF="$DEBUGFS/ntb_perf/$LOCAL_DEV" 572 LOCAL_PERF="$DEBUGFS/ntb_perf/$LOCAL_DEV"
@@ -541,6 +588,7 @@ function cleanup()
541 _modprobe -r ntb_perf 2> /dev/null 588 _modprobe -r ntb_perf 2> /dev/null
542 _modprobe -r ntb_pingpong 2> /dev/null 589 _modprobe -r ntb_pingpong 2> /dev/null
543 _modprobe -r ntb_transport 2> /dev/null 590 _modprobe -r ntb_transport 2> /dev/null
591 _modprobe -r ntb_msi_test 2> /dev/null
544 set -e 592 set -e
545} 593}
546 594
@@ -577,5 +625,7 @@ ntb_tool_tests
577echo 625echo
578ntb_pingpong_tests 626ntb_pingpong_tests
579echo 627echo
628ntb_msi_tests
629echo
580ntb_perf_tests 630ntb_perf_tests
581echo 631echo
diff --git a/tools/testing/selftests/powerpc/mm/.gitignore b/tools/testing/selftests/powerpc/mm/.gitignore
index d503b8764a8e..7101ffd08d66 100644
--- a/tools/testing/selftests/powerpc/mm/.gitignore
+++ b/tools/testing/selftests/powerpc/mm/.gitignore
@@ -4,4 +4,4 @@ tempfile
4prot_sao 4prot_sao
5segv_errors 5segv_errors
6wild_bctr 6wild_bctr
7large_vm_fork_separation \ No newline at end of file 7large_vm_fork_separation
diff --git a/tools/testing/selftests/powerpc/stringloops/asm/ppc_asm.h b/tools/testing/selftests/powerpc/stringloops/asm/ppc_asm.h
index d2c0a911f55e..2b488b78c4f2 100644
--- a/tools/testing/selftests/powerpc/stringloops/asm/ppc_asm.h
+++ b/tools/testing/selftests/powerpc/stringloops/asm/ppc_asm.h
@@ -1,6 +1,6 @@
1/* SPDX-License-Identifier: GPL-2.0 */ 1/* SPDX-License-Identifier: GPL-2.0 */
2#ifndef _PPC_ASM_H 2#ifndef _PPC_ASM_H
3#define __PPC_ASM_H 3#define _PPC_ASM_H
4#include <ppc-asm.h> 4#include <ppc-asm.h>
5 5
6#ifndef r1 6#ifndef r1
diff --git a/tools/testing/selftests/powerpc/tm/tm-vmxcopy.c b/tools/testing/selftests/powerpc/tm/tm-vmxcopy.c
index 147c6dc4eb0b..c1e788a6df47 100644
--- a/tools/testing/selftests/powerpc/tm/tm-vmxcopy.c
+++ b/tools/testing/selftests/powerpc/tm/tm-vmxcopy.c
@@ -79,7 +79,7 @@ int test_vmxcopy()
79 79
80 "5:;" 80 "5:;"
81 "stxvd2x 40,0,%[vecoutptr];" 81 "stxvd2x 40,0,%[vecoutptr];"
82 : [res]"=r"(aborted) 82 : [res]"=&r"(aborted)
83 : [vecinptr]"r"(&vecin), 83 : [vecinptr]"r"(&vecin),
84 [vecoutptr]"r"(&vecout), 84 [vecoutptr]"r"(&vecout),
85 [map]"r"(a) 85 [map]"r"(a)
diff --git a/tools/testing/selftests/powerpc/vphn/Makefile b/tools/testing/selftests/powerpc/vphn/Makefile
index 18b885da01bd..cf65cbf33085 100644
--- a/tools/testing/selftests/powerpc/vphn/Makefile
+++ b/tools/testing/selftests/powerpc/vphn/Makefile
@@ -1,7 +1,7 @@
1# SPDX-License-Identifier: GPL-2.0-only 1# SPDX-License-Identifier: GPL-2.0-only
2TEST_GEN_PROGS := test-vphn 2TEST_GEN_PROGS := test-vphn
3 3
4CFLAGS += -m64 4CFLAGS += -m64 -I$(CURDIR)
5 5
6top_srcdir = ../../../../.. 6top_srcdir = ../../../../..
7include ../../lib.mk 7include ../../lib.mk
diff --git a/tools/testing/selftests/powerpc/vphn/asm/lppaca.h b/tools/testing/selftests/powerpc/vphn/asm/lppaca.h
new file mode 120000
index 000000000000..942b1d00999c
--- /dev/null
+++ b/tools/testing/selftests/powerpc/vphn/asm/lppaca.h
@@ -0,0 +1 @@
../../../../../../arch/powerpc/include/asm/lppaca.h \ No newline at end of file
diff --git a/tools/testing/selftests/powerpc/vphn/vphn.c b/tools/testing/selftests/powerpc/vphn/vphn.c
index 1d1f5f2be3b2..5b5fbddccabd 120000
--- a/tools/testing/selftests/powerpc/vphn/vphn.c
+++ b/tools/testing/selftests/powerpc/vphn/vphn.c
@@ -1 +1 @@
../../../../../arch/powerpc/mm/book3s64/vphn.c \ No newline at end of file ../../../../../arch/powerpc/platforms/pseries/vphn.c \ No newline at end of file
diff --git a/tools/testing/selftests/powerpc/vphn/vphn.h b/tools/testing/selftests/powerpc/vphn/vphn.h
deleted file mode 120000
index 45fe160f8288..000000000000
--- a/tools/testing/selftests/powerpc/vphn/vphn.h
+++ /dev/null
@@ -1 +0,0 @@
1../../../../../arch/powerpc/mm/book3s64/vphn.h \ No newline at end of file
diff --git a/tools/testing/selftests/proc/.gitignore b/tools/testing/selftests/proc/.gitignore
index 444ad39d3700..66fab4c58ed4 100644
--- a/tools/testing/selftests/proc/.gitignore
+++ b/tools/testing/selftests/proc/.gitignore
@@ -12,4 +12,5 @@
12/read 12/read
13/self 13/self
14/setns-dcache 14/setns-dcache
15/setns-sysvipc
15/thread-self 16/thread-self
diff --git a/tools/testing/selftests/proc/Makefile b/tools/testing/selftests/proc/Makefile
index 9f09fcd09ea3..a8ed0f684829 100644
--- a/tools/testing/selftests/proc/Makefile
+++ b/tools/testing/selftests/proc/Makefile
@@ -17,6 +17,7 @@ TEST_GEN_PROGS += proc-uptime-002
17TEST_GEN_PROGS += read 17TEST_GEN_PROGS += read
18TEST_GEN_PROGS += self 18TEST_GEN_PROGS += self
19TEST_GEN_PROGS += setns-dcache 19TEST_GEN_PROGS += setns-dcache
20TEST_GEN_PROGS += setns-sysvipc
20TEST_GEN_PROGS += thread-self 21TEST_GEN_PROGS += thread-self
21 22
22include ../lib.mk 23include ../lib.mk
diff --git a/tools/testing/selftests/proc/proc-pid-vm.c b/tools/testing/selftests/proc/proc-pid-vm.c
index 853aa164a401..18a3bde8bc96 100644
--- a/tools/testing/selftests/proc/proc-pid-vm.c
+++ b/tools/testing/selftests/proc/proc-pid-vm.c
@@ -215,6 +215,11 @@ static const char str_vsyscall[] =
215"ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]\n"; 215"ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]\n";
216 216
217#ifdef __x86_64__ 217#ifdef __x86_64__
218static void sigaction_SIGSEGV(int _, siginfo_t *__, void *___)
219{
220 _exit(1);
221}
222
218/* 223/*
219 * vsyscall page can't be unmapped, probe it with memory load. 224 * vsyscall page can't be unmapped, probe it with memory load.
220 */ 225 */
@@ -231,11 +236,19 @@ static void vsyscall(void)
231 if (pid == 0) { 236 if (pid == 0) {
232 struct rlimit rlim = {0, 0}; 237 struct rlimit rlim = {0, 0};
233 (void)setrlimit(RLIMIT_CORE, &rlim); 238 (void)setrlimit(RLIMIT_CORE, &rlim);
239
240 /* Hide "segfault at ffffffffff600000" messages. */
241 struct sigaction act;
242 memset(&act, 0, sizeof(struct sigaction));
243 act.sa_flags = SA_SIGINFO;
244 act.sa_sigaction = sigaction_SIGSEGV;
245 (void)sigaction(SIGSEGV, &act, NULL);
246
234 *(volatile int *)0xffffffffff600000UL; 247 *(volatile int *)0xffffffffff600000UL;
235 exit(0); 248 exit(0);
236 } 249 }
237 wait(&wstatus); 250 waitpid(pid, &wstatus, 0);
238 if (WIFEXITED(wstatus)) { 251 if (WIFEXITED(wstatus) && WEXITSTATUS(wstatus) == 0) {
239 g_vsyscall = true; 252 g_vsyscall = true;
240 } 253 }
241} 254}
diff --git a/tools/testing/selftests/proc/setns-sysvipc.c b/tools/testing/selftests/proc/setns-sysvipc.c
new file mode 100644
index 000000000000..903890c5e587
--- /dev/null
+++ b/tools/testing/selftests/proc/setns-sysvipc.c
@@ -0,0 +1,133 @@
1/*
2 * Copyright © 2019 Alexey Dobriyan <adobriyan@gmail.com>
3 *
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16/*
17 * Test that setns(CLONE_NEWIPC) points to new /proc/sysvipc content even
18 * if old one is in dcache.
19 */
20#undef NDEBUG
21#include <assert.h>
22#include <errno.h>
23#include <stdio.h>
24#include <sched.h>
25#include <signal.h>
26#include <stdlib.h>
27#include <string.h>
28#include <unistd.h>
29#include <sys/types.h>
30#include <sys/stat.h>
31#include <fcntl.h>
32#include <sys/ipc.h>
33#include <sys/shm.h>
34
35static pid_t pid = -1;
36
37static void f(void)
38{
39 if (pid > 0) {
40 kill(pid, SIGTERM);
41 }
42}
43
44int main(void)
45{
46 int fd[2];
47 char _ = 0;
48 int nsfd;
49
50 atexit(f);
51
52 /* Check for priviledges and syscall availability straight away. */
53 if (unshare(CLONE_NEWIPC) == -1) {
54 if (errno == ENOSYS || errno == EPERM) {
55 return 4;
56 }
57 return 1;
58 }
59 /* Distinguisher between two otherwise empty IPC namespaces. */
60 if (shmget(IPC_PRIVATE, 1, IPC_CREAT) == -1) {
61 return 1;
62 }
63
64 if (pipe(fd) == -1) {
65 return 1;
66 }
67
68 pid = fork();
69 if (pid == -1) {
70 return 1;
71 }
72
73 if (pid == 0) {
74 if (unshare(CLONE_NEWIPC) == -1) {
75 return 1;
76 }
77
78 if (write(fd[1], &_, 1) != 1) {
79 return 1;
80 }
81
82 pause();
83
84 return 0;
85 }
86
87 if (read(fd[0], &_, 1) != 1) {
88 return 1;
89 }
90
91 {
92 char buf[64];
93 snprintf(buf, sizeof(buf), "/proc/%u/ns/ipc", pid);
94 nsfd = open(buf, O_RDONLY);
95 if (nsfd == -1) {
96 return 1;
97 }
98 }
99
100 /* Reliably pin dentry into dcache. */
101 (void)open("/proc/sysvipc/shm", O_RDONLY);
102
103 if (setns(nsfd, CLONE_NEWIPC) == -1) {
104 return 1;
105 }
106
107 kill(pid, SIGTERM);
108 pid = 0;
109
110 {
111 char buf[4096];
112 ssize_t rv;
113 int fd;
114
115 fd = open("/proc/sysvipc/shm", O_RDONLY);
116 if (fd == -1) {
117 return 1;
118 }
119
120#define S32 " key shmid perms size cpid lpid nattch uid gid cuid cgid atime dtime ctime rss swap\n"
121#define S64 " key shmid perms size cpid lpid nattch uid gid cuid cgid atime dtime ctime rss swap\n"
122 rv = read(fd, buf, sizeof(buf));
123 if (rv == strlen(S32)) {
124 assert(memcmp(buf, S32, strlen(S32)) == 0);
125 } else if (rv == strlen(S64)) {
126 assert(memcmp(buf, S64, strlen(S64)) == 0);
127 } else {
128 assert(0);
129 }
130 }
131
132 return 0;
133}
diff --git a/tools/testing/selftests/ptrace/.gitignore b/tools/testing/selftests/ptrace/.gitignore
index b3e59d41fd82..cfcc49a7def7 100644
--- a/tools/testing/selftests/ptrace/.gitignore
+++ b/tools/testing/selftests/ptrace/.gitignore
@@ -1 +1,2 @@
1get_syscall_info
1peeksiginfo 2peeksiginfo
diff --git a/tools/testing/selftests/ptrace/Makefile b/tools/testing/selftests/ptrace/Makefile
index cb21c76a18ca..c0b7f89f0930 100644
--- a/tools/testing/selftests/ptrace/Makefile
+++ b/tools/testing/selftests/ptrace/Makefile
@@ -1,6 +1,6 @@
1# SPDX-License-Identifier: GPL-2.0-only 1# SPDX-License-Identifier: GPL-2.0-only
2CFLAGS += -iquote../../../../include/uapi -Wall 2CFLAGS += -iquote../../../../include/uapi -Wall
3 3
4TEST_GEN_PROGS := peeksiginfo 4TEST_GEN_PROGS := get_syscall_info peeksiginfo
5 5
6include ../lib.mk 6include ../lib.mk
diff --git a/tools/testing/selftests/ptrace/get_syscall_info.c b/tools/testing/selftests/ptrace/get_syscall_info.c
new file mode 100644
index 000000000000..5bcd1c7b5be6
--- /dev/null
+++ b/tools/testing/selftests/ptrace/get_syscall_info.c
@@ -0,0 +1,271 @@
1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Copyright (c) 2018 Dmitry V. Levin <ldv@altlinux.org>
4 * All rights reserved.
5 *
6 * Check whether PTRACE_GET_SYSCALL_INFO semantics implemented in the kernel
7 * matches userspace expectations.
8 */
9
10#include "../kselftest_harness.h"
11#include <err.h>
12#include <signal.h>
13#include <asm/unistd.h>
14#include "linux/ptrace.h"
15
16static int
17kill_tracee(pid_t pid)
18{
19 if (!pid)
20 return 0;
21
22 int saved_errno = errno;
23
24 int rc = kill(pid, SIGKILL);
25
26 errno = saved_errno;
27 return rc;
28}
29
30static long
31sys_ptrace(int request, pid_t pid, unsigned long addr, unsigned long data)
32{
33 return syscall(__NR_ptrace, request, pid, addr, data);
34}
35
36#define LOG_KILL_TRACEE(fmt, ...) \
37 do { \
38 kill_tracee(pid); \
39 TH_LOG("wait #%d: " fmt, \
40 ptrace_stop, ##__VA_ARGS__); \
41 } while (0)
42
43TEST(get_syscall_info)
44{
45 static const unsigned long args[][7] = {
46 /* a sequence of architecture-agnostic syscalls */
47 {
48 __NR_chdir,
49 (unsigned long) "",
50 0xbad1fed1,
51 0xbad2fed2,
52 0xbad3fed3,
53 0xbad4fed4,
54 0xbad5fed5
55 },
56 {
57 __NR_gettid,
58 0xcaf0bea0,
59 0xcaf1bea1,
60 0xcaf2bea2,
61 0xcaf3bea3,
62 0xcaf4bea4,
63 0xcaf5bea5
64 },
65 {
66 __NR_exit_group,
67 0,
68 0xfac1c0d1,
69 0xfac2c0d2,
70 0xfac3c0d3,
71 0xfac4c0d4,
72 0xfac5c0d5
73 }
74 };
75 const unsigned long *exp_args;
76
77 pid_t pid = fork();
78
79 ASSERT_LE(0, pid) {
80 TH_LOG("fork: %m");
81 }
82
83 if (pid == 0) {
84 /* get the pid before PTRACE_TRACEME */
85 pid = getpid();
86 ASSERT_EQ(0, sys_ptrace(PTRACE_TRACEME, 0, 0, 0)) {
87 TH_LOG("PTRACE_TRACEME: %m");
88 }
89 ASSERT_EQ(0, kill(pid, SIGSTOP)) {
90 /* cannot happen */
91 TH_LOG("kill SIGSTOP: %m");
92 }
93 for (unsigned int i = 0; i < ARRAY_SIZE(args); ++i) {
94 syscall(args[i][0],
95 args[i][1], args[i][2], args[i][3],
96 args[i][4], args[i][5], args[i][6]);
97 }
98 /* unreachable */
99 _exit(1);
100 }
101
102 const struct {
103 unsigned int is_error;
104 int rval;
105 } *exp_param, exit_param[] = {
106 { 1, -ENOENT }, /* chdir */
107 { 0, pid } /* gettid */
108 };
109
110 unsigned int ptrace_stop;
111
112 for (ptrace_stop = 0; ; ++ptrace_stop) {
113 struct ptrace_syscall_info info = {
114 .op = 0xff /* invalid PTRACE_SYSCALL_INFO_* op */
115 };
116 const size_t size = sizeof(info);
117 const int expected_none_size =
118 (void *) &info.entry - (void *) &info;
119 const int expected_entry_size =
120 (void *) &info.entry.args[6] - (void *) &info;
121 const int expected_exit_size =
122 (void *) (&info.exit.is_error + 1) -
123 (void *) &info;
124 int status;
125 long rc;
126
127 ASSERT_EQ(pid, wait(&status)) {
128 /* cannot happen */
129 LOG_KILL_TRACEE("wait: %m");
130 }
131 if (WIFEXITED(status)) {
132 pid = 0; /* the tracee is no more */
133 ASSERT_EQ(0, WEXITSTATUS(status));
134 break;
135 }
136 ASSERT_FALSE(WIFSIGNALED(status)) {
137 pid = 0; /* the tracee is no more */
138 LOG_KILL_TRACEE("unexpected signal %u",
139 WTERMSIG(status));
140 }
141 ASSERT_TRUE(WIFSTOPPED(status)) {
142 /* cannot happen */
143 LOG_KILL_TRACEE("unexpected wait status %#x", status);
144 }
145
146 switch (WSTOPSIG(status)) {
147 case SIGSTOP:
148 ASSERT_EQ(0, ptrace_stop) {
149 LOG_KILL_TRACEE("unexpected signal stop");
150 }
151 ASSERT_EQ(0, sys_ptrace(PTRACE_SETOPTIONS, pid, 0,
152 PTRACE_O_TRACESYSGOOD)) {
153 LOG_KILL_TRACEE("PTRACE_SETOPTIONS: %m");
154 }
155 ASSERT_LT(0, (rc = sys_ptrace(PTRACE_GET_SYSCALL_INFO,
156 pid, size,
157 (unsigned long) &info))) {
158 LOG_KILL_TRACEE("PTRACE_GET_SYSCALL_INFO: %m");
159 }
160 ASSERT_EQ(expected_none_size, rc) {
161 LOG_KILL_TRACEE("signal stop mismatch");
162 }
163 ASSERT_EQ(PTRACE_SYSCALL_INFO_NONE, info.op) {
164 LOG_KILL_TRACEE("signal stop mismatch");
165 }
166 ASSERT_TRUE(info.arch) {
167 LOG_KILL_TRACEE("signal stop mismatch");
168 }
169 ASSERT_TRUE(info.instruction_pointer) {
170 LOG_KILL_TRACEE("signal stop mismatch");
171 }
172 ASSERT_TRUE(info.stack_pointer) {
173 LOG_KILL_TRACEE("signal stop mismatch");
174 }
175 break;
176
177 case SIGTRAP | 0x80:
178 ASSERT_LT(0, (rc = sys_ptrace(PTRACE_GET_SYSCALL_INFO,
179 pid, size,
180 (unsigned long) &info))) {
181 LOG_KILL_TRACEE("PTRACE_GET_SYSCALL_INFO: %m");
182 }
183 switch (ptrace_stop) {
184 case 1: /* entering chdir */
185 case 3: /* entering gettid */
186 case 5: /* entering exit_group */
187 exp_args = args[ptrace_stop / 2];
188 ASSERT_EQ(expected_entry_size, rc) {
189 LOG_KILL_TRACEE("entry stop mismatch");
190 }
191 ASSERT_EQ(PTRACE_SYSCALL_INFO_ENTRY, info.op) {
192 LOG_KILL_TRACEE("entry stop mismatch");
193 }
194 ASSERT_TRUE(info.arch) {
195 LOG_KILL_TRACEE("entry stop mismatch");
196 }
197 ASSERT_TRUE(info.instruction_pointer) {
198 LOG_KILL_TRACEE("entry stop mismatch");
199 }
200 ASSERT_TRUE(info.stack_pointer) {
201 LOG_KILL_TRACEE("entry stop mismatch");
202 }
203 ASSERT_EQ(exp_args[0], info.entry.nr) {
204 LOG_KILL_TRACEE("entry stop mismatch");
205 }
206 ASSERT_EQ(exp_args[1], info.entry.args[0]) {
207 LOG_KILL_TRACEE("entry stop mismatch");
208 }
209 ASSERT_EQ(exp_args[2], info.entry.args[1]) {
210 LOG_KILL_TRACEE("entry stop mismatch");
211 }
212 ASSERT_EQ(exp_args[3], info.entry.args[2]) {
213 LOG_KILL_TRACEE("entry stop mismatch");
214 }
215 ASSERT_EQ(exp_args[4], info.entry.args[3]) {
216 LOG_KILL_TRACEE("entry stop mismatch");
217 }
218 ASSERT_EQ(exp_args[5], info.entry.args[4]) {
219 LOG_KILL_TRACEE("entry stop mismatch");
220 }
221 ASSERT_EQ(exp_args[6], info.entry.args[5]) {
222 LOG_KILL_TRACEE("entry stop mismatch");
223 }
224 break;
225 case 2: /* exiting chdir */
226 case 4: /* exiting gettid */
227 exp_param = &exit_param[ptrace_stop / 2 - 1];
228 ASSERT_EQ(expected_exit_size, rc) {
229 LOG_KILL_TRACEE("exit stop mismatch");
230 }
231 ASSERT_EQ(PTRACE_SYSCALL_INFO_EXIT, info.op) {
232 LOG_KILL_TRACEE("exit stop mismatch");
233 }
234 ASSERT_TRUE(info.arch) {
235 LOG_KILL_TRACEE("exit stop mismatch");
236 }
237 ASSERT_TRUE(info.instruction_pointer) {
238 LOG_KILL_TRACEE("exit stop mismatch");
239 }
240 ASSERT_TRUE(info.stack_pointer) {
241 LOG_KILL_TRACEE("exit stop mismatch");
242 }
243 ASSERT_EQ(exp_param->is_error,
244 info.exit.is_error) {
245 LOG_KILL_TRACEE("exit stop mismatch");
246 }
247 ASSERT_EQ(exp_param->rval, info.exit.rval) {
248 LOG_KILL_TRACEE("exit stop mismatch");
249 }
250 break;
251 default:
252 LOG_KILL_TRACEE("unexpected syscall stop");
253 abort();
254 }
255 break;
256
257 default:
258 LOG_KILL_TRACEE("unexpected stop signal %#x",
259 WSTOPSIG(status));
260 abort();
261 }
262
263 ASSERT_EQ(0, sys_ptrace(PTRACE_SYSCALL, pid, 0, 0)) {
264 LOG_KILL_TRACEE("PTRACE_SYSCALL: %m");
265 }
266 }
267
268 ASSERT_EQ(ARRAY_SIZE(args) * 2, ptrace_stop);
269}
270
271TEST_HARNESS_MAIN
diff --git a/tools/testing/selftests/safesetid/safesetid-test.c b/tools/testing/selftests/safesetid/safesetid-test.c
index 892c8e8b1b8b..8f40c6ecdad1 100644
--- a/tools/testing/selftests/safesetid/safesetid-test.c
+++ b/tools/testing/selftests/safesetid/safesetid-test.c
@@ -142,23 +142,19 @@ static void ensure_securityfs_mounted(void)
142 142
143static void write_policies(void) 143static void write_policies(void)
144{ 144{
145 static char *policy_str =
146 "1:2\n"
147 "1:3\n"
148 "2:2\n"
149 "3:3\n";
145 ssize_t written; 150 ssize_t written;
146 int fd; 151 int fd;
147 152
148 fd = open(add_whitelist_policy_file, O_WRONLY); 153 fd = open(add_whitelist_policy_file, O_WRONLY);
149 if (fd < 0) 154 if (fd < 0)
150 die("cant open add_whitelist_policy file\n"); 155 die("cant open add_whitelist_policy file\n");
151 written = write(fd, "1:2", strlen("1:2")); 156 written = write(fd, policy_str, strlen(policy_str));
152 if (written != strlen("1:2")) { 157 if (written != strlen(policy_str)) {
153 if (written >= 0) {
154 die("short write to %s\n", add_whitelist_policy_file);
155 } else {
156 die("write to %s failed: %s\n",
157 add_whitelist_policy_file, strerror(errno));
158 }
159 }
160 written = write(fd, "1:3", strlen("1:3"));
161 if (written != strlen("1:3")) {
162 if (written >= 0) { 158 if (written >= 0) {
163 die("short write to %s\n", add_whitelist_policy_file); 159 die("short write to %s\n", add_whitelist_policy_file);
164 } else { 160 } else {
diff --git a/tools/testing/selftests/seccomp/seccomp_bpf.c b/tools/testing/selftests/seccomp/seccomp_bpf.c
index dc66fe852768..6ef7f16c4cf5 100644
--- a/tools/testing/selftests/seccomp/seccomp_bpf.c
+++ b/tools/testing/selftests/seccomp/seccomp_bpf.c
@@ -1775,13 +1775,18 @@ void tracer_ptrace(struct __test_metadata *_metadata, pid_t tracee,
1775 unsigned long msg; 1775 unsigned long msg;
1776 static bool entry; 1776 static bool entry;
1777 1777
1778 /* Make sure we got an empty message. */ 1778 /*
1779 * The traditional way to tell PTRACE_SYSCALL entry/exit
1780 * is by counting.
1781 */
1782 entry = !entry;
1783
1784 /* Make sure we got an appropriate message. */
1779 ret = ptrace(PTRACE_GETEVENTMSG, tracee, NULL, &msg); 1785 ret = ptrace(PTRACE_GETEVENTMSG, tracee, NULL, &msg);
1780 EXPECT_EQ(0, ret); 1786 EXPECT_EQ(0, ret);
1781 EXPECT_EQ(0, msg); 1787 EXPECT_EQ(entry ? PTRACE_EVENTMSG_SYSCALL_ENTRY
1788 : PTRACE_EVENTMSG_SYSCALL_EXIT, msg);
1782 1789
1783 /* The only way to tell PTRACE_SYSCALL entry/exit is by counting. */
1784 entry = !entry;
1785 if (!entry) 1790 if (!entry)
1786 return; 1791 return;
1787 1792
diff --git a/tools/testing/selftests/tc-testing/tc-tests/actions/skbedit.json b/tools/testing/selftests/tc-testing/tc-tests/actions/skbedit.json
index 45e7e89928a5..bf5ebf59c2d4 100644
--- a/tools/testing/selftests/tc-testing/tc-tests/actions/skbedit.json
+++ b/tools/testing/selftests/tc-testing/tc-tests/actions/skbedit.json
@@ -70,6 +70,123 @@
70 "teardown": [] 70 "teardown": []
71 }, 71 },
72 { 72 {
73 "id": "d4cd",
74 "name": "Add skbedit action with valid mark and mask",
75 "category": [
76 "actions",
77 "skbedit"
78 ],
79 "setup": [
80 [
81 "$TC actions flush action skbedit",
82 0,
83 1,
84 255
85 ]
86 ],
87 "cmdUnderTest": "$TC actions add action skbedit mark 1/0xaabb",
88 "expExitCode": "0",
89 "verifyCmd": "$TC actions list action skbedit",
90 "matchPattern": "action order [0-9]*: skbedit mark 1/0xaabb",
91 "matchCount": "1",
92 "teardown": [
93 "$TC actions flush action skbedit"
94 ]
95 },
96 {
97 "id": "baa7",
98 "name": "Add skbedit action with valid mark and 32-bit maximum mask",
99 "category": [
100 "actions",
101 "skbedit"
102 ],
103 "setup": [
104 [
105 "$TC actions flush action skbedit",
106 0,
107 1,
108 255
109 ]
110 ],
111 "cmdUnderTest": "$TC actions add action skbedit mark 1/0xffffffff",
112 "expExitCode": "0",
113 "verifyCmd": "$TC actions list action skbedit",
114 "matchPattern": "action order [0-9]*: skbedit mark 1/0xffffffff",
115 "matchCount": "1",
116 "teardown": [
117 "$TC actions flush action skbedit"
118 ]
119 },
120 {
121 "id": "62a5",
122 "name": "Add skbedit action with valid mark and mask exceeding 32-bit maximum",
123 "category": [
124 "actions",
125 "skbedit"
126 ],
127 "setup": [
128 [
129 "$TC actions flush action skbedit",
130 0,
131 1,
132 255
133 ]
134 ],
135 "cmdUnderTest": "$TC actions add action skbedit mark 1/0xaabbccddeeff112233",
136 "expExitCode": "255",
137 "verifyCmd": "$TC actions list action skbedit",
138 "matchPattern": "action order [0-9]*: skbedit mark 1/0xaabbccddeeff112233",
139 "matchCount": "0",
140 "teardown": []
141 },
142 {
143 "id": "bc15",
144 "name": "Add skbedit action with valid mark and mask with invalid format",
145 "category": [
146 "actions",
147 "skbedit"
148 ],
149 "setup": [
150 [
151 "$TC actions flush action skbedit",
152 0,
153 1,
154 255
155 ]
156 ],
157 "cmdUnderTest": "$TC actions add action skbedit mark 1/-1234",
158 "expExitCode": "255",
159 "verifyCmd": "$TC actions list action skbedit",
160 "matchPattern": "action order [0-9]*: skbedit mark 1/-1234",
161 "matchCount": "0",
162 "teardown": []
163 },
164 {
165 "id": "57c2",
166 "name": "Replace skbedit action with new mask",
167 "category": [
168 "actions",
169 "skbedit"
170 ],
171 "setup": [
172 [
173 "$TC actions flush action skbedit",
174 0,
175 1,
176 255
177 ],
178 "$TC actions add action skbedit mark 1/0x11223344 index 1"
179 ],
180 "cmdUnderTest": "$TC actions replace action skbedit mark 1/0xaabb index 1",
181 "expExitCode": "0",
182 "verifyCmd": "$TC actions list action skbedit",
183 "matchPattern": "action order [0-9]*: skbedit mark 1/0xaabb",
184 "matchCount": "1",
185 "teardown": [
186 "$TC actions flush action skbedit"
187 ]
188 },
189 {
73 "id": "081d", 190 "id": "081d",
74 "name": "Add skbedit action with priority", 191 "name": "Add skbedit action with priority",
75 "category": [ 192 "category": [
diff --git a/tools/testing/selftests/x86/fsgsbase.c b/tools/testing/selftests/x86/fsgsbase.c
index 5ab4c60c100e..15a329da59fa 100644
--- a/tools/testing/selftests/x86/fsgsbase.c
+++ b/tools/testing/selftests/x86/fsgsbase.c
@@ -489,25 +489,11 @@ static void test_ptrace_write_gsbase(void)
489 * selector value is changed or not by the GSBASE write in 489 * selector value is changed or not by the GSBASE write in
490 * a ptracer. 490 * a ptracer.
491 */ 491 */
492 if (gs != *shared_scratch) { 492 if (gs == 0 && base == 0xFF) {
493 nerrs++; 493 printf("[OK]\tGS was reset as expected\n");
494 printf("[FAIL]\tGS changed to %lx\n", gs);
495
496 /*
497 * On older kernels, poking a nonzero value into the
498 * base would zero the selector. On newer kernels,
499 * this behavior has changed -- poking the base
500 * changes only the base and, if FSGSBASE is not
501 * available, this may have no effect.
502 */
503 if (gs == 0)
504 printf("\tNote: this is expected behavior on older kernels.\n");
505 } else if (have_fsgsbase && (base != 0xFF)) {
506 nerrs++;
507 printf("[FAIL]\tGSBASE changed to %lx\n", base);
508 } else { 494 } else {
509 printf("[OK]\tGS remained 0x%hx%s", *shared_scratch, have_fsgsbase ? " and GSBASE changed to 0xFF" : ""); 495 nerrs++;
510 printf("\n"); 496 printf("[FAIL]\tGS=0x%lx, GSBASE=0x%lx (should be 0, 0xFF)\n", gs, base);
511 } 497 }
512 } 498 }
513 499
diff --git a/tools/testing/selftests/zram/README b/tools/testing/selftests/zram/README
index 7972cc512408..110b34834a6f 100644
--- a/tools/testing/selftests/zram/README
+++ b/tools/testing/selftests/zram/README
@@ -37,4 +37,4 @@ Commands required for testing:
37 - mkfs/ mkfs.ext4 37 - mkfs/ mkfs.ext4
38 38
39For more information please refer: 39For more information please refer:
40kernel-source-tree/Documentation/blockdev/zram.txt 40kernel-source-tree/Documentation/admin-guide/blockdev/zram.rst